购买商品,商品详情页

This commit is contained in:
itgaojian163 2025-06-10 10:50:44 +08:00
parent 5976746087
commit e32e376eb8
29 changed files with 686 additions and 12 deletions

View File

@ -27,7 +27,12 @@
"pages/copyright/applyRepair/applyRepair",
"pages/copyright/applyRefund/applyRefund",
"pages/shop/market/market",
"pages/shop/publishCopyright/publishCopyright"
"pages/shop/publishCopyright/publishCopyright",
"pages/shop/buyGoods/buyGoods",
"pages/shop/sellGoods/sellGoods",
"pages/shop/purchaseGoods/purchaseGoods",
"pages/shop/betrayGoods/betrayGoods",
"pages/shop/goodsDetail/goodsDetail"
],
"window": {
"navigationBarTextStyle": "black",

View File

@ -129,6 +129,10 @@ swiper-item {
border-radius: 5px;
text-align: center;
}
.bottom-btn-green.active{
background-color: var(--gray-bg-color);
color: var(--text-brown-color);
}
.ml-10 {
margin-left: 10rpx;
@ -330,4 +334,8 @@ swiper-item {
.weui-half-screen-dialog__ft {
height: 0;
padding: 0rpx 0rpx 50rpx;
}
.tip-margin{
margin-top: 80px;
}

View File

@ -26,6 +26,7 @@ const apiPath = {
canRefundProList: '/api/proj/refund/apply/listpage-proj-unapply/self', //可以退款的项目
applyRefundPro: '/api/proj/refund/apply/save', //申请退款
cancelRefundPro: '/api/proj/refund/apply/cancel/self/{projRefundApplyId}', //取消申请退款
dealDetail: '/api/agreementportal/get/{id}', //协议operator
}
class ProjectService {
//首页介绍数量
@ -84,7 +85,7 @@ class ProjectService {
//获取使用规则数据
static doGetRuleDate(id) {
const path = apiPath.ruleData.replace('{id}', id)
return request(path, "GET", null, "operator", false)
return request(path, "GET", null, "operator", false)
}
static doGetInvestDetail(data) {
return request(apiPath.investDetail, "GET", data)
@ -122,6 +123,11 @@ class ProjectService {
static doApplyRefundPro(data) {
return request(apiPath.applyRefundPro, "POST", data)
}
//获取协议详情
static doGetDealDetail(id) {
const path = apiPath.dealDetail.replace('{id}', id)
return request(path, "GET", null, "operator", true)
}
}
export default ProjectService;

View File

@ -16,6 +16,8 @@ const apiPath = {
// ce3ded65-68ed-4f42-89da-de1b813b8f7e 证件类型
goodsDics: "/api/data/listbyparentid/{dId}", //商品数据字典
areaList: "/api/area/listbyparentid/{pId}", //省市区树结构
saveOrder: '/api/order/save/{goodsId}', //新增订单
confirmOrder: '/api/order/confirm-pay/{orderId}', //确定付款
}
class Shop {
// 通用路径参数替换方法
@ -99,6 +101,18 @@ class Shop {
pId: id
})
}
//新增订单
static doSaveOrder(id) {
return this.requestHandler(apiPath.saveOrder, "POST", null, {
goodsId: id
})
}
//确定付款
static doConfirmOrder(oId) {
return this.requestHandler(apiPath.confirmOrder, "PUT", null, {
orderId: oId
})
}
}
export default Shop;

View File

@ -0,0 +1,66 @@
// pages/shop/betrayGoods/betrayGoods.js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})

View File

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

View File

@ -0,0 +1,2 @@
<!--pages/shop/betrayGoods/betrayGoods.wxml-->
<text>pages/shop/betrayGoods/betrayGoods.wxml</text>

View File

@ -0,0 +1 @@
/* pages/shop/betrayGoods/betrayGoods.wxss */

View File

@ -0,0 +1,66 @@
// pages/shop/buyGoods/buyGoods.js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})

View File

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

View File

@ -0,0 +1,2 @@
<!--pages/shop/buyGoods/buyGoods.wxml-->
<text>pages/shop/buyGoods/buyGoods.wxml</text>

View File

@ -0,0 +1 @@
/* pages/shop/buyGoods/buyGoods.wxss */

View File

@ -0,0 +1,190 @@
// pages/shop/goodsDetail/goodsDetail.js
import Shop from '../../../net/api/shop'
import {
sImgPrefix,
} from '../../../net/mainUrl'
const app = getApp()
const deviceInfo = wx.getDeviceInfo()
const screenInfo = wx.getWindowInfo();
const statusBarHeight = screenInfo.statusBarHeight; // 状态栏高度
const navBarHeight = deviceInfo.platform == 'IOS' ? 48 : 50; // 导航栏高度iOS 为 44pxAndroid 为 48px
Page({
/**
* 页面的初始数据
*/
data: {
animationClass: '',
statusBarHeight: statusBarHeight,
totalHeight: navBarHeight,
id: '',
msgType: 'info',
msgHint: '',
msgShow: false,
goods: null,
isagree: false
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
wx.setNavigationBarTitle({
title: '我要买',
})
wx.setNavigationBarColor({
frontColor: '#FFFFFF', // 必写项,字体颜色仅支持#ffffff和#000000
backgroundColor: '#000000', // 传递的颜色值,仅支持十六进制颜色
})
const id = options.id
if (id != '') {
this.setData({
id: id
})
this.doGetDetail()
} else {
this.setData({
msgType: 'error',
msgHint: '数据有误,请刷新重试',
msgShow: true
})
setTimeout(() => {
wx.navigateBack()
}, 1200);
}
},
onShow() {
this.setData({
animationClass: 'fade-in'
})
},
onHide() {
this.setData({
animationClass: 'fade-out'
})
},
doBack() {
wx.navigateBack()
},
doPreImg(e) {
const url = e.currentTarget.dataset.url
wx.previewImage({
urls: [url],
})
},
doChangeDeal() {
this.setData({
isagree: !this.data.isagree
})
},
//显示购买协议
doShowDeal() {
wx.navigateTo({
url: '/pages/treaty/rule/rule?id=db805bf2-eef9-47d5-941b-cdc3b83ec316&needToken=true',
})
},
//提交购买
doConfirm() {
if (this.data.isagree) {
this.doSaveOrder()
} else {
this.setData({
msgHint: '请阅读并同意购买协议',
msgType: 'info',
msgShow: true
})
}
},
async doSaveOrder() {
try {
wx.showLoading({
title: '购买中..',
});
const res = await Shop.doSaveOrder(this.data.id);
wx.hideLoading();
if (res && res.data != '') {
await this.doConfirmOrder(res.data);
} else {
this.setData({
msgHint: '网络错误,请稍后重试',
msgType: 'error',
msgShow: true
});
}
} catch (err) {
wx.hideLoading();
this.setData({
msgHint: err.msg ? err.msg : '网络错误,请稍后重试',
msgType: 'error',
msgShow: true
});
}
},
async doConfirmOrder(id) {
try {
wx.showLoading({
title: '购买中...',
});
await Shop.doConfirmOrder(id);
wx.hideLoading();
this.setData({
msgHint: '购买成功',
msgType: 'success',
msgShow: true
});
setTimeout(() => {
wx.navigateBack();
}, 1500);
} catch (err) {
wx.hideLoading();
this.setData({
msgHint: err.msg ? err.msg : '网络错误,请稍后重试',
msgType: 'error',
msgShow: true
});
}
},
doGetDetail() {
const that = this
wx.showLoading({
title: '加载中...',
})
Shop.doGetGoodsDetail(that.data.id)
.then(res => {
wx.hideLoading()
console.log(res)
if (res.goodsPhoto && res.goodsPhoto != '') {
res.goodsPhoto = sImgPrefix + res.goodsPhoto
that.setData({
goods: res
})
} else {
that.setData({
msgHint: '网络错误,请稍后重试',
msgType: 'error',
msgShow: true
})
setTimeout(() => {
wx.navigateBack()
}, 1200);
}
})
.catch(err => {
wx.hideLoading()
that.setData({
msgHint: err.msg ? err.msg : '网络错误,请稍后重试',
msgType: 'error',
msgShow: true
})
setTimeout(() => {
wx.navigateBack()
}, 1200);
})
}
})

View File

@ -0,0 +1,8 @@
{
"usingComponents": {
"container-loading": "/components/container-loading/container-loading",
"mp-loading": "weui-miniprogram/loading/loading",
"mp-toptips": "weui-miniprogram/toptips/toptips"
},
"navigationStyle": "custom"
}

View File

@ -0,0 +1,27 @@
<view class="page-container {{animationClass}}" style="height: 100vh;background-color: var(--tabbar-normal-color);padding: 0rpx 30rpx;">
<view class="temp-custom-navbar" style="height: {{totalHeight}}px; padding-top: {{statusBarHeight}}px;">
<view bind:tap="doBack" class="icon-arrow-white-left-line size-64"></view>
<view class="temp-navbar-title" style="color:var(--white-color);">我要买</view>
</view>
<view wx:if="{{goods != null}}" class="detail-box">
<image bind:tap="doPreImg" data-url="{{goods.goodsPhoto}}" src="{{goods.goodsPhoto}}" mode="aspectFill" class="detail-img"></image>
<view class="bottom-fixed-footer" style="background-color: var(--tabbar-normal-color);color:var(--white-color);">
<view class="goods-name">{{goods.goodsName}}</view>
<view class="goods-info-box mt-20">
<rich-text class="goods-price" nodes="{{tools.moneyTxt(12,goods.goodsOpenPrice)}}"></rich-text>
<view style="font-size: 28rpx;">上架:{{goods.goodsStatusTime}}</view>
</view>
<view class="deal-box mt-20" style="margin-bottom: 60rpx;">
<view class="deal-box" bind:tap="doChangeDeal">
<checkbox class="custom-wx-checkbox" style="margin-top: -6rpx;" checked="{{isagree}}"></checkbox>
<view>我同意平台</view>
</view>
<view class="deal-link" bind:tap="doShowDeal">《购买协议》</view>
</view>
<view class="bottom-btn-green {{isagree? '':'active'}}" bind:tap="doConfirm">立即购买</view>
</view>
</view>
</view>
<mp-toptips ext-class="tip-margin" delay="2000" msg="{{msgHint}}" type="{{msgType}}" show="{{msgShow}}"></mp-toptips>
<wxs src="../../../utils/comm.wxs" module="tools"></wxs>

View File

@ -0,0 +1,88 @@
/* app.wxss */
.fade-in {
animation: fadeIn 0.5s;
}
.fade-out {
animation: fadeOut 0.5s;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
.temp-custom-navbar {
display: flex;
flex-direction: row;
align-items: center;
background-color: transparent;
position: relative;
}
/* 标题 */
.temp-navbar-title {
font-size: 32rpx;
font-weight: bold;
position: absolute;
left: 50%;
transform: translateX(-50%);
}
.temp-navbar-back {
color: var(--white-color);
}
.detail-box {
display: flex;
flex-direction: column;
align-items: center;
}
.detail-img {
width: 80%;
height: 50vh;
margin-top: 30rpx;
}
.goods-name {
font-size: 32rpx;
font-weight: bold;
}
.goods-info-box {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.deal-box {
display: flex;
flex-direction: row;
align-items: center;
}
.goods-price {
font-size: 42rpx;
font-weight: bold;
}
.deal-link {
color: var(--primary-color)
}

View File

@ -235,9 +235,36 @@ Page({
return item;
});
},
doPublish() {
//我要买
doBuy() {
wx.navigateTo({
url: '/pages/shop/publishCopyright/publishCopyright',
url: '/pages/shop/buyGoods/buyGoods',
})
},
//已购买
doPurchase() {
wx.navigateTo({
url: '/pages/shop/purchaseGoods/purchaseGoods',
})
},
//我要卖
doSell() {
wx.navigateTo({
url: '/pages/shop/sellGoods/sellGoods',
})
},
//已销售
doBetray() {
wx.navigateTo({
url: '/pages/shop/betrayGoods/betrayGoods',
})
},
//详情
doDetail(e) {
const id = e.currentTarget.dataset.value
wx.navigateTo({
url: '/pages/shop/goodsDetail/goodsDetail?id=' + id,
animation: 'fade'
})
}
})

View File

@ -26,15 +26,19 @@
</view>
</view>
<view class="title-func-box">
<view class="title-func-item">
<view class="title-func-item" bind:tap="doBuy">
<image class="func-img" src="/static/images/icon_buy.png"></image>
<text class="func-txt">我要买</text>
</view>
<view class="title-func-item" bind:tap="doPurchase">
<image class="func-img" src="/static/images/icon_purchase.png"></image>
<text class="func-txt">已购买</text>
</view>
<view class="title-func-item">
<view class="title-func-item" bind:tap="doSell">
<image class="func-img" src="/static/images/icon_sell.png"></image>
<text class="func-txt">我要卖</text>
</view>
<view class="title-func-item">
<view class="title-func-item" bind:tap="doBetray">
<image class="func-img" src="/static/images/icon_betray.png"></image>
<text class="func-txt">已销售</text>
</view>
@ -58,7 +62,7 @@
</scroll-view>
</view>
<view class="condition-item mt-20">
<view class="condition-item-title">所属者类型</view>
<view class="condition-item-title">价格排序</view>
<scroll-view scroll-x style="flex:1;">
<view class="list-tabs ml-20">
<block wx:for="{{ownerList}}" wx:key="index">
@ -77,7 +81,7 @@
</view>
<view class="content-box">
<block wx:for="{{goodsList}}" wx:key="index">
<view class="content-item">
<view class="content-item" bind:tap="doDetail" data-value="{{item.goodsId}}">
<view class="content-item-img-box">
<image src="{{item.preImg}}" class="content-item-img" mode="aspectFill"></image>
</view>

View File

@ -97,6 +97,7 @@
.title-func-box {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-top: 30rpx;
}
@ -106,9 +107,9 @@
align-items: center;
}
.title-func-item:nth-of-type(n+2) {
/* .title-func-item:nth-of-type(n+2) {
margin-left: 40rpx;
}
} */
.func-img {
width: 120rpx;

View File

@ -0,0 +1,66 @@
// pages/shop/purchaseGoods/purchaseGoods.js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})

View File

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

View File

@ -0,0 +1,2 @@
<!--pages/shop/purchaseGoods/purchaseGoods.wxml-->
<text>pages/shop/purchaseGoods/purchaseGoods.wxml</text>

View File

@ -0,0 +1 @@
/* pages/shop/purchaseGoods/purchaseGoods.wxss */

View File

@ -0,0 +1,28 @@
// pages/shop/sellGoods/sellGoods.js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
wx.setNavigationBarTitle({
title: '我要卖',
})
wx.setNavigationBarColor({
frontColor: '#000000', // 必写项,字体颜色仅支持#ffffff和#000000
backgroundColor: '#FFFFFF', // 传递的颜色值,仅支持十六进制颜色
animation: { // 可选项
duration: 500,
timingFunc: 'easeIn'
}
})
},
})

View File

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

View File

@ -0,0 +1,2 @@
<!--pages/shop/sellGoods/sellGoods.wxml-->
<text>pages/shop/sellGoods/sellGoods.wxml</text>

View File

@ -0,0 +1 @@
/* pages/shop/sellGoods/sellGoods.wxss */

View File

@ -28,7 +28,12 @@ Page({
timingFunc: 'easeIn'
}
})
this.getDeal()
const needToken = options.needToken
if (needToken) {
this.getDetailNeed()
} else {
this.getDeal()
}
},
//获取协议内容
getDeal() {
@ -65,5 +70,41 @@ Page({
wx.navigateBack()
}, 1500);
})
},
//获取协议
getDetailNeed() {
const _self = this
wx.showLoading({
title: '加载中...',
})
ProApi.doGetDealDetail(_self.data.id)
.then(res => {
wx.hideLoading()
if (res && res.content && res.content != '') {
_self.setData({
title: res.title,
content: res.content
})
} else {
_self.setData({
showError: true,
errorHint: '很遗憾,当前服务器返回的数据有误,辛苦您过会儿再尝试。'
})
setTimeout(() => {
wx.navigateBack()
}, 1500);
}
})
.catch(err => {
wx.hideLoading()
console.log(err)
_self.setData({
showError: true,
errorHint: '很遗憾,当前服务器返回的数据有误,辛苦您过会儿再尝试。'
})
setTimeout(() => {
wx.navigateBack()
}, 1500);
})
}
})

