feat: 添加静态资源文件及基础组件

- 新增大量图片资源,包括图标、背景图、海报等,用于页面展示
- 添加字体文件及样式配置,支持自定义字体
- 引入 uni-ui 组件库,包括图标、弹窗、日期选择器等常用组件
- 添加网络状态监听、加密工具等基础工具函数
- 配置 Vuex 状态管理,包括购物车数量、热门搜索词等
- 增加页面组件,如用户协议、分销信息、提现状态等
- 配置项目构建和忽略文件,优化开发体验
This commit is contained in:
2026-02-26 17:59:51 +08:00
commit a5c5d753b6
720 changed files with 178840 additions and 0 deletions

View File

@@ -0,0 +1,472 @@
<template>
<view :style="colorStyle">
<view class="flex-col flex-center py-78">
<baseMoney :money="payPriceShow" symbolSize="48" integerSize="64" decimalSize="48" color="#333" weight></baseMoney>
<view class="flex-y-center mt-20">
<text class="fs-24 text--w111-333 lh-36rpx pr-10">支付剩余时间</text>
<countDown
:is-day="false"
tip-text=" "
day-text=" "
hour-text=":"
minute-text=":"
second-text=" "
bgColor="#FFFFFF"
dotColor="var(--view-theme)"
:datatime="invalidTime"
></countDown>
</view>
</view>
<view class="px-20">
<view v-if="yuePayStatus" class="bg--w111-fff rd-24rpx pay_card mb-20">
<view class="flex-between-center pay_item">
<view class="flex-y-center">
<image class="w-52 h-52" :src="imgHost + '/statics/images/order/yue_pay.png'"></image>
<view class="pl-20">
<view class="text--w111-333 fs-28 lh-38rpx">
余额支付
<text class="pl-10 text-theme">(¥{{ now_money }})</text>
</view>
<view class="fs-22 text--w111-999 lh-30rpx mt-8">可与其他方式组合使用</view>
</view>
</view>
<view class="flex flex-y-center iconfont fs-40 text--w111-999">
<text v-if="yueStatus" class="fs-28 text--w111-333 mr-12">-¥{{ yueNeedMoney }}</text>
<text class="iconfont fs-40 text--w111-999" :class="yueStatus ? 'icon-a-ic_CompleteSelect' : 'icon-ic_unselect'" @click="yuePayStatusChange"></text>
</view>
</view>
</view>
<view class="bg--w111-fff rd-24rpx pay_card" v-show="isShow">
<view class="flex-between-center pay_item" v-for="(item, index) in payTypeList" :key="index" @tap="payTypeSel(item.value, index)">
<view class="flex-y-center">
<image class="w-52 h-52" :src="item.icon"></image>
<view class="pl-20">
<view class="text--w111-333 fs-28 lh-38rpx">{{ item.name }}</view>
<view class="fs-22 text--w111-999 lh-30rpx mt-8" v-if="item.value == 'yue'">可用余额¥{{ now_money }}</view>
<view class="fs-22 text--w111-999 lh-30rpx mt-8" v-else>{{ item.title }}</view>
</view>
</view>
<text class="iconfont fs-40 text--w111-999" :class="active == index ? 'icon-a-ic_CompleteSelect' : 'icon-ic_unselect'"></text>
</view>
</view>
</view>
<view class="w-full h-128 fixed-lb pb-safe flex-center">
<view class="w-710 h-80 flex-center rd-40rpx text--w111-fff bg-color fs-28" @click="goPay()">确认付款</view>
</view>
<view v-show="false" v-html="formContent"></view>
</view>
</template>
<script>
import countDown from '@/components/countDown';
import colors from "@/mixins/color";
import { getCashierOrder, orderPay } from "@/api/order";
import { rechargePayAPi, memberCardPayApi } from "@/api/user.js"
import { HTTP_REQUEST_URL } from '@/config/app';
export default {
data() {
return {
invalidTime: 0,
checked:false,
orderId: 0,
fromType: '',
active: -1,
payPrice: 0,
payPriceShow: 0,
now_money:'',
payPostage: 0,
offlinePostage: false,
invalidTime: 0,
initIn: false,
jumpData: {
orderId: '',
msg: ''
},
formContent: '',
imgHost: HTTP_REQUEST_URL,
cartArr: [
{
"name": "微信支付",
"icon": HTTP_REQUEST_URL + "/statics/images/order/wx_pay.png",
value: 'weixin',
title: '使用微信快捷支付',
payStatus: 1,
},
{
"name": "支付宝支付",
"icon": HTTP_REQUEST_URL + "/statics/images/order/alipay.png",
value: 'alipay',
title: '使用线上支付宝支付',
payStatus: 1,
},
// {
// "name": "余额抵扣",
// "icon": HTTP_REQUEST_URL + "/statics/images/order/yue_pay.png",
// value: 'yue',
// title: '可用余额:',
// payStatus: 1,
// },
{
"name": "线下支付",
"icon": HTTP_REQUEST_URL + "/statics/images/order/xianxia_pay.png",
value: 'offline',
title: '使用线下付款方式',
payStatus: 2,
}
],
paytype:'',
isShow: false,
yuePayStatus: false,
yueStatus:false,
canSel: true
}
},
mixins: [colors],
components: {
countDown,
},
computed:{
payTypeList(){
let list = [];
this.cartArr.forEach(item=>{
if(item.payStatus == 1){
list.push(item);
}
})
return list
},
yueNeedMoney(){
return Number(this.payPriceShow) < Number(this.now_money) ? this.payPriceShow : this.now_money
},
},
watch:{
yueStatus(val){
if(val){
// 判断是否有余额
if(Number(this.now_money) <= 0){
this.yueStatus = false
return this.$util.Tips({
title: '余额不足'
})
}
if(Number(this.payPriceShow) <= Number(this.now_money)){
this.active = -2
this.canSel = false
this.paytype = 'yue'
}
} else {
if(this.active<0){
this.active = this.cartArr.findIndex(item=>item.payStatus == 1)
this.paytype = this.cartArr[this.active].value
}
this.canSel = true
}
},
},
onLoad(options) {
if (options.order_id) this.orderId = options.order_id;
if (options.from_type) this.fromType = options.from_type;
this.getCashierOrder();
},
methods: {
payTypeSel(paytype, index) {
console.log(paytype, index)
this.active = index;
this.paytype = paytype;
if(!this.canSel) {
// return this.$util.Tips({
// title: '已选择余额抵扣'
// })
this.yueStatus = false
// return
}
if (this.offlinePostage) {
if (paytype == 'offline') {
this.payPriceShow = this.$util.$h.Sub(this.payPrice, this.payPostage);
} else {
this.payPriceShow = this.payPrice;
}
}
},
yuePayStatusChange(e){
this.yueStatus = !this.yueStatus;
},
getCashierOrder() {
getCashierOrder(this.orderId, this.fromType).then(res => {
this.isShow = true;
//微信支付是否开启
this.cartArr[0].payStatus = res.data.pay_weixin_open || 0
//支付宝是否开启
// #ifdef MP-WEIXIN
/*微信小程序环境中不允许支付宝支付*/
this.cartArr[1].payStatus = 0;
// #endif
// #ifdef H5
/*微信公众号环境中不允许支付宝支付*/
this.cartArr[1].payStatus = this.$wechat.isWeixin() ? 0 : res.data.ali_pay_status;
// #endif
// #ifdef APP-PLUS
this.cartArr[1].payStatus = res.data.ali_pay_status || 0;
// #endif
//余额抵扣是否开启
this.yuePayStatus = res.data.yue_pay_status == 1;
this.now_money = res.data.now_money;
//线下支付是否开启
if (res.data.offline_pay_status == 1) {
this.cartArr[2].payStatus = 1
} else {
this.cartArr[2].payStatus = 0
}
// 订单价格
this.payPrice = this.payPriceShow = res.data.pay_price
//剩余时间
this.invalidTime = res.data.invalid_time;
// 邮费
this.payPostage = res.data.pay_postage;
this.getShowPay();
this.$nextTick(e=>{
if(this.yuePayStatus && Number(this.payPriceShow) <= Number(this.now_money)){
this.yueStatus = true
} else {
this.payTypeSel(this.payTypeList[0].value, 0)
}
})
}).catch(err => {
this.isShow = true;
uni.hideLoading();
return this.$util.Tips({
title: err
})
})
},
getShowPay(){
//付费会员购买和余额充值不允许使用线下支付和余额抵扣,未开启线上支付支付的话给出提示并且返回上一页
//检查支付类型列表数组的payStatus是不是都是0或者2
const isAllPayStatusZero = this.cartArr.every(item => item.payStatus == 0 || item.payStatus == 2);
if(isAllPayStatusZero && ['vip','recharge'].includes(this.fromType)){
return this.$util.Tips({
title: '未开启线上支付,请联系管理员'
}, {
tab: 3,
});
}
},
goPay(){
let that = this;
if(that.active == -1) return that.$util.Tips({
title: '请选择付款方式'
});
if (!that.orderId) return that.$util.Tips({
title: '请选择要支付的订单'
});
if (that.paytype == 'yue' && parseFloat(this.now_money) < parseFloat(that.payPriceShow)) return that.$util.Tips({
title: '余额不足'
});
uni.showLoading({
title: '支付中'
});
let funApi = '';
if(this.fromType == 'order'){
funApi = orderPay({
uni: that.orderId,
paytype: that.paytype,
use_balance: that.yueStatus ? 1 : 0,
// #ifdef MP
'from': 'routine',
// #endif
// #ifdef H5
'from': this.$wechat.isWeixin() ? 'weixin' : 'weixinh5',
// #endif
// #ifdef H5
quitUrl: location.port ? location.protocol + '//' + location.hostname + ':' + location.port + '/pages/goods/order_pay_status/index?order_id=' + this.orderId : location.protocol + '//' + location.hostname +'/pages/goods/order_pay_status/index?order_id=' + this.orderId
// #endif
// #ifdef APP-PLUS
quitUrl: '/pages/goods/order_pay_status/index?order_id=' + this.orderId
// #endif
})
}else if(this.fromType == 'recharge'){
funApi = rechargePayAPi({
uni: this.orderId,
paytype: that.paytype,
// #ifdef MP
'from': 'routine',
// #endif
// #ifdef H5
'from': this.$wechat.isWeixin() ? 'weixin' : 'weixinh5',
// #endif
// #ifdef H5
quitUrl: location.port ? location.protocol + '//' + location.hostname + ':' + location.port + '/pages/users/user_payment/index' : location.protocol + '//' + location.hostname +'/pages/users/user_payment/index'
// #endif
// #ifdef APP-PLUS
quitUrl: '/pages/users/user_payment/index'
// #endif
})
}else if(this.fromType == 'vip'){
funApi = memberCardPayApi({
uni: this.orderId,
paytype: this.paytype,
// #ifdef MP
'from': 'routine',
// #endif
// #ifdef H5
'from': this.$wechat.isWeixin() ? 'weixin' : 'weixinh5',
quitUrl: '/pages/annex/vip_paid/index',
// #endif
// #ifdef APP-PLUS
quitUrl: '/pages/annex/vip_paid/index',
// #endif
})
}
funApi.then(res=>{
let status = res.data.status,
orderId = res.data.result.order_id || '',
jsConfig = res.data.result.jsConfig;
this.orderId = res.data.result.order_id ? res.data.result.order_id : this.orderId;
//页面回调地址
let PageObj = {
'order': '/pages/goods/order_pay_status/index?order_id=' + this.orderId + '&msg=' +res.msg +'&type=3' + '&totalPrice=' + this.payPriceShow,
'recharge': '/pages/users/user_payment/index',
'vip': '/pages/annex/vip_paid/index',
};
let backUrl = PageObj[this.fromType];
switch (status) {
case 'ORDER_EXIST':
case 'EXTEND_ORDER':
case 'PAY_ERROR':
this.pageReject(res.msg,backUrl);
break;
case 'SUCCESS':
this.pageReject(res.msg,backUrl);
break;
case 'WECHAT_PAY':
this.wechatPayFun(jsConfig,backUrl);
break;
case 'PAY_DEFICIENCY':
uni.hideLoading();
this.pageReject(res.msg,backUrl);
break;
case "WECHAT_H5_PAY":
uni.hideLoading();
// that.$util.Tips({
// title: '订单创建成功!'
// });
setTimeout(() => {
location.href = res.data.result.jsConfig.mweb_url + '&redirect_url=' + window.location.protocol + '//' + window.location.host + backUrl;
}, 500);
break;
case 'ALIPAY_PAY':
//#ifdef H5
uni.hideLoading();
that.formContent = res.data.result.jsConfig;
that.$nextTick(() => {
document.getElementById('alipaysubmit').submit();
})
//#endif
// #ifdef APP-PLUS
uni.requestPayment({
provider: 'alipay',
orderInfo: jsConfig,
success: (e) => {
that.pageReject('支付成功',backUrl);
},
fail: (e) => {
that.pageReject('支付失败',backUrl);
},
complete: () => {
uni.hideLoading();
},
});
// #endif
break;
}
}).catch(err=>{
uni.hideLoading();
return that.$util.Tips({
title: err
});
})
},
wechatPayFun(jsConfig, backUrl){
let that = this;
// #ifdef MP
uni.requestPayment({
timeStamp: jsConfig.timestamp,
nonceStr: jsConfig.nonceStr,
package: jsConfig.package,
signType: jsConfig.signType,
paySign: jsConfig.paySign,
success: function(res) {
console.log("success");
that.pageReject('支付成功',backUrl);
},
fail: function(e) {
console.log("fail");
that.pageReject('支付失败',backUrl);
},
})
// #endif
// #ifdef H5
this.$wechat.pay(jsConfig).then(res => {
this.pageReject('支付成功',backUrl);
}).catch(res => {
if (!this.$wechat.isWeixin()) {
this.pageReject('支付失败',backUrl);
}
if (res.errMsg == 'chooseWXPay:cancel') {
this.pageReject('取消支付',backUrl);
}
})
// #endif
// #ifdef APP-PLUS
uni.requestPayment({
provider: 'wxpay',
orderInfo: jsConfig,
success: (e) => {
that.pageReject('支付成功',backUrl);
},
fail: (e) => {
that.pageReject('支付失败',backUrl);
},
});
// #endif
},
pageReject(msg,backUrl){
uni.hideLoading();
return this.$util.Tips({
title: msg
}, {
tab: 5,
url: backUrl
});
}
}
}
</script>
<style lang="scss">
/deep/ .styleAll {
padding: 0 6rpx;
border: 1rpx solid #dddddd;
border-radius: 8rpx;
}
.pay_card {
padding: 40rpx 32rpx;
}
.ye-pay-card {
padding: 40rpx 0 40rpx 32rpx;
}
.pay_item ~ .pay_item {
margin-top: 56rpx;
}
.icon-ic_unselect {
color: #ccc;
}
.icon-a-ic_CompleteSelect {
color: var(--view-theme);
}
</style>

View File

@@ -0,0 +1,171 @@
<script>
import baseDrawer from '@/components/tui-drawer/tui-drawer.vue';
export default {
props: {
visible: {
type: Boolean,
default: false,
},
promotionId:{
type: [String, Number],
default: ''
},
brandList:{
type:Array,
default: () => []
},
promotionList:{
type:Array,
default: () => []
},
labelList:{
type:Array,
default: () => []
},
},
data(){
return {
promotions_id: [],
brand_id: [],
store_label_id: [],
}
},
watch:{
// promotionId:{
// handler(val){
// this.promotions_id = val.split(',');
// },
// immediate:true
// },
},
computed: {
fixedTop() {
// #ifdef MP || APP-PLUS
return uni.getWindowInfo().statusBarHeight
// #endif
// #ifdef H5
return 20
// #endif
}
},
components: {
baseDrawer
},
methods: {
closeDrawer() {
this.$emit('closeDrawer');
},
checkPromotion(item){
if(this.promotions_id.includes(item.id)){
this.promotions_id = this.promotions_id.filter(function (ele){return ele != item.id;});
}else{
this.promotions_id.push(item.id);
}
},
checkLabel(item){
if(this.store_label_id.includes(item.id)){
this.store_label_id = this.store_label_id.filter(function (ele){return ele != item.id;});
}else{
this.store_label_id.push(item.id);
}
},
checkBrand(item){
if(this.brand_id.includes(item.id)){
this.brand_id = this.brand_id.filter(function (ele){return ele != item.id;});
}else{
this.brand_id.push(item.id);
}
},
confirmFilter(){
let data = {
promotions_id: this.promotions_id.join(','),
brand_id: this.brand_id.join(','),
store_label_id: this.store_label_id.join(',')
};
this.$emit('filterChange',data);
},
resetFilter(){
this.promotions_id = [];
this.brand_id = [];
this.store_label_id = [];
}
}
}
</script>
<template>
<view>
<base-drawer mode="right" :visible="visible" background-color="transparent" mask maskClosable
@close="closeDrawer">
<view class="drawer_box bg--w111-fff px-32 h-full">
<scroll-view scroll-y="true" style="height: 100vh;">
<view :style="{height:fixedTop + 'px'}"></view>
<view class="h-80 flex-center fs-34 fw-500 text--w111-333">筛选</view>
<view class="activity_box py-24">
<view v-if="promotionList.length">
<view class="fs-28 text--w111-333 fw-500">商品活动</view>
<view class="grid-column-3 box_gap mt-24">
<view class="h-56 rd-28rpx bg--w111-f5f5f5 flex-center fs-24 text--w111-333"
v-for="item in promotionList" :key="item.id"
:class="{active: promotions_id.includes(item.id)}"
@tap="checkPromotion(item)">
<text class="inline-block w-full line1 px-12 text-center">{{item.desc}}</text>
</view>
</view>
</view>
<view v-if="brandList.length">
<view class="fs-28 text--w111-333 fw-500 mt-24">品牌</view>
<view class="grid-column-3 box_gap mt-24">
<view class="h-56 rd-28rpx bg--w111-f5f5f5 flex-center fs-24 text--w111-333"
v-for="item in brandList" :key="item.id"
:class="{active: brand_id.includes(item.id)}"
@tap="checkBrand(item)">
<text class="inline-block w-full line1 px-12 text-center">{{item.brand_name}}</text>
</view>
</view>
</view>
<view v-if="labelList.length">
<view class="fs-28 text--w111-333 fw-500 mt-24">商品标签</view>
<view class="grid-column-3 box_gap mt-24">
<view class="h-56 rd-28rpx bg--w111-f5f5f5 flex-center fs-24 text--w111-333"
v-for="item in labelList" :key="item.id"
:class="{active: store_label_id.includes(item.id)}"
@tap="checkLabel(item)">
<text class="inline-block w-full line1 px-12 text-center">{{item.label_name}}</text>
</view>
</view>
</view>
</view>
<view class="pb-safe">
<view class="h-112"></view>
</view>
</scroll-view>
<view class="fixed-lb pb-safe w-full">
<view class="px-32 flex-between-center h-112">
<view class="w-296 h-72 rd-40rpx flex-center font-num con_border bg--w111-fff"
@tap="resetFilter()">重置</view>
<view class="w-296 h-72 rd-40rpx flex-center text--w111-fff bg-color" @tap="confirmFilter()">确定</view>
</view>
</view>
</view>
</base-drawer>
</view>
</template>
<style>
.drawer_box {
width: 668rpx;
border-radius: 40rpx 0 0 40rpx;
overflow: auto;
}
.box_gap {
grid-row-gap: 24rpx;
grid-column-gap: 26rpx;
}
.con_border{
border: 1rpx solid var(--view-theme);
}
.active{
border: 1px solid var(--view-theme);
color: var(--view-theme);
background: var(--view-minorColorT);
}
</style>

View File

@@ -0,0 +1,96 @@
<template>
<base-drawer mode="bottom" :maskZIndex="1999" :zIndex="2000" :visible="visible" background-color="transparent" mask maskClosable @close="closeDrawer">
<view class="w-full bg--w111-f5f5f5 rd-t-40rpx py-32">
<view class="text-center fs-32 text--w111-333 fw-500">赠品</view>
<view class="px-20">
<scroll-view class="mt-48 w-full scroll-content" scroll-y="true">
<view class="text--w111-333 fs-28 lh-40rpx">本单可获得以下赠品</view>
<view class="gift-card mt-24 bg--w111-fff rd-16rpx p-16 flex-y-center"
v-for="(item,index) in giveCartInfo" :key="item.id" @tap="goPage(1,'/pages/goods_details/index?id=' + item.productInfo.id)">
<image class="w-116 h-116 rd-16rpx" :src="item.productInfo.attrInfo.image" v-if="item.productInfo.attrInfo"></image>
<image class="w-116 h-116 rd-16rpx" :src="item.productInfo.image" v-else></image>
<view class="flex-1 flex-between-center pl-16">
<view class="w-460">
<view class="w-full line1 fs-28 lh-40rpx">{{item.productInfo.store_name}}</view>
<view class="fs-22 text--w111-999 lh-30rpx mt-12">数量x{{item.cart_num}}</view>
</view>
<text class="iconfont icon-ic_rightarrow fs-24 text--w111-999"></text>
</view>
</view>
<view class="gift-card mt-24 bg--w111-fff rd-16rpx p-16 flex-y-center"
v-for="(item,index) in giveData.give_coupon" :key="index" @tap="goPage(1,'/pages/users/user_coupon/index')">
<view class="w-116 h-116 rd-16rpx flex-center bg--w111-f5f5f5">
<text class="fs-48 gold iconfont icon-a-ic_discount1"></text>
</view>
<view class="flex-1 flex-between-center pl-16">
<view class="w-460">
<view class="w-full line1 fs-28 lh-40rpx">{{item.coupon_title}}</view>
<view class="fs-22 text--w111-999 lh-30rpx mt-12">数量x1</view>
</view>
<text class="iconfont icon-ic_rightarrow fs-24 text--w111-999"></text>
</view>
</view>
<view class="gift-card mt-24 bg--w111-fff rd-16rpx p-16 flex-y-center"
v-if="giveData.give_integral>0"
@tap="goPage(1,'/pages/users/user_integral/index')">
<view class="w-116 h-116 rd-16rpx flex-center bg--w111-f5f5f5">
<text class="fs-48 gold iconfont icon-ic_badge11"></text>
</view>
<view class="flex-1 flex-between-center pl-16">
<view class="w-460">
<view class="w-full line1 fs-28 lh-40rpx">{{giveData.give_integral}}积分</view>
<view class="fs-22 text--w111-999 lh-30rpx mt-12">数量x1</view>
</view>
<text class="iconfont icon-ic_rightarrow fs-24 text--w111-999"></text>
</view>
</view>
</scroll-view>
</view>
<view class="mx-20 pb-safe">
<view class="mt-52 h-72 flex-center rd-36px bg-color fs-26 text--w111-fff" @tap="closeDrawer">确定</view>
</view>
</view>
</base-drawer>
</template>
<script>
import baseDrawer from '@/components/tui-drawer/tui-drawer.vue';
export default {
props:{
visible: {
type: Boolean,
default: false,
},
giveCartInfo:{
type: Array,
default: ()=>[]
},
giveData:{
type: Object,
default: ()=>{}
},
},
components: {
baseDrawer
},
methods:{
closeDrawer() {
this.$emit('closeDrawer');
},
goPage(type,url){
uni.navigateTo({
url
})
}
}
}
</script>
<style>
.gold{
color: #DCA658;
}
.scroll-content{
height: 800rpx;
}
</style>

View File

