first commit
This commit is contained in:
@@ -0,0 +1,335 @@
|
||||
<template>
|
||||
<!-- pages/address_edit/address_edit.wxml -->
|
||||
<view class="address-edit">
|
||||
<form @submit="formSubmit" report-submit="true">
|
||||
<view class="form bg-white">
|
||||
<view class="form-item row">
|
||||
<view class="label">收货人</view>
|
||||
<input
|
||||
class="ml10"
|
||||
v-model="addressObj.contact"
|
||||
name="contact"
|
||||
type="text"
|
||||
placeholder="请填写收货人姓名"
|
||||
/>
|
||||
</view>
|
||||
<view class="form-item row">
|
||||
<view class="label">联系方式</view>
|
||||
<input
|
||||
class="ml10"
|
||||
name="telephone"
|
||||
v-model="addressObj.telephone"
|
||||
type="number"
|
||||
placeholder="请填写手机号码"
|
||||
/>
|
||||
</view>
|
||||
<view @click="showRegion = true">
|
||||
<view class="form-item row">
|
||||
<view class="label">所在地区</view>
|
||||
<input
|
||||
class="ml10"
|
||||
name="region"
|
||||
v-model="region"
|
||||
disabled
|
||||
type="text"
|
||||
placeholder="请选择省、市、区"
|
||||
/>
|
||||
<image class="icon-sm ml10" src="/static/images/arrow_right.png" />
|
||||
</view>
|
||||
</view>
|
||||
<view>
|
||||
<u-field
|
||||
v-model="addressObj.address"
|
||||
type="textarea"
|
||||
label="详细地址"
|
||||
placeholder="请填写小区、街道、门牌号等信息"
|
||||
:field-style="{ flex: 1, 'margin-left': '20rpx', height: '160rpx' }"
|
||||
/>
|
||||
<!-- <view class="form-item row" style="height: 200rpx;"> -->
|
||||
<!-- <view class="label mt20" style="align-self: flex-start;">详细地址</view> -->
|
||||
<!-- <textarea name="address" style="height: 160rpx;padding: 20rpx 20rpx 20rpx 30rpx;" v-model="addressObj.address" @input="textareaChange" placeholder="请填写小区、街道、门牌号等信息" auto-blur /> -->
|
||||
<!-- </view> -->
|
||||
</view>
|
||||
</view>
|
||||
<view class="mt10 mb10 bg-white check-wrap">
|
||||
<radio-group class="row" @click="ChangeIsDefault">
|
||||
<radio
|
||||
id="checkbox"
|
||||
style="border-radius: 50%; transform: scale(0.7)"
|
||||
:checked="addressObj.is_default ? true : false"
|
||||
color="#FF2C3C"
|
||||
/>
|
||||
<label for="checkbox">
|
||||
<text>设置为默认</text>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
<button class="my-btn bg-primary white br60" form-type="submit">完成</button>
|
||||
</form>
|
||||
<u-select
|
||||
v-model="showRegion"
|
||||
mode="mutil-column-auto"
|
||||
@confirm="regionChange"
|
||||
:list="lists"
|
||||
></u-select>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop开源商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
|
||||
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | likeshop团队版权所有并拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshop.cn.team
|
||||
// +----------------------------------------------------------------------
|
||||
import { editAddress, getOneAddress, hasRegionCode, addAddress } from '@/api/user'
|
||||
import area from '@/utils/area'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
addressObj: {
|
||||
contact: '',
|
||||
telephone: '',
|
||||
province: '',
|
||||
city: '',
|
||||
district: '',
|
||||
address: '',
|
||||
is_default: 0
|
||||
},
|
||||
region: '',
|
||||
addressId: '',
|
||||
defaultRegion: ['广东省', '广州市', '番禺区'],
|
||||
defaultRegionCode: '440113',
|
||||
showRegion: false,
|
||||
lists: []
|
||||
}
|
||||
},
|
||||
props: {},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
this.addressId = parseInt(options.id)
|
||||
if (options.id) {
|
||||
uni.setNavigationBarTitle({
|
||||
title: '编辑地址'
|
||||
})
|
||||
this.getOneAddressFun()
|
||||
} else {
|
||||
uni.setNavigationBarTitle({
|
||||
title: '添加地址'
|
||||
})
|
||||
this.getWxAddressFun()
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.lists = area
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload: function () {
|
||||
uni.removeStorageSync('wxAddress')
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户点击右上角分享
|
||||
*/
|
||||
// onShareAppMessage: function () {},
|
||||
methods: {
|
||||
formSubmit(e) {
|
||||
let { value } = e.detail
|
||||
let {
|
||||
addressObj: { province_id, city_id, district_id, is_default, address },
|
||||
addressId
|
||||
} = this
|
||||
value.address = address
|
||||
if (!value.contact)
|
||||
return this.$toast({
|
||||
title: '请填写收货人姓名'
|
||||
})
|
||||
if (!value.telephone)
|
||||
return this.$toast({
|
||||
title: '请填写手机号码'
|
||||
})
|
||||
if (!value.region)
|
||||
return this.$toast({
|
||||
title: '请选择省、市、区'
|
||||
})
|
||||
if (!value.address)
|
||||
return this.$toast({
|
||||
title: '请填写小区、街道、门牌号等信息'
|
||||
})
|
||||
value.province_id = parseInt(province_id)
|
||||
value.city_id = parseInt(city_id)
|
||||
value.district_id = parseInt(district_id)
|
||||
value.is_default = is_default
|
||||
value.id = addressId
|
||||
delete value.region
|
||||
|
||||
if (addressId) {
|
||||
editAddress(value)
|
||||
.then((res) => {
|
||||
if (res.code == 1) {
|
||||
this.$toast(
|
||||
{
|
||||
title: res.msg
|
||||
},
|
||||
{
|
||||
tab: 3,
|
||||
url: 1
|
||||
}
|
||||
)
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
return this.$toast({
|
||||
title: err
|
||||
})
|
||||
})
|
||||
} else {
|
||||
addAddress(value)
|
||||
.then((res) => {
|
||||
if (res.code == 1) {
|
||||
this.$toast(
|
||||
{
|
||||
title: res.msg
|
||||
},
|
||||
{
|
||||
tab: 3,
|
||||
url: 1
|
||||
}
|
||||
)
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
return this.$toast({
|
||||
title: err
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
regionChange(region) {
|
||||
this.addressObj.province_id = region[0].value
|
||||
this.addressObj.city_id = region[1].value
|
||||
this.addressObj.district_id = region[2].value
|
||||
this.region = region[0].label + ' ' + region[1].label + ' ' + region[2].label
|
||||
},
|
||||
|
||||
ChangeIsDefault: function (e) {
|
||||
if (this.addressObj.is_default == 0) {
|
||||
this.addressObj.is_default = 1
|
||||
} else {
|
||||
this.addressObj.is_default = 0
|
||||
}
|
||||
},
|
||||
|
||||
textareaChange: function (e) {
|
||||
this.addressObj.address = e.detail.value
|
||||
},
|
||||
|
||||
getOneAddressFun() {
|
||||
getOneAddress(this.addressId).then((res) => {
|
||||
if (res.code == 1) {
|
||||
let { city, province, district } = res.data
|
||||
this.addressObj = res.data
|
||||
this.region = `${province} ${city} ${district}`
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getWxAddressFun() {
|
||||
let wxAddress = uni.getStorageSync('wxAddress')
|
||||
if (!wxAddress) return
|
||||
wxAddress = JSON.parse(wxAddress)
|
||||
let {
|
||||
userName: contact,
|
||||
telNumber: telephone,
|
||||
provinceName: province,
|
||||
cityName: city,
|
||||
detailInfo: address
|
||||
} = wxAddress
|
||||
let district = wxAddress.countryName || wxAddress.countyName
|
||||
hasRegionCode({
|
||||
province,
|
||||
city,
|
||||
district
|
||||
}).then((res) => {
|
||||
if (res.code == 1) {
|
||||
if (res.data.province && res.data.city && res.data.district) {
|
||||
this.addressObj.province_id = res.data.province
|
||||
this.addressObj.city_id = res.data.city
|
||||
this.addressObj.district_id = res.data.district
|
||||
this.region = `${province} ${city} ${district}`
|
||||
}
|
||||
this.addressObj.contact = contact
|
||||
this.addressObj.telephone = telephone
|
||||
this.addressObj.address = address
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
/* pages/address_edit/address_edit.wxss */
|
||||
|
||||
.address-edit {
|
||||
padding-top: 10rpx;
|
||||
.form {
|
||||
flex: 1;
|
||||
.form-item {
|
||||
padding: 0 24rpx;
|
||||
height: 80rpx;
|
||||
&:not(:nth-of-type(3)) {
|
||||
border-bottom: $-solid-border;
|
||||
}
|
||||
.label {
|
||||
width: 150rpx;
|
||||
}
|
||||
input {
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
.check-wrap {
|
||||
padding: 20rpx;
|
||||
}
|
||||
.my-btn {
|
||||
margin: 30rpx 26rpx;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
van-field view {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
van-field textarea {
|
||||
height: 100% !important;
|
||||
padding-top: 10rpx !important;
|
||||
}
|
||||
|
||||
.van-cell {
|
||||
padding: 20rpx !important;
|
||||
}
|
||||
|
||||
.van-field__body--textarea,
|
||||
.van-field__input {
|
||||
margin-left: 15rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,275 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="all_comments">
|
||||
<view class="header bg-white" v-if="!isEmpty">
|
||||
<view class="title xs">
|
||||
<text class="lighter mr10">商品好评率</text>
|
||||
<text class="primary">{{ percent }}</text>
|
||||
</view>
|
||||
<view class="tab row">
|
||||
<block v-for="(item, index) in categoryList" :key="index">
|
||||
<view
|
||||
:class="
|
||||
'tab-item xs mr10 br60 mb20 ' +
|
||||
(type == item.id ? 'bg-primary white' : 'common-bg')
|
||||
"
|
||||
:key="index"
|
||||
:data-id="item.id"
|
||||
@tap="onChangType"
|
||||
v-if="item.count"
|
||||
>
|
||||
{{ item.name }}({{ item.count }})
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
<view class="main bg-white">
|
||||
<view class="evaluation-list">
|
||||
<view v-for="(item, index) in commentList" :key="index" class="evaluation-item">
|
||||
<view class="user-info row">
|
||||
<image class="avatar mr20" :src="item.avatar"></image>
|
||||
<view class="user-name md mr10">{{ item.nickname }}</view>
|
||||
<u-rate
|
||||
disabled
|
||||
size="26rpx"
|
||||
color="#FF2C3C"
|
||||
v-model="item.goods_comment"
|
||||
></u-rate>
|
||||
</view>
|
||||
<view class="muted xs mt10">
|
||||
<text class="mr20">{{ item.create_time }}</text>
|
||||
<text v-show="item.spec_value_str">{{ item.spec_value_str }}</text>
|
||||
</view>
|
||||
<view v-if="item.comment" class="dec mt20">{{ item.comment }}</view>
|
||||
<view class="img mt20 row" style="flex-wrap: wrap" v-if="item.image.length">
|
||||
<view
|
||||
v-for="(imgitem, imgindex) in item.image"
|
||||
:key="imgindex"
|
||||
class="img-item mr10 mb20"
|
||||
:data-current="imgitem"
|
||||
:data-uri="item.image"
|
||||
@tap="previewImage"
|
||||
>
|
||||
<custom-image
|
||||
width="160rpx"
|
||||
fit="cover"
|
||||
height="160rpx"
|
||||
radius="6rpx"
|
||||
lazy-load
|
||||
class="goods-img"
|
||||
:src="imgitem"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="seller-recall-container common-bg mt10" v-if="item.reply">
|
||||
<view class="lighter nr" style="word-wrap: break-word">
|
||||
商家回复:<span class="normal two-txt-cut">{{ item.reply }}</span>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<loading-footer :status="status" slotEmpty>
|
||||
<view slot="empty" class="column-center" style="padding-top: 200rpx">
|
||||
<image class="img-null" src="/static/images/goods_null.png"></image>
|
||||
<text class="lighter">暂无评价</text>
|
||||
</view>
|
||||
</loading-footer>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop开源商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
|
||||
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | likeshop团队版权所有并拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshop.cn.team
|
||||
// +----------------------------------------------------------------------
|
||||
import { getCommentList, getCommentCategory } from '../../api/store'
|
||||
import { loadingType } from '../../utils/type'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
status: loadingType.LOADING,
|
||||
page: 1,
|
||||
type: '',
|
||||
commentList: [],
|
||||
categoryList: [],
|
||||
percent: '',
|
||||
isEmpty: true
|
||||
}
|
||||
},
|
||||
|
||||
components: {},
|
||||
props: {},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: async function (options) {
|
||||
this.id = options.id
|
||||
await this.getCommentCategoryFun()
|
||||
this.getCommentListFun()
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady: function () {},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow: function () {},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面隐藏
|
||||
*/
|
||||
onHide: function () {},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload: function () {},
|
||||
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh: function () {},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom: function () {
|
||||
this.getCommentListFun()
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户点击右上角分享
|
||||
*/
|
||||
// onShareAppMessage: function () {},
|
||||
methods: {
|
||||
onChangType(e) {
|
||||
let { id } = e.currentTarget.dataset
|
||||
let { type } = this
|
||||
if (id == type) return
|
||||
this.type = id
|
||||
this.page = 1
|
||||
this.commentList = []
|
||||
this.status = loadingType.LOADING
|
||||
this.$nextTick(() => this.getCommentListFun())
|
||||
},
|
||||
|
||||
getCommentCategoryFun() {
|
||||
return new Promise((resolve) => {
|
||||
getCommentCategory(this.id).then((res) => {
|
||||
let {
|
||||
code,
|
||||
data: { comment, percent }
|
||||
} = res
|
||||
if (code == 1) {
|
||||
this.categoryList = comment
|
||||
this.percent = percent
|
||||
this.type = comment[0].id
|
||||
this.$nextTick(() => resolve())
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
getCommentListFun() {
|
||||
let { page, status, commentList, type } = this
|
||||
if (status == loadingType.FINISHED) return
|
||||
getCommentList({
|
||||
id: type,
|
||||
goods_id: this.id,
|
||||
page_no: page
|
||||
}).then((res) => {
|
||||
if (res.code == 1) {
|
||||
let { list, more } = res.data
|
||||
commentList.push(...list)
|
||||
this.commentList = commentList
|
||||
this.page++
|
||||
this.$nextTick(() => {
|
||||
if (!more) {
|
||||
this.status = loadingType.FINISHED
|
||||
}
|
||||
|
||||
if (commentList.length <= 0) {
|
||||
this.status = loadingType.EMPTY
|
||||
} else {
|
||||
console.log('commentList false')
|
||||
this.isEmpty = false
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
previewImage(e) {
|
||||
const { current, uri } = e.currentTarget.dataset
|
||||
let urls = uri
|
||||
uni.previewImage({
|
||||
current,
|
||||
// 当前显示图片的http链接
|
||||
urls // 需要预览的图片http链接列表
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.all_comments {
|
||||
padding-top: 20rpx;
|
||||
.header {
|
||||
.title {
|
||||
padding: 24rpx 26rpx;
|
||||
border-bottom: var(--border);
|
||||
}
|
||||
.tab {
|
||||
padding: 30rpx 0 10rpx 20rpx;
|
||||
flex-wrap: wrap;
|
||||
.tab-item {
|
||||
padding: 9rpx 29rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.common-bg {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.main {
|
||||
.evaluation-list {
|
||||
.evaluation-item {
|
||||
padding: 20rpx;
|
||||
&:not(:last-of-type) {
|
||||
border-bottom: $-solid-border;
|
||||
}
|
||||
.avatar {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.seller-recall-container {
|
||||
padding: 24rpx 20rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,729 @@
|
||||
// +---------------------------------------------------------------------- // | likeshop开源商城系统
|
||||
// +---------------------------------------------------------------------- // |
|
||||
欢迎阅读学习系统程序代码,建议反馈是我们前进的动力 // | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github // | 访问官网:https://www.likeshop.cn // |
|
||||
访问社区:https://home.likeshop.cn // | 访问手册:http://doc.likeshop.cn // |
|
||||
微信公众号:likeshop技术社区 // |
|
||||
likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识 // |
|
||||
likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识 // |
|
||||
禁止对系统程序代码以任何目的,任何形式的再发布 // | likeshop团队版权所有并拥有最终解释权 //
|
||||
+---------------------------------------------------------------------- // | author:
|
||||
likeshop.cn.team // +----------------------------------------------------------------------
|
||||
|
||||
<template>
|
||||
<view>
|
||||
<view class="confirm-order">
|
||||
<view class="confirm-con">
|
||||
<!-- 收货方式 -->
|
||||
<view class="contain">
|
||||
<u-tabs
|
||||
:list="addressTabsList"
|
||||
:is-scroll="addressTabsList.length === 1"
|
||||
:current="addressTabsIndex"
|
||||
:active-color="primaryColor"
|
||||
bar-width="100"
|
||||
:bar-style="{ top: '100%' }"
|
||||
@change="changeDelivery"
|
||||
/>
|
||||
<!-- 快递配送 -->
|
||||
<view
|
||||
v-show="addressTabsList[addressTabsIndex]['sign'] === 'express'"
|
||||
class="receiving-card"
|
||||
@click="onAddressExpress"
|
||||
>
|
||||
<u-image
|
||||
class="icon-md mr20"
|
||||
width="44"
|
||||
height="44"
|
||||
src="/static/images/icon_address.png"
|
||||
mode="scaleToFill"
|
||||
/>
|
||||
<view class="receiving-content">
|
||||
<template v-if="address.id">
|
||||
<view class="md black bold">
|
||||
<text>{{ address.contact }}</text>
|
||||
<text class="ml10">{{ address.telephone }}</text>
|
||||
</view>
|
||||
<view class="xs black mt10">{{
|
||||
address.province +
|
||||
address.city +
|
||||
address.district +
|
||||
address.address
|
||||
}}</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view>请选择收货地址</view>
|
||||
</template>
|
||||
</view>
|
||||
<u-icon name="arrow-right" />
|
||||
</view>
|
||||
<!-- 门店自提 -->
|
||||
<view
|
||||
v-show="addressTabsList[addressTabsIndex]['sign'] === 'store'"
|
||||
class="receiving-card"
|
||||
@click="onAddressStore"
|
||||
>
|
||||
<u-image
|
||||
class="icon-md mr20"
|
||||
width="44"
|
||||
height="44"
|
||||
src="/static/images/icon_address.png"
|
||||
mode="scaleToFill"
|
||||
/>
|
||||
<view class="receiving-content">
|
||||
<template v-if="storeInfo.id">
|
||||
<text class="md black bold">{{ storeInfo.name }}</text>
|
||||
<text class="xs black mt10">{{ storeInfo.shop_address }}</text>
|
||||
<text class="xs muted mt10">
|
||||
<text>营业时间:</text>
|
||||
<text
|
||||
>{{ storeInfo.business_start_time }} -
|
||||
{{ storeInfo.business_end_time }}</text
|
||||
>
|
||||
</text>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view>请选择门店地址</view>
|
||||
</template>
|
||||
</view>
|
||||
<u-icon name="arrow-right" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 门店自提表单 -->
|
||||
<view
|
||||
v-show="addressTabsList[addressTabsIndex]['sign'] === 'store'"
|
||||
class="contain store-from"
|
||||
>
|
||||
<view class="store-from-item">
|
||||
<text>提货人</text>
|
||||
<u-input
|
||||
v-model="userConsignee"
|
||||
class="flex1"
|
||||
type="text"
|
||||
input-align="right"
|
||||
:clearable="false"
|
||||
placeholder="请输入提货人"
|
||||
/>
|
||||
</view>
|
||||
<view class="store-from-item">
|
||||
<text>联系方式</text>
|
||||
<u-input
|
||||
v-model="userMobile"
|
||||
class="flex1"
|
||||
type="text"
|
||||
input-align="right"
|
||||
:clearable="false"
|
||||
placeholder="请输入联系方式"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="goods contain">
|
||||
<order-goods
|
||||
:team="{ need: orderInfo.team_need }"
|
||||
:list="goodsLists"
|
||||
:delivery="delivery"
|
||||
:order_type="orderInfo.order_type"
|
||||
mode="comfirm"
|
||||
></order-goods>
|
||||
<!-- <view class="item row-between">
|
||||
<view>配送方式</view>
|
||||
<view>快递</view>
|
||||
</view> -->
|
||||
<view class="item row-between">
|
||||
<view>买家留言</view>
|
||||
<u-input
|
||||
v-model="userRemark"
|
||||
class="flex1 ml20"
|
||||
:clearable="false"
|
||||
placeholder="请添加备注(150字以内)"
|
||||
></u-input>
|
||||
</view>
|
||||
</view>
|
||||
<view class="contain benefit" v-if="orderInfo.order_type == 0">
|
||||
<view class="item row-between" @tap="showCoupon = true">
|
||||
<view>优惠券</view>
|
||||
<view class="row">
|
||||
<text class="primary" v-if="orderInfo.discount_amount"
|
||||
>-¥{{ orderInfo.discount_amount }}</text
|
||||
>
|
||||
<text v-else-if="usableCoupon.length" class="primary">{{
|
||||
usableCoupon.length + '张可用'
|
||||
}}</text>
|
||||
<text v-else class="muted">无优惠券可用</text>
|
||||
<image
|
||||
class="icon-sm ml20"
|
||||
src="/static/images/arrow_right.png"
|
||||
></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item row" @tap="changeIntegral" v-if="orderInfo.integral_switch">
|
||||
<view>积分抵扣</view>
|
||||
<view class="ml20 muted xs row" style="flex: 1">
|
||||
共{{ orderInfo.user_integral }}积分{{
|
||||
orderInfo.user_integral < orderInfo.integral_limit
|
||||
? ',满' + orderInfo.integral_limit + '可用'
|
||||
: ''
|
||||
}}
|
||||
<view style="margin-top: 10rpx" @tap.stop="dialogIntegralDesc">
|
||||
<u-icon
|
||||
class="ml10"
|
||||
color="#999"
|
||||
size="30"
|
||||
name="question-circle"
|
||||
></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<checkbox
|
||||
:disabled="
|
||||
orderInfo.user_integral < orderInfo.integral_limit ||
|
||||
orderInfo.integral_config == 0
|
||||
"
|
||||
:checked="Boolean(useIntegral)"
|
||||
>
|
||||
</checkbox>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="price contain">
|
||||
<view class="item row-between">
|
||||
<view>商品金额</view>
|
||||
<view>¥{{ orderInfo.total_goods_price }}</view>
|
||||
</view>
|
||||
<view class="item row-between">
|
||||
<view>运费</view>
|
||||
<view>¥{{ orderInfo.shipping_price }}</view>
|
||||
</view>
|
||||
<view class="item row-between" v-if="orderInfo.discount_amount">
|
||||
<view>优惠券</view>
|
||||
<view class="primary">-¥{{ orderInfo.discount_amount }}</view>
|
||||
</view>
|
||||
<view class="item row-between" v-if="orderInfo.integral_amount">
|
||||
<view>积分抵扣</view>
|
||||
<view class="primary">-¥{{ orderInfo.integral_amount }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="footer bg-white row-between fixed">
|
||||
<view class="all-price lg row">
|
||||
<text>合计:</text>
|
||||
<view class="primary">
|
||||
<price-format
|
||||
:first-size="36"
|
||||
:second-size="36"
|
||||
:price="orderInfo.order_amount"
|
||||
></price-format>
|
||||
</view>
|
||||
</view>
|
||||
<button class="btn br60 white" size="md" hover-class="none" @tap="onSubmitOrder">
|
||||
提交订单
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
<loading-view v-if="showLoading" background-color="transparent" :size="50"></loading-view>
|
||||
<loading-view v-if="isFirstLoading"></loading-view>
|
||||
<u-popup v-model="showCoupon" border-radius="14" mode="bottom" closeable>
|
||||
<view class="pop-title row-between">
|
||||
<view class="title">优惠券</view>
|
||||
</view>
|
||||
<view v-if="showCoupon">
|
||||
<tabs :active="couponTabsIndex" :config="{ underLineWidth: 100 }">
|
||||
<tab :title="'可使用优惠券 (' + usableCoupon.length + ')'">
|
||||
<coupon-obj
|
||||
:list="usableCoupon"
|
||||
:type="0"
|
||||
@change="onSelectCoupon"
|
||||
:coupon-id="couponId"
|
||||
></coupon-obj>
|
||||
</tab>
|
||||
<tab :title="'不可用优惠券 (' + unusableCoupon.length + ')'">
|
||||
<coupon-obj
|
||||
:list="unusableCoupon"
|
||||
:type="1"
|
||||
@change="onSelectCoupon"
|
||||
></coupon-obj>
|
||||
</tab>
|
||||
</tabs>
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { orderBuy, getOrderCoupon, getDelivery } from '@/api/order'
|
||||
import { teamBuy } from '@/api/activity'
|
||||
import { prepay, getMnpNotice, getPayway } from '@/api/app'
|
||||
import { wxpay, alipay } from '@/utils/pay'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
isFirstLoading: true, // 首次页面加载loading
|
||||
showLoading: false, // Loading: 显示 | 隐藏
|
||||
address: {}, // 收货地址信息
|
||||
orderInfo: {}, // 订单信息
|
||||
goodsLists: [], // 商品列表
|
||||
addressId: '', // 收货地址ID
|
||||
useIntegral: 0, // 使用积分
|
||||
userRemark: '', // 用户留言
|
||||
userConsignee: '', // 取货人
|
||||
userMobile: '', // 联系电话
|
||||
|
||||
storeInfo: {}, // 门店信息
|
||||
|
||||
couponId: '', // 优惠券ID
|
||||
showCoupon: false, // 显示优惠券Popup
|
||||
couponTabsIndex: 0, // 优惠券Tabs索引
|
||||
usableCoupon: [], // 优惠券--可使用
|
||||
unusableCoupon: [], // 优惠券--不可用
|
||||
|
||||
bargainLaunchId: -1,
|
||||
|
||||
addressTabsIndex: 0, // 地址Tabs索引
|
||||
// 地址Tabs列表
|
||||
addressTabsList: [
|
||||
{
|
||||
id: 1,
|
||||
sign: 'express',
|
||||
name: '快递配送'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
sign: 'store',
|
||||
name: '门店自提'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
delivery() {
|
||||
return this.addressTabsList[this.addressTabsIndex]['id']
|
||||
}
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
const data = JSON.parse(decodeURIComponent(options.data))
|
||||
|
||||
this.goods = data.goods
|
||||
this.type = data.type
|
||||
this.teamId = data.teamId
|
||||
this.bargainLaunchId = options.bargain_launch_id
|
||||
this.foundId = data.foundId || 0
|
||||
|
||||
// 配送方式
|
||||
getDelivery()
|
||||
// 请求结果判断
|
||||
.then(({ code, data, msg }) => {
|
||||
if (code != 1) throw new Error(msg)
|
||||
return data
|
||||
})
|
||||
// 配送方式Tabs处理
|
||||
.then((data) => {
|
||||
// 快递
|
||||
if (!data.is_express) {
|
||||
this.addressTabsList = this.addressTabsList.filter(
|
||||
(item) => item.sign !== 'express'
|
||||
)
|
||||
}
|
||||
// 自提
|
||||
if (!data.is_selffetch) {
|
||||
this.addressTabsList = this.addressTabsList.filter(
|
||||
(item) => item.sign !== 'store'
|
||||
)
|
||||
}
|
||||
})
|
||||
// 页面数据初始化
|
||||
.then(() => {
|
||||
this.handleOrderMethods('info')
|
||||
this.initCouponData()
|
||||
})
|
||||
// 监听全局事件
|
||||
.then(() => {
|
||||
uni.$on('selectaddress', (params) => {
|
||||
this.addressId = params.id
|
||||
this.handleOrderMethods('info')
|
||||
})
|
||||
|
||||
uni.$on('payment', (params) => {
|
||||
setTimeout(() => {
|
||||
uni.$off('payment')
|
||||
|
||||
if (params.result) {
|
||||
uni.redirectTo({
|
||||
url: `/pages/pay_result/pay_result?id=${params.order_id}`
|
||||
})
|
||||
} else {
|
||||
uni.redirectTo({
|
||||
url: '/pages/user_order/user_order'
|
||||
})
|
||||
}
|
||||
}, 500)
|
||||
})
|
||||
|
||||
uni.$on('store', (params) => {
|
||||
this.storeInfo = params
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
},
|
||||
|
||||
onUnload() {
|
||||
// 取消全局监听
|
||||
uni.$off(['selectaddress', 'store'])
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 更改配送方式
|
||||
changeDelivery(index) {
|
||||
this.addressTabsIndex = index
|
||||
this.handleOrderMethods('info')
|
||||
},
|
||||
|
||||
// 点击选择收货地址
|
||||
onAddressExpress() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/user_address/user_address?type=${1}`
|
||||
})
|
||||
},
|
||||
|
||||
// 点击门店自提
|
||||
onAddressStore() {
|
||||
uni.navigateTo({
|
||||
url: `/bundle/pages/store_list/store_list`
|
||||
})
|
||||
},
|
||||
|
||||
// 更改积分使用
|
||||
changeIntegral() {
|
||||
const useIntegral = this.useIntegral
|
||||
|
||||
const orderInfo = this.orderInfo
|
||||
const integral_limit = orderInfo.integral_limit
|
||||
const user_integral = orderInfo.user_integral
|
||||
|
||||
if (integral_limit > user_integral) return this.$toast({ title: '未满足使用条件' })
|
||||
|
||||
this.useIntegral = useIntegral ? 0 : 1
|
||||
this.$nextTick(() => this.handleOrderMethods('info'))
|
||||
},
|
||||
|
||||
// 积分使用说明Dialog
|
||||
dialogIntegralDesc() {
|
||||
const desc = this.orderInfo.integral_desc
|
||||
|
||||
uni.showModal({
|
||||
title: '积分使用说明',
|
||||
content: desc,
|
||||
confirmColor: '#FF2C3C',
|
||||
showCancel: false
|
||||
})
|
||||
},
|
||||
|
||||
// 选择优惠券
|
||||
onSelectCoupon(value) {
|
||||
this.couponId = value
|
||||
this.showCoupon = false
|
||||
this.handleOrderMethods('info')
|
||||
},
|
||||
|
||||
// 获取微信授权
|
||||
authWechatMessage() {
|
||||
return new Promise((resolve, reject) => {
|
||||
getMnpNotice({
|
||||
scene: 1
|
||||
})
|
||||
.then(({ code, data, msg }) => {
|
||||
if (code != 1) throw new Error(msg)
|
||||
return data
|
||||
})
|
||||
.then((data) => {
|
||||
if (!data.length) return reject()
|
||||
uni.requestSubscribeMessage({
|
||||
tmplIds: data,
|
||||
success(res) {
|
||||
resolve(res)
|
||||
},
|
||||
fail(err) {
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 点击订单提交
|
||||
onSubmitOrder() {
|
||||
uni.showModal({
|
||||
title: '温馨提示',
|
||||
content: '是否确认下单?',
|
||||
confirmColor: '#FF2C3C',
|
||||
success: ({ confirm }) => {
|
||||
if (!confirm) return
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
this.authWechatMessage()
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
.finally(() => {
|
||||
this.handleOrderMethods('submit')
|
||||
})
|
||||
// #endif
|
||||
|
||||
// #ifndef MP-WEIXIN
|
||||
this.handleOrderMethods('submit')
|
||||
// #endif
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 初始化优惠券数据
|
||||
initCouponData() {
|
||||
getOrderCoupon({
|
||||
goods: this.goods
|
||||
})
|
||||
.then(({ code, data, msg }) => {
|
||||
if (code != 1) throw new Error(msg)
|
||||
return data
|
||||
})
|
||||
.then((data) => {
|
||||
this.usableCoupon = data.usable
|
||||
this.unusableCoupon = data.unusable
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
},
|
||||
|
||||
// 初始化页面数据
|
||||
async initPageData(from) {
|
||||
this.showLoading = true
|
||||
|
||||
try {
|
||||
const { code, data, msg } = this.teamId ? await teamBuy(from) : await orderBuy(from)
|
||||
|
||||
if (code == 1) {
|
||||
this.address = data.address
|
||||
this.goodsLists = data.goods_lists
|
||||
//TODO
|
||||
if (data.selffetch_info) {
|
||||
console.log(456)
|
||||
this.storeInfo = data.selffetch_info.selffetch_shop
|
||||
? data.selffetch_info.selffetch_shop
|
||||
: {}
|
||||
this.userConsignee = data.selffetch_info.contact
|
||||
this.userMobile = data.selffetch_info.mobile
|
||||
}
|
||||
|
||||
this.orderInfo = data
|
||||
this.$nextTick(() => {
|
||||
this.isFirstLoading = false
|
||||
})
|
||||
} else {
|
||||
throw new Error(msg)
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
this.$toast({ title: '网络异常,请重新进入页面' })
|
||||
} finally {
|
||||
this.showLoading = false
|
||||
}
|
||||
},
|
||||
|
||||
// 订单提交
|
||||
async handleOrderSubmit(from) {
|
||||
this.showLoading = true
|
||||
|
||||
from.remark = this.userRemark
|
||||
from.type = this.type
|
||||
|
||||
try {
|
||||
const { code, data, msg } = this.teamId ? await teamBuy(from) : await orderBuy(from)
|
||||
|
||||
if (code == 1) {
|
||||
uni.redirectTo({
|
||||
url: `/pages/payment/payment?from=${data.type}&order_id=${data.order_id}`
|
||||
})
|
||||
} else {
|
||||
throw new Error(msg)
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
// this.$toast({ title: '下单异常,请重新操作' })
|
||||
} finally {
|
||||
this.showLoading = false
|
||||
}
|
||||
},
|
||||
|
||||
// 订单处理
|
||||
handleOrderMethods(action) {
|
||||
// 订单提交数据
|
||||
const orderFrom = {
|
||||
action,
|
||||
goods: this.goods,
|
||||
delivery_type: this.delivery,
|
||||
use_integral: this.useIntegral,
|
||||
address_id: this.addressId,
|
||||
coupon_id: this.couponId,
|
||||
bargain_launch_id: this.bargainLaunchId == -1 ? '' : this.bargainLaunchId
|
||||
}
|
||||
|
||||
// 门店自提
|
||||
if (this.addressTabsList[this.addressTabsIndex]['sign'] === 'store') {
|
||||
orderFrom.selffetch_shop_id = this.storeInfo.id
|
||||
orderFrom.consignee = this.userConsignee
|
||||
orderFrom.mobile = this.userMobile
|
||||
}
|
||||
|
||||
// 拼团
|
||||
if (this.teamId) {
|
||||
const goods = this.goods[0]
|
||||
|
||||
delete orderFrom.goods
|
||||
|
||||
orderFrom.item_id = goods.item_id
|
||||
orderFrom.goods_num = goods.num
|
||||
orderFrom.team_id = this.teamId
|
||||
orderFrom.found_id = this.foundId
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case 'info':
|
||||
this.initPageData(orderFrom)
|
||||
break
|
||||
case 'submit':
|
||||
this.handleOrderSubmit(orderFrom)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.confirm-order .confirm-con {
|
||||
overflow: hidden;
|
||||
padding-bottom: calc(120rpx + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
.confirm-order .contain {
|
||||
border-radius: 14rpx;
|
||||
margin: 20rpx 20rpx 0;
|
||||
background-color: #fff;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.confirm-order .img-line {
|
||||
height: 1.5px;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.confirm-order .coupons {
|
||||
height: 100rpx;
|
||||
padding: 0 24rpx;
|
||||
}
|
||||
|
||||
.goods .title {
|
||||
padding: 22rpx 24rpx;
|
||||
border-bottom: 1px solid #f6f6f6;
|
||||
}
|
||||
|
||||
.goods .all-num {
|
||||
padding: 22rpx 24rpx;
|
||||
border-bottom: 1px dotted #f6f6f6;
|
||||
}
|
||||
|
||||
.confirm-order .footer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 100rpx;
|
||||
padding: 0 30rpx;
|
||||
box-sizing: content-box;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
.confirm-order .price {
|
||||
padding: 28rpx 20rpx;
|
||||
}
|
||||
|
||||
.confirm-order .price .item:not(:last-of-type) {
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.confirm-order .goods > .item,
|
||||
.confirm-order .benefit > .item {
|
||||
padding: 0 24rpx;
|
||||
height: 80rpx;
|
||||
}
|
||||
|
||||
.confirm-order .btn {
|
||||
background: linear-gradient(90deg, rgba(249, 95, 47, 1) 0%, rgba(255, 44, 60, 1) 100%);
|
||||
padding: 0 50rpx;
|
||||
}
|
||||
|
||||
.confirm-order .van-cell:after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.goods .shop-icon {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
|
||||
.pop-title {
|
||||
height: 100rpx;
|
||||
border-bottom: 1rpx solid #f2f2f2;
|
||||
}
|
||||
|
||||
.pop-title .title {
|
||||
margin-left: 30rpx;
|
||||
font-size: 34rpx;
|
||||
font-weight: bold;
|
||||
line-height: 36rpx;
|
||||
}
|
||||
|
||||
.receiving-way {
|
||||
margin: 20rpx 20rpx 0 20rpx;
|
||||
border-radius: 7px;
|
||||
background-color: #ffffff;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.receiving-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 160rpx;
|
||||
padding: 20rpx;
|
||||
border-top: 1px solid #f2f2f2;
|
||||
}
|
||||
|
||||
.receiving-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.store-from {
|
||||
padding: 0 20rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.store-from-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100rpx;
|
||||
}
|
||||
|
||||
.store-from-item:nth-child(n + 2) {
|
||||
border-top: 1px dashed #f2f2f2;
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,980 @@
|
||||
<template>
|
||||
<view class="goods-details">
|
||||
<navbar title="商品详情" :background="{background: `rgba(256,256,256,${percent})`}" :titleColor="`rgba(0,0,0,${percent})`" :immersive="true"></navbar>
|
||||
<!-- #ifdef H5 -->
|
||||
<download-nav v-if="showDownload" :top="44"></download-nav>
|
||||
<!-- #endif -->
|
||||
<loading-view v-if="isFirstLoading"></loading-view>
|
||||
<view class="contain" v-if="!isNull">
|
||||
<bubble-tips top="180rpx"></bubble-tips>
|
||||
<product-swiper :imgUrls="swiperList" :video="goodsDetail.video"></product-swiper>
|
||||
<!-- 秒杀 -->
|
||||
<view class="seckill row-between" v-if="goodsType == 1">
|
||||
<view class="price row">
|
||||
<view class="row white info">
|
||||
<view style="align-items: baseline;" class="row ml20">
|
||||
<view class="mr10">秒杀价</view>
|
||||
<price-format :first-size="46" :second-size="32" :subscript-size="32"
|
||||
:price="goodsDetail.min_price" :weight="500"></price-format>
|
||||
<template v-if="goodsDetail.min_price != goodsDetail.max_price">
|
||||
<text style="font-size: 46rpx;">-</text>
|
||||
<price-format :first-size="46" :second-size="32" :subscript-size="32"
|
||||
:show-subscript="false" :price="goodsDetail.max_price" :weight="500"></price-format>
|
||||
</template>
|
||||
<view class="ml10">
|
||||
<price-format :subscript-size="30" :line-through="true" :first-size="30"
|
||||
:second-size="30" :price="goodsDetail.market_price">
|
||||
</price-format>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="down column-center">
|
||||
<view class="xxs primary mb10">距活动结束仅剩</view>
|
||||
<u-count-down :timestamp="countTime" @end="getGoodsDetailFun" color="#fff" bg-color="#FF2C3C"
|
||||
separator-color="#FF2C3C" font-size="24" height="36" separator-size="26"></u-count-down>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 拼团 -->
|
||||
<view class="group" v-show="goodsType == 2">
|
||||
<view class="row info" style="height: 100%">
|
||||
<view class="row-between ml20 white" style="flex: 1;">
|
||||
<view style="align-items: baseline;" class="row">
|
||||
<view class="mr10">拼团价</view>
|
||||
<price-format :subscript-size="32" :first-size="46" :second-size="32"
|
||||
:price="team.team_min_price" :weight="500"></price-format>
|
||||
<text class="xs">起</text>
|
||||
</view>
|
||||
<view class="mr20 row group-num">
|
||||
<view class="group-icon">
|
||||
<image src="/static/images/icon_group.png" class="icon-sm"></image>
|
||||
</view>
|
||||
<view class="xxs ml10 mr10">{{ team.people_num }}人团</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="down column-center">
|
||||
<view class="xxs primary mb10">距活动结束仅剩</view>
|
||||
<u-count-down :timestamp="countTime" color="#fff" bg-color="#FF2C3C" separator-color="#FF2C3C"
|
||||
font-size="24" height="36" separator-size="26" @end="getGoodsDetailFun"></u-count-down>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="goods-info bg-white">
|
||||
<view class="info-header row" v-if="goodsType != 1">
|
||||
<view class="price row flex1">
|
||||
<view class="primary mr10">
|
||||
<price-format :first-size="46" :second-size="32" :subscript-size="32"
|
||||
:price="goodsDetail.min_price" :weight="500"></price-format>
|
||||
<template v-if="goodsDetail.min_price != goodsDetail.max_price">
|
||||
<text style="font-size: 46rpx;">-</text>
|
||||
<price-format :first-size="46" :second-size="32" :subscript-size="32"
|
||||
:show-subscript="false" :price="goodsDetail.max_price" :weight="500"></price-format>
|
||||
</template>
|
||||
</view>
|
||||
<view class="line-through muted md">
|
||||
<price-format :price="goodsDetail.market_price"></price-format>
|
||||
</view>
|
||||
</view>
|
||||
<image class="icon-share" src="/static/images/icon_share.png" @tap="showShareBtn = true"></image>
|
||||
</view>
|
||||
<view class="row" v-if="!goodsType && (goodsDetail.member_price)">
|
||||
<view class="vip-price row">
|
||||
<view class="price-name xxs">会员价</view>
|
||||
<view style="padding: 0 11rpx">
|
||||
<price-format :price="goodsDetail.member_price " :first-size="26" :second-size="26"
|
||||
:subscript-size="22" :weight="500" color="#7B3200">
|
||||
</price-format>
|
||||
<text class="xxs" style="color: #7B3200;">起</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="row">
|
||||
<view class="name lg bold">{{ goodsDetail.name }}</view>
|
||||
<image class="icon-share" src="/static/images/icon_share.png" @tap="showShareBtn = true"
|
||||
v-if="goodsType == 1"></image>
|
||||
</view>
|
||||
<view class="row-between xs lighter" style="padding: 0 24rpx 20rpx">
|
||||
<text v-if="goodsDetail.stock !== true">库存: {{ goodsDetail.stock }}件</text>
|
||||
<text>销量: {{ goodsDetail.sales_sum }}件</text>
|
||||
<text>浏览量: {{ goodsDetail.click_count }}次</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="group-play bg-white mt20" v-if="goodsType == 2">
|
||||
<view class="title">拼团玩法</view>
|
||||
<view class="steps row">
|
||||
<view class="row step">
|
||||
<view class="number xxs">1</view>
|
||||
<view class="sm">开团/参团</view>
|
||||
</view>
|
||||
<view class="line"></view>
|
||||
<view class="row step">
|
||||
<view class="number xxs">2</view>
|
||||
<view class="sm">团满即成新团</view>
|
||||
</view>
|
||||
<view class="line"></view>
|
||||
<view class="row step">
|
||||
<view class="number xxs">3</view>
|
||||
<view class="sm">满员发货</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="discount mt20 bg-white" v-if="couponList.length || goodsDetail.order_give_integral">
|
||||
<view class="row" style="align-items: flex-start;">
|
||||
<view class="text muted">优惠</view>
|
||||
<view style="flex: 1">
|
||||
<view :class="['row coupons', {mb30: goodsDetail.order_give_integral > 0}]"
|
||||
v-if="couponList.length" @tap="showCouponFun">
|
||||
<view class="flexnone">
|
||||
<u-tag text="领券" size="mini" type="primary" mode="plain" />
|
||||
</view>
|
||||
<view class="con row ml20" style="flex: 1">
|
||||
<view v-for="(item, index) in couponList" :key="index" class="coupons-item mr20">
|
||||
<view v-if="index < 2" class="row xs">
|
||||
<view class="line1">
|
||||
{{ item.use_condition }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<image class="icon-sm" src="/static/images/arrow_right.png"></image>
|
||||
</view>
|
||||
<view class="row integral" style="align-items: flex-start;"
|
||||
v-if="goodsDetail.order_give_integral">
|
||||
<view class="flexnone">
|
||||
<u-tag text="积分" size="mini" type="primary" mode="plain" />
|
||||
</view>
|
||||
<view class="ml20">下单最多可获得{{goodsDetail.order_give_integral}}积分</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<swiper v-if="teamFound.length" class="mt20 bg-white" autoplay="true" style="height: 240rpx;"
|
||||
vertical="true" circular="true" :interval="5000">
|
||||
<swiper-item v-for="(sitem, index) in teamFound" :key="index">
|
||||
<view class="group-list">
|
||||
<view v-for="(item, index2) in sitem" :key="index2" class="group-item bg-white row-between">
|
||||
<view class="row" style="max-width: 280rpx;">
|
||||
<custom-image :src="item.avatar" width="80rpx" height="80rpx" radius="50%">
|
||||
</custom-image>
|
||||
<view class="ml20 line1 normal">{{ item.nickname }}</view>
|
||||
</view>
|
||||
<view class="row ml20" style="flex: none;">
|
||||
<view class="column-center">
|
||||
<text class="sm normal">
|
||||
还差
|
||||
<text class="primary">{{ item.need - item.join }}</text>
|
||||
人成团
|
||||
</text>
|
||||
<view class="muted xs">
|
||||
剩余
|
||||
<u-count-down :timestamp="getTeamCountTime(item.found_end_time)"
|
||||
separator-color="#999" color="#999" :separator-size="24" :font-size="24"
|
||||
bg-color="transparent" @end="getGoodsDetailFun"></u-count-down>
|
||||
</view>
|
||||
</view>
|
||||
<view class="group-btn br60 white row-center" @tap="showSpecFun(3, item.id)">去参团</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<view v-if="!goodsType" class="spec row bg-white mt20" @tap="showSpecFun(0)">
|
||||
<view class="text lighter">已选</view>
|
||||
<view class="line1 mr20" style="flex: 1;">{{ checkedGoods.spec_value_str || '默认' }}</view>
|
||||
<image class="icon-sm" src="/static/images/arrow_right.png"></image>
|
||||
</view>
|
||||
<navigator class="mt20" hover-class="none" url="/bundle/pages/server_explan/server_explan?type=2">
|
||||
<view class="row bg-white" style="padding: 24rpx 24rpx;">
|
||||
<view class="text lighter flex1">售后保障</view>
|
||||
<image class="icon-sm" src="/static/images/arrow_right.png"></image>
|
||||
</view>
|
||||
</navigator>
|
||||
<view class="evaluation bg-white mt20">
|
||||
<navigator hover-class="none" :url="'/pages/all_comments/all_comments?id=' + goodsDetail.id"
|
||||
class="title row-between">
|
||||
<view>
|
||||
<text class="balck md mr10">用户评价</text>
|
||||
<text class="primary sm">好评率{{ comment.goods_rate || '0%' }}</text>
|
||||
</view>
|
||||
<view class="row">
|
||||
<text class="lighter">查看全部</text>
|
||||
<image class="icon-sm" src="/static/images/arrow_right.png"></image>
|
||||
</view>
|
||||
</navigator>
|
||||
<view class="con" v-if="comment.goods_rate">
|
||||
<view class="user-info row">
|
||||
<image class="avatar mr20" :src="comment.avatar"></image>
|
||||
<view class="user-name md mr10">{{ comment.nickname }}</view>
|
||||
</view>
|
||||
<view class="muted xs mt10">
|
||||
<text class="mr20">{{ comment.create_time }}</text>
|
||||
</view>
|
||||
<view v-if="comment.comment" class="dec mt20">{{ comment.comment }}</view>
|
||||
</view>
|
||||
<view class="con row-center muted" v-else>暂无评价</view>
|
||||
</view>
|
||||
|
||||
<view class="goods-like mt20 bg-white" v-if="goodsLike.length">
|
||||
<goods-like :list="goodsLike"></goods-like>
|
||||
</view>
|
||||
<view class="details mt20 bg-white">
|
||||
<view class="title lg">商品详情</view>
|
||||
<view class="content">
|
||||
<u-parse :html="goodsDetail.content" :lazy-load="true" :show-with-animation="true"></u-parse>
|
||||
</view>
|
||||
</view>
|
||||
<view class="footer row bg-white fixed">
|
||||
<navigator class="btn column-center" hover-class="none"
|
||||
url="/bundle/pages/contact_offical/contact_offical">
|
||||
<image class="icon-md" src="/static/images/icon_contact.png"></image>
|
||||
<text class="xxs lighter">客服</text>
|
||||
</navigator>
|
||||
<button class="btn column-center" hover-class="none" @tap="collectGoodsFun">
|
||||
<image class="icon-md"
|
||||
:src="goodsDetail.is_collect == 1 ? '/static/images/icon_collection_s.png' : '/static/images/icon_collection.png'">
|
||||
</image>
|
||||
<text class="xxs lighter">收藏</text>
|
||||
</button>
|
||||
<navigator class="btn cart column-center" hover-class="none" open-type="switchTab"
|
||||
url="/pages/shop_cart/shop_cart">
|
||||
<image class="icon-md" src="/static/images/icon_cart.png"></image>
|
||||
<text class="xxs lighter">购物车</text>
|
||||
<u-badge v-if="cartNum" bgColor="#FF2C3C" :offset="[8, 10]" :count="cartNum"></u-badge>
|
||||
</navigator>
|
||||
<view v-if="btnText.yellow" class="add-cart br60 white mr10 md ml20" @tap="showSpecFun(1)">
|
||||
{{ btnText.yellow }}
|
||||
</view>
|
||||
<view class="right-buy br60 white mr20 ml10 md" @tap="showSpecFun(2)">{{ btnText.red }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else>
|
||||
<view class="details-null column-center">
|
||||
<image class="img-null" src="/static/images/goods_null.png"></image>
|
||||
<view class="xs muted">该商品已下架或不存在,去逛逛别的吧~</view>
|
||||
</view>
|
||||
<recommend></recommend>
|
||||
</view>
|
||||
<spec-popup :show="showSpec" :goods="goodsDetail" :is-seckill="goodsType == 1" @close="showSpec = false"
|
||||
:show-add="popupType == 1 || popupType == 0" :show-buy="popupType == 2 || popupType == 0"
|
||||
:showConfirm="popupType == 3" @buynow="onBuy" @addcart="onAddCart" @change="onChangeGoods"
|
||||
:group="Boolean(isGroup)" :red-btn-text="btnText.red" :yellow-btn-text="btnText.yellow"
|
||||
@confirm="onConfirm"></spec-popup>
|
||||
|
||||
<share-popup v-model="showShareBtn"
|
||||
:share-id="id"
|
||||
pagePath="pages/goods_details/goods_details"
|
||||
:type="1"
|
||||
:config="{
|
||||
avatar: userInfo.avatar,
|
||||
nickname: userInfo.nickname,
|
||||
image: goodsDetail.poster || goodsDetail.image,
|
||||
price: goodsDetail.min_price,
|
||||
marketPrice: goodsDetail.market_price,
|
||||
name: goodsDetail.name
|
||||
}">
|
||||
</share-popup>
|
||||
<!-- 领券 -->
|
||||
<u-popup v-model="showCoupon" mode="bottom" border-radius="14">
|
||||
<view>
|
||||
<view class="row-between" style="padding: 30rpx">
|
||||
<view class="title md bold">领券</view>
|
||||
<view class="close" @tap="showCoupon = false">
|
||||
<image class="icon-lg" src="/static/images/icon_close.png"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content bg-body">
|
||||
<scroll-view scroll-y="true" style="height: 700rpx">
|
||||
<coupon-list :list="couponList" @reflash="getGoodsCouponFun" :btn-type="3"></coupon-list>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</u-popup>
|
||||
|
||||
<view class="share-money" :class="{ show: showCommission && enableCommission}">
|
||||
<view class="row-end">
|
||||
<view class="share-close row-center" @tap="showCommission=false">
|
||||
<u-icon name="close" size="16" color="#fff"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view class="share-con mt10" @tap="showShareBtn=true">
|
||||
<view class="primary" style="font-size: 45rpx;">
|
||||
{{distribution.earnings}}<text class="xs">元</text>
|
||||
</view>
|
||||
<view class="lighter xxs">
|
||||
好友下单最高可赚
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<u-back-top :scroll-top="scrollTop" :top="1000" :customStyle="{ backgroundColor: '#FFF', color: '#000', boxShadow: '0px 3px 6px rgba(0, 0, 0, 0.1)'}"></u-back-top>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getGoodsDetail,
|
||||
addCart,
|
||||
getPoster,
|
||||
getCartNum
|
||||
} from '@/api/store';
|
||||
import {
|
||||
collectGoods
|
||||
} from '@/api/user';
|
||||
import {
|
||||
getGoodsCoupon,
|
||||
teamCheck
|
||||
} from '@/api/activity';
|
||||
import {
|
||||
mapActions,
|
||||
mapGetters
|
||||
} from 'vuex';
|
||||
import {
|
||||
arraySlice,
|
||||
trottle
|
||||
} from '@/utils/tools';
|
||||
import {
|
||||
toLogin
|
||||
} from '@/utils/login';
|
||||
import {
|
||||
getUser,
|
||||
inputInviteCode
|
||||
} from '@/api/user';
|
||||
import Cache from '@/utils/cache';
|
||||
import {
|
||||
strToParams
|
||||
} from '@/utils/tools'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
scrollTop: 0,
|
||||
percent: 0,
|
||||
isFirstLoading: true,
|
||||
isNull: false,
|
||||
showSpec: false,
|
||||
showCoupon: false,
|
||||
showShareBtn: false,
|
||||
showCommission: true,
|
||||
popupType: '',
|
||||
swiperList: [],
|
||||
goodsDetail: {},
|
||||
goodsLike: [],
|
||||
goodsType: 0,
|
||||
checkedGoods: {},
|
||||
couponList: [],
|
||||
comment: {},
|
||||
countTime: 0,
|
||||
tagStyle: {
|
||||
img: 'width:100%;'
|
||||
},
|
||||
team: {},
|
||||
teamFound: [],
|
||||
isGroup: 0,
|
||||
id: '',
|
||||
showDownload: false,
|
||||
distribution: {}
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
this.onPageScroll = trottle(this.onPageScroll, 500, this)
|
||||
if (options && options.scene) {
|
||||
let scene = strToParams(decodeURIComponent(options.scene));
|
||||
console.log(scene, decodeURIComponent(options.scene))
|
||||
options.id = scene.id;
|
||||
}
|
||||
// #ifdef H5
|
||||
if (options && options.isapp == 1) {
|
||||
this.showDownload = true;
|
||||
}
|
||||
// #endif
|
||||
if (!options.id) {
|
||||
return this.$toast({
|
||||
title: '缺少参数,无法查看商品'
|
||||
}, {
|
||||
tab: 3
|
||||
});
|
||||
} else {
|
||||
this.id = options.id;
|
||||
}
|
||||
this.getGoodsCouponFun();
|
||||
this.getCartNum();
|
||||
},
|
||||
onShow() {
|
||||
this.getGoodsDetailFun();
|
||||
},
|
||||
onPageScroll(e) {
|
||||
const top = uni.upx2px(100)
|
||||
const {
|
||||
scrollTop
|
||||
} = e
|
||||
this.percent = scrollTop / top > 1 ? 1 : scrollTop / top
|
||||
this.scrollTop = scrollTop
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['getCartNum']),
|
||||
async getGoodsDetailFun() {
|
||||
const {
|
||||
data,
|
||||
code
|
||||
} = await getGoodsDetail({
|
||||
id: this.id
|
||||
});
|
||||
if (code == 1) {
|
||||
let {
|
||||
goods_image,
|
||||
content,
|
||||
comment,
|
||||
like,
|
||||
activity,
|
||||
distribution
|
||||
} = data;
|
||||
let {
|
||||
info,
|
||||
team,
|
||||
team_found
|
||||
} = activity; //秒杀时间
|
||||
let time = info ?
|
||||
info.end_time - Date.now() / 1000 //拼团时间
|
||||
:
|
||||
team ?
|
||||
team.end_time - Date.now() / 1000 :
|
||||
0;
|
||||
|
||||
if (team_found) {
|
||||
team_found = arraySlice(team_found, [], 2);
|
||||
}
|
||||
this.distribution = distribution || {}
|
||||
this.goodsDetail = data;
|
||||
this.swiperList = goods_image;
|
||||
this.comment = comment;
|
||||
this.goodsLike = like;
|
||||
this.countTime = time;
|
||||
this.goodsType = activity.type || 0;
|
||||
this.team = team ? team : {};
|
||||
this.teamFound = team_found ? team_found : [];
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.isFirstLoading = false;
|
||||
});
|
||||
// #ifdef H5
|
||||
let options = {
|
||||
shareTitle: data.name,
|
||||
shareLink: location.href + '&invite_code=' + this.userInfo.distribution_code,
|
||||
shareImage: data.image,
|
||||
shareDesc: data.remark
|
||||
};
|
||||
this.wxShare(options);
|
||||
// #endif
|
||||
} else {
|
||||
this.isNull = true
|
||||
this.isFirstLoading = false;
|
||||
}
|
||||
},
|
||||
async getGoodsCouponFun() {
|
||||
const {
|
||||
data,
|
||||
code
|
||||
} = await getGoodsCoupon({
|
||||
id: this.id
|
||||
});
|
||||
if (code == 1) {
|
||||
this.couponList = data;
|
||||
}
|
||||
},
|
||||
async collectGoodsFun() {
|
||||
if (!this.isLogin) return toLogin();
|
||||
const {
|
||||
goodsDetail: {
|
||||
is_collect
|
||||
}
|
||||
} = this;
|
||||
const {
|
||||
data,
|
||||
code
|
||||
} = await collectGoods({
|
||||
is_collect: is_collect == 0 ? 1 : 0,
|
||||
goods_id: this.id
|
||||
});
|
||||
if (code == 1) {
|
||||
if (is_collect == 0) {
|
||||
this.$toast({
|
||||
title: '收藏成功'
|
||||
});
|
||||
} else {
|
||||
this.$toast({
|
||||
title: '取消收藏'
|
||||
});
|
||||
}
|
||||
this.getGoodsDetailFun();
|
||||
}
|
||||
},
|
||||
showCouponFun() {
|
||||
if (!this.isLogin) return toLogin();
|
||||
this.showCoupon = true;
|
||||
},
|
||||
onChangeGoods(e) {
|
||||
console.log(e);
|
||||
this.checkedGoods = e.detail;
|
||||
},
|
||||
showSpecFun(type, id) {
|
||||
if (!this.isLogin) return toLogin();
|
||||
if (this.goodsType == 2 && [2, 3].includes(type)) {
|
||||
this.isGroup = 1;
|
||||
this.foundId = id;
|
||||
} else {
|
||||
this.isGroup = 0;
|
||||
this.foundId = '';
|
||||
}
|
||||
this.popupType = type;
|
||||
this.showSpec = true;
|
||||
},
|
||||
onBuy(e) {
|
||||
let {
|
||||
id,
|
||||
goodsNum
|
||||
} = e.detail;
|
||||
const {
|
||||
goodsType,
|
||||
team
|
||||
} = this;
|
||||
let goods = [{
|
||||
item_id: id,
|
||||
num: goodsNum
|
||||
}];
|
||||
const params = {
|
||||
goods,
|
||||
};
|
||||
this.showSpec = false;
|
||||
goodsType == 2 ? (params.teamId = team.team_id) : '';
|
||||
this.foundId ? (params.foundId = this.foundId) : '';
|
||||
uni.navigateTo({
|
||||
url: '/pages/confirm_order/confirm_order?data=' + encodeURIComponent((JSON.stringify(params)))
|
||||
})
|
||||
console.log(1111)
|
||||
},
|
||||
onConfirm(e) {
|
||||
const {
|
||||
team: {
|
||||
team_id
|
||||
}
|
||||
} = this;
|
||||
teamCheck({
|
||||
team_id,
|
||||
found_id: this.foundId
|
||||
}).then(res => {
|
||||
if (res.code == 1) {
|
||||
this.onBuy(e);
|
||||
}
|
||||
});
|
||||
},
|
||||
async onAddCart(e) {
|
||||
let {
|
||||
id,
|
||||
goodsNum
|
||||
} = e.detail;
|
||||
|
||||
if (this.goodsType == 2) {
|
||||
// 拼团单独购买
|
||||
let goods = [{
|
||||
item_id: id,
|
||||
num: goodsNum
|
||||
}];
|
||||
uni.navigateTo({
|
||||
url: '/pages/confirm_order/confirm_order?data=' + encodeURIComponent((JSON.stringify({
|
||||
goods
|
||||
})))
|
||||
})
|
||||
return
|
||||
}
|
||||
const {
|
||||
code,
|
||||
data,
|
||||
msg
|
||||
} = await addCart({
|
||||
item_id: id,
|
||||
goods_num: goodsNum
|
||||
});
|
||||
if (code == 1) {
|
||||
this.getCartNum();
|
||||
this.$toast({
|
||||
title: msg,
|
||||
icon: 'success'
|
||||
});
|
||||
this.showSpec = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
async onShareAppMessage() {
|
||||
const {
|
||||
goodsDetail,
|
||||
team,
|
||||
userInfo
|
||||
} = this;
|
||||
return {
|
||||
title: team.share_title || goodsDetail.name,
|
||||
imageUrl: goodsDetail.image,
|
||||
path: '/pages/goods_details/goods_details?id=' + this.id + "&invite_code=" + userInfo.distribution_code
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['cartNum', 'userInfo']),
|
||||
btnText() {
|
||||
const {
|
||||
goodsType
|
||||
} = this;
|
||||
switch (goodsType) {
|
||||
case 1:
|
||||
return {
|
||||
red: '立即抢购',
|
||||
yellow: ''
|
||||
};
|
||||
case 2:
|
||||
return {
|
||||
red: '立即开团',
|
||||
yellow: '单独购买'
|
||||
};
|
||||
default:
|
||||
return {
|
||||
red: '立即购买',
|
||||
yellow: '加入购物车'
|
||||
};
|
||||
}
|
||||
},
|
||||
getTeamCountTime() {
|
||||
return time => time - Date.now() / 1000;
|
||||
},
|
||||
enableCommission() {
|
||||
const {
|
||||
goodsType,
|
||||
distribution: {
|
||||
earnings,
|
||||
is_show
|
||||
}
|
||||
} = this
|
||||
return goodsType == 0 && earnings > 0 && is_show == 1
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.goods-details {
|
||||
padding-bottom: calc(120rpx + env(safe-area-inset-bottom));
|
||||
|
||||
.seckill {
|
||||
height: 100rpx;
|
||||
background: #ffd4d8;
|
||||
|
||||
.price {
|
||||
width: 504rpx;
|
||||
height: 100%;
|
||||
background: url(../../static/images/bg_seckill.png) no-repeat;
|
||||
background-size: 100%;
|
||||
}
|
||||
|
||||
.down {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.group {
|
||||
height: 100rpx;
|
||||
width: 100%;
|
||||
background-image: url(../../static/images/pintuan_bg.png);
|
||||
background-size: 100%;
|
||||
|
||||
.group-num {
|
||||
border: 1px solid #ffffff;
|
||||
border-radius: 4rpx;
|
||||
|
||||
.group-icon {
|
||||
background: #fff;
|
||||
padding: 3rpx 7rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.down {
|
||||
height: 100%;
|
||||
background-color: #fff5e1;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-info {
|
||||
position: relative;
|
||||
|
||||
.info-header {
|
||||
padding: 20rpx 0 0rpx 24rpx;
|
||||
|
||||
.price {
|
||||
align-items: baseline;
|
||||
}
|
||||
}
|
||||
|
||||
.vip-price {
|
||||
margin: 0 24rpx;
|
||||
background-color: #FFE9BA;
|
||||
color: #FFD4B7;
|
||||
line-height: 36rpx;
|
||||
border-radius: 6rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.price-name {
|
||||
background-color: #101010;
|
||||
padding: 3rpx 12rpx;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 20rpx;
|
||||
height: 20rpx;
|
||||
position: absolute;
|
||||
right: -15rpx;
|
||||
background-color: #FFE9BA;
|
||||
border-radius: 50%;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
padding: 20rpx 24rpx;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.icon-share {
|
||||
width: 134rpx;
|
||||
height: 60rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.discount {
|
||||
padding: 24rpx;
|
||||
|
||||
.text {
|
||||
width: 100rpx;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.con {
|
||||
width: 400rpx;
|
||||
}
|
||||
|
||||
.coupons-item {
|
||||
overflow: hidden;
|
||||
|
||||
&>view {
|
||||
position: relative;
|
||||
height: 40rpx;
|
||||
line-height: 40rpx;
|
||||
padding: 0 18rpx;
|
||||
border-radius: 6rpx;
|
||||
box-sizing: border-box;
|
||||
background-color: $-color-primary;
|
||||
color: #fff;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
|
||||
&::after,
|
||||
&::before {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 20rpx;
|
||||
height: 20rpx;
|
||||
position: absolute;
|
||||
left: -14rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 50%;
|
||||
border: 1px solid currentColor;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
&::after {
|
||||
right: -14rpx;
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.details-null {
|
||||
padding-top: 140rpx;
|
||||
margin-bottom: 100rpx;
|
||||
}
|
||||
|
||||
.spec {
|
||||
padding: 24rpx;
|
||||
|
||||
.text {
|
||||
width: 100rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.evaluation {
|
||||
.title {
|
||||
height: 100rpx;
|
||||
border-bottom: $-solid-border;
|
||||
padding: 0 24rpx;
|
||||
}
|
||||
|
||||
.con {
|
||||
padding: 30rpx 24rpx;
|
||||
}
|
||||
|
||||
.user-info .avatar {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.details {
|
||||
.title {
|
||||
line-height: 88rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&>.content {
|
||||
padding: 0 20rpx 20rpx;
|
||||
overflow: hidden;
|
||||
|
||||
::v-deep image {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
// #ifdef H5
|
||||
::v-deep img {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN || APP-PLUS
|
||||
::v-deep ._img {
|
||||
display: block;
|
||||
}
|
||||
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
height: 100rpx;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
box-sizing: content-box;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
|
||||
.btn {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
position: relative;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.cart-num {
|
||||
position: absolute;
|
||||
left: 60rpx;
|
||||
top: 6rpx;
|
||||
}
|
||||
|
||||
.add-cart,
|
||||
.right-buy {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 16rpx 0;
|
||||
}
|
||||
|
||||
.add-cart {
|
||||
background-color: #ffa630;
|
||||
}
|
||||
|
||||
.right-buy {
|
||||
background-color: $-color-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.group-play {
|
||||
.title {
|
||||
padding: 20rpx 28rpx;
|
||||
border-bottom: $-solid-border;
|
||||
}
|
||||
|
||||
.steps {
|
||||
padding: 20rpx 28rpx;
|
||||
|
||||
.step {
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.line {
|
||||
flex: 1;
|
||||
border: 1px dashed #999999;
|
||||
margin: 0 20rpx;
|
||||
}
|
||||
|
||||
.number {
|
||||
border: 1rpx solid #707070;
|
||||
width: 28rpx;
|
||||
height: 28rpx;
|
||||
border-radius: 50%;
|
||||
line-height: 28rpx;
|
||||
text-align: center;
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.group-list {
|
||||
.group-item {
|
||||
padding: 20rpx 24rpx;
|
||||
|
||||
&:not(:last-of-type) {
|
||||
border-bottom: $-solid-border;
|
||||
}
|
||||
|
||||
.group-btn {
|
||||
background: linear-gradient(90deg, #f95f2f 0%, #ff2c3c 100%);
|
||||
height: 58rpx;
|
||||
padding-left: 28rpx;
|
||||
padding-right: 28rpx;
|
||||
margin-left: 30rpx;
|
||||
box-shadow: 0px 6rpx 12rpx rgba(249, 47, 138, 0.4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.share-money {
|
||||
position: fixed;
|
||||
left: 20rpx;
|
||||
bottom: calc(130rpx + env(safe-area-inset-bottom));
|
||||
transform: scale(0);
|
||||
transition: all .3s;
|
||||
|
||||
&.show {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.share-close {
|
||||
width: 34rpx;
|
||||
height: 34rpx;
|
||||
background: #a7a7a7;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.share-con {
|
||||
background: url('../../static/images/bg_packet_img.png');
|
||||
width: 241rpx;
|
||||
height: 208rpx;
|
||||
background-size: 100%;
|
||||
padding-top: 20rpx;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,316 @@
|
||||
<template>
|
||||
<view class="goods-search">
|
||||
|
||||
<view class="header-wrap">
|
||||
<u-sticky offset-top="0" h5-nav-height="0">
|
||||
<view class="search">
|
||||
<u-search v-model="keyword" @focus="showHistory = true" :focus="showHistory" @search="onSearch" bg-color="#F4F4F4"></u-search>
|
||||
</view>
|
||||
<view v-show="!showHistory" class="header row bg-white">
|
||||
<view :class="'tag row-center ' + (comprehensive ? 'primary' : '')" @tap="onNormal">综合</view>
|
||||
<view class="tag row-center" data-type="priceSort" @tap="onPriceSort">
|
||||
<text :class="priceSort ? 'primary' : ''">价格</text>
|
||||
<view>
|
||||
<trigonometry direction="up" size="small" :color="priceSort == 'desc' ? '#FF5058' : '#333'">
|
||||
</trigonometry>
|
||||
<trigonometry size="small" :color="priceSort == 'asc' ? '#FF5058' : '#333'"></trigonometry>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tag row-center" data-type="saleSort" @tap="onSaleSort">
|
||||
<text :class="saleSort ? 'primary' : ''">销量</text>
|
||||
<view>
|
||||
<trigonometry direction="up" size="small" :color="saleSort == 'desc' ? '#FF5058' : '#333'">
|
||||
</trigonometry>
|
||||
<trigonometry size="small" :color="saleSort == 'asc' ? '#FF5058' : '#333'"></trigonometry>
|
||||
</view>
|
||||
</view>
|
||||
<view class="tag row-center" @tap="changeType">
|
||||
<image class="icon-sm" :src=" goodsType === 'one' ? '/static/images/icon_double.png' : '/static/images/icon_one.png'"></image>
|
||||
</view>
|
||||
</view>
|
||||
</u-sticky>
|
||||
</view>
|
||||
<view v-show="showHistory" class="content bg-white">
|
||||
<view v-if="hotList.length" class="search-words">
|
||||
<view class="title">热门搜索</view>
|
||||
<view class="words row wrap">
|
||||
<view v-for="(item, index) in hotList" :key="index" class="item br60 mr20 mb20 lighter sm line1" @tap="onChangeKeyword(item)">{{item}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="historyList.length" class="search-words">
|
||||
<view class="title row-between">
|
||||
<view>历史搜索</view>
|
||||
<view class="xs muted mr20" style="padding: 10rpx 20rpx" @tap="clearSearchFun">清空</view>
|
||||
</view>
|
||||
<view class="words row wrap">
|
||||
<view v-for="(item, index) in historyList" :key="index" class="item br60 mr20 mb20 lighter sm line1" @tap="onChangeKeyword(item)">{{item}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-show="!showHistory" class="content">
|
||||
<view class="goods-list">
|
||||
<view v-show="goodsType == 'double'" class="double">
|
||||
<goods-list type="double" :list="goodsList"></goods-list>
|
||||
</view>
|
||||
<view v-show="goodsType == 'one'" class="one">
|
||||
<goods-list :list="goodsList" type="one"></goods-list>
|
||||
</view>
|
||||
</view>
|
||||
<loading-footer :status="status" :slot-empty="true">
|
||||
<view slot="empty" class="column-center" style="padding-top: 200rpx">
|
||||
<image class="img-null" src="/static/images/goods_null.png"></image>
|
||||
<text class="lighter">暂无商品</text>
|
||||
</view>
|
||||
</loading-footer>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getGoodsSearch,
|
||||
getSearchpage,
|
||||
clearSearch
|
||||
} from '@/api/store';
|
||||
import {
|
||||
trottle,
|
||||
loadingFun,
|
||||
getRect
|
||||
} from '@/utils/tools';
|
||||
import {
|
||||
loadingType
|
||||
} from '@/utils/type';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
keyword: '',
|
||||
status: loadingType.LOADING,
|
||||
page: 1,
|
||||
goodsType: 'double',
|
||||
goodsList: [],
|
||||
priceSort: '',
|
||||
saleSort: '',
|
||||
showHistory: false,
|
||||
hotList: [],
|
||||
historyList: []
|
||||
};
|
||||
},
|
||||
|
||||
components: {},
|
||||
props: {},
|
||||
watch: {
|
||||
// 监听属性
|
||||
keyword(value, old) {
|
||||
if (!value && !this.id) {
|
||||
this.showHistory = true
|
||||
}
|
||||
},
|
||||
showHistory(value) {
|
||||
if (value) {
|
||||
this.getSearchpageFun();
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
computed: {
|
||||
comprehensive() {
|
||||
const {
|
||||
priceSort,
|
||||
saleSort
|
||||
} = this
|
||||
if (priceSort == '' && saleSort == '') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
onLoad(options) {
|
||||
this.onNormal = trottle(this.onNormal, 500, this);
|
||||
this.onPriceSort = trottle(this.onPriceSort, 500, this);
|
||||
this.onSaleSort = trottle(this.onSaleSort, 500, this);
|
||||
this.onSearch = trottle(this.onSearch, 500, this);
|
||||
this.init(options);
|
||||
},
|
||||
|
||||
|
||||
onReachBottom: function() {
|
||||
this.getGoodsSearchFun();
|
||||
},
|
||||
methods: {
|
||||
onChange(e) {
|
||||
this.keyword = e.value
|
||||
},
|
||||
|
||||
changeType() {
|
||||
this.goodsType = this.goodsType === 'one' ? 'double' : 'one'
|
||||
},
|
||||
|
||||
clearSearchFun() {
|
||||
clearSearch().then(res => {
|
||||
if (res.code == 1) {
|
||||
this.getSearchpageFun();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onNormal() {
|
||||
this.priceSort = ''
|
||||
this.saleSort = ''
|
||||
this.onRefresh();
|
||||
},
|
||||
|
||||
onPriceSort() {
|
||||
let {
|
||||
priceSort
|
||||
} = this;
|
||||
this.saleSort = ''
|
||||
this.priceSort = priceSort == 'asc' ? 'desc' : 'asc'
|
||||
this.onRefresh();
|
||||
},
|
||||
|
||||
onSaleSort() {
|
||||
let {
|
||||
saleSort
|
||||
} = this;
|
||||
this.priceSort = ''
|
||||
this.saleSort = saleSort == 'desc' ? 'asc' : 'desc'
|
||||
this.onSearch();
|
||||
},
|
||||
|
||||
init(option) {
|
||||
let {
|
||||
id,
|
||||
name,
|
||||
type
|
||||
} = option;
|
||||
this.type = type;
|
||||
if (id) {
|
||||
uni.setNavigationBarTitle({
|
||||
title: name
|
||||
});
|
||||
this.id = id;
|
||||
this.getGoodsSearchFun();
|
||||
} else {
|
||||
uni.setNavigationBarTitle({
|
||||
title: '搜索'
|
||||
});
|
||||
this.showHistory = true
|
||||
}
|
||||
},
|
||||
|
||||
getSearchpageFun() {
|
||||
getSearchpage().then(res => {
|
||||
if (res.code == 1) {
|
||||
let {
|
||||
history_lists,
|
||||
hot_lists
|
||||
} = res.data;
|
||||
this.hotList = hot_lists
|
||||
this.historyList = history_lists
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onClear() {
|
||||
if (this.id) {
|
||||
this.onSearch();
|
||||
}
|
||||
},
|
||||
onSearch() {
|
||||
this.onRefresh()
|
||||
},
|
||||
onRefresh() {
|
||||
this.showHistory = false
|
||||
this.page = 1
|
||||
this.goodsList = []
|
||||
this.status = loadingType.LOADING
|
||||
this.$nextTick(() => {
|
||||
this.getGoodsSearchFun();
|
||||
});
|
||||
},
|
||||
|
||||
onChangeKeyword(item) {
|
||||
this.keyword = item
|
||||
this.showHistory = false
|
||||
this.onRefresh();
|
||||
},
|
||||
|
||||
async getGoodsSearchFun() {
|
||||
let {
|
||||
page,
|
||||
goodsList,
|
||||
keyword,
|
||||
priceSort,
|
||||
saleSort,
|
||||
status
|
||||
} = this;
|
||||
if (status == loadingType.FINISHED) return;
|
||||
const params = {
|
||||
category_id: this.type == 1 ? this.id : '',
|
||||
brand_id: this.type == 0 ? this.id : '',
|
||||
page_no: page,
|
||||
keyword,
|
||||
price: priceSort,
|
||||
sales_sum: saleSort
|
||||
}
|
||||
const data = await loadingFun(getGoodsSearch, page, goodsList, status, params)
|
||||
if (!data) return
|
||||
this.page = data.page
|
||||
this.goodsList = data.dataList
|
||||
this.status = data.status
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.goods-search {
|
||||
.header-wrap {
|
||||
.search {
|
||||
box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.03);
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.header {
|
||||
height: 80rpx;
|
||||
|
||||
.tag {
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.content {
|
||||
.search-words {
|
||||
padding-left: 24rpx;
|
||||
padding-bottom: 20rpx;
|
||||
|
||||
.title {
|
||||
padding: 26rpx 0;
|
||||
}
|
||||
|
||||
.words {
|
||||
.item {
|
||||
line-height: 52rpx;
|
||||
height: 52rpx;
|
||||
padding: 0 24rpx;
|
||||
background-color: #F5F5F5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.goods-list {
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,841 @@
|
||||
<template>
|
||||
<view class="index home-bg" :style="[navBackground]">
|
||||
<!-- #ifdef H5 -->
|
||||
<download-nav v-if="isShowDownload"></download-nav>
|
||||
<!-- #endif -->
|
||||
<u-sticky offset-top="0" h5-nav-height="0" bg-color="transparent" :enable="enable">
|
||||
<u-navbar
|
||||
:border-bottom="false"
|
||||
:is-fixed="false"
|
||||
custom-class="home-bg"
|
||||
:background="navBackground"
|
||||
:is-back="false"
|
||||
>
|
||||
<view class="row logo-wrap flex1" v-show="navBg < 1 && showLogo">
|
||||
<image :src="logo" mode="heightFix" class="logo ml30"></image>
|
||||
</view>
|
||||
<view class="flex1 row nav-search" v-show="navSearch">
|
||||
<navigator
|
||||
hover-class="none"
|
||||
@click="goPage('/bundle/pages/message_center/message_center')"
|
||||
>
|
||||
<image class="icon-md ml30" src="/static/images/icon_news.png"> </image>
|
||||
</navigator>
|
||||
<navigator
|
||||
class="ml20 flex1 mr20"
|
||||
hover-class="none"
|
||||
url="/pages/goods_search/goods_search"
|
||||
>
|
||||
<u-search
|
||||
wrap-bg-color="transparent"
|
||||
:bg-color="'#fff'"
|
||||
:disabled="true"
|
||||
:height="62"
|
||||
>
|
||||
</u-search>
|
||||
</navigator>
|
||||
</view>
|
||||
</u-navbar>
|
||||
</u-sticky>
|
||||
<view class="flex1 row" v-if="showLogo">
|
||||
<navigator
|
||||
hover-class="none"
|
||||
@tap="goPage('/bundle/pages/message_center/message_center')"
|
||||
>
|
||||
<image class="icon-md ml30" src="/static/images/icon_news.png"> </image>
|
||||
</navigator>
|
||||
<navigator
|
||||
class="ml20 flex1 mr20"
|
||||
hover-class="none"
|
||||
url="/pages/goods_search/goods_search"
|
||||
>
|
||||
<u-search
|
||||
wrap-bg-color="transparent"
|
||||
:bg-color="'#fff'"
|
||||
:disabled="true"
|
||||
:height="62"
|
||||
></u-search>
|
||||
</navigator>
|
||||
</view>
|
||||
<view class="contain">
|
||||
<view class="main">
|
||||
<bubble-tips top="50rpx" :discharge="isDischarge"></bubble-tips>
|
||||
<swipers :pid="1" height="322rpx" padding="20rpx 0"></swipers>
|
||||
<!-- 导航入口 -->
|
||||
<view class="nav bg-white" v-if="navList.length">
|
||||
<swiper :style="'height:' + navSwiperH + 'rpx;'" @change="swiperChange">
|
||||
<swiper-item v-for="(items, index) in navList" :key="index">
|
||||
<view class="nav-list row wrap">
|
||||
<view
|
||||
v-for="(item, index2) in items"
|
||||
:key="index2"
|
||||
@tap="tapMenu(item)"
|
||||
class="nav-item column-center"
|
||||
>
|
||||
<image class="nav-icon" :src="item.image"></image>
|
||||
<view class="name xs">{{ item.name }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<view class="dots" v-if="navList.length > 1">
|
||||
<view
|
||||
v-for="(item, index) in navList"
|
||||
:key="index"
|
||||
:class="'dot ' + (index == currentSwiper ? 'active' : '')"
|
||||
></view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 资讯 -->
|
||||
<navigator
|
||||
v-if="news.length"
|
||||
class="information bg-white row mt20"
|
||||
hover-class="none"
|
||||
open-type="navigate"
|
||||
url="/pages/news_list/news_list"
|
||||
>
|
||||
<image class="icon-toutiao" src="/static/images/icon_toutiao.png"></image>
|
||||
<text class="gap-line"></text>
|
||||
<view class="news flex1">
|
||||
<view class="shade"></view>
|
||||
<swiper
|
||||
autoplay="true"
|
||||
style="height: 76rpx; flex: 1"
|
||||
vertical="true"
|
||||
circular="true"
|
||||
:interval="3000"
|
||||
>
|
||||
<swiper-item v-for="(item, index) in news" :key="index" class="row">
|
||||
<view class="flexnone">
|
||||
<u-tag
|
||||
v-if="item.is_new"
|
||||
shape="circle"
|
||||
text="最新"
|
||||
size="mini"
|
||||
type="primary"
|
||||
mode="plain"
|
||||
/>
|
||||
</view>
|
||||
<view class="text-swiper ml10 line1">{{ item.title }}</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
<image class="icon-sm ml20" src="/static/images/arrow_right.png" />
|
||||
</navigator>
|
||||
<!-- 领卷 -->
|
||||
<swipers :is-swiper="false" :pid="23" height="170rpx" padding="20rpx 0 0"></swipers>
|
||||
<!-- 活动专区 -->
|
||||
<view class="special-area mt20">
|
||||
<view>
|
||||
<scroll-view style="white-space: nowrap" :scroll-x="true">
|
||||
<navigator
|
||||
class="item bg-white"
|
||||
v-for="(item, index) in activityArea"
|
||||
:key="index"
|
||||
hover-class="none"
|
||||
:url="`/bundle/pages/activity_detail/activity_detail?id=${item.id}&name=${item.title}&title=${item.name}`"
|
||||
>
|
||||
<view class="column-center">
|
||||
<custom-image
|
||||
width="300rpx"
|
||||
height="436rpx"
|
||||
:src="item.image"
|
||||
></custom-image>
|
||||
<!-- <view class="title xxl">{{item.name}}</view>
|
||||
<view class="desc primary xxs line1">{{item.title}}</view> -->
|
||||
</view>
|
||||
</navigator>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 秒杀 -->
|
||||
<view class="seckill mt20" v-if="seckillGoods.length">
|
||||
<active-area type="seckill" progressBarColor="#FF2C3C" :lists="seckillGoods">
|
||||
<navigator
|
||||
slot="header"
|
||||
hover-class="none"
|
||||
class="row activity-header white"
|
||||
open-type="navigate"
|
||||
url="/bundle/pages/goods_seckill/goods_seckill"
|
||||
>
|
||||
<view class="title xxl bold">超值秒杀</view>
|
||||
<view class="row flex1">
|
||||
<text class="white xs ml10 line1"
|
||||
>{{ seckill.start_time }}点场</text
|
||||
>
|
||||
<view class="dec ml20 row-center mr20 br60">
|
||||
<u-count-down
|
||||
:timestamp="remainTime"
|
||||
separator-color="#FF2C3C"
|
||||
color="#FF2C3C"
|
||||
:separator-size="24"
|
||||
:font-size="24"
|
||||
bg-color="transparent"
|
||||
></u-count-down>
|
||||
</view>
|
||||
</view>
|
||||
<view class="row xs">
|
||||
更多
|
||||
<u-icon name="arrow-right" size="28"></u-icon>
|
||||
</view>
|
||||
</navigator>
|
||||
</active-area>
|
||||
</view>
|
||||
<!-- 热销 -->
|
||||
<view class="hot mt20" v-if="hotGoods.length && seting.hots">
|
||||
<active-area type="hot" progressBarColor="#9912FE" :lists="hotGoods">
|
||||
<navigator
|
||||
slot="header"
|
||||
hover-class="none"
|
||||
class="row activity-header"
|
||||
open-type="navigate"
|
||||
url="/bundle/pages/hot_list/hot_list"
|
||||
>
|
||||
<view class="title flex1">
|
||||
<image
|
||||
class="title-image"
|
||||
src="/static/images/hot_title.png"
|
||||
></image>
|
||||
</view>
|
||||
<view class="row xs">
|
||||
更多
|
||||
<u-icon name="arrow-right" size="28"></u-icon>
|
||||
</view>
|
||||
</navigator>
|
||||
</active-area>
|
||||
</view>
|
||||
<!-- 新品推荐 -->
|
||||
<view v-if="newGoods.length && seting.news" class="new-goods">
|
||||
<active-area type="news" progressBarColor="#9912FE" :lists="newGoods">
|
||||
<navigator
|
||||
slot="header"
|
||||
hover-class="none"
|
||||
class="row activity-header"
|
||||
open-type="navigate"
|
||||
url=""
|
||||
>
|
||||
<view class="title flex1">
|
||||
<image
|
||||
class="title-image"
|
||||
src="/static/images/new_title.png"
|
||||
></image>
|
||||
</view>
|
||||
<!-- <view class="row xs">
|
||||
更多
|
||||
<u-icon name="arrow-right" size="28"></u-icon>
|
||||
</view> -->
|
||||
</navigator>
|
||||
</active-area>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 好物优选 -->
|
||||
<view class="goods mt20" v-if="goodsList.length">
|
||||
<view class="goods-title row-center">
|
||||
<text class="line"></text>
|
||||
<view class="row">
|
||||
<image class="mr10 icon" src="/static/images/icon_like.png"></image>
|
||||
<text class="bold xxl">好物优选</text>
|
||||
</view>
|
||||
<text class="line"></text>
|
||||
</view>
|
||||
<goods-list :list="goodsList"></goods-list>
|
||||
<loading-footer :status="status"></loading-footer>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<u-popup class="coupons-popup" v-model="showCoupop" mode="center">
|
||||
<view class="wrap">
|
||||
<image class="coupon-bg" src="/static/images/home_coupon_bg.png"></image>
|
||||
<scroll-view :scroll-y="true" style="height: 460rpx; margin-top: 300rpx">
|
||||
<view class="item" v-for="(item, index) in couponPopList" :key="item.id">
|
||||
<image class="img" src="/static/images/pop_bg_coupon.png"></image>
|
||||
<view class="row item-con">
|
||||
<view class="row-center price">
|
||||
<price-format
|
||||
color="#FF2C3C"
|
||||
:showSubscript="true"
|
||||
:subscriptSize="32"
|
||||
:first-size="56"
|
||||
:second-size="40"
|
||||
:price="item.money"
|
||||
/>
|
||||
</view>
|
||||
<view class="ml20 mr20">
|
||||
<view class="bold md lighter">{{ item.name }}</view>
|
||||
<view class="xs muted mt10">{{ item.use_goods_type }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<view class="white row-center bg-primary lg btn br60" @click="showCoupop = false"
|
||||
>立即领取</view
|
||||
>
|
||||
</u-popup>
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<lyg-popup
|
||||
v-if="appConfig.app_agreement"
|
||||
title="用户使用及隐私保护政策提示"
|
||||
protocolPath="/bundle/pages/server_explan/server_explan?type=0"
|
||||
policyPath="/bundle/pages/server_explan/server_explan?type=1"
|
||||
policyStorageKey="has_read_privacy"
|
||||
>
|
||||
</lyg-popup>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<!-- 用户隐私协议弹框 -->
|
||||
<privacy-popup v-model="showPrivacyPopup"></privacy-popup>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- 无网络提示 -->
|
||||
<u-no-network z-index="1200" @retry="handleRetry"></u-no-network>
|
||||
|
||||
<u-back-top
|
||||
:scroll-top="scrollTop"
|
||||
:top="1000"
|
||||
:customStyle="{
|
||||
backgroundColor: '#FFF',
|
||||
color: '#000',
|
||||
boxShadow: '0px 3px 6px rgba(0, 0, 0, 0.1)'
|
||||
}"
|
||||
></u-back-top>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapMutations, mapGetters, mapActions } from 'vuex'
|
||||
import { getHome, getMenu, getBestList } from '@/api/store'
|
||||
import { loadingType } from '@/utils/type'
|
||||
import { loadingFun, menuJump, arraySlice, setTabbar, getRect, trottle } from '@/utils/tools'
|
||||
import { toLogin } from '@/utils/login'
|
||||
import Cache from '@/utils/cache'
|
||||
import { getConfig, userShare, getRegisterCoupon } from '@/api/app'
|
||||
const app = getApp()
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
scrollTop: 0,
|
||||
navSwiperH: 374,
|
||||
logo: '',
|
||||
navHeight: 0,
|
||||
currentSwiper: 0,
|
||||
page: 1,
|
||||
status: loadingType.LOADING,
|
||||
remainTime: '',
|
||||
navBg: 0,
|
||||
navList: [],
|
||||
news: [],
|
||||
goodsList: [],
|
||||
seckill: {},
|
||||
seckillGoods: [],
|
||||
hotGoods: [],
|
||||
newGoods: [],
|
||||
activityArea: [],
|
||||
showCoupop: false,
|
||||
couponPopList: [],
|
||||
coupon: [],
|
||||
isDischarge: true,
|
||||
enable: true,
|
||||
isShowDownload: false,
|
||||
showPrivacyPopup: false //微信用户隐私协议
|
||||
}
|
||||
},
|
||||
async onLoad(options) {
|
||||
// #ifdef MP-WEIXIN
|
||||
if (wx.getPrivacySetting) {
|
||||
wx.getPrivacySetting({
|
||||
success: (res) => {
|
||||
console.log(res, '------') // 返回结果为: res = { needAuthorization: true/false, privacyContractName: '《xxx隐私保护指引》' }
|
||||
if (res.needAuthorization) {
|
||||
// 需要弹出隐私协议
|
||||
setTimeout(() => {
|
||||
uni.hideTabBar()
|
||||
}, 100)
|
||||
this.showPrivacyPopup = true
|
||||
} else {
|
||||
uni.showTabBar()
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
uni.showTabBar()
|
||||
console.log(err)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
uni.showTabBar()
|
||||
}
|
||||
|
||||
// #endif
|
||||
|
||||
this.headerAction = wx.createAnimation({
|
||||
delay: 0,
|
||||
duration: 100,
|
||||
timingFunction: 'ease-in-out'
|
||||
})
|
||||
this.onPageScroll = trottle(this.onPageScroll, 500, this)
|
||||
setTabbar()
|
||||
this.navHeight = app.globalData.navHeight
|
||||
this.isDischarge = false
|
||||
await this.getMenuFun()
|
||||
this.getBestListFun()
|
||||
console.log(this.appConfig)
|
||||
// #ifdef H5
|
||||
if (options && options.isapp == 1) {
|
||||
this.isShowDownload = true
|
||||
}
|
||||
// #endif
|
||||
},
|
||||
async onShow() {
|
||||
this.$nextTick(function () {
|
||||
getRect('.index').then((res) => {
|
||||
if (res.top == 0) {
|
||||
this.navBg = 0
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// #ifdef H5
|
||||
this.enable = true
|
||||
// #endif
|
||||
await this.getHomeFun()
|
||||
this.getCartNum()
|
||||
this.isLogin && this.getRegisterCouponFun()
|
||||
|
||||
// #ifdef MP
|
||||
wx.getUpdateManager().onUpdateReady(function () {
|
||||
wx.showModal({
|
||||
title: '更新提示',
|
||||
content: '新版本已经准备好,是否重启应用?',
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
|
||||
wx.getUpdateManager().applyUpdate()
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
onHide() {
|
||||
// #ifdef H5
|
||||
this.enable = false
|
||||
// #endif
|
||||
},
|
||||
onReachBottom() {
|
||||
this.getBestListFun()
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
this.getHomeFun()
|
||||
this.getMenuFun()
|
||||
},
|
||||
onShareAppMessage() {
|
||||
console.log(this.inviteCode)
|
||||
const shareInfo = Cache.get('shareInfo')
|
||||
return {
|
||||
title: shareInfo.mnp_share_title,
|
||||
path: 'pages/index/index?invite_code=' + this.inviteCode,
|
||||
imageUrl: shareInfo.mnp_share_image
|
||||
}
|
||||
},
|
||||
onPageScroll(e) {
|
||||
const top = uni.upx2px(100)
|
||||
const { scrollTop } = e
|
||||
if (!this.enable) return
|
||||
let percent = scrollTop / top
|
||||
this.navBg = percent > 1 ? 1 : percent
|
||||
this.scrollTop = scrollTop
|
||||
},
|
||||
destroyed() {
|
||||
this.isDischarge = true
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['SETCONFIG']),
|
||||
...mapActions(['getCartNum', 'getUser']),
|
||||
// 网络重试刷新网络请求(解决在ios中首次进入时需要授权蜂窝加载空白页面问题
|
||||
async handleRetry() {
|
||||
console.log('网络重试刷')
|
||||
try {
|
||||
const { code, data } = await getConfig()
|
||||
if (code == 1) {
|
||||
this.SETCONFIG(data)
|
||||
setTabbar()
|
||||
}
|
||||
} catch (e) {
|
||||
uni.showTabBar()
|
||||
}
|
||||
this.getShareInfo()
|
||||
this.getUser()
|
||||
},
|
||||
async getShareInfo() {
|
||||
const { code, data } = await userShare()
|
||||
if (code == 1) {
|
||||
Cache.set('shareInfo', data)
|
||||
}
|
||||
},
|
||||
async getHomeFun() {
|
||||
const { code, data } = await getHome()
|
||||
uni.stopPullDownRefresh()
|
||||
if (code == 1) {
|
||||
const { coupon, news, seckill, host_goods, shop_logo, new_goods, activity_area } =
|
||||
data
|
||||
this.remainTime = Math.abs(seckill.end_time - Date.parse(new Date()) / 1000)
|
||||
this.logo = shop_logo
|
||||
this.news = news
|
||||
this.seckillGoods = seckill.goods
|
||||
this.seckill = seckill
|
||||
this.hotGoods = host_goods
|
||||
this.coupon = coupon
|
||||
this.newGoods = new_goods
|
||||
this.activityArea = activity_area
|
||||
}
|
||||
},
|
||||
|
||||
async getMenuFun() {
|
||||
const { code, data } = await getMenu({
|
||||
type: 1
|
||||
})
|
||||
uni.stopPullDownRefresh()
|
||||
if (code == 1) {
|
||||
// 截取数组
|
||||
if (data.length <= 5) {
|
||||
this.navSwiperH = 200
|
||||
} else {
|
||||
this.navSwiperH = 374
|
||||
}
|
||||
this.navList = arraySlice(data)
|
||||
}
|
||||
},
|
||||
async getBestListFun() {
|
||||
let { page, goodsList, status } = this
|
||||
const data = await loadingFun(getBestList, page, goodsList, status)
|
||||
if (!data) return
|
||||
this.page = data.page
|
||||
this.goodsList = data.dataList
|
||||
this.status = data.status
|
||||
},
|
||||
async tapMenu(item) {
|
||||
if (!this.isLogin) return toLogin()
|
||||
menuJump(item)
|
||||
},
|
||||
goPage(url) {
|
||||
if (!this.isLogin) return toLogin()
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
},
|
||||
swiperChange(e) {
|
||||
this.currentSwiper = e.detail.current
|
||||
},
|
||||
getRegisterCouponFun() {
|
||||
getRegisterCoupon().then((res) => {
|
||||
if (res.code == 1) {
|
||||
if (res.data && res.data.length) {
|
||||
this.showCoupop = true
|
||||
}
|
||||
this.couponPopList = res.data
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['cartNum', 'inviteCode', 'appConfig']),
|
||||
navBackground() {
|
||||
return this.seting.top_bg_image
|
||||
? {
|
||||
'background-image': `url(${this.seting.top_bg_image})`
|
||||
}
|
||||
: {}
|
||||
},
|
||||
showLogo() {
|
||||
return this.seting.logo
|
||||
},
|
||||
navSearch() {
|
||||
if (this.showLogo === 0) return true
|
||||
|
||||
return this.navBg < 1 ? false : true
|
||||
},
|
||||
seting() {
|
||||
const { index_setting } = this.appConfig
|
||||
return index_setting
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
// #ifdef H5
|
||||
::v-deep .home-bg {
|
||||
background: url(../../static/images/bg_hometop.png) no-repeat;
|
||||
background-size: 100% auto;
|
||||
}
|
||||
|
||||
// #endif
|
||||
.home-bg {
|
||||
background: url(../../static/images/bg_hometop.png) no-repeat;
|
||||
background-size: 100% auto;
|
||||
}
|
||||
.index {
|
||||
.live-play {
|
||||
position: fixed;
|
||||
z-index: 999;
|
||||
bottom: 200rpx;
|
||||
right: 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border: $-solid-border;
|
||||
border-radius: 50%;
|
||||
font-size: 32rpx;
|
||||
background-color: #ffffff;
|
||||
|
||||
&__icon {
|
||||
animation: scale 0.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes scale {
|
||||
from {
|
||||
top: 0px;
|
||||
transform: scale(1);
|
||||
}
|
||||
to {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
background-size: 100% auto;
|
||||
|
||||
.logo-wrap {
|
||||
position: absolute;
|
||||
|
||||
.logo {
|
||||
width: auto;
|
||||
height: 52rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.header {
|
||||
.navigation-bar {
|
||||
padding-top: var(--status-bar-height);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
.contain {
|
||||
.main {
|
||||
position: relative;
|
||||
z-index: 9;
|
||||
padding: 0 20rpx;
|
||||
|
||||
.nav {
|
||||
position: relative;
|
||||
border-radius: 14rpx;
|
||||
|
||||
.nav-item {
|
||||
width: 20%;
|
||||
margin-top: 30rpx;
|
||||
|
||||
.nav-icon {
|
||||
width: 82rpx;
|
||||
height: 82rpx;
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.dots {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
bottom: 20rpx;
|
||||
display: flex;
|
||||
|
||||
.dot {
|
||||
width: 10rpx;
|
||||
height: 6rpx;
|
||||
border-radius: 6rpx;
|
||||
margin-right: 10rpx;
|
||||
background-color: rgba(255, 44, 60, 0.4);
|
||||
|
||||
&.active {
|
||||
width: 20rpx;
|
||||
background-color: $-color-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.information {
|
||||
height: 76rpx;
|
||||
box-shadow: 0px 0px 14px rgba(0, 0, 0, 0.06);
|
||||
padding: 0 20rpx;
|
||||
box-sizing: border-box;
|
||||
border-radius: 14rpx;
|
||||
|
||||
.news {
|
||||
position: relative;
|
||||
|
||||
.shade {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 100;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-toutiao {
|
||||
width: 114rpx;
|
||||
height: 34rpx;
|
||||
}
|
||||
|
||||
.gap-line {
|
||||
height: 28rpx;
|
||||
width: 1px;
|
||||
background-color: #dcdddc;
|
||||
margin: 0 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.special-area {
|
||||
.item {
|
||||
width: 300rpx;
|
||||
border-radius: 20rpx;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
margin-right: 20rpx;
|
||||
|
||||
.title {
|
||||
padding: 10rpx 0;
|
||||
}
|
||||
|
||||
.desc {
|
||||
background-color: #fee9eb;
|
||||
padding: 6rpx 20rpx;
|
||||
border-radius: 60rpx;
|
||||
max-width: 260rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.activity-header {
|
||||
height: 90rpx;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.seckill {
|
||||
.dec {
|
||||
background-color: #fffbdb;
|
||||
width: 150rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.hot,
|
||||
.new-goods {
|
||||
.title-image {
|
||||
width: 144rpx;
|
||||
height: 55rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.goods {
|
||||
.goods-title {
|
||||
height: 100rpx;
|
||||
|
||||
.line {
|
||||
width: 58rpx;
|
||||
height: 1px;
|
||||
background-color: #ccc;
|
||||
margin: 0 22rpx;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 38rpx;
|
||||
height: 38rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.coupon-pop-container {
|
||||
background-image: url(../../static/images/home_coupon_bg.png);
|
||||
width: 638rpx;
|
||||
height: 804rpx;
|
||||
background-size: 100% 100%;
|
||||
padding-top: 323rpx;
|
||||
|
||||
.coupon-pop-lists {
|
||||
.coupon-pop-item {
|
||||
background-image: url(../../static/images/pop_bg_coupon.png);
|
||||
width: 488rpx;
|
||||
height: 150rpx;
|
||||
background-size: 100% 100%;
|
||||
margin-top: 20rpx;
|
||||
|
||||
.coupon-left {
|
||||
width: 160rpx;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.coupon-right {
|
||||
padding-left: 30rpx;
|
||||
border-left: 1rpx dashed $-color-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.coupons-popup {
|
||||
.wrap {
|
||||
position: relative;
|
||||
width: 638rpx;
|
||||
height: 803rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.coupon-bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.item {
|
||||
position: relative;
|
||||
width: 488rpx;
|
||||
height: 150rpx;
|
||||
margin: 0 auto 20rpx;
|
||||
}
|
||||
|
||||
.img {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.item-con {
|
||||
z-index: 10;
|
||||
position: relative;
|
||||
padding: 20rpx 0;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.price {
|
||||
width: 160rpx;
|
||||
border-right: 1px dashed $-color-primary;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 478rpx;
|
||||
height: 84rpx;
|
||||
margin: 20rpx auto;
|
||||
box-sizing: border-box;
|
||||
border: 3px solid #f8d07c;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- pages/news_details/news_details.wxml -->
|
||||
<view class="news-details">
|
||||
<view class="header">
|
||||
<view class="title xxl mb20">{{ articleDetail.title }}</view>
|
||||
<view class="row-between">
|
||||
<view class="xs lighter">发布时间:{{ articleDetail.create_time }}</view>
|
||||
<view class="row">
|
||||
<view class="ml10 xs muted">{{ articleDetail.visit }}人浏览</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="main">
|
||||
<u-parse :html="article_content" :tag-style="tagStyle" />
|
||||
</view>
|
||||
</view>
|
||||
<loading-view v-if="showLoading"></loading-view>
|
||||
<!--<import src="/wxParse/wxParse.wxml"></import>-->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop开源商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
|
||||
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | likeshop团队版权所有并拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshop.cn.team
|
||||
// +----------------------------------------------------------------------
|
||||
import { getArticleDetail } from '../../api/new';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
showLoading: true,
|
||||
articleDetail: {},
|
||||
article_content: "",
|
||||
tagStyle: {
|
||||
img: 'width:100%;'
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
components: {
|
||||
},
|
||||
props: {},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
this.type = options.type || '';
|
||||
this.id = options.id;
|
||||
|
||||
if (this.type) {
|
||||
uni.setNavigationBarTitle({
|
||||
title: '帮助详情'
|
||||
});
|
||||
} else {
|
||||
uni.setNavigationBarTitle({
|
||||
title: '资讯详情'
|
||||
});
|
||||
}
|
||||
|
||||
this.getArticleDetailFun();
|
||||
},
|
||||
|
||||
|
||||
methods: {
|
||||
getArticleDetailFun() {
|
||||
getArticleDetail({
|
||||
type: this.type,
|
||||
id: this.id
|
||||
}).then(res => {
|
||||
if (res.code == 1) {
|
||||
this.articleDetail = res.data
|
||||
//wxParse.wxParse('content', 'html', res.data.content, this, 15)
|
||||
setTimeout(() => {
|
||||
this.article_content = res.data.content;
|
||||
}, 200);
|
||||
setTimeout(() => {
|
||||
this.showLoading = false
|
||||
}, 300);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
/* pages/news_details/news_details.wxss */
|
||||
page {
|
||||
background-color: #fff;
|
||||
}
|
||||
.news-details .header{
|
||||
padding: 20rpx 15px;
|
||||
border-bottom: var(--border);
|
||||
}
|
||||
.news-details .main {
|
||||
padding: 40rpx 15px;
|
||||
}
|
||||
.wxParse-p image {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,212 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- pages/news_list/news_list.wxml -->
|
||||
<view class="news_list">
|
||||
<view class="contain">
|
||||
<view class="banner" v-if="showAd">
|
||||
<!-- 存在就是10 不存在为7 -->
|
||||
<swipers :pid="type ? 10 : 7" height="300rpx" radius="0rpx"></swipers>
|
||||
</view>
|
||||
<tabs :active="active" @change="changeActive" v-if="categoryList.length">
|
||||
<tab title="全部"></tab>
|
||||
<tab v-for="(item, index) in categoryList" :key="index" :title="item.name" ></tab>
|
||||
</tabs>
|
||||
<view class="main">
|
||||
<view class="article-list">
|
||||
<view v-for="(item, index) in newsList" :key="index" :data-id="item.id" class="article-item bg-white" @tap="goPage">
|
||||
<view class="row">
|
||||
<view class="info">
|
||||
<view class="title lg line2 mb20">{{ item.title }}</view>
|
||||
<view class="lighter line2">
|
||||
<view>{{ item.synopsis }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<image width="240rpx" height="180rpx" lazy-load class="img ml20" :src="item.image" />
|
||||
</view>
|
||||
<view class="row-between mt20">
|
||||
<view class="xs muted">发布时间: {{item.create_time}}</view>
|
||||
<view class="row">
|
||||
<!-- <image class="icon-sm" src="/static/images/icon_see.png"></image> -->
|
||||
<view class="ml10 xs muted">{{ item.visit }}人浏览</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<loading-footer :status="status" slotEmpty>
|
||||
<view slot="empty" class="column-center" style="padding-top: 100rpx">
|
||||
<image class="img-null" src="/static/images/news_null.png"></image>
|
||||
<text class="nr muted">暂无数据~</text>
|
||||
</view>
|
||||
</loading-footer>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <loading-view v-if="showLoading"></loading-view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop开源商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
|
||||
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | likeshop团队版权所有并拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshop.cn.team
|
||||
// +----------------------------------------------------------------------
|
||||
import { getCategoryList, getArticleList } from '@/api/new';
|
||||
import { loadingType } from '@/utils/type';
|
||||
import {loadingFun} from '@/utils/tools'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
active: 0,
|
||||
showLoading: true,
|
||||
categoryList: [],
|
||||
newsList: [],
|
||||
page: 1,
|
||||
status: loadingType.LOADING,
|
||||
bannerList: [],
|
||||
type: 0,
|
||||
showAd: false
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
//分类id
|
||||
this.id = options.id; //type存在则为帮助中心
|
||||
|
||||
this.type = options.type || '';
|
||||
|
||||
if (this.type) {
|
||||
uni.setNavigationBarTitle({
|
||||
title: '帮助中心'
|
||||
});
|
||||
} else {
|
||||
uni.setNavigationBarTitle({
|
||||
title: '商城资讯'
|
||||
});
|
||||
}
|
||||
this.showAd = true
|
||||
this.getCategoryListFun();
|
||||
},
|
||||
|
||||
onReachBottom: function () {
|
||||
this.getArticleListFun();
|
||||
},
|
||||
|
||||
|
||||
methods: {
|
||||
changeActive(e) {
|
||||
this.active = e;
|
||||
this.page = 1;
|
||||
this.newsList = [];
|
||||
this.status = loadingType.LOADING
|
||||
setTimeout(() => {
|
||||
this.getArticleListFun();
|
||||
}, 100);
|
||||
},
|
||||
|
||||
getCategoryListFun() {
|
||||
getCategoryList({
|
||||
type: this.type
|
||||
}).then(res => {
|
||||
if (res.code == 1) {
|
||||
this.categoryList = res.data
|
||||
console.log(this.categoryList)
|
||||
this.getArticleListFun();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getArticleListFun() {
|
||||
let {
|
||||
active,
|
||||
page,
|
||||
newsList,
|
||||
status
|
||||
} = this;
|
||||
|
||||
// active是选中的分类索引,索引0是全部,索引1开始才是的分类列表的数据
|
||||
let id = active ? this.categoryList[active - 1].id : '';
|
||||
|
||||
loadingFun(getArticleList, page, newsList, status, {
|
||||
type: this.type,
|
||||
id,
|
||||
page_no: page}).then(res => {
|
||||
if(res) {
|
||||
this.page = res.page;
|
||||
this.newsList = res.dataList
|
||||
this.status = res.status
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
goPage(e) {
|
||||
let {
|
||||
id
|
||||
} = e.currentTarget.dataset;
|
||||
uni.navigateTo({
|
||||
url: `/pages/news_details/news_details?id=${id}&type=${this.type}`
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
/* pages/information/information.wxss */
|
||||
.news_list {
|
||||
.banner {
|
||||
|
||||
}
|
||||
.main {
|
||||
.article-list {
|
||||
padding-top: 20rpx;
|
||||
.article-item {
|
||||
padding: 20rpx;
|
||||
border-bottom: var(--border);
|
||||
align-items: flex-start;
|
||||
.info {
|
||||
flex: 1;
|
||||
}
|
||||
.img {
|
||||
width: 240rpx;
|
||||
height: 180rpx;
|
||||
flex: none;
|
||||
}
|
||||
}
|
||||
&:last-of-type {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.footer {
|
||||
padding: 30rpx 0;
|
||||
}
|
||||
}
|
||||
|
||||
page .van-tabs .van-tab--active {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
|
||||
.news_list .van-tab {
|
||||
width: 25%;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,788 @@
|
||||
// +---------------------------------------------------------------------- // |
|
||||
likeshop开源商城系统 //
|
||||
+---------------------------------------------------------------------- // |
|
||||
欢迎阅读学习系统程序代码,建议反馈是我们前进的动力 // |
|
||||
gitee下载:https://gitee.com/likeshop_gitee // |
|
||||
github下载:https://github.com/likeshop-github // |
|
||||
访问官网:https://www.likeshop.cn // | 访问社区:https://home.likeshop.cn // |
|
||||
访问手册:http://doc.likeshop.cn // | 微信公众号:likeshop技术社区 // |
|
||||
likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
|
||||
// |
|
||||
likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布 // |
|
||||
likeshop团队版权所有并拥有最终解释权 //
|
||||
+---------------------------------------------------------------------- // |
|
||||
author: likeshop.cn.team //
|
||||
+----------------------------------------------------------------------
|
||||
|
||||
<template>
|
||||
<view>
|
||||
<navbar title="订单详情"></navbar>
|
||||
<view class="order-details">
|
||||
<view class="header-bg"></view>
|
||||
<view class="main">
|
||||
<view class="header">
|
||||
<view class="item" v-if="orderDetail.order_status == 0">
|
||||
<view class="white lg mb10">等待买家付款</view>
|
||||
<view
|
||||
class="white sm row"
|
||||
style="line-height: 26rpx"
|
||||
v-if="cancelTime > 0"
|
||||
>支付剩余
|
||||
<u-count-down
|
||||
separator="zh"
|
||||
:timestamp="cancelTime"
|
||||
separator-color="#fff"
|
||||
color="#fff"
|
||||
:separator-size="26"
|
||||
:font-size="26"
|
||||
bg-color="transparent"
|
||||
></u-count-down>
|
||||
自动关闭</view
|
||||
>
|
||||
</view>
|
||||
<template v-if="orderDetail.delivery_type == 1">
|
||||
<view class="item" v-if="orderDetail.order_status == 1">
|
||||
<view class="white lg mb10">等待商家发货</view>
|
||||
<view class="white sm">您的商品正在打包中,请耐心等待…</view>
|
||||
</view>
|
||||
<view class="item" v-if="orderDetail.order_status == 2">
|
||||
<view class="white lg mb10">已发货</view>
|
||||
<view class="white sm">您的商品正在路中,请耐心等待…</view>
|
||||
</view>
|
||||
<view class="item" v-if="orderDetail.order_status == 3">
|
||||
<view class="white lg mb10">已完成</view>
|
||||
<view class="white sm">商品已签收,期待再次购买!</view>
|
||||
</view>
|
||||
<view class="item" v-if="orderDetail.order_status == 4">
|
||||
<view class="white lg mb10">订单已关闭</view>
|
||||
<!-- <view class="white sm">原因:超时未支付</view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<template v-if="orderDetail.delivery_type == 2">
|
||||
<view class="item" v-if="orderDetail.order_status == 1">
|
||||
<view class="white lg mb10">待取货</view>
|
||||
<view class="white sm">请前往指定门店取货</view>
|
||||
</view>
|
||||
<view class="item" v-if="orderDetail.order_status == 3">
|
||||
<view class="white lg mb10">已完成</view>
|
||||
<view class="white sm">交易已完成,感谢您的购买!</view>
|
||||
</view>
|
||||
<view class="item" v-if="orderDetail.order_status == 4">
|
||||
<view class="white lg mb10">订单已关闭</view>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
<!-- 快递配送 -->
|
||||
<view
|
||||
v-if="orderDetail.delivery_type == 1"
|
||||
class="receiving-card contain"
|
||||
@click="onAddressExpress"
|
||||
>
|
||||
<u-image
|
||||
class="icon-md mr20"
|
||||
width="44"
|
||||
height="44"
|
||||
src="/static/images/icon_address.png"
|
||||
mode="scaleToFill"
|
||||
/>
|
||||
<view class="receiving-content">
|
||||
<view class="md black bold">
|
||||
<text>{{ orderDetail.consignee }}</text>
|
||||
<text class="ml10">{{ orderDetail.mobile }}</text>
|
||||
</view>
|
||||
<view class="xs black mt10">{{
|
||||
orderDetail.delivery_address
|
||||
}}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 门店自提 -->
|
||||
<view
|
||||
v-if="orderDetail.delivery_type == 2"
|
||||
class="receiving-card contain"
|
||||
>
|
||||
<u-image
|
||||
class="icon-md mr20"
|
||||
width="44"
|
||||
height="44"
|
||||
src="/static/images/icon_address.png"
|
||||
mode="scaleToFill"
|
||||
/>
|
||||
<view class="receiving-content">
|
||||
<text class="md black bold">{{
|
||||
orderDetail.selffetch_shop.name
|
||||
}}</text>
|
||||
<text class="xs black mt10">{{
|
||||
orderDetail.selffetch_shop.shop_address
|
||||
}}</text>
|
||||
<text class="xs muted mt10">
|
||||
<text>营业时间:</text>
|
||||
<text
|
||||
>{{ orderDetail.selffetch_shop.business_start_time }} -
|
||||
{{ orderDetail.selffetch_shop.business_end_time }}</text
|
||||
>
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 扫码收货 -->
|
||||
<view v-if="orderDetail.delivery_type == 2" class="contain receive">
|
||||
<view v-if="orderDetail.verification_status" class="delivery--die">
|
||||
<u-image
|
||||
src="/static/images/delivery_die.png"
|
||||
width="134"
|
||||
height="98"
|
||||
mode="scaleFill"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="receive-qr" v-if="showQRSelffetch">
|
||||
<text class="xs lighter">请凭二维码取货</text>
|
||||
<view
|
||||
class="mt20 qr-contain"
|
||||
:class="{ 'qr-contain--die': orderDetail.verification_status }"
|
||||
ref="qr-image"
|
||||
>
|
||||
<tki-qrcode
|
||||
ref="qrcode"
|
||||
uni="px"
|
||||
:val="orderDetail.pickup_code"
|
||||
:size="118 * 2"
|
||||
:showLoading="false"
|
||||
/>
|
||||
</view>
|
||||
<view class="mt30 xs black qr-code"
|
||||
>提货码:{{ orderDetail.pickup_code }}</view
|
||||
>
|
||||
</view>
|
||||
|
||||
<view class="nr receive-info">
|
||||
<view class="receive-info-item">
|
||||
<text class="normal">提货人</text>
|
||||
<text class="black">{{ orderDetail.consignee }}</text>
|
||||
</view>
|
||||
<view class="receive-info-item">
|
||||
<text class="normal">联系方式</text>
|
||||
<text class="black">{{ orderDetail.mobile }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="goods contain" style="margin-bottom: 0">
|
||||
<view class="status row-between" v-if="team.status != null">
|
||||
<view>拼团状态</view>
|
||||
<view
|
||||
:style="
|
||||
'padding: 6rpx 26rpx; ' +
|
||||
(team.status == 2 && 'background-color: #d7d7d7')
|
||||
"
|
||||
class="bg-primary br60 white sm"
|
||||
>
|
||||
{{ teamStatus(team.status) }}
|
||||
</view>
|
||||
</view>
|
||||
<order-goods
|
||||
:team="team"
|
||||
:link="true"
|
||||
:list="orderDetail.order_goods"
|
||||
:order_type="orderDetail.order_type"
|
||||
></order-goods>
|
||||
</view>
|
||||
|
||||
<view class="price contain" style="border-radius: 0rpx 14rpx">
|
||||
<view class="row-between" v-if="priceShow">
|
||||
<view>商品总价</view>
|
||||
<view class="black">
|
||||
<price-format :price="orderDetail.goods_price"></price-format>
|
||||
</view>
|
||||
</view>
|
||||
<view class="row-between" v-if="priceShow">
|
||||
<view>运费</view>
|
||||
<view class="black"
|
||||
>+
|
||||
<price-format :price="orderDetail.shipping_price"></price-format>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
v-if="orderDetail.discount_amount != 0 && priceShow"
|
||||
class="row-between"
|
||||
>
|
||||
<view>优惠券</view>
|
||||
<view class="primary"
|
||||
>-
|
||||
<price-format :price="orderDetail.discount_amount"></price-format>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
v-if="orderDetail.integral_amount != 0 && priceShow"
|
||||
class="row-between"
|
||||
>
|
||||
<view>积分抵扣</view>
|
||||
<view class="primary"
|
||||
>-
|
||||
<price-format :price="orderDetail.integral_amount"></price-format>
|
||||
</view>
|
||||
</view>
|
||||
<view class="row-between">
|
||||
<view class="">
|
||||
<text v-if="orderDetail.order_status === 0">需</text>
|
||||
<text v-else>实</text>
|
||||
付款:
|
||||
</view>
|
||||
<view class="primary xl">
|
||||
<price-format
|
||||
:first-size="34"
|
||||
:second-size="34"
|
||||
:price="orderDetail.order_amount"
|
||||
>
|
||||
</price-format>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
class="row-center muted"
|
||||
style="padding: 40rpx 0"
|
||||
@click="priceShow = !priceShow"
|
||||
>
|
||||
<view>
|
||||
<text class="mr10" v-if="priceShow"> 收起 </text>
|
||||
<text class="mr10" v-else> 查看更多 </text>
|
||||
|
||||
<u-icon name="arrow-up" v-if="priceShow" />
|
||||
<u-icon name="arrow-down" v-else />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="order-info contain">
|
||||
<view class="item row" style="align-items: flex-start">
|
||||
<view class="title">买家留言</view>
|
||||
<view class="black">{{ orderDetail.user_remark || "无" }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="order-info contain">
|
||||
<view class="item row">
|
||||
<view class="title">订单编号</view>
|
||||
<view class="black">{{ orderDetail.order_sn }}</view>
|
||||
</view>
|
||||
<view class="item row">
|
||||
<view class="title">订单类型</view>
|
||||
<view class="black">{{ orderDetail.order_type_desc }}</view>
|
||||
</view>
|
||||
<view class="item row">
|
||||
<view class="title">支付方式</view>
|
||||
<view class="black">{{ orderDetail.pay_way_text }}</view>
|
||||
</view>
|
||||
<view class="item row">
|
||||
<view class="title">下单时间</view>
|
||||
<view class="black">{{ orderDetail.create_time }}</view>
|
||||
</view>
|
||||
<view v-if="orderDetail.pay_time" class="item row">
|
||||
<view class="title">付款时间</view>
|
||||
<view class="black">{{ orderDetail.pay_time }}</view>
|
||||
</view>
|
||||
<view v-if="orderDetail.shipping_time" class="item row">
|
||||
<view class="title">发货时间</view>
|
||||
<view class="black">{{ orderDetail.shipping_time }}</view>
|
||||
</view>
|
||||
<view v-if="orderDetail.confirm_take_time" class="item row">
|
||||
<view class="title">成交时间</view>
|
||||
<view class="black">{{ orderDetail.confirm_take_time }}</view>
|
||||
</view>
|
||||
<view v-if="orderDetail.cancel_time" class="item row">
|
||||
<view class="title">关闭时间</view>
|
||||
<view class="black">{{ orderDetail.cancel_time }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
class="footer bg-white row fixed"
|
||||
v-if="
|
||||
orderDetail.cancel_btn ||
|
||||
orderDetail.delivery_btn ||
|
||||
orderDetail.take_btn ||
|
||||
orderDetail.del_btn ||
|
||||
orderDetail.pay_btn
|
||||
"
|
||||
>
|
||||
<view style="flex: 1"></view>
|
||||
<view v-if="orderDetail.cancel_btn">
|
||||
<button
|
||||
size="sm"
|
||||
class="plain br60"
|
||||
hover-class="none"
|
||||
@tap="cancelOrder"
|
||||
>
|
||||
取消订单
|
||||
</button>
|
||||
</view>
|
||||
<navigator
|
||||
v-if="orderDetail.delivery_btn"
|
||||
hover-class="none"
|
||||
:url="
|
||||
'/bundle/pages/goods_logistics/goods_logistics?id=' +
|
||||
orderDetail.id
|
||||
"
|
||||
>
|
||||
<button size="sm" class="plain br60" hover-class="none">
|
||||
查看物流
|
||||
</button>
|
||||
</navigator>
|
||||
<view v-if="orderDetail.take_btn" class="ml20">
|
||||
<button
|
||||
size="sm"
|
||||
class="plain br60 primary red"
|
||||
hover-class="none"
|
||||
@tap.stop="comfirmOrder"
|
||||
>
|
||||
确认收货
|
||||
</button>
|
||||
</view>
|
||||
<view v-if="orderDetail.del_btn">
|
||||
<button
|
||||
size="sm"
|
||||
class="plain br60"
|
||||
hover-class="none"
|
||||
@tap="delOrder"
|
||||
>
|
||||
删除订单
|
||||
</button>
|
||||
</view>
|
||||
<view class="ml20" v-if="orderDetail.pay_btn">
|
||||
<button size="sm" class="bg-primary br60 white" @tap="payNow">
|
||||
立即付款
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<loading-view v-if="isFirstLoading"></loading-view>
|
||||
<order-dialog
|
||||
ref="orderDialog"
|
||||
:orderId="orderDetail.id"
|
||||
:type="type"
|
||||
@refresh="onRefresh"
|
||||
></order-dialog>
|
||||
<loading-view
|
||||
v-if="showLoading"
|
||||
background-color="transparent"
|
||||
:size="50"
|
||||
></loading-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getOrderDetail,
|
||||
getwechatSyncCheck,
|
||||
getwxReceiveDetail,
|
||||
confirmOrder,
|
||||
} from "@/api/order";
|
||||
import { compareWeChatVersion } from "@/utils/tools";
|
||||
|
||||
import { prepay } from "@/api/app";
|
||||
import { wxpay, alipay } from "@/utils/pay";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
orderDetail: {},
|
||||
team: {},
|
||||
isFirstLoading: true,
|
||||
type: 0,
|
||||
cancelTime: 0,
|
||||
showCancel: "",
|
||||
showLoading: false,
|
||||
imageQR: "",
|
||||
priceShow: false,
|
||||
};
|
||||
},
|
||||
|
||||
components: {},
|
||||
props: {},
|
||||
|
||||
onLoad: function (options) {
|
||||
this.id = options.id;
|
||||
this.getOrderDetailFun();
|
||||
},
|
||||
|
||||
onUnload() {
|
||||
uni.$off("payment");
|
||||
},
|
||||
|
||||
onShow() {
|
||||
this.getOrderDetailFun();
|
||||
},
|
||||
|
||||
methods: {
|
||||
onRefresh() {
|
||||
uni.$emit("refreshorder");
|
||||
const { type } = this;
|
||||
if ([0, 2].includes(type)) {
|
||||
this.getOrderDetailFun();
|
||||
} else if (type == 1) {
|
||||
setTimeout(() => {
|
||||
uni.navigateBack();
|
||||
}, 2000);
|
||||
}
|
||||
},
|
||||
orderDialog() {
|
||||
this.$refs.orderDialog.open();
|
||||
},
|
||||
|
||||
delOrder() {
|
||||
this.type = 1;
|
||||
this.$nextTick(async () => {
|
||||
this.orderDialog();
|
||||
});
|
||||
},
|
||||
// 小程序确认收货
|
||||
comfirmReceive(transaction_id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
wx.openBusinessView({
|
||||
businessType: "weappOrderConfirm",
|
||||
extraData: {
|
||||
transaction_id,
|
||||
},
|
||||
success({ extraData }) {
|
||||
if (extraData.status == "success") {
|
||||
resolve("确认收货");
|
||||
} else {
|
||||
resolve("取消收货");
|
||||
}
|
||||
},
|
||||
fail(err) {
|
||||
reject(err);
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
//查询是否收货成功
|
||||
querycomfirmReceive(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
getwechatSyncCheck({ id })
|
||||
.then(({ data }) => {
|
||||
if (data.order.order_state === 4) {
|
||||
resolve("已确认收货");
|
||||
} else {
|
||||
reject("未确认收货");
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
comfirmOrder() {
|
||||
this.type = 2;
|
||||
this.$nextTick(async () => {
|
||||
// #ifdef MP-WEIXIN
|
||||
let res = {};
|
||||
if (this.orderDetail.pay_way === 1) {
|
||||
res = await getwechatSyncCheck({ id: this.id });
|
||||
console.log(res);
|
||||
}
|
||||
if (
|
||||
compareWeChatVersion("2.6.0") === 1 &&
|
||||
wx.openBusinessView &&
|
||||
this.orderDetail.pay_way === 1 &&
|
||||
res.data.order.order_state !== 1
|
||||
) {
|
||||
try {
|
||||
const { data } = await getwxReceiveDetail({
|
||||
order_id: this.id,
|
||||
});
|
||||
await this.comfirmReceive(data.transaction_id);
|
||||
await this.querycomfirmReceive(this.id);
|
||||
await confirmOrder(this.id);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
this.getOrderDetailFun();
|
||||
} else {
|
||||
this.orderDialog();
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifndef MP-WEIXIN
|
||||
this.orderDialog();
|
||||
// #endif
|
||||
});
|
||||
},
|
||||
|
||||
cancelOrder() {
|
||||
this.type = 0;
|
||||
this.$nextTick(() => {
|
||||
this.orderDialog();
|
||||
});
|
||||
},
|
||||
|
||||
payNow() {
|
||||
uni.$on("payment", (params) => {
|
||||
setTimeout(() => {
|
||||
if (params.result) {
|
||||
this.$toast({
|
||||
title: "支付成功",
|
||||
});
|
||||
this.getOrderDetailFun();
|
||||
uni.$emit("refreshorder");
|
||||
} else {
|
||||
this.$toast({
|
||||
title: "支付失败",
|
||||
});
|
||||
}
|
||||
}, 500);
|
||||
});
|
||||
|
||||
uni.navigateTo({
|
||||
url: `/pages/payment/payment?from=${"order"}&order_id=${this.id}`,
|
||||
});
|
||||
},
|
||||
|
||||
getOrderDetailFun() {
|
||||
getOrderDetail(this.id)
|
||||
.then((res) => {
|
||||
if (res.code == 1) {
|
||||
this.cancelTime = res.data.order_cancel_time - Date.now() / 1000;
|
||||
this.orderDetail = res.data;
|
||||
this.team = res.data.team || {};
|
||||
this.$nextTick(() => {
|
||||
this.isFirstLoading = false;
|
||||
});
|
||||
} else {
|
||||
setTimeout(() => uni.navigateBack(), 1500);
|
||||
}
|
||||
return res.data;
|
||||
})
|
||||
.then((data) => {
|
||||
if (data.delivery_type === 2) {
|
||||
// 提货码
|
||||
this.$nextTick(function () {
|
||||
const refQR = this.$refs["qrcode"];
|
||||
refQR._makeCode();
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
showQRSelffetch() {
|
||||
let result = false;
|
||||
|
||||
if (this.orderDetail.order_status) {
|
||||
result = true;
|
||||
}
|
||||
|
||||
if (this.orderDetail.order_type == 2) {
|
||||
this.orderDetail.team_status == 1 ? (result = true) : (result = false);
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
teamStatus() {
|
||||
return (status) => {
|
||||
switch (status) {
|
||||
case 0:
|
||||
return "拼团中";
|
||||
case 1:
|
||||
return "拼团成功";
|
||||
case 2:
|
||||
return "拼团失败";
|
||||
}
|
||||
};
|
||||
},
|
||||
getOrderType() {
|
||||
return (type) => {
|
||||
switch (type) {
|
||||
case 0:
|
||||
return "普通订单";
|
||||
case 1:
|
||||
return "秒杀订单";
|
||||
case 2:
|
||||
return "拼团订单";
|
||||
case 3:
|
||||
return "砍价订单";
|
||||
}
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.order-details {
|
||||
position: relative;
|
||||
padding-bottom: calc(120rpx + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
.order-details .header-bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 200rpx;
|
||||
background-color: $-color-primary;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.order-details .goods .status {
|
||||
height: 88rpx;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.order-details .main {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.order-details .contain {
|
||||
margin: 0 20rpx 20rpx;
|
||||
border-radius: 14rpx;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.order-details .header {
|
||||
padding: 24rpx 40rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.order-details .img-line {
|
||||
height: 1.5px;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.order-details .address-wrap {
|
||||
height: 164rpx;
|
||||
padding: 0 24rpx;
|
||||
}
|
||||
|
||||
.order-details .order-info {
|
||||
padding: 12rpx 0;
|
||||
}
|
||||
|
||||
.order-details .order-info .item {
|
||||
padding: 12rpx 24rpx;
|
||||
}
|
||||
|
||||
.order-details .order-info .item .title {
|
||||
width: 180rpx;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.order-details .price > view {
|
||||
height: 60rpx;
|
||||
padding: 0 24rpx;
|
||||
}
|
||||
|
||||
.order-details .footer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 100rpx;
|
||||
padding: 0 24rpx;
|
||||
box-sizing: content-box;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
.footer .plain {
|
||||
border: 1px solid #bbbbbb;
|
||||
}
|
||||
|
||||
.footer .plain.red {
|
||||
border: 1px solid $-color-primary;
|
||||
}
|
||||
|
||||
.tips-dialog {
|
||||
height: 230rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.order-details .invite-btn {
|
||||
background: linear-gradient(270deg, #ff2c3c 0%, #f95f2f 100%);
|
||||
margin: 30rpx 26rpx 40rpx;
|
||||
}
|
||||
|
||||
.receiving-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 160rpx;
|
||||
padding: 20rpx;
|
||||
border-top: 1px solid #f2f2f2;
|
||||
}
|
||||
|
||||
.receiving-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.receive {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.delivery--die {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 30rpx;
|
||||
}
|
||||
|
||||
.receive-qr {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 460rpx;
|
||||
}
|
||||
|
||||
.qr-contain {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 140px;
|
||||
height: 140px;
|
||||
padding: 8px;
|
||||
border: 1px solid #cccccc;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.qr-contain--die {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.qr-contain--die::before {
|
||||
position: absolute;
|
||||
z-index: 99;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: block;
|
||||
content: "";
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.qr-code {
|
||||
padding: 8rpx 30rpx;
|
||||
border-radius: 60px;
|
||||
background-color: #f6f6f6;
|
||||
}
|
||||
|
||||
.receive-info {
|
||||
padding-left: 20rpx;
|
||||
}
|
||||
|
||||
.receive-info-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 100rpx;
|
||||
padding-right: 30rpx;
|
||||
}
|
||||
|
||||
.receive-info-item:nth-child(n + 2) {
|
||||
border-top: $-dashed-border;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,160 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop开源商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
|
||||
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | likeshop团队版权所有并拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshop.cn.team
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
<template>
|
||||
<view class="pay-result column-center">
|
||||
<view class="contain bg-white">
|
||||
<view class="header column-center">
|
||||
<view>
|
||||
<image class="tips-icon" src="/static/images/icon_paySuccess.png"></image>
|
||||
</view>
|
||||
<view class="xl mt20">订单支付成功</view>
|
||||
</view>
|
||||
<view style="height:181rpx"></view>
|
||||
<view class="info">
|
||||
<view class="order-num row-between mt20">
|
||||
<view class="ml20">订单编号</view>
|
||||
<view class="mr20">
|
||||
{{payInfo.order_sn}}
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="payInfo.pay_time" class="order-time row-between mt20">
|
||||
<view class="ml20">付款时间</view>
|
||||
<view class="mr20">{{payInfo.pay_time}}</view>
|
||||
</view>
|
||||
<view class="order-pay-type row-between mt20">
|
||||
<view class="ml20">支付方式</view>
|
||||
<view class="mr20">{{payInfo.pay_way_text}}</view>
|
||||
</view>
|
||||
<view class="order-pay-money row-between mt20">
|
||||
<view class="ml20">支付金额</view>
|
||||
<view class="mr20">
|
||||
<price-format :price="payInfo.order_amount"></price-format>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="line ml20"></view>
|
||||
<view class="opt-btn-contain row-center wrap">
|
||||
<navigator open-type="redirect" hover-class="none" class="check-order-btn row-center bg-primary br60 mt20" url="/pages/user_order/user_order">
|
||||
<view class="white bg-primary lg">查看订单</view>
|
||||
</navigator>
|
||||
<navigator hover-class="none" class="go-back-btn row-center br60 mt20" open-type="switchTab" url="/pages/index/index">
|
||||
<view class="primary br60 lg">返回首页</view>
|
||||
</navigator>
|
||||
</view>
|
||||
</view>
|
||||
<view class="xs muted" style="margin: 50rpx 0;">
|
||||
<view class="row-center">
|
||||
由 likeshop 提供免费开源商城系统
|
||||
</view>
|
||||
<view class="row-center">
|
||||
© likeshop.cn
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getOrderDetail
|
||||
} from '@/api/order';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
payInfo: {}
|
||||
};
|
||||
},
|
||||
|
||||
components: {
|
||||
|
||||
},
|
||||
props: {},
|
||||
onLoad: function(options) {
|
||||
this.id = options.id;
|
||||
this.getOrderResultFun();
|
||||
},
|
||||
|
||||
|
||||
methods: {
|
||||
getOrderResultFun() {
|
||||
getOrderDetail(this.id).then(res => {
|
||||
if (res.code == 1) {
|
||||
this.payInfo = res.data
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.pay-result {
|
||||
.contain {
|
||||
width: 682rpx;
|
||||
margin-left: 20rpx;
|
||||
margin-right: 20rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-top: 78rpx;
|
||||
padding-left: 20rpx;
|
||||
padding-right: 20rpx;
|
||||
padding-bottom: 40rpx;
|
||||
position: relative;
|
||||
|
||||
.tips-icon {
|
||||
width: 112rpx;
|
||||
height: 112rpx;
|
||||
}
|
||||
|
||||
.header {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
top: -50rpx;
|
||||
}
|
||||
|
||||
.order-num {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.info {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.opt-btn-contain {
|
||||
margin-top: 40rpx;
|
||||
|
||||
.check-order-btn {
|
||||
width: 650rpx;
|
||||
height: 84rpx;
|
||||
}
|
||||
|
||||
.go-back-btn {
|
||||
width: 650rpx;
|
||||
height: 84rpx;
|
||||
border:1px solid $-color-primary;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 650rpx;
|
||||
border-top: 1px solid rgba(229, 229, 229, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,340 @@
|
||||
<template>
|
||||
<view class="payment-pages">
|
||||
<view class="payment u-skeleton">
|
||||
<!-- Header -->
|
||||
<view class="payment-header">
|
||||
<price-format class="u-skeleton-fillet" :subscript-size="40" :first-size="56" :second-size="40"
|
||||
:price="amount" :weight="500" />
|
||||
<template v-if="timeout > 0">
|
||||
<view class="payment-count-down">
|
||||
<text>支付剩余时间</text>
|
||||
<u-count-down :timestamp="timeout" :font-size="22" />
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
<!-- Main -->
|
||||
<view class="payment-main">
|
||||
<view class="payway-container u-skeleton-fillet">
|
||||
<!-- Payway -->
|
||||
<u-radio-group v-model="payway" style="width: 100%;">
|
||||
<view class="payway">
|
||||
<view class="payway-item" v-for="(item, index) in paywayList" :key="item.id"
|
||||
@click="changePayway(item.pay_way)">
|
||||
<u-image :src="item.icon" width="48" height="48" mode="scaleToFill" />
|
||||
<view class="payway-item-content">
|
||||
<text class="payway-item-content-name">{{ item.name }}</text>
|
||||
<text class="payway-item-content-tips">{{ item.extra }}</text>
|
||||
</view>
|
||||
<u-radio shape="circle" :name="item.pay_way" :active-color="primaryColor" />
|
||||
</view>
|
||||
</view>
|
||||
</u-radio-group>
|
||||
<template v-if="!paywayList.length">
|
||||
<view class="payway-empty">暂无支付方式</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- Footer -->
|
||||
<view class="payment-footer u-skeleton-fillet">
|
||||
<view :class="['payment-submit', {'payment-submit--disabled': loadingPay}]" @tap="handlePrepay">
|
||||
<u-loading mode="circle" :show="loadingPay" />
|
||||
<text v-show="!loadingPay">立即支付</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
<u-skeleton :loading="loadingSkeleton" :animation="true" bgColor="#FFF" />
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
/**
|
||||
* @description 支付页面
|
||||
* @query {String} from 订单来源: order-商品订单; recharge-充值订单;
|
||||
* @query {Number} order_id 订单ID
|
||||
*/
|
||||
import {
|
||||
prepay,
|
||||
getPayway
|
||||
} from '@/api/app'
|
||||
import {
|
||||
wxpay,
|
||||
alipay
|
||||
} from '@/utils/pay'
|
||||
|
||||
export default {
|
||||
name: 'Payment',
|
||||
|
||||
data() {
|
||||
return {
|
||||
from: '', // 订单来源
|
||||
order_id: '', // 订单ID
|
||||
amount: 0, // 支付金额
|
||||
timeout: 0, // 倒计时间戳
|
||||
payway: '', // 支付方式
|
||||
paywayList: [], // 支付方式列表
|
||||
|
||||
loadingSkeleton: true, // 骨架屏Loading
|
||||
loadingPay: false, // 支付处理中Loading
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 更改支付方式
|
||||
changePayway(value) {
|
||||
this.$set(this, 'payway', value)
|
||||
},
|
||||
|
||||
// 初始化页面数据
|
||||
initPageData() {
|
||||
// 获取支付方式
|
||||
getPayway({
|
||||
from: this.from,
|
||||
order_id: this.order_id,
|
||||
}).then(res => {
|
||||
if (res.code != 1) throw new Error(res.msg)
|
||||
return res.data
|
||||
}).then(data => {
|
||||
this.loadingSkeleton = false
|
||||
this.amount = data.order_amount
|
||||
this.paywayList = data.pay
|
||||
this.payway = this.paywayList[0]?.pay_way
|
||||
// 倒计时
|
||||
const startTimestamp = new Date().getTime() / 1000
|
||||
const endTimestamp = data.cancel_time * 1
|
||||
this.timeout = endTimestamp - startTimestamp
|
||||
}).catch(err => {
|
||||
throw new Error(err)
|
||||
})
|
||||
},
|
||||
|
||||
// 预支付处理
|
||||
handlePrepay() {
|
||||
if (this.loadingPay) return
|
||||
this.loadingPay = true
|
||||
prepay({
|
||||
from: this.from,
|
||||
order_id: this.order_id,
|
||||
pay_way: this.payway,
|
||||
}).then(({
|
||||
code,
|
||||
data
|
||||
}) => {
|
||||
switch (code) {
|
||||
case 1:
|
||||
this.handleWechatPay(data);
|
||||
break;
|
||||
case 10001:
|
||||
this.handleAlipayPay(data);
|
||||
break;
|
||||
case 20001:
|
||||
this.handleWalletPay();
|
||||
break;
|
||||
}
|
||||
}).catch(err => {
|
||||
|
||||
}).finally(() => {
|
||||
setTimeout(() => {
|
||||
this.loadingPay = false
|
||||
}, 500)
|
||||
})
|
||||
},
|
||||
|
||||
// 微信支付
|
||||
handleWechatPay(data) {
|
||||
wxpay(data).then(res => {
|
||||
console.log(res)
|
||||
this.handPayResult(res)
|
||||
})
|
||||
},
|
||||
|
||||
// 支付宝支付
|
||||
handleAlipayPay(data) {
|
||||
alipay(data).then(res => {
|
||||
console.log(res)
|
||||
this.handPayResult(res)
|
||||
})
|
||||
},
|
||||
|
||||
// 钱包余额支付
|
||||
handleWalletPay() {
|
||||
console.log('支付成功')
|
||||
//余额支付成功
|
||||
this.handPayResult('success')
|
||||
},
|
||||
|
||||
// 支付后处理
|
||||
handPayResult(result) {
|
||||
switch (result) {
|
||||
case 'success':
|
||||
uni.$emit('payment', {
|
||||
result: true,
|
||||
order_id: this.order_id
|
||||
});
|
||||
break;
|
||||
case 'fail':
|
||||
default:
|
||||
uni.$emit('payment', {
|
||||
result: false,
|
||||
order_id: this.order_id
|
||||
})
|
||||
}
|
||||
// 页面出栈
|
||||
// uni.navigateBack()
|
||||
}
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
const from = options.from
|
||||
const order_id = options.order_id
|
||||
|
||||
try {
|
||||
if (!from && !order_id) throw new Error('页面参数有误')
|
||||
this.from = from
|
||||
this.order_id = order_id
|
||||
this.initPageData()
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
uni.navigateBack()
|
||||
}
|
||||
},
|
||||
|
||||
onUnload() {
|
||||
this.handPayResult('fail')
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.payment-pages {
|
||||
height: 100%;
|
||||
|
||||
.payment {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100% - env(safe-area-inset-bottom));
|
||||
|
||||
&-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 300rpx;
|
||||
background: linear-gradient(270deg, #FF2C3C 0%, #F95F2F 100%);
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
|
||||
&-main {
|
||||
flex: 1;
|
||||
margin-top: -40rpx;
|
||||
padding: 0 20rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
&-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100rpx;
|
||||
padding: 0 20rpx;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
.payway-container {
|
||||
padding: 0 20rpx;
|
||||
border-radius: 7px;
|
||||
background-color: #FFFFFF;
|
||||
|
||||
.payway-empty {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 20rpx 0;
|
||||
font-size: 26rpx;
|
||||
color: $-color-muted;
|
||||
}
|
||||
}
|
||||
|
||||
.payway {
|
||||
width: 100%;
|
||||
|
||||
&-item {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 120rpx;
|
||||
|
||||
&:nth-child(n+2) {
|
||||
border-top: $-dashed-border;
|
||||
}
|
||||
|
||||
&-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-left: 16rpx;
|
||||
|
||||
&-name {
|
||||
font-size: 28rpx;
|
||||
color: $-color-black;
|
||||
}
|
||||
|
||||
&-tips {
|
||||
font-size: 22rpx;
|
||||
color: $-color-muted;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-count-down {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 7rpx 25rpx;
|
||||
border-radius: 60px;
|
||||
margin-top: 10rpx;
|
||||
font-size: 22rpx;
|
||||
background-color: #FFFFFF;
|
||||
color: $-color-normal;
|
||||
}
|
||||
|
||||
&-submit {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 74rpx;
|
||||
font-size: 28rpx;
|
||||
border-radius: 60px;
|
||||
background: linear-gradient(270deg, #FF2C3C 0%, #F95F2F 100%);
|
||||
color: #FFFFFF;
|
||||
|
||||
&--disabled::before {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
display: block;
|
||||
content: "";
|
||||
background: rgba(255, 255, 255, .3) !important;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,402 @@
|
||||
<template>
|
||||
<view class="shop-cart">
|
||||
<view
|
||||
class="main"
|
||||
:style="{ 'padding-bottom': cartType == 1 ? '100rpx' : 0 }"
|
||||
>
|
||||
<view
|
||||
v-for="(item, index) in cartLists"
|
||||
:key="index"
|
||||
class="cart-list mb20"
|
||||
v-show="!(cartType != 1)"
|
||||
>
|
||||
<view
|
||||
class="cart-item bg-white"
|
||||
:class="{ invalid: item.cart_status != 0 }"
|
||||
>
|
||||
<view class="row-between select" v-if="item.cart_status == 0">
|
||||
<checkbox
|
||||
:value="item.cart_id + ''"
|
||||
:checked="item.selected == 1"
|
||||
@click="changOneSelect(item.cart_id, item.selected)"
|
||||
>选择</checkbox
|
||||
>
|
||||
<view
|
||||
:data-cartid="item.cart_id"
|
||||
@click="changeDelPopup(item.cart_id)"
|
||||
>
|
||||
<image class="icon-xl" src="/static/images/icon_del.png" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="select row-between sm muted" v-else>
|
||||
已失效
|
||||
<view
|
||||
:data-cartid="item.cart_id"
|
||||
@click="changeDelPopup(item.cart_id)"
|
||||
>
|
||||
<image class="icon-xl" src="/static/images/icon_del.png" />
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
class="row"
|
||||
style="padding: 20rpx"
|
||||
@tap="goPage"
|
||||
:data-url="'/pages/goods_details/goods_details?id=' + item.goods_id"
|
||||
>
|
||||
<custom-image
|
||||
width="180rpx"
|
||||
height="180rpx"
|
||||
radius="10rpx"
|
||||
class="goods-img mr20"
|
||||
lazy-load
|
||||
:src="item.img"
|
||||
/>
|
||||
<view class="info" style="flex: 1">
|
||||
<view class="line2 nr">{{ item.name }}</view>
|
||||
<view class="muted xs line1 mt10">
|
||||
{{ item.spec_value_str }}
|
||||
</view>
|
||||
<view class="row-between mt20">
|
||||
<view class="price row primary">
|
||||
<price-format
|
||||
:price="item.price"
|
||||
:firstSize="32"
|
||||
:secondSize="32"
|
||||
:showSubscript="true"
|
||||
:subscriptSize="32"
|
||||
></price-format>
|
||||
</view>
|
||||
<view class="cartNum" @tap.stop="">
|
||||
<u-number-box
|
||||
:disabled="item.cart_status != 0"
|
||||
:value="item.goods_num"
|
||||
:min="1"
|
||||
:max="item.item_stock"
|
||||
@change="countChange($event, item.cart_id, item)"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
class="cart-null column-center bg-white mb20"
|
||||
style="padding: 80rpx 0 50rpx"
|
||||
v-show="!(cartType != 2)"
|
||||
>
|
||||
<image class="img-null" src="/static/images/cart_null.png"></image>
|
||||
<view class="muted mb20">购物车暂无任何商品~</view>
|
||||
<navigator
|
||||
open-type="switchTab"
|
||||
url="/pages/index/index"
|
||||
hover-class="none"
|
||||
class="primary br60 btn row-center"
|
||||
>去逛逛</navigator
|
||||
>
|
||||
</view>
|
||||
<view v-if="!isLogin" class="login column-center">
|
||||
<image class="img-null" src="/static/images/cart_null.png"></image>
|
||||
<view class="muted mt20">登录后才能查看购物车哦</view>
|
||||
<navigator class="white br60 row-center btn" url="/pages/login/login">
|
||||
<!-- <image class="mr10" src="/static/images/icon_wechat.png"></image> -->
|
||||
<text>去登录</text>
|
||||
</navigator>
|
||||
</view>
|
||||
<recommend v-if="isShow"></recommend>
|
||||
</view>
|
||||
<view class="footer row bg-white" v-show="!(cartType != 1)">
|
||||
<checkbox-group class="row" @change="changeAllSelect">
|
||||
<checkbox id="checkAll" value="all" :checked="isSelectedAll"></checkbox>
|
||||
<label for="checkAll" class="ml10">全选</label>
|
||||
</checkbox-group>
|
||||
<view class="all-price lg mr20 row-end">
|
||||
<view>合计:</view>
|
||||
<view class="primary">¥{{ totalPrice || 0 }}</view>
|
||||
</view>
|
||||
<view
|
||||
class="right-btn br60 white"
|
||||
:style="' ' + (nullSelect ? 'background: #d7d7d7' : '')"
|
||||
@tap="goToConfirm"
|
||||
>去结算</view
|
||||
>
|
||||
</view>
|
||||
<u-modal
|
||||
v-model="delPopup"
|
||||
:showCancelButton="true"
|
||||
comfirm-text="狠心删除"
|
||||
confirm-color="#FF2C3C"
|
||||
:show-title="false"
|
||||
@confirm="goodsDelete"
|
||||
@cancel="changeDelPopup"
|
||||
>
|
||||
<view class="column-center tips-dialog" style="padding-top: 40rpx">
|
||||
<image class="icon-lg" src="/static/images/icon_warning.png" />
|
||||
<view style="margin: 30rpx 0">确认删除该商品吗?</view>
|
||||
</view>
|
||||
</u-modal>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getCartList,
|
||||
changeCartSelect,
|
||||
changeGoodsCount,
|
||||
deleteGoods,
|
||||
} from "@/api/store";
|
||||
import { getUser } from "@/api/user";
|
||||
import { mapGetters, mapActions } from "vuex";
|
||||
import Cache from "@/utils/cache";
|
||||
import { setTabbar } from "@/utils/tools";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
//购物车状态 1为有 2为空 0则什么都不显示
|
||||
cartType: 0,
|
||||
isShow: false,
|
||||
cartLists: [],
|
||||
delPopup: false,
|
||||
totalPrice: "",
|
||||
};
|
||||
},
|
||||
|
||||
components: {},
|
||||
computed: {
|
||||
...mapGetters(["cartNum"]),
|
||||
nullSelect() {
|
||||
let index = this.cartLists.findIndex(
|
||||
(item) => item.selected == 1 && item.cart_status == 0
|
||||
);
|
||||
|
||||
if (index == -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
isSelectedAll() {
|
||||
let index = this.cartLists.findIndex(
|
||||
(item) => item.selected == 0 && item.cart_status == 0
|
||||
);
|
||||
|
||||
if (index == -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
},
|
||||
onLoad() {
|
||||
setTabbar();
|
||||
},
|
||||
onShow() {
|
||||
this.isLogin && this.getCartListFun();
|
||||
},
|
||||
|
||||
onPullDownRefresh() {
|
||||
this.getCartListFun();
|
||||
},
|
||||
// onShareAppMessage() {
|
||||
// const shareInfo = Cache.get('shareInfo')
|
||||
// return {
|
||||
// title: shareInfo.mnp_share_title,
|
||||
// path: "pages/index/index?invite_code=" + this.userInfo.distribution_code
|
||||
// };
|
||||
// },
|
||||
methods: {
|
||||
...mapActions(["getCartNum"]),
|
||||
goodsDelete() {
|
||||
this.delPopup = false;
|
||||
deleteGoods({
|
||||
cart_id: this.cartId,
|
||||
}).then((res) => {
|
||||
if (res.code == 1) {
|
||||
this.getCartListFun();
|
||||
}
|
||||
});
|
||||
},
|
||||
changeDelPopup(cartId) {
|
||||
if (cartId) {
|
||||
this.cartId = cartId;
|
||||
}
|
||||
|
||||
this.delPopup = !this.delPopup;
|
||||
},
|
||||
|
||||
getCartListFun() {
|
||||
getCartList().then((res) => {
|
||||
uni.stopPullDownRefresh({
|
||||
success: (res) => {},
|
||||
});
|
||||
|
||||
if (res.code == 1) {
|
||||
let { lists, total_amount } = res.data;
|
||||
let cartType = 0;
|
||||
|
||||
if (lists.length == 0) {
|
||||
cartType = 2;
|
||||
} else {
|
||||
cartType = 1;
|
||||
}
|
||||
|
||||
this.cartLists = lists;
|
||||
this.cartType = cartType;
|
||||
this.totalPrice = total_amount;
|
||||
this.isShow = true;
|
||||
this.getCartNum();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
changOneSelect(cartId, selected) {
|
||||
selected = !selected;
|
||||
this.changeCartSelectFun([cartId], selected);
|
||||
},
|
||||
|
||||
// 更改全选状态
|
||||
changeAllSelect() {
|
||||
const { isSelectedAll, cartLists } = this;
|
||||
console.log(cartLists, "###");
|
||||
let cartid = cartLists.map((item) => item.cart_id);
|
||||
this.changeCartSelectFun(cartid, !isSelectedAll);
|
||||
},
|
||||
|
||||
changeCartSelectFun(cartId, selected) {
|
||||
console.log("selected ", selected);
|
||||
changeCartSelect({
|
||||
cart_id: cartId,
|
||||
selected: selected ? 1 : 0,
|
||||
}).then((res) => {
|
||||
if (res.code == 1) {
|
||||
this.getCartListFun();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
countChange({ value }, cartId, item) {
|
||||
console.log("countChange", value, cartId, item);
|
||||
changeGoodsCount({
|
||||
cart_id: cartId,
|
||||
goods_num: value,
|
||||
}).then((res) => {
|
||||
if (res.code == 1) {
|
||||
this.getCartListFun();
|
||||
} else {
|
||||
this.getCartListFun();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
goToConfirm() {
|
||||
let { cartLists } = this;
|
||||
let goods = [];
|
||||
cartLists.forEach((item) => {
|
||||
if (item.selected && item.cart_status == 0) {
|
||||
goods.push({
|
||||
item_id: item.item_id,
|
||||
num: item.goods_num,
|
||||
});
|
||||
}
|
||||
});
|
||||
if (goods.length == 0)
|
||||
return this.$toast({
|
||||
title: "您还没有选择商品哦",
|
||||
});
|
||||
uni.navigateTo({
|
||||
url:
|
||||
"/pages/confirm_order/confirm_order?data=" +
|
||||
encodeURIComponent(
|
||||
JSON.stringify({
|
||||
goods,
|
||||
type: "cart",
|
||||
})
|
||||
),
|
||||
});
|
||||
},
|
||||
|
||||
goPage(e) {
|
||||
const { url } = e.currentTarget.dataset;
|
||||
uni.navigateTo({
|
||||
url,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.shop-cart {
|
||||
.main {
|
||||
padding-bottom: 100rpx;
|
||||
}
|
||||
|
||||
.cart-list {
|
||||
.cart-item {
|
||||
margin: 20rpx 20rpx 0;
|
||||
border-radius: 10rpx;
|
||||
// &.invalid {
|
||||
// background-color: $-color-body;
|
||||
// }
|
||||
}
|
||||
|
||||
.select {
|
||||
height: 80rpx;
|
||||
padding: 0 20rpx;
|
||||
border-bottom: $-solid-border;
|
||||
}
|
||||
}
|
||||
|
||||
.cart-null {
|
||||
.btn {
|
||||
border: 1px solid $-color-primary;
|
||||
width: 184rpx;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding: 8rpx 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: fixed;
|
||||
padding: 0 24rpx;
|
||||
width: 100%;
|
||||
height: 100rpx;
|
||||
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.1);
|
||||
bottom: var(--window-bottom);
|
||||
box-sizing: border-box;
|
||||
z-index: 20;
|
||||
|
||||
.all-price {
|
||||
text-align: right;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.right-btn {
|
||||
padding: 13rpx 45rpx;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(249, 95, 47, 1) 0%,
|
||||
rgba(255, 44, 60, 1) 100%
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
.login {
|
||||
height: calc(100vh - var(--window-bottom));
|
||||
background: #fff;
|
||||
text-align: center;
|
||||
|
||||
.btn {
|
||||
background-color: #09bb07;
|
||||
width: 280rpx;
|
||||
line-height: 70rpx;
|
||||
margin: 40rpx auto 0;
|
||||
|
||||
image {
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<view class="sort">
|
||||
<navigator class="header" hover-class="none" url="/pages/goods_search/goods_search">
|
||||
<u-search bg-color="#F4F4F4" :disabled="true"></u-search>
|
||||
</navigator>
|
||||
<view class="content">
|
||||
<cate-one v-if="appConfig.cate_style == 2" :list="cateList"></cate-one>
|
||||
<cate-two v-if="appConfig.cate_style == 3" :list="cateList"></cate-two>
|
||||
<cate-three v-if="appConfig.cate_style == 4" :list="cateList"></cate-three>
|
||||
<cate-four v-if="appConfig.cate_style == 1" :list="cateList"></cate-four>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getCatrgory
|
||||
} from '@/api/store';
|
||||
import {
|
||||
getRect,
|
||||
setTabbar
|
||||
} from '@/utils/tools';
|
||||
import {
|
||||
mapGetters,
|
||||
mapActions
|
||||
} from 'vuex'
|
||||
import Cache from '@/utils/cache'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
cateList: []
|
||||
};
|
||||
},
|
||||
|
||||
components: {},
|
||||
onLoad(options) {
|
||||
setTabbar()
|
||||
this.getCatrgoryFun();
|
||||
},
|
||||
onShow() {
|
||||
this.getCartNum()
|
||||
},
|
||||
onShareAppMessage() {
|
||||
const shareInfo = Cache.get('shareInfo')
|
||||
return {
|
||||
title: shareInfo.mnp_share_title,
|
||||
path: "pages/index/index?invite_code=" + this.inviteCode,
|
||||
imageUrl: shareInfo.mnp_share_image,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['getCartNum']),
|
||||
getCatrgoryFun() {
|
||||
getCatrgory().then(res => {
|
||||
if (res.code == 1) {
|
||||
this.cateList = res.data
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["cartNum", "inviteCode", "appConfig"])
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
$header-height: 94rpx;
|
||||
$nav-height: 80rpx;
|
||||
page {
|
||||
|
||||
|
||||
.sort {
|
||||
.header {
|
||||
box-sizing: border-box;
|
||||
height: $header-height;
|
||||
border-bottom: $-solid-border;
|
||||
|
||||
.search {
|
||||
flex: 1;
|
||||
height: 60rpx;
|
||||
|
||||
input {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.content {
|
||||
height: calc(100vh - #{$header-height} - var(--window-top) - var(--window-bottom));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,435 @@
|
||||
<template>
|
||||
<view class="user" :style="[background]">
|
||||
<view class="header">
|
||||
<!-- #ifndef H5 -->
|
||||
<u-sticky offset-top="0" h5-nav-height="0" bg-color="transparent">
|
||||
<u-navbar
|
||||
:is-back="false"
|
||||
title="个人中心"
|
||||
:title-bold="true"
|
||||
:is-fixed="false"
|
||||
:border-bottom="false"
|
||||
:background="{ background: 'rgba(256,256, 256,' + navBg + ')' }"
|
||||
:title-color="navBg > 0.5 ? '#000' : '#fff'"
|
||||
></u-navbar>
|
||||
</u-sticky>
|
||||
<!-- #endif -->
|
||||
<view class="user-info row-between">
|
||||
<view class="info row">
|
||||
<image
|
||||
class="avatar mr20 flexnone"
|
||||
@tap="goLogin"
|
||||
:src="isLogin ? userInfo.avatar : '/static/images/my_portrait_empty.png'"
|
||||
></image>
|
||||
<view class="white" v-if="isLogin">
|
||||
<view class="name xxl line1">{{ userInfo.nickname }}</view>
|
||||
<view class="user-id row-between" v-if="userInfo.sn">
|
||||
<view class="xs white ml20 mr20">会员ID: {{ userInfo.sn || '' }}</view>
|
||||
<view class="xs normal copy-btn row-center ml5" @tap.stop="onCopy"
|
||||
>复制</view
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
<view class="white" v-else @tap="goLogin">
|
||||
<view style="font-size: 42rpx">点击登录</view>
|
||||
<view class="sm">登录体验更多功能</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="row" style="align-self: flex-start">
|
||||
<view
|
||||
class="user-opt"
|
||||
style="margin-right: 30rpx"
|
||||
@tap="goPage('/bundle/pages/message_center/message_center')"
|
||||
>
|
||||
<view class="dot row-center" v-if="userInfo.notice_num"></view>
|
||||
<image
|
||||
style="width: 58rpx; height: 58rpx"
|
||||
src="/static/images/icon_my_news.png"
|
||||
></image>
|
||||
</view>
|
||||
<view class="user-opt" @tap="goPage('/bundle/pages/user_profile/user_profile')">
|
||||
<image
|
||||
style="width: 58rpx; height: 58rpx"
|
||||
src="/static/images/icon_my_setting.png"
|
||||
></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="member column-end" @tap="goPage('/pages/user_vip/user_vip')">
|
||||
<view class="member-entery row-between">
|
||||
<view class="row">
|
||||
<image class="icon-md" src="/static/images/icon_member.png"></image>
|
||||
<view class="ml10">{{
|
||||
isLogin ? userInfo.level : '登录查看会员权益'
|
||||
}}</view>
|
||||
</view>
|
||||
<view class="row">
|
||||
<view class="sm">{{ userInfo.next_level_tips || '查看会员权益' }}</view>
|
||||
<u-icon name="arrow-right"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="my-assets bg-white">
|
||||
<view class="title row lg">我的资产</view>
|
||||
<view class="nav row">
|
||||
<view
|
||||
class="column-center mb20 assets-item"
|
||||
@tap="goPage('/bundle/pages/user_wallet/user_wallet')"
|
||||
>
|
||||
<view class="xl primary">{{ userInfo.user_money }}</view>
|
||||
<view class="sm">余额</view>
|
||||
</view>
|
||||
<view
|
||||
class="column-center mb20 assets-item"
|
||||
@tap="goPage('/bundle/pages/user_sign/user_sign')"
|
||||
>
|
||||
<view class="xl primary">{{ userInfo.user_integral }}</view>
|
||||
<view class="sm">积分</view>
|
||||
</view>
|
||||
<view
|
||||
class="column-center mb20 assets-item"
|
||||
@tap="goPage('/pages/user_coupon/user_coupon')"
|
||||
>
|
||||
<view class="xl primary">{{ userInfo.coupon }}</view>
|
||||
<view class="sm">优惠券</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="order-nav bg-white">
|
||||
<view class="title row-between" @tap="goPage('/pages/user_order/user_order')">
|
||||
<view class="lg">我的订单</view>
|
||||
<view class="muted sm row">
|
||||
全部订单
|
||||
<image class="icon-sm ml10" src="/static/images/arrow_right.png"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="nav row">
|
||||
<view
|
||||
class="item column-center mb20"
|
||||
@tap="goPage('/pages/user_order/user_order?type=pay')"
|
||||
>
|
||||
<view class="icon-contain">
|
||||
<view v-if="userInfo.wait_pay" class="badge xs row-center bg-white">
|
||||
{{ userInfo.wait_pay }}
|
||||
</view>
|
||||
<image class="nav-icon" src="/static/images/icon_my_payment.png"></image>
|
||||
</view>
|
||||
<view class="sm mt10">待付款</view>
|
||||
</view>
|
||||
<view
|
||||
class="item column-center mb20"
|
||||
@tap="goPage('/pages/user_order/user_order?type=delivery')"
|
||||
>
|
||||
<view class="icon-contain">
|
||||
<view v-if="userInfo.wait_delivery" class="badge xs row-center bg-white">
|
||||
{{ userInfo.wait_delivery }}
|
||||
</view>
|
||||
<image class="nav-icon mb10" src="/static/images/icon_my_fahuo.png"></image>
|
||||
</view>
|
||||
<view class="sm">待发货</view>
|
||||
</view>
|
||||
<view
|
||||
class="item column-center mb20"
|
||||
@tap="goPage('/pages/user_order/user_order?type=delivery')"
|
||||
>
|
||||
<view class="icon-contain">
|
||||
<view v-if="userInfo.wait_take" class="badge xs row-center bg-white">
|
||||
{{ userInfo.wait_take }}
|
||||
</view>
|
||||
<image class="nav-icon" src="/static/images/icon_my_shouhuo.png"></image>
|
||||
</view>
|
||||
<view class="sm mt10">待收货</view>
|
||||
</view>
|
||||
<view
|
||||
class="item column-center mb20"
|
||||
@tap="goPage('/bundle/pages/goods_comment_list/goods_comment_list')"
|
||||
>
|
||||
<view class="icon-contain">
|
||||
<view v-if="userInfo.wait_comment" class="badge xs row-center bg-white">
|
||||
{{ userInfo.wait_comment }}
|
||||
</view>
|
||||
<image class="nav-icon" src="/static/images/icon_my_pingjia.png"></image>
|
||||
</view>
|
||||
<view class="sm mt10">商品评价</view>
|
||||
</view>
|
||||
<view
|
||||
class="item column-center mb20"
|
||||
@tap="goPage('/bundle/pages/post_sale/post_sale')"
|
||||
>
|
||||
<view class="icon-contain">
|
||||
<view v-if="userInfo.after_sale" class="badge xs row-center bg-white">
|
||||
{{ userInfo.after_sale }}
|
||||
</view>
|
||||
<image class="nav-icon" src="/static/images/icon_my_shouhou.png"></image>
|
||||
</view>
|
||||
<view class="sm mt10">退款/售后</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="server-nav bg-white" v-if="menuList && menuList.length > 0">
|
||||
<view>
|
||||
<view class="title row-between">
|
||||
<view class="lg">我的功能</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="nav row wrap">
|
||||
<button
|
||||
v-for="(item, index) in menuList"
|
||||
:key="index"
|
||||
class="item column-center mb20"
|
||||
hover-class="none"
|
||||
:open-type="item.link_type == 3 ? 'contact' : ''"
|
||||
@tap="tapMenu(item)"
|
||||
style="width: 25%"
|
||||
>
|
||||
<image class="nav-icon" :src="item.image"></image>
|
||||
<view class="sm mt10">{{ item.name }}</view>
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
<recommend />
|
||||
<view class="xs muted" style="margin: 50rpx 0;">
|
||||
<view class="row-center">
|
||||
由 likeshop 提供免费开源商城系统
|
||||
</view>
|
||||
<view class="row-center">
|
||||
© likeshop.cn
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters, mapActions } from 'vuex'
|
||||
import { getUser } from '@/api/user'
|
||||
import { getMenu } from '@/api/store'
|
||||
import { toLogin, wxMnpLogin } from '@/utils/login'
|
||||
import { menuJump, copy, setTabbar } from '@/utils/tools'
|
||||
import Cache from '@/utils/cache'
|
||||
const app = getApp()
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
showNav: false,
|
||||
navH: 0,
|
||||
navBg: 0,
|
||||
menuList: [],
|
||||
statusBarH: ''
|
||||
}
|
||||
},
|
||||
|
||||
components: {},
|
||||
props: {},
|
||||
|
||||
onLoad(options) {
|
||||
setTabbar()
|
||||
this.getMenuFun()
|
||||
},
|
||||
|
||||
onShow() {
|
||||
this.getUser()
|
||||
this.getCartNum()
|
||||
},
|
||||
onPageScroll(e) {
|
||||
const top = uni.upx2px(100)
|
||||
const { scrollTop } = e
|
||||
let percent = scrollTop / top > 1 ? 1 : scrollTop / top
|
||||
this.navBg = percent
|
||||
},
|
||||
|
||||
onUnload() {},
|
||||
onPullDownRefresh() {
|
||||
this.getUser().then(() => {
|
||||
uni.stopPullDownRefresh()
|
||||
})
|
||||
this.getMenuFun()
|
||||
},
|
||||
onShareAppMessage() {
|
||||
const shareInfo = Cache.get('shareInfo')
|
||||
return {
|
||||
title: shareInfo.mnp_share_title,
|
||||
path: 'pages/index/index?invite_code=' + this.inviteCode,
|
||||
imageUrl: shareInfo.mnp_share_image
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['getCartNum', 'getUser']),
|
||||
goLogin() {
|
||||
let { isLogin } = this
|
||||
if (isLogin) {
|
||||
uni.navigateTo({
|
||||
url: '/bundle/pages/user_set/user_set'
|
||||
})
|
||||
return
|
||||
}
|
||||
toLogin()
|
||||
},
|
||||
|
||||
goPage(url) {
|
||||
if (!this.isLogin) return toLogin()
|
||||
uni.navigateTo({
|
||||
url
|
||||
})
|
||||
},
|
||||
tapMenu(item) {
|
||||
if (!this.isLogin) return toLogin()
|
||||
console.log(item)
|
||||
menuJump(item)
|
||||
},
|
||||
async getMenuFun() {
|
||||
const { data, code } = await getMenu({
|
||||
type: 2
|
||||
})
|
||||
if (code == 1) {
|
||||
this.menuList = data
|
||||
}
|
||||
},
|
||||
|
||||
onCopy(e) {
|
||||
copy(this.userInfo.sn)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['cartNum', 'userInfo', 'inviteCode', 'appConfig']),
|
||||
background() {
|
||||
const { center_setting } = this.appConfig
|
||||
return center_setting.top_bg_image
|
||||
? {
|
||||
'background-image': `url(${center_setting.top_bg_image})`
|
||||
}
|
||||
: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.user {
|
||||
background-image: url(../../static/images/my_topbg.png);
|
||||
background-size: 100% 420rpx;
|
||||
background-repeat: no-repeat;
|
||||
.header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 420rpx;
|
||||
.user-info {
|
||||
padding: 10rpx 30rpx;
|
||||
//#ifdef H5
|
||||
padding-top: 90rpx;
|
||||
//#endif
|
||||
.avatar {
|
||||
height: 110rpx;
|
||||
width: 110rpx;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.name {
|
||||
text-align: left;
|
||||
margin-bottom: 5rpx;
|
||||
max-width: 400rpx;
|
||||
}
|
||||
|
||||
.user-id {
|
||||
border: 1px solid white;
|
||||
border-radius: 100rpx;
|
||||
|
||||
.copy-btn {
|
||||
background-color: #ffdfda;
|
||||
height: 40rpx;
|
||||
width: 90rpx;
|
||||
border-radius: 100rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.user-opt {
|
||||
position: relative;
|
||||
|
||||
.dot {
|
||||
position: absolute;
|
||||
background-color: #ee0a24;
|
||||
border: 2rpx solid #ffffff;
|
||||
color: $-color-primary;
|
||||
border-radius: 100%;
|
||||
top: 6rpx;
|
||||
right: 0rpx;
|
||||
font-size: 22rpx;
|
||||
min-width: 16rpx;
|
||||
height: 16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.buyer-type {
|
||||
background-color: #ffa200;
|
||||
height: 38rpx;
|
||||
padding: 0 10rpx;
|
||||
}
|
||||
}
|
||||
.member {
|
||||
flex: 1;
|
||||
padding: 0 20rpx;
|
||||
.member-entery {
|
||||
color: #ffe0a1;
|
||||
padding: 0 16rpx;
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
background: url(../../static/images/bg_member_grade.png);
|
||||
background-size: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.order-nav {
|
||||
.icon-contain {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.order-nav,
|
||||
.my-assets {
|
||||
margin: 20rpx 20rpx 0;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.server-nav {
|
||||
margin: 20rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
height: 88rpx;
|
||||
padding: 0 30rpx;
|
||||
border-bottom: $-dashed-border;
|
||||
}
|
||||
|
||||
.nav {
|
||||
padding: 26rpx 0 0;
|
||||
|
||||
.assets-item {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.item {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.badge {
|
||||
padding: 0 6rpx;
|
||||
min-width: 28rpx;
|
||||
height: 28rpx;
|
||||
border-radius: 28rpx;
|
||||
box-sizing: border-box;
|
||||
border: 1rpx solid $-color-primary;
|
||||
color: $-color-primary;
|
||||
position: absolute;
|
||||
left: 33rpx;
|
||||
top: -10rpx;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.nav-icon {
|
||||
width: 52rpx;
|
||||
height: 52rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,306 @@
|
||||
<template>
|
||||
<!-- pages/user_address/user_address.wxml -->
|
||||
<view class="user-address">
|
||||
<view class="no-address column-center" v-if="!hasAddress">
|
||||
<image class="img-null mt20" src="/static/images/address_null.png"></image>
|
||||
<view class="sm muted">暂无添加地址,请添加~</view>
|
||||
</view>
|
||||
<view class="address-list" v-else>
|
||||
<radio-group class="radio-group" @change="radioChange">
|
||||
<view
|
||||
v-for="(item, index) in addressList"
|
||||
:key="index"
|
||||
class="item bg-white mb20"
|
||||
:data-id="item.id"
|
||||
@tap="onSelect"
|
||||
>
|
||||
<view class="address">
|
||||
<view class="consignee md bold">
|
||||
{{ item.contact }}
|
||||
<text class="phone ml10">{{ item.telephone }}</text>
|
||||
</view>
|
||||
<view class="lighter sm mt10">
|
||||
{{ item.province }} {{ item.city }} {{ item.district }}
|
||||
{{ item.address }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="operation row-between">
|
||||
<view>
|
||||
<radio
|
||||
class="radio row"
|
||||
color="#FF2C3C"
|
||||
:value="item.id + ''"
|
||||
:checked="item.is_default == '1' ? true : false"
|
||||
>
|
||||
<text>设为默认</text>
|
||||
</radio>
|
||||
</view>
|
||||
<view class="row-center">
|
||||
<view class="row mr20" @click.stop="editAddress(item.id)">
|
||||
<image
|
||||
class="icon-md mr10"
|
||||
src="/static/images/icon_edit.png"
|
||||
></image>
|
||||
编辑
|
||||
</view>
|
||||
<view class="row ml20" :data-id="item.id" @tap.stop="showSurePop">
|
||||
<image
|
||||
class="icon-md mr10"
|
||||
src="/static/images/icon_del_1.png"
|
||||
></image>
|
||||
删除
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</radio-group>
|
||||
</view>
|
||||
<u-modal
|
||||
id="delete-dialog"
|
||||
v-model="deleteSure"
|
||||
:showCancelButton="true"
|
||||
confirm-text="狠心删除"
|
||||
confirm-color="#FF2C3C"
|
||||
:show-title="false"
|
||||
@confirm="delAddressFun"
|
||||
@cancel="hidePop"
|
||||
>
|
||||
<view class="column-center tips-dialog">
|
||||
<image class="icon-lg" src="/static/images/icon_warning.png"></image>
|
||||
<view style="margin-top: 30rpx">确认删除该地址吗?</view>
|
||||
</view>
|
||||
</u-modal>
|
||||
<view class="footer row-between fixed bg-white">
|
||||
<!-- #ifdef H5 || MP-WEIXIN -->
|
||||
<view class="btn row-center bg-gray br60 mr20" @click="getWxAddressFun" v-if="isWeixin">
|
||||
<image class="icon-lg mr10" src="/static/images/icon_wechat.png"></image>
|
||||
<text class="md">微信导入</text>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<view class="btn bg-primary white md row-center br60" @click="addAddress"
|
||||
>新增收货地址</view
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop开源商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
|
||||
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | likeshop团队版权所有并拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshop.cn.team
|
||||
// +----------------------------------------------------------------------
|
||||
import { getAddressLists, delAddress, setDefaultAddress } from '@/api/user'
|
||||
import wechath5 from '@/utils/wechath5'
|
||||
import { isWeixinClient } from '@/utils/tools'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
addressList: [],
|
||||
hasAddress: true,
|
||||
deleteSure: false,
|
||||
currentId: 0,
|
||||
isWeixin: true
|
||||
}
|
||||
},
|
||||
|
||||
props: {},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
this.type = options.type
|
||||
//#ifdef H5
|
||||
this.isWeixin = isWeixinClient()
|
||||
//#endif
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow: function () {
|
||||
this.getAddressListsFun()
|
||||
},
|
||||
|
||||
methods: {
|
||||
onSelect(e) {
|
||||
if (this.type) {
|
||||
let { id } = e.currentTarget.dataset
|
||||
uni.$emit('selectaddress', {
|
||||
id
|
||||
})
|
||||
uni.navigateBack()
|
||||
}
|
||||
},
|
||||
|
||||
addAddress() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/address_edit/address_edit'
|
||||
})
|
||||
},
|
||||
|
||||
editAddress(id) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/address_edit/address_edit?id=${id}`
|
||||
})
|
||||
},
|
||||
|
||||
getAddressListsFun() {
|
||||
getAddressLists().then((res) => {
|
||||
if (res.code == 1) {
|
||||
if (res.data.length) {
|
||||
this.addressList = res.data
|
||||
this.hasAddress = true
|
||||
} else {
|
||||
this.hasAddress = false
|
||||
}
|
||||
} else {
|
||||
this.hasAddress = false
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
radioChange(e) {
|
||||
let id = e.detail.value
|
||||
console.log(e)
|
||||
setDefaultAddress(id).then((res) => {
|
||||
if (res.code == 1) this.getAddressListsFun()
|
||||
})
|
||||
},
|
||||
|
||||
onLoadFun() {
|
||||
this.getAddressListsFun()
|
||||
},
|
||||
|
||||
delAddressFun(e) {
|
||||
let id = this.currentId
|
||||
delAddress(id).then((res) => {
|
||||
if (res.code == 1) {
|
||||
this.$toast({
|
||||
title: res.msg
|
||||
})
|
||||
this.deleteSure = false
|
||||
this.getAddressListsFun()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getWxAddressFun() {
|
||||
// #ifdef H5
|
||||
wechath5.getWxAddress().then((res) => {
|
||||
uni.setStorageSync('wxAddress', JSON.stringify(res))
|
||||
setTimeout(() => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/address_edit/address_edit`
|
||||
})
|
||||
}, 200)
|
||||
})
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
uni.authorize({
|
||||
scope: 'scope.address',
|
||||
success: function (res) {
|
||||
uni.chooseAddress({
|
||||
success: function (res) {
|
||||
uni.setStorageSync('wxAddress', JSON.stringify(res))
|
||||
setTimeout(() => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/address_edit/address_edit`
|
||||
})
|
||||
}, 200)
|
||||
},
|
||||
fail: function (res) {
|
||||
if (res.errMsg == 'chooseAddress:cancel')
|
||||
return this.$toast({
|
||||
title: '取消选择'
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
fail: function (res) {
|
||||
uni.showModal({
|
||||
title: '您已拒绝导入微信地址权限',
|
||||
content: '是否进入权限管理,调整授权?',
|
||||
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
uni.openSetting({
|
||||
success: function (res) {}
|
||||
})
|
||||
} else if (res.cancel) {
|
||||
return this.$toast({
|
||||
title: '已取消!'
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
|
||||
showSurePop: function (e) {
|
||||
this.deleteSure = true
|
||||
this.currentId = e.currentTarget.dataset.id
|
||||
},
|
||||
hidePop: function (e) {
|
||||
this.deleteSure = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
/* pages/user_address/user_address.wxss */
|
||||
.user-address {
|
||||
padding-bottom: calc(140rpx + env(safe-area-inset-bottom));
|
||||
.no-address {
|
||||
padding-top: 300rpx;
|
||||
text-align: center;
|
||||
}
|
||||
.address-list {
|
||||
padding: 10rpx 0;
|
||||
.item {
|
||||
padding: 0 30rpx;
|
||||
.address {
|
||||
padding: 20rpx 0;
|
||||
border-bottom: $-solid-border;
|
||||
}
|
||||
.operation {
|
||||
height: 80rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.footer {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 118rpx;
|
||||
padding: 0 30rpx;
|
||||
box-sizing: content-box;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
.btn {
|
||||
flex: 1;
|
||||
height: 80rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tips-dialog {
|
||||
height: 230rpx;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,205 @@
|
||||
<template>
|
||||
<!-- pages/user_collection/user_collection.wxml -->
|
||||
<view class="user-collection">
|
||||
<view class="goods-list mt20">
|
||||
<view v-for="(item, index) in collectionList" :key="index" class="collection-item row bg-white" @tap="goToGoodsDetail" :data-id="item.id">
|
||||
<custom-image width="160rpx" height="160rpx" radius="6rpx" lazy-load class="mr20 goods-img" :src="item.image" />
|
||||
<view class="info">
|
||||
<view class="row-between">
|
||||
<view class="name line2">{{item.name}}</view>
|
||||
<image style="height: 56rpx;width: 56rpx;flex: none;margin-left: 14rpx" src="/static/images/icon_del.png" @tap.stop="deleteConfirm" :data-id="item.id"></image>
|
||||
</view>
|
||||
<view class="row-between mt20">
|
||||
<price-format :first-size="30" :second-size="26" :price="item.price" :weight="400" :subscriptSize="30" :showSubscript="true" color="#FF2C3C" />
|
||||
<view class="btn primary br60 sm">去购买</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<loading-footer :status="status" slotEmpty>
|
||||
<view class="data-null column-center" slot="empty">
|
||||
<image src="/static/images/profit_null.png" class="img-null" />
|
||||
<text class="sm muted">暂无收藏~</text>
|
||||
</view>
|
||||
</loading-footer>
|
||||
</view>
|
||||
<u-modal
|
||||
v-model="deleteSure"
|
||||
confirm-text="狠心删除"
|
||||
confirm-color="#FF2C3C"
|
||||
:showCancelButton="true"
|
||||
:show-title="false"
|
||||
@confirm="cancelCollect"
|
||||
@cancel="deleteCancel"
|
||||
>
|
||||
<view class="column-center tips-dialog" style="padding: 20rpx 0;">
|
||||
<image class="icon-lg" src="/static/images/icon_warning.png"></image>
|
||||
<view style="margin-top:30rpx">确认删除该收藏吗?</view>
|
||||
</view>
|
||||
</u-modal>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop开源商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
|
||||
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | likeshop团队版权所有并拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshop.cn.team
|
||||
// +----------------------------------------------------------------------
|
||||
import { getCollectGoods, collectGoods } from "@/api/user";
|
||||
import { CollectType, loadingType } from "@/utils/type";
|
||||
import {loadingFun} from "@/utils/tools"
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
page: 1,
|
||||
status: loadingType.LOADING,
|
||||
collectionList: [],
|
||||
collectionGoods: CollectType.COLLECTION,
|
||||
deleteSure: false,
|
||||
};
|
||||
},
|
||||
|
||||
components: {
|
||||
},
|
||||
props: {},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
this.getCollectGoodsFun();
|
||||
},
|
||||
|
||||
|
||||
onReachBottom: function () {
|
||||
this.$nextTick(() => {
|
||||
this.getCollectGoodsFun();
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
deleteCancel: function (e) {
|
||||
this.deleteSure = false;
|
||||
},
|
||||
deleteConfirm: function (e) {
|
||||
this.id = e.currentTarget.dataset.id;
|
||||
this.deleteSure = true;
|
||||
},
|
||||
|
||||
getCollectGoodsFun() {
|
||||
let {
|
||||
page,
|
||||
collectionList,
|
||||
status
|
||||
} = this;
|
||||
|
||||
loadingFun(getCollectGoods, page, collectionList, status).then(res => {
|
||||
if(res) {
|
||||
this.page = res.page;
|
||||
this.collectionList = res.dataList
|
||||
this.status = res.status
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
reflesh() {
|
||||
this.collectionList = [];
|
||||
this.page = 1;
|
||||
this.status = loadingType.LOADING;
|
||||
this.getCollectGoodsFun();
|
||||
},
|
||||
|
||||
cancelCollect() {
|
||||
collectGoods({
|
||||
is_collect: CollectType.CANCEL_COLLECTION,
|
||||
goods_id: this.id
|
||||
}).then(res => {
|
||||
if (res.code == 1) {
|
||||
this.collectionList = [];
|
||||
this.page = 1;
|
||||
this.status = loadingType.LOADING;
|
||||
this.getCollectGoodsFun();
|
||||
this.deleteSure = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
goToGoodsDetail: function (e) {
|
||||
let {
|
||||
id
|
||||
} = e.currentTarget.dataset;
|
||||
uni.navigateTo({
|
||||
url: '/pages/goods_details/goods_details?id=' + id
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
|
||||
.user-collection {
|
||||
.goods-list {
|
||||
.collection-item {
|
||||
padding: 20rpx;
|
||||
&:not(:last-of-type) {
|
||||
border-bottom: $-solid-border;
|
||||
}
|
||||
.info {
|
||||
flex: 1;
|
||||
}
|
||||
.goods-img {
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
flex: none;
|
||||
}
|
||||
.btn {
|
||||
width: 148rpx;
|
||||
height: 52rpx;
|
||||
right: 20rpx;
|
||||
border: 1px solid $-color-primary;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
.del-btn {
|
||||
height: 100%;
|
||||
width: 65px;
|
||||
}
|
||||
.store-list {
|
||||
height: calc(100vh - 100rpx);
|
||||
overflow: hidden;
|
||||
}
|
||||
.store-item {
|
||||
height: 140rpx;
|
||||
border-bottom: 1rpx solid #E5E5E5;
|
||||
.store-img {
|
||||
height: 80rpx;
|
||||
width: 80rpx;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
.tips-dialog {
|
||||
height: 230rpx;
|
||||
width: 100%;
|
||||
}
|
||||
.data-null {
|
||||
padding-top: 100rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<!-- pages/user_coupon/user_coupon.wxml -->
|
||||
<view class="user-coupon">
|
||||
<tabs :active="active" sticky line-width="40" @change="onChange">
|
||||
<tab v-for="(item, index) in coupons" :key="index" :title="item.title + '(' + item.num + ')'">
|
||||
<my-coupons :type="item.type" @getnum="onChangeNum($event, index)"></my-coupons>
|
||||
</tab>
|
||||
</tabs>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
active: 0,
|
||||
coupons: [{
|
||||
title: '可使用',
|
||||
num: '0',
|
||||
type: 0
|
||||
}, {
|
||||
title: '已使用',
|
||||
num: '0',
|
||||
type: 1
|
||||
}, {
|
||||
title: '已过期',
|
||||
num: '0',
|
||||
type: 2
|
||||
}]
|
||||
};
|
||||
},
|
||||
|
||||
components: {
|
||||
|
||||
},
|
||||
props: {},
|
||||
|
||||
methods: {
|
||||
onChangeNum(e, index) {
|
||||
this.coupons[index].num = e.detail
|
||||
},
|
||||
onChange(e) {
|
||||
console.log(e)
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
/* pages/user_coupon/user_coupon.wxss */
|
||||
</style>
|
||||
@@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<view class="user-getcoupon">
|
||||
<coupon-list v-if="!showNull" :list="couponList" :btn-type="3" @reflash="getCouponListFun"></coupon-list>
|
||||
<view v-else class="column-center" style="padding-top: 200rpx">
|
||||
<image class="img-null" src="/static/images/coupon_null.png"></image>
|
||||
<text class="muted">暂无优惠券可领~</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop开源商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
|
||||
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | likeshop团队版权所有并拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshop.cn.team
|
||||
// +----------------------------------------------------------------------
|
||||
import { getCouponList } from '../../api/activity';
|
||||
import {getCoupon} from "../../api/user"
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
couponList: [],
|
||||
showNull: false
|
||||
};
|
||||
},
|
||||
|
||||
components: {
|
||||
|
||||
},
|
||||
props: {},
|
||||
|
||||
onLoad (options) {
|
||||
this.getCouponListFun();
|
||||
},
|
||||
|
||||
methods: {
|
||||
getCouponListFun() {
|
||||
getCouponList().then(res => {
|
||||
if (res.code == 1) {
|
||||
if (res.data.length <= 0) {
|
||||
this.showNull = true;
|
||||
return;
|
||||
}
|
||||
this.couponList = res.data;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
</style>
|
||||
@@ -0,0 +1,94 @@
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop开源商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
|
||||
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | likeshop团队版权所有并拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshop.cn.team
|
||||
// +----------------------------------------------------------------------
|
||||
<template>
|
||||
<view class="user-order">
|
||||
<navbar title="我的订单"></navbar>
|
||||
<tabs :active="active" @change="changeShow" :config="{itemWidth: 150}">
|
||||
<tab v-for="(item, index) in order" :key="index" :title="item.name" :name="item.type">
|
||||
<order-list v-if="item.isShow" :order-type="item.type" :ref="'order' + item.type"></order-list>
|
||||
</tab>
|
||||
</tabs>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { orderType } from '@/utils/type';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
active: orderType.ALL,
|
||||
order: [{
|
||||
name: '全部',
|
||||
type: orderType.ALL,
|
||||
isShow: false
|
||||
}, {
|
||||
name: '待付款',
|
||||
type: orderType.PAY,
|
||||
isShow: false
|
||||
}, {
|
||||
name: '待收货',
|
||||
type: orderType.DELIVERY,
|
||||
isShow: false
|
||||
}, {
|
||||
name: '已完成',
|
||||
type: orderType.FINISH,
|
||||
isShow: false
|
||||
}, {
|
||||
name: '已关闭',
|
||||
type: orderType.CLOSE,
|
||||
isShow: false
|
||||
}]
|
||||
};
|
||||
},
|
||||
|
||||
components: {
|
||||
},
|
||||
props: {},
|
||||
onLoad: function (options) {
|
||||
const{order} = this
|
||||
let type = options.type || orderType.ALL;
|
||||
let index = order.findIndex(item => item.type == type)
|
||||
this.changeShow(index);
|
||||
},
|
||||
|
||||
onPullDownRefresh: function () {
|
||||
const {active, order} = this
|
||||
console.log(this.$refs['order' + order[active].type])
|
||||
this.$refs['order' + order[active].type][0].reflesh()
|
||||
},
|
||||
|
||||
onReachBottom: function () {
|
||||
const {active, order} = this
|
||||
console.log(this.$refs['order' + order[active].type])
|
||||
this.$refs['order' + order[active].type][0].getOrderListFun()
|
||||
},
|
||||
methods: {
|
||||
changeShow(index) {
|
||||
if(index != -1) {
|
||||
this.active = index
|
||||
this.order[index].isShow = true
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,249 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="user-vip">
|
||||
<view class="header">
|
||||
<view class="user-vip-info row">
|
||||
<custom-image width="110rpx" height="110rpx" round :src="userInfo.avatar"></custom-image>
|
||||
<view class="ml20 column">
|
||||
<view class="user-text white xxl row">{{userInfo.nickname}}</view>
|
||||
<view class="user-level white xs row-center">当前等级:{{userInfo.level_name || "无"}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content">
|
||||
<view class="vip-swiper-container">
|
||||
<swiper class="swiper" style="height: 320rpx" previous-margin="60rpx" next-margin="60rpx" display-multiple-items="1"
|
||||
:current="currentIndex" @change="bindchange">
|
||||
<swiper-item v-for="(item, index) in levelList" :key="index">
|
||||
<view class="vip-card-item" :style="'background-image: url(' + item.background_image + ');'">
|
||||
<view class="row-between">
|
||||
<view>
|
||||
<view v-if="item.current_level_status == 1" class="row grade white sm">当前等级</view>
|
||||
<view v-else-if="item.current_level_status == -1" class="row white sm ml20">未解锁</view>
|
||||
<view v-else-if="item.current_level_status == 0" class="row white sm ml20">已解锁</view>
|
||||
</view>
|
||||
<image class="grade-icon" :src="item.image"></image>
|
||||
</view>
|
||||
<view class="row-between vip-name white">
|
||||
<view class="bold">{{item.name}}</view>
|
||||
<view class="sm">{{item.next_level}}</view>
|
||||
</view>
|
||||
<view class="row-center" v-if="item.diff_growth_percent">
|
||||
<view class="vip-progress bg-white row">
|
||||
<view class="vip-progress-bar" :style="'width: ' + (item.diff_growth_percent*100) + '%'"></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="row-between mt20" style="padding: 0 30rpx">
|
||||
<navigator hover-class="none" class="row">
|
||||
<view class="sm white" style="line-height: 36rpx">
|
||||
{{item.current_level_status == 0 ? '当前高于该等级' : item.current_growth_tips}}
|
||||
</view>
|
||||
</navigator>
|
||||
<view class="white">{{item.diff_growth_tips}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
<view class="vip-grade-rule">
|
||||
<view class="title row">
|
||||
<view class="line br60"></view>
|
||||
<view class="xl ml20 bold">成长值规则</view>
|
||||
</view>
|
||||
<text class="rule-content column lighter ml20">
|
||||
{{growthRule}}
|
||||
</text>
|
||||
</view>
|
||||
<view class="vip-rights">
|
||||
<view class="title row">
|
||||
<view class="line br60"></view>
|
||||
<view class="xl ml20 bold">会员权益</view>
|
||||
</view>
|
||||
<view class="rights-list row">
|
||||
<view v-for="(item, index) in privilegeList" :key="index" class="rights-item column-center">
|
||||
<image class="mb10" :src="item.image"></image>
|
||||
<view class="sm">{{item.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<loading-view v-if="!userInfo.nickname"></loading-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getLevelList
|
||||
} from '@/api/user';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
userInfo: {},
|
||||
currentIndex: 0,
|
||||
levelList: [],
|
||||
growthRule: "",
|
||||
privilegeList: []
|
||||
};
|
||||
},
|
||||
|
||||
components: {},
|
||||
props: {},
|
||||
|
||||
onLoad: function(options) {
|
||||
this.getLevelListFun();
|
||||
},
|
||||
|
||||
|
||||
methods: {
|
||||
bindchange(e) {
|
||||
let {
|
||||
current
|
||||
} = e.detail;
|
||||
let currentLevel = this.levelList[current];
|
||||
this.currentIndex = current
|
||||
this.privilegeList = currentLevel.level_privilege
|
||||
},
|
||||
|
||||
getLevelListFun() {
|
||||
getLevelList().then(res => {
|
||||
const {
|
||||
code,
|
||||
data
|
||||
} = res;
|
||||
if (code != 1) return;
|
||||
const {
|
||||
user,
|
||||
growth_rule,
|
||||
level_list
|
||||
} = data;
|
||||
let index = level_list.findIndex(item => item.current_level_status == 1);
|
||||
if (index == -1) index = 0;
|
||||
this.userInfo = user
|
||||
this.growthRule = growth_rule
|
||||
this.levelList = level_list
|
||||
this.currentIndex = index
|
||||
this.privilegeList = level_list[index].level_privilege
|
||||
});
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #fff;
|
||||
|
||||
.user-vip {
|
||||
.header {
|
||||
background-image: url(../../static/images/vip_grade_bg.png);
|
||||
padding-top: 30rpx;
|
||||
background-size: 100% 100%;
|
||||
height: 382rpx;
|
||||
|
||||
.user-vip-info {
|
||||
padding-left: 30rpx;
|
||||
|
||||
.user-level {
|
||||
border: 1px solid white;
|
||||
border-radius: 100rpx;
|
||||
padding: 4rpx 20rpx;
|
||||
line-height: 30rpx;
|
||||
}
|
||||
|
||||
.user-text {
|
||||
line-height: 50rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-top: -200rpx;
|
||||
|
||||
.vip-card-item {
|
||||
height: 320rpx;
|
||||
width: 600rpx;
|
||||
position: relative;
|
||||
background-size: 100% 100%;
|
||||
|
||||
.grade {
|
||||
line-height: 36rpx;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
border-top-right-radius: 100rpx;
|
||||
border-bottom-right-radius: 100rpx;
|
||||
height: 50rpx;
|
||||
padding: 0 28rpx;
|
||||
}
|
||||
|
||||
.user-grade {
|
||||
line-height: 36rpx;
|
||||
margin-left: 30rpx;
|
||||
}
|
||||
|
||||
.grade-icon {
|
||||
width: 120rpx;
|
||||
height: 100rpx;
|
||||
}
|
||||
|
||||
.vip-name {
|
||||
padding: 10rpx 30rpx;
|
||||
font-size: 46rpx;
|
||||
text-align: center;
|
||||
align-items: flex-end;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.vip-progress {
|
||||
height: 8rpx;
|
||||
width: 540rpx;
|
||||
|
||||
.vip-progress-bar {
|
||||
background-color: #f8d07c;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.vip-grade-rule {
|
||||
margin: 24rpx 40rpx;
|
||||
|
||||
.title {
|
||||
.line {
|
||||
width: 8rpx;
|
||||
height: 34rpx;
|
||||
background-color: #f79c0c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.vip-rights {
|
||||
margin: 24rpx 40rpx;
|
||||
|
||||
.title {
|
||||
padding: 28rpx 0;
|
||||
|
||||
.line {
|
||||
width: 8rpx;
|
||||
height: 34rpx;
|
||||
background-color: #f79c0c;
|
||||
}
|
||||
}
|
||||
|
||||
.rights-item {
|
||||
width: 25%;
|
||||
padding-bottom: 30rpx;
|
||||
|
||||
image {
|
||||
width: 82rpx;
|
||||
height: 82rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<view class="page-body">
|
||||
<view class="page-section page-section-gap">
|
||||
<web-view :src="url"></web-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
url: ''
|
||||
};
|
||||
},
|
||||
|
||||
components: {},
|
||||
props: {},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
this.url = options.url
|
||||
},
|
||||
methods: {}
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
/* pages/webview/webview.wxss */
|
||||
.page-section-gap{
|
||||
box-sizing: border-box;
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user