View File

@ -31,6 +31,11 @@
background-repeat: no-repeat;
background-size: contain;
}
.icon-arrow-white-left-line{
background-image: url('data:image/svg+xml;charset=utf-8;base64,PHN2ZyB0PSIxNzQ5NDYzNjkwOTY5IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjQyNzYiIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+PHBhdGggZD0iTTYwOCA3MzZjLTYuNCAwLTE5LjIgMC0yNS42LTYuNGwtMTkyLTE5MkMzODQgNTI0LjggMzg0IDQ5OS4yIDM5MC40IDQ4Ni40bDE5Mi0xOTJjMTIuOC0xMi44IDMyLTEyLjggNDQuOCAwczEyLjggMzIgMCA0NC44TDQ2MC44IDUxMmwxNjYuNCAxNjYuNGMxMi44IDEyLjggMTIuOCAzMiAwIDQ0LjhDNjI3LjIgNzM2IDYxNC40IDczNiA2MDggNzM2eiIgZmlsbD0iI2ZmZmZmZiIgcC1pZD0iNDI3NyI+PC9wYXRoPjwvc3ZnPg==');
background-repeat: no-repeat;
background-size: contain;
}
.icon-add {
background-image: url('data:image/svg+xml;charset=utf-8;base64,PHN2ZyB0PSIxNzQyOTYwODU2NzU0IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjIzMDUyIiB3aWR0aD0iMTYiIGhlaWdodD0iMTYiPjxwYXRoIGQ9Ik01ODguOCA0MzUuMmgzNTguNGE3Ni44IDc2LjggMCAxIDEgMCAxNTMuNmgtMzU4LjR2MzU4LjRhNzYuOCA3Ni44IDAgMSAxLTE1My42IDB2LTM1OC40aC0zNTguNGE3Ni44IDc2LjggMCAxIDEgMC0xNTMuNmgzNTguNHYtMzU4LjRhNzYuOCA3Ni44IDAgMSAxIDE1My42IDB2MzU4LjR6IiBmaWxsPSIjNTUwMTAxIiBwLWlkPSIyMzA1MyI+PC9wYXRoPjwvc3ZnPg==');