@@ -0,0 +1,337 @@
<template>
<!-- 选择发票信息下拉列表 -->
<view>
<view :class="{ mask: invShow }" @touchmove.stop.prevent @click="invClose"></view>
<view class="popup" :class="{ on: invShow }" @touchmove.stop.prevent>
<view class="popup-hd">抬头选择<view class="close" @click="invClose"><text class="iconfont icon-ic_close"></text></view>
</view>
<scroll-view class="popup-bd" scroll-y="true">
<radio-group v-if="invList.length" name="inv" @change="invChange">
<template v-for="(item, index) in invList">
<label v-if="item.type === 1 || item.type === 2 && isSpecial" :key="item.id" :class="{ checked: (invChecked || invId) == item.id }" class="acea-row row-middle item">
<text class="iconfont icon-ic_complete"></text>
<radio class="radio" :value="item.id" :checked="item.id === invChecked" />
<view class="text">
<view class="acea-row row-middle type">{{ item.type === 1 ? '普通' : '专用' }}发票抬头-{{ item.header_type === 1 ? '个人' : '企业' }}</view>
<view class="acea-row row-middle text-bottom">
<view class="text-left">
<view class="acea-row row-middle name-wrap">
<view class="name">{{item.name}}</view>
<view v-if="item.is_default" class="default">默认</view>
</view>
<view class="number">{{item.header_type == 1 ? item.drawer_phone : item.duty_number}}</view>
</view>
<navigator v-if="!isOrder" class="navigator acea-row row-center-wrapper" :url="`/pages/users/user_invoice_form/index?from=order_confirm&id=${item.id}&${urlQuery}`"
hover-class="none"><text class="iconfont icon-ic_edit"></text></navigator>
<navigator v-else class="navigator acea-row row-center-wrapper" :url="`/pages/users/user_invoice_form/index?from=order_details&id=${item.id}&order_id=${orderId}`"
hover-class="none"><text class="iconfont icon-ic_edit"></text></navigator>
</view>
</view>
</label>
</template>
</radio-group>
<view v-else class="empty">
<image class="image" :src="imgHost + '/statics/images/noInvoice.png'"></image>
<view>您还没有添加发票信息哟~</view>
</view>
</scroll-view>
<view class="popup-ft">
<button v-if="isOrder && invList.length" class="navigator" plain @click="invSub">确认提交</button>
<navigator v-if="!isOrder" class="button text-center" :url="`/pages/users/user_invoice_form/index?from=order_confirm&${urlQuery}`" hover-class="none">添加新的抬头</navigator>
<navigator v-else class="button text-center" :url="`/pages/users/user_invoice_form/index?order_id=${orderId}&from=order_details`" hover-class="none">添加新的抬头</navigator>
<!-- <button class="button" plain @click="invCancel">不开发票</button> -->
<slot name="buttom"></slot>
</view>
</view>
</view>
</template>
<script>
import {
HTTP_REQUEST_URL
} from '@/config/app';
export default {
data() {
return {
invId: 0,
imgHost: HTTP_REQUEST_URL
}
},
props: {
invShow: {
type: Boolean,
default: false
},
invList: {
type: Array,
default () {
return [];
}
},
invChecked: {
type: String,
default: ''
},
isSpecial: {
type: Boolean,
default: false
},
urlQuery: {
type: String,
default: ''
},
isOrder: {
type: Number,
default: 0
},
orderId: {
type: String,
default: ''
}
},
methods: {
invClose(state) {
this.$emit('inv-close');
},
invChange(e) {
if (this.isOrder) {
this.invId = e.detail.value
} else {
this.$emit('inv-change', e.detail.value);
}
},
invSub() {
this.$emit('inv-change', this.invId || this.invChecked);
},
invCancel() {
this.$emit('inv-cancel');
}
},
}
</script>
<style lang="scss" scoped>
/deep/uni-radio .uni-radio-input {
margin-right: 0;
}
.popup {
position: fixed;
bottom: 0;
left: 0;
z-index: 2000;
width: 100%;
border-top-left-radius: 32rpx;
border-top-right-radius: 32rpx;
background-color: #F5F5F5;
transform: translateY(100%);
transition: 0.3s;
}
.popup.on {
transform: translateY(0);
}
.popup-hd {
position: relative;
height: 108rpx;
font-size: 32rpx;
line-height: 108rpx;
text-align: center;
color: #333333;
.close {
position: absolute;
top: 50%;
right: 32rpx;
width: 36rpx;
height: 36rpx;
border-radius: 18rpx;
margin-top: -16rpx;
background-color: #EEEEEE;
text-align: center;
line-height: 36rpx;
}
.iconfont {
font-size: 24rpx;
color: #999999;
}
}
.popup-bd {
height: 792rpx;
padding: 24rpx 20rpx 8rpx;
box-sizing: border-box;
.item {
position: relative;
border: 1rpx solid #FFFFFF;
border-radius: 24rpx;
margin-bottom: 20rpx;
background-color: #FFFFFF;
overflow: hidden;
&::after {
content: "";
position: absolute;
top: 0;
right: 0;
border: 36rpx solid #FFFFFF;
}
.icon-ic_complete {
position: absolute;
top: 8rpx;
right: 8rpx;
z-index: 2;
font-size: 32rpx;
color: #FFFFFF;
}
&.checked {
border-color: var(--view-theme);
&::after {
border-color: var(--view-theme);
border-bottom-color: transparent;
border-left-color: transparent;
}
}
}
.radio {
display: none;
}
.text {
flex: 1;
min-width: 0;
}
.text-bottom {
position: relative;
padding: 32rpx 24rpx;
&::before {
content: "";
position: absolute;
top: 0;
right: 24rpx;
left: 24rpx;
border-top: 1rpx solid #eee;
}
}
.name-wrap {
display: inline-flex;
max-width: 100%;
}
.name {
flex: 1;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-weight: 500;
font-size: 28rpx;
line-height: 40rpx;
color: #333333;
}
.default {
height: 34rpx;
padding: 0 8rpx;
border-radius: 8rpx;
margin-left: 8rpx;
background-color: #FCEAE9;
font-size: 22rpx;
line-height: 34rpx;
color: var(--view-theme);
}
.email {
margin-top: 16rpx;
font-size: 24rpx;
color: #666666;
}
.number {
margin-top: 12rpx;
font-size: 24rpx;
line-height: 34rpx;
color: #999999;
}
.text-left {
flex: 1;
min-width: 0;
}
.type {
padding: 24rpx;
font-size: 24rpx;
line-height: 34rpx;
color: #333333;
}
.navigator {
width: 56rpx;
height: 56rpx;
border-radius: 50%;
margin-left: 24rpx;
.iconfont {
font-size: 32rpx;
color: #333333;
}
}
}
.popup-ft {
padding: 20rpx 20rpx calc(20rpx + env(safe-area-inset-bottom));
.navigator {
height: 80rpx;
border-radius: 40rpx;
background-color: var(--view-theme);
font-size: 28rpx;
line-height: 80rpx;
text-align: center;
color: #FFFFFF;
border: none;
.iconfont {
margin-right: 14rpx;
font-size: 30rpx;
}
}
.button {
height: 80rpx;
border: 1rpx solid var(--view-theme);
border-radius: 40rpx;
margin-top: 24rpx;
font-size: 28rpx;
line-height: 80rpx;
color: var(--view-theme);
}
}
.empty {
padding-top: 58rpx;
font-size: 26rpx;
text-align: center;
color: #999999;
.image {
width: 400rpx;
height: 260rpx;
margin-bottom: 20rpx;
}
}
.mask {
z-index: 1999;
}
</style>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,250 @@
@charset "UTF-8";
/* 颜色变量 */
/* 行为相关颜色 */
/* 文字基本颜色 */
/* 背景颜色 */
/* 边框颜色 */
/* 尺寸变量 */
/* 文字尺寸 */
/* 图片尺寸 */
/* Border Radius */
/* 水平间距 */
/* 垂直间距 */
/* 透明度 */
/* 文章场景相关 */
li {
list-style: none;
}
ul,
li {
margin: 0;
padding: 0;
}
.lottery_container {
width: 100%;
height: 100%;
}
.grid_wrap {
width: 100%;
height: 100%;
position: relative;
}
.grid_wrap .lottery_wrap_border {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.grid_wrap .lottery_wrap_border ul {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
}
.grid_wrap .lottery_wrap_border ul li {
border-radius: 50%;
width: 17upx;
height: 17upx;
background-color: #bce0e9;
}
.grid_wrap .lottery_wrap_border ul li:nth-child(even) {
width: 24upx;
height: 24upx;
background-color: #f5fbc8;
}
.grid_wrap .lottery_wrap_border ul:nth-child(odd) {
width: 100%;
height: 35upx;
left: 0;
right: 0;
flex-direction: row;
}
.grid_wrap .lottery_wrap_border ul:nth-child(odd) li {
margin: 0 10upx;
}
.grid_wrap .lottery_wrap_border ul:nth-child(even) {
width: 35upx;
height: 100%;
top: 0;
bottom: 0;
flex-direction: column;
}
.grid_wrap .lottery_wrap_border ul:nth-child(even) li {
margin: 10upx 0;
}
.grid_wrap .lottery_wrap_border ul:nth-child(3) {
bottom: 0;
}
.grid_wrap .lottery_wrap_border ul:nth-child(4) {
right: 0;
}
.grid_wrap .lottery_wrap_border ul:nth-child(1) li:nth-child(odd),
.grid_wrap .lottery_wrap_border ul:nth-child(4) li:nth-child(odd) {
animation: blink_large 1s linear infinite;
}
.grid_wrap .lottery_wrap_border ul:nth-child(1) li:nth-child(even),
.grid_wrap .lottery_wrap_border ul:nth-child(4) li:nth-child(even) {
animation: blink_small 1s linear infinite;
}
.grid_wrap .lottery_wrap_border ul:nth-child(3) li:nth-child(even),
.grid_wrap .lottery_wrap_border ul:nth-child(2) li:nth-child(even) {
width: 17upx;
height: 17upx;
background-color: #bce0e9;
animation: blink_large 1s linear infinite;
}
.grid_wrap .lottery_wrap_border ul:nth-child(3) li:nth-child(odd),
.grid_wrap .lottery_wrap_border ul:nth-child(2) li:nth-child(odd) {
width: 24upx;
height: 24upx;
background-color: #f5fbc8;
animation: blink_small 1s linear infinite;
}
.grid_wrap .lottery_wrap {
width: 100%;
height: 100%;
font-size: 14upx;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 1;
}
.grid_wrap .lottery_wrap .lottery_grid {
width: 100%;
height: 424rpx;
position: relative;
}
.grid_wrap .lottery_wrap .lottery_grid li {
width: 32%;
height: 130rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
float: left;
position: absolute;
border-radius: 16rpx;
color: #E74435;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 20upx;
/* margin: 4px; */
padding: 4px;
background: #FEF6E7;
}
.grid_wrap .lottery_wrap .lottery_grid li .in_line {
border-radius: 12rpx;
width: 100%;
height: 130rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
padding: 0 4rpx;
}
.grid_wrap .lottery_wrap .lottery_grid li .grid_img {
width: 72rpx;
height: 72rpx;
}
.grid_wrap .lottery_wrap .lottery_grid .active {
background: rgba(255,125,0,0.2) !important;
color: #E93323;
}
.grid_wrap .lottery_wrap .lottery_grid li:nth-of-type(1) {
left: 1%;
top: 1%;
}
.grid_wrap .lottery_wrap .lottery_grid li:nth-of-type(2) {
left: 34%;
top: 1%;
}
.grid_wrap .lottery_wrap .lottery_grid li:nth-of-type(3) {
left: 67%;
top: 1%;
}
.grid_wrap .lottery_wrap .lottery_grid li:nth-of-type(4) {
left: 67%;
top: 34%;
}
.grid_wrap .lottery_wrap .lottery_grid li:nth-of-type(5) {
left: 67%;
top: 67%;
}
.grid_wrap .lottery_wrap .lottery_grid li:nth-of-type(6) {
left: 34%;
top: 67%;
}
.grid_wrap .lottery_wrap .lottery_grid li:nth-of-type(7) {
left: 1%;
top: 67%;
}
.grid_wrap .lottery_wrap .lottery_grid li:nth-of-type(8) {
left: 1%;
top: 34%;
}
.grid_wrap .lottery_wrap .lottery_grid li:nth-of-type(9) {
left: 34%;
top: 34%;
cursor: pointer;
color: #ffffff;
background: linear-gradient(90deg, var(--view-gradient) 0, var(--view-theme) 100%);
}
@keyframes blink_large {
to {
width: 24upx;
height: 24upx;
background-color: #f5fbc8;
}
}
@keyframes blink_small {
to {
width: 17upx;
height: 17upx;
background-color: #bce0e9;
}
}
/*# sourceMappingURL=SJ-LotteryDraw.css.map */

View File

@@ -0,0 +1,159 @@
<template>
<view class="lottery_container">
<view class="grid_wrap">
<view class="lottery_wrap">
<view class="lottery_grid">
<view v-for="(item, index) in prizeData" :key="index" :class="{ active: current_index == index && index != 8 }" class="item" @click="luck_draw">
<view :class="{in_line:index != 8 }" class="lottery-msg">
<image v-if="index != 8" class="grid_img" mode='aspectFit' :src="item.image" alt="" />
<text v-if="index !=8" class="name line1">
{{ index == 8 ? '抽奖' : item.name }}
</text>
<view v-else class="flex-col flex-center lottery-click">
<!-- <text class="fs-36">立即抽奖</text> -->
<text class="fs-36">{{lotteryNum}}次</text>
<text class="fs-20 lh-28rpx">抽奖机会</text>
</view>
</view>
</view>
</view>
</view>
<!-- <view class="lottery_wrap_border">
<ul v-for="(item, index) in 4" :key="index">
<li v-for="(item, index) in 12" :key="index"></li>
</ul>
</view> -->
</view>
</view>
</template>
<script>
import LotteryDraw from './js/grids_lottery.js';
export default {
data() {
return {
current_index: -1,
lotteryBtn: true
};
},
props: {
prizeData: {
type: Array,
default: function() {
return []
}
},
lotteryType: {
type: Number,
default: 0
},
datatime: {
type: Number,
default: 0
},
lotteryNum: {
type: Number,
default: 0
},
isRotating: {
type: Boolean,
default: false
},
winingIndex: {
type: Number,
default: 0
},
},
watch: {
isRotating(newValue, oldValue) {
let that = this;
if (newValue) {
// let lottery_draw_param = res;
let win = new LotteryDraw({
domData: that.prizeData,
// ...lottery_draw_param
startIndex: 3, //开始抽奖位置,从0开始
totalCount: 3, //一共要转的圈数
winingIndex: this.winingIndex, //中奖的位置,从0开始
speed: 100 //抽奖动画的速度 [数字越大越慢,默认100]
},
function(index, count) {
that.current_index = index;
if (that.winingIndex == index && 3 ==
count) {
that.lotteryBtn = true
that.$emit('luck_draw_finish', that.prizeData[index])
}
}
);
}
}
},
mounted() {},
methods: {
luck_draw(event) {
let timestamp = Date.parse(new Date()) / 1000;
if (this.lotteryType == 1 && parseInt(timestamp) > parseInt(this.datatime)) {
return this.$util.Tips({
title: '您抽奖的有效时间已到期'
}, function() {
uni.switchTab({
url: '/pages/index/index'
})
});
}
let index = event.currentTarget.dataset.index;
if (this.lotteryBtn && index == 8) {
this.lotteryBtn = false
} else {
return
}
let that = this;
if (index == 8) {
// 点击抽奖之后知道获奖位置,修改父组件中lottery_draw_param的值
this.$emit('get_winingIndex', function(res) {
let lottery_draw_param = res;
let win = new LotteryDraw({
domData: that.prizeData,
...lottery_draw_param
},
function(index, count) {
that.current_index = index;
if (lottery_draw_param.winingIndex == index && lottery_draw_param.totalCount ==
count) {
that.lotteryBtn = true
that.$emit('luck_draw_finish', that.prizeData[index])
}
}
);
});
}
}
}
};
</script>
<style scoped lang="scss">
@import './css/grids_lottery.css';
.lottery-msg {
width: 100%;
height: 100%;
padding: 0 4rpx;
.name {}
}
.lottery-click {
width: 100%;
height: 100%;
}
.lottery_grid .name {
width: 100%;
text-align: center;
}
</style>

View File

@@ -0,0 +1,47 @@
function LotteryDraw(obj, callback) {
this.timer = null; //计时器
this.startIndex = obj.startIndex-1 || 0; //从第几个位置开始抽奖 [默认为零]
this.count = 0; //计数,跑的圈数
this.winingIndex = obj.winingIndex || 0;//获奖的位置
this.totalCount = obj.totalCount || 6;//抽奖跑的圈数
this.speed = obj.speed || 100;
this.domData=obj.domData;
this.rollFn();
this.callback = callback;
}
LotteryDraw.prototype = {
rollFn: function() {
var that = this;
// console.log(`获奖位置:${this.winingIndex}`)
// 活动index值增加,即移动到下一个格子
this.startIndex++;
//startIndex是最后一个时一圈走完,重新开始
if (this.startIndex >= this.domData.length - 1) {
this.startIndex = 0;
this.count++;
}
// 当跑的圈数等于设置的圈数,且活动的index值是奖品的位置时停止
if (this.count >= this.totalCount && this.startIndex === this.winingIndex) {
if (typeof this.callback === 'function') {
setTimeout(function() {
that.callback(that.startIndex,that.count); //执行回调函数,抽奖完成的相关操作
}, 400);
}
clearInterval(this.timer);
}else { //重新开始一圈
if (this.count >= this.totalCount - 1) {
this.speed += 30;
}
this.timer = setTimeout(function() {
that.callback(that.startIndex,that.count);
that.rollFn();
}, this.speed);
}
}
}
module.exports = LotteryDraw;

View File

@@ -0,0 +1,119 @@
<template>
<view class="lottery_container">
<view class="grid_wrap">
<view class="lottery_wrap">
<ul class="lottery_grid">
<li v-for="(item, index) in prizeData" :class="{ active: current_index == index && index != 8 }"
:key="index" @click="luck_draw" :data-index="index">
<view :class="{in_line:index != 8 }" class="lottery-msg">
<image v-if="index != 8" class="grid_img" mode='aspectFit' :src="item.image" alt="" />
<text v-if="index !=8" class="name">
{{ index == 8 ? '抽奖' : item.name }}
</text>
<view v-else class="flex-col flex-center lottery-click">
<image src="../../static/lottery_text.png" class="w-140 h-32 block"></image>
<text class="fs-20 lh-28rpx pt-6">剩余 {{lotteryNum}} 次机会</text>
</view>
</view>
</li>
</ul>
</view>
</view>
</view>
</template>
<script>
import LotteryDraw from './js/grids_lottery.js';
export default {
data() {
return {
current_index: -1,
lotteryBtn: true
};
},
props: {
prizeData: {
type: Array,
default: function() {
return []
}
},
lotteryType: {
type: Number,
default: 0
},
datatime: {
type: Number,
default: 0
},
lotteryNum:{
type: Number,
default: 0
}
},
onLoad() {
},
methods: {
luck_draw(event) {
console.log(123456);
let timestamp = Date.parse(new Date())/1000;
if(this.lotteryType == 1 && parseInt(timestamp)>parseInt(this.datatime)){
return this.$util.Tips({
title: '您抽奖的有效时间已到期'
},function(){
uni.switchTab({
url: '/pages/index/index'
})
});
}
let index = event.currentTarget.dataset.index;
if (this.lotteryBtn && index == 8) {
this.lotteryBtn = false
} else {
return
}
let that = this;
if (index == 8) {
// 点击抽奖之后知道获奖位置,修改父组件中lottery_draw_param的值
this.$emit('get_winingIndex', function(res) {
let lottery_draw_param = res;
let win = new LotteryDraw({
domData: that.prizeData,
...lottery_draw_param
},
function(index, count) {
that.current_index = index;
if (lottery_draw_param.winingIndex == index && lottery_draw_param.totalCount ==
count) {
that.lotteryBtn = true
that.$emit('luck_draw_finish', that.prizeData[index])
}
}
);
});
}
}
}
};
</script>
<style scoped lang="scss">
@import './css/pay_lottery.css';
.lottery-msg {
width: 100%;
height: 100%;
padding: 0 4rpx;
.name {}
}
.lottery-click {
width: 100%;
height: 100%;
}
</style>

View File

@@ -0,0 +1,139 @@
<template>
<!-- 抽奖结果弹窗 -->
<view class="aleart flex-col flex-center" v-if="aleartStatus" @touchmove.stop.prevent>
<image :src="alData.image" class="w-180 h-180"></image>
<view class="fs-34 font-red fw-500 lh-48rpx mt-24"
:class="theme ? 'font-num' : 'font-red'"
>{{alData.type > 1 ? '恭喜你获得' : alData.name}}</view>
<view class="fs-26 text--w111-333 lh-36rpx mt-24">{{aleartData.msg}}</view>
<view class="btn flex-center fs-28 text--w111-fff mt-32" @tap="posterImageClose"
:class="theme ? 'bg-gradient1' : 'bg-red-g'"
>{{alData.type > 1 ? '立即领取' : '我知道了'}}</view>
<text class="close iconfont icon-ic_close1" @click="posterImageClose"></text>
<slot name="bottom"></slot>
</view>
</template>
<script>
import { openReceivedSubscribe } from "@/utils/SubscribeMessage.js"
export default {
data() {
return {
aleartData: {}
}
},
props: {
aleartType: {
type: Number,
default:0
},
alData: {
type: Object,
default:()=>{}
},
aleartStatus: {
type: Boolean,
default: false
},
theme:{
type: Boolean,
default: false
}
},
watch: {
aleartType(type) {
if (type === 1) {
this.aleartData = {
title: '暂无抽奖资格',
msg: `1、您未关注公众号
2、您未获得VIP权限,获取VIP途径:
(1)购买过打通版的用户可在会员群联系官方客服开通
(2)官方小程序商城购买CRMEB打通版、企业版后自动开通`,
btn: '我知道了'
}
} else if (type === 2) {
this.aleartData = {
title: '抽奖结果',
img: this.alData.image,
msg: this.alData.prompt,
btn: '好的',
type: this.alData.type
}
}
},
aleartStatus(status) {
if (!status) {
this.aleartData = {}
}
}
},
methods: {
//隐藏弹窗
posterImageClose(type) {
if(this.alData.type == 4){
// #ifdef MP-WEIXIN
uni.showLoading({
title: '正在加载'
});
openReceivedSubscribe().then(res=>{
uni.hideLoading();
uni.navigateTo({
url: '/pages/goods/lottery/grids/record'
})
}).catch(err=>{
uni.hideLoading();
uni.navigateTo({
url: '/pages/goods/lottery/grids/record'
})
})
// #endif
// #ifdef H5 || APP-PLUS
uni.navigateTo({
url: '/pages/goods/lottery/grids/record'
})
// #endif
}
this.$emit("close", false)
},
}
}
</script>
<style lang="scss" scoped>
.aleart {
width: 480rpx;
height: 544rpx;
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
z-index: 9999;
background-color: #fff;
border-radius: 48rpx;
background-image:url('../../static/alert_modal_bg.png');
background-size:100%;
background-repeat: no-repeat;
}
.aleart .close{
position: absolute;
left:50%;
bottom:-100rpx;
transform: translateX(-50%);
color: #fff;
font-size:50rpx;
}
.font-red{
color: #e93323;
}
.btn{
width: 280rpx;
height: 80rpx;
border-radius: 50rpx;
color: #fff;
}
.bg-red-g{
background: linear-gradient(90deg, #FF7931 0%, #E93323 100%);
}
</style>

View File

@@ -0,0 +1,81 @@
<template>
<view>
<base-drawer mode="bottom" :visible="refundData.show" background-color="transparent" mask maskClosable @close="closeDrawer">
<view class="w-full bg--w111-fff rd-t-40rpx py-32 relative">
<view class="text-center fs-32 text--w111-333 fw-500">选择退款原因</view>
<view class="close flex-center" @tap='closeDrawer'>
<text class="iconfont icon-ic_close fs-24 text--w111-999"></text>
</view>
<view class="mt-48 px-24 scroll-content">
<view class="list">
<view class="cell flex-between-center"
v-for="(item,index) in refundData.RefundArray" :key='index'
@click="tapSelect(index)">
<view class="fs-28">{{item}}</view>
<text v-if="index == current" class="iconfont icon-a-ic_CompleteSelect fs-36 font-num"></text>
<text v-else class="iconfont icon-ic_unselect fs-36 text--w111-ccc"></text>
</view>
</view>
<view class="pb-safe">
<view class="mt-52 w-full h-72 flex-center rd-36px bg-color fs-26 text--w111-fff" @tap="determine">确定</view>
</view>
</view>
</view>
</base-drawer>
</view>
</template>
<script>
import baseDrawer from '@/components/tui-drawer/tui-drawer.vue';
export default {
props: {
refundData: {
type: Object,
default: function() {
return {
show: false,
RefundArray: []
};
}
},
},
components: {
baseDrawer
},
data() {
return {
current:0
};
},
methods: {
closeDrawer: function() {
this.$emit('changeClose');
},
tapSelect(index){
this.current = index;
},
determine(){
this.$emit('selectInfo',this.current);
}
}
}
</script>
<style lang="scss" scoped>
.scroll-content{
max-height: 800rpx;
overflow-y: auto;
}
.cell ~ .cell{
margin-top: 64rpx;
}
.close{
position: absolute;
right: 32rpx;
top: 36rpx;
width: 36rpx;
height: 36rpx;
border-radius: 50%;
background-color: #eee;
}
</style>

View File

@@ -0,0 +1,74 @@
<template>
<view class="gift-message-card">
<view class="message-header">
<image class="avatar" :src="avatar" mode="aspectFill"></image>
<text class="gift-text">{{ nickname }} 赠您一份礼物,请查收!</text>
</view>
<view class="divider"></view>
<view class="message-content">
<text class="message-text">{{
gift_mark || "天天开心,所得皆所愿~"
}}</text>
</view>
</view>
</template>
<script>
export default {
name: "SendGiftMarkCard",
props: {
avatar: {
type: String,
default: "",
},
nickname: {
type: String,
default: "匿名",
},
gift_mark: {
type: String,
default: "",
},
},
};
</script>
<style lang="scss" scoped>
.gift-message-card {
background-color: #ffffff;
border-radius: 24rpx;
padding: 32rpx 24rpx;
.message-header {
display: flex;
align-items: center;
margin-bottom: 20rpx;
.avatar {
width: 36rpx;
height: 36rpx;
border-radius: 50%;
margin-right: 16rpx;
}
.gift-text {
font-size: 28rpx;
color: #ae5a2a;
font-weight: 400;
}
}
.divider {
height: 1rpx;
background-color: #f5f5f5;
margin: 20rpx 0;
}
.message-content {
.message-text {
font-size: 28rpx;
color: #333;
line-height: 1.5;
}
}
}
</style>

View File

@@ -0,0 +1,429 @@
<template>
<view class="aleart" v-if="aleartStatus" :style="'background-image: url(' + giftbag + ');'">
<template v-if="!posterImageStatus">
<text class="iconfont icon-ic_close1 close" @click="posterImageClose"></text>
<view class="from">赠送给好友一份礼物</view>
<view class="message line2">{{ giftData.message }}</view>
<view class="aleart-body">
<image class="goods-img" :src="giftData.image" mode=""></image>
</view>
<view class="title line1">
{{ giftData.title }}
</view>
<!-- #ifdef H5 -->
<view class="btn" @tap="copyLink">复制礼物链接</view>
<!-- #endif -->
<!-- #ifndef H5 -->
<button class="btn" open-type="share" hover-class="none">送给好友</button>
<!-- #endif -->
<view class="btn-clear" @click="getPoster()">保存海报</view>
</template>
<template v-if="posterImageStatus">
<text class="iconfont icon-ic_close1 close" @click="posterImageClose"></text>
<image class="poster-img" :src="posterImage"></image>
<!-- #ifdef H5 -->
<view class="keep">长按图片可以保存到手机</view>
<!-- #endif -->
</template>
<!-- #ifdef H5 || APP-PLUS -->
<zb-code
ref="qrcode"
:show="codeShow"
:cid="cid"
:val="codeVal"
:size="size"
:unit="unit"
:background="background"
:foreground="foreground"
:pdground="pdground"
:icon="codeIcon"
:iconSize="iconsize"
:onval="onval"
:loadMake="loadMake"
@result="qrR"
/>
<!-- #endif -->
</view>
</template>
<script>
import { HTTP_REQUEST_URL } from '@/config/app';
export default {
data() {
return {
aleartData: {},
bag: HTTP_REQUEST_URL + '/statics/images/canvas-bag.png',
giftBorder: HTTP_REQUEST_URL + '/statics/images/gift-border.png',
giftbag: HTTP_REQUEST_URL + '/statics/images/gift-bag.png',
//二维码参数
codeShow: false,
cid: '1',
codeVal: '', // 要生成的二维码值
size: 200, // 二维码大小
unit: 'upx', // 单位
background: '#FFF', // 背景色
foreground: '#000', // 前景色
pdground: '#000', // 角标色
codeIcon: '', // 二维码图标
iconsize: 40, // 二维码图标大小
lv: 3, // 二维码容错级别 , 一般不用设置,默认就行
onval: true, // val值变化时自动重新生成二维码
loadMake: true, // 组件加载完成后自动生成二维码
PromotionCode: '',
posterImageStatus: false,
posterImage: ''
};
},
props: {
giftData: {
type: Object
},
aleartStatus: {
type: Boolean,
default: false
}
},
watch: {
aleartStatus(status) {
if (!status) {
this.aleartData = {};
} else {
// #ifdef H5
this.codeVal = window.location.origin + '/pages/goods/receive_gift/index?id=' + this.giftData.id + '&spid=' + this.$store.state.app.uid;
// #endif
// #ifdef APP-PLUS
this.codeVal = HTTP_REQUEST_URL + '/pages/goods/receive_gift/index?id=' + this.giftData.id + '&spid=' + this.$store.state.app.uid;
// #endif
// #ifdef MP
this.PromotionCode = this.giftData.code;
// #endif
}
}
},
methods: {
copyLink() {
uni.setClipboardData({
data: this.codeVal,
success: () => {
this.$util.Tips({
title: '复制成功'
});
}
});
},
qrR(res) {
// #ifdef H5
if (!this.$wechat.isWeixin() || this.shareQrcode != '1') {
this.PromotionCode = res;
}
// #endif
// #ifdef APP-PLUS
this.PromotionCode = res;
// #endif
},
//隐藏弹窗
posterImageClose() {
this.posterImageStatus = false;
this.$emit('close', false);
},
drawPoster(loadedImages, name, store_name) {
// 截断标题函数
function truncateTitle(title, maxLength) {
if (title.length > maxLength) {
return title.substring(0, maxLength) + '...';
}
return title;
}
// 获取canvas上下文
const ctx = uni.createCanvasContext('posterCanvas');
return new Promise(async (resolve, reject) => {
uni.getImageInfo({
src: loadedImages[0],
success: (res) => {
// 海报尺寸
const posterWidth = 375;
const posterHeight = 579;
// const posterWidth = res.width / 2;
// const posterHeight = res.height / 2;
// 绘制背景图
ctx.drawImage(loadedImages[0], 0, 0, posterWidth, posterHeight);
ctx.save();
// 头像和标题的布局
const avatarSize = 22; // 头像尺寸
const nickname = name; // 昵称
const title = '送你一份礼物'; // 标题文字
const titleFontSize = 14; // 标题字号
const nicknameFontSize = 14; // 昵称字号
const padding = 10; // 元素之间的间距
// 计算标题宽度
ctx.setFontSize(titleFontSize);
const titleWidth = ctx.measureText(title).width;
const nicknameWidth = ctx.measureText(nickname).width;
// 计算头像和标题的总宽度
const totalWidth = avatarSize + padding + nicknameWidth + padding + titleWidth;
// 计算起始绘制位置(水平居中)
const startX = (posterWidth - totalWidth) / 2;
const startY = 47; // 距离顶部的距离
// 绘制头像
// ctx.drawImage(loadedImages[3], startX, startY, avatarSize, avatarSize);
const avatarX = startX + avatarSize / 2; // 头像中心点 X
const avatarY = startY + avatarSize / 2; // 头像中心点 Y
ctx.save(); // 保存画布状态
ctx.beginPath();
ctx.arc(avatarX, avatarY, avatarSize / 2, 0, Math.PI * 2); // 绘制圆形路径
ctx.clip(); // 裁剪圆形区域
ctx.drawImage(loadedImages[3], startX, startY, avatarSize, avatarSize); // 绘制头像
ctx.restore(); // 恢复画布状态
// 绘制昵称
ctx.setFontSize(nicknameFontSize);
ctx.setTextAlign('left');
ctx.fillText(nickname, startX + avatarSize + padding, startY + avatarSize - 5); // 调整文字垂直居中
// 绘制标题
ctx.setFontSize(titleFontSize);
ctx.fillText(title, startX + avatarSize + padding + nicknameWidth + padding, startY + avatarSize - 5);
// 商品图尺寸
const productImageSize = 225; // 商品图尺寸为 225px x 225px
// 绘制商品图边框
const productBorderX = (posterWidth - productImageSize) / 2; // 水平居中
const productBorderY = startY + avatarSize + 31; // 距离头像和标题的间距
ctx.drawImage(loadedImages[1], productBorderX, productBorderY, productImageSize, productImageSize);
// 绘制商品图
const productImagePadding = 10; // 商品图与边框的内边距
const productImageX = productBorderX + productImagePadding;
const productImageY = productBorderY + productImagePadding + 11;
const productImageInnerSize = productImageSize - 2 * productImagePadding; // 商品图实际绘制尺寸
ctx.drawImage(loadedImages[2], productImageX, productImageY, productImageInnerSize, productImageInnerSize - 10);
// 绘制商品标题
const productTitle = store_name;
const maxTitleLength = 20; // 标题最大长度
const truncatedTitle = truncateTitle(productTitle, maxTitleLength); // 截断标题
ctx.setFontSize(14);
ctx.setTextAlign('center');
ctx.fillText(truncatedTitle, posterWidth / 2, productBorderY + productImageSize + 26);
// 绘制分享二维码
const qrCodeSize = 100;
const qrCodeX = (posterWidth - qrCodeSize) / 2;
const qrCodeY = productBorderY + productImageSize + 63; // 距离商品标题的间距
ctx.drawImage(loadedImages[4], qrCodeX, qrCodeY, qrCodeSize, qrCodeSize);
// 绘制完成
ctx.draw(false, () => {
// 生成海报图片
uni.canvasToTempFilePath({
canvasId: 'posterCanvas',
width: posterWidth,
height: posterHeight,
success: (res) => {
resolve(res.tempFilePath);
},
fail: (err) => {
reject(err);
}
});
});
}
});
});
},
loadImage(src) {
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = 'anonymous'; // 允许跨域
img.src = src;
img.onload = () => {
resolve(img);
};
img.onerror = (err) => reject(err);
});
},
share() {
this.$emit('shareH5');
},
getPoster() {
let images = [this.bag, this.giftBorder, this.giftData.image, this.giftData.avatar, this.PromotionCode];
let postImg = ['', '', '', '', ''];
// #ifdef MP
for (let i = 0; i < images.length; i++) {
uni.downloadFile({
url: images[i],
success: (res) => {
if (res.statusCode == 200) {
postImg[i] = res.tempFilePath;
}
const allNotEmpty = postImg.every((item) => item !== '');
if (allNotEmpty) this.goPoster(postImg);
},
fail: function () {
this.$set(this, 'PromotionCode', '');
}
});
}
// #endif
// #ifndef MP
this.goPoster(images);
// #endif
},
goPoster(postImg) {
this.drawPoster(postImg, this.giftData.nickname, this.giftData.title)
.then((posterPath) => {
// #ifdef APP-PLUS || MP
this.savePosterPathMp(posterPath);
// #endif
// #ifdef H5
this.posterImage = posterPath;
this.posterImageStatus = true;
// #endif
})
.catch((err) => {
console.error('海报生成失败:', err);
});
},
// #ifdef APP-PLUS || MP
savePosterPathMp(url) {
let that = this;
uni.saveImageToPhotosAlbum({
filePath: url,
success: function (res) {
that.$util.Tips({
title: '保存成功',
icon: 'success'
});
},
fail: function (res) {
that.$util.Tips({
title: '保存失败'
});
}
});
},
// #endif
savePic(url) {
var a = document.createElement('a'); // 生成一个a元素
a.download = 'Gift'; // 设置图片名称
a.style.display = 'none';
a.href = url; // 将生成的URL设置为a.href属性
document.body.appendChild(a); // 将a标签追加到文档对象中
a.click(); // 触发a的单击事件
a.remove(); // 一次性的,用完就删除a标签
}
}
};
</script>
<style lang="scss" scoped>
.aleart {
width: 600rpx;
height: 980rpx;
position: fixed;
left: 50%;
transform: translateX(-50%);
z-index: 200;
top: 50%;
margin-top: -490rpx;
background-color: #fff;
border-radius: 32rpx;
background-size: 100% 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
/* 动画设置 */
animation: scaleUp 0.3s ease-out;
.poster-img {
width: 100%;
height: 100%;
border-radius: 32rpx;
}
.from {
font-size: 28rpx;
font-weight: 500;
color: #333333;
margin-bottom: 16rpx;
}
.message {
max-width: 70%;
font-weight: 400;
font-size: 26rpx;
color: #999999;
margin-bottom: 42rpx;
}
.aleart-body {
display: flex;
align-items: center;
justify-content: center;
width: 396rpx;
height: 419rpx;
background-image: url('../../static/gift-border.png');
background-size: 100% 100%;
margin-bottom: 32rpx;
.goods-img {
width: 360rpx;
height: 360rpx;
margin-top: 24rpx;
}
}
.title {
max-width: 80%;
font-weight: 400;
font-size: 28rpx;
color: #333333;
margin-bottom: 52rpx;
text-align: center;
}
.btn,
.btn-clear {
width: 396rpx;
height: 80rpx;
line-height: 80rpx;
border-radius: 20px;
text-align: center;
font-size: 28rpx;
}
.btn {
color: #fff;
background: linear-gradient(90deg, #ff7931 0%, #e93323 100%);
}
.btn-clear {
margin-top: 20rpx;
color: #e93323;
border: 1px solid #e93323;
}
.keep {
font-size: 24rpx;
font-weight: bold;
color: rgba(255, 255, 255, 0.7);
position: fixed;
right: calc(50% - 130rpx);
bottom: -45rpx;
display: block;
}
.close {
font-size: 50rpx;
color: #fff;
position: fixed;
right: calc(50% - 23rpx);
bottom: -110rpx;
display: block;
}
}
@keyframes scaleUp {
from {
transform: translateX(-50%) scale(0.5);
opacity: 0; /* 可选:淡入效果 */
}
to {
transform: translateX(-50%) scale(1);
opacity: 1;
}
}
</style>

View File

@@ -0,0 +1,101 @@
<template>
<view class="bg--w111-fff rd-16rpx pt-32 pl-24 pr-24 pb-32 flex-between-center">
<view v-for="(item,index) in list" :key="index" class="item">
<view class="h-32 flex-x-center item relative" >
<view class="iconfont fs-32 text--w111-999" :class="index <= indexActive ? 'icon-a-ic_CompleteSelect' : 'icon-ic-complete1'"></view>
<text class="line"
:style="{'width': lineWidth + 'rpx','right': lineRight}"
:class="index < indexActive ? 'bg-color' : ''"
></text>
</view>
<view class="fs-22 text--w111-999 lh-30rpx mt-16" :class="{active:index <= indexActive}">{{item}}</view>
</view>
</view>
</template>
<script>
export default {
props: {
type: {
type: Number,
default: 0
},
applyType: {
type: Number,
default: 0
}
},
data() {
return {}
},
computed: {
list() {
// 步骤条全部选中
if(this.type == -1){
return ['提交申请', '用户已撤销', '退款完成']
}else if(this.type == 3){
return ['提交申请', '商家已拒绝', '退款失败']
} else if(this.type == 6 && this.applyType == 4){
return ['提交申请', '平台强制退款', '退款完成']
}else if([0,6].includes(this.type) && this.applyType == 1){
return ['提交申请', '商家审核', '退款完成']
}else if([0,4,5,6].includes(this.type) && this.applyType == 2){
return ['提交申请', '商家审核','商品寄回', '退款完成']
}else if([0,4,5,6].includes(this.type) && this.applyType == 3){
return ['提交申请', '商家审核','商家收货', '退款完成']
}else {
return ['提交申请', '商家审核', '退款完成']
}
},
indexActive(){
if(this.type == -1){
return 2
}else if(this.type == 3){
return 2
} else if(this.type == 6 && this.applyType == 4){
return 2
}else if(this.applyType == 1){
if([0,1].includes(this.type)){
return 0
}else{
return 2
}
}else if([2,3].includes(this.applyType)){
if(this.type == 0){
return 0
}else if(this.type == 6){
return 3
}else{
return 1
}
}
},
lineWidth(){
if(this.list.length == 4){
return 132
}else{
return 230
}
},
lineRight(){
return '-' + (this.lineWidth - 14) + 'rpx'
}
},
}
</script>
<style lang="scss">
.line{
height:4rpx;
background: #f5f5f5;
position: absolute;
top:16rpx;
}
.item:last-child .line{
display: none;
}
.icon-a-ic_CompleteSelect{
color: var(--view-theme);
}
.active{
color: #333;
}
</style>

View File

@@ -0,0 +1,127 @@
<template>
<view class="modal_container" v-if="visible" @touchmove.stop.prevent>
<view class="modal_box relative">
<view class="h-172 flex-col flex-center">
<view class="fs-32 lh-44rpx fw-500">核销信息</view>
<view class="fs-26 lh-36rpx mt-28" v-if="productType == 4">已核销 {{writeOff}} / 需要核销 {{writeTimes}}</view>
</view>
<view class="mt-52 flex-col flex-center">
<view class="qrcode flex-center">
<view class="qrcode_content">
<!-- #ifdef MP -->
<image :src="qrc" class="image"></image>
<!-- #endif -->
<!-- #ifdef H5 -->
<image v-if="$wechat.isWeixin()" :src="qrc" class="image"></image>
<w-qrcode v-else :options="qrcode"></w-qrcode>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<w-qrcode :options="qrcode"></w-qrcode>
<!-- #endif -->
</view>
</view>
<view class="bg-primary-light qrocode-num rd-16rpx flex-center fs-32 fw-500 font-color mt-48">{{verifyCode}}</view>
<view class="mt-24 text--w111-999 fs-24" v-if="writeDay">核销时间:{{writeDay}}</view>
</view>
<text class="iconfont icon-ic_close1 close fs-48 text--w111-fff"></text>
</view>
<view class="mask z-90" @click="closeModal"></view>
</view>
</template>
<script>
export default {
props:{
visible: {
type: Boolean,
default: false,
},
qrcode:{
type:Object,
default: ()=>{}
},
verifyCode:{
type: String,
default:""
},
writeDay:{
type: String,
default:""
},
writeOff:{
type: [String, Number],
default: 0
},
writeTimes:{
type: [String, Number],
default: 0
},
productType:{
type: Number,
default: 0
},
qrc:{
type: String,
default:""
},
},
methods:{
moveHandle(){
return false
},
closeModal(){
this.$emit('closeModal');
}
}
}
</script>
<style>
.modal_box{
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
z-index: 3000;
width:600rpx;
height:906rpx;
background:#fff;
border-radius:32rpx;
-webkit-mask: radial-gradient(circle at 14rpx 172rpx, transparent 14rpx, red 0) -14rpx;
}
.h-172{
height:172rpx;
border-bottom: 1px dashed #ccc;
}
.z-90{
z-index:2999;
}
.qrcode{
width:440rpx;
height:440rpx;
background-image: url('../../static/qrcode_bg.png');
background-size:100%;
background-repeat: no-repeat;
}
.qrcode_content{
width:360rpx;
height:360rpx;
}
.bg-primary-light{
background: var(--view-minorColorT);
}
.qrocode-num{
width:440rpx;
height:80rpx;
}
.close{
position: absolute;
left:50%;
bottom: -96rpx;
transform: translateX(-50%);
}
.qrcode_content .image {
width: 100%;
height: 100%;
}
</style>

View File

@@ -0,0 +1,99 @@
<template>
<view :style="colorStyle">
<!-- 商品详情 -->
<view class="m-20 pro-box rd-20rpx bg--w111-fff flex-between-center">
<image class="w-108 h-108 rd-16rpx" :src="storeInfo.image"></image>
<view class="flex-1 pl-28">
<view class="w-510 line1 fs-30 fw-500">{{storeInfo.store_name}}</view>
<view class="pt-30 fs-24">
<text class="font-num fs-30 fw-500 pr-8">{{count}}</text>条种草秀
</view>
</view>
</view>
<view class="px-20" v-if="contentList.length">
<waterfallsFlow :wfList="contentList" @onFlowLike="flowLike"></waterfallsFlow>
</view>
<view class="px-20 mt-20" v-else>
<emptyPage title="暂无内容~"></emptyPage>
</view>
<home></home>
</view>
</template>
<script>
import colors from "@/mixins/color";
import { communityElegantListApi } from "@/api/community.js";
import { getProductDetail } from "@/api/store.js"
import waterfallsFlow from "@/components/discoverWaterfall/WaterfallsFlow.vue";
import emptyPage from '@/components/emptyPage.vue';
export default {
data() {
return {
contentList:[],
loading:false,
params:{
page:1,
limit:20,
product_id:''
},
storeInfo:{},
count:0
};
},
components:{ waterfallsFlow, emptyPage },
mixins: [colors],
provide() {
return {
flowLike: this.flowLike
}
},
onPageScroll(object) {
uni.$emit('scroll');
},
onLoad(options) {
this.params.product_id = options.id || '';
this.getProductInfo(options.id);
this.getList();
},
methods:{
getProductInfo(id){
getProductDetail(id, {promotions_type: 0}).then(res=>{
this.storeInfo = res.data.storeInfo;
})
},
getList(){
if (this.loading) return;
this.loading = true;
communityElegantListApi(this.params).then(res=>{
let list = res.data.list;
this.count = res.data.count;
let loading = list.length < this.params.limit;
this.contentList = this.contentList.concat(list);
this.params.page++;
this.loading = loading;
})
},
flowLike(data){
let index = this.contentList.findIndex(item=> data.id == item.id);
this.contentList[index].is_like = data.status;
if(data.status == 1){
this.contentList[index].like_num++;
}else{
this.contentList[index].like_num--;
}
},
},
onReachBottom() {
this.getList()
}
}
</script>
<style lang="scss">
.w-510{
width: 510rpx;
}
.pro-box{
padding: 20rpx 30rpx;
}
</style>

View File

@@ -0,0 +1,614 @@
<template>
<view :style="colorStyle">
<view class="px-20">
<view class="w-full bg--w111-fff rd-24rpx p-24 mt-24"v-show="showCardOne">
<view class='flex-y-center'>
<text class="iconfont icon-icon_WeChat_1 fs-36"></text>
<text class="fs-30 lh-42rpx fw-500 pl-8">方式一:商品卡片分享</text>
</view>
<view class="mt-24 w-full h-256 bg--w111-f9f9f9 rd-12rpx relative bg-cover" :style="[shareCardBg]">
<view class="flex-y-center card-site">
<image :src="mpData.logo_url" class="site-logo"></image>
<text class="site-name line1">{{mpData.site_name}}</text>
</view>
<image :src="storeInfo.image" class="w-210 h-168 card-center-image" mode="aspectFill"></image>
<!-- -->
</view>
<!-- #ifdef MP-WEIXIN -->
<button class="w-full bg-gradient h-80 rd-40rpx flex-center fs-28 text--w111-fff mt-24" open-type="share" hover-class="none">分享商品卡片</button>
<!-- #endif -->
<!-- #ifdef APP || H5 -->
<view class="w-full bg-gradient h-80 rd-40rpx flex-center fs-28 text--w111-fff mt-24" @tap="cardShare">分享商品卡片</view>
<!-- #endif -->
</view>
<view class="w-full bg--w111-fff rd-24rpx p-24 mt-32">
<view class="flex-between-center">
<view class='flex-y-center'>
<image src="../static/share_picture.png" class="w-36 h-36"></image>
<text class="fs-30 lh-42rpx fw-500 pl-8">方式{{showCardOne ? '二' : '一'}}:商品图片分享</text>
</view>
<text class="iconfont fs-28 text--w111-666"
v-if="storeInfo.slider_image.length > 1"
:class="isGrid ? 'icon-a-ic_Imageandtextsorting' : 'icon-a-ic_Picturearrangement'"
@tap="()=>{isGrid = !isGrid}"></text>
</view>
<view v-if="storeInfo.slider_image.length == 1">
<view class="mt-24 flex-x-center" >
<view class="load-box poster-img" v-show="!posterImage"></view>
<image v-show="posterImage" :src="posterImage" @tap="proviewPhoto(0)" class="poster-img" mode="aspectFill"></image>
</view>
<view class="w-full flex-between-center">
<!-- #ifdef MP-WEIXIN || APP-PLUS -->
<view class="w-full bg-gradient h-80 rd-40rpx flex-center fw-500 fs-28 text--w111-fff mt-24" @tap="savePoster">保存商品海报图片</view>
<!-- #endif -->
<!-- #ifdef H5 -->
<view class="w-full bg-gradient h-80 rd-40rpx flex-center fs-28 text--w111-fff mt-24" @tap="proviewPhoto(0)">保存分享</view>
<!-- #endif -->
</view>
</view>
<view v-else>
<view class="mt-24" v-show="!isGrid">
<scroll-view scroll-x="true" class="white-nowrap vertical-middle w-full" show-scrollbar="false">
<view class="inline-block mr-16" v-show="!posterImage">
<view class="load-box w-192 h-192 rd-8rpx"></view>
</view>
<view class="inline-block mr-16" v-for="(item,index) in productSwiper" :key="index">
<view class="w-192 h-192 relative text--w111-fff" @tap="proviewPhoto(index)">
<image :src="item.pic" class="w-full h-full rd-8rpx"
:class="{'b-e': item.isQrcode}" mode="aspectFill"></image>
<view class="qr-tag flex-center fs-18 text--w111-fff" v-if="posterImage && item.isQrcode">二维码推广图</view>
<!-- #ifdef MP-WEIXIN || APP-PLUS -->
<text class="iconfont fs-36 select-icon"
:class="item.select ? 'icon-a-ic_CompleteSelect' : 'icon-ic_unselect'" @tap.stop="selectPic(item)"></text>
<!-- #endif -->
</view>
</view>
</scroll-view>
</view>
<view class="w-full grid-column-3 grid-gap-16rpx mt-24" v-show="isGrid">
<view class="load-box w-full h-210 rd-12rpx" v-show="!posterImage"></view>
<view class="w-full h-210 relative text--w111-fff"
:class="{'b-e rd-12rpx': item.isQrcode}"
v-for="(item,index) in productSwiper" :key="index"
@tap="proviewPhoto(index)">
<image :src="item.pic" class="w-full h-full rd-12rpx"
mode="aspectFill"></image>
<view class="qr-tag flex-center fs-18 text--w111-fff" v-if="posterImage && item.isQrcode">二维码推广图</view>
<!-- #ifdef MP-WEIXIN || APP-PLUS -->
<text class="iconfont fs-36 select-icon"
:class="item.select ? 'icon-a-ic_CompleteSelect' : 'icon-ic_unselect'"
@tap.stop="selectPic(item)"></text>
<!-- #endif -->
</view>
</view>
<view class="w-full flex-between-center">
<!-- #ifdef MP-WEIXIN || APP-PLUS -->
<view class="w-320 h-80 rd-40rpx flex-center fs-26 view-border fw-500 font-num mt-24" @tap="savePhoto('pic')">保存选中图片</view>
<view class="w-320 bg-gradient h-80 rd-40rpx flex-center fw-500 fs-28 text--w111-fff mt-24" @tap="savePhoto('poster')">保存商品海报图片</view>
<!-- #endif -->
<!-- #ifdef H5 -->
<view class="w-full bg-gradient h-80 rd-40rpx flex-center fs-28 text--w111-fff mt-24" @tap="proviewPhoto(0)">保存分享</view>
<!-- #endif -->
</view>
</view>
</view>
<view class="w-full bg--w111-fff rd-24rpx p-24 mt-24">
<view class='flex-y-center'>
<image src="../static/share_text.png" class="w-36 h-36"></image>
<text class="fs-30 lh-42rpx fw-500 pl-8">方式{{showCardOne ? '三' : '二'}}:文案分享</text>
</view>
<!-- #ifdef MP-WEIXIN -->
<view class="mt-24 bg--w111-f9f9f9 rd-12rpx p-16 fs-26 lh-36rpx space-line">
{{storeInfo.share_content || storeInfo.store_name}}
<text><br/>{{shortLink}}</text>
</view>
<!-- #endif -->
<!-- #ifdef H5 || APP-PLUS -->
<view class="mt-24 bg--w111-f9f9f9 rd-12rpx p-16 fs-26 lh-36rpx space-line">
{{storeInfo.share_content || storeInfo.store_name}}
<text><br/>{{codeVal}}</text>
</view>
<!-- #endif -->
<view class="w-full flex-between-center">
<view class="w-320 h-80 rd-40rpx flex-center fs-26 view-border fw-500 font-num mt-24" @tap="copyShare(0)">仅复制链接</view>
<view class="w-320 bg-gradient h-80 rd-40rpx flex-center fw-500 fs-28 text--w111-fff mt-24" @tap="copyShare(1)">复制文案及链接</view>
</view>
</view>
<view class="pb-safe">
<view class="h-80"></view>
</view>
</view>
<!-- #ifdef H5 || APP-PLUS -->
<zb-code ref="qrcode" onval loadMake :show="codeShow" cid="1" :val="codeVal" @result="qrR" />
<!-- #endif -->
<canvas class="canvas" canvas-id="myCanvas" v-if="canvasStatus"></canvas>
</view>
</template>
<script>
import colors from "@/mixins/color";
import {HTTP_REQUEST_URL} from '@/config/app';
import { getProductDetail, getProductCode, getShortLinkApi } from "@/api/store.js";
import { getUserInfo, userShare } from '@/api/user.js';
import { toLogin } from '@/libs/login.js';
import { mapGetters } from 'vuex';
import zbCode from '@/components/zb-code/zb-code.vue'
export default {
data() {
return {
imgHost: HTTP_REQUEST_URL,
id: 0,
canvasStatus: false,
//二维码参数
codeShow: false,
codeVal: "", // 要生成的二维码值
shareQrcode: 0,
PromotionCode: '',
followCode: '',
siteName: '', //商城名称
posterTitle: '',
themeColor: '#e93323',
fontColor: '#e93323',
posterImage: '', //海报路径
storeImage: '', //海报产品图
isDown: true,
posterImageStatus: false,
storeInfo:{
slider_image: []
},
productSwiper: [],
showCardOne: true,
shortLink: '',
isGrid: true,
mpData:{}
};
},
components: { zbCode },
computed:{
...mapGetters(['isLogin', 'uid']),
shareCardBg(){
return {
backgroundImage: 'url('+this.imgHost+'/statics/images/promoter/promoter_group9.png'+')'
}
},
},
mixins: [colors],
onLoad(options) {
// #ifdef H5
this.showCardOne = this.$wechat.isWeixin() ? true : false;
// #endif
if (!options.id) {
return this.$util.Tips({
title: '缺少参数无法查看商品'
}, {
tab: 3
});
}
this.id = options.id || 0;
this.getInfo();
// #ifdef MP-WEIXIN
this.mpData = uni.getStorageSync('BASIC_CONFIG');
this.getShortLink();
// #endif
},
onReady: function() {
this.isNodes++;
let uid = this.isLogin ? this.$store.state.app.uid : ''
// #ifdef H5
this.codeVal = window.location.origin + '/pages/goods_details/index?id=' + this.id +
'&spid=' + uid
// #endif
// #ifdef APP-PLUS
this.codeVal = HTTP_REQUEST_URL + '/pages/goods_details/index?id=' + this.id +
'&spid=' + uid
// #endif
},
methods:{
async getInfo(){
let res = await getProductDetail(this.id, {promotions_type: 0});
let storeInfo = res.data.storeInfo;
this.$set(this, 'storeInfo', storeInfo);
this.$set(this, 'shareQrcode', res.data.share_qrcode);
this.$set(this, 'siteName', res.data.site_name);
this.$set(this, 'posterTitle', res.data.product_poster_title);
this.productSwiper = storeInfo.slider_image.map(item=>{
return {
pic: item,
select: false,
isQrcode: false,
}
})
setTimeout(()=>{
this.goPoster();
},500)
},
getShortLink(){
getShortLinkApi(this.id).then(res=>{
this.shortLink = res.data.code;
}).catch(err=>{
return this.$util.Tips({
title: err
});
})
},
copyShare(type){
let that = this;
let shareText = this.storeInfo.share_content || this.storeInfo.store_name;
let copyText = '';
// #ifdef MP-WEIXIN
copyText = type == 1 ? shareText + ' ' + this.shortLink : this.shortLink;
// #endif
// #ifdef APP-PLUS || H5
copyText = type == 1 ? shareText + ' ' + this.codeVal : this.codeVal;
// #endif
uni.setClipboardData({
data: copyText,
success:()=>{
uni.showToast({
title: '复制成功,快去分享吧',
icon: 'none'
})
}
})
},
qrR(res) {
// #ifdef H5
if (!this.$wechat.isWeixin() || this.shareQrcode != '1') {
this.PromotionCode = res;
this.followCode = ''
}
// #endif
// #ifdef APP-PLUS
this.PromotionCode = res;
// #endif
},
//替换安全域名
setDomain: function(url) {
url = url ? url.toString() : '';
//本地调试打开,生产请注销
if (url.indexOf('https://') > -1) return url;
else return url.replace('http://', 'https://');
},
//图片转符合安全域名路径
downloadFileImage(url) {
url = this.setDomain(url)
return new Promise((resolve, reject) => {
let that = this;
uni.downloadFile({
url: url,
success: function(res) {
resolve(res.tempFilePath);
},
fail: function(err) {
console.error(err.errMsg);
}
});
})
},
async goPoster() {
let that = this;
let storeImage = await this.downloadFileImage(this.storeInfo.image);
let posterbackgd = await this.downloadFileImage(this.imgHost + '/statics/images/product/posterbackgd.png');
// #ifdef MP-WEIXIN
// 小程序端获取小程序码
let res = await getProductCode(that.id);
if(!res.data.code){
return that.$util.Tips({
title: '小程序二维码需要发布正式版后才能获取到'
});
}
let PromotionCode = await this.downloadFileImage(res.data.code)
// #endif
// #ifdef H5
let PromotionCode = '';
if(this.$wechat.isWeixin()){
// 公众号端获取公众号二维码
let res = await getProductCode(that.id);
PromotionCode = await this.downloadFileImage(res.data.code)
}else{
// h5端获取本地生成的二维码
PromotionCode = this.PromotionCode;
}
// #endif
// #ifdef APP-PLUS
let PromotionCode = this.PromotionCode;
// #endif
that.$set(that, 'canvasStatus', true);
let arr2 = [posterbackgd, storeImage, PromotionCode];
that.$nextTick(function() {
setTimeout(()=>{
that.$util.PosterCanvas(that.fontColor, that.themeColor, that.siteName,arr2,
that.storeInfo.store_name,
that.storeInfo.price,
that.storeInfo.ot_price,
that.posterTitle,
function(tempFilePath) {
that.$set(that, 'posterImage', tempFilePath);
that.$set(that, 'posterImageStatus', true);
that.$set(that, 'canvasStatus', false);
that.productSwiper.unshift({
pic:tempFilePath,
select: false,
isQrcode:true
})
});
},1000)
})
},
cardShare(){
// #ifdef H5
this.ShareInfo();
uni.showToast({
title: '请点击右上角三个点进行分享',
icon: 'none'
})
// #endif
// #ifdef APP-PLUS
this.appShare();
// #endif
},
//#ifdef H5
ShareInfo() {
let data = this.storeInfo;
if (this.$wechat.isWeixin()) {
let configAppMessage = {
desc: data.store_info,
title: data.store_name,
link: '/pages/goods_details/index?id=' + this.id + '&spid=' + this.uid,
imgUrl: data.image
};
this.$wechat.wechatEvevt([
'updateAppMessageShareData',
'updateTimelineShareData',
'onMenuShareAppMessage',
'onMenuShareTimeline'
], configAppMessage).then(res => {}).catch(err => {});
}
},
//#endif
appShare() {
let that = this;
uni.share({
provider: "weixin",
scene: 'WXSceneSession',
type: 0,
href: `${HTTP_REQUEST_URL}/pages/goods_details/index?id=${that.id}&spid=${that.uid}`,
title: that.storeInfo.store_name,
summary: that.storeInfo.store_info,
imageUrl: that.storeInfo.small_image,
success: function(res) {
},
fail: function(err) {
uni.showToast({
title: '分享失败',
icon: 'none',
duration: 2000
})
}
});
},
selectPic(item){
item.select = !item.select;
},
savePhoto(type){
// #ifdef MP-WEIXIN
let that = this;
uni.getSetting({
success(res){
if (!res.authSetting['scope.writePhotosAlbum']) {
uni.authorize({
scope: 'scope.writePhotosAlbum',
success() {
if(type == 'poster'){
that.savePoster()
}else{
that.mpSave();
}
}
});
}else{
if(type == 'poster'){
that.savePoster()
}else{
that.mpSave();
}
}
}
})
// #endif
// #ifdef APP-PLUS
if(type == 'poster'){
this.savePoster()
}else{
this.mpSave();
}
// #endif
},
mpSave(){
let that = this;
let arr = this.productSwiper.filter(val => val.select);
let picLength = arr.length; // 要下载的总条数
let index = 0;
uni.showLoading({
title: '图片下载中',
mask: true
});
for (let i = 0; i < arr.length; i++) {
if(arr[i].isQrcode){
this.savePoster();
}else{
uni.downloadFile({
url: arr[i].pic,
success: function(res) {
var temp = res.tempFilePath
uni.saveImageToPhotosAlbum({
filePath: temp,
success(res1) {
index++;
// 全部下载完后触发
if (index == picLength) {
uni.hideLoading()
that.$util.Tips({
title: '保存成功',
icon: 'success'
});
}
},
fail: function(res) {
uni.hideLoading()
that.$util.Tips({
title: '保存失败'
});
}
})
},
fail(err) {
uni.hideLoading()
}
})
}
}
},
savePoster(){
let that = this;
uni.saveImageToPhotosAlbum({
filePath: that.posterImage,
success(res1) {
that.$util.Tips({
title: '保存成功',
icon: 'success'
});
},
fail: function(res) {
that.$util.Tips({
title: '保存失败'
});
}
})
},
proviewPhoto(index){
let list = this.productSwiper.map(item=> item.pic);
uni.previewImage({
current: index,
urls: list
});
},
},
// #ifdef MP
onShareAppMessage: function() {
let that = this;
userShare();
return {
title: that.storeInfo.store_name || '',
imageUrl: that.storeInfo.image || '',
path: '/pages/goods_details/index?id=' + that.id + '&spid=' + that.uid
};
},
onShareTimeline() {
let that = this;
userShare();
return {
title: that.storeInfo.store_name || '',
imageUrl: that.storeInfo.image || '',
path: '/pages/goods_details/index?id=' + that.id + '&spid=' + that.uid
};
},
// #endif
}
</script>
<style lang="scss">
.icon-icon_WeChat_1{
color: rgba(11, 190, 36, 1);
}
.h-256{
height: 256rpx;
}
.bg-cover{
background-size: cover;
}
.card-site{
position: absolute;
left: 50%;
top: 24rpx;
transform: translateX(-50%);
width: 210rpx;
.site-logo{
width: 18rpx;
height: 18rpx;
border-radius: 50%;
}
.site-name{
width: 152rpx;
font-size: 18rpx;
color: #727272;
line-height: 16rpx;
padding-left: 4rpx;
}
}
.card-center-image{
position: absolute;
left: 50%;
top: 48rpx;
transform: translateX(-50%);
}
.poster-img{
width: 254rpx;
height: 438rpx;
border-radius: 12rpx;
border: 1rpx solid #EEEEEE;
}
.load-box{
animation: looming-gray 1s infinite linear;
background-color: #e3e3e3;
}
.view-border{
border: 1px solid var(--view-theme);
}
.icon-a-ic_CompleteSelect{
color: var(--view-theme);
}
.space-line{
white-space: pre-line
}
.select-icon{
position: absolute;
top: 12rpx;
right: 12rpx;
}
.b-e{
border: 1rpx solid #EEEEEE;
}
.qr-tag{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 40rpx;
border-radius: 0 0 8rpx 8rpx;
background-color: rgba(0, 0, 0, 0.5);
}
.canvas {
position: fixed;
top: -1300px;
left: 0;
width: 750px;
height: 1300px;
}
@keyframes looming-gray {
0% {
background-color: #e3e3e3aa;
}
50% {
background-color: #e3e3e3;
}
100% {
background-color: #e3e3e3aa;
}
}
</style>

View File

@@ -0,0 +1,338 @@
<template>
<view class="evaluateWtapper" :style="colorStyle">
<!-- 商品详情 -->
<view class="pt-24 pb-24 pl-32 pr-32 flex-between-center" v-if="replyCon.product"
@click="details(replyCon.product)">
<image class="w-104 h-104 rd-16rpx" :src="replyCon.product.image"></image>
<view class="ml-24 w-462 line2 text--w111-333 fs-28 lh-40rpx">{{replyCon.product.store_name}}</view>
<view class="flex-center w-56 h-56 rd-28rpx cart_border ml-40">
<text class="iconfont icon-ic_ShoppingCart1 text-primary-con"></text>
</view>
</view>
<!-- 评价内容卡片 -->
<view class="bg--w111-fff rd-24rpx pt-32 pb-32 pl-56 pr-56 mt-24" v-if="replyCon.reply">
<view class="flex-between-center">
<view class="flex-y-center">
<view class="flex-y-center">
<view class="w-64 h-64 rd-32rpx relative" :class="{'svip-border': replyCon.user.vip_status}">
<image :src="replyCon.reply.avatar" class="w-full h-full rd-28rpx"></image>
<image class="vip-badge" src="@/static/img/svip_badge.png" v-show="replyCon.user.vip_status"></image>
</view>
<text class="fs-28 text--w111-333 pl-12">{{replyCon.reply.nickname}}</text>
</view>
<view class="vip flex-center" v-if="replyCon.user.level_name">
<text class="iconfont icon-huiyuandengji"></text>
V{{replyCon.user.level_name}}
</view>
</view>
<view class="fs-26 text--w111-999">{{replyCon.reply.add_time}}</view>
</view>
<view class="mt-32">
<view class="flex-y-center">
<view class="flex pr-40">
<text class="iconfont icon-ic_star1 fs-18 text-primary-con"
v-for="item in Number(replyCon.star)" :key="item"></text>
</view>
<text class="fs-22 text--w111-999 pro_name relative" v-if="replyCon.reply.suk">{{replyCon.reply.suk }}</text>
</view>
</view>
<view class="mt-24 fs-28 text--w111-333 lh-44rpx">{{replyCon.reply.comment}}</view>
<image :src="pic" v-for="(pic,i) in replyCon.reply.pics" :key="i" class="w-full mt-20 rd-16rpx"
mode="widthFix"></image>
<view class="mt-24">
<text class="fs-22 text--w111-999">浏览{{replyCon.reply.views_num}}次</text>
</view>
</view>
<view class="bg--w111-fff rd-24rpx pt-32 pb-32 pl-56 pr-56 mt-24">
<view class="text--w111-333 fs-28 fw-500">{{replyNum}}条回复</view>
<view class="reply_box pb-24" v-for="(item,index) in replyList" :key="index">
<view class="flex justify-between items-baseline">
<view class="flex-y-center mt-32">
<view class="w-64 h-64 rd-32rpx relative" :class="{'svip-border': item.user.vip_status}">
<image class="w-full h-full rd-50-p111-" :src="item.user.avatar" v-if="item.uid && item.user"></image>
<image class="w-full h-full rd-50-p111-" src="../static/store.png" v-if="!item.uid"></image>
<image class="w-full h-full rd-50-p111-" src="@/static/images/f.png" v-if="!item.user"></image>
<image class="vip-badge" src="@/static/img/svip_badge.png" v-show="item.user.vip_status"></image>
</view>
<view class="flex-col pl-16">
<view class="flex-y-center">
<text class="text--w111-333 fs-24"
:class="!item.uid ? 'text_score':''">{{item.user?item.user.nickname:'用户'}}</text>
<view class="store_badge flex-center fs-18" v-if="!item.uid">商家</view>
<view class="vip flex-center" v-if="item.user.level_name">
<text class="iconfont icon-huiyuandengji"></text>
V{{item.user.level_name}}
</view>
</view>
<view class="fs-26 text--w111-999">{{item.create_time}}</view>
</view>
</view>
<view class="flex-y-center" :class="item.is_praise ? 'font-num':''">
<text class="iconfont icon-ic_Like fs-32" @click="praise(item)"></text>
<text class="fs-22 pl-8">{{item.praise}}</text>
</view>
</view>
<view class="mt-24 fs-26 text--w111-333 lh-44rpx pb-24">{{item.content}}</view>
</view>
</view>
<view class="h-120 pb-safe"></view>
<view class="page_footer fixed-lb w-full bg--w111-fff pr-20 pb-safe">
<view class="pl-32 pr-24 h-96 flex-between-center">
<view class="w-498 h-64 rd-32rpx bg--w111-f5f5f5 pl-24 flex-y-center text--w111-999 px-20"
@tap="showInput = true">
<text class="iconfont icon-ic_edit"></text>
<text class="fs-26 pl-16">说说你的看法吧~</text>
</view>
<view class="flex-y-center pl-28">
<view :class="replyCon.is_praise ? 'text-primary-con':''">
<text class="iconfont icon-ic_Like"
@click="tapPraise"></text>
<text class="fs-22 pl-8">{{replyCon.reply?replyCon.reply.praise:0}}</text>
</view>
<view class="pl-32">
<text class="iconfont icon-ic_message"></text>
<text class="fs-22 pl-8">{{replyCon.reply ? replyCon.reply.comment_sum : 0}}</text>
</view>
</view>
</view>
</view>
<tui-drawer mode="bottom" :visible="showInput" background-color="transparent" mask maskClosable @close="closeDrawer">
<view class="w-full bg--w111-fff drawer-text pt-16 pl-32 pr-32">
<view class="bg--w111-f5f5f5 flex justify-between items-end rd-32rpx pt-8 pr-8 pb-8 pl-24 relative">
<textarea class="w-528 fs-28 h-auto"
:auto-height="true"
wrap-style="wrap"
max-height="100px"
placeholder-class='placeholder'
placeholder="说说你的看法吧"
:always-embed="true"
:adjust-position="true"
cursor-spacing="85rpx"
v-model="con"
:maxlength="150"
name="mark">
</textarea>
<view class="w-96 h-48 rd-24rpx flex-center bg-color text--w111-fff fs-24 ml-24"
@tap="sendText">发送</view>
</view>
</view>
</tui-drawer>
<home></home>
</view>
</template>
<script>
import {
getReplyInfo,
getReplyComment,
postReplyPraise,
replyComment,
postUnReplyPraise,
getReplyPraise,
getUnReplyPraise
} from '@/api/store.js';
import tuiDrawer from "@/components/tui-drawer/tui-drawer.vue"
import colors from '@/mixins/color.js';
export default {
components: {
tuiDrawer
},
mixins: [colors],
data: function() {
return {
id: 0,
page: 1,
limit: 200,
replyCon: {},
replyList: [],
con: '',
scrollTop: 0,
replyNum: 0,
showInput:false
};
},
onLoad(options) {
this.id = options.id
this.getInfo();
this.getList();
},
onShow() {
uni.removeStorageSync('form_type_cart');
},
methods: {
tapPraise() {
if (this.replyCon.is_praise) {
getUnReplyPraise(this.id).then(res => {
this.replyCon.is_praise = !this.replyCon.is_praise
this.replyCon.reply.praise = this.replyCon.reply.praise - 1
return this.$util.Tips({
title: res.msg
});
});
} else {
getReplyPraise(this.id).then(res => {
this.replyCon.is_praise = !this.replyCon.is_praise
this.replyCon.reply.praise = this.replyCon.reply.praise + 1
return this.$util.Tips({
title: res.msg
});
});
}
},
// 设置页面滚动位置
setPageScrollTo() {
let view = uni
.createSelectorQuery()
.in(this)
.select('#tops');
view.boundingClientRect(res => {
this.scrollTop = parseFloat(res.height);
}).exec();
},
sendText() {
if (!this.con.trim()) {
return this.$util.Tips({
title: '说点什么呗'
});
}
replyComment(this.id, {
content: this.con
}).then(res => {
let that = this;
this.con = '';
that.showInput = false;
this.replyNum = this.replyNum + 1;
this.getList();
this.$util.Tips({
title: res.msg
});
})
},
details(info) {
if(info.is_presale_product){
uni.navigateTo({
url: `/pages/activity/goods_details/index?id=${info.id}&type=6`
})
}else{
uni.navigateTo({
url: `/pages/goods_details/index?id=${info.id}`
})
}
},
getInfo() {
getReplyInfo(this.id).then(res => {
this.replyCon = res.data;
this.replyNum = this.replyCon.reply.comment_sum;
})
},
getList() {
getReplyComment(this.id, {
page: this.page,
limit: this.limit
}).then(res => {
this.replyList = res.data
}).catch(err => {
return this.$util.Tips({
title: err.msg
});
})
},
getpreviewImage: function(index) {
uni.previewImage({
urls: this.replyCon.reply.pics,
current: this.replyCon.reply.pics[index]
});
},
praise(item) {
if (item.is_praise) {
postUnReplyPraise(item.id).then(res => {
item.is_praise = !item.is_praise
item.praise = item.praise - 1
return this.$util.Tips({
title: res.msg
});
});
} else {
postReplyPraise(item.id).then(res => {
item.is_praise = !item.is_praise
item.praise = item.praise + 1
return this.$util.Tips({
title: res.msg
});
});
}
},
closeDrawer(){
this.showInput = false;
}
},
onPageScroll(object) {
uni.$emit('scroll');
},
}
</script>
<style lang="scss">
.cart_border {
border: 1px solid var(--view-theme);
}
.text-primary-con {
color: var(--view-theme);
}
.text_score {
color: #FAAD14;
}
.store_badge {
width: 48rpx;
height: 26rpx;
background: #FAAD14;
border-radius: 4rpx;
color: #fff;
margin-left: 8rpx;
}
.vip{
width: 64rpx;
height: 26rpx;
background: #FEF0D9;
border: 1px solid #FACC7D;
border-radius: 50rpx;
font-size: 18rpx;
font-weight: 500;
color: #DFA541;
margin-left: 10rpx;
.iconfont {
font-size: 16rpx;
margin-right: 4rpx;
}
}
.svip-border{
border: 2rpx solid #F1BB0D;
}
.vip-badge{
position: absolute;
top: -10rpx;
left: 36rpx;
width: 18rpx;
height: 18rpx;
}
.drawer-text{
padding-bottom: calc(16rpx + env(safe-area-inset-bottom));
}
.pro_name::before {
content: '';
width: 1px;
height: 18rpx;
background-color: #ccc;
position: absolute;
left: -20rpx;
top: 8rpx;
}
.reply_box~.reply_box {
border-top: 1px solid #ddd;
}
</style>

View File

@@ -0,0 +1,336 @@
<template>
<view :style="colorStyle">
<view class="px-20">
<view class="h-120 bg--w111-fff rd-24rpx mt-24 pl-24 flex-y-center">
<text class="fs-28 fw-500 mr-32">商品评价</text>
<view class="flex-y-center">
<view class="flex-y-center nav-item" v-for="(item, index) in replyNav" :key="index"
@tap="replyNavChange(item.value)">
<image :src=" reply_score == item.value ? item.activePic : item.pic" class="w-44 h-44"></image>
<text class="fs-32 pl-14"
:class="reply_score == item.value ? 'font-num' : 'text--w111-999'">{{item.title}}</text>
</view>
</view>
</view>
<view class="bg--w111-fff rd-24rpx mt-20 pt-32 pr-24 pb-32 pl-24">
<view class="flex-y-center pb-40 bb-e">
<image :src="productInfo.attrInfo ? productInfo.attrInfo.image : productInfo.image" class="w-88 h-88 rd-16rpx"></image>
<view class="pl-20 flex-1">
<view class="fs-28 lh-40rpx line1 w-538">{{productInfo.store_name}}</view>
<view v-if='send_gift_type != 2' class="fs-32 SemiBold mt-12">¥{{productInfo.attrInfo?productInfo.attrInfo.price:productInfo.price}}</view>
</view>
</view>
<view class="pt-40">
<textarea placeholder='商品满足你的期待么?说说你的想法,分享给想买的他们吧~(最多输入100个字)' v-model="comment" name="comment" placeholder-class='placeholder' maxlength='100' class="fs-26 lh-40rpx"></textarea>
<view class="grid-column-4 grid-gap-24rpx">
<view class="relative h-148" v-for="(item,index) in pics" :key="index">
<image :src="item" mode="aspectFill" class="w-148 h-148 rd-16rpx"></image>
<view class="abs-rt w-32 h-32 of0b21 flex-center fs-24" @click="DelPic(index)">
<text class="iconfont icon-ic_close text--w111-fff"></text>
</view>
</view>
<view class="h-148 flex-col flex-center upload bg--w111-f5f5f5 rd-16rpx"
@click='uploadpic' v-if="pics.length < 8">
<image class="w-48 h-48" src="../static/ic_camera.png"></image>
<text class="fs-24 lh-34rpx pt-8">上传图片</text>
</view>
</view>
</view>
<view class="flex-y-center pt-26" v-if="community_status">
<text class="iconfont fs-32" :class="is_sync ? 'icon-a-ic_CompleteSelect' : 'icon-ic_unselect'"
@tap="checkSync"></text>
<text class="fs-24 pl-8">评论晒图</text>
</view>
</view>
<view class="bg--w111-fff rd-24rpx mt-20 pt-32 pr-24 pb-32 pl-24">
<view class="flex-y-center">
<text class="fs-28 fw-500">商品质量</text>
<view class="ml-40 flex">
<text class="star iconfont text--w111-999"
:class="item <= product_score ? 'icon-ic_star1 font-num' : 'icon-ic_star'"
v-for="(item, index) in starArr" :key="index" @click="stars(0,item)"></text>
</view>
</view>
<view class="flex-y-center mt-40">
<text class="fs-28 fw-500">服务态度</text>
<view class="ml-40 flex">
<text class="star iconfont text--w111-999"
:class="item <= service_score ? 'icon-ic_star1 font-num' : 'icon-ic_star'"
v-for="(item, index) in starArr" :key="index" @click="stars(1,item)"></text>
</view>
</view>
<!-- delivery_score -->
<view class="flex-y-center mt-40">
<text class="fs-28 fw-500">物流服务</text>
<view class="ml-40 flex">
<text class="star iconfont text--w111-999"
:class="item <= delivery_score ? 'icon-ic_star1 font-num' : 'icon-ic_star'"
v-for="(item, index) in starArr" :key="index" @click="stars(2,item)"></text>
</view>
</view>
</view>
</view>
<view class="h-120"></view>
<view class='fixed-lb w-full bg--w111-fff pb-safe'>
<view class="mx-20 h-120 flex-center">
<view class="w-full h-80 rd-40rpx flex-center text--w111-fff fs-28"
:class="isSelectStar ? 'bg-color' : 'bg-hui'"
@tap="formSubmit">提交</view>
</view>
</view>
<canvas canvas-id="canvas" v-if="canvasStatus"
:style="{width: canvasWidth + 'px', height: canvasHeight + 'px',position: 'absolute',left:'-100000px',top:'-100000px'}"></canvas>
</view>
</template>
<script>
import {orderProduct,orderComment} from '@/api/order.js';
import { getCommunityConfig } from "@/api/community.js"
import {toLogin} from '@/libs/login.js';
import {mapGetters} from "vuex";
import colors from "@/mixins/color";
import { HTTP_REQUEST_URL } from '@/config/app';
export default {
components: {},
mixins: [colors],
data() {
return {
imgHost: HTTP_REQUEST_URL,
pics: [],
replyNav:[
{
title:'好评',
pic: HTTP_REQUEST_URL + '/statics/images/product/product_reply_icon1_0.png',
activePic:HTTP_REQUEST_URL + '/statics/images/product/product_reply_icon1.png',
value:3,
},
{
title:'中评',
pic: HTTP_REQUEST_URL + '/statics/images/product/product_reply_icon2_0.png',
activePic: HTTP_REQUEST_URL + '/statics/images/product/product_reply_icon2.png',
value:2,
},
{
title:'差评',
pic: HTTP_REQUEST_URL + '/statics/images/product/product_reply_icon3_0.png',
activePic: HTTP_REQUEST_URL + '/statics/images/product/product_reply_icon3.png',
value:1,
}
],
orderId: '',
unique: '',
productInfo: {},
cart_num: 0,
isAuto: false, //没有授权的不会自动授权
isShowAuth: false, //是否隐藏授权
canvasWidth: "",
canvasHeight: "",
canvasStatus: false,
product_score:-1,
service_score:-1,
delivery_score: -1,
reply_score:3,
comment:"",
starArr:[1,2,3,4,5],
is_sync:0,
community_status:1,
canvasWidth:'',
canvasHeight:''
};
},
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV) {
// #ifndef MP
this.getOrderProduct();
// #endif
}
},
deep: true
}
},
computed:{
...mapGetters(['isLogin']),
isSelectStar(){
if(this.product_score >= 0 && this.service_score >= 0 && this.delivery_score >= 0 && this.comment ){
return true
}
}
},
onLoad(options) {
if (!options.unique || !options.uni) return this.$util.Tips({
title: '缺少参数'
}, {
tab: 3,
url: 1
});
this.unique = options.unique;
this.orderId = options.uni;
this.send_gift_type = options.send_gift_type;
if (this.isLogin) {
this.getOrderProduct();
this.getConfig();
}
},
onShow() {
uni.removeStorageSync('form_type_cart');
},
methods: {
getConfig(){
getCommunityConfig().then(res=>{
this.community_status = res.data.community_status;
})
},
getOrderProduct: function() {
let that = this;
orderProduct(that.unique).then(res => {
that.$set(that, 'productInfo', res.data.productInfo);
that.cart_num = res.data.cart_num;
});
},
stars: function(type, star) {
if(type == 0){
this.product_score = star;
}else if(type == 1){
this.service_score = star;
}else {
this.delivery_score = star;
}
},
replyNavChange(value){
this.reply_score = value;
},
checkSync(){
if(this.is_sync){
this.is_sync = 0;
}else{
this.is_sync = 1;
}
},
/**
* 删除图片
*
*/
DelPic: function(index) {
let that = this,
pic = this.pics[index];
that.pics.splice(index, 1);
that.$set(that, 'pics', that.pics);
},
/**
* 上传文件
*
*/
uploadpic: function() {
let that = this;
this.canvasStatus = true
that.$util.uploadImageChange({count:8,url:'upload/image'}, function(res) {
that.pics.push(res.data.url);
}, (res) => {
this.canvasStatus = false
}, (res) => {
this.canvasWidth = res.w
this.canvasHeight = res.h
});
},
/**
* 立即评价
*/
formSubmit: function() {
let that = this;
if (!this.comment) return that.$util.Tips({
title: '请填写你对宝贝的心得!'
});
if(!this.isSelectStar) return that.$util.Tips({
title: '请完成打分!'
});
if(this.community_status && this.is_sync && !this.pics.length) return that.$util.Tips({
title: '请上传要分享的图片!'
});
let o8e37 = {
reply_score: this.reply_score,
product_score: this.product_score,
service_score: this.service_score,
delivery_score: this.delivery_score,
pics: this.pics,
unique: this.unique,
comment: this.comment,
is_sync: this.is_sync
};
uni.showLoading({
title: "正在发布评论……"
});
orderComment(o8e37).then(res => {
uni.hideLoading();
let jumpPath = res.data.to_lottery ?
'/pages/goods/goods_comment_con/lottery_comment?type=4&order_id=' + that
.orderId : '/pages/goods/order_details/index?order_id=' + that.orderId
let obj = {
tab: 3,
url: 1
};
let pages = getCurrentPages();
if (pages[pages.length - 3]) {
if (pages[pages.length - 3].route == 'pages/goods/order_pay_status/index') {
obj.tab = 5;
obj.url = '/pages/goods/order_list/index';
}
}
if (res.data.to_lottery) {
obj.tab = 5;
obj.url = '/pages/goods/goods_comment_con/lottery_comment?type=4&order_id=' + that.orderId
}
that.$util.Tips({
title: '感谢您的评价!',
icon: 'success'
}, obj);
}).catch(err => {
uni.hideLoading();
return that.$util.Tips({
title: err
});
});
}
}
}
</script>
<style lang="scss" scoped>
.SemiBold {
font-family: SemiBold;
}
.good-pic{
width: 54rpx;
height: 59rpx;
}
.nav-item ~ .nav-item{
margin-left: 38rpx;
}
.bb-e{
border-bottom: 1px solid #eee;
}
.placeholder{
color: #ccc;
font-size: 26rpx;
line-height: 40rpx;
}
.upload{
border: 1px dashed #ccc;
}
.of0b21{
background-color: #999;
border-radius: 0 16rpx 0 16rpx;
}
.star ~ .star{
margin-left: 24rpx;
}
.bg-hui{
background-color: #ccc;
}
.icon-a-ic_CompleteSelect{
color: var(--view-theme);
}
</style>

View File

@@ -0,0 +1,263 @@
<template>
<view :style="colorStyle">
<view class="w-full fixed-lt z-99 bg-gradient" :style="{'padding-top': sysHeight + 'px'}">
<view class="w-full px-20 pl-20 h-80 flex-between-center">
<text class="iconfont icon-ic_leftarrow fs-40 text--w111-fff"></text @tap="goIndex">
<text class="fs-34 fw-500 text--w111-fff">评价抽奖</text>
<text></text>
</view>
<view class="flex-col flex-center mt-50">
<view class="flex-y-center">
<text class="iconfont icon-ic-complete1 fs-52 text--w111-fff"></text>
<text class="fs-40 fw-500 text--w111-fff pl-16">评价完成</text>
</view>
<view class="flex-center mt-30">
<view class="w-192 h-64 rd-40rpx flex-center fs-24 text--w111-fff white-border" @tap="goBack">返回订单</view>
<view class="w-192 h-64 rd-40rpx flex-center fs-24 text--w111-fff white-border ml-32" @tap="goIndex">返回首页</view>
</view>
</view>
<view class="h-216"></view>
</view>
<view class="relative content bg--w111-fff w-full pt-32 pl-20 pr-20 z-999" :style="{'top': 164 + sysHeight + 'px'}">
<view class="card bg--w111-fff rd-24rpx h-544 pt-32 pl-20 pr-20"
v-show="lotteryShow && prize.length">
<gridsLottery
:prizeData="prize"
:lotteryNum="lottery_num"
:lotteryType='1'
:datatime="datatime"
@get_winingIndex='getWiningIndex'
@luck_draw_finish='luck_draw_finish' >
</gridsLottery>
</view>
</view>
<lotteryAleart
:aleartStatus="aleartStatus"
theme
:alData="alData"
:aleartType="aleartType"
@close="closeLottery" >
</lotteryAleart>
<view class="mask z-8000" v-if="aleartStatus" @tap="lotteryAleartClose"></view>
<home></home>
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight;
import countDown from '@/components/countDown';
import gridsLottery from '../components/lottery/payLottery.vue'
import lotteryAleart from '../components/lotteryAleart/index.vue'
import colors from "@/mixins/color";
import {
openOrderSubscribe
} from '@/utils/SubscribeMessage.js';
import {
toLogin
} from '@/libs/login.js';
import {
getLotteryData,
startLottery,
receiveLottery
} from '@/api/lottery.js'
import {
mapGetters
} from "vuex";
import {HTTP_REQUEST_URL} from '@/config/app';
export default {
components: {
gridsLottery,
lotteryAleart,
countDown
},
mixins: [colors],
computed: mapGetters(['isLogin']),
data() {
return {
sysHeight:sysHeight,
lotteryShow: false,
addressModel: false,
lottery_num: 0,
aleartType: 0,
aleartStatus: false,
lottery_draw_param: {
startIndex: 3, //开始抽奖位置,从0开始
totalCount: 3, //一共要转的圈数
winingIndex: 1, //中奖的位置,从0开始
speed: 100 //抽奖动画的速度 [数字越大越慢,默认100]
},
alData: {},
type: '',
prize: [],
orderId: '',
order_pay_info: {
paid: 1,
_status: {}
},
isAuto: false, //没有授权的不会自动授权
isShowAuth: false, //是否隐藏授权
couponsHidden: true,
couponList: [],
datatime:0,
imgHost:HTTP_REQUEST_URL
};
},
computed: mapGetters(['isLogin']),
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV) {
// this.getOrderPayInfo();
}
},
deep: true
}
},
onLoad(options) {
this.orderId = options.order_id;
this.type = options.type;
if (this.isLogin) {
// this.getOrderPayInfo();
this.getLotteryData(this.type)
}
// #ifdef H5
document.addEventListener('visibilitychange', (e) => {
let state = document.visibilityState
if (state == 'hidden') {
}
if (state == 'visible') {
// this.getOrderPayInfo();
}
});
// #endif
},
onShow() {
uni.removeStorageSync('form_type_cart');
if(!this.isLogin){
toLogin()
}
},
methods: {
getWiningIndex(callback) {
this.aleartType = 0
startLottery({
id: this.id
}).then(res => {
this.prize.forEach((item, index) => {
if (res.data.id === item.id) {
this.alData = res.data
this.lottery_draw_param.winingIndex = index;
callback(this.lottery_draw_param);
}
})
}).catch(err => {
this.$util.Tips({
title: err
});
})
},
/**
* 去首页关闭当前所有页面
*/
goIndex: function(e) {
uni.switchTab({
url: '/pages/index/index'
});
},
goBack(){
uni.navigateBack()
},
getLotteryData(type) {
getLotteryData(type).then(res => {
this.lotteryShow = true;
this.factor_num = res.data.lottery.factor_num;
this.id = res.data.lottery.id;
this.prize = res.data.lottery.prize
if(this.prize.length){
this.prize.push({name:1})
};
this.lottery_num = res.data.lottery_num;
this.datatime = parseInt(res.data.cache_time);
}).catch(err => {
uni.redirectTo({
url: '/pages/goods/order_details/index?order_id=' + this.orderId
})
})
},
closeLottery(status) {
this.aleartStatus = false
this.getLotteryData(this.type)
if (this.alData.type === 6) {
this.addressModel = true
}
},
getWiningIndex(callback) {
this.aleartType = 0
startLottery({
id: this.id
}).then(res => {
this.prize.forEach((item, index) => {
if (res.data.id === item.id) {
this.alData = res.data
this.lottery_draw_param.winingIndex = index;
callback(this.lottery_draw_param);
}
})
}).catch(err => {
this.$util.Tips({
title: err
});
})
// //props修改在小程序和APP端不成功,所以在这里使用回调函数传参,
},
// 抽奖完成
luck_draw_finish(param) {
this.aleartType = 2
this.aleartStatus = true
},
}
}
</script>
<style lang="scss" scoped>
.fs-52{
font-size:52rpx;
}
.white-border{
border: 1px solid #fff;
}
.ml-48{
margin-left: 48rpx;
}
.h-216{
height:216rpx;
}
.h-544{
height:544rpx;
}
.content{
background: #f5f5f5;
border-radius: 40rpx 40rpx 0 0;
left:0;
min-height:500rpx;
}
.card ~ .card{
margin-top: 20rpx;
}
.h-76{
height:76rpx;
}
.cell ~ .cell {
border-top: 1px solid #eee;
}
.card_btn{
width: 114rpx;
height: 52rpx;
border-radius: 26rpx;
border: 1px solid #E93323;
}
.z-8000{
z-index: 8000;
}
</style>

View File

@@ -0,0 +1,328 @@
<template>
<view :style="colorStyle">
<!-- 导航区 -->
<view class="w-full fixed-lt bg--w111-fff z-10 rd-b-24rpx">
<view class="pl-32 pr-32 pt-24 pb-32">
<view class="flex-between-center">
<view>
<text class="text--w111-333 fs-30 fw-500">评价</text>
<text class="fs-24 text--w111-666 pl-8">({{tabList[0].count}})</text>
</view>
<view class="flex-y-center">
<text class="fs-28 text-primary-con Regular">{{replyData.reply_chance}}%</text>
<text class="fs-24 text--w111-999 pl-4 pr-12">好评率</text>
</view>
</view>
<view class="flex-y-center mt-34">
<view
class="tab_item inline-block h-56 rd-28rpx lh-56rpx text-center px-24 fs-24 bg--w111-f5f5f5 text--w111-333"
v-for="(item, index) in tabList" :key="index"
:class="item.type == type ? 'active' : ''"
@click='changeType(item.type)'>{{ item.title }}({{ item.count }})</view>
</view>
</view>
</view>
<view class="h-190"></view>
<!-- 评论卡片 -->
<view v-if="reply.length">
<view class="mt-20 rd-24rpx bg--w111-fff p-32"
v-for="item in reply" :key="item.id" @click="goPage(item.id)">
<view class="flex-between-center">
<view class="flex-y-center">
<view class="w-56 h-56 rd-28rpx relative" :class="{'svip-border': item.vip_status}">
<image :src="item.avatar" class="w-full h-full rd-28rpx"></image>
<image class="vip-badge" src="@/static/img/svip_badge.png" v-show="item.vip_status"></image>
</view>
<text class="fs-28 text--w111-333 pl-12">{{item.nickname}}</text>
<view class="vip flex-center" v-if="item.level_name">
<text class="iconfont icon-huiyuandengji"></text>
V{{item.level_name}}
</view>
</view>
<view class="fs-26 text--w111-999 Regular">{{item.add_time}}</view>
</view>
<view class="flex-between-center mt-32">
<view class="flex-y-center">
<view class="flex pr-20">
<text class="iconfont icon-ic_star1 fs-18 text-primary-con" v-for="star in Number(item.star)"
:key="star"></text>
</view>
<text class="w-400 line1" v-show="item.suk">
<text class="text--w111-ccc fs-18">|</text>
<text class="pl-20 fs-22 text--w111-999">{{item.suk}}</text>
</text>
</view>
<image src="../static/hp_icon.png" class="w-78 h-30" mode="aspectFit" v-show="item.reply_score == 3"></image>
<image src="../static/zp_icon.png" class="w-78 h-30" mode="aspectFit" v-show="item.reply_score == 2"></image>
<image src="../static/cp_icon.png" class="w-78 h-30" mode="aspectFit" v-show="item.reply_score == 1"></image>
</view>
<view class="mt-20 fs-28 text--w111-333 lh-44rpx">{{item.comment}}</view>
<!-- 1张照片 -->
<image :src="item.pics[0]" class="w-400 h-400 rd-16rpx mt-20" mode="aspectFill"
v-if="item.pics.length == 1"></image>
<!-- 2张照片 -->
<view class="mt-20 grid-column-2 grid-gap-x-10rpx grid-gap-y-20rpx" v-if="item.pics.length == 2">
<image class="w-full h-338 rd-16rpx" :src="itemp" mode="aspectFill" v-for="(itemp,ip) in item.pics"
:key="ip"></image>
</view>
<!-- 多于2张照片 -->
<view class="mt-20 grid-column-3 grid-gap-10rpx" v-if="item.pics.length > 2">
<image class="w-full h-222 rd-16rpx" :src="itemp" mode="aspectFill" v-for="(itemp,ip) in item.pics"
:key="ip"></image>
</view>
<!-- 浏览次数 点赞 -->
<view class="flex-between-center mt-24">
<text class="fs-22 text--w111-999">浏览{{item.views_num}}次</text>
<view class="flex text--w111-333">
<view class="flex-y-center" :class="item.is_praise ? 'text-primary-con':''">
<text class="iconfont icon-ic_Like fs-32"
@tap.stop="tapPraise(item)"></text>
<text class="fs-22 pl-8">{{item.praise}}</text>
</view>
<view class="ml-32 flex-y-center">
<text class="iconfont icon-ic_message fs-32"></text>
<text class="fs-22 pl-8">{{item.replyComment ? item.replyComment.sum : 0}}</text>
</view>
</view>
</view>
</view>
</view>
<view class="px-20 mt-20" v-else>
<emptyPage title="暂无评论,去看点别的吧~" src="/statics/images/noMessage.gif"></emptyPage>
</view>
<home></home>
</view>
</template>
<script>
import {
getReplyList,
getReplyConfig,
getReplyPraise,
getUnReplyPraise
} from '@/api/store.js';
import colors from '@/mixins/color.js';
import {toLogin} from '@/libs/login.js';
import {mapGetters} from "vuex";
import {HTTP_REQUEST_URL} from '@/config/app';
import emptyPage from '@/components/emptyPage.vue';
export default {
mixins: [colors],
computed: mapGetters(['isLogin']),
data() {
return {
tabList: [{
title: '全部',
type: 0,
count: ''
},
{
title: '好评',
type: 3,
count: ''
},
{
title: '中评',
type: 2,
count: ''
},
{
title: '差评',
type: 1,
count: ''
},
],
replyData: {},
product_id: 0,
reply: [],
type: 0,
loading: false,
loadend: false,
loadTitle: '加载更多',
page: 1,
limit: 20,
imgHost: HTTP_REQUEST_URL,
isShowAuth: false,
};
},
components:{ emptyPage },
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
let that = this;
if (!options.product_id) return that.$util.Tips({
title: '缺少参数'
}, {
tab: 3,
url: 1
});
that.product_id = options.product_id;
},
onShow() {
uni.removeStorageSync('form_type_cart');
this.getProductReplyCount();
this.loadend = false;
this.page = 1;
this.reply = [];
this.getProductReplyList();
},
methods: {
replyFun(e) {
this.reply = e;
},
changeLogin() {
toLogin()
},
onLoadFun() {
this.isShowAuth = false
},
// 授权关闭
authColse: function(e) {
this.isShowAuth = e
},
/**
* 获取评论统计数据
*
*/
getProductReplyCount: function() {
let that = this;
getReplyConfig(that.product_id).then(res => {
that.$set(that, 'replyData', res.data);
this.tabList[0].count = res.data.sum_count;
this.tabList[1].count = res.data.good_count;
this.tabList[2].count = res.data.in_count;
this.tabList[3].count = res.data.poor_count;
});
},
/**
* 分页获取评论
*/
getProductReplyList: function() {
let that = this;
if (that.loadend) return;
if (that.loading) return;
that.loading = true;
that.loadTitle = '';
getReplyList(that.product_id, {
page: that.page,
limit: that.limit,
type: that.type,
}).then(res => {
let list = res.data,
loadend = list.length < that.limit;
that.reply = that.$util.SplitArray(list, that.reply);
that.$set(that, 'reply', that.reply);
that.loading = false;
that.loadend = loadend;
that.loadTitle = loadend ? "没有更多内容啦~" : "加载更多";
that.page = that.page + 1;
}).catch(err => {
that.loading = false,
that.loadTitle = '加载更多'
});
},
/*
* 点击事件切换
* */
changeType: function(e) {
let type = parseInt(e);
if (type == this.type) return;
this.type = type;
this.page = 1;
this.loadend = false;
this.$set(this, 'reply', []);
this.getProductReplyList();
},
goPage(id) {
uni.navigateTo({
url: '/pages/goods/goods_comment_con/comment_con?id=' + id
})
},
tapPraise(item) {
if (item.is_praise) {
getUnReplyPraise(item.id).then(res => {
item.is_praise = !item.is_praise;
item.praise = item.praise - 1;
return this.$util.Tips({
title: res.msg
});
});
} else {
getReplyPraise(item.id).then(res => {
item.is_praise = !item.is_praise;
item.praise = item.praise + 1;
return this.$util.Tips({
title: res.msg
});
});
}
},
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function() {
this.getProductReplyList();
},
onPageScroll(object) {
uni.$emit('scroll');
},
}
</script>
<style lang="scss">
.emptyBox {
text-align: center;
margin-top: 40rpx;
.tips {
color: #aaa;
font-size: 26rpx;
}
image {
width: 414rpx;
height: 336rpx;
}
}
.active {
background: var(--view-minorColorT);
border: 1rpx solid var(--view-theme);
color: var(--view-theme);
}
.text-primary-con {
color: var(--view-theme);
}
.tab_item~.tab_item {
margin-left: 16rpx;
}
.vip{
width: 64rpx;
height: 26rpx;
background: #FEF0D9;
border: 1px solid #FACC7D;
border-radius: 50rpx;
font-size: 18rpx;
font-weight: 500;
color: #DFA541;
margin-left: 10rpx;
.iconfont {
font-size: 16rpx;
margin-right: 4rpx;
}
}
.svip-border{
border: 2rpx solid #F1BB0D;
}
.vip-badge{
position: absolute;
top: -16rpx;
right: -8rpx;
width: 32rpx;
height: 30rpx;
}
</style>

View File

@@ -0,0 +1,763 @@
<template>
<!-- 商品列表 -->
<view :style="colorStyle">
<view class="header_box fixed-lt w-full z-20 bg--w111-fff" :style="{'padding-top': sysHeight + 'px'}">
<view class="h-80 px-20 flex-y-center">
<text class="iconfont icon-ic_leftarrow fs-40 mr-16" @tap="goBack"></text>
<!-- #ifdef MP-WEIXIN -->
<view class="w-438 h-58 rd-30 bg--w111-f5f5f5 flex-y-center px-32 relative">
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<view class="flex-1 h-58 rd-30 bg--w111-f5f5f5 flex-y-center px-32 relative">
<!-- #endif -->
<text class="iconfont icon-ic_search fs-24"></text>
<input v-model="where.keyword" class="pl-18 w-460 line1 fs-24" placeholder="请输入商品名称" @confirm="searchSubmit" />
<text class="iconfont icon-ic_close1 fs-28 text--w111-999 z-10" v-if="where.keyword" @tap="clearWord"></text>
</view>
<text class="pl-16" @tap="searchSubmit">搜索</text>
</view>
<scroll-view scroll-x="true" class="white-nowrap vertical-middle w-full pl-32"
show-scrollbar="false" v-if="cateSearch">
<view class="inline-block fs-30 h-80 lh-80rpx mr-40"
v-for="item in filterCateList" :key="item.id"
:class="item.id == where.sid ? 'text-primary-con fw-500 fs-32' : ''"
@tap="cateCheck(item)">{{item.cate_name}}</view>
</scroll-view>
<view class="h-88 px-32 flex-between-center relative">
<view class="text--w111-333 fw-500 select_cate relative" v-if="!cateSearch && title">{{title}}</view>
<view class="text--w111-333 fs-26 fw-500 flex-y-center" v-else @tap="toggleSortable">
<text>综合排序</text>
<text class="iconfont icon-ic_down2 fs-14 ml-6"></text>
</view>
<view class="text--w111-666 flex-y-center fs-26" @tap='set_where(3)'>
<text :class="[1,2].includes(stock) ? 'text-primary-con' : ''">销量</text>
<text v-show="stock==2" class="iconfont icon-ic_down2 fs-14 ml-6 text-primary-con"></text>
<text v-show="stock==1" class="iconfont icon-ic_up2 fs-14 ml-6 text-primary-con"></text>
<text v-show="stock==0" class="iconfont icon-ic_down2 fs-14 ml-6"></text>
</view>
<view class="text--w111-666 flex-y-center fs-26" @tap='set_where(2)'>
<text :class="[1,2].includes(price) ? 'text-primary-con' : ''">价格</text>
<text v-show="price==2" class="iconfont icon-ic_down2 fs-14 ml-6 text-primary-con"></text>
<text v-show="price==1" class="iconfont icon-ic_up2 fs-14 ml-6 text-primary-con"></text>
<text v-show="price==0" class="iconfont icon-ic_down2 fs-14 ml-6"></text>
</view>
<view class="text--w111-666 flex-y-center fs-26">
<text class="iconfont" :class="is_switch ? 'icon-a-ic_Imageandtextsorting' : 'icon-a-ic_QRcode'" @tap='Changswitch'></text>
<text class="menu_line"></text>
<view @tap="showFilterDrawer = true">筛选</view>
<text class="iconfont icon-ic_sort pl-8" @tap="showFilterDrawer = true"></text>
</view>
<view class="sortable-box w-full bg--w111-fff rd-b-24rpx z-999" v-if="showSortAbleBox">
<view class="flex-between-center pb-40"
v-for="(item, index) in sortableShowTab" :key="index" @tap="checkSortable(item.value)">
<text class="fs-26" :class="item.value == where.defaultOrder ? 'text-primary-con' : 'text--w111-333'">{{item.title}}</text>
<image class="w-28 h-28" src="../static/dui-icon.png" v-show="item.value == where.defaultOrder"></image>
</view>
</view>
</view>
<view class="py-16 flex-y-center bg--w111-fff" v-if="(promotionList.length && !cateSearch) || where.promotions_id">
<scroll-view scroll-x="true" class="white-nowrap vertical-middle w-full" show-scrollbar="false">
<view
class="inline-block op-border ml-24 h-48 lh-48rpx bg--w111-f5f5f5 px-24 rd-24 text-center fs-22 text--w111-333"
v-for="item in promotionList" :key="item.id"
:class="where.promotions_id == item.id ? 'active' : ''"
@tap="promotionTap(item)">
<text class="w-full line1 text-center">{{item.desc}}</text>
</view>
</scroll-view>
</view>
</view>
<view class="pt-16 pl-20 pr-20 bg--w111-fff" :style="{'margin-top':marTop + 'rpx'}" v-if="is_switch==false">
<view class="flex mb-32 pro_item" v-for="(item,index) in tempArr" :key="index" @tap="goDetail(item)">
<view class="list-pic w-240 h-240 relative">
<easy-loadimage
:image-src="item.image"
:borderSrc="item.activity_frame.image"
width="240rpx"
height="240rpx"
borderRadius="20rpx"></easy-loadimage>
</view>
<view class="flex-1 pl-20 flex-col justify-between">
<view class="w-full">
<view class="w-full line2 fs-28 text--w111-333 lh-40rpx">
<text v-if="item.brand_name" class="brand-tag">{{ item.brand_name }}</text>{{item.store_name}}
</view>
<view class="w-full flex items-end flex-wrap mt-16">
<BaseTag
:text="label.label_name"
:color="label.color"
:background="label.bg_color"
:borderColor="label.border_color"
:circle="label.border_color ? true : false"
:imgSrc="label.icon"
v-for="(label, idx) in item.store_label" :key="idx"></BaseTag>
</view>
</view>
<view class="flex-y-center">
<baseMoney :money="item.price" symbolSize="24" integerSize="40" decimalSize="24" weight></baseMoney>
<view class="inline-block h-26 lh-28rpx rd-14rpx bg--w111-F7E9CD fs-22 ml-8" v-if="Number(item.vip_price) > 0">
<text class="inline-block h-26 lh-28rpx svip_rd fs-18 bg--w111-484643 text--w111-FDDAA4 px-8">SVIP</text>
<text class="px-8 fs-22">¥{{item.vip_price}}</text>
</view>
</view>
<view class="flex-between-center">
<view class="text--w111-999 fs-22">
<text>已售{{item.sales}}件</text>
<text class="pl-16">评分 {{item.star}}</text>
</view>
<view class="w-44 h-44 rd-24 bg-gradient flex-center" @tap.stop="addCartTap(item)">
<text class="iconfont icon-ic_ShoppingCart1 text--w111-fff fs-26"></text>
</view>
</view>
</view>
</view>
<view class='loadingicon acea-row row-center-wrapper' v-if='tempArr.length > 0'>
<text class='loading iconfont icon-jiazai' :hidden='loading==false'></text>{{loadTitle}}
</view>
</view>
<view class="p-20 relative" :style="{'margin-top':marTop + 'rpx'}" v-else>
<view class="jinabian"></view>
<waterfallsFlow ref="waterfallsFlow" :wfList="tempArr" @itemTap="goDetail"></waterfallsFlow>
</view>
<view class='px-20' v-if="tempArr.length==0 && where.page > 1">
<emptyPage :title="where.keyword ? '无搜索结果,换个词试试吧' : '暂无商品,去看点别的吧~'"
:src="where.keyword ? '/statics/images/noSearch.gif' : '/statics/images/empty-box.gif'"></emptyPage>
<recommend :hostProduct="hostProduct"></recommend>
</view>
<view class="fixed-lb w-full pb-safe bg--w111-fff z-101"
v-if="promotionList.length && where.promotions_id">
<view class="w-full h-108 px-20 flex-between-center">
<view class="flex-y-center" @tap="getCartList(0)">
<view class="w-80 h-80 rd-50-p111- flex-center cart-icon relative">
<text class="iconfont icon-ic_ShoppingCart1 fs-48"></text>
<uni-badge class="badge-style" v-if="cart_num > 0" :text="cart_num"></uni-badge>
</view>
<view class="ml-24">
<view class="flex-y-center">
<text class="fs-28 fw-500">小计:</text>
<baseMoney :money="discountInfo.deduction.pay_price" symbolSize="28" integerSize="40" decimalSize="28"
incolor="#333" weight></baseMoney>
</view>
<view class="fs-24 lh-34rpx text--w111-999"
v-if="discountInfo.deduction.sum_price"
>已优惠¥{{$util.$h.Sub(discountInfo.deduction.sum_price,discountInfo.deduction.pay_price)}}</view>
</view>
</view>
<view class="w-176 h-72 rd-40rpx flex-center text--w111-fff fs-26 fw-500 bg-gradient"
@tap="subOrder">去结算({{cart_num}})</view>
</view>
</view>
<productWindow
:attr="attr"
:isShow='1'
:iSplus='1'
:iScart='1'
:type="2"
:storeInfo='storeInfo'
@myevent="onMyEvent"
@ChangeAttr="ChangeAttr"
@ChangeCartNum="ChangeCartNumDuo"
@attrVal="attrVal"
@iptCartNum="iptCartNum"
@goCat="goCatNum"
id='product-window'
:is_vip="is_vip" :fangda='false'></productWindow>
<cartList
:cartData="cartData"
:hideEmpty="false"
@closeList="closeList"
@ChangeCartNumDan="ChangeCartList"
@ChangeSubDel="ChangeClearCart"
@ChangeOneDel="ChangeOneDel">
</cartList>
<filterDrawer
:visible="showFilterDrawer"
:promotionId="where.promotions_id"
:brandList="brandList"
:labelList="labelList"
:promotionList="promotionList"
@closeDrawer="()=>{showFilterDrawer = false}"
@filterChange="filterConfirm"></filterDrawer>
<view class="mask" v-if="showSortAbleBox" @tap="showSortAbleBox = false"></view>
<home></home>
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight;
import homeList from '@/components/homeList';
import productWindow from '@/components/productWindow';
import waterfallsFlow from "@/components/WaterfallsFlow/WaterfallsFlow.vue";
import {
getProductslist,
getProductHot,
searchFilterApi,
levelCategoryApi,
getAttr,
postCartAdd,
postCartNum
} from '@/api/store.js';
import {cartDel} from "@/api/order.js";
import { toLogin } from '@/libs/login.js';
import recommend from '@/components/recommend';
import cartList from '@/components/cartList';
import filterDrawer from '../components/filterDrwer/index.vue';
import emptyPage from '@/components/emptyPage.vue';
import { mapGetters } from "vuex";
import { goShopDetail } from '@/libs/order.js';
import { vcartList, getCartCounts, cartCompute } from '@/api/order.js';
import colors from '@/mixins/color.js';
import skuSelect from '@/mixins/skuSelect.js'
import { HTTP_REQUEST_URL } from '@/config/app';
export default {
computed: {
...mapGetters(['uid', 'isLogin'])
},
components: {
recommend,
homeList,
waterfallsFlow,
productWindow,
filterDrawer,
emptyPage,
cartList
},
mixins: [colors, skuSelect],
data() {
return {
id: 0,
productValue: [], //系统属性
is_vip: 0, //是否是会员
attr: {
cartAttr: false,
productAttr: [],
productSelect: {}
},
attrValue: '', //已选属性
storeName: '',
sysHeight: sysHeight,
goodList: true,
currentPage: false,
tempArr: [],
is_switch: true,
where: {
sid: 0,
keyword: '',
priceOrder: '',
salesOrder: '',
news: 0,
page: 1,
limit: 10,
cid: 0,
tid: 0,
brand_id: '',
promotions_id: 0,
promotions_type:0,
defaultOrder:0
},
price: 0,
stock: 0,
nows: false,
loadend: false,
loading: false,
loadTitle: '加载更多',
title: '',
hostProduct: [],
hotPage: 1,
hotLimit: 10,
hotScroll: false,
brandList: [],
promotionList:[],
labelList:[],
filterCateList:[],
storeInfo: {},
totalPrice: 0,
promotionsInfo: {},
totalNum: 0,
imgHost: HTTP_REQUEST_URL,
isShowAuth: false,
marTop:'',
showFilterDrawer:false,
cateSearch:false,
showSortAbleBox:false,
sortableShowTab:[
{title:'综合排序',value:0},
{title:'好评优先',value:1},
{title:'新品优先',value:2},
],
cartData: {
cartList: [],
iScart: false
},
cart_num: 0,
discountInfo:{
deduction:{},
}
};
},
provide() {
return {
addCartClick: this.addCartTap,
isVip: false
};
},
onLoad: function(options) {
this.where.cid = options.cid || 0;
this.$set(this.where, 'sid', options.sid || 0);
this.$set(this.where, 'tid', options.tid || 0);
this.title = options.title || '';
this.$set(this.where, 'keyword', options.searchValue || '');
this.$set(this.where, 'productId', options.productId || '');
this.$set(this.where, 'brand_id', options.brandId || 0);
if (options.promotions_type) {
this.where.promotions_type = options.promotions_type;
this.where.promotions_id = options.promotions_id;
}
if(options.sid && options.sid != 0){
//用于判断顶部分类选择内容是否展示
this.cateSearch = true;
this.getProCate();
}
this.getProductList();
this.getSearchFilter();
},
methods: {
addCartTap(data){
if(data.spec_type){
this.goCartDuo(data);
}else{
this.goCartDan(data, 0, true);
}
},
// 购物车计算
getCartCompute(cartId) {
cartCompute({cartId}).then(res => {
this.discountInfo.deduction = res.data.deduction;
}).catch(err => {
this.$util.Tips({
title: err
})
})
},
getTotalPrice(){
vcartList().then(res => {
if (res.data.length) {
let cartId = res.data.map(item=> item.id).join(',');
this.getCartCompute(cartId);
}
})
},
getCartList(iSshow) {
let that = this;
vcartList().then(res => {
that.$set(that.cartData, 'cartList', res.data);
if (res.data.length) {
that.$set(that.cartData, 'iScart', iSshow ? false : !that.cartData.iScart);
let cartId = res.data.map(item=> item.id).join(',');
that.getCartCompute(cartId);
} else {
that.$set(that.cartData, 'iScart', false);
}
if (!res.data.length) {
this.$store.commit('indexData/setCartNum', 0);
this.tempArr.forEach((item) => {
item.cart_num = 0
})
}
})
},
getCartNum() {
let that = this;
getCartCounts().then(res => {
this.cart_num = res.data.count;
this.$store.commit('indexData/setCartNum', res.data.count)
});
},
goCart() {
if (this.where.promotions_type) {
uni.switchTab({
url: '/pages/order_addcart/order_addcart'
})
} else {
uni.switchTab({
url: '/pages/goods_cate/goods_cate'
})
}
},
// 商品详情接口;
getAttrs(id) {
let that = this;
getAttr(id, 0).then(res => {
uni.hideLoading();
that.$set(that.attr, 'productAttr', res.data.productAttr);
that.$set(that, 'productValue', res.data.productValue);
that.$set(that, 'is_vip', res.data.storeInfo.is_vip);
that.$set(that, 'storeInfo', res.data.storeInfo);
that.DefaultSelect();
})
},
getProCate(){
levelCategoryApi({id:this.where.sid}).then(res=>{
this.filterCateList = res.data;
})
},
// 筛选
getSearchFilter() {
let data = {
keyword: this.where.keyword,
cid: this.where.cid,
sid: this.where.sid,
tid: this.where.tid,
productId: this.where.productId,
promotions_type: this.where.promotions_type,
// promotions_id: this.where.promotions_id
};
searchFilterApi(data).then(res => {
this.brandList = res.data.brand;
this.labelList = res.data.store_label;
this.promotionList = res.data.promotions;
if(res.data.promotions.length && this.isLogin){
this.getCartList(1);
this.getCartNum();
}
this.getMarTop();
}).catch(err => {
return this.$util.Tips({
title: err.msg
});
})
},
toggleSortable(){
this.showSortAbleBox = !this.showSortAbleBox;
},
checkSortable(val){
this.where.defaultOrder = val;
this.showSortAbleBox = false;
this.loadend = false;
this.$set(this.where, 'page', 1);
this.getProductList(true);
},
promotionTap(item){
this.where.promotions_id = this.where.promotions_id == 0 ? item.id : 0;
this.loadend = false;
this.$set(this.where, 'page', 1);
this.getProductList(true);
},
clearWord(){
this.where.keyword = ''
},
cateCheck(item){
this.where.sid = item.id;
this.loadend = false;
this.$set(this.where, 'page', 1);
this.getProductList(true);
},
filterConfirm(data){
this.showFilterDrawer = false;
Object.assign(this.where,data);
this.loadend = false;
this.$set(this.where, 'page', 1);
this.getProductList(true);
},
// 去详情页
goDetail(item) {
this.currentPage = false;
goShopDetail(item, this.uid).catch(res => {
uni.navigateTo({
url: `/pages/goods_details/index?id=${item.id}`
});
});
},
Changswitch: function() {
let that = this;
this.currentPage = false
that.is_switch = !that.is_switch
},
searchSubmit: function(e) {
let that = this;
this.currentPage = false
that.loadend = false;
that.$set(that.where, 'page', 1)
this.getProductList(true);
this.getSearchFilter();
},
search(){
},
/**
* 获取我的推荐
*/
get_host_product: function() {
let that = this;
if (that.hotScroll) return
getProductHot({
page:that.hotPage,
limit:that.hotLimit,
}).then(res => {
that.hotPage++
that.hotScroll = res.data.list.length < that.hotLimit
that.hostProduct = that.hostProduct.concat(res.data.list)
// that.$set(that, 'hostProduct', res.data)
});
},
//点击事件处理
set_where: function(e) {
this.currentPage = false
switch (e) {
case 1:
// #ifdef H5
return history.back();
// #endif
// #ifndef H5
return uni.navigateBack({
delta: 1,
})
// #endif
break;
case 2:
if (this.price == 0) this.price = 1;
else if (this.price == 1) this.price = 2;
else if (this.price == 2) this.price = 0;
this.stock = 0;
break;
case 3:
if (this.stock == 0) this.stock = 1;
else if (this.stock == 1) this.stock = 2;
else if (this.stock == 2) this.stock = 0;
this.price = 0
break;
case 4:
this.nows = !this.nows;
break;
}
this.loadend = false;
this.$set(this.where, 'page', 1);
this.getProductList(true);
},
//设置where条件
setWhere: function() {
if (this.price == 0) this.where.priceOrder = '';
else if (this.price == 1) this.where.priceOrder = 'asc';
else if (this.price == 2) this.where.priceOrder = 'desc';
if (this.stock == 0) this.where.salesOrder = '';
else if (this.stock == 1) this.where.salesOrder = 'asc';
else if (this.stock == 2) this.where.salesOrder = 'desc';
this.where.news = this.nows ? 1 : 0;
},
productslist(){
},
//查找产品
getProductList: function(isPage) {
let that = this;
that.setWhere();
if (that.loadend) return;
if (that.loading) return;
if (isPage === true) {
that.$set(that, 'tempArr', []);
}
that.loading = true;
that.loadTitle = '';
getProductslist(that.where).then(res => {
let list = res.data;
let productList = that.$util.SplitArray(list, that.tempArr);
let loadend = list.length < that.where.limit;
that.loadend = loadend;
that.loading = false;
that.loadTitle = loadend ? '没有更多内容啦~' : '加载更多';
that.$set(that, 'tempArr', productList);
that.$set(that.where, 'page', that.where.page + 1);
if (!that.tempArr.length) this.get_host_product();
}).catch(err => {
that.loading = false;
that.loadTitle = '加载更多';
});
},
getMarTop(){
if(this.promotionList.length || this.filterCateList.length){
this.$nextTick(()=>{
this.marTop = (115 + sysHeight) * 2;
})
}else{
this.$nextTick(()=>{
this.marTop = (75 + sysHeight) * 2
})
}
},
// 生成订单;
subOrder() {
let that = this,
list = that.cartData.cartList,
ids = [];
if (list.length) {
list.forEach(item => {
if (item.attrStatus && item.status) {
ids.push(item.id)
}
});
uni.navigateTo({
url: '/pages/goods/order_confirm/index?cartId=' + ids.join(',')
});
that.cartData.iScart = false;
} else {
return that.$util.Tips({
title: '请选择产品'
});
}
},
goBack(){
// uni.navigateBack()
let pages = getCurrentPages(); // 获取当前打开过的页面路由数,
if (pages.length > 1) {
uni.navigateBack()
} else {
uni.switchTab({
url: '/pages/index/index'
});
}
},
ChangeClearCart(event){
let that = this,
list = that.cartData.cartList,
ids = [];
list.forEach(item => {
ids.push(item.id)
});
cartDel(ids.join(",")).then(res => {
that.$set(that.cartData, 'cartList', []);
that.cartData.iScart = false;
that.discountInfo.deduction.pay_price = 0;
that.discountInfo.deduction.sum_price = 0;
that.getCartNum();
})
},
},
onPageScroll(e) {
this.currentPage = false;
uni.$emit('scroll');
},
onReachBottom() {
if (this.tempArr.length > 0) {
this.getProductList();
} else {
this.get_host_product();
}
},
onPullDownRefresh() {
if (this.tempArr.length > 0) {
this.getProductList();
} else {
this.get_host_product();
}
setTimeout(function () {
uni.stopPullDownRefresh();
}, 1000);
},
}
</script>
<style scoped lang="scss">
.z-200{
z-index: 200;
}
.z-101{
z-index: 101;
}
.pro_item ~ .pro_item{
margin-top: 32rpx;
}
.border-picture {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 16rpx 16rpx 0 0;
background: center/cover no-repeat;
}
.menu_line {
width: 1px;
height: 30rpx;
background: #B3B3B3;
margin: 0 20rpx;
}
.icon-ic_close1{
position: absolute;
right: 34rpx;
top: 50%;
transform: translateY(-50%);
}
.select_cate{
&:after{
content: '';
position: absolute;
top: 42rpx;
left:50%;
transform: translateX(-50%);
width:36rpx;
height:10rpx;
background-image: url('../static/select_zs.png');
background-size: 100%;
}
}
.jinabian{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 330rpx;
background: linear-gradient(180deg, #FFFFFF 0%, rgba(255,255,255,0) 100%);
}
.info_box{
padding: 16rpx 20rpx;
border-radius: 0 0 20rpx 20rpx;
background-color: #fff;
}
.text-primary-con{
color: var(--view-theme);
}
.bg-primary-light{
background: var(--view-minorColorT);
}
.bg--w111-484643{
background: linear-gradient(90deg, #484643 0%, #1F1B17 100%);
}
.text--w111-FDDAA4{
color: #FDDAA4;
}
.svip_rd{
border-radius: 14rpx 0 8rpx 14rpx;
}
.op-border{
border: 1px solid #f5f5f5;
}
.active{
border: 1px solid var(--view-theme);
color: var(--view-theme);
background: var(--view-minorColorT);
}
.sortable-box{
padding: 32rpx 32rpx 0;
position: absolute;
top: 88rpx;
left: 0;
}
.cart-icon{
background: #F9F9F9;
border: 2rpx solid #F2F2F2;
}
.badge-style {
position: absolute;
top: -10rpx;
right: -20rpx;
/deep/ .uni-badge--error {
background-color: var(--view-theme) !important;
}
.uni-badge {
color: var(--view-theme);
border: 1px solid var(--view-theme);
z-index: 29;
}
}
</style>

View File

@@ -0,0 +1,322 @@
<template>
<view :style="colorStyle">
<view class="w-full relative header_bg" :style="{'height': (174 + sysHeight) * 2 + 'rpx'}">
<view class="w-full fixed-lt z-99" :style="{'padding-top': sysHeight * 2 + 'rpx'}"
:class="pageScrollStatus ? 'bg--w111-fff' : ''">
<view class="h-80 px-20 flex-between-center">
<text class="iconfont icon-ic_leftarrow fs-40" :class="pageScrollStatus ? 'text--w111-333' : 'text--w111-fff'" @click="goPage(3)"></text>
<text class="fs-34 fw-500" :class="pageScrollStatus ? 'text--w111-333' : 'text--w111-fff'">物流查询</text>
<text></text>
</view>
</view>
<view class="w-full abs-lb white_jianbian"></view>
</view>
<view class="relative px-20 z-20 express_box">
<view class="h-66 rd-t-24rpx light px-24 flex-between-center fs-20">
<text>{{orderInfo.delivery_name}} {{orderInfo.delivery_id}}</text>
<text class="inline-block copy_btn fs-22 text--w111-333" @tap="copyOrderId">复制单号</text>
</view>
<view class="rd-b-24rpx bg--w111-fff flex-between-center">
<view class="w-316 h-142 flex-col flex-center">
<text class="fs-32 fw-500 lh-44rpx">{{orderInfo.user_name}}</text>
<text class="fs-22 text--w111-999 lh-30rpx mt-8">{{orderInfo.user_phone}}</text>
</view>
<view class="flex-1 h-142 flex-center fs-28 fw-500 lh-40rpx relative city-box">
<text>{{orderInfo.send_city}}</text>
<text class="iconfont icon-a-jiantou11 mx-32"></text>
<text>{{orderInfo.user_city}}</text>
</view>
</view>
</view>
<view class="px-20 mt-20">
<view class="bg--w111-fff rd-16rpx pt-32 pr-24 pl-24 pb-32">
<view class="flex-between-center">
<view class="fs-32 fw-500 text--w111-333">
<text>物流详情</text>
</view>
</view>
<view class="logisticsCon mt-50 relative" v-if="expressList.length">
<view class='item' v-for="(item,index) in logisticList" :key="index">
<view class='circular' :class='index === 0 ? "on text-center":""'>
<text class="iconfont icon-ic_complete text--w111-fff fs-24" v-if="index == 0"></text>
</view>
<view class='text' :class='index===0 ? "on-font on":""'>
<view>{{item.status}}</view>
<view class='data' :class='index===0 ? "on-font on":""'>{{item.time}}</view>
</view>
</view>
<view class="more-text fs-24" @tap="checkShowMore">
<text>{{showMore ? '收起' : '查看更多物流信息'}}</text>
<text class="iconfont fs-24 pl-8" :class="showMore ? 'icon-ic_uparrow' : 'icon-ic_downarrow'"></text>
</view>
</view>
<emptyPage title="暂无物流信息" src="/statics/images/noExpress.gif" v-else></emptyPage>
</view>
</view>
<view class="px-20" v-if="product.length">
<view class="bg--w111-fff rd-16rpx mt-20 p-24">
<view class="flex w-full product" v-for="(item,index) in product" :key="index">
<image class="w-120 h-120 rd-16rpx" :src='item.productInfo.image' ></image>
<view class="flex-1 flex justify-between pl-20">
<view class="w-382">
<view class="w-full line2 fs-28 text--w111-333 lh-40rpx">{{item.productInfo.store_name}}</view>
<view class="w-full line1 fs-24 text--w111-999 lh-34rpx mt-20"></view>
</view>
<view class="flex-1 flex-col items-end">
<baseMoney :money="item.truePrice" symbolSize="20" integerSize="36" decimalSize="20" color="#333" weight></baseMoney>
<view class="fs-24 text--w111-999 lh-40rpx mt-10">共{{item.cart_num}}件</view>
</view>
</view>
</view>
</view>
<recommend :hostProduct='hostProduct'></recommend>
</view>
<home></home>
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight;
import { express } from '@/api/order.js';
import { getProductHot } from '@/api/store.js';
import { toLogin } from '@/libs/login.js';
import { mapGetters } from "vuex";
import recommend from '@/components/recommend';
import emptyPage from '@/components/emptyPage.vue';
import colors from "@/mixins/color";
import { HTTP_REQUEST_URL } from '@/config/app';
export default {
components: {
recommend,
emptyPage
},
mixins: [colors],
data() {
return {
sysHeight:sysHeight,
imgHost: HTTP_REQUEST_URL,
orderId: '',
type:'',
product: [],
orderInfo: {},
expressList: [],
hostProduct: [],
isShowAuth: false,
pageScrollStatus:false,
showMore: false
};
},
computed: {
...mapGetters(['isLogin']),
logisticList(){
if(this.showMore){
return this.expressList
}else{
return this.expressList.slice(0,1)
}
}
},
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV) {
//#ifndef MP
this.getExpress();
this.get_host_product();
//#endif
}
},
deep: true
}
},
onLoad: function(options) {
if (!options.orderId) return this.$util.Tips({
title: '缺少订单号'
});
if(typeof(options.type) == 'undefined'){
this.type = ''
}else{
this.type = options.type
}
this.orderId = options.orderId;
if (this.isLogin) {
this.getExpress();
this.get_host_product();
}
},
onPageScroll(object) {
if (object.scrollTop > 100) {
this.pageScrollStatus = true;
} else if (object.scrollTop < 100) {
this.pageScrollStatus = false;
}
uni.$emit('scroll');
},
onShow() {
uni.removeStorageSync('form_type_cart');
if(!this.isLogin){
toLogin()
}
},
methods: {
// 授权关闭
authColse: function(e) {
this.isShowAuth = e
},
/**
* 授权回调
*/
onLoadFun: function() {
this.getExpress();
this.get_host_product();
this.isShowAuth = false;
},
copyOrderId: function() {
uni.setClipboardData({
data: this.orderInfo.delivery_id
});
},
getExpress: function() {
let that = this;
express(that.orderId,this.type).then(function(res) {
that.$set(that, 'product', res.data.order.cartInfo || []);
that.$set(that, 'orderInfo', res.data.order);
that.$set(that, 'expressList', res.data.express || []);
}).catch((error) => {
this.$util.Tips({
title: error
});
});
},
/**
* 获取我的推荐
*/
get_host_product: function() {
let that = this;
getProductHot().then(function(res) {
that.$set(that, 'hostProduct', res.data);
});
},
checkShowMore(){
this.showMore = !this.showMore
},
goPage(type, url){
if(type == 1){
uni.navigateTo({
url
})
}else if(type == 2){
uni.switchTab({
url
})
}else if(type == 3){
uni.navigateBack();
}
},
}
}
</script>
<style scoped lang="scss">
.header_bg{
height: 369rpx;
background: linear-gradient(90deg, #FF7931 0%, #E93323 100%);
}
.white_jianbian{
height:180rpx;
background: linear-gradient(0deg, #F5F5F5 0%, rgba(245,245,245,0) 100%);
}
.light{
background: rgba(255,255,255,0.9);
}
.express_box{
margin-top: -240rpx;
}
.copy_btn{
width: 112rpx;
height: 34rpx;
background: #F5F5F5;
border-radius: 20rpx;
text-align:center;
line-height:34rpx;
}
.city-box{
&:before{
content: '';
width: 1px;
height: 64rpx;
background-color: #eee;
position: absolute;
top: 40rpx;
left: 0;
}
}
.more-text{
position: absolute;
left: 40rpx;
bottom: -12rpx;
&:before{
content: '';
width: 14rpx;
height: 14rpx;
border-radius: 50%;
background-color: #ddd;
position: absolute;
left: -26rpx;
top: 8rpx;
}
}
.logisticsCon .item {
padding: 0 20rpx;
position: relative;
}
.logisticsCon .item .circular {
width: 14rpx;
height: 14rpx;
border-radius: 50%;
position: absolute;
left: 14rpx;
background-color: #ddd;
}
.logisticsCon .item .circular.on {
width: 40rpx;
height: 40rpx;
background-color: var(--view-theme);
left: 0;
}
.logisticsCon .item .text.on-font {
color: var(--view-theme);
}
.logisticsCon .item .text .data.on-font {
color: var(--view-theme);
}
.logisticsCon .item .text {
font-size: 26rpx;
color: #666;
width: 615rpx;
border-left: 1rpx solid #e6e6e6;
padding: 0 0 40rpx 38rpx;
}
.logisticsCon .item .text .data {
font-size: 24rpx;
color: #999;
margin-top: 10rpx;
}
.logisticsCon .item .text .data .time {
margin-left: 15rpx;
}
.z-99{
z-index:99;
}
.product ~ .product{
margin-top: 20rpx;
}
</style>

View File

@@ -0,0 +1,531 @@
<template>
<view :style="colorStyle">
<form @submit="subRefund">
<view class='apply-return'>
<view class="return">
<view class='goodsStyle acea-row row-between' v-for="(item,index) in refundCartInfo" :key="index">
<view class='pictrue'>
<image class="w-136 h-136 rd-16rpx" :src="item.productInfo.image"></image>
</view>
<view class='text'>
<view class="nameCon">
<view class='name line2'>{{item.productInfo.store_name}}</view>
</view>
<view class="num">购买数量:{{item.cart_num}}</view>
</view>
</view>
<view class="tips acea-row row-middle" v-if="refundNum">
<text class="title">售后退款</text>
<text>有{{refundCartInfo.length}}个商品已申请售后</text>
</view>
</view>
<view class='list'>
<view class='item acea-row row-between-wrapper'>
<view>退款金额</view>
<text class="text--w111-333 fs-36 Regular font-color"> -¥{{refund_price}}</text>
</view>
<view class='item acea-row row-between-wrapper'>
<view>售后类型</view>
<view v-if="status && status._type !== 1 && !productType" class="picker acea-row row-between-wrapper" @click="returnTypeTap">
<view class='reason'>{{returnType}}</view>
<text class='iconfont icon-ic_rightarrow'></text>
</view>
<view v-else class="num">仅退款(无需退货)</view>
</view>
<view class='item acea-row row-between-wrapper'>
<view>退货件数</view>
<view class='num' v-if="refundCartInfo.length !== 1 || refund_total_num == 1">
{{refund_total_num}}
</view>
<picker v-else class='num' @change="returnGoodsNum" :value="refund_num_index" :range="refundNumData">
<view class="picker acea-row row-between-wrapper">
<view class='reason'>{{refundNumData[refund_num_index]}}</view>
<text class='iconfont icon-ic_rightarrow'></text>
</view>
</picker>
<!-- <input type="number" v-model="refund_num" @input="inputNumber" v-else /> -->
</view>
<view class='item acea-row row-between-wrapper' v-if="refundReason.RefundArray.length">
<view>申请原因</view>
<view class="num" @click="reasonTap">
<view class="picker acea-row row-between-wrapper">
<view class='reason'>{{refundItem}}</view>
<text class='iconfont icon-ic_rightarrow'></text>
</view>
</view>
</view>
</view>
<view class="list">
<view class='item textarea'>
<view class="acea-row row-between-wrapper">
<view>申请说明</view>
<view class="fontNum">{{fontNum}}/100</view>
</view>
<textarea placeholder='请填写备注说明' placeholder-class="placeholder" maxlength=100 name="refund_reason_wap_explain" @input="sumfontnum"></textarea>
</view>
<view class='item acea-row row-between'>
<view class='upload acea-row row-middle'>
<view class='pictrue' v-for="(item,index) in refund_reason_wap_img" :key="index">
<image :src='item' mode="aspectFill"></image>
<view class='iconfont icon-ic_close' @tap='DelPic(index)'></view>
</view>
<view class='pictrue acea-row row-center-wrapper row-column' @tap='uploadpic'
v-if="refund_reason_wap_img.length < 3">
<image class="img" src="../static/ic_camera.png"></image>
<view>上传凭证</view>
</view>
</view>
</view>
</view>
<view style="height: 140rpx;"></view>
<view class="bntCon flex-center fixed-lb pb-safe">
<button class='returnBnt bg-color' form-type="submit">申请退款</button>
</view>
</view>
</form>
<refundPopup :refundData='refundReason' @changeClose='changeClose' @selectInfo='selectInfo'></refundPopup>
<refundPopup :refundData='returnGoods' @changeClose='changeGoodsClose' @selectInfo='selectGoodsInfo'></refundPopup>
<home></home>
</view>
</template>
<script>
import {
ordeRefundReason,
orderRefundVerify,
getOrderDetail,
returnGoodsSubmit,
postRefundGoods
} from '@/api/order.js';
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from "vuex";
import refundPopup from '../components/refundPopup/index.vue'
import colors from '@/mixins/color.js';
export default {
components: {
refundPopup
},
mixins: [colors],
data() {
return {
id:0,
cartIds:[],
refund_reason_wap_img: [],
status: {},
refundCartInfo: [],
refund_total_num: 0,
orderId: 0,
refundNumData: [],
refund_num_index: 0,
productType:0,
isShowAuth: false,
refund_price:0,
fontNum:0,
refundNum:0,
refundItem:'',
refundReason:{
RefundArray: [],
show:false
},
returnType:'',
returnGoods:{
RefundArray: ['仅退款(无需退货)', '退货退款(快递退回)','退货退款(到店退货)'],
show:false
},
returnGoodsIndex:0
};
},
computed: {
...mapGetters(['isLogin']),
inputWid() {
return function(value) {
if (value == '') {
return '300rpx';
} else {
console.log(String(value).length)
return String(value).length * 16 + 'rpx';
}
};
}
},
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV) {
//#ifndef MP
this.refundGoodsInfo();
this.getRefundReason();
//#endif
}
},
deep: true
}
},
onPageScroll(object) {
uni.$emit('scroll');
},
onLoad(options) {
this.returnType = this.returnGoods.RefundArray[0];
this.orderId = options.orderId;
this.id = options.id;
this.productType = parseInt(options.productType) || 0;
if(options.cartIds){
this.cartIds = JSON.parse(options.cartIds) || []
}
if (this.isLogin) {
this.refundGoodsInfo();
this.getRefundReason();
} else {
toLogin()
}
},
onShow() {
uni.removeStorageSync('form_type_cart');
},
methods: {
onLoadFun(){
this.refundGoodsInfo();
this.getRefundReason();
this.isShowAuth = false
},
// 授权关闭
authColse: function(e) {
this.isShowAuth = e
},
reasonTap(){
this.refundReason.show = true;
},
changeClose(){
this.refundReason.show = false;
},
selectInfo(e){
this.refundItem = this.refundReason.RefundArray[e];
this.changeClose();
},
returnTypeTap(){
this.returnGoods.show = true;
},
changeGoodsClose(){
this.returnGoods.show = false;
},
selectGoodsInfo(e){
this.returnGoodsIndex = e;
this.returnType = this.returnGoods.RefundArray[e];
this.changeGoodsClose();
},
// 限制文本框字数
sumfontnum(e) {
this.fontNum = e.detail.value.length
},
refundGoodsInfo(){
postRefundGoods({id:this.id,cart_ids:this.cartIds}).then(res=>{
let data = res.data;
this.status = data._status;
this.refundCartInfo = data.cartInfo;
this.refundNum = data.refund_num;
this.refundCartInfo.forEach(item=>{
this.refund_total_num = this.$util.$h.Add(this.refund_total_num, item.cart_num);
let price = this.$util.$h.Add(this.refund_price, this.$util.$h.Mul(item.cart_num,item.truePrice));
this.refund_price = price;
})
this.refundNumData = Array(this.refund_total_num).fill(0).map((e, i) => i + 1);
this.refund_num_index = this.refund_total_num - 1;
}).catch(err=>{
return this.$util.Tips({
title: err
});
})
},
/**
* 获取退款理由
*/
getRefundReason: function() {
let that = this;
ordeRefundReason().then(res => {
that.$set(that.refundReason, 'RefundArray', res.data);
this.refundItem = res.data[0];
})
},
/**
* 删除图片
*
*/
DelPic: function(e) {
let index = e,
that = this,
pic = this.refund_reason_wap_img[index];
that.refund_reason_wap_img.splice(index, 1);
that.$set(that, 'refund_reason_wap_img', that.refund_reason_wap_img);
},
/**
* 上传文件
*
*/
uploadpic: function() {
let that = this;
this.$util.uploadImageOne('upload/image', function(res) {
that.refund_reason_wap_img.push(res.data.url);
that.$set(that, 'refund_reason_wap_img', that.refund_reason_wap_img);
});
},
/**
* 申请退货
*/
subRefund: function(e) {
let that = this,
value = e.detail.value;
//收集form表单
// if (!value.refund_reason_wap_explain) return this.$util.Tips({
// title: '请输入申请说明'
// });
let cartInfo = this.refundCartInfo;
if(cartInfo.length === 1){
this.cartIds = [
{
cart_id:cartInfo[0].id,
cart_num: this.refund_num_index + 1
}
]
}
returnGoodsSubmit(this.id, {
text: that.refundItem || '',
refund_reason_wap_explain: value.refund_reason_wap_explain,
refund_reason_wap_img: that.refund_reason_wap_img.join(','),
refund_type: parseInt(this.returnGoodsIndex)+1,
uni: that.orderId,
cart_ids: this.cartIds,
refund_price: this.refund_price
}).then(res => {
return this.$util.Tips({
title: '申请成功',
icon: 'success'
}, {
tab: 5,
url: '/pages/users/user_return_list/index?isT=1'
});
}).catch(err => {
return this.$util.Tips({
title: err
});
})
},
returnGoodsNum(e) {
let num = Number(e.detail.value);
this.$set(this, 'refund_num_index', num);
let price = this.$util.$h.Mul(this.refundNumData[num],this.refundCartInfo[0].truePrice);
this.refund_price = price;
}
}
}
</script>
<style scoped lang="scss">
.apply-return{
.return{
width: 710rpx;
background: #FFFFFF;
border-radius: 24rpx;
margin: 20rpx auto 0 auto;
padding-bottom: 32rpx;
.tips{
width: 662rpx;
height: 72rpx;
background: #F5F5F5;
border-radius: 8rpx;
margin: 32rpx auto 0 auto;
padding: 0 20rpx;
color: #999999;
font-size: 26rpx;
.title{
color: #333333;
margin-right: 20rpx;
}
}
}
.goodsStyle{
padding: 32rpx 24rpx 0 24rpx;
border-radius: 24rpx;
.pictrue{
width: 136rpx;
height: 136rpx;
border-radius: 16rpx;
image{
border-radius: 16rpx;
}
}
.text{
width: 504rpx;
font-size: 24rpx;
font-weight: 400;
.nameCon{
height: 104rpx;
.name{
font-size: 28rpx;
color: #333;
}
}
.num{
color: #999999;
}
}
}
}
.apply-return .list {
background-color: #fff;
width: 710rpx;
border-radius: 16rpx;
margin: 20rpx auto 0 auto;
padding: 1rpx 24rpx 32rpx 24rpx;
}
.apply-return .list .item {
font-size: 28rpx;
color: #333;
margin-top: 32rpx;
.fontNum{
font-size: 24rpx;
color: #999;
}
.placeholder{
font-size: 26rpx;
color: #CCCCCC;
}
}
.apply-return .list .item .num {
color: #282828;
width: 427rpx;
text-align: right;
.iconfont{
color: #999;
font-size: 30rpx;
margin-left: 12rpx;
}
.label{
color: var(--view-theme);
font-size: 32rpx;
}
}
.apply-return .list .item .num .picker .reason {
width: 385rpx;
}
.apply-return .list .item .num .picker .iconfont {
color: #999;
font-size: 30rpx;
margin-top: 2rpx;
}
.apply-return .list .item textarea {
height: 166rpx;
margin-top: 24rpx;
font-size: 26rpx;
}
.apply-return .list .item .placeholder {
color: #bbb;
}
.apply-return .list .item .title {
height: 95rpx;
width: 100%;
}
.apply-return .list .item .title .tip {
font-size: 30rpx;
color: #bbb;
}
.apply-return .list .item .upload .pictrue {
margin: 22rpx 23rpx 0 0;
width: 156rpx;
height: 156rpx;
position: relative;
font-size: 24rpx;
color: #bbb;
border-radius: 16rpx;
.img{
width: 48rpx;
height: 48rpx;
margin-bottom: 8rpx;
}
}
.apply-return .list .item .upload .pictrue:nth-of-type(4n) {
margin-right: 0;
}
.apply-return .list .item .upload .pictrue image {
width: 100%;
height: 100%;
border-radius: 16rpx;
}
.apply-return .list .item .upload .pictrue .icon-ic_close {
position: absolute;
font-size: 24rpx;
top: 0;
right: 0;
width: 32rpx;
height: 32rpx;
background: #999999;
border-radius: 0 16rpx 0 16rpx;
text-align: center;
line-height: 32rpx;
color: #fff;
}
.apply-return .list .item .upload .pictrue .icon-icon25201 {
color: #bfbfbf;
font-size: 50rpx;
}
.apply-return .list .item .upload .pictrue:nth-last-child(1) {
width: 148rpx;
height: 148rpx;
background: #F5F5F5;
font-size: 24rpx;
color: #333;
}
.apply-return .bntCon{
width: 100%;
height: 120rpx;
background: #FFFFFF;
}
.apply-return .returnBnt {
font-size: 28rpx;
color: #fff;
width: 710rpx;
height: 80rpx;
border-radius: 50rpx;
text-align: center;
line-height: 80rpx;
}
.goodsStyle .text .name {
align-self: flex-start;
}
.list /deep/ .uni-input-input {
text-align: right;
color: var(--view-theme);
font-weight: 400;
font-size: 36rpx;
max-width: 300rpx;
font-family: 'Regular';
}
.Regular{
font-family: 'Regular';
}
</style>

View File

@@ -0,0 +1,251 @@
<template>
<view :style="colorStyle">
<view class='apply-return'>
<splitOrder :splitGoods="returnGoodsList" @getList="getCheckList" :select_all="false"></splitOrder>
<view style="height: 140rpx;"></view>
<view class="bntCon acea-row row-center-wrapper">
<button class='returnBnt bg-color' @click="subRefund">申请退款</button>
</view>
</view>
<home></home>
</view>
</template>
<script>
import {
refundGoodsList
} from '@/api/order.js';
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from "vuex";
import splitOrder from '@/components/splitOrder';
import colors from '@/mixins/color.js';
export default {
components: {
splitOrder
},
mixins: [colors],
data() {
return {
returnGoodsList: [],
id: 0,
cartList: [],
orderId: "",
isShowAuth: false
};
},
computed: mapGetters(['isLogin']),
watch: {
isLogin: {
handler: (newV, oldV) => {
if (newV) {
// this.getGoodsList();
}
},
deep: true
}
},
onLoad(options) {
if (!options.id) return this.$util.Tips({
title: '缺少订单id,无法选择商品'
}, {
tab: 3,
url: 1
});
this.id = options.id;
this.orderId = options.orderId;
},
onShow() {
uni.removeStorageSync('form_type_cart');
this.cartList = []
this.returnGoodsList = []
if (this.isLogin) {
this.getGoodsList();
} else {
toLogin()
}
},
methods: {
/**
* 获取商品列表
*/
getGoodsList() {
let that = this;
refundGoodsList(that.id).then(res => {
let list = res.data,goods = []
list.forEach((item) => {
item.checked = false
item.numShow = item.surplus_num
if(!item.is_gift){
goods.push(item)
}
})
that.$set(that, 'returnGoodsList', goods);
});
},
getCheckList(val) {
let that = this;
that.returnGoodsList = val;
this.cartList = [];
val.forEach((item) => {
if (item.checked) {
// item.cart_num = item.surplus_num
this.cartList.push({
cart_id:item.cart_id,
cart_num:item.surplus_num
})
}
})
},
/**
* 申请退货
*/
subRefund(e) {
let that = this
//收集form表单
if (!this.cartList.length) return this.$util.Tips({
title: '请先选择退货商品'
});
let obj = JSON.stringify(this.cartList);
uni.navigateTo({
url: `/pages/goods/goods_return/index?orderId=` + this.orderId + '&id=' + this.id + '&cartIds=' + obj
})
}
},
onPageScroll(object) {
uni.$emit('scroll');
},
}
</script>
<style scoped lang="scss">
/deep/.splitOrder uni-checkbox .uni-checkbox-input.uni-checkbox-input-checked{
border: 1px solid var(--view-theme)!important;
background-color: var(--view-theme)!important;
}
/deep/.splitOrder checkbox .wx-checkbox-input.wx-checkbox-input-checked{
border: 1px solid var(--view-theme)!important;
background-color: var(--view-theme)!important;
}
.apply-return .list {
background-color: #fff;
margin-top: 18rpx;
}
.apply-return .list .item {
margin-left: 30rpx;
padding-right: 30rpx;
min-height: 90rpx;
border-bottom: 1rpx solid #eee;
font-size: 30rpx;
color: #333;
}
.apply-return .list .item .num {
color: #282828;
width: 427rpx;
text-align: right;
}
.apply-return .list .item .num .picker .reason {
width: 385rpx;
}
.apply-return .list .item .num .picker .iconfont {
color: #666;
font-size: 30rpx;
margin-top: 2rpx;
}
.apply-return .list .item.textarea {
padding: 30rpx 30rpx 30rpx 0;
}
.apply-return .list .item textarea {
height: 100rpx;
font-size: 30rpx;
}
.apply-return .list .item .placeholder {
color: #bbb;
}
.apply-return .list .item .title {
height: 95rpx;
width: 100%;
}
.apply-return .list .item .title .tip {
font-size: 30rpx;
color: #bbb;
}
.apply-return .list .item .upload {
padding-bottom: 36rpx;
}
.apply-return .list .item .upload .pictrue {
margin: 22rpx 23rpx 0 0;
width: 156rpx;
height: 156rpx;
position: relative;
font-size: 24rpx;
color: #bbb;
}
.apply-return .list .item .upload .pictrue:nth-of-type(4n) {
margin-right: 0;
}
.apply-return .list .item .upload .pictrue image {
width: 100%;
height: 100%;
border-radius: 3rpx;
}
.apply-return .list .item .upload .pictrue .icon-guanbi1 {
position: absolute;
font-size: 45rpx;
top: -10rpx;
right: -10rpx;
}
.apply-return .list .item .upload .pictrue .icon-icon25201 {
color: #bfbfbf;
font-size: 50rpx;
}
.apply-return .list .item .upload .pictrue:nth-last-child(1) {
border: 1rpx solid #ddd;
box-sizing: border-box;
}
.apply-return .bntCon{
width: 100%;
height: 112rpx;
background: #FFFFFF;
position: fixed;
left:0;
bottom: 0;
bottom: calc(0rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
bottom: calc(0rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
}
.apply-return .returnBnt {
font-size: 32rpx;
color: #fff;
width: 710rpx;
height: 80rpx;
border-radius: 50rpx;
text-align: center;
line-height: 80rpx;
font-size: 28rpx;
}
.goodsStyle .text .name {
align-self: flex-start;
}
</style>

View File

@@ -0,0 +1,518 @@
<template>
<view :style="colorStyle">
<view class="h-120 flex-between-center px-20">
<view class="h-72 bg--w111-f5f5f5 rd-36rpx px-32 flex-1 flex-y-center relative">
<text class="iconfont icon-ic_search text--w111-999"></text>
<input type="text" confirm-type="search" placeholder="请输入要查询的内容" @confirm="inputConfirm" @input="setValue"
class="fs-28 w-438 text--w111-333 pl-18 line1" v-model="searchValue" />
<text class="iconfont icon-ic_close1 fs-28 text--w111-999 z-10" v-show="searchValue"
@tap="clearSearchVal"></text>
</view>
<view class="fs-28 text--w111-333 ml-32" @tap='searchBut'>搜索</view>
</view>
<view class="px-20" v-if="history.length">
<view class="flex-between-center mt-16 mb-24">
<view class="fs-28 lh-40rpx fw-500 text--w111-333">历史搜索</view>
<text class="iconfont icon-ic_delete fs-28 text--w111-999" @tap="clear"></text>
</view>
<view class="flex flex-wrap">
<view class="max-w-686 h-56 lh-56rpx line1 rd-28rpx bg--w111-f5f5f5 px-24 fs-24 text--w111-666 mr-24 mb-16"
v-for="(item,index) in isShowMore ? history : history.slice(0,7)" :key="index"
@tap='setHotSearchValue(item.keyword)' v-if="item.keyword">{{item.keyword}}</view>
<view class="w-56 h-56 rd-28rpx bg--w111-f5f5f5 flex-center text--w111-666"
v-if="history.length > 7" @tap="isShowMore = !isShowMore">
<text class="iconfont fs-24" :class="isShowMore ? 'icon-ic_uparrow' : 'icon-ic_downarrow'"></text>
</view>
</view>
</view>
<view class="px-20">
<view class="flex-between-center mt-40 mb-24">
<view class="fs-28 lh-40rpx fw-500 text--w111-333">热门搜索</view>
<text class="iconfont icon-ic_Refresh fs-28 text--w111-999" :class="isSpin ? 'spin' : ''" @tap="refresh"></text>
</view>
<view class="flex flex-wrap">
<view class="flex-center search_item h-56 rd-28rpx px-24 fs-24 mr-24 mb-16"
v-for="(item,index) in hotSearchList" :key="index"
:style="{'color':item.color,'background-color':item.bg_color,border: item.border_color ? '1px solid ' + item.border_color : 'none'}"
@tap='setHotSearchValue(item.name)'>
<view class="flex-y-center">
<image v-if="item.icon" :src="item.icon" class="w-24 h-24 rd-4rpx mr-8"></image>
<text>{{item.name}}</text>
</view>
</view>
</view>
</view>
<view>
<scroll-view scroll-x="true" class="white-nowrap vertical-middle w-730 mt-32 pl-20" show-scrollbar="false">
<view class="inline-block mr-20" v-if="salesRecommendList.length">
<view class="w-454 rd-24rpx gradient_bg pt-22 pb-8">
<view class="fs-28 font-red lh-40rpx fw-600 pl-24 mb-18 flex-y-center"
@tap="goRank(1)">
<image src="@/static/img/sales_icon.png" class="w-40 h-40"></image>
<text class="pl-8">销量</text>
</view>
<view class="mx-8 rd-24rpx bg--w111-fff h-748 p-20">
<view class="flex-y-center" v-if="salesRecommendList[0]" @tap="goDetail(salesRecommendList[0])">
<view class="relative w-108 h-108">
<image :src="salesRecommendList[0].image" class="w-108 h-108 rd-16rpx"></image>
<view class="rank-count rank-count1 fs-24 text--w111-fff flex-center">1</view>
</view>
<view class="flex-1 h-108 flex-col flex-x-center ml-16">
<view class="w-260 fs-26 text--w111-333 lh-40rpx line1">{{salesRecommendList[0].store_name}}</view>
<view class="w-260 fs-22 text--w111-999 lh-30rpx mt-8 line1">{{salesRecommendList[0].store_info}}</view>
</view>
</view>
<view class="flex-y-center mt-16" v-if="salesRecommendList[1]" @tap="goDetail(salesRecommendList[1])">
<view class="relative w-108 h-108">
<image :src="salesRecommendList[1].image" class="w-108 h-108 rd-16rpx"></image>
<view class="rank-count rank-count2 fs-24 text--w111-fff flex-center">2</view>
</view>
<view class="flex-1 h-108 flex-col flex-x-center ml-16">
<view class="flex-between-center">
<view class="w-260 fs-26 text--w111-333 lh-40rpx line1">{{salesRecommendList[1].store_name}}</view>
</view>
<view class="w-260 fs-22 text--w111-999 lh-30rpx mt-8 line1">{{salesRecommendList[1].store_info}}</view>
</view>
</view>
<view class="flex-y-center mt-16 mb-34" v-if="salesRecommendList[2]" @tap="goDetail(salesRecommendList[2])">
<view class="relative w-108 h-108">
<image :src="salesRecommendList[2].image" class="w-108 h-108 rd-16rpx"></image>
<view class="rank-count rank-count3 fs-24 text--w111-fff flex-center">3</view>
</view>
<view class="flex-1 h-108 flex-col flex-x-center ml-16">
<view class="flex-between-center">
<view class="w-260 fs-26 text--w111-333 lh-40rpx line1">{{salesRecommendList[2].store_name}}</view>
</view>
<view class="w-260 fs-22 text--w111-999 lh-30rpx mt-8 line1">{{salesRecommendList[2].store_info}}</view>
</view>
</view>
<view class="flex-between-center scroll_cell" v-for="(item,index) in salesRecommendList.slice(3)" :key="index" @tap="goDetail(item)">
<view class="flex-y-center">
<text class="inline-block w-30 h-32 lh-32rpx text--w111-fff text-center fs-24 rank_4">{{index + 4}}</text>
<text class="fs-26 text--w111-333 ml-20 w-360 line1">{{item.store_name}}</text>
</view>
</view>
</view>
</view>
</view>
<view class="inline-block mr-20" v-if="scoreRecommendList.length">
<view class="w-454 rd-24rpx gradient_bg pt-22 pb-8">
<view class="fs-28 font-red lh-40rpx fw-600 pl-24 mb-18 flex-y-center"
@tap="goRank(2)">
<image src="@/static/img/sales_icon.png" class="w-40 h-40"></image>
<text class="pl-8">评分</text>
</view>
<view class="mx-8 rd-24rpx bg--w111-fff h-748 p-20">
<view class="flex-y-center" v-if="scoreRecommendList[0]" @tap="goDetail(scoreRecommendList[0])">
<view class="relative w-108 h-108">
<image :src="scoreRecommendList[0].image" class="w-108 h-108 rd-16rpx"></image>
<view class="rank-count rank-count1 fs-24 text--w111-fff flex-center">1</view>
</view>
<view class="flex-1 h-108 flex-col flex-x-center ml-16">
<view class="flex-between-center">
<view class="w-260 fs-26 text--w111-333 lh-40rpx line1">{{scoreRecommendList[0].store_name}}</view>
</view>
<view class="w-260 fs-22 text--w111-999 lh-30rpx mt-8 line1">{{scoreRecommendList[0].store_info}}</view>
</view>
</view>
<view class="flex-y-center mt-16" v-if="scoreRecommendList[1]" @tap="goDetail(scoreRecommendList[1])">
<view class="relative w-108 h-108">
<image :src="scoreRecommendList[1].image" class="w-108 h-108 rd-16rpx"></image>
<view class="rank-count rank-count2 fs-24 text--w111-fff flex-center">2</view>
</view>
<view class="flex-1 h-108 flex-col flex-x-center ml-16">
<view class="flex-between-center">
<view class="w-260 fs-26 text--w111-333 lh-40rpx line1">{{scoreRecommendList[1].store_name}}</view>
</view>
<view class="w-260 fs-22 text--w111-999 lh-30rpx mt-8 line1">{{scoreRecommendList[1].store_info}}</view>
</view>
</view>
<view class="flex-y-center mt-16 mb-34" v-if="scoreRecommendList[2]" @tap="goDetail(scoreRecommendList[2])">
<view class="relative w-108 h-108">
<image :src="scoreRecommendList[2].image" class="w-108 h-108 rd-16rpx"></image>
<view class="rank-count rank-count3 fs-24 text--w111-fff flex-center">3</view>
</view>
<view class="flex-1 h-108 flex-col flex-x-center ml-16">
<view class="flex-between-center">
<view class="w-260 fs-26 text--w111-333 lh-40rpx line1">{{scoreRecommendList[2].store_name}}</view>
</view>
<view class="w-260 fs-22 text--w111-999 lh-30rpx mt-8 line1">{{scoreRecommendList[2].store_info}}</view>
</view>
</view>
<view class="flex-between-center scroll_cell" v-for="(item,index) in scoreRecommendList.slice(3)" :key="index" @tap="goDetail(item)">
<view class="flex-y-center">
<text class="inline-block w-30 h-32 lh-32rpx text--w111-fff text-center fs-24 rank_4">{{index + 4}}</text>
<text class="fs-26 text--w111-333 ml-20 w-360 line1">{{item.store_name}}</text>
</view>
</view>
</view>
</view>
</view>
<view class="inline-block mr-20" v-if="collectRecommendList.length">
<view class="w-454 rd-24rpx gradient_bg pt-22 pb-8">
<view class="fs-28 font-red lh-40rpx fw-600 pl-24 mb-18 flex-y-center"
@tap="goRank(3)">
<image src="@/static/img/sales_icon.png" class="w-40 h-40"></image>
<text class="pl-8">收藏</text>
</view>
<view class="mx-8 rd-24rpx bg--w111-fff h-748 p-20">
<view class="flex-y-center" v-if="collectRecommendList[0]" @tap="goDetail(collectRecommendList[0])">
<view class="relative w-108 h-108">
<image :src="collectRecommendList[0].image" class="w-108 h-108 rd-16rpx"></image>
<view class="rank-count rank-count1 fs-24 text--w111-fff flex-center">1</view>
</view>
<view class="flex-1 h-108 flex-col flex-x-center ml-16">
<view class="flex-between-center">
<view class="w-260 fs-26 text--w111-333 lh-40rpx line1">{{collectRecommendList[0].store_name}}</view>
</view>
<view class="w-260 fs-22 text--w111-999 lh-30rpx mt-8 line1">{{collectRecommendList[0].store_info}}</view>
</view>
</view>
<view class="flex-y-center mt-16" v-if="collectRecommendList[1]" @tap="goDetail(collectRecommendList[1])">
<view class="relative w-108 h-108">
<image :src="collectRecommendList[1].image" class="w-108 h-108 rd-16rpx"></image>
<view class="rank-count rank-count2 fs-24 text--w111-fff flex-center">2</view>
</view>
<view class="flex-1 h-108 flex-col flex-x-center ml-16">
<view class="flex-between-center">
<view class="w-260 fs-26 text--w111-333 lh-40rpx line1">{{collectRecommendList[1].store_name}}</view>
</view>
<view class="w-260 fs-22 text--w111-999 lh-30rpx mt-8 line1">{{collectRecommendList[1].store_info}}</view>
</view>
</view>
<view class="flex-y-center mt-16 mb-34" v-if="collectRecommendList[2]" @tap="goDetail(collectRecommendList[2])">
<view class="relative w-108 h-108">
<image :src="collectRecommendList[2].image" class="w-108 h-108 rd-16rpx"></image>
<view class="rank-count rank-count3 fs-24 text--w111-fff flex-center">3</view>
</view>
<view class="flex-1 h-108 flex-col flex-x-center ml-16">
<view class="flex-between-center">
<view class="w-260 fs-26 text--w111-333 lh-40rpx line1">{{collectRecommendList[2].store_name}}</view>
</view>
<view class="w-260 fs-22 text--w111-999 lh-30rpx mt-8 line1">{{collectRecommendList[2].store_info}}</view>
</view>
</view>
<view class="flex-between-center scroll_cell" v-for="(item,index) in collectRecommendList.slice(3)" :key="index" @tap="goDetail(item)">
<view class="flex-y-center">
<text class="inline-block w-30 h-32 lh-32rpx text--w111-fff text-center fs-24 rank_4">{{index + 4}}</text>
<text class="fs-26 text--w111-333 ml-20 w-360 line1">{{item.store_name}}</text>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
<scroll-view scroll-y="true" class="fuzzy_modal" :style="{height:fuzzyHeight + 'px',top: 60 + 'px'}"
v-if="newPartyList.length" @touchmove.stop.prevent>
<view class="cell" v-for="(item,index) in newPartyList" :key="index"
@tap="setCommentSearch(item.id)">
<view class="keyword line1" v-html="item.keyword"></view>
</view>
</scroll-view>
<home></home>
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight;
import {
getSearchKeyword,
getSearchRecommendApi,
getHotWordApi
} from '@/api/store.js';
import { searchList, clearSearch } from '@/api/api.js';
import recommend from '@/components/recommend';
import colors from "@/mixins/color";
import { goShopDetail } from '@/libs/order.js';
import { HTTP_REQUEST_URL } from '@/config/app.js';
import { Debounce } from '@/utils/validate.js'
export default {
components: {
recommend,
},
mixins: [colors],
data() {
return {
hostProduct: [],
searchValue: '',
focus: true,
bastList: [],
hotSearchList: [],
isSpin:false,
first: 0,
limit: 8,
page: 1,
loading: false,
loadend: false,
loadTitle: '加载更多',
hotPage: 1,
isScroll: true,
history: [],
imgHost: HTTP_REQUEST_URL,
salesRecommendList:[],
scoreRecommendList:[],
collectRecommendList:[],
sysHeight:sysHeight,
newPartyList: [], //模糊搜索关键词列表
isShowMore: false
};
},
computed: {
fuzzyHeight() {
let screenHeight = uni.getWindowInfo().screenHeight;
return screenHeight - this.sysHeight - 56;
}
},
onLoad(e) {
this.searchValue = e.searchVal || '';
this.getSearchHotKeywords();
this.getSearchRecommend();
setTimeout(()=>{
this.newPartySearch();
},1000)
},
onShow: function(e) {
uni.removeStorageSync('form_type_cart');
this.searchList();
},
onPullDownRefresh() {
this.getSearchHotKeywords();
this.getSearchRecommend();
this.searchList();
setTimeout(()=> {
this.newPartySearch();
uni.stopPullDownRefresh();
}, 1000);
},
onPageScroll(object) {
uni.$emit('scroll');
},
methods: {
refresh(){
this.isSpin = true;
this.getSearchHotKeywords();
},
// 获取搜索热词
getSearchHotKeywords(){
getHotWordApi().then(res=>{
this.hotSearchList = res.data;
setTimeout(_=>{
this.isSpin = false;
},1000)
})
},
searchList() {
searchList({
page: 1,
limit: 10
}).then(res => {
this.history = res.data;
});
},
clear() {
let that = this;
clearSearch().then(res => {
uni.showToast({
title: res.msg,
success() {
that.history = [];
}
});
});
},
inputConfirm: function(event) {
if (event.detail.value) {
uni.hideKeyboard();
this.setHotSearchValue(event.detail.value);
}
},
setValue: Debounce(function(e){
this.newPartySearch();
}),
newPartySearch: function() {
getSearchKeyword({keyword:this.searchValue}).then(res => {
this.newPartyList = res.data.list;
this.newPartyList.map((item) => {
this.$set(item,'keyword',this.brightKeyword(item.store_name,res.data.keyword));
});
});
},
brightKeyword(val,keyword) {
const escapedVal = this.escapeHtml(val);
// 转义关键字中的正则特殊字符(如 . * 等)
const escapedKeyword = keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const regex = new RegExp(`(${escapedKeyword})`, 'gi');
// 高亮匹配项并保留转义后的安全文本
return escapedVal.replace(regex, '<span style="color: #C9771E;">$1</span>');
},
escapeHtml(text) {
const map = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#039;'
};
return text.replace(/[&<>"']/g, (m) => map[m]);
},
setCommentSearch(id) {
uni.navigateTo({
url:'/pages/goods/goods_list/index?productId=' + id
})
},
setHotSearchValue: function(event) {
this.$set(this, 'searchValue', event);
this.focus = false;
this.searchBut();
},
searchBut: function() {
let that = this;
that.focus = false;
if (that.searchValue.length > 0) {
this.newPartyList = [];
uni.navigateTo({
url:'/pages/goods/goods_list/index?searchValue=' + that.searchValue
})
} else {
return this.$util.Tips({
title: '请输入要搜索的商品',
icon: 'none',
duration: 1000,
mask: true,
});
}
},
getSearchRecommend(){
getSearchRecommendApi(1).then(res=>{
this.salesRecommendList = res.data;
})
getSearchRecommendApi(2).then(res=>{
this.scoreRecommendList= res.data;
})
getSearchRecommendApi(3).then(res=>{
this.collectRecommendList= res.data;
})
},
// 去详情页
goDetail(item) {
goShopDetail(item, this.uid).catch(res => {
uni.navigateTo({
url: `/pages/goods_details/index?id=${item.id}&fromType=1`
});
});
},
goRank(type){
uni.navigateTo({
url:`/pages/columnGoods/rank/index?type=${type}`
})
},
clearSearchVal(){
this.searchValue = '';
this.newPartyList = [];
}
}
}
</script>
<style>
page {
background-color: #fff;
}
</style>
<style lang="scss" scoped>
.font-red{
color: #e93323;
}
.gradient_bg {
background: linear-gradient(172deg, rgba(255, 250, 218, 0.15) 0%, #fceae9 100%), linear-gradient(112deg, #fadfdf 0%, rgba(252, 234, 233, 0) 100%);
}
.max-200{
max-width: 200rpx;
}
.pb-8{
padding-bottom:8rpx;
}
.w-40{
width: 40rpx;
}
.h-40{
height:40rpx;
}
.search_item{
color: #666;
background-color: #f5f5f5;
}
.rank-count{
width:30rpx;
height:32rpx;
position: absolute;
top:0;
left:0;
background-size: cover;
}
.rank-count1{
background-image:url('@/static/img/rank1_icon.png');
}
.rank-count2{
background-image:url('@/static/img/rank2_icon.png');
}
.rank-count3{
background-image:url('@/static/img/rank3_icon.png');
}
.rank_4{
background-image:url('../static/rank4_icon.png');
background-size:100%;
}
.scroll_cell ~ .scroll_cell{
margin-top: 32rpx;
}
.fuzzy_modal {
background-color: #FFF;
position: fixed;
width: 100%;
left: 0;
box-sizing: border-box;
.cell {
width: 100%;
height: 88rpx;
border-bottom: 0.5px solid #f5f5f5;
.keyword {
height: 88rpx;
line-height: 88rpx;
font-size: 28rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #1B1B1B;
padding-left: 32rpx;
flex: 1;
}
}
}
.max-w-686{
max-width: 686rpx;
}
.spin{
animation-name: spin;
animation-duration: 1s;
animation-timing-function: linear;
animation-iteration-count: infinite;
transform-origin: center center;
display: inline-block;
}
@keyframes spin{
from{
transform: rotate(0deg);
}
to{
transform: rotate(360deg);
}
}
.icon-ic_close1{
position: absolute;
right: 20rpx;
top: 50%;
transform: translateY(-50%);
}
</style>

View File

@@ -0,0 +1,86 @@
<template>
<!-- 无缝滚动效果 -->
<view class="marquee-wrap">
<view class="marquee-list" :class="{'animate-up': animateUp}">
<view class="marquee-item" v-for="(item, index) in listData" :key="item.id">
{{ prefix }}<text class="name">{{ item.user ? item.user.nickname : '****' }}</text>获得<text>{{ item.prize.name }}</text>
</view>
</view>
</view>
</template>
<script>
export default {
name: "noticeBar",
data() {
return {
animateUp: false,
listData: JSON.parse(JSON.stringify(this.showMsg)),
timer: null
}
},
props: {
showMsg: {
type: Array
},
prefix: {
type: String
},
},
mounted() {
this.timer = setInterval(this.scrollAnimate, 2500);
},
methods: {
scrollAnimate() {
this.animateUp = true
setTimeout(() => {
this.listData.push(this.listData[0])
this.listData.shift()
this.animateUp = false
}, 500)
}
},
destroyed() {
clearInterval(this.timer)
}
};
</script>
<style lang="scss" scoped>
.marquee-wrap {
width: 100%;
height: 40rpx;
border-radius: 20px;
margin: 0 auto;
overflow: hidden;
.marquee-list {
padding: 0;
.marquee-item {
width: 100%;
height: 100%;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
padding: 0;
list-style: none;
line-height: 40rpx;
// text-align: center;
color: #fff;
font-size: 26rpx;
font-weight: 400;
}
.name {
color: #FFEF6C;
}
}
.animate-up {
transition: all 0.5s ease-in-out;
// transform: translateY(-40rpx);
margin-top: -40rpx;
}
}
</style>

View File

@@ -0,0 +1,258 @@
<template>
<view class="show-box">
<view class="table-title acea-row row-between-wrapper" :style="{
backgroundImage: `url(${imgHost}/statics/images/lottery4.png)`
}">
<view class="text" v-if="showMsg.type === 'user'">
中奖记录
</view>
<view class="text" v-else-if="showMsg.type === 'me'">
我的奖品
</view>
<view class="text" v-else-if="showMsg.type === 'prize'">
活动奖品
</view>
</view>
<view class="table" v-if="['me','user','prize'].includes(showMsg.type)">
<view v-if="showMsg.type=='me'" class="table-head">
<view class="nickname" style="width: 20%;">序号</view>
<view class="table-name time" style="width: 45%;">获奖时间</view>
<view class="table-name" style="width: 35%;">奖品名称</view>
</view>
<view v-if="showMsg.type == 'prize'">
<view class="prize-list acea-row">
<template v-for="(item,index) in showMsg.data">
<view v-if="item.type&&item.type!=1" class="prize-item" :key="item.id">
<view class="prize-item-inner">
<image :src="item.image" class="image"></image>
</view>
<view class="name line1">{{item.name}}</view>
</view>
</template>
</view>
</view>
<view v-else-if="showMsg.type=='user'" class="table-d">
<view class="table-body" v-for="(item,index) in showMsg.data" :key="index">
<view class="table-name time">
{{item.add_time}}
</view>
<view class="nickname">
{{showMsg.type === 'user' ? (item.user?item.user.nickname:'') : index + 1}}
</view>
<view class="table-name">
{{item.prize.name}}
</view>
</view>
</view>
<view v-else class="table-d me">
<view class="table-body acea-row row-middle" v-for="(item,index) in showMsg.data" :key="index">
<view class="nickname" style="width: 20%;">
<view class="inner acea-row row-center-wrapper">{{showMsg.type === 'user' ? (item.user?item.user.nickname:'') : index + 1}}</view>
</view>
<view class="table-name time" style="width: 45%;">
{{item.add_time}}
</view>
<view class="table-name" style="width: 35%;">
{{item.prize.name}}
</view>
</view>
</view>
</view>
<view class="content" v-else v-html="showMsg.data"></view>
</view>
</template>
<script>
import {
HTTP_REQUEST_URL
} from '@/config/app';
export default {
data() {
return {
imgHost: HTTP_REQUEST_URL,
}
},
props: {
showMsg: {
type: Object
},
},
}
</script>
<style lang="scss" scoped>
.show-box {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
background: linear-gradient(90deg, #FFFEFD 0%, #FFE3E3 100%);
padding: 112rpx 0 48rpx;
border-radius: 24rpx;
+.show-box {
margin-top: 60rpx;
}
}
.table-title {
position: absolute;
top: -24rpx;
height: 108rpx;
padding: 12rpx 104rpx 26rpx;
background-size: 100% 100%;
.text {
color: #FFFFFF;
font-size: 32rpx;
font-weight: 500;
}
image {
width: 50rpx;
height: 16rpx;
}
}
.table-d {
max-height: 200rpx;
overflow-y: scroll;
&.me {
.table-body {
height: 72rpx;
margin: 0 20rpx 32rpx;
background: linear-gradient(90deg, #FEFDFB 0%, #FFD8D8 47%, rgba(255, 228, 228, 0) 100%, rgba(255, 204, 204, 0) 100%, rgba(255, 204, 204, 0) 100%);
.nickname {
width: 30%;
.inner {
width: 40rpx;
height: 40rpx;
border-radius: 20rpx;
margin-left: 12rpx;
background: rgba(255, 71, 71, 0.2);
font-size: 28rpx;
}
}
}
}
}
.table {
width: 100%;
.table-head,
.table-body {
display: flex;
justify-content: space-around;
}
.table-head {
margin: 0 20rpx 32rpx;
font-weight: 500;
font-size: 28rpx;
line-height: 40rpx;
color: #333333;
.nickname {
width: 30%;
padding: 10rpx 20rpx;
}
.table-name {
width: 30%;
text-align: left;
padding: 10rpx 20rpx;
}
.time {
width: 40%;
}
}
.table-body {
color: #333333;
+.table-body {
margin-top: 32rpx;
}
.nickname {
width: 30%;
font-size: 24rpx;
line-height: 34rpx;
padding: 0 20rpx;
}
.table-name {
width: 30%;
text-align: left;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
font-size: 24rpx;
line-height: 34rpx;
padding: 0 20rpx;
}
.time {
width: 40%;
}
}
.prize-list {
padding: 0 24rpx;
margin-right: -23rpx;
}
.prize-item {
position: relative;
padding: 8rpx;
border-radius: 16rpx;
margin: 0 23rpx 32rpx 0;
background: linear-gradient(180deg, #FFB7B7 3%, #FF5E5E 100%);
.name {
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 50rpx;
padding-top: 14rpx;
border-radius: 0 0 16rpx 16rpx;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMEAAAAzCAYAAAAuGGyOAAAAAXNSR0IArs4c6QAABtlJREFUeNrtnc1yG8cVhb/TA/BHFUm2RVqKqCrTjKi1U1lkk4WTdVJeZZ9H0SKpPEwewE+RbRaSrNCJ6EgmFYVSJJEi0CcLICQIAsTMYGYwFLurwBoMZrr73j63v+6eH8rf8hp4jNnFPCXwDyLfEdkh8lTf8IaUUrrE6dXDrz/5hO5mH29J+tJ9fUHwliJ3DdvytxgDaHiKIGP4EfSBQ55jPUF+AnqMww4xfk/o7eh37CY3p7TI5D/+ZqMXvSn4QrDpqG3k+6DtrNu5jYAIRBP7xh5qfaj780EwHhDm/HYmCEAYBsxbjrAeYR4hPQL+jvyM2HlGp/NMvz14lZoqpVIC//OvPkXhXr+ve8R4T4QvLT+w9SCgB2Gls0zfJyLv9z1Fy6ManhkEk06atj1y7Ph52UiQSPCWg8Gwy49R9gi8g3lOj+cs8y998/ZFavIrJvA//fL2cTf7qfq+I3RHhE2bB8A2aDtb6dwkGqKhDzEae1RrE8Q+S5f5giAHCca3RwrzeMFTKiFxSpP/B8s7cOSp0BPgO/ATrB9AeyjsoWyPz/b39Gt6SUItFfbDrzvvVg8+vxaW1ohhnRDXQXf75n6I+lmE+0FsaaUz6L2HvXiMxnGypqZvzwiChZLAOj30ovNm5AEg6WywBKAPPvSerKeIp0R2otgJhBe9GF/GEF4uhe4+f3v+Ug+JSZrzCpvAZz+/9eG91kKmWwq6pcht5M2ANu2wZXsrLGXrZDojbkcTYzWaKhwEbSdB3iCYXNbk7XMBo2HAHHEA2hXsYnYj+gF71+ZFBq+R3oBek4U3HC694Q87r6WPL3j8kMDNr26w1LtO39ePyW50Y7jeJ94Q3EbhLmZDZsPWBrARlrObBA2GJHHgT6KJnqwHT2yjWXq4WFNXngTFDC0WtGI4JFMY7A7D+YuGAf3OR8AeUfuSf4yE/QB7se99MvYC2UtifEfI3hN774/pHnaj3tONH+h1enR7Pf7b6dM96rGy0iNe67Py78hPViL/vBn59K+R3xP5C4FXvwgcHQTuHAYOjwP/uZ5xbbnD8WGHsJTR+9BhqdPhmKVjx9WuOis4ruKwiuK1SHYLeR2HNcy6xJrN57LWgHWtZstYYEPUyUQSg+Ngd7Ge9WL/ugZNJRJQfRDMdPZF9R2d2wz+DH6SRkwabnvkd4/sH63XeM8ax+pz8p2BiD3Y9lDEc4kqh515g+AykqBzHpoqAFhN3XPGHs/J8SryqDrpVIQDJY4NPTz+pWDQzmzcHO011W+q1S1c1Fwz21KVt9GsFCaMHIuMMifucdns8hfTggH2tN0uUF3Xa7Obd6hn5e4GGztnVqEOEqjqwFYLg0DTdqtAdVWvzWreoZqVuxpsbJUOgkSCRIJEgkSCRIJEgkSCRIJEgkSCj5wEecTi0kUuhgSuiQR24YIXSwJXW7CbJIHrJUHlnf/kzBsngefNyjNIUCJqRQ0dtyo+yfWV2zgJXKcPi9tRGQlqtctnMphBguK9gevudHIf58J1r2JE0MycoEQXX+u8ahYJymqqCbsmkmC+8dulIEH+AX5hrxcjQYPOaQsJZqpWDWiDWSSYb/yWjwQFe7JSY1vP3514Mj6rI0ETmHTzJHCd9rSOBCVWBxobAyYSLIwEqsoeN2DX3CSgJAnKjt0XRYL8dhvP2RPW1HPWfN3Boz5IJChJgsoPr4sEs+xu+qJGO0hwpt3VPvOnB0+FJPDYZ/GRvxgS1Lw4XzMJXLoOnjaFqtv2NpGg/KrQx0aCplMiQWvmBOWvD3xsJGg6FNpxnWAxJKCdJEhzApe3beEkUOk6LIYEuiqrQ4kEV4sEok75nC/mUqwO6VKRQHjOdfIWzwk0mwTzXydwrTHTbhJUfcNYwyQ4PUUtu2LcDAnOtH9lJFADdi2MBAUNVZk6VUmC/BXQ6UtHWkICNTBOr/KKcStIoAL1UQUkqKsXuwwkUHPOWehdpC2cE1xMAheoz/mVkIXeRVrokbYcvXspEhYhgUvaXAKNC72LdPQZFVWr6kSCqgTWQhJUfUNhW0iQV1O12qUiJCgetYt9xlglCy5BAlVNgrKrYDW4Yw6Szv9kWYUkyHltpPLXMLqOHuhSvW1C1bRgk37TtIZT9UV63uArcF75t03MN6FMb5toYk4wr99Um9MbJ0EFJiQSXEkSmLp6lsWRoLwPEwkSCSp3SyJBIkEiQSJBIkEiQSJBIkEiQSJBIkEiQSJBIkEiQSJBIkEiQSJBIkEiQSLBybdEgkSCq00Cj/3f2kSCRIJEgkSCRILWkeB8EKjIQxrTSXDy0LkveBXLJRJ3URJoyif3qoHrq2MtaNWk9p9gfxUkqPhZg/8BIpDzbv3ZQOwAAAAASUVORK5CYII=);
background-repeat: no-repeat;
background-size: 100% 100%;
text-align: center;
font-weight: 500;
font-size: 20rpx;
line-height: 28rpx;
color: #FFFFFF;
}
}
.prize-item-inner {
width: 176rpx;
height: 176rpx;
border-radius: 12rpx;
background-color: #FFFFFF;
.image {
display: block;
width: 128rpx;
height: 128rpx;
margin: 0 auto;
object-fit: contain;
}
}
}
.content {
width: 100%;
padding: 0 20rpx;
}
</style>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,180 @@
<template>
<view :style="colorStyle">
<view class="px-20 mt-32">
<view class="bg--w111-fff rd-24rpx p-24 flex-between-center item"
v-for="item in lotteryList" :key="item.id">
<easy-loadimage
:image-src="item.prize.image"
width="136rpx"
height="136rpx"
borderRadius="16rpx"></easy-loadimage>
<view class="flex-1 pl-24 h-136 flex-between-center">
<view class="w-328 h-136 flex-col justify-between">
<view class="w-full h-80 line2">
<text class="label" :class="'label' + item.prize.type">{{item.prize.type | typeName}}</text>
<text class="name">{{item.prize.name}}</text>
</view>
<view class="fs-22 text--w111-999">兑换时间:{{item.receive_time || '--'}}</view>
</view>
<view class="w-120 h-56 rd-30rpx flex-center fs-24 bg-gradient text--w111-fff"
@tap="goDetail(item)" v-if="item.type == 4">{{item.type ==4 && item.wechat_state == 'WAIT_USER_CONFIRM' ? '去领取' : '已领取'}}</view>
<view class="w-120 h-56 rd-30rpx flex-center fs-24 bg-gradient text--w111-fff"
@tap="goDetail(item)" v-else>{{item.is_receive == 0 && item.type == 6 ? '去领取' : '去查看'}}</view>
</view>
</view>
</view>
<view class="px-20 mt-20" v-if="lotteryList.length === 0 && !loading">
<emptyPage title="暂无中奖记录~" src="/statics/images/noOrder.gif"></emptyPage>
</view>
<home></home>
</view>
</template>
<script>
import {getLotteryList} from '@/api/lottery.js';
import { postCartAdd } from '@/api/store.js';
import emptyPage from '@/components/emptyPage.vue'
import colors from '@/mixins/color.js';
export default {
components: {
emptyPage
},
mixins:[colors],
data() {
return {
loading: false,
where: {
page: 1,
limit: 20,
},
lotteryList: [],
loadTitle: ''
}
},
onShow() {
this.lotteryList = [];
this.where.page = 1;
this.loading = false;
this.loadend = false;
this.getLotteryList()
},
filters: {
typeName(type) {
if (type == 2) {
return '积分'
} else if (type == 3) {
return '余额'
} else if (type == 4) {
return '红包'
} else if (type == 5) {
return '优惠券'
} else if (type == 6) {
return '商品'
}
}
},
onPageScroll(object) {
uni.$emit('scroll');
},
methods: {
getLotteryList() {
if (this.loadend) return;
if (this.loading) return;
this.loading = true;
this.loadTitle = '';
getLotteryList(this.where).then(res => {
let list = res.data;
let lotteryList = this.$util.SplitArray(list, this.lotteryList);
let loadend = list.length < this.where.limit;
this.loadend = loadend;
this.loading = false;
this.loadTitle = loadend ? '没有更多内容啦~' : '加载更多';
this.$set(this, 'lotteryList', lotteryList);
this.$set(this.where, 'page', this.where.page + 1);
}).catch(err => {
that.loading = false;
that.loadTitle = '加载更多';
});
},
goDetail(item){
let type = item.type;
if (type == 2) {
uni.navigateTo({
url: '/pages/users/user_integral/index'
})
} else if (type == 3) {
uni.navigateTo({
url: '/pages/users/user_money/index'
})
} else if (type == 4) {
if(item.wechat_state == 'WAIT_USER_CONFIRM'){
uni.navigateTo({
url: '/pages/users/user_spread_money/receiving?type=2&id=' + item.order_id
})
}
} else if (type == 5) {
uni.navigateTo({
url: '/pages/users/user_coupon/index'
})
} else if (type == 6) {
if(item.oid > 0){
uni.navigateTo({
url: `/pages/goods/order_details/index?order_id=${item.oid}`
})
}else{
postCartAdd({
cartNum: 1,
new: 1,
is_new: 1,
productId: item.prize.product_id,
uniqueId: item.prize.unique,
luckRecordId: item.id,
}).then(res => {
uni.navigateTo({
url: `/pages/goods/order_confirm/index?new=1&luckRecordId=${item.id}&cartId=${res.data.cartId}`
});
}).catch(err => {
this.$util.Tips({
title: `${err},请联系客服`
});
});;
}
}
}
},
onReachBottom() {
this.getLotteryList();
}
}
</script>
<style lang="scss" scoped>
.item ~ .item{
margin-top: 20rpx;
}
.item{
.name {
width: 328rpx;
height: 80rpx;
line-height: 40rpx;
color: #333;
font-weight: 500;
font-size: 28rpx;
}
.label {
padding: 0 6rpx;
font-size: 20rpx;
margin-right: 16rpx;
border-radius: 6rpx;
vertical-align: middle;
}
.label2, .label3, .label5{
border: 1rpx solid #FF7D00;
color: #FF7D00;
}
.label4, .label6{
border: 1rpx solid var(--view-theme);
color: var(--view-theme);
}
}
</style>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,398 @@
<template>
<view :style="colorStyle">
<view>
<view class="fixed-lt w-full h-212 bg_mask z-900" :style="{ top: statusBarHeight + 'px' }">
<view class="px-20 h-80 flex mt-12">
<view class="w-56 h-56 rd-50-p111- bg-black flex-center fs-42 text--w111-fff" @tap="backPage()">
<text class="iconfont icon-ic_leftarrow"></text>
</view>
</view>
</view>
<!-- #ifdef MP || APP-PLUS -->
<view :style="{'height': statusBarHeight + 'px'}"></view>
<view class="px-20 p-b-20">
<!-- #endif -->
<!-- #ifndef MP -->
<view class="p-20">
<!-- #endif -->
<view class="rd-24rpx pro_card" v-for="(item, index) in discountsData" :key="index">
<view class="w-full h-710 rd-t-24rpx relative">
<image class="w-full h-full rd-t-24rpx block" mode="aspectFill" :src="item.image"></image>
<view class="match-box rd-24rpx p-24 text--w111-fff">
<view class="fs-26 lh-36rpx w-full line1">{{item.title}}</view>
<view class="fs-22 lh-30rpx w-full line1 mt-12rpx">{{item.products[0].title}}</view>
</view>
</view>
<view class="rd-b-24rpx bg--w111-fff pt-24 pb-32">
<scroll-view scroll-x="true" scroll-with-animation
class="white-nowrap vertical-middle w-686 ml-24" show-scrollbar="false">
<view class="inline-block mr-24" v-for="(pro,indexn) in item.products" :key="indexn">
<view class="w-222 rd-24rpx con-border relative">
<image class="w-full h-222 rd-t-24rpx block" :src="pro.image"
@tap="checkPro(pro, indexn, item)"></image>
<view class="bg--w111-fff py-16 mx-16">
<view class="fs-24 lh-34rpx w-full line1">{{ pro.title }}</view>
<view
class="w-full px-16 mt-8 h-36 bg--w111-f5f5f5 rd-20rpx px-12 flex-between-center fs-20"
@tap="selecAttr(pro,index,indexn)">
<view class="w-138 line1">{{pro.suk}}</view>
<text class="iconfont icon-ic_downarrow text--w111-999 fs-20"></text>
</view>
<view class="mt-16 pl-16 SemiBold font-num fs-30">¥{{pro.price}}</view>
</view>
<text class="iconfont fs-38 set-icon"
:class="pro.select ? 'icon-a-ic_CompleteSelect font-color' : 'icon-ic_unselect text--w111-fff'"
@tap="checkPro(pro, indexn, item)"></text>
<div class="bgIcon" v-if="pro.select"></div>
</view>
</view>
</scroll-view>
<view class="mt-32 flex-between-center px-24">
<view class="flex items-baseline">
<text class="fs-24 lh-34rpx text--w111-999">共2件,合计:</text>
<baseMoney :money="item.totalPrice" symbolSize="28" integerSize="44"
decimalSize="28" weight></baseMoney>
</view>
<view class="w-186 h-64 rd-36rpx flex-center fs-24 text--w111-fff bg-gradient1"
@tap="subData(item)">购买此套餐</view>
</view>
</view>
</view>
</view>
</view>
<base-drawer mode="bottom" :visible="visible" background-color="transparent" mask maskClosable
@close="closeDrawer">
<scroll-view scroll-y="true" style="max-height: 800rpx;">
<view class="bg--w111-fff">
<view class="w-full pt-32">
<view class="px-32 flex">
<image class="w-180 h-180 rd-16rpx" :src="attr.productSelect.image"></image>
<view class="pl-24">
<baseMoney :money="attr.productSelect.price" symbolSize="32" integerSize="48"
decimalSize="32" incolor="var(--primary-theme-con)" weight></baseMoney>
<view class="mt-20 fs-24 text--w111-999">库存:{{ attr.productSelect.stock }}</view>
</view>
</view>
</view>
<view class="px-32">
<view class="item mt-32" v-for="(item, indexw) in attr.productAttr" :key="indexw">
<view class="fs-28">{{ item.attr_name }}</view>
<view class="flex-y-center flex-wrap">
<view class="sku-item" :class="item.index === itemn.attr ? 'active' : ''"
v-for="(itemn, indexn) in item.attr_value" @click="tapAttr(indexw, indexn)"
:key="indexn">
{{ itemn.attr }}
</view>
</view>
</view>
</view>
<view class="mx-20 pb-box">
<view class="mt-52 h-72 flex-center rd-36px bg-color fs-26 text--w111-fff" @click="closeDrawer">
确定</view>
</view>
</view>
</scroll-view>
</base-drawer>
</view>
</view>
</template>
<script>
/*
* 这是一段很重要的注释,方便您以后理解
* 以前的逻辑较为混乱,用一个对象去管理多个套餐多个商品的sku属性
* 这次修改以后,没有复用sku弹窗组件,主要是这里的逻辑可以独立处理
* 初始化请求到套餐列表用下标为所有商品赋值sku名称和unique码
* 在点击商品打开sku弹窗以后,拿到选中的sku以后,将suk和unique赋值到商品中,
* 同时更新页面视图,在选择套餐时就省事多了,直接穿参操作即可
* */
let sysHeight = uni.getWindowInfo().statusBarHeight;
import {
matchPayListApi,
postCartAdd
} from "@/api/store.js"
import colors from '@/mixins/color.js';
import productWindow from '@/components/productWindow';
import baseDrawer from '@/components/tui-drawer/tui-drawer.vue';
export default {
data() {
return {
statusBarHeight: sysHeight,
id: 0,
params: {
page: 1,
limit: 20
},
discountsData: [],
selectValue: [],
selectAttr: [],
loading: false,
attr: {
cartAttr: false,
productAttr: [],
productSelect: {},
},
productValue: [], //系统属性
index: 0,
indexn: 0,
visible: false
}
},
components: {
baseDrawer
},
mixins: [colors],
onLoad(e) {
this.id = e.id ? e.id : 0;
this.getList()
},
methods: {
getList() {
if (this.loading) return;
this.loading = true;
matchPayListApi(this.id, this.params).then(res => {
this.loading = false;
if (!res.data.length) {
return uni.navigateBack({
delta: 1
});
}
res.data.map((item, index) => {
this.$set(item, 'totalPrice', 0);
item.products.map((item1, i) => {
let skuData = this.DefaultSelect(item1);
Object.assign(item1, skuData);
if(!item.type){
this.$set(item1, 'select', true);
item.totalPrice += Number(item1.price);
}else{
this.$set(item1, 'select', i == 0 ? true : false);
this.$set(item, 'totalPrice', Number(item.products[0].price));
}
})
})
this.discountsData = this.discountsData.concat(res.data);
this.params.page = this.params.page + 1;
}).catch(err => {
this.$util.Tips({
title: err
});
})
},
backPage() {
uni.navigateBack()
},
checkPro(pro, indexn, item) {
if(!item.type) return this.$util.Tips({
title: '本套餐为固定套餐,不可更改'
})
if(item.type && indexn == 0) return this.$util.Tips({
title: '套餐主商品不可取消'
})
pro.select = !pro.select;
if (pro.select) {
item.totalPrice = (Number(item.totalPrice) + Number(pro.price)).toFixed(2);
} else {
item.totalPrice = (Number(item.totalPrice) - Number(pro.price)).toFixed(2);
let i = this.selectValue.findIndex(v => v == pro.id);
}
},
tapAttr: function(indexw, indexn) {
let that = this;
this.$set(this.attr.productAttr[indexw], 'index', this.attr.productAttr[indexw].attr_values[indexn]);
let value = that.getCheckedValue().join(",");
let skuData = {
price: this.productValue[value].price,
unique: this.productValue[value].unique || '',
suk: this.productValue[value].suk || '默认',
};
this.attr.productSelect = {
price: this.productValue[value].price,
image: this.productValue[value].image,
stock: this.productValue[value].stock
};
this.$nextTick(() => {
Object.assign(this.discountsData[this.index].products[this.indexn], skuData);
let priceNum = 0;
let newArr = this.discountsData[this.index].products.filter(item=> item.select === true);
for (let i = 0; i < newArr.length; i++) {
priceNum += parseFloat(newArr[i].price)
}
this.$set(this.discountsData[this.index],'totalPrice',priceNum);
})
},
//获取被选中属性;
getCheckedValue: function() {
let productAttr = this.attr.productAttr;
let value = [];
for (let i = 0; i < productAttr.length; i++) {
for (let j = 0; j < productAttr[i].attr_values.length; j++) {
if (productAttr[i].index === productAttr[i].attr_values[j]) {
value.push(productAttr[i].attr_values[j]);
}
}
}
return value;
},
DefaultSelect(item) {
let productAttr = item.productAttr;
let value = [];
let arrPrice = []
for (var key in item.productValue) {
arrPrice.push(item.productValue[key].price)
}
let min = Math.min.apply(null, arrPrice);
for (var key in item.productValue) {
if (item.productValue[key].product_stock > 0 && item.productValue[key].price == min) {
value = item.productAttr.length ? key.split(',') : [];
break;
}
}
for (let i = 0; i < item.productAttr.length; i++) {
this.$set(item.productAttr[i], 'index', value[i]);
}
let productSelect = item.productValue[value.join(',')];
let skuData = {
price: productSelect.price,
unique: productSelect.unique || '',
suk: productSelect.suk || '默认',
stock: productSelect.stock
};
return skuData
},
closeDrawer() {
this.visible = false;
},
selecAttr(item, index, indexn) {
this.index = index;
this.indexn = indexn;
this.productValue = item.productValue;
this.attr = {
productAttr: item.productAttr,
productSelect: {
price: item.price,
image: item.image,
stock: item.stock
},
};
this.visible = true;
},
subData(item) {
let reqData = {
new: 1,
discountId: item.id,
discountInfos: []
};
let count = 0;
item.products.forEach((pro, i) => {
if (pro.select) {
count++;
reqData.discountInfos.push({
id: pro.id,
unique: pro.unique,
product_id: pro.product_id
})
}
})
if (count < 2) {
return this.$util.Tips({
title: '请先选择套餐商品'
});
}
postCartAdd(reqData).then(res => {
uni.navigateTo({
url: '/pages/goods/order_confirm/index?new=1&noCoupon=1&cartId=' + res.data.cartId
.join(',')
});
}).catch(err => {
return this.$util.Tips({
title: err
});
});
},
},
}
</script>
<style>
page{
background-color: #000;
}
.pro_card~.pro_card {
margin-top: 20rpx;
}
.z-900 {
z-index: 900;
}
.con-border {
border: 1rpx solid var(--view-theme);
}
.SemiBold {
font-family: SemiBold;
}
.jianbian {
background: linear-gradient(90deg, #FF7931 0%, #E93323 100%);
}
.bg-black {
background-color: rgba(0, 0, 0, 0.4);
}
.set-icon {
position: absolute;
right: 8rpx;
top: 8rpx;
z-index: 9;
}
.bgIcon{
position: absolute;
right: 12rpx;
top: 12rpx;
width: 30rpx;
height: 30rpx;
background-color: #fff;
border-radius: 50%;
}
.match-box {
width: 424rpx;
background-color: rgba(0, 0, 0, 0.3);
position: absolute;
left: 24rpx;
bottom: 24rpx;
}
.sku-item {
height: 56rpx;
line-height: 56rpx;
border: 1px solid #F2F2F2;
font-size: 24rpx;
color: #333;
padding: 0 44rpx;
border-radius: 28rpx;
margin: 24rpx 0 0 16rpx;
background-color: #F2F2F2;
word-break: break-all;
}
.active {
color: var(--view-theme);
background: var(--view-minorColorT);
border-color: var(--view-theme);
}
.scroll-content {
max-height: 800rpx;
overflow-y: auto;
}
.pb-box{
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
}
</style>

View File

@@ -0,0 +1,510 @@
<template>
<view :style="colorStyle">
<view class="px-20">
<view class="flex justify-between mt-24">
<view class="flex-1 mt-8">
<view class="fs-36 fw-500 lh-50rpx">{{orderInfo._status._msg}}</view>
<view class="w-486 fs-24 text--w111-999 lh-34rpx mt-12">{{orderInfo._status.desc}}</view>
</view>
<image :src="orderInfo._status.pic" class="w-172 h-172"></image>
</view>
<statusLine :type="orderInfo._status._type" :applyType="orderInfo.apply_type"></statusLine>
<view class="bg--w111-fff rd-16rpx mt-20 pt-32 pl-24 pr-24 pb-32"
v-if="[2,3].includes(orderInfo.apply_type)">
<view class="flex-between-center">
<text class="fs-32 fw-500">商家地址</text>
<text class="inline-block copy_btn fs-22" @click="copyAddress">复制</text>
</view>
<view class="mt-28 fs-28 lh-40rpx">
<text>{{orderInfo._status.refund_name}}</text>
<text class="pl-20">{{orderInfo._status.refund_phone}}</text>
</view>
<view class="w-full fs-24 lh-34rpx text--w111-999 mt-8 line2">{{orderInfo._status.refund_address}}</view>
</view>
<view class="bg--w111-fff rd-16rpx mt-20 pt-32 pl-24 pr-24 pb-32">
<view class="flex justify-between order_goods" v-for="(item,index) in cartInfo" :key="index">
<image class="w-136 h-136 rd-16rpx" :src='item.productInfo.attrInfo.image' v-if="item.productInfo.attrInfo"></image>
<image class="w-136 h-136 rd-16rpx" :src='item.productInfo.image' v-else></image>
<view class="flex-1 h-136 pl-20 flex-col justify-between">
<view class="w-full fs-28 lh-40rpx line2">{{item.productInfo.store_name}}</view>
<view class="flex-between-center fs-24 lh-34rpx">
<text class="text--w111-999">购买数量: {{item.cart_num}}</text>
<text>购买售价:{{item.productInfo.attrInfo ? item.productInfo.attrInfo.price : item.productInfo.price}}</text>
</view>
</view>
</view>
<!-- #ifdef MP -->
<button class="flex-center pt-24 bt-e fs-28 mt-32" hover-class='none' open-type='contact'
v-if="orderInfo.routine_contact_type == 1">
<text class="iconfont icon-ic_customerservice fs-40"></text>
<text class="fs-18">客服</text>
</button>
<view class='flex-center pt-24 bt-e fs-28 mt-32' v-else @tap="goGoodCall">
<text class="iconfont icon-ic_customerservice"></text>
<text class="pl-16">联系客服</text>
</view>
<!-- #endif -->
<!-- #ifdef H5 || APP-PLUS -->
<view class='flex-center pt-24 bt-e fs-28 mt-32' @tap="goGoodCall">
<text class="iconfont icon-ic_customerservice"></text>
<text class="pl-16">联系客服</text>
</view>
<!-- #endif -->
</view>
<view class="bg--w111-fff rd-16rpx mt-20 pt-32 pl-24 pr-24 pb-32">
<view>
<view class="flex-between-center fs-28">
<text>退款原因</text>
<text>{{orderInfo.refund_reason}}</text>
</view>
<view class="pt-32 flex-between-center fs-28">
<text>退款金额</text>
<text class="font-color fs-36 Regular">¥{{parseFloat(orderInfo.refunded_price) || orderInfo.refund_price}}</text>
</view>
<view class="pt-32 flex-between-center fs-28">
<text>申请件数</text>
<text>{{orderInfo.refund_num}}</text>
</view>
</view>
</view>
<view class="bg--w111-fff rd-16rpx mt-20 pt-32 pl-24 pr-24 pb-32">
<view class="cell flex-between-center">
<text class="fs-28">订单编号</text>
<view>
<text class="fs-28 pr-12">{{orderInfo.store_order_sn}}</text>
<text class="inline-block copy_btn fs-22" @click="copy(orderInfo.store_order_sn)">复制</text>
</view>
</view>
<view class="cell flex-between-center fs-28">
<text>申请时间</text>
<text>{{orderInfo._add_time}}</text>
</view>
<view class="cell flex-between-center fs-28">
<text>售后类型</text>
<text v-if="orderInfo.apply_type == 1">仅退款</text>
<text v-else-if="[2,3].includes(orderInfo.apply_type)">退货退款</text>
<text v-else-if="orderInfo.apply_type == 4">商家主动退款</text>
</view>
<view class="cell flex-between-center">
<text class="fs-28">售后单号</text>
<view>
<text class="fs-28 pr-12">{{orderInfo.order_id}}</text>
<text class="inline-block copy_btn fs-22" @click="copy(orderInfo.order_id)">复制</text>
</view>
</view>
<view class="bt mt-32">
<view class="pt-32 flex justify-between fs-28" v-if="orderInfo.remark">
<text>备注说明</text>
<view class="w-462 line2 lh-40rpx text-right">{{orderInfo.remark}}</view>
</view>
<view class="pt-32 flex justify-between fs-28" v-if="orderInfo.refund_img && orderInfo.refund_img.length">
<text>售后凭证</text>
<view class="w-462 flex justify-end" v-if="orderInfo.refund_img.length < 5">
<view class='pictrue mr-8' v-for="(item,index) in orderInfo.refund_img" :key="index">
<image class="w-88 h-88 rd-8rpx" :src='item' mode="aspectFill" ></image>
</view>
</view>
<scroll-view scroll-x="true" scroll-with-animation
class="white-nowrap vertical-middle w-462" show-scrollbar="false" v-else>
<view class="inline-block mr-12" v-for="(item,index) in orderInfo.refund_img" :key="index">
<image class="w-88 h-88 rd-8rpx" :src="item"></image>
</view>
</scroll-view>
</view>
<view class="pt-32 flex justify-between fs-28">
<text>退款方式</text>
<view class="w-462 line2 lh-40rpx text-right">{{orderInfo.refund_price_type}}</view>
</view>
</view>
</view>
<view class="bg--w111-fff rd-16rpx mt-20 pt-32 pl-24 pr-24 pb-32" v-if="[2,3].includes(orderInfo.apply_type) && orderInfo._status._type== 5">
<view class="fs-28 fw-500">退货信息</view>
<view class="bt mt-32">
<view class="pt-32 flex justify-between fs-28">
<text>退货方式</text>
<view class="w-462 line2 lh-40rpx text-right">{{orderInfo.apply_type == 2 ? '快递退回' : '到店退货'}}</view>
</view>
<view class="pt-32 flex justify-between fs-28" v-if="orderInfo.apply_type == 2">
<text>物流公司</text>
<view class="w-462 line2 lh-40rpx text-right">{{orderInfo.refund_express_name}}</view>
</view>
<view class="pt-32 flex justify-between fs-28" v-if="orderInfo.apply_type == 2">
<text>物流单号</text>
<view class="w-462 line2 lh-40rpx text-right">{{orderInfo.refund_express}}</view>
</view>
<view class="pt-32 flex justify-between fs-28">
<text>退货说明</text>
<view class="w-462 line2 lh-40rpx text-right">{{orderInfo.refund_explain}}</view>
</view>
<view class="pt-32 flex justify-between fs-28" v-if="orderInfo.refund_goods_img.length">
<text>售后凭证</text>
<view class="w-462 flex justify-end" v-if="orderInfo.refund_goods_img.length < 5">
<view class='pictrue mr-8' v-for="(item,index) in orderInfo.refund_goods_img" :key="index">
<image :src='item' mode="aspectFill" class="w-88 h-88 rd-8rpx"></image>
</view>
</view>
<scroll-view scroll-x="true" scroll-with-animation
class="white-nowrap vertical-middle w-462" show-scrollbar="false" v-else>
<view class="inline-block mr-12" v-for="(item,index) in orderInfo.refund_goods_img" :key="index">
<image class="w-88 h-88 rd-8rpx" :src="item"></image>
</view>
</scroll-view>
</view>
<view class="pt-32 flex justify-between fs-28">
<text>联系电话</text>
<view class="w-462 line2 lh-40rpx text-right">{{orderInfo.refund_phone}}</view>
</view>
</view>
</view>
</view>
<view class="h-200"></view>
<view class='fixed-lb bt w-full bg--w111-fff pb-safe'>
<view class="h-96 px-20 flex-y-center justify-end">
<view class="btn w-144 h-56 rd-30rpx flex-center fs-24 border bg--w111-fff"
v-if="[0,1,2,4,5].includes(orderInfo.refund_type) && orderInfo.is_cancel == 0"
@tap='cancelRefundOrder'>撤销售后</view>
<view class="btn w-144 h-56 rd-30rpx flex-center fs-24 text--w111-fff bg-color"
v-if="orderInfo.refund_type == 4 && orderInfo.is_cancel == 0 && orderInfo.apply_type == 2"
@tap='refundInput'>退回商品</view>
<view class="btn w-144 h-56 rd-30rpx flex-center fs-24 text--w111-fff bg-color"
v-if="[5,6].includes(orderInfo.refund_type) && orderInfo.apply_type == 2"
@tap='refundLogistics'>返件信息</view>
<view class="btn w-144 h-56 rd-30rpx flex-center fs-24 border bg--w111-fff"
v-if="orderInfo.refund_type == 3 && orderInfo.is_cancel == 0" @click="refundAgain">再次申请</view>
</view>
</view>
<home></home>
</view>
</template>
<script>
import {
getRefundOrderDetail,
orderAgain,
orderTake,
cancelRefundOrder,
orderRefundAgain
} from '@/api/order.js';
import { openOrderRefundSubscribe } from '@/utils/SubscribeMessage.js';
import { getUserInfo } from '@/api/user.js';
import {toLogin} from '@/libs/login.js';
import {mapGetters} from "vuex";
import colors from "@/mixins/color";
import statusLine from '../components/statusLine/index'
import { HTTP_REQUEST_URL } from '@/config/app';
export default {
components: {
statusLine,
},
mixins: [colors],
data() {
return {
imgHost: HTTP_REQUEST_URL,
giveData: {
give_integral: 0,
give_coupon: []
},
giveCartInfo: [],
config: {
qrc: {
code: "",
size: 360, // 二维码大小
level: 4, //等级 0~4
bgColor: '#FFFFFF', //二维码背景色 默认白色
color: ['#333', '#333'], //边框颜色支持渐变色
}
},
order_id: '',
evaluate: 0,
cartInfo: [], //购物车产品
pid: 0, //上级订单ID
split: [], //分单商品
orderInfo: {
system_store: {},
_status: {}
}, //订单详情
system_store: {},
isGoodsReturn: false, //是否为退款订单
status: {}, //订单底部按钮状态
refund_close: false,
isClose: false,
pay_close: false,
pay_order_id: '',
totalPrice: '0',
isAuto: false, //没有授权的不会自动授权
isShowAuth: false, //是否隐藏授权
routineContact: 0,
express_num: '',
invoice_func: false,
invoiceData: {},
invoice_id: 0,
invChecked: '',
moreBtn: false,
invShow: false,
aleartStatus: false, //发票弹窗
special_invoice: false,
invList: [],
userInfo: {},
isReturen: '',
showQrcode:false
};
},
computed: {
isExpress(){
if((this.orderInfo.shipping_type === 1 || this.orderInfo.shipping_type === 3) && this.orderInfo.product_type==0){
return true
}else{
return false
}
},
...mapGetters(['isLogin']),
},
onLoad: function(options) {
if (options.order_id) {
this.$set(this, 'order_id', options.order_id);
this.isReturen = options.isReturen;
}
if (options.invoice_id) {
this.invoice_id = options.invoice_id
}
},
onShow() {
uni.removeStorageSync('form_type_cart');
if (this.isLogin) {
this.getOrderInfo();
this.getUserInfo();
} else {
toLogin()
}
},
onPageScroll(object) {
uni.$emit('scroll');
},
methods: {
onLoadFun() {
this.getOrderInfo();
this.getUserInfo();
this.isShowAuth = false
},
// 授权关闭
authColse: function(e) {
this.isShowAuth = e
},
getpreviewImage: function(index, num) {
uni.previewImage({
urls: num ? this.orderInfo.refund_img : this.orderInfo.refund_goods_img,
current: num ? this.orderInfo.refund_img[index] : this.orderInfo.refund_goods_img[index]
});
},
cancelRefundOrder(orderId) {
let that = this;
uni.showModal({
title: '取消申请',
content: '您确认放弃此次申请吗?',
success: (res) => {
if (res.confirm) {
cancelRefundOrder(that.order_id).then(res => {
return that.$util.Tips({
title: '操作成功',
icon: 'success'
}, {
tab: 4,
url: '/pages/users/user_return_list/index'
});
}).catch(err => {
return that.$util.Tips({
title: err
});
})
}
}
})
},
refundInput() {
uni.navigateTo({
url: `/pages/goods/order_refund_goods/index?orderId=` + this.order_id
})
},
goGoodCall() {
let url = `/pages/extension/customer_list/chat?orderId=${this.order_id}&isReturen=${this.isReturen}`
let obj = {
store_name: this.orderInfo.order_id,
path: `/pages/goods/order_after_details/index?order_id=${this.orderInfo.order_id}`,
image: ''
}
this.$util.getCustomer(this.userInfo,url,obj,1)
},
/**
* 事件回调
*
*/
onChangeFun: function(e) {
let opt = e;
let action = opt.action || null;
let value = opt.value != undefined ? opt.value : null;
(action && this[action]) && this[action](value);
},
/**
* 拨打电话
*/
makePhone: function() {
uni.makePhoneCall({
phoneNumber: this.system_store.phone
})
},
/**
* 打开地图
*
*/
showMaoLocation: function() {
if (!this.system_store.latitude || !this.system_store.longitude) return this.$util.Tips({
title: '缺少经纬度信息无法查看地图!'
});
uni.openLocation({
latitude: parseFloat(this.system_store.latitude),
longitude: parseFloat(this.system_store.longitude),
scale: 8,
name: this.system_store.name,
address: this.system_store.address + this.system_store.detailed_address,
success: function() {
},
});
},
/**
* 获取用户信息
*
*/
getUserInfo: function() {
let that = this;
getUserInfo().then(res => {
that.userInfo = res.data;
})
},
/**
* 获取订单详细信息
*
*/
getOrderInfo: function() {
let that = this;
uni.showLoading({
title: "正在加载中"
});
getRefundOrderDetail(this.order_id).then(res => {
let _type = res.data._status._type;
uni.hideLoading();
that.$set(that, 'orderInfo', res.data);
let cartInfo = res.data.cartInfo;
let cartObj = [],giftObj = [];
cartInfo.forEach(item => {
if (item.is_gift == 1) {
giftObj.push(item)
} else {
cartObj.push(item)
}
})
that.$set(that, 'cartInfo', cartObj);
that.$set(that, 'giveCartInfo', giftObj);
}).catch(err => {
uni.hideLoading();
if (err.status == 403) {
uni.navigateTo({
url: '/pages/goods/order_list/index'
})
} else {
that.$util.Tips({
title: err
}, '/pages/goods/order_list/index');
}
});
},
copy: function(code) {
let that = this;
uni.setClipboardData({
data: code
});
},
copyAddress() {
uni.setClipboardData({
data: this.orderInfo._status.refund_name + this.orderInfo._status.refund_phone + this.orderInfo._status.refund_address
});
},
/**
* 打电话
*/
goTel: function() {
uni.makePhoneCall({
phoneNumber: this.orderInfo.delivery_id
})
},
goPage(type, url){
if(type == 1){
uni.navigateTo({
url
})
}else if(type == 2){
uni.switchTab({
url
})
}else if(type == 3){
uni.navigateBack();
}
},
// 返件信息
refundLogistics(){
uni.navigateTo({
url: '/pages/goods/goods_logistics/index?orderId='+ this.order_id + '&type=refund'
})
},
// 再次申请售后
refundAgain(){
orderRefundAgain(this.orderInfo.id).then(res=>{
this.$util.Tips({
title: res.msg
}, '/pages/users/user_return_list/index');
}).catch(err => {
return this.$util.Tips({
title: err
});
})
},
}
}
</script>
<style lang="scss">
.order_goods ~ .order_goods{
margin-top: 32rpx;
}
.Regular {
font-family: Regular;
}
.copy_btn{
width: 68rpx;
height: 36rpx;
background: #F5F5F5;
border-radius: 20rpx;
text-align:center;
line-height:36rpx;
}
.btn ~ .btn{
margin-left: 16rpx;
}
.bt{
border-top:1rpx solid #eee;
}
.border{
border: 1rpx solid #ccc;
}
.border_bt{
border-bottom: 1rpx solid #eee;
}
.bt-e{
border-top: 1px solid #eee;
}
.cell ~ .cell{
margin-top: 32rpx;
}
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,566 @@
<template>
<view :style="colorStyle">
<view class="fixed-lt bg--w111-f5f5f5 w-full z-999 header_box" :style="{ 'padding-top': sysHeight + 'px' }">
<view class="h-80 px-20 flex-y-center">
<text class="iconfont icon-ic_leftarrow fs-40 text--w111-333" @click="goPage(3)"></text>
<!-- #ifdef MP-WEIXIN -->
<view class="w-444 h-58 rd-30 bg--w111-fff flex-y-center px-32 ml-20">
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<view class="flex-1 h-58 rd-30 bg--w111-fff flex-y-center px-32 ml-20">
<!-- #endif -->
<text class="iconfont icon-ic_search fs-24 text--w111-999"></text>
<input
v-model="keyword"
confirm-type="search"
@focus="searchFocus"
@confirm="inputConfirm"
class="pl-18 flex-1 fs-24"
placeholder="请输入商品名称"
placeholder-class="text--w111-999"
/>
</view>
</view>
<view class="h-100 w-full px-32 flex-between-center fs-26" v-show="!focus">
<text :class="orderStatus === '' ? 'active' : ''" @click="statusClick('')">全部</text>
<text :class="orderStatus === 0 ? 'active' : ''" @click="statusClick(0)">待付款</text>
<text :class="orderStatus === 1 ? 'active' : ''" @click="statusClick(1)">待发货</text>
<view class="relative">
<text :class="orderStatus === 2 ? 'active' : ''" @click="statusClick(2)">待收货/核销</text>
<uni-badge class="uni-badge-left-margin" v-if="orderData.received_count > 0" :text="orderData.received_count"></uni-badge>
</view>
<text :class="orderStatus === 3 ? 'active' : ''" @click="statusClick(3)">待评价</text>
</view>
</view>
<view class="pt-32 pl-20 pr-20" :style="{ 'margin-top': marTop - 50 + 'px' }" v-show="focus">
<view class="fs-28 text--w111-333 fw-500 lh-40rpx mb-24">历史搜索</view>
<view class="flex flex-wrap">
<text
class="inline-block max-200 h-56 line1 lh-56rpx rd-28rpx bg--w111-fff px-24 fs-24 text--w111-666 text-center mr-24 mb-16"
v-for="(item, index) in historyList"
:key="index"
@click="goSearch(item)"
>
{{ item }}
</text>
</view>
</view>
<view class="px-20" :style="{ 'margin-top': marTop + 'px' }" v-show="!focus">
<view class="order_card " v-for="(item, index) in orderList" :key="index" @click="goOrderDetails(item.order_id)">
<view v-if="item.is_send_gift" class="o5c782 z-999">
<text class="iconfont icon-ic_gift2 text--w111-CA790F fs-32 pr-10"></text>
<text class="fs-26 text--w111-AE5A2A" v-if="item.receive_gift_uid != 0 && item.receive_gift_uid == uid">{{ item.nickname }} 送的礼物</text>
<text class="fs-26 text--w111-AE5A2A" v-else>送给 {{ item.receive_gift_uid ? item.receive_gift_user_info.receive_gift_nickname : 'TA' }} 的礼物</text>
</view>
<view class="bg--w111-fff rd-24rpx rd-24rpx pt-32 pb-32 pl-24 pr-24" :class="{'-mt-24':item.is_send_gift}">
<view class="flex-between-center">
<view class="flex-y-center">
<text v-if="item.type_name" class="h-32 lh-28rpx bg--w111-fff px-6 rd-6rpx text-center vertical-middle fs-20 o8e37 font-num">
{{ item.type_name }}
</text>
<text class="fs-28 lh-40rpx text--w111-333 pl-16">{{ item._add_time }}</text>
</view>
<view class="fs-26">
<view class="font-num">
<text v-if="item.is_send_gift">{{ item.receive_gift_uid == 0 ? '待领取' : '已领取' }}</text>
<template v-else>
<text v-show="item.is_del == 0">{{ item._status._title }}</text>
<text v-show="item.is_del == 1">交易取消</text>
<text v-if="item.refund.length">{{ item.is_all_refund ? ',退款中' : ',部分退款中' }}</text>
</template>
</view>
</view>
</view>
<view class="mt-26" v-if="item.cartInfo.length && item.cartInfo.length == 1">
<view class="flex justify-between" v-for="(items, i) in item.cartInfo" :key="i">
<view class="flex">
<easy-loadimage :image-src="items.productInfo.image" width="136rpx" height="136rpx" borderRadius="16rpx"></easy-loadimage>
<view class="ml-20">
<view class="w-346 fs-28 text--w111-333 lh-40rpx line2">
{{ items.productInfo.store_name }}
</view>
<view class="w-346 fs-24 text--w111-999 lh-34rpx line1 mt-12">{{ items.productInfo.attrInfo.suk }}</view>
</view>
</view>
<view>
<baseMoney
v-if="items.productInfo.attrInfo && item.receive_gift_uid != uid"
:money="item.pay_price"
symbolSize="20"
integerSize="32"
decimalSize="20"
incolor="#333333"
weight
></baseMoney>
<view class="fs-24 text--w111-999 lh-34rpx text-right">共{{ item.total_num }}件</view>
</view>
</view>
</view>
<view class="mt-26 relative" v-if="item.cartInfo.length && item.cartInfo.length > 1">
<scroll-view scroll-x="true" class="white-nowrap vertical-middle w-560" show-scrollbar="false">
<view class="inline-block mr-16" v-for="(items, i) in item.cartInfo" :key="i">
<easy-loadimage :image-src="items.productInfo.image" width="136rpx" height="136rpx" borderRadius="16rpx"></easy-loadimage>
</view>
</scroll-view>
<view class="abs-rt h-136 flex-col flex-center">
<baseMoney v-if="item.receive_gift_uid != uid" :money="item.pay_price" symbolSize="20" integerSize="32" decimalSize="20" incolor="#333333" weight></baseMoney>
<view class="fs-24 text--w111-999 lh-34rpx text-right">共{{ item.total_num }}件</view>
</view>
</view>
<view class="h-72 rd-8rpx bg--w111-f5f5f5 mt-26 px-20 flex-between-center">
<view v-show="item.is_del == 0" @click.stop="goRefundDetails">
<text class="text--w111-333 fs-26">{{ item._status._title }}</text>
<text class="text--w111-999 fs-26 pl-20">{{ item._status._msg }}</text>
</view>
<view v-show="item.is_del == 1">
<text class="text--w111-333 fs-26">已取消</text>
<text class="text--w111-999 fs-26 pl-20">本次交易已取消,感谢您的支持</text>
</view>
<text class="iconfont icon-ic_rightarrow fs-24 text--w111-999"></text>
</view>
</view>
</view>
<block v-if="orderList.length == 0 && !loading">
<emptyPage title="暂无订单信息~" :src="keyword ? '/statics/images/noSearch.gif' : '/statics/images/noOrder.gif'"></emptyPage>
</block>
<view class="loadingicon flex-center" v-if="orderList.length > 0">
<text class="loading iconfont icon-ic_Refresh" :hidden="loading == false"></text>
<text class="fs-26 pb-32">{{ loadTitle }}</text>
</view>
</view>
<!-- 确认框 -->
<tuiModal :show="showModal" :title="modalTitle" :content="modalContent" :maskClosable="false" @click="handleClick" @cancel="hideModal"></tuiModal>
</view>
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight;
import { getOrderList, orderData, orderCancel, orderDel, orderPay, orderAgain } from '@/api/order.js';
import { openOrderSubscribe } from '@/utils/SubscribeMessage.js';
import tuiModal from '@/components/tui-modal/index.vue';
import { toLogin } from '@/libs/login.js';
import { mapGetters } from 'vuex';
import emptyPage from '@/components/emptyPage.vue';
import colors from '@/mixins/color.js';
import Loading from '@/components/Loading/index.vue';
export default {
components: {
Loading,
emptyPage,
tuiModal
},
mixins: [colors],
data() {
return {
sysHeight: sysHeight,
loaded: false,
loading: false, //是否加载中
loadend: false, //是否加载完毕
loadTitle: '加载更多', //提示语
orderList: [], //订单数组
orderData: {}, //订单详细统计
orderStatus: '', //订单状态
orderType: '', //订单类型
page: 1,
limit: 20,
pay_close: false,
pay_order_id: '',
totalPrice: '0',
isAuto: false, //没有授权的不会自动授权
isShowAuth: false, //是否隐藏授权
keyword: '',
marTop: 0,
focus: false,
// 搜索历史
historyList: [],
// 临时搜索列表
tempStorage: [],
//确认模态框
showModal: false,
modalTitle: '',
modalContent: '',
modalType: 0,
orderId: '',
uid: 0
};
},
computed: {
...mapGetters(['isLogin']),
fixedTop() {
// #ifdef MP || APP-PLUS
return this.sysHeight + 'px';
// #endif
return this.data;
// #ifndef MP
return 0;
// #endif
}
},
onShow() {
uni.removeStorageSync('form_type_cart');
this.page = 1;
this.loadend = false;
this.orderList = [];
this.uid = this.$store.state.app.uid;
if (this.isLogin) {
this.getFun();
} else {
toLogin();
}
},
onPageScroll(object) {
uni.$emit('scroll');
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
if (options.status) this.orderStatus = options.status == undefined && options.status != 0 ? '' : parseInt(options.status);
if (options.type) this.orderType = options.type == undefined && options.type != 0 ? '' : parseInt(options.type);
this.getMarTop();
},
methods: {
getFun() {
this.getOrderData();
this.getOrderList();
},
onLoadFun() {
this.getFun();
this.isShowAuth = false;
},
getMarTop() {
let that = this;
setTimeout(() => {
// 获取小程序头部高度
let o8fa227 = uni.createSelectorQuery().in(this).select('.header_box');
o8fa227
.boundingClientRect(function (data) {
that.marTop = data.height;
})
.exec();
}, 100);
},
/**
* 获取订单统计数据
*
*/
getOrderData: function () {
let that = this;
orderData({ channel: this.$store.state.app.identity == 1 ? 1 : '' }).then((res) => {
that.$set(that, 'orderData', res.data);
});
},
showModalChange(orderId, type) {
this.orderId = orderId;
this.modalType = type;
if (type == 1) {
this.modalTitle = '确认收货';
this.modalContent = '为保障权益,请收到货确认无误后,再确认收货';
} else if (type == 2) {
this.modalTitle = '删除订单';
this.modalContent = '确定删除该订单?';
} else if (type == 3) {
this.modalTitle = '温馨提示';
this.modalContent = '确认取消该订单?';
}
this.showModal = true;
},
handleClick(e) {
let of0b21 = e.index;
if (of0b21 == 1) {
if (this.modalType == 1) {
orderTake(this.orderId)
.then((res) => {
this.showModal = false;
this.goSearch('');
this.getOrderData();
})
.catch((err) => {
return this.$util.Tips({
title: err
});
});
} else if (this.modalType == 2) {
orderDel(this.orderId).then((res) => {
this.showModal = false;
this.goSearch('');
this.getOrderData();
});
} else if (this.modalType == 3) {
this.showModal = false;
orderCancel(this.orderId).then(() => {
this.goSearch('');
this.getOrderData();
});
}
} else {
this.showModal = false;
}
},
hideModal() {
this.showModal = false;
},
/**
* 取消订单
*
*/
cancelOrder: function (index, order_id) {
let that = this;
if (!order_id)
return that.$util.Tips({
title: '缺少订单号无法取消订单'
});
orderCancel(order_id)
.then((res) => {
return that.$util.Tips(
{
title: res.msg,
icon: 'success'
},
function () {
that.orderList.splice(index, 1);
that.$set(that, 'orderList', that.orderList);
that.$set(that.orderData, 'unpaid_count', that.orderData.unpaid_count - 1);
that.getOrderData();
}
);
})
.catch((err) => {
return that.$util.Tips({
title: err
});
});
},
goPay: function (order_id) {
uni.redirectTo({
url: `/pages/goods/cashier/index?order_id=${order_id}&from_type=order`
});
},
goRefundDetails() {
if (!order_id)
return this.$util.Tips({
title: '缺少订单号无法查看订单详情'
});
uni.navigateTo({
url: '/pages/goods/order_after_details/index?order_id=' + order_id + '&isReturen=1'
});
},
goOrderDetails(order_id) {
if (!order_id)
return this.$util.Tips({
title: '缺少订单号无法查看订单详情'
});
// #ifdef MP
uni.showLoading({
title: '正在加载'
});
openOrderSubscribe()
.then(() => {
uni.hideLoading();
uni.navigateTo({
url: '/pages/goods/order_details/index?order_id=' + order_id
});
})
.catch((err) => {
uni.hideLoading();
});
// #endif
// #ifndef MP
uni.navigateTo({
url: '/pages/goods/order_details/index?order_id=' + order_id
});
// #endif
},
/**
* 切换类型
*/
statusClick: function (status) {
if (this.loading) return;
if (status === this.orderStatus) return;
this.orderStatus = status;
this.loadend = false;
this.page = 1;
this.$set(this, 'orderList', []);
this.getOrderList();
},
searchFocus() {
try {
this.historyList = [];
this.tempStorage = [];
let arr = uni.getStorageSync('orderHistoryList');
if (arr.length > 0) {
this.historyList = Array.from(new Set(arr));
} else {
this.historyList = [];
}
this.tempStorage = this.historyList;
} catch (e) {}
this.focus = true;
},
goSearch(keyword) {
this.loadend = false;
this.loading = false;
this.keyword = keyword;
this.page = 1;
this.orderList = [];
this.getOrderList();
},
inputConfirm() {
this.loadend = false;
this.loading = false;
this.page = 1;
this.orderList = [];
this.getOrderList();
setTimeout((e) => {
let arr = this.tempStorage;
if (this.keyword !== '') {
arr.unshift(this.keyword);
this.tempStorage = [...Array.from(new Set(arr))];
uni.setStorageSync('orderHistoryList', this.tempStorage);
}
}, 1000);
},
/**
* 获取订单列表
*/
getOrderList: function () {
let that = this;
if (that.loadend) return;
if (that.loading) return;
that.loading = true;
that.loadTitle = '加载更多';
getOrderList({
status: that.orderStatus,
page: that.page,
limit: that.limit,
search: this.keyword,
channel: this.$store.state.app.identity == 1 ? 1 : '',
type: this.orderType
})
.then((res) => {
let list = res.data || [];
let loadend = list.length < that.limit;
that.orderList = that.$util.SplitArray(list, that.orderList);
that.$set(that, 'orderList', that.orderList);
that.loadend = loadend;
that.loading = false;
that.loadTitle = loadend ? '没有更多内容啦~' : '加载更多';
that.page = that.page + 1;
that.focus = false;
})
.catch((err) => {
that.loading = false;
that.loadTitle = '加载更多';
});
},
/**
* 删除订单
*/
delOrder: function (order_id, index) {
let that = this;
uni.showModal({
title: '删除订单',
content: '确定删除该订单',
success: function (res) {
if (res.confirm) {
orderDel(order_id)
.then((res) => {
that.orderList.splice(index, 1);
that.$set(that, 'orderList', that.orderList);
that.$set(that.orderData, 'unpaid_count', that.orderData.unpaid_count - 1);
that.getOrderData();
return that.$util.Tips({
title: '删除成功',
icon: 'success'
});
})
.catch((err) => {
return that.$util.Tips({
title: err
});
});
} else if (res.cancel) {
return that.$util.Tips({
title: '已取消'
});
}
}
});
},
goPage(type, url) {
if (type == 1) {
uni.navigateTo({
url
});
} else if (type == 2) {
uni.switchTab({
url
});
} else if (type == 3) {
let pages = getCurrentPages(); // 获取当前打开过的页面路由数,
if (pages.length > 1) {
uni.navigateBack();
} else {
uni.switchTab({
url: '/pages/index/index'
});
}
}
}
},
onReachBottom: function () {
this.getOrderList();
}
};
</script>
<style scoped lang="scss">
.o8e37 {
border: 1px solid var(--view-theme);
}
.border_ccc {
border: 1rpx solid #ccc;
}
.active {
color: var(--view-theme);
font-weight: 500;
font-size: 30rpx;
}
.abs-rt {
position: absolute;
top: 0;
right: 0;
}
.order_card ~ .order_card {
margin-top: 20rpx;
}
.btn ~ .btn {
margin-left: 16rpx;
}
.uni-badge-left-margin {
position: absolute;
top: -16rpx;
right: -30rpx;
/deep/ .uni-badge--error {
background-color: var(--view-theme) !important;
}
.uni-badge {
color: var(--view-theme);
border: 1px solid var(--view-theme);
z-index: 29;
}
}
.o5c782 {
background-color: #fefaf3;
padding: 24rpx 24rpx 48rpx 24rpx;
border-radius: 16rpx 16rpx 0 0rpx;
color: #ae5a2a;
font-size: 26rpx;
}
</style>

View File

@@ -0,0 +1,538 @@
<template>
<view :style="colorStyle">
<view class="w-full relative z-99 bg-gradient" :style="{ 'padding-top': sysHeight + 'px' }">
<view class="w-full px-20 pl-20 h-80 flex-between-center" @tap="goIndex()">
<text class="iconfont icon-ic_leftarrow fs-40 text--w111-fff"></text>
<text class="fs-34 fw-500 text--w111-fff">订单支付</text>
<text></text>
</view>
<view class="flex-col flex-center mt-50">
<view class="flex-y-center">
<text class="iconfont icon-ic-complete1 fs-52 text--w111-fff" v-if="order_pay_info.paid || order_pay_info.pay_type == 'offline'"></text>
<view v-else class="iconfont icon-ic_close1 fs-52 text--w111-fff"></view>
<text class="fs-40 fw-500 text--w111-fff pl-16" v-if="order_pay_info.pay_type == 'offline' && !order_pay_info.paid">订单创建成功</text>
<text class="fs-40 fw-500 text--w111-fff pl-16" v-else>{{ order_pay_info.paid ? '订单支付成功' : '等待支付...' }}</text>
</view>
<view class="flex-center mt-30">
<view class="w-192 h-64 rd-40rpx flex-center fs-24 text--w111-fff white-border" @tap="goIndex">返回首页</view>
<view v-if="!order_pay_info.is_send_gift || !order_pay_info.paid" class="w-192 h-64 rd-40rpx flex-center fs-24 text--w111-fff white-border ml-48" @tap="goOrderDetails">
查看订单
</view>
<view v-else-if="order_pay_info.paid" @click="giftModalShow = true" class="w-192 h-64 rd-40rpx flex-center fs-24 text--w111-fff white-border ml-48">送给好友</view>
</view>
</view>
<view class="h-216"></view>
</view>
<view class="relative content bg--w111-fff w-full pt-32 pl-20 pr-20 z-100">
<view
class="card bg--w111-fff rd-24rpx h-484 pt-32 pl-20 pr-20"
v-if="order_pay_info.paid && order_pay_info.pay_type != 'offline' && prize.length && loading && lotteryLoading"
>
<gridsLottery
:prizeData="prize"
@get_winingIndex="getWiningIndex"
@luck_draw_finish="luck_draw_finish"
:lotteryNum="lottery_num"
:lotteryType="1"
:datatime="datatime"
></gridsLottery>
</view>
<view class="card bg--w111-fff rd-24rpx px-32" v-if="showGift">
<view class="cell flex-between-center py-32" v-for="(item, index) in couponList" :key="index + 'n'" @click="goPage(1, '/pages/users/user_coupon/index')">
<view class="flex-y-center">
<image :src="imgHost + '/statics/images/order/prize_coupon_icon.png'" class="w-76 h-76 rd-40rpx"></image>
<view class="ml-24">
<view class="fs-28 text--w111-333 lh-38rpx">下单得{{ item.coupon_price }}元优惠券</view>
<view class="fs-22 text--w111-999 lh-30rpx mt-8" v-if="parseInt(item.use_min_price > 0)">满{{ item.use_min_price }}元可用</view>
<view class="fs-22 text--w111-999 lh-30rpx mt-8" v-else>无门槛优惠券</view>
</view>
</view>
<view class="card_btn flex-center font-color fs-22">去使用</view>
</view>
<view class="cell flex-between-center py-32" v-for="(item, index) in giftList" :key="index + 'o'">
<view class="flex-y-center">
<image :src="imgHost + '/statics/images/order/prize_gift_icon.png'" class="w-76 h-76 rd-40rpx"></image>
<view class="ml-24">
<view class="fs-28 text--w111-333 line2 w-400">{{ item.store_name }}</view>
</view>
</view>
<view class="card_btn flex-center font-color fs-22" @tap="goOrderDetails">去使用</view>
</view>
<view class="cell flex-between-center py-32" v-if="prize_integral > 0" @click="goPage(1, '/pages/users/user_integral/index')">
<view class="flex-y-center">
<image :src="imgHost + '/statics/images/order/prize_integral_icon.png'" class="w-76 h-76 rd-40rpx"></image>
<view class="ml-24">
<view class="fs-28 text--w111-333 line2 w-400">获得{{ prize_integral }}积分</view>
<view class="fs-22 text--w111-999 lh-30rpx mt-8">下单即可抵扣</view>
</view>
</view>
<view class="card_btn flex-center font-color fs-22" @tap="goOrderDetails">去使用</view>
</view>
<view class="cell flex-between-center py-32" v-if="prize_exp > 0">
<view class="flex-y-center">
<image :src="imgHost + '/statics/images/order/prize_exp_icon.png'" class="w-76 h-76 rd-40rpx"></image>
<view class="ml-24">
<view class="fs-28 text--w111-333 line2 w-400">获得{{ prize_exp }}经验</view>
<view class="fs-22 text--w111-999 lh-30rpx mt-8">下单即可抵扣</view>
</view>
</view>
<view class="card_btn flex-center font-color fs-22" @tap="goOrderDetails">去使用</view>
</view>
</view>
<recommend :hostProduct="hostProduct" :title="recommendTitle"></recommend>
</view>
<lotteryAleart :aleartStatus="aleartStatus" :alData="alData" theme :aleartType="aleartType" @close="closeLottery"></lotteryAleart>
<view class="mask z-8000" v-if="aleartStatus || addressModel" @touchmove.stop.prevent="moveHandle"></view>
<giftModal :aleartStatus="giftModalShow" :giftData="giftData" @shareH5="shareH5" @close="giftModalShow = false"></giftModal>
<view class="mask z-101" v-if="giftModalShow"></view>
<canvas class="canvas" canvas-id="posterCanvas"></canvas>
<activityModal :pageIndex="5"></activityModal>
<home></home>
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight;
// import lotteryModel from './payLottery.vue'
import gridsLottery from '../components/lottery/payLottery.vue';
import lotteryAleart from '../components/lotteryAleart/index.vue';
import recommend from '@/components/recommend';
import { getOrderDetail, orderCoupon, getOrderPrizeApi } from '@/api/order.js';
import { openOrderSubscribe } from '@/utils/SubscribeMessage.js';
import giftModal from '../components/sendGiftPoster/index.vue';
import activityModal from "@/components/activityModal/index.vue";
import { getLotteryData, startLottery, receiveLottery } from '@/api/lottery.js';
import { getProductHot, postCartAdd } from '@/api/store.js';
import { toLogin } from '@/libs/login.js';
import { mapGetters } from 'vuex';
import colors from '@/mixins/color';
import { HTTP_REQUEST_URL } from '@/config/app';
import Cache from '@/utils/cache';
import { userShare } from '@/api/user.js';
export default {
components: {
gridsLottery,
lotteryAleart,
recommend,
giftModal,
activityModal
},
mixins: [colors],
data() {
return {
imgHost: HTTP_REQUEST_URL,
sysHeight: sysHeight,
loading: false,
lotteryLoading: false,
orderLottery: false,
orderId: '',
order_pay_info: {
paid: 1,
_status: {}
},
isAuto: false, //没有授权的不会自动授权
isShowAuth: false, //是否隐藏授权
status: 0,
msg: '',
couponsHidden: true,
couponList: [],
giftList: [],
options: {},
prize: [],
datatime: 0,
totalPrice: 0,
type: '',
lottery_draw_param: {
startIndex: 3, //开始抽奖位置,从0开始
totalCount: 3, //一共要转的圈数
winingIndex: 1, //中奖的位置,从0开始
speed: 100 //抽奖动画的速度 [数字越大越慢,默认100]
},
aleartType: 0,
aleartStatus: false,
addressModel: false,
lottery_num: 0,
alData: {},
hostProduct: [],
hotScroll: false,
hotPage: 1,
hotLimit: 10,
prize_integral: 0,
prize_exp: 0,
giftModalShow: false,
giftData: {
image: '',
title: '',
message: '',
id: 0,
avatar: '',
nickname: '',
code: ''
},
userInfo: Cache.get('USER_INFO') || {},
mpGiftImg: HTTP_REQUEST_URL + '/statics/images/gift_share.jpg',
recommendTitle: ""
};
},
computed: {
...mapGetters(['isLogin', 'cartNum']),
showGift() {
if (!this.couponList.length && !this.giftList.length && this.prize_integral == 0 && this.prize_exp == 0) {
return false;
} else {
return true;
}
}
},
watch: {
isLogin: {
handler: function (newV, oldV) {
if (newV) {
//#ifndef MP
this.getOrderPayInfo();
//#endif
}
},
deep: true
}
},
onLoad: function (options) {
this.options = options;
if (!options.order_id)
return this.$util.Tips(
{
title: '缺少参数无法查看订单支付状态'
},
{
tab: 3,
url: 1
}
);
this.orderId = options.order_id;
this.status = options.status || 0;
this.msg = options.msg || '';
this.type = this.options.type;
this.totalPrice = this.options.totalPrice;
this.getLotteryData(this.type);
this.getHostProduct();
},
onShow() {
uni.setStorageSync('form_type_cart', 1);
if (this.isLogin) {
this.getOrderPayInfo();
} else {
toLogin();
}
},
/**
* 用户点击右上角分享
*/
// #ifdef MP
onShareAppMessage: function () {
let that = this;
userShare();
return {
title: that.giftData.message || '',
imageUrl: that.mpGiftImg || '',
path: '/pages/goods/receive_gift/index?id=' + this.giftData.id + '&spid=' + this.$store.state.app.uid
};
},
onShareTimeline() {
let that = this;
userShare();
return {
title: that.giftData.message,
query: {
id: that.id,
spid: that.uid || 0
},
imageUrl: that.mpGiftImg
};
},
// #endif
methods: {
// #ifdef H5
setOpenShare() {
let that = this;
if (that.$wechat.isWeixin()) {
let configAppMessage = {
desc: this.giftData.message,
title: this.giftData.title,
link: window.location.protocol + '//' + window.location.host + '/pages/goods/receive_gift/index?id=' + this.giftData.id + '&spid=' + that.$store.state.app.uid,
imgUrl: that.mpGiftImg
};
that.$wechat
.wechatEvevt(['updateAppMessageShareData', 'updateTimelineShareData', 'onMenuShareAppMessage', 'onMenuShareTimeline'], configAppMessage)
.then((res) => {})
.catch((res) => {
if (res.is_ready) {
res.wx.updateAppMessageShareData(configAppMessage);
res.wx.updateTimelineShareData(configAppMessage);
res.wx.onMenuShareAppMessage(configAppMessage);
res.wx.onMenuShareTimeline(configAppMessage);
}
});
}
},
// #endif
moveHandle() {
return false;
},
// 授权关闭
authColse: function (e) {
this.isShowAuth = e;
},
openTap() {
this.$set(this, 'couponsHidden', !this.couponsHidden);
},
onLoadFun: function () {
this.getOrderPayInfo();
this.isShowAuth = false;
},
/**
*
* 支付完成查询支付状态
*
*/
getOrderPayInfo: function () {
let that = this;
uni.showLoading({
title: '正在加载中'
});
getOrderDetail(that.orderId)
.then((res) => {
uni.hideLoading();
that.$set(that, 'order_pay_info', res.data);
uni.setNavigationBarTitle({
title: res.data.paid ? '支付成功' : '未支付'
});
uni.$emit('newCartNum', res.data.cartInfo);
if (parseInt(uni.getStorageSync('news')) === 0) {
let colNum = this.cartNum - res.data.total_num;
this.$store.commit('indexData/setCartNum', colNum + '');
uni.removeStorageSync('news');
}
this.giftData = {
image: res.data.cartInfo[0].productInfo.image,
title: res.data.cartInfo[0].productInfo.store_name,
message: res.data.send_gift_mark,
id: res.data.id,
avatar: res.data.avatar,
nickname: res.data.nickname,
code: res.data.send_gift_code
};
// #ifdef H5
if (this.order_pay_info.is_send_gift) this.setOpenShare();
// #endif
if(!this.order_pay_info.is_send_gift){
uni.hideShareMenu()
}
this.loading = true;
setTimeout(function () {
that.getOrderPrize();
}, 1000);
})
.catch((err) => {
this.loading = true;
uni.hideLoading();
});
},
getOrderPrize() {
getOrderPrizeApi(this.orderId).then((res) => {
this.couponList = res.data.coupons;
this.giftList = res.data.gift;
this.prize_integral = res.data.integral;
this.prize_exp = res.data.exp;
});
},
/**
* 去首页关闭当前所有页面
*/
goIndex: function (e) {
let identity = this.$store.state.app.identity;
let styleType = this.$store.state.app.system_channel_style;
if(identity == 1){
uni.redirectTo({
url: this.styleType == 1 ? "/pages/merchant/index/index" : "/pages/merchant/index/goods"
})
}else{
uni.switchTab({
url: '/pages/index/index'
});
}
},
/**
*
* 去订单详情页面
*/
goOrderDetails: function (e) {
let that = this;
// #ifdef MP
uni.showLoading({
title: '正在加载'
});
openOrderSubscribe()
.then((res) => {
uni.hideLoading();
uni.navigateTo({
url: '/pages/goods/order_details/index?order_id=' + that.orderId
});
})
.catch(() => {
uni.hideLoading();
});
// #endif
// #ifndef MP
uni.navigateTo({
url: '/pages/goods/order_details/index?order_id=' + that.orderId
});
// #endif
},
getLotteryData(type) {
getLotteryData(type)
.then((res) => {
this.factor_num = res.data.lottery.factor_num;
this.id = res.data.lottery.id;
this.prize = res.data.lottery.prize;
if (this.prize.length) {
this.prize.push({ name: 1 });
}
this.lottery_num = res.data.lottery_num;
this.lotteryLoading = true;
this.datatime = parseInt(res.data.cache_time);
if (res.data.lottery.type == 6) {
uni.navigateTo({
url: '/pages/goods/lottery/grids/record'
});
}
})
.catch((err) => {
this.lotteryLoading = false;
});
},
getWiningIndex(callback) {
this.aleartType = 0;
startLottery({
id: this.id
})
.then((res) => {
this.prize.forEach((item, index) => {
if (res.data.id === item.id) {
this.alData = res.data;
this.lottery_draw_param.winingIndex = index;
callback(this.lottery_draw_param);
}
});
})
.catch((err) => {
this.$util.Tips({
title: err
});
});
},
// 抽奖完成
luck_draw_finish(param) {
this.aleartType = 2;
this.aleartStatus = true;
},
closeLottery(status) {
this.aleartStatus = false;
if (this.alData.type === 6) {
postCartAdd({
cartNum: 1,
new: 1,
is_new: 1,
productId: this.alData.product_id,
uniqueId: this.alData.unique,
luckRecordId: this.alData.lottery_record_id
})
.then((res) => {
uni.navigateTo({
url: `/pages/goods/order_confirm/index?new=1&luckRecordId=${this.alData.lottery_record_id}&cartId=${res.data.cartId}`
});
})
.catch((err) => {
this.$util.Tips({
title: `${err},请联系客服`
});
});
}
this.getLotteryData(this.type);
},
getHostProduct: function () {
let that = this;
if (that.hotScroll) return;
getProductHot({
page:that.hotPage,
limit:that.hotLimit,
type:2
}).then((res) => {
that.hotPage++;
that.hotScroll = res.data.list.length < that.hotLimit;
that.hostProduct = that.hostProduct.concat(res.data.list);
that.recommendTitle = res.data.title ? res.data.title : '猜你喜欢';
});
},
goPage(type, url) {
if (type == 1) {
uni.navigateTo({
url
});
} else if (type == 2) {
uni.switchTab({
url
});
} else if (type == 3) {
uni.navigateBack();
}
}
},
onPageScroll(e) {
uni.$emit('scroll');
},
onReachBottom() {
this.getHostProduct();
}
};
</script>
<style scoped>
.white-border {
border: 1rpx solid #fff;
}
.h-484 {
height: 484rpx;
}
.content {
background: #f5f5f5;
border-radius: 40rpx 40rpx 0 0;
left: 0;
top: -164rpx;
min-height: 500rpx;
}
.card ~ .card {
margin-top: 20rpx;
}
.cell ~ .cell {
border-top: 1px solid #eee;
}
.card_btn {
width: 114rpx;
height: 52rpx;
border-radius: 26rpx;
border: 1px solid #e93323;
}
.z-8000 {
z-index: 8000;
}
.z-1000 {
z-index: 1000;
}
.canvas {
width: 750rpx;
height: 1108rpx;
z-index: 9999;
position: absolute;
bottom: 40000rpx;
right: 30000rpx;
}
</style>

View File

@@ -0,0 +1,482 @@
<template>
<view :style="colorStyle">
<form @submit="subRefund">
<view class='apply-return'>
<view class="goodsList">
<view class='goodsStyle acea-row row-between' v-for="(item,index) in orderInfo.cart_info" :key="index">
<view class='pictrue'>
<image class="w-136 h-136 rd-16rpx" :src="item.productInfo.image"></image>
</view>
<view class='text'>
<view class="textCon acea-row row-between">
<view class='w-346 fs-28 h-80 lh-40rpx line2'>{{item.productInfo.store_name}}</view>
<view class='money'>
<baseMoney :money="item.truePrice" color='#333333' symbolSize="20" integerSize="32"
decimalSize="24" weight></baseMoney>
<view class='num'>共{{item.cart_num}}件</view>
</view>
</view>
<view class="info line1">{{item.productInfo.attrInfo?item.productInfo.attrInfo.suk:item.productInfo.suk}}</view>
</view>
</view>
</view>
<view class="list">
<view class="title acea-row row-between-wrapper">
<view>{{orderInfo.apply_type == 2?'快递退回信息':'到店退货信息'}}</view>
<view class="location" v-if="orderInfo.apply_type == 3" @click="showMaoLocation">查看位置<text class="iconfont icon-ic_rightarrow"></text></view>
</view>
<view class="textInfo">
<view class="acea-row row-middle">
<text class="name">{{orderInfo._status.refund_name}}</text>
<text class="phone">{{orderInfo._status.refund_phone}}</text>
<text class="iconfont icon-ic_phone font-num" @click="goTel"></text>
</view>
<view class="address">地址:{{orderInfo._status.refund_address}}</view>
</view>
</view>
<view class='list' v-if="orderInfo.apply_type == 2">
<view class='item acea-row row-between-wrapper' v-if="expressList.length">
<view>物流公司</view>
<picker class='num' @change="bindPickerChange" :value="seIndex" :range="expressList" range-key="name">
<view class="picker acea-row row-between-wrapper">
<view class='reason'>{{expressList[seIndex].name}}</view>
<text class='iconfont icon-ic_rightarrow'></text>
</view>
</picker>
</view>
<view class='item acea-row row-between-wrapper'>
<view>物流单号</view>
<input class="inputs" type="text" placeholder="请输入退货的物流单号" placeholder-class='placeholder' v-model="refundInfo.refund_express" />
</view>
<!-- <view class='item acea-row row-between-wrapper'>
<view>联系电话</view>
<input class="inputs" type="number" placeholder="请填写您的联系电话" placeholder-class='placeholder' v-model="refundInfo.refund_phone" />
</view> -->
</view>
<view class="list">
<view class='item textarea'>
<view class="acea-row row-between-wrapper">
<view>退货说明</view>
<view class="fontNum">{{fontNum}}/100</view>
</view>
<textarea placeholder='选填,请您详细填写备注说明' v-model="refundInfo.refund_explain" placeholder-class="placeholder" maxlength=100 @input="sumfontnum"></textarea>
</view>
<view class='item acea-row row-between'>
<!-- <view class='title acea-row row-between-wrapper'>
<view>上传凭证</view>
<view class='tip'>( 最多可上传3张 )</view>
</view> -->
<view class='upload acea-row row-middle'>
<view class='pictrue' v-for="(item,index) in refund_reason_wap_img" :key="index">
<image :src='item' mode="aspectFill"></image>
<view class='iconfont icon-ic_close' @tap='DelPic(index)'></view>
</view>
<view class='pictrue acea-row row-center-wrapper row-column' @tap='uploadpic'
v-if="refund_reason_wap_img.length < 3">
<image class="img" src="../static/ic_camera.png"></image>
<view>上传凭证</view>
</view>
</view>
</view>
</view>
<view style="height: 140rpx;"></view>
<view class="bntCon acea-row row-center-wrapper">
<button class='returnBnt bg-color' form-type="submit">提交</button>
</view>
</view>
</form>
<home></home>
</view>
</template>
<script>
import { getRefundOrderDetail, refundExpress } from '@/api/order.js';
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from "vuex";
import colors from '@/mixins/color.js';
export default {
mixins: [colors],
data() {
return {
expressList:[],
orderInfo:{},
seIndex: 0,
refund_reason_wap_img: [],
refundInfo:{
refund_express:'',
refund_explain:'',
id:'',
refund_express_name:'',
refund_img:''
},
isShowAuth: false,
fontNum:0,
};
},
computed: mapGetters(['isLogin']),
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV) {
this.getOrderInfo();
}
},
deep: true
}
},
onLoad(options) {
this.orderId = options.orderId;
if (this.isLogin) {
this.getOrderInfo();
} else {
toLogin()
}
},
onShow() {
uni.removeStorageSync('form_type_cart');
},
onPageScroll(object) {
uni.$emit('scroll');
},
methods: {
onLoadFun(){
this.getOrderInfo();
this.isShowAuth = false;
},
// 授权关闭
authColse: function(e) {
this.isShowAuth = e
},
// 限制文本框字数
sumfontnum(e) {
this.fontNum = e.detail.value.length
},
/**
* 打电话
*/
goTel: function() {
uni.makePhoneCall({
phoneNumber: this.orderInfo._status.refund_phone
})
},
/**
* 打开地图
*
*/
showMaoLocation: function() {
let latitude = this.orderInfo._status.latitude;
let longitude = this.orderInfo._status.longitude;
if (!latitude || !longitude) return this.$util.Tips({
title: '缺少经纬度信息无法查看地图!'
});
uni.openLocation({
latitude: parseFloat(latitude),
longitude: parseFloat(longitude),
scale: 8,
name: this.orderInfo._status.refund_name,
address: this.orderInfo._status.refund_address,
success: function() {
},
});
},
/**
* 申请退货
*/
subRefund: function(e) {
let that = this
if (!that.refundInfo.refund_express && that.orderInfo.apply_type == 2) return this.$util.Tips({
title: '请输入快递单号'
});
// if (!that.refundInfo.refund_phone) return this.$util.Tips({
// title: '请输入手机号'
// });
// if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(that.refundInfo.refund_phone)) return this.$util.Tips({
// title: '请输入正确的手机号码'
// });
that.refundInfo.refund_express_name = that.expressList[that.seIndex].name;
that.refundInfo.refund_img = that.refund_reason_wap_img.join(',');
refundExpress(that.refundInfo).then(res => {
return this.$util.Tips({
title: res.msg,
icon: 'success'
}, {
tab: 5,
url: '/pages/users/user_return_list/index?isT=1'
});
}).catch(err => {
return this.$util.Tips({
title: err
});
})
},
/**
* 删除图片
*
*/
DelPic: function(e) {
let index = e,
that = this,
pic = this.refund_reason_wap_img[index];
that.refund_reason_wap_img.splice(index, 1);
that.$set(that, 'refund_reason_wap_img', that.refund_reason_wap_img);
},
/**
* 上传文件
*
*/
uploadpic: function() {
let that = this;
this.$util.uploadImageOne('upload/image', function(res) {
that.refund_reason_wap_img.push(res.data.url);
that.$set(that, 'refund_reason_wap_img', that.refund_reason_wap_img);
});
},
/**
* 获取订单详情
*
*/
getOrderInfo: function() {
let that = this;
getRefundOrderDetail(that.orderId).then(res => {
that.$set(that, 'orderInfo', res.data);
that.expressList = res.data.express_list;
that.refundInfo.id = res.data.id;
});
},
bindPickerChange(e) {
this.$set(this, 'seIndex', e.detail.value);
}
}
}
</script>
<style scoped lang="scss">
.apply-return .list {
background-color: #fff;
width: 710rpx;
border-radius: 24rpx;
margin: 20rpx auto 0 auto;
padding: 32rpx 24rpx;
.title{
width: 100%;
font-weight: 500;
color: #333333;
font-size: 28rpx;
.location{
font-weight: 400;
.iconfont{
font-size: 24rpx;
margin-left: 6rpx;
}
}
}
.textInfo{
font-weight: 400;
color: #333333;
font-size: 28rpx;
margin-top: 32rpx;
.iconfont{
font-size: 26rpx;
margin-left: 10rpx;
}
.phone{
margin-left: 18rpx;
}
.address{
color: #999999;
font-size: 24rpx;
margin-top: 8rpx;
}
}
}
.apply-return .list .item {
font-size: 28rpx;
color: #333;
font-weight: 400;
&~.item{
margin-top: 32rpx;
}
.fontNum{
font-size: 24rpx;
color: #999;
}
.placeholder{
font-size: 26rpx;
color: #CCCCCC;
}
}
.apply-return .list .item .inputs{
text-align: right;
font-size: 28rpx;
}
.apply-return .list .item .num {
color: #282828;
width: 427rpx;
text-align: right;
}
.apply-return .list .item .num .picker .reason {
width: 398rpx;
}
.apply-return .list .item .num .picker .iconfont {
color: #333;
font-size: 24rpx;
margin-top: 1rpx;
}
.apply-return .list .item textarea {
height: 166rpx;
font-size: 26rpx;
margin-top: 24rpx;
}
.apply-return .list .item .placeholder {
color: #bbb;
}
.apply-return .list .item .title {
height: 95rpx;
width: 100%;
}
.apply-return .list .item .title .tip {
font-size: 30rpx;
color: #bbb;
}
.apply-return .list .item .upload .pictrue {
margin: 22rpx 23rpx 0 0;
width: 156rpx;
height: 156rpx;
position: relative;
font-size: 24rpx;
color: #bbb;
border-radius: 16rpx;
.img{
width: 48rpx;
height: 48rpx;
margin-bottom: 8rpx;
}
}
.apply-return .list .item .upload .pictrue:nth-of-type(4n) {
margin-right: 0;
}
.apply-return .list .item .upload .pictrue image {
width: 100%;
height: 100%;
border-radius: 3rpx;
}
.apply-return .list .item .upload .pictrue .icon-ic_close {
position: absolute;
font-size: 24rpx;
top: 0;
right: 0;
width: 32rpx;
height: 32rpx;
background: #999999;
border-radius: 0 16rpx 0 16rpx;
text-align: center;
line-height: 32rpx;
color: #fff;
}
.apply-return .list .item .upload .pictrue .icon-icon25201 {
color: #bfbfbf;
font-size: 50rpx;
}
.apply-return .list .item .upload .pictrue:nth-last-child(1) {
width: 148rpx;
height: 148rpx;
background: #F5F5F5;
font-size: 24rpx;
color: #333;
}
.apply-return .bntCon{
width: 100%;
height: 120rpx;
background: #FFFFFF;
position: fixed;
left:0;
bottom: 0;
bottom: calc(0rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
bottom: calc(0rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
}
.apply-return .returnBnt {
font-size: 28rpx;
color: #fff;
width: 710rpx;
height: 80rpx;
border-radius: 50rpx;
text-align: center;
line-height: 80rpx;
}
.goodsList{
width: 710rpx;
padding: 32rpx 24rpx;
border-radius: 24rpx;
background-color: #fff;
margin: 20rpx auto 0 auto;
}
.goodsStyle{
margin: 0;
padding: 0;
&~.goodsStyle{
margin-top: 32rpx;
}
.pictrue{
width: 136rpx;
height: 136rpx;
border-radius: 16rpx;
image{
border-radius: 16rpx;
}
}
.text{
color: #333;
width: 506rpx;
font-weight: 400;
.textCon{
height: 100rpx;
}
.info{
color: #999999;
font-size: 24rpx;
width: 360rpx;
}
.money{
.num{
font-size: 24rpx;
color: #999;
margin-top: 8rpx;
}
}
}
}
.goodsStyle .text .name {
align-self: flex-start;
}
.list /deep/ .uni-input-input {
text-align: right;
}
</style>

View File

@@ -0,0 +1,287 @@
<template>
<view class="warpper">
<image class="top-bg" src="../static/receive-gift-bag.png" mode=""></image>
<image class="top-bow" src="../static/bow.png" mode=""></image>
<view class="aleart">
<view class="from">{{ nickname }} 送给您的一份礼物</view>
<view class="message">{{ gift_mark }}</view>
<view class="aleart-body">
<view class="goods-img">
<image class="img" :src="image" mode=""></image>
<view class="expire" v-if="refund_status != 0 || giftStatus == 4">
<image src="../static/expire.png" mode=""></image>
</view>
</view>
</view>
<view class="title line1">
{{ store_name }}
</view>
<view v-if="cartInfo.length > 1" class="more text--w111-999" @click="showDrawer = true">
全部{{ cartInfo.length }}件
<text class="iconfont icon-ic_downarrow"></text>
</view>
</view>
<view v-if="(giftStatus == 1 || giftStatus == 2) && refund_status == 0" class="btn" @click="goGetGift()">
{{ giftStatusText }}
</view>
<view v-else-if="giftStatus == 3 && refund_status == 0" class="btn-n">礼物已被领取</view>
<!-- <view v-else-if="refund_status != 0 || giftStatus == 4" class="btn-n">礼物已失效</view> -->
<text v-if="(giftStatus == 1 || giftStatus == 2) && refund_status == 0" class="text--w111-999 mt-32 fs-28">礼物超过24小时未领取将失效</text>
<text v-if="refund_status != 0 || giftStatus == 4" class="text--w111-999 mt-32 fs-28">礼物超过24小时未领取已失效</text>
<base-drawer
mode="bottom"
:visible="showDrawer"
background-color="transparent"
mask
maskClosable
@close="
() => {
showDrawer = false;
}
"
>
<view class="w-full bg--w111-fff rd-t-40rpx py-32">
<view class="text-center fs-32 text--w111-333 fw-500">礼品清单</view>
<view class="mt-64 px-32">
<view class="mb-38" v-for="(item, index) in cartInfo" :key="index">
<view class="flex-y-center">
<image class="w-160 h-160 mr-30 rd-16rpx" :src="item.productInfo.image"></image>
<view class="flex-1 flex-col justify-between h-160">
<text class="text--w111-333 fs-28 fw-400 line2">{{ item.productInfo.store_name }}</text>
<view class="flex flex-between-center">
<view class="mt-6 fs-22 text--w111-999">
{{ item.productInfo.attrInfo.suk }}
</view>
<view class="mt-6 pl-40 fs-22 text--w111-999">
x
<text class="fs-26">{{ item.cart_num }}</text>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="mx-20 pb-safe">
<view class="mt-52 h-72 flex-center rd-36px bg-red fs-26 text--w111-fff" @tap="showDrawer = false">确定</view>
</view>
</view>
</base-drawer>
</view>
</template>
<script>
import { getSendGiftOrderDetail } from '@/api/order.js';
import { toLogin } from '@/libs/login.js';
import { mapGetters } from 'vuex';
let app = getApp();
export default {
computed: mapGetters(['isLogin']),
data() {
return {
order_id: '',
giftStatus: 0,
refund_status: 0,
gift_mark: '',
image: '',
store_name: '',
nickname: '',
giftStatusText: '',
o_id: 0,
showDrawer: false,
cartInfo: []
};
},
props: {},
watch: {
isLogin: {
handler: function (newV, oldV) {
if (newV) {
this.getOrderInfo();
}
},
deep: true
}
},
onLoad(options) {
if (this.isLogin) {
this.order_id = options.id;
// #ifdef MP
if (options.scene) {
let value = this.$util.getUrlParams(decodeURIComponent(options.scene));
if (value.order_id) options.id = value.id;
//记录推广人uid
if (value.pid) app.globalData.spid = value.pid;
}
// #endif
this.getOrderInfo();
} else {
toLogin();
}
},
methods: {
goGetGift() {
if (this.giftStatus == 2) {
uni.reLaunch({
url: `/pages/goods/order_details/index?order_id=${this.o_id}`
});
} else {
uni.reLaunch({
url: `/pages/goods/order_confirm/index?order_id=${this.order_id}&is_send_gift=2`
});
}
},
getOrderInfo() {
getSendGiftOrderDetail(this.order_id).then((res) => {
this.cartInfo = res.data.cartInfo;
this.gift_uid = res.data.receive_gift_uid;
this.gift_mark = res.data.send_gift_mark;
this.nickname = res.data.nickname;
this.refund_status = res.data.refund_status;
this.image = res.data.cartInfo[0].productInfo.image;
this.store_name = res.data.cartInfo[0].productInfo.store_name;
this.o_id = res.data.order_id;
if (!res.data.receive_gift_time_valid) {
this.giftStatus = 4;
this.giftStatusText = '礼物已失效';
return;
}
if (this.gift_uid === 0) {
this.giftStatus = 1;
this.giftStatusText = '收下礼物';
} else if (this.gift_uid === this.$store.state.app.uid) {
this.giftStatus = 2;
this.giftStatusText = '查看礼物';
} else if (this.gift_uid !== this.uid) {
this.giftStatus = 3;
}
});
}
}
};
</script>
<style lang="scss" scoped>
.warpper {
display: flex;
flex-direction: column;
align-items: center;
.top-bg {
width: 100%;
height: 206rpx;
}
.top-bow {
width: 342rpx;
height: 78rpx;
margin-top: -120rpx;
z-index: 9;
}
}
.more {
background-color: #f5f5f5;
border-radius: 8rpx;
font-size: 26rpx;
color: #999999;
display: flex;
align-items: center;
justify-content: center;
padding: 8rpx 24rpx;
margin-bottom: 44rpx;
.iconfont {
font-size: 26rpx;
margin-left: 4rpx;
}
}
.aleart {
width: 670rpx;
z-index: 7;
margin-top: -20rpx;
background-color: #fff;
padding-top: 100rpx;
border-radius: 24rpx;
background-size: 100% 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.from {
font-size: 28rpx;
font-weight: 500;
color: #333333;
margin-bottom: 16rpx;
}
.message {
font-weight: 400;
font-size: 26rpx;
color: #999999;
margin-bottom: 42rpx;
}
.aleart-body {
display: flex;
align-items: center;
justify-content: center;
width: 396rpx;
height: 419rpx;
background-image: url('/pages/goods/static/gift-border.png');
background-size: 100% 100%;
margin-bottom: 40rpx;
.goods-img {
width: 360rpx;
height: 360rpx;
margin-top: 24rpx;
position: relative;
.img {
width: 100%;
height: 100%;
}
.expire {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.6);
display: flex;
align-items: center;
justify-content: center;
image {
width: 236rpx;
height: 236rpx;
margin: auto;
}
}
}
}
.title {
width: 396rpx;
font-weight: 400;
font-size: 28rpx;
color: #333333;
margin-bottom: 34rpx;
text-align: center;
}
}
.btn,
.btn-clear,
.btn-n {
width: 670rpx;
height: 84rpx;
line-height: 84rpx;
border-radius: 20px;
text-align: center;
margin-top: 56rpx;
}
.btn {
color: #fff;
background: linear-gradient(90deg, #ff7931 0%, #e93323 100%);
}
.btn-clear {
color: #e93323;
border: 1px solid #e93323;
}
.btn-n {
color: #fff;
background: #cccccc;
}
</style>

View File

@@ -0,0 +1,124 @@
<template>
<view class="warpper">
<view class="aleart">
<view class="aleart-body">
<image v-if="!status" class="goods-img" src="../static/receive_gifts_error.png" mode=""></image>
<image v-else class="goods-img" src="../static/receive_gifts_success.png" mode=""></image>
</view>
<view class="title">
{{ status ? '礼物领取成功' : '领取失败,礼物已失效' }}
</view>
<view v-if="status" class="btn" @click="goPage(0)">
查看礼物详情
</view>
<view v-if="status" class="btn-clear" @click="goPage(1)">
返回商城首页
</view>
<view v-if="!status" class="btn" @click="goPage(1)">
返回商城首页
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
status: 0,
orderId: 0
};
},
onLoad(options) {
this.status = options.status;
this.orderId = options.order_id;
},
methods: {
goPage(type) {
if (type) {
uni.reLaunch({
url: '/pages/index/index'
});
} else {
uni.reLaunch({
url: `/pages/goods/order_details/index?order_id=${this.orderId}`
});
}
}
}
};
</script>
<style lang="scss" scoped>
.warpper {
display: flex;
flex-direction: column;
align-items: center;
}
.aleart {
width: 670rpx;
z-index: 7;
background-color: #fff;
padding: 74rpx 30rpx 50rpx;
border-radius: 12rpx;
background-size: 100% 100%;
margin-top: 24rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.from {
font-size: 28rpx;
font-weight: 500;
color: #333333;
margin-bottom: 16rpx;
}
.message {
font-weight: 400;
font-size: 26rpx;
color: #999999;
margin-bottom: 42rpx;
}
.aleart-body {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 32rpx;
padding: 0 30rpx;
.goods-img {
width: 206rpx;
height: 152rpx;
margin-top: 24rpx;
}
}
.title {
font-weight: 500;
font-size: 32rpx;
color: #282828;
margin-bottom: 48rpx;
}
}
.btn,
.btn-clear,
.btn-n {
width: 100%;
height: 84rpx;
line-height: 84rpx;
border-radius: 20px;
text-align: center;
margin-bottom: 30rpx;
}
.btn {
color: #fff;
background: #e93323;
}
.btn-clear {
color: #e93323;
border: 1px solid #e93323;
}
.btn-n {
color: #fff;
background: #cccccc;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 B

BIN
pages/goods/static/bow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 615 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 723 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 916 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB