This commit is contained in:
kikyoe 2025-09-09 16:23:08 +08:00
parent 4036939b9c
commit 9e3f154836
136 changed files with 22105 additions and 7029 deletions

5
api/afterSale.js Normal file
View File

@ -0,0 +1,5 @@
export const apiArr = {
afterSaleCreate: "/api/v2/wechat/commodity/after-sales/refund-info/create", //商品订单售后信息创建
cancelOrConfirm: "/api/v2/wechat/commodity/order/cancel_or_confirm", //商品订单确认收货或取消
isAllow: "/api/v2/wechat/commodity/after-sales/is-allow", //判断订单是否能申请售后
};

View File

@ -47,4 +47,5 @@ export const apiArr = {
getPayOrderInfo:"/api/v2/wechat/community-order-pay/get-one", //根据缴费信息获取支付信息
getPayOrderList:"/api/v2/wechat/community-order-pay/get-page", //查询缴费记录
OrderPay:"/api/v2/wechat/community-order-pay/preorder",//预下单
tradeQuery:"/api/v2/wechat/community-order-pay/trade-query",//缴费查单
};

7
api/groupPurchase.js Normal file
View File

@ -0,0 +1,7 @@
export const apiArr = {
groupBuyList: "/api/v2/wechat/commodity/group-buy/list", //团购列表
groupGoodsList: "/api/v2/wechat/commodity/group-goods/list", //团购商品列表
groupBuyAddress: "/api/v2/wechat/commodity/group-buy/address", //团购自提地址
groupBuyRecord: "/api/v2/wechat/commodity/group-buy/buy-record", //团购购买记录
groupBuyWriteOff: "/api/v2/wechat/commodity/group-buy/write-off", //团购核销
};

22
api/park.js Normal file
View File

@ -0,0 +1,22 @@
export const apiArr = {
carList: '/api/v2/wechat/smart-parking/car/list', // 车辆列表
carAdd: '/api/v2/wechat/smart-parking/car/add', // 车辆添加
monthCardCreate: '/api/v2/wechat/smart-parking/month-card/create', // 月卡订单创建
monthCardOrderList: '/api/v2/wechat/smart-parking/month-card/order/list', // 包月订单列表
monthCardOrderPreorder: '/api/v2/wechat/smart-parking/month-card/order/preorder', // 月卡充值预下单
monthCardOrderQuery: '/api/v2/wechat/smart-parking/month-card/order/trade_query', // 月卡充值订单交易查询
billingRulesList: '/api/v2/wechat/smart-parking/billing-rules/list', // 月卡计费规则列表
tempParkingCreate: '/api/v2/wechat/smart-parking/temp-parking/create', // 临时车缴费订单创建
tempParkingInfo: '/api/v2/wechat/smart-parking/temp-parking/info', // 临时车缴费信息
tempParkingOrderDelete: '/api/v2/wechat/smart-parking/temp-parking/order/delete', // 临时车停车订单删除
tempParkingOrderInfo: '/api/v2/wechat/smart-parking/temp-parking/order/info', // 临时车停车订单信息
tempParkingOrderList: '/api/v2/wechat/smart-parking/temp-parking/order/list', // 临时车停车订单列表
tempParkingOrderPreorder: '/api/v2/wechat/smart-parking/temp-parking/preorder', // 临时车缴费订单预下单
tempParkingOrderQuery: '/api/v2/wechat/smart-parking/temp-parking/trade_query', // 临时车缴费订单交易查询
parkList: '/api/v2/wechat/smart-parking/parking/list', // 停车场列表
deleteCar: '/api/v2/wechat/smart-parking/car/del', // 删除车辆
}

View File

@ -12,5 +12,12 @@ export const apiArr = {
payOrder: "/api/v2/wechat/commodity/order/pay",//支付订单
settingDefaultAddress: '/api/v2/wechat/commodity/receiving_address/default', // 收货地址设置默认
updateAddress: '/api/v2/wechat/commodity/receiving_address/update', // 收货地址修改
addAddress: '/api/v2/wechat/commodity/receiving_address/add', // 收货地址添加
addAddressList: '/api/v2/wechat/commodity/receiving_address', // 收货地址列表
queryOrder: '/api/v2/wechat/commodity/order/trade_query', // 查询订单
getComment: '/api/v2/wechat/commodity/review/list', // 获取评论
mergePreorder: '/api/v2/wechat/commodity/order/preorder', // 商品订单合并预下单
goodsSearch: '/api/v2/wechat/commodity/search', // 商品搜索
}

View File

@ -39,23 +39,26 @@
this.address = uni.getStorageSync('city');
return;
}
uni.request({
url: apiArr.get_host_info,
method: 'post',
header: {
'Content-type': 'application/x-www-form-urlencoded'
},
dataType: 'json',
success: (result) => {
console.log(result, 'result');
let wxapp = result.data.all.wxapp;
if (wxapp) {
this.qqmap_key = wxapp.qqmap_key;
this.qqmap_key = '55NBZ-MUQYW-EAJRL-YIWPA-ZXCR6-4NBPP';
this.getUserLocation()
}
},
})
// uni.request({
// url: apiArr.get_host_info,
// method: 'post',
// header: {
// 'Content-type': 'application/x-www-form-urlencoded'
// },
// dataType: 'json',
// success: (result) => {
// console.log(result, 'result');
// let wxapp = result.data.all.wxapp;
// if (wxapp) {
// this.qqmap_key = wxapp.qqmap_key;
// this.getUserLocation()
// }
// },
// })
},
getUserLocation() {

View File

@ -201,7 +201,7 @@ export default {
? this.city.ad_code
: uni.getStorageSync("ad_code"),
page_num: this.page_num,
page_size: this.page_size,
page_size: 9999,
}).then((res) => {
console.log(res.rows);
this.communityList = res.rows;

View File

@ -106,6 +106,18 @@ image {
position: relative;
}
.swiperBox_no1 {
height: 300rpx;
width: 710rpx;
position: relative;
margin-top: 170rpx;
margin: 170rpx auto 0;
}
.swiperBox_no_img{
border-radius: 15rpx;
}
.swiperBox1 swiper {
height: 100%;
}
@ -154,6 +166,12 @@ image {
margin-top: -96rpx;
}
.swiperBox_no2 {
height: 150rpx;
width: 710rpx;
margin: 0 auto;;
}
.funcList {
display: flex;
align-items: center;

View File

@ -1,21 +1,59 @@
<template>
<div class="container">
<div class="empty" v-if="communityList.length == 0">
<view class="container">
<!-- <view class="empty" v-if="communityList.length == 0">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_newEmpty.png" alt="" />
<text>当前账户未绑定任何项目房源信息</text>
<button class="emptyBtn" @click="addCommunity">新增房产绑定</button>
<!-- <button class="emptyBtn2" @click="refresh">刷新</button> -->
</div>
<div v-else>
<div class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }">
<div class="searchBox_add">
<div class="emptyCommunity" @click="addCommunity">
{{ communityVal }}
</div>
</div>
</div>
</view> -->
<div class="swiperBox1">
<view v-if="communityList.length == 0">
<view class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }">
<view class="searchBox_add">
<view class="emptyCommunity" @click="addCommunity">
{{ communityVal }}
</view>
</view>
</view>
<view class="swiperBox_no1">
<swiper @animationfinish="swipers" autoplay circular>
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/community_no_image1.png" mode="aspectFill"
class="swiperBox_no_img" @click="addCommunity" />
</swiper>
<view class="dot">
<view :class="['dotItem', currentIdx == index ? 'active' : '']" v-for="(item, index) in bannerList"
:key="index">
</view>
</view>
</view>
<view class="swiperBox_no2">
<swiper @animationfinish="swipers" autoplay circular>
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/community_no_image2.png" mode="aspectFill"
class="swiperBox_no_img" @click="addCommunity" />
</swiper>
</view>
<view class="funcList">
<u-grid :col="5" :border="false">
<u-grid-item v-for="(item, index) in noValFunctionList" @click="addCommunity" :key="index">
<image class="grid_Pic" :src="item.nav_icon" mode=""></image>
<text class="grid_Text">{{ item.nav_name }}</text>
</u-grid-item>
</u-grid>
</view>
</view>
<view v-else>
<view class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }">
<view class="searchBox_add">
<view class="emptyCommunity" @click="addCommunity">
{{ communityVal }}
</view>
</view>
</view>
<view class="swiperBox1">
<swiper @animationfinish="swipers" autoplay circular>
<swiper-item v-for="(item, index) in bannerList" :key="index" @click="headerServerClick(item)">
<image :src="item.ad_picture" mode="aspectFill" />
@ -27,15 +65,15 @@
:key="index">
</view>
</view>
</div>
</view>
<div class="swiperBox2">
<view class="swiperBox2">
<swiper @animationfinish="swipers" autoplay circular>
<swiper-item v-for="(item, index) in streamerList" :key="index" @click="headerServerClick(item)">
<image :src="item.ad_picture" mode="aspectFill" class="swiperBox2_img" />
</swiper-item>
</swiper>
</div>
</view>
<view class="funcList">
<u-grid :col="rowNum" :border="false">
@ -46,66 +84,66 @@
</u-grid>
</view>
<div v-for="(item, index) in tileList" :key="index" :class="['ads', index == 0 ? 'ads_first' : '']"
<view v-for="(item, index) in tileList" :key="index" :class="['ads', index == 0 ? 'ads_first' : '']"
@click="headerServerClick(item)">
<image :src="item.ad_picture" mode="aspectFill" />
</div>
</view>
<div class="tabs">
<div v-for="(item, index) in categoryList" :key="index"
<view class="tabs">
<view v-for="(item, index) in categoryList" :key="index"
:class="['tabItem', selectedTab === index ? 'active2' : '']" @click="selectTab(index, item)">
{{ item.category_name }}
</div>
</div>
</view>
</view>
<div class="newsList">
<div class="newsItem" v-for="item in infoList" @click="detail(item)" :key="item.id">
<div class="newsItem_left">
<div class="newsItem_left_tit">{{ item.title }}</div>
<div class="newsItem_left_sub">{{ item.author }}</div>
</div>
<div class="newsItem_right">
<view class="newsList">
<view class="newsItem" v-for="item in infoList" @click="detail(item)" :key="item.id">
<view class="newsItem_left">
<view class="newsItem_left_tit">{{ item.title }}</view>
<view class="newsItem_left_sub">{{ item.author }}</view>
</view>
<view class="newsItem_right">
<image :src="item.list_image" mode="aspectFill" />
</div>
</div>
</div>
</view>
</view>
</view>
<div class="tips">{{ loadMoreText }}</div>
<view class="tips">{{ loadMoreText }}</view>
<div class="bigAds" v-if="ads1Show">
<div class="bigAdsCon">
<div class="bigAdsCon_img">
<view class="bigAds" v-if="ads1Show">
<view class="bigAdsCon">
<view class="bigAdsCon_img">
<swiper @animationfinish="swipers" autoplay circular>
<swiper-item v-for="(item, index) in largePopList" :key="index" @click="headerServerClick(item)">
<image :src="item.ad_picture" mode="aspectFill" />
</swiper-item>
</swiper>
</div>
<div class="close" @click="closeAds">
</view>
<view class="close" @click="closeAds">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_close.png">
</image>
</div>
</div>
</div>
</view>
</view>
</view>
<div class="bigAds" v-if="ads2Show">
<div class="bigAdsCon2">
<div class="bigAdsCon2_img">
<view class="bigAds" v-if="ads2Show">
<view class="bigAdsCon2">
<view class="bigAdsCon2_img">
<swiper :current="currentSwiperIndex" @change="onSwiperChange" @animationfinish="swipers" autoplay circular>
<swiper-item v-for="(item, index) in popList" :key="index">
<image :src="item.ad_picture" mode="aspectFill" />
</swiper-item>
</swiper>
</div>
<div class="AdsBtnList">
<div class="AdsBtnItem1" @click="closeAds2">取消</div>
<div class="AdsBtnItem2" @click="onDetailClick">了解详情</div>
</div>
</div>
</div>
</div>
</view>
<view class="AdsBtnList">
<view class="AdsBtnItem1" @click="closeAds2">取消</view>
<view class="AdsBtnItem2" @click="onDetailClick">了解详情</view>
</view>
</view>
</view>
</view>
<nav-footer :current="3" />
</div>
</view>
</template>
<script>
@ -134,7 +172,50 @@ export default {
communityList: [],
flag: false,
defaultFunctionList: [],
functionList: [],
noValFunctionList: [
{
nav_icon: 'http://localhost:8080/noValFunction1.png',
nav_name: "物业介绍",
},
{
nav_icon: 'http://localhost:8080/noValFunction2.png',
nav_name: "物业缴费",
},
{
nav_icon: 'http://localhost:8080/noValFunction3.png',
nav_name: "物业公积金",
},
{
nav_icon: 'http://localhost:8080/noValFunction1.png',
nav_name: "物业保修",
},
{
nav_icon: 'http://localhost:8080/noValFunction4.png',
nav_name: "便民电话",
},
{
nav_icon: 'http://localhost:8080/noValFunction5.png',
nav_name: "人脸门禁",
},
{
nav_icon: 'http://localhost:8080/noValFunction6.png',
nav_name: "手机开门",
},
{
nav_icon: 'http://localhost:8080/noValFunction7.png',
nav_name: "物业活动",
},
{
nav_icon: 'http://localhost:8080/noValFunction8.png',
nav_name: "访客邀请",
},
{
nav_icon: 'http://localhost:8080/noValFunction10.png',
nav_name: "场地预约",
},
],
ads1Show: false,
ads2Show: false,
@ -168,6 +249,51 @@ export default {
},
async onShow() {
this.defaultFunctionList = [
{
create_time: "",
id: 4,
is_published: 1,
jump_target: 1,
mini_program_url: "/packages/community/repairList/index",
nav_icon: picUrl + "/static/images/2025-07-05/db3s1b1lyxawt8cnke.png",
nav_name: "报事报修",
other_appid: "",
other_path: "",
sort: 5,
update_time: "",
visible_communities: ""
},
{
create_time: "",
id: 5,
is_published: 1,
jump_target: 1,
mini_program_url: "/packages/community/propertyPayment/index",
nav_icon: picUrl + "/static/images/2025-07-05/db3s1t7d1k0qmuha61.png",
nav_name: "物业缴费",
other_appid: "",
other_path: "",
sort: 4,
update_time: "",
visible_communities: "",
},
{
create_time: "",
id: 7,
is_published: 1,
jump_target: 1,
mini_program_url: "/packages/community/providentFund/index",
nav_icon: picUrl + "/static/images/2025-07-05/db3s29e33rd7rsrecf.png",
nav_name: "物业公积金",
other_appid: "",
other_path: "",
sort: 2,
update_time: "",
visible_communities: ""
}
]
//
// if (!uni.getStorageSync("changeCommData")) {
// return;
@ -200,7 +326,6 @@ export default {
res.rows = res.rows.filter((item) => {
return item.front_end_display != 1;
});
console.log("🚀 ~ onLoad ~ res.rows:", res.rows)
if (!uni.getStorageSync("changeCommData")) {
uni.setStorageSync("changeCommData", { name: res.rows[0].name, id: res.rows[0].community_id })
uni.setStorageSync("isShowNav", res.rows[0].room_owner_list[0].type)
@ -215,7 +340,6 @@ export default {
if (this.communityList.length == 0) {
this.communityVal = "添加我的房产";
} else {
console.log("🚀 ~ onLoad ~ this.communityList:", this.communityList)
this.communityVal = uni.getStorageSync("changeCommData").name;
}
this.getfunctionNum();
@ -261,9 +385,13 @@ export default {
},
closeAds() {
this.ads1Show = false;
// 1
uni.setStorageSync('ads1Showed', true);
},
closeAds2() {
this.ads2Show = false;
// 2
uni.setStorageSync('ads2Showed', true);
},
jump(e) {
if (!e) {
@ -293,6 +421,7 @@ export default {
},
async getfunctionNum() {
this.functionList = this.defaultFunctionList;
const res = await request(
apiArr.commInfo,
"POST",
@ -318,16 +447,24 @@ export default {
console.log(res, "xx");
// rowNum colNum
const totalItems = this.rowNum * this.colNum;
// 使 slice totalItems
this.functionList = res.rows.slice(0, totalItems).map((item) => {
const totalItems = this.rowNum * this.colNum - 3;
// totalItems
const newItems = res.rows.slice(0, totalItems).map((item) => {
return {
...item,
nav_icon: picUrl + item.nav_icon,
};
});
console.log("functionList", this.functionList);
// nav_name
newItems.forEach(newItem => {
const exists = this.functionList.some(existingItem =>
existingItem.nav_name === newItem.nav_name
);
if (!exists) {
this.functionList.push(newItem);
}
});
},
async getAdvertising() {
@ -385,7 +522,9 @@ export default {
ad_picture: picUrl + item.ad_picture,
};
});
this.ads1Show = res4.rows.length !== 0 ? true : false;
// 1广
const ads1Showed = uni.getStorageSync('ads1Showed');
this.ads1Show = !ads1Showed && res4.rows.length !== 0 ? true : false;
const res5 = await request(apiArr.advPage, "POST", {
community_id: Number(uni.getStorageSync("changeCommData").id),
@ -399,7 +538,9 @@ export default {
ad_picture: picUrl + item.ad_picture,
};
});
this.ads2Show = res5.rows.length !== 0 ? true : false;
// 2广
const ads2Showed = uni.getStorageSync('ads2Showed');
this.ads2Show = !ads2Showed && res5.rows.length !== 0 ? true : false;
},
headerServerClick(e) {

View File

@ -0,0 +1,131 @@
page {
background-color: #f6f7fb;
}
.community-list-container {
padding: 20rpx;
min-height: 100vh;
}
.search-bar {
background-color: #fff;
padding: 20rpx;
border-radius: 10rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
}
.search-input {
display: flex;
align-items: center;
background-color: #f0f0f0;
border-radius: 50rpx;
padding: 15rpx 20rpx;
}
.search-icon {
width: 40rpx;
height: 40rpx;
font-family: 'iconfont';
color: #999;
margin-right: 15rpx;
font-size: 30rpx;
}
.search-input input {
flex: 1;
font-size: 28rpx;
color: #333;
background-color: transparent;
}
.community-list {
border-radius: 10rpx;
overflow: hidden;
}
.community-item {
padding: 20rpx;
display: flex;
margin-bottom: 15rpx;
background-color: #fff;
}
.community-item:last-child {
border-bottom: none;
}
.community-image {
width: 160rpx;
height: 160rpx;
border-radius: 10rpx;
overflow: hidden;
margin-right: 20rpx;
flex-shrink: 0;
}
.community-image image {
width: 100%;
height: 100%;
}
.community-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
}
.community-name {
font-size: 32rpx;
font-weight: bold;
color: #333;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
overflow: hidden;
}
.community-address {
font-size: 26rpx;
color: #666;
margin-top: 10rpx;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
overflow: hidden;
}
.community-distance {
font-size: 24rpx;
color: #999;
margin-top: 10rpx;
}
/* 适配不同屏幕尺寸 */
@media screen and (min-width: 768px) {
.community-list-container {
padding: 30rpx;
}
.community-item {
padding: 30rpx;
}
.community-image {
width: 200rpx;
height: 200rpx;
}
.community-name {
font-size: 36rpx;
}
.community-address {
font-size: 28rpx;
}
.community-distance {
font-size: 26rpx;
}
}

View File

@ -0,0 +1,85 @@
<template>
<view class="community-list-container">
<!-- <view class="search-bar">
<view class="search-input">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_communitySearchIcon.png"
mode="aspectFill" class="search-icon"></image>
<input type="text" placeholder="搜索社区" />
</view>
</view> -->
<view class="community-list">
<view class="community-item" v-for="(item, index) in communityList" :key="index">
<view class="community-image">
<image :src="item.image" mode="aspectFill"></image>
</view>
<view class="community-info">
<view class="community-name">{{ item.name }}</view>
<view class="community-address">{{ item.address }}</view>
<view class="community-distance">{{ item.distance }}</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'CommunityList',
data() {
return {
communityList: [
{
id: 1,
name: '凯旋城东区',
address: '衡水市,桃城-衡水市人民路与育才街交叉口西行100米路南',
distance: '0 m',
image: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test_community.png'
},
{
id: 2,
name: '岸芷庭蓝(一区)',
address: '衡水市,河阳西路与中华南大街交叉口东220米',
distance: '1000 m',
image: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test_community.png'
},
{
id: 3,
name: '滏阳锦苑',
address: '衡水市,滏阳苑',
distance: '2 km',
image: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test_community.png'
},
{
id: 4,
name: '隆兴小区',
address: '衡水市,河北省衡水市高新区隆兴西路隆兴小区',
distance: '5 km',
image: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test_community.png'
},
{
id: 5,
name: '紫金广场',
address: '衡水市,衡水市桃城区人民西路与庆丰南街交叉口',
distance: '894 km',
image: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test_community.png'
},
{
id: 6,
name: '万和瑞景',
address: '衡水市,政通街46号',
distance: '12249 km',
image: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test_community.png'
}
]
};
}
};
</script>
<style>
@import url("./index.css");
</style>

View File

@ -1,6 +1,40 @@
page {
background-color: #f6f7fb;
background-color: #ffffff;
padding: 0;
overflow-y: hidden;
}
.searchBox {
padding-bottom: 24rpx;
background-color: #fff;
margin-top: 105rpx;
}
.searchBox_add {
height: 100%;
width: 100%;
display: flex;
}
.searchBox_left {
flex: 1;
display: flex;
align-items: center;
padding-left: 20rpx;
}
.searchBox_mid {
flex: 1;
font-size: 40rpx;
color: #222222;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
.searchBox_right {
flex: 1;
}
.container {
@ -22,9 +56,22 @@ image {
margin-top: 180rpx;
}
.emptyTitle {
font-size: 36rpx;
color: #222222;
margin-top: 50rpx;
font-weight: bold;
}
.emptyMsg {
font-size: 28rpx;
color: #999999;
margin: 30rpx;
}
.empty image {
width: 340rpx;
height: 240rpx;
width: 500rpx;
height: 400rpx;
}
.addBtn {
@ -57,11 +104,13 @@ image {
border-bottom: 1rpx solid #EBEBEB;
padding: 30rpx 0;
}
.communityItem_left {
display: flex;
align-items: center;
}
.communityItem_left_img {
width: 160rpx;
height: 140rpx;
@ -69,9 +118,11 @@ image {
overflow: hidden;
margin-right: 30rpx;
}
.communityItem_left_msg {
flex: 1;
}
.communityItem_left_msg_tit {
font-size: 30rpx;
color: #222222;

View File

@ -1,35 +1,44 @@
<template>
<view class="container">
<view class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }">
<view class="searchBox_add">
<view class="searchBox_left">
<u-icon bold color="#000" size="40" name="arrow-left" @click="back"></u-icon>
</view>
<view class="searchBox_mid">我的房产</view>
<view class="searchBox_right"></view>
</view>
</view>
<view class="empty" v-if="communityList.length == 0">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_newEmpty.png"
alt="" />
没有添加任何房产
<view class="emptyTitle">绑定房源</view>
<view class="emptyMsg">请绑定房源信息 以便使用其他功能</view>
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/community_no_image3.png" alt="" />
</view>
<div class="communityList">
<div class="communityItem" v-for="item in communityList" :key="item.community_id"
<view class="communityList">
<view class="communityItem" v-for="item in communityList" :key="item.community_id"
@click="choseCommunity(item)">
<div class="communityItem_left">
<div class="communityItem_left_img">
<view class="communityItem_left">
<view class="communityItem_left_img">
<image :src="item.pic" mode="aspectFill"></image>
</div>
<div class="communityItem_left_msg">
<div class="communityItem_left_msg_tit">{{ item.name }}<span> {{ item.room_owner_list.length }}
</span></div>
<div class="communityItem_left_msg_msg">{{ item.addr }}</div>
</div>
</div>
<div class="communityItem_right">
</view>
<view class="communityItem_left_msg">
<view class="communityItem_left_msg_tit">{{ item.name }}<span> {{ item.room_owner_list.length
}}
</span></view>
<view class="communityItem_left_msg_msg">{{ item.addr }}</view>
</view>
</view>
<view class="communityItem_right">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png"
v-if="item.community_id != currentCommunity.id"></image>
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png"
v-if="item.community_id == currentCommunity.id"></image>
</div>
</div>
</div>
</view>
</view>
</view>
<div class="addBtn" @click="addCommunity">添加我的房产</div>
<view class="addBtn" @click="addCommunity">去绑定房源</view>
</view>
</template>
@ -53,6 +62,9 @@ export default {
}
},
methods: {
back() {
NavgateTo("/packages/community/index/index")
},
addCommunity() {
NavgateTo("/packages/community/addCommunity/index")
},
@ -80,7 +92,6 @@ export default {
uni.setStorageSync('changeCommData', { id: e.community_id, name: e.name });
uni.setStorageSync('currentCommunityAddr', e.addr);
uni.setStorageSync("isShowNav", e.room_owner_list[0].type)
console.log("🚀 ~ choseCommunity ~ e.room_owner_list[0].type:", e.room_owner_list[0].type)
NavgateTo("1")
},
},

View File

@ -1,97 +1,97 @@
<template>
<div class="container">
<div class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }">
<div class="searchBox_add">
<div class="searchBox_left">
<view class="container">
<view class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }">
<view class="searchBox_add">
<view class="searchBox_left">
<u-icon bold color="#000" size="40" name="arrow-left" @click="back"></u-icon>
</div>
<div class="searchBox_mid">报修信息</div>
<div class="searchBox_right"></div>
</div>
</div>
</view>
<view class="searchBox_mid">报修信息</view>
<view class="searchBox_right"></view>
</view>
</view>
<div class="repairMsg">
<div class="repairTit">
<view class="repairMsg">
<view class="repairTit">
报修信息
</div>
</view>
<div class="label"><span class="red">*</span>选择房源信息</div>
<div class="roomList">
<div v-for="(item, index) in roomList" :key="index" :class="active == index ?'roomItem active':'roomItem'" @click="changeAct(index)">{{ item.name }}</div>
</div>
<view class="label"><span class="red">*</span>选择房源信息</view>
<view class="roomList">
<view v-for="(item, index) in roomList" :key="index" :class="active == index ?'roomItem active':'roomItem'" @click="changeAct(index)">{{ item.name }}</view>
</view>
<div class="row">
<div class="row_label"><span class="red">*</span>报修类型</div>
<div class="row_con" @click="chose">
<view class="row">
<view class="row_label"><span class="red">*</span>报修类型</view>
<view class="row_con" @click="chose">
<input type="text" :value="category.category_name" placeholder="请选择报修类型" disabled>
<u-icon bold color="#999999" size="30" name="arrow-right"></u-icon>
</div>
</div>
</view>
</view>
<div class="row">
<div class="row_label"><span class="red">*</span>问题描述</div>
<div class="row_con">
<view class="row">
<view class="row_label"><span class="red">*</span>问题描述</view>
<view class="row_con">
<input type="text" placeholder="请描述故障" :value="repairInfo" data-name="repairInfo" @input="handlerInputClick">
</div>
</div>
</view>
</view>
<div class="row">
<div class="row_label"><span class="red">*</span>联系人</div>
<div class="row_con">
<view class="row">
<view class="row_label"><span class="red">*</span>联系人</view>
<view class="row_con">
<input type="text" placeholder="请输入您的姓名" :value="contactName" data-name="contactName" @input="handlerInputClick">
</div>
</div>
</view>
</view>
<div class="row">
<div class="row_label"><span class="red">*</span>联系电话</div>
<div class="row_con">
<view class="row">
<view class="row_label"><span class="red">*</span>联系电话</view>
<view class="row_con">
<input type="number" maxlength="11" placeholder="请输入您的联系方式" :value="contactPhone" data-name="contactPhone" @input="handlerInputClick">
</div>
</div>
</view>
</view>
<div class="row noneBorder">
<div class="row_label"><span class="red">*</span>上门时间</div>
<div class="row_con" @click="choseTime">
<view class="row noneBorder">
<view class="row_label"><span class="red">*</span>上门时间</view>
<view class="row_con" @click="choseTime">
<input type="text" :value="time" placeholder="请选择上门时间" disabled>
<u-icon bold color="#999999" size="30" name="arrow-right"></u-icon>
</div>
</div>
</div>
</view>
</view>
</view>
<div class="repairMedia">
<div class="row df">
<div class="row_label">上传图片</div>
<div class="row_con2">
<view class="repairMedia">
<view class="row df">
<view class="row_label">上传图片</view>
<view class="row_con2">
<u-upload :fileList="imgList" name="imgList" @afterRead="afterReadImg" @delete="deletePic" multiple
:maxCount="5">
<div class="imgCon">
<view class="imgCon">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_imageImg.png" mode="widthFix"></image>
上传图片
</div>
</view>
</u-upload>
</div>
</div>
</view>
</view>
<div class="row df">
<div class="row_label">上传视频</div>
<div class="row_con2">
<view class="row df">
<view class="row_label">上传视频</view>
<view class="row_con2">
<u-upload v-if="!videoList.url" :fileList="videoList" @afterRead="afterReadVideo" @delete="deleteVideo" name="videoList"
:maxCount="1" accept="video">
<div class="imgCon">
<view class="imgCon">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_videoImg.png" mode="widthFix"></image>
上传视频
</div>
</view>
</u-upload>
<div v-if="videoList.url" class="videoBOX">
<view v-if="videoList.url" class="videoBOX">
<video id="myVideo" :src="videoList.url" playsinline webkit-playsinline></video>
<div class="mask" @click="playFullScreenVideo">
<div class="mask_cancel" @click="cancels">删除</div>
</div>
</div>
</div>
</div>
</div>
<view class="mask" @click="playFullScreenVideo">
<view class="mask_cancel" @click="cancels">删除</view>
</view>
</view>
</view>
</view>
</view>
<u-picker :show="show" :columns="[columns]" keyName="category_name" @confirm="confirm1" @cancel="cancel1" />
<u-datetime-picker
@ -105,9 +105,9 @@
@close="cancel2"
/>
<div class="btn" @click="handlerSubmitClick">确认报修</div>
<view class="btn" @click="handlerSubmitClick">确认报修</view>
</div>
</view>
</template>
<script>

View File

@ -1,319 +1,255 @@
<template>
<div class="container">
<div
class="searchBox"
:style="{ height: localHeight + 'px', paddingTop: top + 'px' }"
>
<div class="searchBox_add">
<u-icon
bold
color="#000"
size="40"
name="arrow-left"
@click="back"
></u-icon>
</div>
</div>
<view class="container">
<view class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }">
<view class="searchBox_add">
<u-icon bold color="#000" size="40" name="arrow-left" @click="back"></u-icon>
</view>
</view>
<div class="community">
<div class="community_left">
<image
mode="aspectFill"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/test.png"
alt=""
/>
</div>
<div class="community_right" @click="changeShow">
<div class="community_right_text">
<div class="community_right_text1">{{ currentRoom.name }}</div>
<div class="community_right_text2">{{ currentCommunityAddr }}</div>
</div>
<div class="community_right_more">
<view class="community">
<view class="community_left">
<image mode="aspectFill" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/test.png"
alt="" />
</view>
<view class="community_right" @click="changeShow">
<view class="community_right_text">
<view class="community_right_text1">{{ currentRoom.name }}</view>
<view class="community_right_text2">{{ currentCommunityAddr }}</view>
</view>
<view class="community_right_more">
<u-icon bold color="#999999" size="30" name="arrow-right"></u-icon>
</div>
</div>
</div>
</view>
</view>
</view>
<div class="tabList">
<div
class="tabItem"
:class="active == 0 ? 'active' : ''"
@click="changeTab(0)"
>
<view class="tabList">
<view class="tabItem" :class="active == 0 ? 'active' : ''" @click="changeTab(0)">
账单
</div>
<div class="line"></div>
<div
class="tabItem"
:class="active == 1 ? 'active' : ''"
@click="changeTab(1)"
>
</view>
<view class="line"></view>
<view class="tabItem" :class="active == 1 ? 'active' : ''" @click="changeTab(1)">
缴费记录
</div>
</div>
</view>
</view>
<div class="homeMoney" v-if="active == 0">
<div class="homeMoney_box">
<div class="homeMoney_box_left">
<div class="homeMoney_box_left1">物业公积金</div>
<div class="homeMoney_box_left2">可抵扣账户金额</div>
</div>
<div class="homeMoney_box_right">
<div class="homeMoney_box_right1">
<view class="homeMoney" v-if="active == 0">
<view class="homeMoney_box">
<view class="homeMoney_box_left">
<view class="homeMoney_box_left1">物业公积金</view>
<view class="homeMoney_box_left2">可抵扣账户金额</view>
</view>
<view class="homeMoney_box_right">
<view class="homeMoney_box_right1">
<span></span>{{ balanceMoney }}
</div>
<div class="homeMoney_box_right2" @click="more(currentRoom)">
</view>
<view class="homeMoney_box_right2" @click="more(currentRoom)">
查看详情
<div style="margin-left: 12rpx">
<u-icon
bold
color="#894B11"
size="30"
name="arrow-right"
></u-icon>
</div>
</div>
</div>
</div>
</div>
<view style="margin-left: 12rpx">
<u-icon bold color="#894B11" size="30" name="arrow-right"></u-icon>
</view>
</view>
</view>
</view>
</view>
<div class="payList" v-if="active == 0">
<div class="payItem" v-for="(item, index) in Bill" :key="index">
<div class="payItem_tit">
<div class="payItem_left">
<checkbox
:checked="item.check"
@click="checkChange(item, index)"
></checkbox>
<div style="margin-left: 24rpx">{{ item.order_date }}</div>
</div>
<div class="payItem_right">
<view class="payList" v-if="active == 0">
<view class="payItem" v-for="(item, index) in Bill" :key="index">
<view class="payItem_tit">
<view class="payItem_left">
<checkbox :checked="item.check" @click="checkChange(item, index)"></checkbox>
<view style="margin-left: 24rpx">{{ item.order_date }}</view>
</view>
<view class="payItem_right">
<span></span>
<view class="payItem_money">{{ item.unpaid_amount }}</view>
<p>未缴</p>
<div style="margin-left: 40rpx" @click="changeCheck(item, index)">
<u-icon
bold
color="#894B11"
size="30"
name="arrow-down"
v-if="!item.more"
></u-icon>
<u-icon
bold
color="#894B11"
size="30"
name="arrow-up"
v-if="item.more"
></u-icon>
</div>
</div>
</div>
<div v-if="item.more">
<div
class="payItem_List"
v-for="(items, indes) in item.community_order_rows"
:key="items.order_id"
>
<checkbox
:checked="items.check"
@click="itemsCheckChange(items, indes, index)"
></checkbox>
<div class="Item_time" v-if="items.billing_cycle == 1">
<view style="margin-left: 40rpx" @click="changeCheck(item, index)">
<u-icon bold color="#894B11" size="30" name="arrow-down" v-if="!item.more"></u-icon>
<u-icon bold color="#894B11" size="30" name="arrow-up" v-if="item.more"></u-icon>
</view>
</view>
</view>
<view v-if="item.more">
<view class="payItem_List" v-for="(items, indes) in item.community_order_rows" :key="items.order_id">
<checkbox :checked="items.check" @click="itemsCheckChange(items, indes, index)"></checkbox>
<view class="Item_time" v-if="items.billing_cycle == 1">
{{ items.order_date }}
</div>
<div class="Item_time" v-if="items.billing_cycle == 2">
</view>
<view class="Item_time" v-if="items.billing_cycle == 2">
{{ items.order_datetime }}
</div>
<div class="Item_type">
</view>
<view class="Item_type">
{{ items.community_fee_type ? items.community_fee_type.type_name : '' }}
</div>
<div class="Item_money">{{ items.money }}</div>
<div class="Item_status" v-if="items.status == 0">未付款</div>
<div class="Item_status sucess" v-if="items.status == 1">
</view>
<view class="Item_money">{{ items.money }}</view>
<view class="Item_status" v-if="items.status == 0">未付款</view>
<view class="Item_status sucess" v-if="items.status == 1">
已付款
</div>
</div>
</div>
</div>
</div>
</view>
</view>
</view>
</view>
</view>
<!-- 选择支付类型 -->
<div class="payTypeList" v-if="active == 0">
<div class="PayTypeItem">
<div class="PayTypeItem_left">
<div class="PayTypeItem_img">
<image
mode="aspectFill"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_wechat.png"
alt=""
/>
</div>
<div class="PayTypeItem_con">
<div class="PayTypeItem_con_tit">微信支付</div>
<div class="PayTypeItem_con_msg">单笔支付限额10000.00</div>
</div>
</div>
<view class="payTypeList" v-if="active == 0">
<view class="PayTypeItem">
<view class="PayTypeItem_left">
<view class="PayTypeItem_img">
<image mode="aspectFill"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_wechat.png" alt="" />
</view>
<view class="PayTypeItem_con">
<view class="PayTypeItem_con_tit">微信支付</view>
<view class="PayTypeItem_con_msg">单笔支付限额10000.00</view>
</view>
</view>
<div class="PayTypeItem_right">
<view class="PayTypeItem_right">
<radio :checked="payType == 1" @click="changePayType(1)"></radio>
</div>
</div>
<div class="line3"></div>
<div class="PayTypeItem">
<div class="PayTypeItem_left">
<div class="PayTypeItem_img">
<image
mode="aspectFill"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_homeMoney.png"
alt=""
/>
</div>
<div class="PayTypeItem_con">
<div class="PayTypeItem_con_tit">物业公积金支付</div>
<div class="PayTypeItem_con_msg">
</view>
</view>
<view class="line3"></view>
<view class="PayTypeItem">
<view class="PayTypeItem_left">
<view class="PayTypeItem_img">
<image mode="aspectFill"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_homeMoney.png" alt="" />
</view>
<view class="PayTypeItem_con">
<view class="PayTypeItem_con_tit">物业公积金支付</view>
<view class="PayTypeItem_con_msg">
可用公积金<span></span>{{ balanceMoney }}
<div class="PayTypeItem_con_msg2" @click="changeShow2">
<view class="PayTypeItem_con_msg2" @click="changeShow2">
可组合支付
</div>
</div>
</div>
</div>
</view>
</view>
</view>
</view>
<div class="PayTypeItem_right">
<view class="PayTypeItem_right">
<radio :checked="payType == 2" @click="changePayType(2)"></radio>
</div>
</div>
</div>
</view>
</view>
</view>
<div class="bottom" v-if="active == 0">
<div class="bottom_left">
<view class="bottom" v-if="active == 0">
<view class="bottom_left">
<span>合计</span>
<p></p>
{{ currentMoney }}
</div>
<div class="bottom_right" @click="OrderPay">立即支付</div>
</div>
</view>
<view class="bottom_right" @click="createPay">立即支付</view>
</view>
<div class="payHisList" v-if="active == 1">
<div class="payHisItem" v-for="item in payOrderList" :key="item.id">
<div class="row">
<div class="row_label">缴费金额</div>
<div class="row_con1">{{ item.money }}</div>
</div>
<div class="row">
<div class="row_label2"></div>
<div class="row_con2">{{ item.pay_time }}支付</div>
</div>
<div class="line4"></div>
<div class="row">
<div class="row_label">绑定房源</div>
<div class="row_con3">
<div class="row_con3_1">
<view class="payHisList" v-if="active == 1">
<view class="payHisItem" v-for="item in payOrderList" :key="item.id">
<view class="row">
<view class="row_label">缴费金额</view>
<view class="row_con1">{{ item.money }}</view>
</view>
<view class="row">
<view class="row_label2"></view>
<view class="row_con2">{{ item.pay_time }}支付</view>
</view>
<view class="line4"></view>
<view class="row">
<view class="row_label">绑定房源</view>
<view class="row_con3">
<view class="row_con3_1">
{{ item.community_order.length }}个账单
</div>
<div class="row_con3_2">明细可从收据查看</div>
</div>
</div>
</view>
<view class="row_con3_2">明细可从收据查看</view>
</view>
</view>
<div class="row">
<div class="row_label">应缴费金额</div>
<div class="row_con4">{{ item.money }}</div>
</div>
<view class="row">
<view class="row_label">应缴费金额</view>
<view class="row_con4">{{ item.money }}</view>
</view>
<div class="row">
<div class="row_label">物业费公积金抵扣金额</div>
<div class="row_con4">-{{ item.reduction_money }}</div>
</div>
<view class="row">
<view class="row_label">物业费公积金抵扣金额</view>
<view class="row_con4">-{{ item.reduction_money }}</view>
</view>
<div class="row">
<div class="row_label">缴费单号</div>
<div class="row_con4">{{ item.order_pay_no }}</div>
</div>
<div class="line4"></div>
<div class="Receipt">收据</div>
</div>
</div>
<view class="row">
<view class="row_label">缴费单号</view>
<view class="row_con4">{{ item.order_pay_no }}</view>
</view>
<view class="line4"></view>
<view class="Receipt">收据</view>
</view>
</view>
<div class="boxshadow" v-if="show" @click="changeShow">
<div class="boxshadowCon">
<div class="boxshadowCon_Tit">
<view class="boxshadow" v-if="show" @click="changeShow">
<view class="boxshadowCon">
<view class="boxshadowCon_Tit">
选择房源
<div class="cancel" @click.stop="show = false">取消</div>
</div>
<div class="lines"></div>
<div class="communityList" v-if="roomList.length > 0">
<div
class="communityItem"
v-for="item in roomList"
:key="item.room_id"
@click="selectRoom(item)"
>
<div class="communityItem_text">
<view class="cancel" @click.stop="show = false">取消</view>
</view>
<view class="lines"></view>
<view class="communityList" v-if="roomList.length > 0">
<view class="communityItem" v-for="item in roomList" :key="item.room_id" @click="selectRoom(item)">
<view class="communityItem_text">
{{ item.facility_name }}{{ item.floor }} {{ item.number }}
</div>
<div class="communityItem_radio">
</view>
<view class="communityItem_radio">
<radio :checked="selectedRoomId === item.room_id"></radio>
</div>
</div>
</div>
<div class="communityList" v-else>
<div class="communityItem">
<div class="communityItem_text">暂无房源</div>
</div>
</div>
</div>
</div>
</view>
</view>
</view>
<view class="communityList" v-else>
<view class="communityItem">
<view class="communityItem_text">暂无房源</view>
</view>
</view>
</view>
</view>
<div class="boxshadow" v-if="show2" @click="changeShow2">
<div class="boxshadowCon">
<div class="boxshadowCon_Tit">
<view class="boxshadow" v-if="show2" @click="changeShow2">
<view class="boxshadowCon">
<view class="boxshadowCon_Tit">
付款总金额
<div class="cancel" @click.stop="show2 = false">取消</div>
</div>
<div class="boxshadowCon_subTit">
<view class="cancel" @click.stop="show2 = false">取消</view>
</view>
<view class="boxshadowCon_subTit">
<p></p>
{{ currentMoney }}
</div>
<div class="lines"></div>
</view>
<view class="lines"></view>
<div class="BanlenceList">
<div class="banlenceItem">
<div class="banlenceItem_left">
<image
mode="aspectFill"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_wechat.png"
alt=""
/>
<view class="BanlenceList">
<view class="banlenceItem">
<view class="banlenceItem_left">
<image mode="aspectFill"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_wechat.png" alt="" />
微信支付
</div>
<div class="banlenceItem_right">
</view>
<view class="banlenceItem_right">
<span></span>{{ (currentMoney - balanceMoney).toFixed(2) }}
</div>
</div>
<div class="line3"></div>
<div class="banlenceItem">
<div class="banlenceItem_left">
<image
mode="aspectFill"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_homeMoney.png"
alt=""
/>
</view>
</view>
<view class="line3"></view>
<view class="banlenceItem">
<view class="banlenceItem_left">
<image mode="aspectFill"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_homeMoney.png" alt="" />
物业公积金支付
</div>
<div class="banlenceItem_right">
</view>
<view class="banlenceItem_right">
<span></span>{{ balanceMoney }}
</div>
</div>
</div>
</view>
</view>
</view>
<div class="btn" @click="OrderPay">
<view class="btn" @click="createPay">
物业公积金+微信支付 <span></span>{{ currentMoney }}
</div>
</div>
</div>
</div>
</view>
</view>
</view>
</view>
</template>
<script>
@ -533,7 +469,7 @@ export default {
}).then((res) => {
console.log(res);
this.payInfoId = res.id;
this.getPayInfo();
this.OrderPay();
});
},
//
@ -547,15 +483,22 @@ export default {
//
async OrderPay() {
// this.payInfoId
await request(apiArr.OrderPay, "POST", { order_pay_id: 6 }).then(
await request(apiArr.OrderPay, "POST", { order_pay_id: this.payInfoId }).then(
async (res) => {
const params = {
order_pay_id: this.payInfoId,
}
await request(apiArr.OrderPay, "POST", params).then(
(res) => {
console.log(res);
}
);
}
);
},
//
getPayList() {
request(apiArr.getPayOrderList, "POST", {
room_id: this.currentRoom.room_id,
page_num: this.page_num,
@ -569,7 +512,7 @@ export default {
flag = false;
}
this.flag = flag;
this.payOrderList = this.payOrderList.concat(res.rows);
this.payOrderList = res.rows;
});
},

View File

@ -1,3 +1,7 @@
/* .box{
padding-bottom: 100rpx;
} */
.searchBox {
padding-bottom: 24rpx;
background-color: #fff;
@ -65,6 +69,10 @@
transform: translateX(-50%);
}
.orderListBox{
padding-bottom: 220rpx;
}
.orderList {
margin-top: 20rpx;
@ -167,7 +175,11 @@ page {
align-items: center;
justify-content: center;
margin: 0 auto;
margin-top: 200rpx;
position: fixed;
bottom: 100rpx;
left: 50%;
transform: translateX(-50%);
z-index: 99;
}

View File

@ -25,7 +25,7 @@
</view>
</view>
<view v-if="list.length !== 0">
<view v-if="list.length !== 0" class="orderListBox">
<view class="orderList" v-for="(item, index) in list" :key="index">
<view class="orderItem" @click="handlerDetailClick(item.id)">
<view :class="['orderItemTit', statusType[item.status].style]">

View File

@ -1,667 +0,0 @@
<template>
<view>
<view class="express">
<!-- Step Navigation -->
<view class="strideList">
<view class="strideItem" :class="{active: step == 1}" @tap="changeItem(1)">基础<br />信息</view>
<view class="icons">
<image
:src="step != 2 ? 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/play_1.png' : 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/play_2.png'"
mode="widthFix" />
</view>
<view class="strideItem" :class="{active: step == 2}" @tap="changeItem(2)">病历<br />信息</view>
<view class="icons">
<image
:src="step != 3 ? 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/play_1.png' : 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/play_2.png'"
mode="widthFix" />
</view>
<view class="strideItem" :class="{active: step == 3}" @tap="changeItem(3)">生活<br />方式</view>
<view class="icons">
<image
:src="step != 4 ? 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/play_1.png' : 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/play_2.png'"
mode="widthFix" />
</view>
<view class="strideItem" :class="{active: step == 4}" @tap="changeItem(4)">授权<br />用户</view>
</view>
<!-- Step 1: Basic Information -->
<view class="basic" v-if="step == 1">
<view class="basic_row">
<view class="basic_row_tit">姓名</view>
<view class="basic_row_con">
<input v-model="name" placeholder="请填写您的姓名" placeholder-style="color: #999999;font-size: 26rpx" />
</view>
</view>
<view class="basic_row">
<view class="basic_row_tit">电话</view>
<view class="basic_row_con">
<input v-model="phone" type="number" maxlength="11" placeholder="请填写您的电话"
placeholder-style="color: #999999;font-size: 26rpx" />
</view>
</view>
<view class="basic_row">
<view class="basic_row_tit">性别</view>
<view class="basic_row_con">
<view class="sex" :class="{active2: sex == 'man'}" @tap="changeSex('man')">
<view class="cir"></view>
</view>
<view class="sex" :class="{active2: sex == 'woman'}" @tap="changeSex('woman')">
<view class="cir"></view>
</view>
</view>
</view>
<view class="basic_row">
<view class="basic_row_tit">出生日期</view>
<view class="basic_row_con" @tap="changeShow">
<input v-model="time" disabled placeholder="请选择您的出生日期"
placeholder-style="color: #999999;font-size: 26rpx" />
</view>
</view>
<view class="basic_row">
<view class="basic_row_tit">身高</view>
<view class="basic_row_con">
<input v-model="height" placeholder="请填写身高(单位cm)" placeholder-style="color: #999999;font-size: 26rpx" />
</view>
</view>
<view class="basic_row none">
<view class="basic_row_tit">体重</view>
<view class="basic_row_con">
<input v-model="weight" placeholder="请填写体重(单位Kg)" placeholder-style="color: #999999;font-size: 26rpx" />
</view>
</view>
<view class="btn" @click="headerStepClick">下一步</view>
</view>
<!-- Step 2: Medical Information -->
<view class="infomation" v-if="step == 2">
<view class="basic_row">
<view class="basic_row_tit">血值类型</view>
<view class="basic_row_con" @tap="changeShow2('bloodType', '血脂类型')">
<input v-model="bloodType" disabled placeholder="请选择您的血值类型"
placeholder-style="color: #999999;font-size: 26rpx" />
</view>
</view>
<view class="basic_row">
<view class="basic_row_tit">糖尿病类型</view>
<view class="basic_row_con" @tap="changeShow2('diabetesType', '糖尿病类型')">
<input v-model="diabetesType" disabled placeholder="请选择您的糖尿病类型"
placeholder-style="color: #999999;font-size: 26rpx" />
</view>
</view>
<view class="basic_row">
<view class="basic_row_tit">血压类型</view>
<view class="basic_row_con" @tap="changeShow2('bloodPressure', '血压类型')">
<input v-model="bloodPressure" disabled placeholder="请选择您的血压类型"
placeholder-style="color: #999999;font-size: 26rpx" />
</view>
</view>
<view class="basic_row2">
<view class="basic_row_tit">既往病史</view>
<view class="illnessList">
<view class="illnessItem" :class="{checked: pastCase === 'a'}" @tap="headerInputClick2('pastCase', 'a')">胸闷
</view>
<view class="illnessItem" :class="{checked: pastCase === 'b'}" @tap="headerInputClick2('pastCase', 'b')">心慌
</view>
<view class="illnessItem" :class="{checked: pastCase === 'c'}" @tap="headerInputClick2('pastCase', 'c')">头晕
</view>
<view class="illnessItem" :class="{checked: pastCase === 'd'}" @tap="headerInputClick2('pastCase', 'd')">痛风
</view>
<view class="illnessItem" :class="{checked: pastCase === 'e'}" @tap="headerInputClick2('pastCase', 'e')">
脑血管疾病</view>
<view class="illnessItem" :class="{checked: pastCase === 'f'}" @tap="headerInputClick2('pastCase', 'f')">
急性并发症</view>
<view class="illnessItem" :class="{checked: pastCase === 'g'}" @tap="headerInputClick2('pastCase', 'g')">
心脏疾病</view>
<view class="illnessItem" :class="{checked: pastCase === 'h'}" @tap="headerInputClick2('pastCase', 'h')">其他
</view>
<!-- 其他病史选项... -->
</view>
</view>
<view class="basic_row2">
<view class="basic_row_tit">既往用药</view>
<view class="drugList">
<view class="drugItem" :class="{checked: pharmacy === 'a'}" @tap="headerInputClick2('pharmacy', 'a')">他汀类降脂药
</view>
<view class="drugItem" :class="{checked: pharmacy === 'b'}" @tap="headerInputClick2('pharmacy', 'b')">中药降脂
</view>
<view class="drugItem" :class="{checked: pharmacy === 'c'}" @tap="headerInputClick2('pharmacy', 'c')">中药降酸药
</view>
<view class="drugItem" :class="{checked: pharmacy === 'd'}" @tap="headerInputClick2('pharmacy', 'd')">其他
</view>
</view>
</view>
<view class="basic_row none">
<view class="basic_row_tit">用药时间</view>
<view class="basic_row_con">
<view class="sex" :class="{active2: drugTime == '3'}" @tap="changeTime('3')">
<view class="cir"></view>3
</view>
<view class="sex" :class="{active2: drugTime == '1'}" @tap="changeTime('1')">
<view class="cir"></view>一年以内
</view>
</view>
</view>
<view class="btn" @click="headerStepClick">下一步</view>
</view>
<!-- Step 3: Lifestyle -->
<view class="life" v-if="step == 3">
<!-- 生活方式表单内容... -->
<view class="basic_row3" style="margin-top: 20rpx;">
<view class="basic_row_tit">吸烟情况</view>
<view class="basic_row_con3">
<view class="sex" :class="{ active2: smoke === 'no' }" @click="handleSelect('smoke', 'no')">
<view class="cir"></view>从不
</view>
<view class="sex" :class="{ active2: smoke === 'ring' }" @click="handleSelect('smoke', 'ring')">
<view class="cir"></view>已戒烟
</view>
<view class="sex" :class="{ active2: smoke === 'yes' }" @click="handleSelect('smoke', 'yes')">
<view class="cir"></view>吸烟
</view>
</view>
</view>
<!-- 饮酒情况 -->
<view class="basic_row3">
<view class="basic_row_tit">饮酒情况</view>
<view class="basic_row_con3">
<view class="sex" :class="{ active2: drink === 'no' }" @click="handleSelect('drink', 'no')">
<view class="cir"></view>从不
</view>
<view class="sex" :class="{ active2: drink === 'once' }" @click="handleSelect('drink', 'once')">
<view class="cir"></view>偶尔
</view>
<view class="sex" :class="{ active2: drink === 'yes' }" @click="handleSelect('drink', 'yes')">
<view class="cir"></view>经常
</view>
<view class="sex" :class="{ active2: drink === 'ring' }" @click="handleSelect('drink', 'ring')">
<view class="cir"></view>戒酒
</view>
</view>
</view>
<!-- 日常工作 -->
<view class="basic_row3">
<view class="basic_row_tit">日常工作</view>
<view class="basic_row_con3">
<view class="sex" :class="{ active2: dailyWork === 'easy' }" @click="handleSelect('dailyWork', 'easy')">
<view class="cir"></view>轻体力劳动
</view>
<view class="sex" :class="{ active2: dailyWork === 'in' }" @click="handleSelect('dailyWork', 'in')">
<view class="cir"></view>中体力劳动
</view>
<view class="sex" :class="{ active2: dailyWork === 'repeat' }" @click="handleSelect('dailyWork', 'repeat')">
<view class="cir"></view>重体力劳动
</view>
<view class="sex" :class="{ active2: dailyWork === 'rest' }" @click="handleSelect('dailyWork', 'rest')">
<view class="cir"></view>休息
</view>
</view>
</view>
<!-- 运动情况 -->
<view class="basic_row3">
<view class="basic_row_tit">运动情况</view>
<view class="basic_row_con3">
<view class="sex" :class="{ active2: motion === 'lack' }" @click="handleSelect('motion', 'lack')">
<view class="cir"></view>2
</view>
<view class="sex" :class="{ active2: motion === 'once' }" @click="handleSelect('motion', 'once')">
<view class="cir"></view>3-5
</view>
<view class="sex" :class="{ active2: motion === 'days' }" @click="handleSelect('motion', 'days')">
<view class="cir"></view>每天
</view>
<view class="sex" :class="{ active2: motion === 'no' }" @click="handleSelect('motion', 'no')">
<view class="cir"></view>无运动
</view>
</view>
</view>
<!-- 睡眠情况 -->
<view class="basic_row3 none">
<view class="basic_row_tit">睡眠情况</view>
<view class="basic_row_con3">
<view class="sex" :class="{ active2: sleep === 'law' }" @click="handleSelect('sleep', 'law')">
<view class="cir"></view>规律
</view>
<view class="sex" :class="{ active2: sleep === 'noLaw' }" @click="handleSelect('sleep', 'noLaw')">
<view class="cir"></view>熬夜
</view>
<view class="sex" :class="{ active2: sleep === 'overturn' }" @click="handleSelect('sleep', 'overturn')">
<view class="cir"></view>黑白颠倒
</view>
<view class="sex" :class="{ active2: sleep === 'rest' }" @click="handleSelect('sleep', 'rest')">
<view class="cir"></view>其他
</view>
</view>
</view>
<view class="btn" @click="headerStepClick">下一步</view>
</view>
<!-- Step 4: Authorization -->
<view class="user" v-if="step == 4">
<!-- 授权表单内容... -->
<view class="basic_row3 none">
<view class="basic_row_tit">档案授权</view>
<view class="basic_row_con2">
<view
class="sex"
:class="{ active2: accredit === 'owner' }"
@click="handleSelect('accredit', 'owner')"
>
<view class="cir"></view>对所有人员开放
</view>
<view
class="sex"
:class="{ active2: accredit === 'family' }"
@click="handleSelect('accredit', 'family')"
>
<view class="cir"></view>对家庭成员开放
</view>
<view
class="sex"
:class="{ active2: accredit === 'serve' }"
@click="handleSelect('accredit', 'serve')"
>
<view class="cir"></view>对服务人员开放
</view>
<view
class="sex"
:class="{ active2: accredit === 'oneself' }"
@click="handleSelect('accredit', 'oneself')"
>
<view class="cir"></view>只允许自己查看
</view>
</view>
</view>
<view class="btn" bind:tap="headerSubmitClick">提交</view>
</view>
</view>
<!-- Date Picker Popup -->
<u-popup :show="show" mode="bottom" round close-on-click-overlay>
<view style="width: 100%;">
<u-datetime-picker mode="date" :show="show" :formatter="formatter" @cancel="onClose"
@confirm="onInput"></u-datetime-picker>
</view>
</u-popup>
<!-- Blood Type Picker Popup -->
<u-popup :show="show2" mode="bottom" round close-on-click-overlay>
<view style="width: 100%;">
<u-picker :columns="columns" :show="show2" :title="PopupTitle" @confirm="onInput2" @cancel="onClose2"
show-toolbar></u-picker>
</view>
</u-popup>
</view>
</template>
<script>
export default {
data() {
return {
step: 1,
name: '',
phone: '',
sex: '',
time: '',
height: '',
weight: '',
bloodType: '',
diabetesType: '',
bloodPressure: '',
pastCase: '',
pharmacy: '',
drugTime: '',
smoke: '',
drink: '',
dailyWork: '',
motion: '',
sleep: '',
accredit: '',
show: false,
show2: false,
currentDate: new Date().getTime(),
popupType: '',
PopupTitle: '',
columns: [], // Your picker options
formatter(type, value) {
if (type === 'year') {
return `${value}`;
}
if (type === 'month') {
return `${value}`;
}
if (type === 'day') {
return `${value}`;
}
return value;
}
}
},
methods: {
changeItem(step) {
this.step = step;
},
changeSex(sex) {
this.sex = sex;
},
changeTime(time) {
this.drugTime = time;
},
changeShow() {
this.show = true;
console.log(this.show, 'asdasd');
},
changeShow2(type, title) {
this.popupType = type;
this.PopupTitle = title;
this.show2 = true;
},
headerInputClick(e) {
this[e.currentTarget.dataset.name] = e.detail.value;
},
headerInputClick2(name, val) {
this[name] = val;
},
headerStepClick() {
this.step++;
},
headerSubmitClick() {
// Submit logic
},
onClose() {
this.show = false;
},
onClose2() {
this.show2 = false;
},
onInput(e) {
this.time = this.$u.timeFormat(e.value, 'yyyy-mm-dd');
this.show = false;
},
onInput2(e) {
this[this.popupType] = e[0];
this.show2 = false;
},
handleSelect(name,val) {
console.log(name,val);
this[name] = val;
return;
},
}
}
</script>
<style scoped>
image {
width: 100%;
height: 100%;
}
.strideList {
display: flex;
align-items: center;
justify-content: space-between;
margin: 0 43rpx;
}
.strideItem {
width: 120rpx;
height: 120rpx;
background: #D9D9D9;
border-radius: 50%;
overflow: hidden;
font-weight: 400;
font-size: 32rpx;
color: #FFFFFF;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.icons {
width: 26rpx;
height: 26rpx;
}
.active {
background: #FF512A;
}
.strideList {
margin-top: 42rpx;
}
.basic {
margin: 0 20rpx;
margin-top: 62rpx;
}
.basic_row {
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1rpx solid #E6E6E6;
height: 90rpx;
}
.basic_row_tit {
font-weight: 400;
font-size: 26rpx;
color: #222222;
}
.basic_row_con {
text-align: right;
display: flex;
align-items: center;
height: 100%;
}
.basic_row_con input {
height: 90rpx;
}
.sex {
display: flex;
align-items: center;
font-weight: 400;
font-size: 26rpx;
color: #222222;
margin-left: 40rpx;
}
.cir {
width: 30rpx;
height: 30rpx;
border-radius: 50%;
border: 1rpx solid #555555;
margin-right: 16rpx;
box-sizing: border-box;
}
.active2 .cir {
background-color: #ff512a;
border: none;
}
.none {
border-bottom: none;
}
.btn {
font-weight: 400;
font-size: 36rpx;
color: #FFFFFF;
width: 650rpx;
height: 80rpx;
background: #FF512A;
border-radius: 100rpx 100rpx 100rpx 100rpx;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto;
margin-top: 64rpx;
}
.infomation {
margin: 0 20rpx;
margin-top: 92rpx;
padding-bottom: 60rpx;
}
.basic_row2 {
display: flex;
flex-direction: column;
padding-top: 30rpx;
}
.illnessItem {
width: 150rpx;
height: 50rpx;
background: #F0F0F0;
border-radius: 100rpx 100rpx 100rpx 100rpx;
font-weight: 400;
font-size: 26rpx;
color: #999999;
display: flex;
align-items: center;
justify-content: center;
margin-right: 20rpx;
margin-bottom: 20rpx;
}
.illnessList {
margin-top: 30rpx;
display: flex;
flex-wrap: wrap;
}
.basic_row2 .ipts {
border-bottom: 1rpx solid #E6E6E6;
padding: 30rpx 0;
}
.drugList {
display: flex;
flex-wrap: wrap;
margin-top: 25rpx;
}
.drugItem {
background: #F0F0F0;
border-radius: 100rpx 100rpx 100rpx 100rpx;
white-space: nowrap;
font-weight: 400;
font-size: 26rpx;
color: #999999;
padding: 10rpx;
margin-right: 20rpx;
margin-bottom: 20rpx;
}
.checked {
background: #FF512A;
color: #FFFFFF;
}
.life {
margin: 0 52rpx;
}
.life .basic_row {
width: 100%;
justify-content: flex-start;
min-height: 90rpx;
}
.life .basic_row_tit {
white-space: nowrap;
margin-right: 32rpx;
}
.life .basic_row_con {
flex-wrap: wrap;
}
.life .sex {
margin: 15rpx 0;
margin-right: 16rpx;
}
.basic_row_con3 {
display: flex;
align-items: center;
flex-wrap: wrap;
}
.basic_row3 {
min-height: 90rpx;
display: flex;
padding-top: 30rpx;
padding-bottom: 30rpx;
align-items: flex-start;
border-bottom: 1rpx solid #E6E6E6;
}
.basic_row_con3 .sex {
margin-top: 0;
}
.life .none {
border-bottom: none;
}
.user {
margin: 0 52rpx;
margin-top: 92rpx;
}
.user .none {
border-bottom: none;
}
.user .sex {
margin-bottom: 30rpx;
}
</style>

View File

@ -1,611 +0,0 @@
<template>
<view class="headlth">
<!-- Swiper Section -->
<view class="swiper">
<swiper :autoplay="true" :interval="3000" :duration="500">
<swiper-item>
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/health_img.png" mode="widthFix" />
</swiper-item>
</swiper>
</view>
<!-- Tab List -->
<view class="tabList">
<view class="tabItem" v-for="(item, index) in tabList" :key="index" @tap="jump(item.url)">
<view class="tabImg">
<image :src="item.img" mode="heightFix" />
</view>
<view class="tabName">
{{item.name}}
</view>
</view>
</view>
<view class="gray"></view>
<!-- Hot Services -->
<view class="tit">
热门服务
</view>
<view class="serviceTag">
<view class="serviceTagItem" v-for="(service, idx) in healthServices" :key="idx">
<view class="serviceTagItem_name">{{service.name}}</view>
<view class="serviceTagItem_msg">{{service.value}}</view>
<view :class="'serviceTagItem_img' + (idx+1)">
<image :src="service.icon" mode="widthFix" />
</view>
</view>
</view>
<view class="gray"></view>
<!-- Tabs -->
<view class="tabs">
<view class="tab" :class="{active: tabIndex == 0}" @tap="changeTab(0)">服务列表</view>
<view class="tab" :class="{active: tabIndex == 1}" @tap="changeTab(1)">商户列表</view>
</view>
<!-- Service List -->
<view class="list_item" v-if="tabIndex == 0" v-for="(item, index) in serverList" :key="index">
<view class="item_tit">
<view class="item_tit_left">{{item.cate_name}}</view>
<view class="item_tit_right" @tap="ServerMore(item.cate_id)">
更多
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/water_filter/filter_more.png"
mode="widthFix" />
</view>
</view>
<view class="item_goodsList">
<view class="item_goodsItem" v-for="(items, subIndex) in item.appoints" :key="subIndex"
@tap="ServerDesc(items.appoint_id)">
<view class="item_goodsItem_tit">
<image :src="items.photo" mode="aspectFill" />
</view>
<view class="item_goodsItem_name">{{items.title}}</view>
<view class="item_goodsItem_msg">
<view>{{items.price}}</view>
<text>/{{items.unit}}</text>
</view>
</view>
</view>
</view>
<!-- Merchant List -->
<view class="merchantList" v-if="tabIndex == 1">
<view class="merchantItem" v-for="(item, index) in 4" :key="index">
<view class="merchantItem_left">
<view class="merchantItem_left_img">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/gropBuy/goods.png" mode="widthFix" />
</view>
<view class="merchantItem_left_msg">
<view class="merchantItem_left_msg_tit">永训医疗</view>
<view class="merchantItem_left_msg_add">衡阳市石鼓区中山北路1号</view>
<view class="merchantItem_left_msg_msg">中国领先的高科技医疗设备研...</view>
<view class="merchantItem_left_msg_tag">健康 卫生 先进</view>
</view>
</view>
<view class="merchantItem_right">
电话询价
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
tabList: [{
name: "快速建档",
img: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/health_icon1.png',
url: "../express/express",
},
{
name: "健康自测",
img: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/health_icon2.png',
url: "../SelfTest/SelfTest",
},
{
name: "健康管理",
img: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/health_icon3.png',
url: "",
},
{
name: "上门服务",
img: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/health_icon4.png',
url: "/packages/doorToDoor/pages/doorToDoor/doorToDoor",
},
{
name: "自检报告",
img: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/health_icon5.png',
url: "../report/report",
},
{
name: "健康饮食",
img: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/health_icon6.png',
url: "../food/food",
},
{
name: "健康运动",
img: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/health_icon7.png',
url: "../sports/sports",
},
{
name: "社区商城",
img: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/health_icon8.png',
url: "",
},
],
healthServices: [{
name: '体温',
value: '37°C',
icon: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/health_icon_1.png'
},
{
name: '血压',
value: '37mmHg',
icon: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/health_icon_2.png'
},
{
name: '血糖',
value: '37mmol/L',
icon: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/health_icon_3.png'
},
{
name: '心率',
value: '37次/分',
icon: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/health_icon_4.png'
}
],
tabIndex: 0,
serverList:[
{
cate_name: '家政保洁',
appoints: [
{
appoint_id: 1,
photo: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/Mask_group_1.png',
title: '上门抽血',
price: 45,
unit: '次',
},
{
appoint_id: 2,
photo: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/Mask_group_2.png',
title: '上门肌注',
price: 65,
unit: '次',
},
{
appoint_id: 3,
photo: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/Mask_group_3.png',
title: '脐带护理',
price: 95,
unit: '次',
}
]
},
{
cate_name: '健康养生',
appoints: [
{
appoint_id: 1,
photo: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/Mask_group_4.png',
title: '体质养生',
price: 45,
unit: '张',
},
{
appoint_id: 2,
photo: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/Mask_group_5.png',
title: '四季养生',
price: 300,
unit: '套',
},
{
appoint_id: 3,
photo: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/Mask_group_6.png',
title: '肝脾养生',
price: 451,
unit: '套',
}
]
},
{
cate_name: '跑腿服务',
appoints: [
{
appoint_id: 1,
photo: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/Mask_group_7.png',
title: '同城快递',
price: 45,
unit: '件',
},
{
appoint_id: 2,
photo: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/Mask_group_8.png',
title: '快递代取',
price: 300,
unit: '件',
},
{
appoint_id: 3,
photo: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/Mask_group_9.png',
title: '外卖代取',
price: 451,
unit: '件',
}
]
},
{
cate_name: '设备配套',
appoints: [
{
appoint_id: 1,
photo: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/Mask_group_10.png',
title: '血糖计',
price: 45,
unit: '个',
},
{
appoint_id: 2,
photo: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/Mask_group_11.png',
title: '血压计',
price: 300,
unit: '个',
},
{
appoint_id: 3,
photo: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/health/Mask_group_12.png',
title: '尿酸检测仪',
price: 451,
unit: '个',
}
]
}
],//
}
},
methods: {
jump(url) {
uni.navigateTo({
url: url
});
},
changeTab(index) {
this.tabIndex = index;
},
ServerMore(cateId) {
// Handle more click
console.log('More clicked for category:', cateId);
},
ServerDesc(appointId) {
// Handle service description click
console.log('Service clicked:', appointId);
}
},
onLoad() {
// Load your data here
// this.loadTabList();
// this.loadServerList();
}
}
</script>
<style scoped>
image {
width: 100%;
height: 100%;
}
.swiper {
width: 710rpx;
height: 300rpx;
margin: 0 auto;
margin-top: 30rpx;
}
.swiper .swiper {
width: 100%;
height: 100%;
}
.swiper image {
width: 100%;
height: 100%;
}
.tabList {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin-top: 40rpx;
}
.tabItem {
display: flex;
width: 25%;
align-items: center;
flex-direction: column;
margin-bottom: 46rpx;
}
.tabImg {
height: 54rpx;
}
.tabName {
font-weight: 400;
font-size: 26rpx;
color: #222222;
}
.tit {
font-weight: bold;
font-size: 32rpx;
color: #222222;
margin-left: 20rpx;
padding-top: 30rpx;
}
.serviceTag {
display: flex;
justify-content: space-between;
padding: 0 20rpx;
box-sizing: border-box;
margin-top: 30rpx;
padding-bottom: 30rpx;
}
.serviceTagItem {
width: 171rpx;
height: 212rpx;
background: linear-gradient(148deg, #FFF3EF 0%, #FFD0C0 100%);
border-radius: 30rpx 30rpx 30rpx 30rpx;
box-sizing: border-box;
padding-left: 28rpx;
padding-top: 37rpx;
position: relative;
}
.serviceTagItem_name {
font-weight: bold;
font-size: 28rpx;
color: #000000;
}
.serviceTagItem_msg {
margin-top: 76rpx;
margin-left: 0rpx;
z-index: 2;
position: relative;
}
.serviceTagItem_img1 {
width: 70rpx;
height: 105rpx;
position: absolute;
bottom: 5rpx;
right: 8rpx;
}
.serviceTagItem_img2 {
width: 68.89rpx;
height: 87.54rpx;
position: absolute;
bottom: 15rpx;
right: 6rpx;
}
.serviceTagItem_img3 {
height: 79rpx;
width: 71rpx;
position: absolute;
bottom: 18rpx;
right: 7rpx;
}
.serviceTagItem_img4 {
width: 70rpx;
height: 105rpx;
position: absolute;
bottom: 5rpx;
right: 8rpx;
}
.tabs {
display: flex;
align-items: center;
margin-left: 20rpx;
padding-top: 30rpx;
}
.tabs .tab {
font-weight: 400;
font-size: 28rpx;
color: #555555;
margin-right: 70rpx;
}
.tabs .active {
font-weight: bold;
font-size: 32rpx;
position: relative;
}
.tabs .active::after {
content: '';
width: 127rpx;
height: 10rpx;
background: #FF512A;
position: absolute;
left: 50%;
bottom: -10rpx;
transform: translateX(-50%);
}
.tabs .active::before {
width: 127rpx;
height: 10rpx;
filter: blur(6.599999904632568rpx);
background: #FF5D73;
position: absolute;
left: 50%;
bottom: -10rpx;
transform: translateX(-50%);
}
.list {
margin-top: 36rpx;
}
.item_tit {
display: flex;
align-items: center;
justify-content: space-between;
margin: 0 20rpx;
margin-bottom: 32rpx;
margin-top: 30rpx;
}
.item_tit_left {
font-weight: bold;
font-size: 28rpx;
color: #000000;
}
.item_tit_right {
font-weight: 400;
font-size: 24rpx;
color: #D5AC66;
display: flex;
align-items: center;
}
.item_tit_right image {
width: 12rpx;
height: 22rpx;
margin-left: 8rpx;
}
.item_goodsItem_tit {
width: 223rpx;
height: 161rpx;
}
.item_goodsItem_name {
font-weight: 400;
font-size: 26rpx;
color: #222222;
margin-top: 20rpx;
margin-left: 10rpx;
}
.item_goodsItem_msg {
font-weight: 400;
font-size: 22rpx;
color: #FF512A;
display: flex;
align-items: flex-end;
margin-top: 6rpx;
margin-left: 13rpx;
}
.item_goodsItem_msg view {
font-weight: 500;
font-size: 36rpx;
}
.item_goodsItem_msg text {
font-size: 22rpx;
color: #FF512A;
}
.item_goodsList {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20rpx;
}
.list_item {
padding-bottom: 32rpx;
border-bottom: 1rpx solid #E6E6E6;
}
.merchantList {
margin: 0 20rpx;
margin-top: 30rpx;
}
.merchantItem {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx 0;
border-bottom: 1rpx solid #E6E6E6;
box-sizing: border-box;
}
.merchantItem_right {
font-weight: 400;
font-size: 26rpx;
color: #FFFFFF;
width: 150rpx;
height: 50rpx;
background: #D5AC66;
border-radius: 100rpx 100rpx 100rpx 100rpx;
display: flex;
align-items: center;
justify-content: center;
}
.merchantItem_left {
display: flex;
align-items: center;
}
.merchantItem_left_img {
width: 180rpx;
height: 180rpx;
border-radius: 20rpx;
overflow: hidden;
margin-right: 20rpx;
}
.merchantItem_left_msg_tit {
font-weight: 400;
font-size: 32rpx;
color: #000000;
}
.merchantItem_left_msg_add {
font-weight: 400;
font-size: 24rpx;
color: #999999;
margin-top: 14rpx;
}
.merchantItem_left_msg_msg {
font-weight: 400;
font-size: 22rpx;
color: #FF512A;
background: #FFF0ED;
padding: 2rpx;
margin-top: 16rpx;
}
.merchantItem_left_msg_tag {
font-weight: 400;
font-size: 24rpx;
color: #999999;
margin-top: 18rpx;
}
</style>

View File

@ -1,203 +0,0 @@
<template>
<view class="selftTest">
<view class="Tit">血脂</view>
<view class="row">
<view class="row_tit">总胆固醇</view>
<view class="row_con">
<view wx:if="Info.zdgc_status == '1'">较低</view>
<view wx:if="Info.zdgc_status == '2'">正常</view>
<view wx:if="Info.zdgc_status == '3'">较高</view>
</view>
</view>
<view class="row">
<view class="row_tit">高密度脂</view>
<view class="row_con">
<view wx:if="Info.gmdz_status == '1'">较低</view>
<view wx:if="Info.gmdz_status == '2'">正常</view>
<view wx:if="Info.gmdz_status == '3'">较高</view>
</view>
</view>
<view class="row">
<view class="row_tit">甘油三脂</view>
<view class="row_con">
<view wx:if="Info.gysz_status == '1'">较低</view>
<view wx:if="Info.gysz_status == '2'">正常</view>
<view wx:if="Info.gysz_status == '3'">较高</view>
</view>
</view>
<view class="row">
<view class="row_tit">低密度脂</view>
<view class="row_con">
<view wx:if="Info.dmyh_status == '1'">较低</view>
<view wx:if="Info.dmyh_status == '2'">正常</view>
<view wx:if="Info.dmyh_status == '3'">较高</view>
</view>
</view>
<view class="row">
<view class="row_tit">冠心病指数</view>
<view class="row_con">
<view wx:if="Info.gxbzs_status == '1'">较低</view>
<view wx:if="Info.gxbzs_status == '2'">正常</view>
<view wx:if="Info.gxbzs_status == '3'">较高</view>
</view>
</view>
<view class="row none">
<view class="row_tit">动脉硬化</view>
<view class="row_con">
<view wx:if="Info.dmyh_status == '1'">较低</view>
<view wx:if="Info.dmyh_status == '2'">正常</view>
<view wx:if="Info.dmyh_status == '3'">较高</view>
</view>
</view>
<view class="gray"></view>
<view class="Tit">常规项目</view>
<view class="row type2">
<view class="row_tit">体重</view>
<view class="row_con">
<view wx:if="Info.tz_status == '1'">较低</view>
<view wx:if="Info.tz_status == '2'">正常</view>
<view wx:if="Info.tz_status == '3'">较高</view>
</view>
</view>
<view class="row type2">
<view class="row_tit">心率</view>
<view class="row_con">
<view wx:if="Info.xl_status == '1'">较低</view>
<view wx:if="Info.xl_status == '2'">正常</view>
<view wx:if="Info.xl_status == '3'">较高</view>
</view>
</view>
<view class="row none">
<view class="row_tit">体温</view>
<view class="row_con">
<view wx:if="Info.tw_status == '1'">较低</view>
<view wx:if="Info.tw_status == '2'">正常</view>
<view wx:if="Info.tw_status == '3'">较高</view>
</view>
</view>
<view class="gray"></view>
<view class="Tit">尿酸</view>
<view class="row none">
<view class="row_tit">尿酸</view>
<view class="row_con">
<view wx:if="Info.ns_status == '1'">较低</view>
<view wx:if="Info.ns_status == '2'">正常</view>
<view wx:if="Info.ns_status == '3'">较高</view>
</view>
</view>
<view class="gray"></view>
<view class="Tit">血压</view>
<view class="row">
<view class="row_tit">收缩压</view>
<view class="row_con">
<view wx:if="Info.ssy_status == '1'">较低</view>
<view wx:if="Info.ssy_status == '2'">正常</view>
<view wx:if="Info.ssy_status == '3'">较高</view>
</view>
</view>
<view class="row">
<view class="row_tit">舒张压</view>
<view class="row_con">
<view wx:if="Info.szy_status == '1'">较低</view>
<view wx:if="Info.szy_status == '2'">正常</view>
<view wx:if="Info.szy_status == '3'">较高</view>
</view>
</view>
<view class="row none">
<view class="row_tit">脉搏</view>
<view class="row_con ">
<view wx:if="Info.mb_status == '1'">较低</view>
<view wx:if="Info.mb_status == '2'">正常</view>
<view wx:if="Info.mb_status == '3'">较高</view>
</view>
</view>
<view class="gray"></view>
<view class="Tit">眼科</view>
<view class="row">
<view class="row_tit">左眼视力</view>
<view class="row_con">
<view wx:if="Info.zysl_status == '1'">较低</view>
<view wx:if="Info.zysl_status == '2'">正常</view>
<view wx:if="Info.zysl_status == '3'">较高</view>
</view>
</view>
<view class="row none">
<view class="row_tit">右眼视力</view>
<view class="row_con ">
<view wx:if="Info.yysl_status == '1'">较低</view>
<view wx:if="Info.yysl_status == '2'">正常</view>
<view wx:if="Info.yysl_status == '3'">较高</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
id: "",
Info: "",
}
},
methods: {
},
onLoad(options) {
let that = this
this.id = options.id
}
}
</script>
<style>
.selftTest {
padding: 30rpx 20rpx;
padding-top: 0;
}
.Tit {
font-weight: bold;
font-size: 32rpx;
color: #222222;
margin-bottom: 25rpx;
margin-top: 30rpx;
}
.row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx 0;
border-bottom: 1rpx solid #E6E6E6;
box-sizing: border-box;
}
.row_tit {
font-weight: 400;
font-size: 26rpx;
color: #999999;
}
.row_con {
display: flex;
align-items: center;
font-weight: 400;
font-size: 26rpx;
color: #72BB4E;
}
.row_con input {
text-align: right;
}
.none {
border-bottom: none;
}
.type2 {
color: #FF512A;
}
</style>

View File

@ -1,159 +0,0 @@
<template>
<view class="report">
<view class="reportList">
<view class="reportItem" @click="desc" v-for="(item, index) in orderList">
<view class="reportItem_left">
<view class="reportItem_img">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/port.png" mode="widthFix" />
</view>
<view class="reportItem_text">
<view class="reportItem_text_tit">{{item.title}}检查报告</view>
<view class="reportItem_text_type">检测方式
<view>自测</view>
</view>
</view>
</view>
<view class="reportItem_right">
查看
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/water_filter/filter_more.png"
mode="widthFix" />
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
t: uni.getMenuButtonBoundingClientRect().top,
h: uni.getMenuButtonBoundingClientRect().height,
orderList: [{
title: "123"
}]
}
},
methods: {
handleNavigateBack() {
uni.navigateBack();
},
desc(id) {
//
}
}
}
</script>
<style>
image {
width: 100%;
height: 100%;
}
.nav-box {
box-sizing: border-box;
width: 100%;
z-index: 2;
background: #F9F9F9;
padding-bottom: 25rpx;
}
.nav-box .nav-bar {
display: flex;
align-items: center;
}
.nav-box .nav-bar .nav-bar-left,
.nav-box .nav-bar .nav-bar-right {
padding: 0 20rpx;
width: 132rpx;
/* min-width: 36rpx; */
}
.nav-box .nav-bar .nav-bar-left van-icon {
vertical-align: sub;
color: #333333;
}
.nav-box .nav-bar .nav-bar-title {
flex: 1;
text-align: center;
font-weight: 400;
font-size: 36rpx;
color: #000000;
}
.nav-box .nav-bar-right {
font-weight: 400;
font-size: 26rpx;
color: #FF512A;
display: flex;
align-items: center;
}
.nav-box .nav-bar-right image {
width: 30rpx;
height: 30rpx;
margin-right: 10rpx;
}
.reportList {
margin: 0 20rpx;
margin-top: 15rpx;
}
.reportItem {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx 0;
border-bottom: 1rpx solid #E6E6E6;
}
.reportItem_left {
display: flex;
align-items: center;
}
.reportItem_img {
width: 60rpx;
height: 60rpx;
margin-right: 20rpx;
}
.reportItem_right {
display: flex;
font-weight: 400;
font-size: 26rpx;
color: #222222;
align-items: center;
}
.reportItem_right image {
width: 12rpx;
height: 26rpx;
margin-left: 13rpx;
}
.reportItem_text_tit {
font-weight: 400;
font-size: 26rpx;
color: #222222;
}
.reportItem_text_type {
font-weight: 400;
font-size: 22rpx;
color: #999999;
display: flex;
align-items: center;
}
.reportItem_text_type view {
color: #222;
}
</style>

View File

@ -1,204 +0,0 @@
<template>
<view class="selftTest">
<view class="Tit">血脂</view>
<view class="row">
<view class="row_tit">总胆固醇</view>
<view class="row_con">
<input type="number" v-model="zdgc" @input="ipt1" data-datas="zdgc" placeholder="0.4-4" placeholder-style="color: #999999;font-size: 26rpx;" />mg/dL
</view>
</view>
<view class="row">
<view class="row_tit">高密度脂</view>
<view class="row_con">
<input type="number" v-model="gmdz" @input="ipt1" data-datas="gmdz" placeholder="2.9-6" placeholder-style="color: #999999;font-size: 26rpx;" />mmol/L
</view>
</view>
<view class="row">
<view class="row_tit">甘油三脂</view>
<view class="row_con">
<input type="number" v-model="gysz" @input="ipt1" data-datas="gysz" placeholder="1.04-2.59" placeholder-style="color: #999999;font-size: 26rpx;" />mg/L
</view>
</view>
<view class="row">
<view class="row_tit">低密度脂</view>
<view class="row_con">
<input type="number" v-model="dzdz" @input="ipt1" data-datas="dzdz" placeholder="0.51-1.7" placeholder-style="color: #999999;font-size: 26rpx;" />mmol/dL
</view>
</view>
<view class="row">
<view class="row_tit">冠心病指数</view>
<view class="row_con">
<input type="number" v-model="gxbzs" @input="ipt1" data-datas="gxbzs" placeholder="0.3-3.35" placeholder-style="color: #999999;font-size: 26rpx;" />
</view>
</view>
<view class="row none">
<view class="row_tit">动脉硬化</view>
<view class="row_con">
<input type="number" v-model="dmyh" @input="ipt1" data-datas="dmyh" placeholder="1.3-4.5" placeholder-style="color: #999999;font-size: 26rpx;" />
</view>
</view>
<view class="gray"></view>
<view class="Tit">常规项目</view>
<view class="row">
<view class="row_tit">体重</view>
<view class="row_con">
<input type="number" v-model="tz" @input="ipt1" data-datas="tz" placeholder="1-200" placeholder-style="color: #999999;font-size: 26rpx;" />Kg
</view>
</view>
<view class="row">
<view class="row_tit">心率</view>
<view class="row_con">
<input type="number" v-model="xl" @input="ipt1" data-datas="xl" placeholder="60-100" placeholder-style="color: #999999;font-size: 26rpx;" />/
</view>
</view>
<view class="row none">
<view class="row_tit">体温</view>
<view class="row_con">
<input type="number" v-model="tw" @input="ipt1" data-datas="tw" placeholder="35-37.5" placeholder-style="color: #999999;font-size: 26rpx;" />
</view>
</view>
<view class="gray"></view>
<view class="Tit">尿酸</view>
<view class="row none">
<view class="row_tit">尿酸</view>
<view class="row_con">
<input type="number" v-model="ns" @input="ipt1" data-datas="ns" placeholder="179-416" placeholder-style="color: #999999;font-size: 26rpx;" />μmol/L
</view>
</view>
<view class="gray"></view>
<view class="Tit">血压</view>
<view class="row">
<view class="row_tit">收缩压</view>
<view class="row_con">
<input type="number" v-model="ssy" @input="ipt1" data-datas="ssy" placeholder="1-200" placeholder-style="color: #999999;font-size: 26rpx;" />Kg
</view>
</view>
<view class="row">
<view class="row_tit">舒张压</view>
<view class="row_con">
<input type="number" v-model="szy" @input="ipt1" data-datas="szy" placeholder="60-100" placeholder-style="color: #999999;font-size: 26rpx;" />/
</view>
</view>
<view class="row none">
<view class="row_tit">脉搏</view>
<view class="row_con">
<input type="number" v-model="mb" @input="ipt1" data-datas="mb" placeholder="60-100" placeholder-style="color: #999999;font-size: 26rpx;" />/
</view>
</view>
<view class="gray"></view>
<view class="Tit">眼科</view>
<view class="row">
<view class="row_tit">左眼视力</view>
<view class="row_con">
<input type="number" v-model="zysl" @input="ipt1" data-datas="zysl" placeholder="1.0-4.0" placeholder-style="color: #999999;font-size: 26rpx;" />
</view>
</view>
<view class="row none">
<view class="row_tit">右眼视力</view>
<view class="row_con">
<input type="number" v-model="yysl" @input="ipt1" data-datas="yysl" placeholder="1.0-4.0" placeholder-style="color: #999999;font-size: 26rpx;" />
</view>
</view>
<view class="btn" @tap="submit">
提交
</view>
</view>
</template>
<script>
export default {
data() {
return {
zdgc: '',
gmdz: '',
gysz: '',
dzdz: '',
gxbzs: '',
dmyh: '',
tz: '',
xl: '',
tw: '',
ns: '',
ssy: '',
szy: '',
mb: '',
zysl: '',
yysl: ''
}
},
methods: {
ipt1(e) {
const key = e.currentTarget.dataset.datas;
this[key] = e.detail.value;
},
submit() {
//
}
}
}
</script>
<style>
.selftTest {
padding: 30rpx 20rpx;
padding-top: 0;
}
.Tit {
font-weight: bold;
font-size: 32rpx;
color: #222222;
margin-bottom: 25rpx;
margin-top: 30rpx;
}
.row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx 0;
border-bottom: 1rpx solid #E6E6E6;
box-sizing: border-box;
}
.row_tit {
font-weight: 400;
font-size: 26rpx;
color: #999999;
}
.row_con {
display: flex;
align-items: center;
font-weight: 400;
font-size: 26rpx;
color: #999999;
justify-content: flex-end;
flex: 1;
}
.row_con input {
text-align: right;
color: #222;
flex: 1;
}
.none {
border-bottom: none;
}
.btn {
width: 650rpx;
height: 80rpx;
background: #FF512A;
border-radius: 100rpx 100rpx 100rpx 100rpx;
font-weight: 400;
font-size: 36rpx;
color: #FFFFFF;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto;
margin-top: 30rpx;
}
</style>

View File

@ -1,5 +1,4 @@
.container {
margin-top: 87rpx;
padding: 0 15rpx;
background-color: whte;
}

View File

@ -1,9 +1,9 @@
<template>
<view class="container">
<!-- 头部标题 -->
<view class="header">
<!-- <view class="header">
<text class="title">榴园到家 服务至上</text>
</view>
</view> -->
<!-- 位置和搜索 -->
<view class="location-search">

View File

@ -0,0 +1,374 @@
page {
background-color: #fff;
}
.header {
display: flex;
align-items: center;
position: relative;
z-index: 1;
}
.header_tit {
flex: 1;
text-align: center;
position: relative;
z-index: 0;
}
.header .u-icon {
position: relative;
z-index: 2;
padding: 20rpx;
margin-left: 10rpx;
}
.local {
display: flex;
align-items: center;
font-size: 26rpx;
color: #222222;
box-sizing: border-box;
padding: 20rpx;
width: 100%;
background-color: #fff;
}
#local {
height: 30rpx;
width: 28.08rpx;
margin-right: 17rpx;
}
.u-icon {
margin-left: 10rpx;
}
.search {
background-color: #f6f7fb;
padding: 20rpx 0;
}
.searchBox {
width: 710rpx;
height: 70rpx;
background: #FFFFFF;
border-radius: 100rpx 100rpx 100rpx 100rpx;
margin: 0 auto;
display: flex;
box-sizing: border-box;
align-items: center;
padding-left: 30rpx;
padding-right: 30rpx;
}
.searchBox image {
width: 30rpx;
height: 30rpx;
margin-right: 16rpx;
}
.swiperBox {
height: 350rpx;
width: 100%;
position: relative;
}
.swiper {
height: 350rpx;
width: 100%;
/* position: relative; */
}
.navList {
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
height: 350rpx;
width: 100%;
padding: 30rpx 20rpx;
background-color: #fff;
margin-top: 20rpx;
}
.navItem {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 116rpx;
height: 105rpx;
margin-right: 34rpx;
margin-bottom: 43rpx;
}
.navItemImg {
width: 70rpx;
height: 70rpx;
display: flex;
justify-content: center;
align-items: center;
}
.navItem image {
width: 70rpx;
height: 70rpx;
}
.navItem:nth-child(5n) {
margin-right: 0;
}
.dot {
display: flex;
align-items: center;
justify-content: center;
margin-top: 20rpx;
position: absolute;
left: 50%;
bottom: 25rpx;
transform: translateX(-50%);
}
.dotItem {
width: 8rpx;
height: 8rpx;
border-radius: 50%;
background-color: #E6E6E6;
margin-right: 5rpx;
}
.actives {
width: 20rpx;
height: 8rpx;
background: #FF370B;
border-radius: 10rpx 10rpx 10rpx 10rpx;
}
.scrollBox {
background-color: #f6f7fb;
padding-bottom: 25rpx;
padding-top: 20rpx;
}
.scrollView {
display: flex;
align-items: center;
flex-wrap: nowrap;
padding: 0 14rpx;
}
.scroll-viewItem {
display: flex;
white-space: nowrap;
height: 54rpx;
background: #FFFFFF;
border-radius: 10rpx 10rpx 10rpx 10rpx;
border: 1rpx solid #FFFFFF;
padding: 10rpx 18rpx;
margin-right: 10rpx;
position: relative;
display: flex;
align-items: center;
}
.scroll-viewItem image {
width: 22rpx;
height: 22rpx;
position: absolute;
left: 7rpx;
top: 5rpx;
}
.btnList {
width: 389rpx;
height: 119rpx;
background: #FFFFFF;
border-radius: 100rpx 100rpx 100rpx 100rpx;
position: fixed;
left: 50%;
transform: translateX(-50%);
bottom: 200rpx;
display: flex;
align-items: center;
justify-content: center;
z-index: 2;
}
.btnList_after {
width: 389rpx;
height: 119rpx;
filter: blur(8.600000381469727rpx);
background: rgba(0, 0, 0, 0.3);
border-radius: 100rpx 100rpx 100rpx 100rpx;
position: fixed;
left: 50%;
transform: translateX(-50%);
bottom: 200rpx;
border-radius: 100rpx 100rpx 100rpx 100rpx;
}
.btn_left {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 22rpx;
color: #000000;
}
.btn_left image {
width: 47.97rpx;
height: 44.79rpx;
margin-bottom: 6rpx;
}
.btn_right {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 22rpx;
color: #000000;
}
.btn_right image {
height: 47rpx;
width: 47rpx;
margin-bottom: 6rpx;
}
.line {
width: 1rpx;
height: 82rpx;
border-image: linear-gradient(90deg, rgba(255, 255, 255, 1), rgba(215, 215, 215, 1), rgba(255, 255, 255, 1)) 1 1;
}
.lines {
background-color: #f5f7f9;
height: 40rpx;
width: 100%;
}
.merchantList {
padding: 0 20rpx;
width: 100%;
box-sizing: border-box;
}
.merchantItem {
display: flex;
padding-top: 30px;
padding-bottom: 30rpx;
border-bottom: 1rpx solid #EBEBEB;
;
}
.merchantItem_left {
width: 180rpx;
height: 180rpx;
border-radius: 20rpx 20rpx 20rpx 20rpx;
overflow: hidden;
margin-right: 24rpx;
}
.merchantItem_left image {
width: 100%;
height: 100%;
}
.merchantItem_right {
flex: 1;
}
.merchantItem_right_tit {
display: flex;
align-items: center;
justify-content: space-between;
}
.merchantItem_right_tit_left {
font-size: 30rpx;
color: #222222;
}
.merchantItem_right_tit_right {
font-size: 24rpx;
color: #555555;
}
.merchantItem_right_con {
margin-top: 14rpx;
display: flex;
align-items: center;
justify-content: space-between;
}
.merchangtItem_tag {
font-size: 22rpx;
color: #555555;
padding: 5rpx 12rpx;
white-space: nowrap;
background: rgba(255, 81, 42, 0.1);
border-radius: 100rpx 100rpx 100rpx 100rpx;
display: inline-block;
margin-top: 20rpx;
margin-right: 10rpx;
}
.startList {
display: flex;
align-items: center;
}
.startList image {
width: 22rpx;
height: 22rpx;
margin-right: 3rpx;
}
.merchantItem_right_con_right {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 26rpx;
color: #000000;
}
.merchantItem_right_con_right image {
width: 32rpx;
height: 28.59rpx;
margin-bottom: 6rpx;
}
.merchantItem_right_add {
font-size: 24rpx;
color: #999999;
margin-top: 14rpx;
}
.empty {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-weight: normal;
font-size: 28rpx;
color: #999999;
margin-top: 110rpx;
width: 100%;
}
.empty image {
width: 366rpx;
height: 226rpx;
margin-bottom: 27rpx;
}

View File

@ -0,0 +1,231 @@
<template>
<view class="container">
<view class="header" :style="{ paddingTop: top + 'px', height: localHeight + 'px' }">
<u-icon bold color="#000" size="40" name="arrow-left" @click="back"></u-icon>
<view class="header_tit">{{ headerTitle }}</view>
</view>
<view class="local">
<image id="local" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_localIcon.png"
mode="aspectFill"></image>
{{ address }}
<u-icon name="arrow-down" color="#999999" size="28"></u-icon>
</view>
<view class="search">
<view class="searchBox">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_communitySearchIcon.png"
mode="aspectFill"></image>
<input type="text" placeholder="请输入您想搜索的内容" />
</view>
</view>
<view class="merchantList" v-if="merchatList.length > 0">
<view class="merchantItem" v-for="item in merchatList" :key="item.id" @click="Info(item)">
<view class="merchantItem_left">
<image :src="picUrl + item.bigImg[0]" mode="aspectFill"></image>
</view>
<view class="merchantItem_right">
<view class="merchantItem_right_tit">
<view class="merchantItem_right_tit_left">
{{ item.merchant_name }}
</view>
<view class="merchantItem_right_tit_right">
{{ item.distances }}
</view>
</view>
<view class="merchantItem_right_con">
<view class="merchantItem_right_con_left">
<view class="startList">
<image v-for="index in 5" :key="index" :src="index < item.rating
? 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_start1.png'
: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_start2.png'
" mode="aspectFill"></image>
</view>
<view class="merchangtItem_tag" v-if="item.refund_property_fee_ratio">
买单返物业费
</view>
<view class="merchangtItem_tag" v-if="item.refund_user_points_ratio">
买单返积分
</view>
</view>
<view class="merchantItem_right_con_right" @click="toJump(item)">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_review.png"
mode="aspectFill"></image>
点评
</view>
</view>
<view class="merchantItem_right_add">
{{ item.comAddress }}
</view>
</view>
</view>
</view>
<view v-else>
<view class="empty">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_nearbyList_empty.png"
mode="aspectFill"></image>
暂无数据
</view>
</view>
<view class="btnList">
<!-- <view class="btn_left">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_serverIcon.png"
mode="aspectFill"></image>
到店服务券
</view> -->
<view class="line"></view>
<view class="btn_right">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/lcoal_payIcon.png"
mode="aspectFill"></image>
快捷支付记录
</view>
</view>
<view class="btnList_after"></view>
<!-- <nav-footer :current="2" /> -->
</view>
</template>
<script>
import {
request,
picUrl,
uniqueByField,
menuButtonInfo,
calculateDistance,
NavgateTo,
} from "../../../utils";
import { apiArr } from "../../../api/v2local";
export default {
data() {
return {
headerTitle: "",
picUrl,
top: "",
localHeight: "",
swiperList: [],
currentIndex: 0,
checkedItems: [false, false, false, false],
address: "",
page_size: "10",
page_num: "1",
flag: false,
merchatList: [],
changeId: "",
};
},
onLoad(options) {
this.changeId = JSON.parse(options.item).id;
this.headerTitle = JSON.parse(options.item).cate_name;
const meun = menuButtonInfo();
this.top = meun.top;
// this.top = meun.height + meun.top;
this.localHeight = meun.height;
this.getCateList();
this.getMechantList();
this.address = uni.getStorageSync("location").address;
console.log(this.address);
},
onReachBottom() {
if (this.flag) {
this.getMechantList();
}
},
methods: {
back() {
NavgateTo("1");
},
swiperChange(e) {
this.currentIndex = e.detail.current;
},
checkItem(index) {
this.$set(this.checkedItems, index, !this.checkedItems[index]);
},
//
async getCateList() {
let that = this;
await request(apiArr.getMerChantCateList, "POST").then((res) => {
res.rows = res.rows.filter((item) => item.is_visible == 1)
console.log(res);
// 10
const chunkSize = 10;
that.swiperList = [];
for (let i = 0; i < res.rows.length; i += chunkSize) {
that.swiperList.push(res.rows.slice(i, i + chunkSize));
}
});
},
//
async getMechantList() {
let that = this;
const params = {
merchant_cate_id: this.changeId,
page_num: that.page_num,
page_size: that.page_size,
}
await request(apiArr.getMerchantList, "POST", params).then((res) => {
let latitude = uni.getStorageSync("location").lat;
let longitude = uni.getStorageSync("location").lng;
res.rows.forEach((item) => {
item.bigImg = item.album_images.split(",");
const distanceInKm = calculateDistance(
latitude,
longitude,
item.latitude,
item.longitude
);
item.distances =
distanceInKm >= 1
? `${distanceInKm.toFixed(1)}km`
: `${(distanceInKm * 1000).toFixed(1)}m`;
if (item.ad) {
item.comAddress = item.ad.ad_name.replace(/,/g, "") + item.address;
} else {
item.comAddress = item.address;
}
});
res.rows.sort((a, b) => {
const valueA =
parseFloat(a.distances.replace("km", "").replace("m", "")) *
(a.distances.includes("km") ? 1000 : 1);
const valueB =
parseFloat(b.distances.replace("km", "").replace("m", "")) *
(b.distances.includes("km") ? 1000 : 1);
return valueA - valueB;
});
if (res.rows.length == this.page_size) {
this.page_num = this.page_num + 1;
this.flag = true;
} else {
this.flag = false;
}
this.merchatList = this.merchatList.concat(res.rows);
});
},
//
Info(e) {
uni.setStorageSync("merchantInfo", e);
NavgateTo("../detail/index");
},
//
toJump(e) {
NavgateTo('../comment/index');
},
},
};
</script>
<style>
@import url("./index.css");
</style>

View File

@ -157,6 +157,7 @@ export default {
},
//
getCommentList() {
if (uni.getStorageSync('userId')) {
request(apiArr.getMerchantComment, "POST", {
page_num: this.page_num,
page_size: this.page_size,
@ -181,6 +182,7 @@ export default {
this.commentList = this.commentList.concat(list);
})
}
},
getMerchantInfo() {

View File

@ -6,17 +6,29 @@ page {
/* padding-top: 100rpx; */
}
.local {
display: flex;
align-items: center;
.localBox {
font-size: 26rpx;
color: #222222;
box-sizing: border-box;
padding: 20rpx;
width: 100%;
padding: 20rpx 0;
background-color: #f6f7fb;
}
.localBoxItem{
width: 100%;
display: flex;
align-items: center;
padding: 0 20rpx;
background-color: #fff;
}
.local {
display: flex;
width: auto;
white-space: nowrap;
}
#local {
height: 30rpx;
width: 28.08rpx;
@ -28,16 +40,16 @@ page {
}
.search {
background-color: #f6f7fb;
flex: 1;
padding: 20rpx 0;
margin-left: 15rpx;
}
.searchBox {
width: 710rpx;
width: 93%;
height: 70rpx;
background: #FFFFFF;
border-radius: 100rpx 100rpx 100rpx 100rpx;
margin: 0 auto;
background: #f6f7fb;
border-radius: 100rpx;
display: flex;
box-sizing: border-box;
align-items: center;
@ -86,9 +98,17 @@ page {
margin-bottom: 43rpx;
}
.navItemImg {
width: 70rpx;
height: 70rpx;
display: flex;
justify-content: center;
align-items: center;
}
.navItem image {
width: 70rpx;
height: auto;
height: 70rpx;
}
.navItem:nth-child(5n) {
@ -126,6 +146,7 @@ page {
padding-bottom: 25rpx;
padding-top: 20rpx;
}
.scrollView {
display: flex;
align-items: center;
@ -223,11 +244,13 @@ page {
height: 82rpx;
border-image: linear-gradient(90deg, rgba(255, 255, 255, 1), rgba(215, 215, 215, 1), rgba(255, 255, 255, 1)) 1 1;
}
.lines {
background-color: #f5f7f9;
height: 40rpx;
width: 100%;
}
.merchantList {
padding: 0 20rpx;
width: 100%;
@ -238,7 +261,8 @@ page {
display: flex;
padding-top: 30px;
padding-bottom: 30rpx;
border-bottom: 1rpx solid #EBEBEB;;
border-bottom: 1rpx solid #EBEBEB;
;
}
.merchantItem_left {

View File

@ -1,145 +1,118 @@
<template>
<div class="container">
<div class="local">
<image
id="local"
<view class="container">
<view class="localBox">
<view class="localBoxItem">
<view class="local">
<image id="local"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_localIcon.png"
mode="aspectFill"
></image>
mode="aspectFill"></image>
{{ address }}
<u-icon name="arrow-down" color="#999999" size="28"></u-icon>
</div>
</view>
<div class="search">
<div class="searchBox">
<view class="search">
<view class="searchBox">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_communitySearchIcon.png"
mode="aspectFill"
></image>
mode="aspectFill"></image>
<input type="text" placeholder="请输入您想搜索的内容" />
</div>
</div>
</view>
</view>
</view>
</view>
<div class="swiperBox">
<view class="swiperBox">
<swiper class="swiper" @change="swiperChange" :current="currentIndex">
<swiper-item v-for="(page, pageIndex) in swiperList" :key="pageIndex">
<div class="navList">
<div
class="navItem"
v-for="(item, itemIndex) in page"
:key="itemIndex"
>
<view class="navList">
<view class="navItem" v-for="(item, itemIndex) in page" :key="itemIndex" @click="changeNav(item)">
<view class="navItemImg">
<image :src="picUrl + item.cate_image" mode="widthFix"></image>
<div class="navName">{{ item.cate_name }}</div>
</div>
</div>
</view>
<view class="navName">{{ item.cate_name }}</view>
</view>
</view>
</swiper-item>
</swiper>
<div class="dot">
<div
class="dotItem"
v-for="(page, index) in swiperList" :key="index"
:class="currentIndex == index ? 'actives' : ''"
></div>
</div>
</div>
<view class="dot">
<view class="dotItem" v-for="(page, index) in swiperList" :key="index"
:class="currentIndex == index ? 'actives' : ''"></view>
</view>
</view>
<div class="lines"></div>
<view class="lines"></view>
<!-- <scroll-view scroll-x="true" enhanced enable-flex class="scrollBox">
<div class="scrollView">
<div class="scroll-viewItem" v-for="(item, index) in 4" @click="checkItem(index)">
<view class="scrollView">
<view class="scroll-viewItem" v-for="(item, index) in 4" @click="checkItem(index)">
<image v-show="!checkedItems[index]" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_uncheck.png"
mode="aspectFill"></image>
<image v-show="checkedItems[index]" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local-check.png"
mode="aspectFill"></image>
买单返物业费
</div>
</div>
</view>
</view>
</scroll-view> -->
<div class="merchantList">
<div
class="merchantItem"
v-for="item in merchatList"
:key="item.id"
@click="Info(item)"
>
<div class="merchantItem_left">
<view class="merchantList">
<view class="merchantItem" v-for="item in merchatList" :key="item.id" @click="Info(item)">
<view class="merchantItem_left">
<image :src="picUrl + item.bigImg[0]" mode="aspectFill"></image>
</div>
<div class="merchantItem_right">
<div class="merchantItem_right_tit">
<div class="merchantItem_right_tit_left">
</view>
<view class="merchantItem_right">
<view class="merchantItem_right_tit">
<view class="merchantItem_right_tit_left">
{{ item.merchant_name }}
</div>
<div class="merchantItem_right_tit_right">
</view>
<view class="merchantItem_right_tit_right">
{{ item.distances }}
</div>
</div>
<div class="merchantItem_right_con">
<div class="merchantItem_right_con_left">
<div class="startList">
<image
v-for="index in 5"
:key="index"
:src="
index < item.rating
</view>
</view>
<view class="merchantItem_right_con">
<view class="merchantItem_right_con_left">
<view class="startList">
<image v-for="index in 5" :key="index" :src="index < item.rating
? 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_start1.png'
: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_start2.png'
"
mode="aspectFill"
></image>
</div>
<div
class="merchangtItem_tag"
v-if="item.refund_property_fee_ratio"
>
" mode="aspectFill"></image>
</view>
<view class="merchangtItem_tag" v-if="item.refund_property_fee_ratio">
买单返物业费
</div>
<div
class="merchangtItem_tag"
v-if="item.refund_user_points_ratio"
>
</view>
<view class="merchangtItem_tag" v-if="item.refund_user_points_ratio">
买单返积分
</div>
</div>
<div class="merchantItem_right_con_right" @click="toJump(item)">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_review.png"
mode="aspectFill"
></image>
</view>
</view>
<view class="merchantItem_right_con_right" @click="toJump(item)">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_review.png"
mode="aspectFill"></image>
点评
</div>
</div>
<div class="merchantItem_right_add">
</view>
</view>
<view class="merchantItem_right_add">
{{ item.comAddress }}
</div>
</div>
</div>
</div>
</view>
</view>
</view>
</view>
<div class="btnList">
<div class="btn_left">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_serverIcon.png"
mode="aspectFill"
></image>
<view class="btnList">
<!-- <view class="btn_left">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/local_serverIcon.png"
mode="aspectFill"></image>
到店服务券
</div>
<div class="line"></div>
<div class="btn_right">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/lcoal_payIcon.png"
mode="aspectFill"
></image>
</view> -->
<view class="line"></view>
<view class="btn_right">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/lcoal_payIcon.png"
mode="aspectFill"></image>
快捷支付记录
</div>
</div>
<div class="btnList_after"></div>
</view>
</view>
<view class="btnList_after"></view>
<!-- <nav-footer :current="2" /> -->
</div>
</view>
</template>
<script>
@ -192,6 +165,13 @@ export default {
this.currentIndex = e.detail.current;
},
changeNav(item) {
console.log("🚀 ~ changeNav ~ item:", item)
NavgateTo(`/packages/localLife/classify/index?item=${JSON.stringify(item)}`)
},
checkItem(index) {
this.$set(this.checkedItems, index, !this.checkedItems[index]);
},

View File

@ -0,0 +1,190 @@
[
{
"id": 9001,
"after_sales_no": "AS202508130001",
"commodity_order_id": 1001,
"after_sales_status": 1,
"applicant": "张三",
"after_sales_reason": "拍错商品/不想要了",
"after_sales_type": 1,
"application_description": "请尽快处理退款",
"application_images": "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test.png",
"is_need_process": 1,
"process_status": 1,
"refund_amount": 68.00,
"after_sales_goods": "1@8001",
"refund_method": 1,
"review_status": 1,
"creator": "customer",
"create_time": "2025-08-13T11:20:00Z",
"commodity_order_item": [
{
"id": 7001,
"goods_id": 8001,
"goods_name": "澳洲牛排",
"is_support_same_day": 1,
"commodity_pic": "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test.png",
"sales_price": 68.00,
"count": 1,
"after_sales_status": 1
}
]
},
{
"id": 9002,
"after_sales_no": "AS202508130002",
"commodity_order_id": 1002,
"after_sales_status": 1,
"after_sales_type": 1,
"refund_no": "RF202508130001",
"refund_completed_time": "2025-08-13T14:30:00Z",
"is_need_process": 2,
"process_status": 2,
"refund_amount": 45.80,
"after_sales_goods": "2@8004",
"refund_method": 1,
"review_status": 2,
"review_remark": "审核通过,已原路退款",
"reviewer": "客服008",
"review_time": "2025-08-13T14:15:00Z",
"create_time": "2025-08-13T13:45:00Z",
"commodity_order_item": [
{
"id": 7004,
"goods_id": 8004,
"goods_name": "东北大米",
"sales_price": 22.90,
"count": 2,
"after_sales_status": 3
}
]
},
{
"id": 9003,
"after_sales_no": "AS202508130003",
"commodity_order_id": 1003,
"after_sales_status": 1,
"applicant": "李四",
"after_sales_reason": "商品质量问题",
"after_sales_type": 2,
"application_description": "商品包装破损",
"application_images": "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test.png",
"return_description": "已通过顺丰寄回",
"return_images": "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test.png",
"return_tracking_no": "SF1234567890",
"return_logistics_company": "顺丰速运",
"return_contact_phone": "13800138000",
"is_need_process": 1,
"process_status": 1,
"refund_amount": 152.00,
"after_sales_goods": "1@8003",
"refund_method": 1,
"review_status": 1,
"create_time": "2025-08-13T15:30:00Z",
"commodity_order_item": [
{
"id": 7003,
"goods_id": 8003,
"goods_name": "精品榴莲",
"sales_price": 152.00,
"count": 1,
"after_sales_status": 1
}
]
},
{
"id": 9004,
"after_sales_no": "AS202508130004",
"after_sales_type": 2,
"after_sales_status": 1,
"process_status": 2,
"refund_amount": 39.90,
"review_status": 2,
"review_remark": "商品已验货,符合退款条件",
"reviewer": "质检005",
"review_time": "2025-08-13T16:45:00Z",
"refund_no": "RF202508130002",
"refund_completed_time": "2025-08-13T17:30:00Z",
"create_time": "2025-08-13T09:30:00Z",
"commodity_order_item": [
{
"id": 7005,
"goods_name": "酸奶套装",
"sales_price": 39.90,
"count": 1,
"after_sales_status": 2
}
]
},
{
"id": 9005,
"after_sales_no": "AS202508130005",
"commodity_order_id": 1004,
"after_sales_type": 3,
"after_sales_status": 1,
"applicant": "王五",
"after_sales_reason": "商品发错型号",
"application_description": "购买的是XL码收到L码",
"application_images": "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test.png",
"is_need_process": 1,
"process_status": 1,
"after_sales_goods": "1@8006",
"receiving_address": "上海市浦东新区张江高科88号",
"review_status": 1,
"create_time": "2025-08-13T10:15:00Z",
"commodity_order_item": [
{
"id": 7006,
"goods_id": 8006,
"goods_name": "冷冻虾仁",
"sales_price": 76.50,
"count": 1,
"after_sales_status": 1
}
]
},
{
"id": 9006,
"after_sales_no": "AS202508130006",
"after_sales_type": 3,
"after_sales_status": 1,
"process_status": 2,
"processor": "客服012",
"process_time": "2025-08-13T14:20:00Z",
"process_remark": "已补发新商品物流单号YT987654321",
"review_status": 2,
"reviewer": "客服主管",
"review_time": "2025-08-13T13:40:00Z",
"create_time": "2025-08-13T09:00:00Z",
"commodity_order_item": [
{
"id": 7007,
"goods_id": 8007,
"goods_name": "进口橙子",
"sales_price": 32.00,
"count": 2,
"after_sales_status": 2
}
]
},
{
"id": 9007,
"after_sales_no": "AS202508130007",
"after_sales_status": 2,
"revoke_time": "2025-08-13T11:05:00Z",
"after_sales_type": 1,
"applicant": "赵六",
"after_sales_reason": "商品运输损坏",
"create_time": "2025-08-13T10:30:00Z",
"update_time": "2025-08-13T11:05:00Z",
"commodity_order_item": [
{
"id": 7002,
"goods_name": "有机西兰花",
"sales_price": 10.50,
"count": 1,
"after_sales_status": 4
}
]
}
]

View File

@ -0,0 +1,182 @@
.container {
background-color: #f6f7fb;
}
.after-sale-item{
margin: 20rpx;
min-height: 250rpx;
background-color: #ffffff;
border-radius: 20rpx;
padding: 20rpx;
}
.asGoodTag {
background-color: #ff7d00;
color: white;
font-size: 22rpx;
padding: 5rpx 10rpx;
border-radius: 8rpx 0 8rpx 8rpx;
}
.asGoodTag1 {
margin-right: 15rpx;
}
.tag-img {
position: absolute;
top: 105rpx;
left: 40rpx;
z-index: 1;
}
.header {
margin-bottom: 30rpx;
}
.company-info {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10rpx;
}
.company-name {
font-size: 32rpx;
font-weight: bold;
}
.after-sale-no {
font-size: 24rpx;
color: #ff4d4f;
padding: 4rpx 12rpx;
border-radius: 8rpx;
font-weight: bold;
}
.order-time {
font-size: 26rpx;
color: #888888;
}
.goods-info {
display: flex;
padding: 20rpx 0;
border-top: 1rpx solid #eeeeee;
border-bottom: 1rpx solid #eeeeee;
margin-bottom: 30rpx;
position: relative;
}
.goods-image {
width: 120rpx;
height: 120rpx;
border-radius: 8rpx;
margin-right: 20rpx;
}
.goods-details {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.goods-name {
font-weight: bold;
font-size: 30rpx;
line-height: 42rpx;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.goods-desc {
font-size: 26rpx;
color: #ff4d4f;
background-color: #fff2f0;
padding: 4rpx 12rpx;
border-radius: 8rpx;
display: inline-block;
margin: 10rpx 0;
}
.price-count {
display: flex;
justify-content: space-between;
align-items: center;
}
.goods-price {
font-size: 30rpx;
color: #ff4d4f;
font-weight: bold;
}
.goods-count {
font-size: 26rpx;
color: #888888;
}
.refund-amount {
font-size: 28rpx;
align-self: flex-end;
margin-left: 20rpx;
float: right;
font-weight: 500;
}
.status-container {
margin-bottom: 40rpx;
}
.status-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx;
background-color: #fafafa;
border-radius: 12rpx;
}
.status-label {
font-size: 28rpx;
font-weight: bold;
}
.status-desc {
font-size: 26rpx;
color: #888888;
margin-top: 6rpx;
}
.arrow-right {
font-size: 26rpx;
}
.action-buttons {
display: flex;
justify-content: flex-end;
margin-top: 30rpx;
}
.modify-btn {
width: 160rpx;
height: 60rpx;
background: #d9d9d9;
color: black;
border-radius: 30rpx;
font-size: 24rpx;
margin-right: 20rpx;
}
.cancel-btn {
width: 160rpx;
height: 60rpx;
background: #ffe8e5;
color: #f84723;
border-radius: 30rpx;
font-size: 24rpx;
margin: 0;
border: none;
}

View File

@ -0,0 +1,126 @@
<template>
<view class="container">
<view v-for="(item, index) in currentAfterSale" :key="index">
<view class="after-sale-item">
<!-- 头部信息 -->
<view class="header">
<view class="company-info">
<text class="company-name">{{ item.commodity_order_item[0].goods_name || '衡水喜屏传媒有限公司'
}}</text>
<text class="after-sale-no">退货退款</text>
</view>
<text class="order-time">提交订单{{ formatDate(item.create_time) }}</text>
</view>
<!-- 商品信息 -->
<view class="goods-info" v-for="(ite, index) in item.commodity_order_item" :key="index">
<view class="asGoodTag tag-img" v-if="ite.is_support_same_day === 1">当日达</view>
<image :src="ite.commodity_pic" class="goods-image"></image>
<view class="goods-details">
<text class="goods-name">
<text class="asGoodTag asGoodTag1" v-if="ite.is_support_same_day === 1">当日达</text>
{{ ite.goods_name }}
<text class="refund-amount">退款¥{{ ite.sales_price }}</text>
</text>
<text class="goods-desc">{{ ite.after_sales_reason }}</text>
<view class="price-count">
<text class="goods-price">¥{{ ite.sales_price }}/</text>
<text class="goods-count">x{{ ite.count }}</text>
</view>
</view>
</view>
<!-- 退款状态 -->
<view class="status-container">
<view class="status-item" @click="pendingPage(item)">
<text class="status-label">{{ getStatusText(item.after_sales_status) }}</text>
<text class="status-desc">商家将在<text style="color: #e73b05;">{{
calculateProcessingTime(item.create_time) }}</text>内处理</text>
<view class="arrow-right"></view>
</view>
</view>
<!-- 操作按钮 -->
<view class="action-buttons">
<button class="modify-btn" @click="modifyApplication">修改申请</button>
<button class="cancel-btn" @click="cancelApplication">撤销申请</button>
</view>
</view>
</view>
</view>
</template>
<script>
import afterSaleData from './afterSale.json';
import {
isPhone,
picUrl,
request,
upload,
NavgateTo
} from '../../../utils';
export default {
data() {
return {
currentAfterSale: afterSaleData
};
},
onLoad() {
},
methods: {
getStatusText(status) {
//
const statusMap = {
1: '商家待处理',
2: '已撤销',
3: '已完成',
4: '已拒绝'
};
return statusMap[status] || '未知状态';
},
calculateProcessingTime(createTime) {
return '2天';
},
formatDate(dateString) {
if (!dateString) return '';
const date = new Date(dateString);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
modifyApplication() {
console.log('修改申请');
},
cancelApplication() {
uni.showModal({
title: '提示',
content: '确定要撤销退款申请吗?',
success: (res) => {
if (res.confirm) {
console.log('撤销申请');
uni.navigateBack();
}
}
});
},
pendingPage(item) {
NavgateTo(`/packages/myOrders/pending/index?item=${JSON.stringify(item)}`); //
// NavgateTo(`/packages/myOrders/sendBack/index?item=${JSON.stringify(item)}`); //
// NavgateTo(`/packages/myOrders/refundOver/index?item=${JSON.stringify(item)}`); //退
// NavgateTo(`/packages/myOrders/changeInfo/index?item=${JSON.stringify(item)}`); //
}
}
};
</script>
<style scoped>
@import url(./index.css);
</style>

View File

@ -0,0 +1,254 @@
page {
background-color: #f0f2f5;
}
.apply-container {
/* padding: 10rpx; */
}
/* 弹窗样式 */
.refund-info-container {
background-color: #ffffff;
border-radius: 10rpx;
padding: 30rpx;
}
.refund-title {
font-size: 32rpx;
font-weight: bold;
text-align: center;
margin-bottom: 30rpx;
}
.refund-item {
display: flex;
justify-content: space-between;
padding: 20rpx 0;
border-bottom: 1rpx solid #f0f0f0;
}
.refund-label {
font-size: 28rpx;
color: #333333;
}
.required {
color: #ff4500;
margin-left: 5rpx;
}
.refund-value {
font-size: 28rpx;
color: #666666;
text-align: right;
position: relative;
max-width: 60%;
}
.arrow-right {
display: inline-block;
width: 16rpx;
height: 16rpx;
border-top: 2rpx solid #999999;
border-right: 2rpx solid #999999;
transform: rotate(45deg);
margin-left: 10rpx;
vertical-align: middle;
}
.price {
color: #ff4500;
font-weight: bold;
}
.modify-btn {
color: #007aff;
margin-left: 10rpx;
font-size: 26rpx;
}
.refund-hint {
font-size: 24rpx;
color: #999999;
margin-top: 10rpx;
text-align: right;
}
.hr {
height: 20rpx;
background-color: #f5f5f5;
margin: 20rpx -30rpx;
}
.refund-item2 {
padding: 20rpx 0;
}
.refund-description {
width: 100%;
height: 160rpx;
border: 1rpx solid #e0e0e0;
border-radius: 8rpx;
padding: 15rpx;
font-size: 26rpx;
color: #333333;
box-sizing: border-box;
margin-top: 10rpx;
}
.imgCon {
font-size: 18rpx;
color: #222222;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 120rpx;
height: 120rpx;
background: #F6F7FB;
border: 1rpx solid #D1D1D1;
border-radius: 10rpx 10rpx 10rpx 10rpx;
margin: 20rpx 0;
}
.imgCon image {
width: 34rpx;
height: 34rpx;
margin-bottom: 8rpx;
}
.u-upload__wrap__preview {
width: 120rpx;
height: 120rpx;
border-radius: 10rpx 0rpx 10rpx 10rpx !important;
margin-top: 20rpx !important;
}
.u-upload__wrap__preview__image {
width: 100% !important;
height: 100% !important;
object-fit: cover;
}
.contact-info {
font-size: 24rpx;
color: #666666;
text-align: right;
margin-top: 10rpx;
margin-bottom: 10rpx;
}
.submit-btn {
width: 60%;
height: 88rpx;
background-color: #ff451b;
color: #fff;
font-size: 32rpx;
border-radius: 44rpx;
line-height: 88rpx;
text-align: center;
margin-top: 50rpx;
border: none;
}
/* 选择退款原因弹窗样式 */
.cancel-reason-container {
background-color: #ffffff;
border-radius: 10rpx;
padding: 30rpx;
}
.title {
font-size: 32rpx;
font-weight: bold;
text-align: center;
margin-bottom: 30rpx;
}
.asTabs2 {
display: flex;
border-bottom: 1rpx solid #f0f0f0;
margin-bottom: 20rpx;
}
.asTab2 {
flex: 1;
text-align: center;
padding: 15rpx 0;
font-size: 28rpx;
color: #666666;
position: relative;
}
.asTab2.active {
color: #ff451b;
}
.asTab2.active::after {
content: '';
position: absolute;
bottom: -1rpx;
left: 10%;
width: 80%;
height: 4rpx;
background-color: #ff451b;
}
.reason-list {
max-height: 500rpx;
overflow-y: auto;
}
.reason-item {
display: flex;
align-items: center;
padding: 20rpx 0;
border-bottom: 1rpx solid #f0f0f0;
}
.radio {
width: 28rpx;
height: 28rpx;
border: 2rpx solid #999999;
border-radius: 50%;
margin-right: 20rpx;
}
.radio.active {
border-color: #ff451b;
background-color: #ff451b;
position: relative;
}
.radio.active::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 12rpx;
height: 12rpx;
background-color: #ffffff;
border-radius: 50%;
}
.confirm-btn {
width: 100%;
height: 88rpx;
background-color: #ff451b;
color: #ffffff;
border-radius: 44rpx;
font-size: 32rpx;
margin-top: 30rpx;
}
/* 打开弹窗按钮样式 */
.open-popup-btn {
height: 88rpx;
background-color: #ff451b;
color: #ffffff;
border-radius: 44rpx;
font-size: 32rpx;
margin: 40rpx auto;
display: block;
}

View File

@ -0,0 +1,263 @@
<template>
<view class="apply-container">
<!-- 确认退款信息弹窗 -->
<view class="refund-info-container">
<view class="refund-item">
<view class="refund-label">服务类型<text class="required">*</text></view>
<view class="refund-value" @click="openAfterSalePopup2('serviceType')">
{{ selectedServiceType || '请选择服务类型' }}
<text class="arrow-right"></text>
</view>
</view>
<view class="refund-item">
<view class="refund-label">退款原因<text class="required">*</text></view>
<view class="refund-value" @click="openAfterSalePopup2('refundReason')">
{{ selectedRefundReason || '请选择退款原因' }}
<text class="arrow-right"></text>
</view>
</view>
<view class="refund-item" style="border-bottom: none;">
<view class="refund-label">退款金额<text class="required">*</text></view>
<view class="refund-value">
<text class="price">¥{{ refundAmount || '0.00' }}</text>
<text class="modify-btn" @click="modifyRefundAmount">修改</text>
<view class="refund-hint">可修改最多¥{{ maxRefundAmount || '0.00' }}含发货邮费¥{{ postage || '0.00' }}
</view>
</view>
</view>
<view class="hr"></view>
<view class="refund-item2">
<view class="refund-label">补充描述和凭证</view>
<textarea class="refund-description" placeholder="补充描述,有助于商家更好的处理售后问题" v-model="refundDescription"
maxlength="200"></textarea>
<u-upload :fileList="imgList" @afterRead="afterReadImg" @delete="deletePic" name="1" multiple
:maxCount="3">
<view class="imgCon">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_imageImg.png"
mode="widthFix"></image>
上传凭证
</view>
</u-upload>
</view>
<view class="hr"></view>
<view class="refund-item">
<view class="refund-label">退款方式</view>
<view class="refund-value" style="margin-bottom: 10rpx;">
{{ refundMethod || '自行寄回' }}
<view class="refund-hint">您可自行安排将商品退回商家</view>
</view>
</view>
<view class="refund-item">
<view class="refund-label">商家地址</view>
<view class="refund-value" @click="viewAddressDetails">
{{ merchantAddress || '未设置' }}
<text class="arrow-right"></text>
</view>
</view>
<view class="contact-info">
<text>{{ merchantContact || '未设置' }}</text>
</view>
</view>
<button class="submit-btn" @click="submitRefundApplication">提交申请</button>
<!-- 选择退款原因弹窗 -->
<u-popup ref="popup2" :show="afterSalePopup2" :round="10" @close="closeAfterSalePopup2"
:mask-close-able="false">
<view class="cancel-reason-container">
<view class="title">选择退款原因</view>
<view class="asTabs2">
<view :class="['asTab2', selectedAfterSaleType2 === 0 ? 'active' : '']"
@click="selectAfterSaleType2(0)">
退货退款</view>
<view :class="['asTab2', selectedAfterSaleType2 === 1 ? 'active' : '']"
@click="selectAfterSaleType2(1)">
退货
</view>
</view>
<view class="reason-list" v-if="selectedAfterSaleType2 === 0">
<view v-for="(reason, index) in applyRefundReasons" :key="index" class="reason-item"
@click="selectAsReason(index)">
<view :class="['radio', selectedAsReason === index ? 'active' : '']"></view>
<text>{{ reason }}</text>
</view>
</view>
<view class="reason-list" v-if="selectedAfterSaleType2 === 1">
<view v-for="(reason, index) in cancelReasons" :key="index" class="reason-item"
@click="selectAsReason(index)">
<view :class="['radio', selectedAsReason === index ? 'active' : '']"></view>
<text>{{ reason }}</text>
</view>
</view>
<button class="confirm-btn" @click="confirmAfterSaleCancel2">确定</button>
</view>
</u-popup>
</view>
</template>
<script>
import {
isPhone,
picUrl,
request,
upload,
NavgateTo
} from '../../../utils';
export default {
data() {
return {
currentAfterSale: null,
afterSalePopup2: false,
afterSalePopup3: false,
selectedAfterSaleType2: 0, // 0:退/退, 1:退
selectedAsReason: 0,
selectedServiceType: '',
selectedRefundReason: '',
refundAmount: 0,
maxRefundAmount: 0,
postage: 0,
refundDescription: '',
refundMethod: '自行寄回',
merchantAddress: '衡水市路北街道中心北大街世纪名城41号楼',
merchantContact: '高尚 18032753127',
imgList: [],
applyRefundReasons: [
'商品质量问题',
'商品与描述不符',
'商品破损',
'商品错发/漏发',
'其他原因'
],
cancelReasons: [
'不想要了',
'拍错了',
'商品质量问题',
'其他原因'
]
};
},
onLoad(options) {
const item = JSON.parse(options?.item);
console.log("🚀 ~ onLoad ~ item:", item)
this.currentAfterSale = item;
// 退
if (item) {
this.refundAmount = item.sales_price || 0;
this.maxRefundAmount = item.sales_price || 0;
}
},
methods: {
//
closeAfterSalePopup2() {
this.afterSalePopup2 = false;
},
closeAfterSalePopup3() {
this.afterSalePopup3 = false;
},
//
selectAfterSaleType2(index) {
this.selectedAfterSaleType2 = index;
},
// 退
selectAsReason(index) {
this.selectedAsReason = index;
},
// 退
confirmAfterSaleCancel2() {
const afterSaleTypes = ['退货退款', '退货'];
const selectedType = afterSaleTypes[this.selectedAfterSaleType2];
console.log('选中的售后类型:', selectedType);
let selectedReasonText = '';
if (selectedType == '退货退款') {
selectedReasonText = this.applyRefundReasons[this.selectedAsReason];
} else {
selectedReasonText = this.cancelReasons[this.selectedAsReason];
}
console.log('退款原因:', selectedReasonText);
// 退
this.selectedServiceType = selectedType;
this.selectedRefundReason = selectedReasonText;
this.selectAsReason(0);
this.afterSalePopup2 = false;
},
// 退
openAfterSalePopup2(type) {
this.afterSalePopup3 = false;
this.afterSalePopup2 = true;
},
//
afterReadImg(e) {
e.file.forEach(item => {
upload(item.url, res => {
this.imgList.push({ url: picUrl + res.data.path });
console.log('imgList:', this.imgList);
});
});
},
//
deletePic(e) {
this.imgList.splice(e.index, 1);
},
// 退
modifyRefundAmount() {
console.log('修改退款金额');
// 退
},
//
viewAddressDetails() {
console.log('查看地址详情');
//
},
// 退
submitRefundApplication() {
if (!this.selectedServiceType || !this.selectedRefundReason) {
uni.showToast({
title: '请选择服务类型和退款原因',
icon: 'none'
});
return;
}
//
const refundInfo = {
serviceType: this.selectedServiceType,
refundReason: this.selectedRefundReason,
refundAmount: this.refundAmount,
maxRefundAmount: this.maxRefundAmount,
postage: this.postage,
refundDescription: this.refundDescription,
refundMethod: this.refundMethod,
merchantAddress: this.merchantAddress,
merchantContact: this.merchantContact,
imgList: this.imgList
};
console.log('提交退款申请:', refundInfo);
this.afterSalePopup3 = false;
//
uni.showToast({
title: '退款申请提交成功',
icon: 'success'
});
}
}
};
</script>
<style>
@import url('./index.css');
</style>

View File

@ -0,0 +1,495 @@
page {
background-color: #f6f7fb;
padding-bottom: 120rpx;
}
/* 全部流程弹窗样式 */
.all-process-popup {
background-color: #ffffff;
border-radius: 20rpx;
padding: 30rpx;
position: relative;
}
.popup-title {
font-size: 32rpx;
font-weight: bold;
color: #333333;
text-align: center;
margin-bottom: 30rpx;
}
.process-steps_top {
padding: 30rpx;
background-color: #ffffff;
}
.process-steps {
margin-left: 30rpx;
}
.step-item {
display: flex;
margin-bottom: 30rpx;
position: relative;
}
.step-line {
width: 2rpx;
height: 100%;
background-color: #d9d9d9;
position: absolute;
left: 12rpx;
top: 30rpx;
z-index: 1;
}
.step-line.active {
background-color: #ff4d4f;
}
.step-circle {
width: 20rpx;
height: 20rpx;
border-radius: 50%;
border: 2rpx solid #d9d9d9;
background-color: #ffffff;
margin-right: 20rpx;
z-index: 2;
}
.step-circle.active {
border-color: #ff4d4f;
background-color: #fff2f0;
}
.step-circle.active2 {
border-color: #ff4d4f;
background-color: #ff4d4f;
}
.step-info {
flex: 1;
}
.step-title {
font-size: 28rpx;
color: #999999;
margin-bottom: 10rpx;
display: block;
}
.step-title.active {
color: #ff4d4f;
font-weight: bold;
}
.step-desc {
font-size: 24rpx;
color: #666666;
margin: 10rpx;
}
.step-desc2 {
font-size: 24rpx;
color: #666666;
margin-bottom: 10rpx;
display: block;
}
.confirm-btn {
width: 90%;
height: 90rpx;
background-color: #ff4d4f;
color: #ffffff;
border-radius: 45rpx;
font-size: 32rpx;
line-height: 90rpx;
text-align: center;
margin: 40rpx auto;
display: block;
border: none;
}
.close-btn {
position: absolute;
top: 20rpx;
right: 20rpx;
font-size: 28rpx;
color: #999999;
}
.all-process-link {
font-size: 26rpx;
color: #333;
font-weight: bold;
margin-top: 20rpx;
margin-left: 240rpx;
}
.status-tip {
background-color: #ffffff;
padding: 30rpx 20rpx;
margin-bottom: 20rpx;
text-align: center;
}
.status-title {
font-size: 40rpx;
font-weight: bold;
color: #333333;
display: block;
margin-bottom: 10rpx;
}
.status-desc {
font-size: 24rpx;
color: #999999;
display: block;
margin-bottom: 5rpx;
}
.hr {
height: 20rpx;
background: #f5f7fb;
}
.goods-info {
background-color: #ffffff;
margin-bottom: 20rpx;
padding: 20rpx;
}
.goods-item {
display: flex;
padding: 10rpx 0;
border-bottom: 1rpx solid #eeeeee;
position: relative;
}
.goods-image {
width: 160rpx;
height: 160rpx;
border-radius: 10rpx;
margin-right: 20rpx;
}
.goods-details {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.asGoodTag {
background-color: #ff7d00;
color: white;
font-size: 22rpx;
padding: 5rpx 10rpx;
border-radius: 8rpx 0 8rpx 8rpx;
}
.asGoodTag1 {
margin-right: 15rpx;
}
.tag-img {
position: absolute;
top: 133rpx;
left: 80rpx;
z-index: 1;
}
.goods-name {
font-weight: bold;
font-size: 28rpx;
color: #333333;
margin-bottom: 10rpx;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.goods-desc {
font-size: 26rpx;
color: #ff4d4f;
background-color: #fff2f0;
padding: 4rpx 12rpx;
border-radius: 8rpx;
display: inline-block;
margin: 10rpx 0;
}
.goods-price {
font-size: 26rpx;
color: #ff4d4f;
margin-bottom: 5rpx;
}
.goods-count {
font-size: 24rpx;
color: #666666;
float: right;
}
.refund-info {
background-color: #ffffff;
margin-bottom: 20rpx;
}
.info-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 25rpx 20rpx;
border-bottom: 1rpx solid #eeeeee;
}
.info-item2 {
display: flex;
align-items: center;
padding: 25rpx 20rpx;
}
.address-content {
align-items: center;
flex: 1;
}
.text-wrapper_8 {
display: flex;
flex: 1;
}
.text_41 {
font-size: 28rpx;
color: #333333;
font-weight: bold;
margin-bottom: 8rpx;
display: block;
}
.text_42 {
font-size: 28rpx;
color: #666666;
display: block;
}
.block_15 {
flex: 2;
display: flex;
justify-content: space-between
}
.address-view {
display: flex;
align-items: flex-start;
margin-bottom: 10rpx;
}
.address-val{
display: flex;
align-items: center;
word-break: break-all;
border: 1rpx solid red;
}
.copy-icon {
width: 30rpx;
height: 30rpx;
background-image: url('https://wechat-img-file.oss-cn-beijing.aliyuncs.com/myOrder/copy.png');
background-size: cover;
}
.icon_2 {
width: 40rpx;
height: 40rpx;
}
.info-label {
font-s2ize: 28rpx;
color: #666666;
width: 200rpx;
}
.info-value {
font-size: 28rpx;
color: #333333;
flex: 1;
text-align: right;
padding-right: 20rpx;
}
.info-arrow {
width: 16rpx;
height: 16rpx;
border-top: 2rpx solid #999999;
border-right: 2rpx solid #999999;
transform: rotate(45deg);
}
.action-buttons {
display: flex;
padding: 20rpx;
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 999;
margin-bottom: 30rpx;
}
.cancel-btn {
width: 220rpx;
height: 80rpx;
background-color: #d9d9d9;
color: #333;
border-radius: 40rpx;
font-size: 28rpx;
line-height: 80rpx;
text-align: center;
margin-right: 20rpx;
}
.urge-btn {
width: 220rpx;
height: 80rpx;
background-color: #ffe8e5;
color: #ed4d1c;
border: none;
border-radius: 40rpx;
font-size: 28rpx;
line-height: 80rpx;
text-align: center;
margin-left: 20rpx;
}
.bottomImg{
width: 70rpx;
height: 80rpx;
}
/* 退款去向弹窗样式 */
.money-path-popup-content {
background-color: #ffffff;
border-top-left-radius: 30rpx;
border-top-right-radius: 30rpx;
padding: 20rpx;
height: 45vh;
overflow-y: auto;
}
.popup-header {
display: flex;
align-items: center;
padding: 20rpx 0;
margin-bottom: 30rpx;
}
.header-title {
font-size: 32rpx;
font-weight: bold;
color: #333333;
margin: 0 auto;
}
.close-btn {
font-size: 28rpx;
color: #999999;
}
.refund-method {
margin-bottom: 40rpx;
}
.method-item {
display: flex;
align-items: center;
padding: 20rpx;
}
.wechat-icon {
width: 40rpx;
height: 35rpx;
background-size: cover;
margin-right: 15rpx;
}
.method-text {
font-size: 30rpx;
color: #333333;
flex: 1;
}
.method-text2 {
font-size: 28rpx;
color: #9d9d9d;
flex: 1;
}
.method-amount {
font-size: 30rpx;
font-weight: bold;
}
.refund-status {
padding: 0 70rpx;
}
.status-item {
display: flex;
padding: 20rpx 0;
position: relative;
padding-left: 40rpx;
margin: 20rpx 0;
}
.status-item.active .status-dot {
border: 3rpx solid #e35e38;
}
.status-item.active .status-line {
/* background-color: #e35e38; */
}
.status-dot {
width: 15rpx;
height: 15rpx;
border-radius: 50%;
border: 2rpx solid #d9d9d9;
background-color: #ffffff;
position: absolute;
left: 0;
top: 20rpx;
z-index: 1;
}
.status-line {
border-left: 4rpx dotted #ea704b86;
height: 100%;
position: absolute;
left: 7rpx;
top: 40rpx;
}
.status-item:last-child .status-line {
display: none;
}
.status-info {
flex: 1;
}
.status-text {
font-size: 28rpx;
color: #333333;
display: block;
margin-bottom: 10rpx;
}
.status-desc {
font-size: 24rpx;
color: #999999;
display: block;
}

View File

@ -0,0 +1,314 @@
<template>
<view class="container page">
<!-- 进度指示器 -->
<view class="process-steps_top" v-if="false">
<view class="step-item">
<view class="step-line"></view>
<view class="step-circle active"></view>
<view class="step-info">
<text class="step-title">申请换货</text>
</view>
</view>
<view class="step-item">
<view class="step-line"></view>
<view class="step-circle active active2"></view>
<view class="step-info">
<text class="step-title active">等待商家处理退货申请<text class="step-desc">还剩6天23时26分</text></text>
<text class="step-desc2">如卖家同意,请按照卖家给出的地址及时寄出</text>
<text class="step-desc2">如卖超时未及时处理,平台将自动同意,请按照平台给出的地址及时寄出</text>
<text class="step-desc2">等待买家退货</text>
</view>
</view>
<view class="step-item">
<view class="step-circle"></view>
<view class="step-info">
<text class="step-title">
待卖家确认收货并发货
<text class="all-process-link" @click="showAllProcess">全部流程 ></text>
</text>
</view>
</view>
</view>
<view class="status-tip" v-if="false">
<text class="status-title">换货关闭</text>
<text class="status-desc">2025年7月25日 11:30</text>
<text class="status-desc">由于您主动撤销换货申请,换货关闭</text>
</view>
<view class="status-tip">
<text class="status-title">换货关闭</text>
<text class="status-desc">2025年7月25日 11:30</text>
<text class="status-desc" style="color: #f63b08;">商家拒绝了您的换货申请,换货关闭</text>
</view>
<view class="hr"></view>
<view v-if="false">
<view class="info-item2">
<view class="address-content">
<view class="text-wrapper_8">
<text class="text_41">高尚</text>
<text class="text_42">15901518415</text>
</view>
<view class="block_15">
<view class="address-view">
<view class="address-val">
<text>河北省衡水市桃城区路北街道中心北大街世纪名城41号楼</text>
<!-- <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/myOrder/copy.png"
class="copy-icon" @click="copyRefundNo"/> -->
</view>
</view>
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/af_update_address.png" class="icon_2" />
</view>
</view>
</view>
<button class="addOrderIdBtn" @click="addOrderId">填写单号</button>
</view>
<!-- 商品信息 -->
<view>
<view class="goods-info">
<view class="goods-item">
<view class="asGoodTag tag-img"
v-if="currentAfterSale.commodity_order_item[0].is_support_same_day === 1">当日达</view>
<image class="goods-image" :src="currentAfterSale.commodity_order_item[0].commodity_pic"></image>
<view class="goods-details">
<text class="goods-name">
<text class="asGoodTag asGoodTag1"
v-if="currentAfterSale.commodity_order_item[0].is_support_same_day === 1">当日达</text>
{{ currentAfterSale.commodity_order_item[0].goods_name }}
</text>
<text class="goods-desc">{{ ite.after_sales_reason }}</text>
<text class="goods-price">
{{ '¥' + currentAfterSale.commodity_order_item[0].sales_price.toFixed(2) + '/个' }}
<text class="goods-count">X{{ currentAfterSale.commodity_order_item[0].count }}</text>
</text>
</view>
</view>
</view>
<!-- 退款信息 -->
<view class="refund-info">
<view class="info-item">
<text class="info-label">服务类型</text>
<text class="info-value">{{ getServiceTypeText(currentAfterSale.after_sales_type) }}</text>
<text class="info-arrow"></text>
</view>
<view class="info-item">
<text class="info-label">退款原因</text>
<text class="info-value">{{ currentAfterSale.after_sales_reason }}</text>
<text class="info-arrow"></text>
</view>
<view class="info-item">
<text class="info-label">换货数量</text>
<text class="info-value">{{ currentAfterSale.commodity_order_item[0].count }}</text>
</view>
<view class="info-item">
<text class="info-label">申请时间</text>
<text class="info-value">{{ formatDate(currentAfterSale.create_time) }}</text>
</view>
<view class="info-item">
<text class="info-label">退款编号</text>
<text class="info-value">{{ currentAfterSale.after_sales_no }}</text>
<text class="copy-icon" @click="copyRefundNo"></text>
</view>
<view class="info-item">
<text class="info-label">收货地址</text>
<text class="info-value">{{ currentAfterSale.user_address }}</text>
</view>
<view class="info-item" v-if="false">
<text class="info-label">退款完结</text>
<text class="info-value">{{ formatDate(currentAfterSale.create_time) }}</text>
</view>
</view>
</view>
<!-- 操作按钮 -->
<view class="action-buttons" v-if="false">
<button class="cancel-btn" @click="cancelRefund">撤销申请</button>
<button class="urge-btn" @click="modifyRefund">修改申请</button>
</view>
<!-- 全部流程弹窗 -->
<u-popup ref="allProcessPopup" :show="allProcessPopupShow" :round="10" @close="closeAllProcessPopup">
<view class="all-process-popup">
<view class="popup-title">全部退款流程</view>
<view class="close-btn" @click="closeAllProcessPopup">取消</view>
<view class="process-steps">
<view class="step-item">
<view class="step-line"></view>
<view class="step-circle active"></view>
<view class="step-info">
<text class="step-title">申请换货</text>
</view>
</view>
<view class="step-item">
<view class="step-line"></view>
<view class="step-circle active"></view>
<view class="step-info">
<text class="step-title">商家同意换货</text>
</view>
</view>
<view class="step-item">
<view class="step-line"></view>
<view class="step-circle active active2"></view>
<view class="step-info">
<text class="step-title active">等待商家处理退货申请<text class="step-desc">还剩6天23时26分</text></text>
<text class="step-desc2">卖家已同意换货请您及时退回需更换的商品</text>
<text class="step-desc2">如您超时未填写退货物流信息平台将自动关闭本次换货申请</text>
<text class="step-desc2">未经卖家同意请不要使用到付或平邮</text>
</view>
</view>
<view class="step-item">
<view class="step-line"></view>
<view class="step-circle"></view>
<view class="step-info">
<text class="step-title">待卖家确认收货并发货</text>
</view>
</view>
<view class="step-item">
<view class="step-line"></view>
<view class="step-circle"></view>
<view class="step-info">
<text class="step-title">卖家已发货请注意查收</text>
</view>
</view>
<view class="step-item">
<view class="step-circle"></view>
<view class="step-info">
<text class="step-title">换货完成</text>
</view>
</view>
</view>
<button class="confirm-btn" @click="closeAllProcessPopup">我知道了</button>
</view>
</u-popup>
</view>
</template>
<script>
import {
isPhone,
picUrl,
request,
upload,
NavgateTo
} from '../../../utils';
export default {
data() {
return {
currentAfterSale: {},
pickerDefaultDate: new Date(),
allProcessPopupShow: false
};
},
created() {
//
this.pickerDefaultDate = new Date(this.currentAfterSale.create_time);
},
onLoad(options) {
const item = JSON.parse(options?.item);
console.log("🚀 ~ onLoad ~ item:", item)
this.currentAfterSale = item;
},
methods: {
getServiceTypeText(type) {
return type === 1 ? '退货退款' : '仅退款';
},
//
formatDate(dateString) {
if (!dateString) return '';
const date = new Date(dateString);
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}:${String(date.getSeconds()).padStart(2, '0')}`;
},
//
copyAdress() {
uni.setClipboardData({
data: this.currentAfterSale.after_sales_no,
success: () => {
uni.showToast({
title: '复制成功',
icon: 'success'
});
},
fail: () => {
uni.showToast({
title: '复制失败',
icon: 'none'
});
}
});
},
addOrderId() {
NavgateTo(`../returnLogistics/index?item=${JSON.stringify(this.currentAfterSale)}`);
},
// 退
copyRefundNo() {
uni.setClipboardData({
data: this.currentAfterSale.after_sales_no,
success: () => {
uni.showToast({
title: '复制成功',
icon: 'success'
});
},
fail: () => {
uni.showToast({
title: '复制失败',
icon: 'none'
});
}
});
},
//
cancelRefund() {
uni.showModal({
title: "确定要撤销本次售后申请吗?",
showCancel: true,
cancelText: "暂不撤销",
confirmText: "确认撤销",
confirmColor: "#ff4d4f",
success: (res) => {
if (res.confirm) {
//
uni.showToast({
title: '订单撤销成功',
icon: 'success'
});
}
},
});
},
//
modifyRefund() {
NavgateTo(`../apply/index?item=${JSON.stringify(this.currentAfterSale)}`);
},
//
showAllProcess() {
this.allProcessPopupShow = true;
},
//
closeAllProcessPopup() {
this.allProcessPopupShow = false;
},
}
};
</script>
<style scoped>
@import url('./index.css')
</style>

View File

@ -160,7 +160,7 @@ export default {
});
return;
}
// API
//
uni.showToast({
title: "评价提交成功",
icon: "success",

View File

@ -137,6 +137,16 @@ page {
margin: 0;
}
.afterSaleNum {
font-size: 26rpx;
color: #ff3710;
align-items: center;
display: flex;
position: relative;
right: 230rpx;
font-weight: bold;
}
.yfd-btn {
width: 160rpx;
height: 60rpx;
@ -157,4 +167,404 @@ page {
border-radius: 30rpx;
font-size: 24rpx;
margin: 0;
margin-left: 15rpx;
}
.required{
color: red;
}
.cancel-reason-container {
width: 100%;
background-color: #fff;
border-radius: 16rpx;
padding: 30rpx;
box-sizing: border-box;
max-height: 80vh;
overflow-y: auto;
}
.asType {
margin-bottom: 30rpx;
}
.asType text {
font-size: 28rpx;
color: #333;
display: block;
margin-bottom: 20rpx;
}
.asTabs {
display: flex;
gap: 20rpx;
}
.asTab {
padding: 15rpx 20rpx;
border-radius: 10rpx;
font-size: 28rpx;
color: #333;
}
.asTab.active {
border: 1rpx solid #ff5252;
color: #ff5252;
}
.asTabs2 {
display: flex;
justify-content: space-between;
}
.asTab2 {
width: 50%;
padding: 15rpx 20rpx;
font-size: 28rpx;
color: #333;
text-align: center;
}
.asTab2.active {
border-bottom: 1rpx solid #ff5252;
color: #ff5252;
margin-bottom: 20rpx;
}
.asGoodsInfo {
margin-bottom: 30rpx;
}
.asGoodInfo {
display: flex;
padding: 20rpx 0;
border-bottom: 1rpx solid #f0f0f0;
position: relative;
}
.asGoodRadio{
margin-top: 60rpx;
}
.asGoodImg {
width: 160rpx;
height: 160rpx;
border-radius: 20rpx;
margin-right: 20rpx;
object-fit: cover;
}
.asGoodDetail {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.asGoodTitle {
font-size: 28rpx;
color: #333;
line-height: 40rpx;
display: -webkit-box;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.asGoodTag {
background-color: #ff7d00;
color: white;
font-size: 22rpx;
padding: 5rpx 10rpx;
border-radius: 20rpx 0 20rpx 20rpx;
}
.asGoodTag1 {
margin-right: 15rpx;
}
.tag-img {
position: absolute;
top: 145rpx;
left: 130rpx;
z-index: 1;
}
.asGoodDesc {
font-size: 24rpx;
color: #999;
}
.asGoodPrice {
font-size: 28rpx;
color: #ff5252;
font-weight: bold;
}
.asGoodNum {
font-size: 28rpx;
color: #333;
align-self: flex-start;
margin-top: 120rpx;
}
.title {
font-size: 32rpx;
font-weight: bold;
text-align: center;
margin-bottom: 30rpx;
color: #333;
}
.reason-list {
margin-bottom: 30rpx;
}
.reason-item {
display: flex;
align-items: center;
padding: 20rpx 0;
border-bottom: 1rpx solid #f0f0f0;
}
.radio {
width: 28rpx;
height: 28rpx;
border-radius: 50%;
border: 2rpx solid #999;
margin-right: 20rpx;
position: relative;
}
.radio.active {
border-color: #e60012;
}
.radio.active::after {
content: '';
position: absolute;
width: 14rpx;
height: 14rpx;
background-color: #e60012;
border-radius: 50%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.reason-item text {
font-size: 28rpx;
color: #333;
}
.confirm-btn {
width: 100%;
height: 88rpx;
background-color: #ff451b;
color: #fff;
font-size: 32rpx;
border-radius: 44rpx;
line-height: 88rpx;
text-align: center;
margin-top: 20rpx;
border: none;
}
.noSalePopup {
padding: 50rpx 50rpx 0 50rpx;
text-align: center;
}
.noSalePopup-btn {
width: 250rpx;
height: 70rpx;
background-color: #e60012;
color: #fff;
font-size: 32rpx;
border-radius: 44rpx;
line-height: 70rpx;
text-align: center;
margin-top: 40rpx;
border: none;
}
/* 确认退款信息弹窗样式 */
.refund-info-container {
background-color: #ffffff;
border-radius: 10rpx;
padding: 30rpx;
box-sizing: border-box;
}
.refund-title {
font-size: 32rpx;
color: #333333;
font-weight: bold;
text-align: center;
margin-bottom: 30rpx;
}
.refund-item {
display: flex;
margin-bottom: 26rpx;
padding-bottom: 26rpx;
border-bottom: 1rpx solid #f0f0f0;
}
.hr{
position: relative;
left: -30rpx;
right: -30rpx;
width: 120%;
height: 20rpx;
background-color: #f0f2f5;
margin-top: 20rpx;
margin-bottom: 30rpx;
}
.refund-item2 {
margin-bottom: 26rpx;
border-bottom: 1rpx solid #f0f0f0;
}
.refund-item:last-child {
border-bottom: none;
margin-bottom: 0;
padding-bottom: 0;
}
.refund-label {
width: 200rpx;
font-size: 28rpx;
color: #333333;
display: flex;
align-items: center;
}
.refund-value {
flex: 1;
font-size: 28rpx;
color: #666666;
text-align: right;
display: flex;
justify-content: flex-end;
align-items: center;
position: relative;
}
.price {
color: #ff4d4f;
font-size: 32rpx;
font-weight: bold;
}
.modify-btn {
color: #989898;
font-size: 26rpx;
margin-left: 15rpx;
}
.refund-hint {
font-size: 24rpx;
color: #999999;
text-align: right;
position: absolute;
top: 45rpx;
}
.refund-description {
width: 100%;
height: 160rpx;
border: 1rpx solid #e8e8e8;
border-radius: 8rpx;
padding: 20rpx;
box-sizing: border-box;
font-size: 26rpx;
color: #333333;
resize: none;
margin-top: 10rpx;
}
.refund-attachment {
margin-top: 20rpx;
}
.upload-btn {
display: flex;
align-items: center;
font-size: 26rpx;
color: #1989fa;
}
.upload-icon {
width: 40rpx;
height: 40rpx;
margin-right: 10rpx;
}
.contact-info {
font-size: 26rpx;
color: #666666;
margin-top: 10rpx;
text-align: right;
}
.submit-btn {
width: 100%;
height: 90rpx;
background-color: #ff4d4f;
color: #ffffff;
font-size: 32rpx;
border-radius: 45rpx;
margin-top: 30rpx;
display: flex;
justify-content: center;
align-items: center;
border: none;
}
.arrow-right {
display: inline-block;
width: 14rpx;
height: 14rpx;
border-top: 2rpx solid #999999;
border-right: 2rpx solid #999999;
transform: rotate(45deg);
margin-left: 10rpx;
}
/* 图片上传 */
.imgCon {
font-size: 18rpx;
color: #222222;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 120rpx;
height: 120rpx;
background: #F6F7FB;
border: 1rpx solid #D1D1D1;
border-radius: 10rpx 10rpx 10rpx 10rpx;
margin: 20rpx 0;
}
.imgCon image {
width: 34rpx;
height: 34rpx;
margin-bottom: 8rpx;
}
.u-upload__wrap__preview {
width: 120rpx;
height: 120rpx;
border-radius: 10rpx 0rpx 10rpx 10rpx !important;
margin-top: 20rpx !important;
}
.u-upload__wrap__preview__image {
width: 100% !important;
height: 100% !important;
object-fit: cover;
}

View File

@ -1,12 +1,8 @@
<template>
<view class="container">
<view class="tabs">
<view
v-for="(item, index) in categoryList"
:key="index"
:class="['tabItem', selectedTab === index ? 'active2' : '']"
@click="selectTab(index, item)"
>
<view v-for="(item, index) in categoryList" :key="index"
:class="['tabItem', selectedTab === index ? 'active2' : '']" @click="selectTab(index, item)">
{{ item.category_name }}
</view>
@ -19,17 +15,17 @@
<view v-if="selectedTab === 7">
<rated />
</view>
<view v-if="selectedTab === 8">
<afterSale />
</view>
<view v-else>
<view v-for="(item, index) in orderData" :key="index">
<view class="contentList">
<!-- 订单头部信息 -->
<view class="order-header" @click="toDetails(item.order_status)">
<view class="order-header" @click="toDetails(item)">
<text>提交订单{{ item.order_time }}</text>
<view
v-if="item.order_status == 6 || item.order_status == 5"
class="status3"
>{{ getOrderStatus(item.order_status) }}</view
>
<view v-if="item.order_status == 6 || item.order_status == 5" class="status3">{{
getOrderStatus(item.order_status) }}</view>
<view v-else-if="item.order_status == 7" class="status2">
<img src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/myOrder/refund.png" />
{{ getOrderStatus(item.order_status) }}
@ -40,53 +36,43 @@
</view>
<!-- 商品列表 -->
<view class="goods-list" @click="toDetails(item.order_status)">
<view
v-for="(goods, goodsIndex) in item.commodity_order_item_list
.commodity_pic"
:key="goodsIndex"
class="goods-item"
>
<image :src="goods.image" class="goods-img"></image>
<view class="goods-list" @click="toDetails(item)">
<view v-for="(goods, goodsIndex) in item.commodity_order_item_list" :key="goodsIndex" class="goods-item">
<image :src="goods.commodity_pic" class="goods-img"></image>
</view>
</view>
<!-- 订单底部信息 -->
<view class="order-footer">
<view
class="order-footer-text"
@click="toDetails(item.order_status)"
>{{ item.total_count }}件商品共计
<view class="order-footer-text" @click="toDetails(item)">{{ item.total_count }}件商品共计
<text> {{ item.total_amount }}</text>
</view>
<view>
<view class="btn-group" v-if="item.order_status === 1">
<button class="cancel-btn" @click="cancelOrder">
<button class="cancel-btn" @click="cancelOrder(item)">
取消订单
</button>
<button class="yfd-btn" @click="cancelOrder">运费单</button>
<button class="pay-btn" @click="goToPay">立即支付</button>
<!-- <button class="yfd-btn" @click="cancelOrder">运费单</button> -->
<button class="pay-btn" @click="goToPay(item)">立即支付</button>
</view>
<view class="btn-group" v-if="item.order_status === 3">
<button class="yfd-btn" @click="cancelOrder">运费单</button>
</view>
<view class="btn-group" v-if="item.order_status === 6">
<button class="yfd-btn" @click="cancelOrder">运费单</button>
<button class="pay-btn" @click="cancelOrder">再来一单</button>
<button class="cancel-btn" @click="applyRefund(item)">申请退款</button>
</view>
<view class="btn-group" v-if="item.order_status === 4">
<button class="cancel-btn" @click="checkLogistics">
查看物流
</button>
<button class="yfd-btn" @click="cancelOrder">运费单</button>
<button class="pay-btn" @click="cancelOrder">再来一单</button>
<button class="cancel-btn" @click="viewLogistics(item)">查看物流</button>
<button class="pay-btn" @click="confirmReceiving(item)">确认收货</button>
</view>
<view class="btn-group" v-if="item.order_status === 5">
<button class="cancel-btn" @click="orderEvaluate">
<text class="afterSaleNum">{{item.commodity_order_item_list.length}}笔售后</text>
<button class="cancel-btn" @click="afterSale(item)">退换/售后</button>
<button class="pay-btn" @click="cancelOrder">评价</button>
</view>
<view class="btn-group" v-if="item.order_status === 6">
<!-- <button class="cancel-btn" @click="orderEvaluate">
服务评价
</button>
<button class="yfd-btn" @click="cancelOrder">运费单</button>
<button class="pay-btn" @click="cancelOrder">再来一单</button>
<button class="pay-btn" @click="cancelOrder">再来一单</button> -->
</view>
<view class="btn-group" v-if="item.order_status === 7">
<button class="pay-btn" @click="cancelOrder">再来一单</button>
@ -97,18 +83,59 @@
</view>
</view>
</view>
<!------------------ 以下为popup ------------------>
<!-- 取消订单 -->
<cancel-order-popup :showPopup.sync="showPopup" @orderCancelled="handleOrderCancelled" />
<!-- 申请退款 -->
<refund-popup :showPopup.sync="showTkPopup" @refundConfirmed="handleRefundConfirmed" />
<!-- 退换 售后 - 选择退款原因 -->
<!-- 售后弹窗组件 -->
<after-sale-popup :afterSaleGoods.sync="afterSaleGoods" ref="afterSalePopupRef"
@refundSubmitted="handleRefundSubmitted" />
<!-- 无售后商品 -->
<view>
<u-popup ref="popup" mode="center" :show="noSalePopup" :round="15" :mask-close-able="false">
<view class="noSalePopup">
<view>抱歉该订单已无可申请售后的商品</view>
<button class="noSalePopup-btn" @click="noSalePopup = false">我知道了</button>
</view>
</u-popup>
</view>
</view>
</template>
<script>
import { picUrl, NavgateTo, request } from "../../../utils";
import {
isPhone,
picUrl,
request,
upload,
NavgateTo
} from '../../../utils';
import { apiArr } from "../../../api/order";
import Rated from "./rated.vue";
import AwaitRated from "./awaitRated.vue";
import { apiArr as afterSaleApi } from "../../../api/afterSale";
import Rated from "../rated/rated.vue";
import AwaitRated from "../awaitRated/awaitRated.vue";
import AfterSale from "../afterSale/index.vue";
import cancelOrderPopup from './popup/cancelOrder/cancelOrder.vue';
import refundPopup from './popup/refund/refund.vue';
import afterSalePopup from './popup/afterSale/index.vue';
import orderMockData from "./orderMockData.json";
export default {
components: {
Rated,
AwaitRated,
AfterSale,
cancelOrderPopup,
refundPopup,
afterSalePopup
},
data() {
return {
@ -124,7 +151,13 @@ export default {
{ category_name: "售后" },
],
selectedTab: 0,
orderData: [],
orderData: orderMockData,
showPopup: false,//
afterSaleGoods: [],//
noSalePopup: false,//
showTkPopup: false,//退
afterSaleItem: '',//
};
},
methods: {
@ -134,23 +167,107 @@ export default {
this.getOrderList();
}
},
cancelOrder() {
//
//
cancelOrder(item) {
this.afterSaleItem = item;
this.showPopup = true
},
//
handleOrderCancelled(data) {
console.log("🚀 ~ handleOrderCancelled ~ 取消原因:", data.reason);
const params = {
order_id: this.afterSaleItem.id,
method: 1,
cancel_reason: data.reason,
}
request(afterSaleApi.cancelOrConfirm, "POST", params).then((res) => {
console.log("🚀 ~ handleOrderCancelled ~ res:", res)
});
},
//
afterSale(item) {
this.afterSaleGoods = item.commodity_order_item_list;
this.$refs.afterSalePopupRef.openAfterSalePopup();
console.log(item.id);
//
// request(afterSaleApi.isAllow, "POST", {
// order_id: item.id,
// }).then((res) => {
// console.log("🚀 ~ afterSale ~ res:", res)
// if (res.data.is_allow_after_sales) {
// this.afterSaleGoods = res.data.allow_items;
// // this.selectedAsGood = item.commodity_order_item_list[0].id;
// this.$refs.afterSalePopupRef.openAfterSalePopup();
// } else {
// this.noSalePopup = true
// }
// });
},
// 退
handleRefundSubmitted(data) {
console.log("🚀 ~ handleRefundSubmitted ~ 退款申请提交成功:", data);
},
// 退
applyRefund(item) {
this.afterSaleItem = item;
this.showTkPopup = true
},
//
viewLogistics(item) {
},
// 退
handleRefundConfirmed(data) {
console.log("🚀 ~ handleRefundConfirmed ~ handleRefundConfirmed:", this.afterSaleItem)
console.log("🚀 ~ handleRefundConfirmed ~ 退款原因:", data.reason);
const params = {
nick_name: uni.getStorageSync("nickName"),
order_id: this.afterSaleItem.id,
after_sales_type: 1,
after_sales_reason: data.reason,
refund_amount: this.afterSaleItem.total_amount,
order_status: 3
}
console.log("🚀 ~ handleRefundConfirmed ~ parasm:", params)
request(afterSaleApi.afterSaleCreate, "POST", params).then((res) => {
console.log("🚀 ~ handleRefundConfirmed ~ res:", res)
});
},
//
confirmReceiving(item) {
uni.showModal({
title: "提示",
content: "确定要取消订单吗?",
title: "确认收货",
content: "确认收货后订单状态将变为【已完成】,如有售后需求可正常申请退款/售后,确定要确认收货吗?",
success: (res) => {
if (res.confirm) {
// API
const params = {
order_id: item.id,
method: 2,
}
console.log("🚀 ~ confirmReceiving ~ params:", params)
request(afterSaleApi.cancelOrConfirm, "POST", params).then((res) => {
console.log("🚀 ~ handleRefundConfirmed ~ res:", res)
});
}
},
});
},
goToPay() {
goToPay(item) {
console.log(item);
},
toDetails(order_status) {
toDetails(item) {
NavgateTo(
`/packages/myOrders/orderDetails/index?order_status=${order_status}`
`/packages/myOrders/orderDetails/index?item=${JSON.stringify(item)}`
);
},
@ -187,24 +304,7 @@ export default {
request(apiArr.orderList, "POST", {
user_id: uni.getStorageSync("userId"),
}).then((res) => {
const orderList = res.order_list || [];
let filteredData = orderList;
if (this.selectedTab !== 0) {
const statusMap = {
1: 1, //
2: 3, //
3: 4, //
4: 5, //
};
const targetStatus = statusMap[this.selectedTab];
if (targetStatus) {
filteredData = orderList.filter(
(item) => item.order_status === targetStatus
);
}
}
this.orderData = filteredData;
//
});
},
},

View File

@ -0,0 +1,347 @@
[
{
"id": 1001,
"user_id": 20001,
"supplier_id": 3001,
"supplier_name": "鲜丰水果供应链有限公司",
"order_group_id": 40001,
"order_no": "SH20240823001001",
"total_amount": 156.80,
"total_count": 3,
"order_status": 3,
"cancelled_by": "",
"cancel_time": "",
"cancel_reason": "",
"evauate_status": 2,
"after_sales_status": 2,
"receiving_name": "李佳",
"receiving_phone": "15901518415",
"receiving_address": "北京市朝阳区珠江绿洲文化广场3号楼2单元1002室",
"pay_method": "微信支付",
"payment_amount": 156.80,
"payment_status": "已支付",
"payment_time": "2024-08-23 10:15:30",
"payment_serial": "WX202408231015300012345678",
"payer_name": "李佳",
"completed_at": "",
"order_time": "2024-08-23 10:10:22",
"is_same_day": 2,
"estimated_delivery_time": "2024-08-24 09:00-18:00",
"remark": "请放在小区丰巢柜,谢谢",
"shiliu_score": 156.8,
"shiliu_seed": 28.5,
"timeout_time_stamp": 1724413822,
"order_cate": 1,
"create_time": "2024-08-23 10:10:22",
"update_time": "2024-08-23 10:15:30",
"after_sales_count": 0,
"commodity_order_item_list": [
{
"id": 50001,
"order_id": 1001,
"goods_id": 6001,
"goods_name": "泰国金枕榴莲2-2.5斤/个)",
"commodity_pic": "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test.png",
"goods_unit": "个",
"goods_spec": "2-2.5斤",
"cost_price": 45.00,
"sales_price": 69.90,
"count": 1,
"after_sales_status": 2,
"is_support_same_day": 1,
"is_same_day": false
},
{
"id": 50002,
"order_id": 1001,
"goods_id": 6002,
"goods_name": "阳光玫瑰葡萄1斤装",
"commodity_pic": "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test.png",
"goods_unit": "斤",
"goods_spec": "1斤",
"cost_price": 12.00,
"sales_price": 25.90,
"count": 2,
"after_sales_status": 2,
"is_support_same_day": 1,
"is_same_day": false
}
]
},
{
"id": 1002,
"user_id": 20002,
"supplier_id": 3002,
"supplier_name": "优选生鲜超市供应链",
"order_group_id": 40002,
"order_no": "SH20240823001002",
"total_amount": 89.50,
"total_count": 2,
"order_status": 6,
"cancelled_by": "用户",
"cancel_time": "2024-08-23 09:45:10",
"cancel_reason": "临时改变需求,不需要该商品",
"evauate_status": 2,
"after_sales_status": 2,
"receiving_name": "张伟",
"receiving_phone": "13812345678",
"receiving_address": "上海市浦东新区张江高科技园区博云路2号",
"pay_method": "支付宝支付",
"payment_amount": 0.00,
"payment_status": "未支付",
"payment_time": "",
"payment_serial": "",
"payer_name": "",
"completed_at": "",
"order_time": "2024-08-23 09:30:05",
"is_same_day": 1,
"estimated_delivery_time": "2024-08-23 12:00-14:00",
"remark": "无",
"shiliu_score": 0.0,
"shiliu_seed": 0.0,
"timeout_time_stamp": 1724399405,
"order_cate": 2,
"create_time": "2024-08-23 09:30:05",
"update_time": "2024-08-23 09:45:10",
"after_sales_count": 0,
"commodity_order_item_list": [
{
"id": 50003,
"order_id": 1002,
"goods_id": 6003,
"goods_name": "精品富士苹果5斤装",
"commodity_pic": "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test.png",
"goods_unit": "斤",
"goods_spec": "5斤",
"cost_price": 3.50,
"sales_price": 9.90,
"count": 1,
"after_sales_status": 2,
"is_support_same_day": 1,
"is_same_day": true
},
{
"id": 50004,
"order_id": 1002,
"goods_id": 6004,
"goods_name": "蒙牛纯牛奶200ml*16盒",
"commodity_pic": "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test.png",
"goods_unit": "箱",
"goods_spec": "200ml*16盒",
"cost_price": 35.00,
"sales_price": 79.60,
"count": 1,
"after_sales_status": 2,
"is_support_same_day": 1,
"is_same_day": true
}
]
},
{
"id": 1003,
"user_id": 20003,
"supplier_id": 3003,
"supplier_name": "美菜网餐饮供应链",
"order_group_id": 40003,
"order_no": "SH20240822001003",
"total_amount": 328.00,
"total_count": 5,
"order_status": 5,
"cancelled_by": "",
"cancel_time": "",
"cancel_reason": "",
"evauate_status": 1,
"after_sales_status": 1,
"receiving_name": "王芳",
"receiving_phone": "13987654321",
"receiving_address": "广州市天河区天河路385号天俊阁15楼",
"pay_method": "企业对公转账",
"payment_amount": 328.00,
"payment_status": "已支付",
"payment_time": "2024-08-22 15:20:40",
"payment_serial": "BANK202408221520400098765",
"payer_name": "王芳(企业代付)",
"completed_at": "2024-08-22 18:30:15",
"order_time": "2024-08-22 14:50:33",
"is_same_day": 2,
"estimated_delivery_time": "2024-08-23 08:00-10:00",
"remark": "餐饮用食材,请优先配送,包装需防震",
"shiliu_score": 328.0,
"shiliu_seed": 45.2,
"timeout_time_stamp": 1724319033,
"order_cate": 1,
"create_time": "2024-08-22 14:50:33",
"update_time": "2024-08-22 18:30:15",
"after_sales_count": 1,
"commodity_order_item_list": [
{
"id": 50005,
"order_id": 1003,
"goods_id": 6005,
"goods_name": "新鲜生菜1斤装",
"commodity_pic": "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test.png",
"goods_unit": "斤",
"goods_spec": "1斤",
"cost_price": 1.80,
"sales_price": 3.50,
"count": 2,
"after_sales_status": 1,
"is_support_same_day": 2,
"is_same_day": false
},
{
"id": 50006,
"order_id": 1003,
"goods_id": 6006,
"goods_name": "冷冻鸡胸肉1kg装",
"commodity_pic": "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test.png",
"goods_unit": "袋",
"goods_spec": "1kg",
"cost_price": 12.00,
"sales_price": 22.80,
"count": 3,
"after_sales_status": 2,
"is_support_same_day": 2,
"is_same_day": false
}
]
},
{
"id": 1004,
"user_id": 20004,
"supplier_id": 3004,
"supplier_name": "美菜网餐饮供应链",
"order_group_id": 40004,
"order_no": "SH20240822001003",
"total_amount": 328.00,
"total_count": 5,
"order_status": 4,
"cancelled_by": "",
"cancel_time": "",
"cancel_reason": "",
"evauate_status": 1,
"after_sales_status": 1,
"receiving_name": "王芳",
"receiving_phone": "13987654321",
"receiving_address": "广州市天河区天河路385号天俊阁15楼",
"pay_method": "企业对公转账",
"payment_amount": 328.00,
"payment_status": "已支付",
"payment_time": "2024-08-24 10:20:40",
"payment_serial": "BANK202408221520400098765",
"payer_name": "王芳(企业代付)",
"completed_at": "2024-08-24 18:30:15",
"order_time": "2024-08-24 14:50:33",
"is_same_day": 2,
"estimated_delivery_time": "2024-08-23 08:00-10:00",
"remark": "餐饮用食材,请优先配送,包装需防震",
"shiliu_score": 328.0,
"shiliu_seed": 45.2,
"timeout_time_stamp": 1724319033,
"order_cate": 1,
"create_time": "2024-08-24 14:50:33",
"update_time": "2024-08-24 18:30:15",
"after_sales_count": 1,
"commodity_order_item_list": [
{
"id": 50005,
"order_id": 1003,
"goods_id": 6005,
"goods_name": "新鲜生菜1斤装",
"commodity_pic": "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test.png",
"goods_unit": "斤",
"goods_spec": "1斤",
"cost_price": 1.80,
"sales_price": 3.50,
"count": 2,
"after_sales_status": 1,
"is_support_same_day": 2,
"is_same_day": false
},
{
"id": 50006,
"order_id": 1003,
"goods_id": 6006,
"goods_name": "冷冻鸡胸肉1kg装",
"commodity_pic": "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test.png",
"goods_unit": "袋",
"goods_spec": "1kg",
"cost_price": 12.00,
"sales_price": 22.80,
"count": 3,
"after_sales_status": 2,
"is_support_same_day": 2,
"is_same_day": false
}
]
},
{
"id": 1005,
"user_id": 20005,
"supplier_id": 3005,
"supplier_name": "鲜丰水果供应链有限公司",
"order_group_id": 40005,
"order_no": "SH20240823001001",
"total_amount": 156.80,
"total_count": 3,
"order_status": 1,
"cancelled_by": "",
"cancel_time": "",
"cancel_reason": "",
"evauate_status": 2,
"after_sales_status": 2,
"receiving_name": "李佳",
"receiving_phone": "15901518415",
"receiving_address": "北京市朝阳区珠江绿洲文化广场3号楼2单元1002室",
"pay_method": "微信支付",
"payment_amount": 156.80,
"payment_status": "已支付",
"payment_time": "2024-08-23 10:15:30",
"payment_serial": "WX202408231015300012345678",
"payer_name": "李佳",
"completed_at": "",
"order_time": "2024-08-23 10:10:22",
"is_same_day": 2,
"estimated_delivery_time": "2024-08-24 09:00-18:00",
"remark": "请放在小区丰巢柜,谢谢",
"shiliu_score": 156.8,
"shiliu_seed": 28.5,
"timeout_time_stamp": 1724413822,
"order_cate": 1,
"create_time": "2024-08-23 10:10:22",
"update_time": "2024-08-23 10:15:30",
"after_sales_count": 0,
"commodity_order_item_list": [
{
"id": 50001,
"order_id": 1001,
"goods_id": 6001,
"goods_name": "泰国金枕榴莲2-2.5斤/个)",
"commodity_pic": "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test.png",
"goods_unit": "个",
"goods_spec": "2-2.5斤",
"cost_price": 45.00,
"sales_price": 69.90,
"count": 1,
"after_sales_status": 2,
"is_support_same_day": 1,
"is_same_day": false
},
{
"id": 50002,
"order_id": 1001,
"goods_id": 6002,
"goods_name": "阳光玫瑰葡萄1斤装",
"commodity_pic": "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test.png",
"goods_unit": "斤",
"goods_spec": "1斤",
"cost_price": 12.00,
"sales_price": 25.90,
"count": 2,
"after_sales_status": 2,
"is_support_same_day": 1,
"is_same_day": false
}
]
}
]

View File

@ -0,0 +1,473 @@
.required {
color: red;
}
.cancel-reason-container {
width: 100%;
background-color: #fff;
border-radius: 16rpx;
padding: 30rpx;
box-sizing: border-box;
max-height: 80vh;
overflow-y: auto;
}
.asType {
margin-bottom: 30rpx;
}
.asType text {
font-size: 28rpx;
color: #333;
display: block;
margin-bottom: 20rpx;
}
.asTabs {
display: flex;
gap: 20rpx;
}
.asTab {
padding: 15rpx 20rpx;
border-radius: 10rpx;
font-size: 28rpx;
color: #333;
}
.asTab.active {
border: 1rpx solid #ff5252;
color: #ff5252;
}
.asTabs2 {
display: flex;
justify-content: space-between;
}
.asTab2 {
width: 50%;
padding: 15rpx 20rpx;
font-size: 28rpx;
color: #333;
text-align: center;
}
.asTab2.active {
border-bottom: 1rpx solid #ff5252;
color: #ff5252;
margin-bottom: 20rpx;
}
.asGoodsInfo {
margin-bottom: 30rpx;
}
.asGoodInfo {
display: flex;
padding: 20rpx 0;
border-bottom: 1rpx solid #f0f0f0;
position: relative;
}
.asGoodRadio {
margin-top: 60rpx;
}
.asGoodImg {
width: 160rpx;
height: 160rpx;
border-radius: 20rpx;
margin-right: 20rpx;
object-fit: cover;
}
.asGoodDetail {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.asGoodTitle {
font-size: 28rpx;
color: #333;
line-height: 40rpx;
display: -webkit-box;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.asGoodTag {
background-color: #ff7d00;
color: white;
font-size: 22rpx;
padding: 5rpx 10rpx;
border-radius: 20rpx 0 20rpx 20rpx;
}
.asGoodTag1 {
margin-right: 15rpx;
}
.tag-img {
position: absolute;
top: 145rpx;
left: 130rpx;
z-index: 1;
}
.asGoodDesc {
font-size: 24rpx;
color: #999;
}
.asGoodPrice {
font-size: 28rpx;
color: #ff5252;
font-weight: bold;
}
.asGoodNum {
font-size: 28rpx;
color: #333;
align-self: flex-start;
margin-top: 120rpx;
}
.title {
font-size: 32rpx;
font-weight: bold;
text-align: center;
margin-bottom: 30rpx;
color: #333;
}
.reason-list {
margin-bottom: 30rpx;
}
.reason-item {
display: flex;
align-items: center;
padding: 20rpx 0;
border-bottom: 1rpx solid #f0f0f0;
}
.radio {
width: 28rpx;
height: 28rpx;
border-radius: 50%;
border: 2rpx solid #999;
margin-right: 20rpx;
position: relative;
}
.radio.active {
border-color: #e60012;
}
.radio.active::after {
content: '';
position: absolute;
width: 14rpx;
height: 14rpx;
background-color: #e60012;
border-radius: 50%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.reason-item text {
font-size: 28rpx;
color: #333;
}
.confirm-btn {
width: 100%;
height: 88rpx;
background-color: #ff451b;
color: #fff;
font-size: 32rpx;
border-radius: 44rpx;
line-height: 88rpx;
text-align: center;
margin-top: 20rpx;
border: none;
}
/* 确认退款信息弹窗样式 */
.refund-info-container {
background-color: #ffffff;
border-radius: 10rpx;
padding: 30rpx;
box-sizing: border-box;
}
.refund-title {
font-size: 32rpx;
color: #333333;
font-weight: bold;
text-align: center;
margin-bottom: 30rpx;
}
.refund-item {
display: flex;
margin-bottom: 26rpx;
padding-bottom: 26rpx;
border-bottom: 1rpx solid #f0f0f0;
}
.hr {
position: relative;
left: -30rpx;
right: -30rpx;
width: 120%;
height: 20rpx;
background-color: #f0f2f5;
margin-top: 20rpx;
margin-bottom: 30rpx;
}
.refund-item2 {
margin-bottom: 26rpx;
border-bottom: 1rpx solid #f0f0f0;
}
.refund-item:last-child {
border-bottom: none;
margin-bottom: 0;
padding-bottom: 0;
}
.refund-label {
width: 200rpx;
font-size: 28rpx;
color: #333333;
display: flex;
align-items: center;
}
.refund-value {
flex: 1;
font-size: 28rpx;
color: #666666;
text-align: right;
display: flex;
justify-content: flex-end;
align-items: center;
position: relative;
}
.price {
color: #ff4d4f;
font-size: 32rpx;
font-weight: bold;
}
.modify-btn {
color: #989898;
font-size: 26rpx;
margin-left: 15rpx;
}
.refund-hint {
font-size: 24rpx;
color: #999999;
text-align: right;
position: absolute;
top: 45rpx;
}
.refund-description {
width: 100%;
height: 160rpx;
border: 1rpx solid #e8e8e8;
border-radius: 8rpx;
padding: 20rpx;
box-sizing: border-box;
font-size: 26rpx;
color: #333333;
resize: none;
margin-top: 10rpx;
}
.contact-info {
font-size: 24rpx;
color: #666666;
text-align: right;
margin-top: 10rpx;
margin-bottom: 30rpx;
}
.submit-btn {
width: 100%;
height: 88rpx;
background-color: #ff451b;
color: #fff;
font-size: 32rpx;
border-radius: 44rpx;
line-height: 88rpx;
text-align: center;
margin-top: 20rpx;
border: none;
}
.arrow-right {
display: inline-block;
width: 16rpx;
height: 16rpx;
border-top: 2rpx solid #999;
border-right: 2rpx solid #999;
transform: rotate(45deg);
margin-left: 10rpx;
}
.imgCon {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 120rpx;
height: 120rpx;
border: 1rpx dashed #e8e8e8;
border-radius: 8rpx;
margin-top: 20rpx;
}
.imgCon image {
width: 40rpx;
height: 40rpx;
margin-bottom: 10rpx;
}
.imgCon text {
font-size: 24rpx;
color: #999999;
}
.text_42{
font-size: 24rpx;
color: #a7a7a7;
margin-left: 10rpx;
}
.block_15{
display: flex;
margin-top: 15rpx;
justify-content: space-between;
}
.address-view{
display: flex;
}
.copy-icon {
width: 40rpx;
height: 40rpx;
background-image: url('https://wechat-img-file.oss-cn-beijing.aliyuncs.com/myOrder/copy.png');
background-size: cover;
margin-left: 15rpx;
}
.icon_2 {
width: 55rpx;
height: 50rpx;
position: relative;
top: -30rpx;
}
.popup-header {
display: flex;
width: 90%;
padding-left: 80rpx;
margin: 20rpx 0;
}
.popup-header-h3 {
font-weight: bold;
margin: 0 auto;
}
.popup-header-view {
font-size: 24rpx;
color: #999;
margin-right: 30rpx;
}
.temp {
display: flex;
justify-content: space-between;
align-items: center;
}
.temp1 {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 24rpx;
color: #959595;
margin: 20rpx 0 5rpx 0;
}
.temp_img {
width: 35rpx;
height: 35rpx;
margin-right: 10rpx;
}
.temp_img1 {
width: 30rpx;
height: 30rpx;
margin: 5rpx 5rpx 0 5rpx;
}
.itemSize {
width: 30%;
font-size: 26rpx;
color: #333;
background: #F6F7FB;
border-radius: 40rpx;
padding: 10rpx 15rpx;
white-space: nowrap;
margin:20rpx 30rpx;
}
.itemSize_active {
background: #FF370B;
color: #fff;
}
.itemSize-img{
width: 100rpx;
height: 100rpx;
margin-right: 30rpx;
border-radius: 20rpx;
border:1rpx solid red;
}
.itemSize_top{
display: flex;
margin-left: 30rpx;
}
.itemSize_info {
margin-top: 10rpx;
}
.itemSize_name {
font-size: 28rpx;
font-weight: 500;
font-weight: bold;
}
.itemSize_price {
font-size: 28rpx;
font-weight: 500;
margin-top: 10rpx;
color: red;
}

View File

@ -0,0 +1,501 @@
<template>
<view>
<!-- 选择售后商品 -->
<view>
<u-popup ref="popup" :show="afterSalePopup" :round="10" @close="closeAfterSalePopup"
:mask-close-able="false">
<view class="cancel-reason-container">
<view class="title">选择退款原因</view>
<view class="asType">
<text>请选择售后类型</text>
<view class="asTabs">
<view :class="['asTab', selectedAfterSaleType === 0 ? 'active' : '']"
@click="selectAfterSaleType(0)">
退货/退款</view>
<view :class="['asTab', selectedAfterSaleType === 1 ? 'active' : '']"
@click="selectAfterSaleType(1)">换货
</view>
</view>
</view>
<view class="asGoodsInfo" v-for="(item, index) in afterSaleGoods" :key="index">
<view class="asGoodInfo" @click="selectAsGood(item)">
<view :class="['radio asGoodRadio', selectedAsGood == item.id ? 'active' : '']"></view>
<view class="asGoodTag tag-img" v-if="item.is_support_same_day === 1">当日达</view>
<image :src="item.commodity_pic" class="asGoodImg"></image>
<view class="asGoodDetail">
<view class="asGoodTitle">
<text class="asGoodTag asGoodTag1" v-if="item.is_support_same_day === 1">当日达</text>
{{ item.goods_name}}
</view>
<view class="asGoodDesc">{{ item.goods_spec }}</view>
<view class="asGoodPrice">¥{{ item.cost_price }}/</view>
</view>
<view class="asGoodNum">x{{ item.count }}</view>
</view>
</view>
<button class="confirm-btn" @click="confirmAfterSaleCancel">下一步</button>
</view>
</u-popup>
</view>
<!------------------------ 退货退款逻辑 ------------------------>
<!-- 选择退款原因 -->
<view v-if="selectedAfterSaleType === 0">
<u-popup ref="popup" :show="afterSalePopup2" :round="10" @close="closeAfterSalePopup2"
:mask-close-able="false">
<view class="cancel-reason-container">
<view class="title">选择退款原因</view>
<view class="asTabs2">
<view :class="['asTab2', selectedAfterSaleType2 === 0 ? 'active' : '']"
@click="selectAfterSaleType2(0)">
退货退款</view>
<view :class="['asTab2', selectedAfterSaleType2 === 1 ? 'active' : '']"
@click="selectAfterSaleType2(1)">退货
</view>
</view>
<view class="reason-list" v-if="selectedAfterSaleType2 === 0">
<view v-for="(reason, index) in applyRefundReasons" :key="index" class="reason-item"
@click="selectAsReason(index)">
<view :class="['radio', selectedAsReason === index ? 'active' : '']"></view>
<text>{{ reason }}</text>
</view>
</view>
<view class="reason-list" v-if="selectedAfterSaleType2 === 1">
<view v-for="(reason, index) in cancelReasons" :key="index" class="reason-item"
@click="selectAsReason(index)">
<view :class="['radio', selectedAsReason === index ? 'active' : '']"></view>
<text>{{ reason }}</text>
</view>
</view>
<button class="confirm-btn" @click="confirmAfterSaleCancel2">下一步</button>
</view>
</u-popup>
</view>
<!-- 确认退款信息 -->
<view v-if="selectedAfterSaleType === 0">
<u-popup ref="popup" :show="afterSalePopup3" :round="10" @close="closeAfterSalePopup3"
:mask-close-able="false">
<view class="refund-info-container">
<view class="refund-title">确认退款信息</view>
<view class="refund-item">
<view class="refund-label">服务类型<text class="required">*</text></view>
<view class="refund-value" @click="openAfterSalePopup2('serviceType')">
{{ selectedServiceType || '请选择服务类型' }}
<text class="arrow-right"></text>
</view>
</view>
<view class="refund-item">
<view class="refund-label">退款原因<text class="required">*</text></view>
<view class="refund-value" @click="openAfterSalePopup2('refundReason')">
{{ selectedRefundReason || '请选择退款原因' }}
<text class="arrow-right"></text>
</view>
</view>
<view class="refund-item" style="border-bottom: none;">
<view class="refund-label">退款金额<text class="required">*</text></view>
<view class="refund-value">
<text class="price">¥{{ refundAmount || '0.00' }}</text>
<text class="modify-btn" @click="modifyRefundAmount">修改</text>
<view class="refund-hint">可修改最多¥{{ maxRefundAmount || '0.00' }}含发货邮费¥{{ postage || '0.00'
}}</view>
</view>
</view>
<view class="hr"></view>
<view class="refund-item2">
<view class="refund-label">补充描述和凭证</view>
<textarea class="refund-description" placeholder="补充描述,有助于商家更好的处理售后问题"
v-model="refundDescription" maxlength="200"></textarea>
<u-upload :fileList="imgList" @afterRead="afterReadImg" @delete="deletePic" name="1" multiple
:maxCount="3">
<view class="imgCon">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_imageImg.png"
mode="widthFix"></image>
上传凭证
</view>
</u-upload>
</view>
<view class="hr"></view>
<view class="refund-item">
<view class="refund-label">退款方式</view>
<view class="refund-value" style="margin-bottom: 30rpx;">
{{ refundMethod || '自行寄回' }}
<view class="refund-hint">您可自行安排将商品退回商家</view>
</view>
</view>
<view class="refund-item">
<view class="refund-label">商家地址</view>
<view class="refund-value" @click="viewAddressDetails">
{{ merchantAddress || '未设置' }}
<text class="arrow-right"></text>
</view>
</view>
<view class="contact-info">
<text>{{ merchantContact || '未设置' }}</text>
</view>
<button class="submit-btn" @click="submitRefundApplication">提交申请</button>
</view>
</u-popup>
</view>
<!------------------------ 换货逻辑 ------------------------>
<!-- 选择退款原因 -->
<view v-if="selectedAfterSaleType === 1">
<u-popup ref="popup" :show="afterSalePopup2" :round="10" @close="closeAfterSalePopup2"
:mask-close-able="false">
<view class="cancel-reason-container">
<view class="title">选择换货原因</view>
<view class="reason-list">
<view v-for="(reason, index) in exchangeReasons" :key="index" class="reason-item"
@click="selectReason(index)">
<view :class="['radio', selectedReason === index ? 'active' : '']"></view>
<text>{{ reason }}</text>
</view>
</view>
<button class="confirm-btn" @click="confirmChange">下一步</button>
</view>
</u-popup>
</view>
<!-- 确认退款信息 -->
<view v-if="selectedAfterSaleType === 1">
<u-popup ref="popup" :show="afterSalePopup3" :round="10" @close="closeAfterSalePopup3"
:mask-close-able="false">
<view class="refund-info-container">
<view class="refund-title">申请退换</view>
<view class="refund-item">
<view class="refund-label">换货原因<text class="required">*</text></view>
<view class="refund-value" @click="openAfterSalePopup2('refundReason')">
{{ changeRefundReason || '请选择退换原因' }}
<text class="arrow-right"></text>
</view>
</view>
<view class="refund-item">
<view class="refund-label">换货商品<text class="required">*</text></view>
<view class="refund-value" @click="changeGood()">
{{ changeServiceType || '请选择需要换的商品' }}
<text class="arrow-right"></text>
</view>
</view>
<view class="text-wrapper_8">
<text class="text_41">高尚</text>
<text class="text_42">15901518415</text>
</view>
<view class="block_15">
<view class="address-view">
<text> {{ merchantAddress }} </text>
<view class="copy-icon" @click="copyRefundNo"></view>
</view>
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/af_update_address.png" class="icon_2"></image>
</view>
<view class="hr"></view>
<view class="refund-item2">
<view class="refund-label">补充描述和凭证</view>
<textarea class="refund-description" placeholder="补充描述,有助于商家更好的处理售后问题"
v-model="refundDescription" maxlength="200"></textarea>
<u-upload :fileList="imgList" @afterRead="afterReadImg" @delete="deletePic" name="1" multiple
:maxCount="3">
<view class="imgCon">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_imageImg.png"
mode="widthFix"></image>
上传凭证
</view>
</u-upload>
</view>
<button class="submit-btn" @click="submitRefundApplication">提交申请</button>
</view>
</u-popup>
</view>
<!-- 选择商品 -->
<u-popup :show="showSize" round="20rpx" mode="bottom" @close="closeSize">
<view class="popup-header">
<h3 class="popup-header-h3">选择款式</h3>
<view class="popup-header-view" @click="closeSize">取消</view>
</view>
<view class="itemSize_top">
<image :src="changeImg" class="itemSize-img"></image>
<view class="itemSize_info">
<view class="itemSize_name">{{ changeName }}</view>
<view class="itemSize_price">{{ changePrice }}/</view>
</view>
</view>
<view class="itemSize" v-for="(item, index) in info.commodity_goods_info_list" :key="item.id"
@click="changeGG(item, index)" :class="index == currentGGIndex ? 'itemSize_active' : ''">
{{ item.goods_name }} {{ item.goods_spec }} / {{ item.goods_unit }}
</view>
</u-popup>
</view>
</template>
<script>
import { upload, picUrl } from '../../../../../utils';
export default {
name: 'AfterSalePopup',
props: {
afterSaleGoods: {
type: Array,
default: () => []
}
},
data() {
return {
afterSalePopup: false,
afterSalePopup2: false,
afterSalePopup3: false,
selectedAsGood: '',
selectedAfterSaleType: 0, // 0:退/退, 1:
selectedAfterSaleType2: 0, // 0:退/退, 1:退
selectedAsReason: 0,
selectedReason: 0,//
selectedServiceType: '',
selectedRefundReason: '',
changeRefundReason: '', //
changeServiceType: '', //
showSize: false,//
changeImg: "",
changeName: "",
changePrice: "",
refundAmount: 0,
maxRefundAmount: 0,
postage: 0,
refundDescription: '',
refundMethod: '自行寄回',
merchantAddress: '衡水市路北街道中心北大街世纪名城41号楼',
merchantContact: '高尚 18032753127',
imgList: [],
applyRefundReasons: [
'商品质量问题',
'商品与描述不符',
'商品破损',
'商品错发/漏发',
'其他原因'
],
cancelReasons: [
'不想要了',
'拍错了',
'商品质量问题',
'其他原因'
],
exchangeReasons: [
'不想要了,无理由换货',
'商品信息拍错',
'没用/少用优惠',
'缺货',
'其他'
],
};
},
methods: {
//
openAfterSalePopup() {
this.$nextTick(() => {
if (this.afterSaleGoods && this.afterSaleGoods.length > 0) {
this.selectedAsGood = this.afterSaleGoods[0].id;
this.afterSalePopup = true;
}
})
},
//
selectAsGood(item) {
this.selectedAsGood = item.id;
},
//
closeAfterSalePopup() {
this.afterSalePopup = false;
},
//
closeAfterSalePopup() {
this.afterSalePopup = false;
},
closeAfterSalePopup2() {
if (this.selectedReason !== null && this.selectedReason !== undefined) {
this.changeRefundReason = this.exchangeReasons[this.selectedReason];
}
this.afterSalePopup2 = false;
},
closeAfterSalePopup3() {
this.afterSalePopup3 = false;
},
//
selectAfterSaleType(index) {
this.selectedAfterSaleType = index;
},
selectAfterSaleType2(index) {
this.selectedAfterSaleType2 = index;
},
//
confirmAfterSaleCancel() {
const afterSaleTypes = ['退货/退款', '换货'];
const selectedType = afterSaleTypes[this.selectedAfterSaleType];
console.log('售后商品 - 选中的售后类型:', selectedType);
console.log('选中的售后商品:', this.selectedAsGood);
this.afterSalePopup = false;
this.afterSalePopup2 = true;
},
// 退
selectAsReason(index) {
this.selectedAsReason = index;
},
//
selectReason(index) {
this.selectedReason = index;
},
//
confirmChange() {
let selectedReasonText = '';
selectedReasonText = this.exchangeReasons[this.selectedReason];
console.log('换货原因:', selectedReasonText);
// changeRefundReason
this.changeRefundReason = selectedReasonText;
this.afterSalePopup2 = false;
this.afterSalePopup3 = true;
},
//
closeAfterSalePopup2() {
if (this.selectedReason !== null && this.selectedReason !== undefined) {
this.changeRefundReason = this.exchangeReasons[this.selectedReason];
}
this.afterSalePopup2 = false;
},
// 退
confirmAfterSaleCancel2() {
const afterSaleTypes = ['退货退款', '退货'];
const selectedType = afterSaleTypes[this.selectedAfterSaleType2];
console.log('选中的售后类型:', selectedType);
let selectedReasonText = '';
if (selectedType == '退货退款') {
selectedReasonText = this.applyRefundReasons[this.selectedAsReason];
} else {
selectedReasonText = this.cancelReasons[this.selectedAsReason];
}
console.log('退款原因:', selectedReasonText);
// 退
this.selectedServiceType = selectedType;
this.selectedRefundReason = selectedReasonText;
// 退
this.refundAmount = 4704.00;
this.maxRefundAmount = 53.80;
this.postage = 0.00;
this.selectAsReason(0);
this.afterSalePopup2 = false;
this.afterSalePopup3 = true;
},
// 退
openAfterSalePopup2(type) {
this.afterSalePopup3 = false;
this.afterSalePopup2 = true;
},
//
changeGood() {
this.afterSalePopup3 = false;
this.showSize = true;
},
closeSize() {
this.showSize = false;
},
//
changeGG(item, index) {
console.log("🚀 ~ changeGG ~ item:", item);
this.currentGG = item;
this.currentGGIndex = index;
if (this.currentGG.cart_count) {
this.currentNum = this.currentGG.cart_count.count;
} else {
this.currentGG.cart_count = { count: 0 };
}
this.changeImg = item.commodity_pic[0]
this.changeName = item.goods_alias
this.changePrice = item.sales_price
this.afterSalePopup3 = true;
this.showSize = false;
},
//
afterReadImg(e) {
e.file.forEach(item => {
upload(item.url, res => {
this.imgList.push({ url: picUrl + res.data.path });
console.log('imgList:', this.imgList);
});
});
},
//
deletePic(e) {
this.imgList.splice(e.index, 1);
},
// 退
modifyRefundAmount() {
console.log('修改退款金额');
},
//
viewAddressDetails() {
console.log('查看地址详情');
},
// 退
submitRefundApplication() {
if (!this.selectedServiceType || !this.selectedRefundReason) {
uni.showToast({
title: '请选择服务类型和退款原因',
icon: 'none'
});
return;
}
//
const refundInfo = {
serviceType: this.selectedServiceType,
refundReason: this.selectedRefundReason,
refundAmount: this.refundAmount,
maxRefundAmount: this.maxRefundAmount,
postage: this.postage,
refundDescription: this.refundDescription,
refundMethod: this.refundMethod,
merchantAddress: this.merchantAddress,
merchantContact: this.merchantContact,
imgList: this.imgList
};
console.log('提交退款申请:', refundInfo);
this.afterSalePopup3 = false;
// 退
this.$emit('refundSubmitted', refundInfo);
}
}
};
</script>
<style>
@import url('./index.css');
</style>

View File

@ -0,0 +1,64 @@
.cancel-reason-container {
padding: 20rpx;
background-color: #fff;
border-radius: 10rpx;
width: 100%;
margin: 0 auto;
}
.title {
font-size: 32rpx;
font-weight: bold;
text-align: center;
margin: 20rpx 0 40rpx;
}
.reason-list {
margin-bottom: 40rpx;
}
.reason-item {
display: flex;
align-items: center;
padding: 20rpx 0;
border-bottom: 1rpx solid #eee;
}
.radio {
width: 32rpx;
height: 32rpx;
border: 2rpx solid #999;
border-radius: 50%;
margin-right: 20rpx;
position: relative;
}
.radio.active {
border-color: #ff4400;
}
.radio.active::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 16rpx;
height: 16rpx;
background-color: #ff4400;
border-radius: 50%;
}
.confirm-btn {
background-color: #ff4400;
color: #fff;
border: none;
border-radius: 40rpx;
padding: 15rpx 0;
width: 80%;
font-size: 32rpx;
margin-top: 20rpx;
align-items: center;
justify-content: center;
display: flex;
}

View File

@ -0,0 +1,81 @@
<template>
<view class="container">
<u-popup ref="popup" :show="showPopup" :round="10" @close="closePopup" :mask-close-able="false">
<view class="cancel-reason-container">
<view class="title">选择取消原因</view>
<view class="reason-list">
<view v-for="(reason, index) in cancelReasons" :key="index" class="reason-item" @click="selectReason(index)">
<view :class="['radio', selectedReason === index ? 'active' : '']"></view>
<text>{{ reason }}</text>
</view>
</view>
<button class="confirm-btn" @click="confirmCancel">确认取消</button>
</view>
</u-popup>
</view>
</template>
<script>
import { NavgateTo } from '../../../../../utils';
export default {
name: 'cancelOrderPopup',
props: {
showPopup: {
type: Boolean,
default: false
}
},
data() {
return {
cancelReasons: [
'商品价格不稳定',
'买错规格/品种',
'未按时发货',
'业务反馈没货',
'不想要了,无理由退货'
],
selectedReason: 0
};
},
methods: {
closePopup() {
this.$emit('update:showPopup', false);
},
selectReason(index) {
this.selectedReason = index;
},
confirmCancel() {
const selectedText = this.cancelReasons[this.selectedReason];
console.log("🚀 ~ confirmCancel ~ 取消原因:", selectedText);
uni.showModal({
title: "取消订单",
content: "千辛万苦挑选的商品,确定要取消吗?",
success: (res) => {
if (res.confirm) {
this.$emit('update:showPopup', false);
this.$emit('orderCancelled', { reason: selectedText });
uni.showToast({
title: '订单取消成功',
icon: 'success'
});
}
},
});
}
},
watch: {
showPopup(newVal) {
if (newVal) {
this.selectedReason = 0;
}
}
}
};
</script>
<style scoped>
@import './cancelOrder.css';
</style>

View File

@ -0,0 +1,67 @@
.cancel-reason-container {
padding: 20rpx;
background-color: #fff;
border-radius: 10rpx;
width: 100%;
margin: 0 auto;
max-height: 80vh;
overflow-y: auto;
}
.title {
font-size: 32rpx;
font-weight: bold;
text-align: center;
margin: 20rpx 0 40rpx;
}
.reason-list {
margin-bottom: 40rpx;
}
.reason-item {
display: flex;
align-items: center;
padding: 20rpx 0;
border-bottom: 1rpx solid #eee;
}
.radio {
width: 32rpx;
height: 32rpx;
border: 2rpx solid #999;
border-radius: 50%;
margin-right: 20rpx;
position: relative;
}
.radio.active {
border-color: #ff4400;
}
.radio.active::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 16rpx;
height: 16rpx;
background-color: #ff4400;
border-radius: 50%;
}
.confirm-btn {
background-color: #ff4400;
color: #fff;
border: none;
border-radius: 40rpx;
padding: 15rpx 0;
width: 80%;
font-size: 32rpx;
margin-top: 20rpx;
align-items: center;
justify-content: center;
display: flex;
margin-left: 10%;
}

View File

@ -0,0 +1,80 @@
<template>
<view>
<u-popup ref="popup" :show="showPopup" :round="10" @close="closePopup" :mask-close-able="false">
<view class="cancel-reason-container">
<view class="title">选择退款原因</view>
<view class="reason-list">
<view v-for="(reason, index) in applyRefundReasons" :key="index" class="reason-item"
@click="selectReason(index)">
<view :class="['radio', selectedReason === index ? 'active' : '']"></view>
<text>{{ reason }}</text>
</view>
</view>
<button class="confirm-btn" @click="confirmRefund">确认取消</button>
</view>
</u-popup>
</view>
</template>
<script>
import { NavgateTo } from '../../../../../utils';
export default {
name: 'refundPopup',
props: {
showPopup: {
type: Boolean,
default: false
},
},
data() {
return {
applyRefundReasons: [
'不想要了,无理由退货',
'商品信息拍错',
'没用/少用优惠',
'缺货',
'其他'
],
selectedReason: 0
};
},
methods: {
closePopup() {
this.$emit('update:showPopup', false);
},
selectReason(index) {
this.selectedReason = index;
},
confirmRefund() {
const selectedText = this.applyRefundReasons[this.selectedReason];
console.log("🚀 ~ confirmRefund ~ 退款原因:", selectedText);
this.$emit('update:showPopup', false);
this.$emit('refundConfirmed', { reason: selectedText });
uni.showModal({
title: '退款申请成功',
content: '将在审核后完成退款',
showCancel: false,
success: (res) => {
if (res.confirm) {
console.log('用户点击确定');
}
}
});
}
},
watch: {
showPopup(newVal) {
if (newVal) {
this.selectedReason = 0;
}
}
}
};
</script>
<style scoped>
@import './refund.css';
</style>

View File

@ -1,30 +1,30 @@
<template>
<view class="container">
<!-- 顶部状态栏 -->
<view class="status-bar" v-if="status === '待付款'">
<view class="status-bar" v-if="status === '1'">
<view class="status">待付款</view>
<view class="countdown">剩余支付时间: {{ countdown }}</view>
<view class="tips">10分钟内未支付订单自动取消</view>
</view>
<view class="status-bar" v-if="status === '待发货'">
<view class="status-bar" v-if="status === '3'">
<view class="status">待发货</view>
<view class="countdown">预计到货时间: 2025-09-09 9:59:59</view>
<view class="countdown">预计到货时间: {{ orderInfo.estimated_delivery_time }}</view>
<view class="tips">商家正在加急打包中了请耐心等候</view>
</view>
<view class="status-bar" v-if="status === '配送中'">
<view class="status-bar" v-if="status === '4'">
<view class="status">待配送</view>
<view class="countdown">预计到货时间: 2025-09-09 9:59:59</view>
<view class="countdown">预计到货时间: {{ orderInfo.estimated_delivery_time }}</view>
<view class="tips">
配送司机15901518415
<img class="phone" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/myOrder/phone.png" />
</view>
</view>
<view class="status-bar" v-if="status === '已完成' || status === '退款中'">
<view class="status-bar" v-if="status === '5' || status === '退款中'">
<view class="status">已完成</view>
<view class="countdown">预计到货时间: 2025-09-09 9:59:59</view>
<view class="countdown">预计到货时间: {{ orderInfo.estimated_delivery_time }}</view>
<view class="tips">感谢对我们的信任期待下次光临</view>
</view>
<view class="status-bar" v-if="status === '已取消'">
<view class="status-bar" v-if="status === '6'">
<view class="status">已取消</view>
<view class="countdown">订单已取消</view>
<view class="tips">您的订单已取消再来一单吧</view>
@ -39,27 +39,22 @@
<!-- 订单金额 -->
<view class="amount-section">
<view v-if="status !== '退款中'">
<view class="total-amount">¥{{ orderInfo.totalAmount }}</view>
<view class="original-price"
>商品下单应付
<text> ¥{{ orderInfo.originalPrice }}</text>
<view class="total-amount">¥{{ orderInfo.payment_amount }}</view>
<view class="original-price">商品下单应付
<text> ¥{{ orderInfo.payment_amount }}</text>
</view>
</view>
<view
class="goods-item"
v-for="(item, index) in orderInfo.goodsList"
:key="index"
>
<view class="goods-item" v-for="(item, index) in orderInfo.commodity_order_item_list" :key="index">
<view class="goods-content">
<image :src="item.image" class="goods-img"></image>
<image :src="item.commodity_pic" class="goods-img"></image>
<view class="goods-info">
<view>
<view class="goods-name">{{ item.name }}</view>
<view class="goods-name">{{ item.goods_name }}</view>
<view class="goods-desc">{{ item.desc }}</view>
</view>
<view>
<view class="goods-price">¥{{ item.price }}</view>
<view class="goods-info-right"> x{{ item.quantity }}</view>
<view class="goods-price">¥{{ item.sales_price }}</view>
<view class="goods-info-right"> x{{ item.count }}</view>
</view>
</view>
</view>
@ -67,14 +62,12 @@
</view>
<view class="hr"></view>
<view class="info-item">
<view class="info-label1"
>下单总金额( ¥{{ orderInfo.orderAmount }} )</view
>
<view class="info-label1">下单总金额( ¥{{ orderInfo.orderAmount }} )</view>
<view class="info-action">明细</view>
</view>
<view class="info-item">
<view class="info-label">商品下单总金额</view>
<view class="info-value">¥{{ orderInfo.goodsTotal }}</view>
<view class="info-value">¥{{ orderInfo.total_amount }}</view>
</view>
<view class="info-item">
<view class="info-label">运费总计</view>
@ -88,11 +81,12 @@
<view class="section-title">配送信息</view>
<view class="info-item">
<view class="info-label">配送方式</view>
<view class="info-value">{{ orderInfo.deliveryType }}</view>
<view class="info-value" v-if="orderInfo.order_cate === 1">商家自配</view>
<view class="info-value" v-if="orderInfo.order_cate === 2">客户自提</view>
</view>
<view class="info-item">
<view class="info-label">预计配送时间</view>
<view class="info-value">{{ orderInfo.deliveryTime }}</view>
<view class="info-value">{{ orderInfo.estimated_delivery_time }}</view>
</view>
</view>
@ -101,14 +95,13 @@
<view class="section-title">收货信息</view>
<view class="info-item">
<view class="info-label">收货人</view>
<view class="info-value"
>{{ orderInfo.recipientName }}
<text> {{ orderInfo.recipientPhone }}</text>
<view class="info-value">{{ orderInfo.receiving_name }}
<text> {{ orderInfo.receiving_phone }}</text>
</view>
</view>
<view class="info-item">
<view class="info-label">收货地址</view>
<view class="info-value">{{ orderInfo.recipientAddress }}</view>
<view class="info-value">{{ orderInfo.receiving_address }}</view>
</view>
</view>
@ -117,15 +110,15 @@
<view class="section-title">订单信息</view>
<view class="info-item">
<view class="info-label">订单编号</view>
<view class="info-value">{{ orderInfo.orderNumber }}</view>
<view class="info-value">{{ orderInfo.order_no }}</view>
</view>
<view class="info-item">
<view class="info-label">支付方式</view>
<view class="info-value">{{ orderInfo.paymentMethod }}</view>
<view class="info-value">{{ orderInfo.pay_method }}</view>
</view>
<view class="info-item">
<view class="info-label">下单时间</view>
<view class="info-value">{{ orderInfo.orderTime }}</view>
<view class="info-value">{{ orderInfo.order_time }}</view>
</view>
<view class="info-item">
<view class="info-label">备注</view>
@ -134,28 +127,28 @@
</view>
<!-- 底部操作按钮 -->
<view class="bottom-buttons" v-if="status === '待付款'">
<view class="bottom-buttons" v-if="status === '1'">
<button class="cancel-btn" @click="cancelOrder">取消订单</button>
<button class="yfd-btn" @click="cancelOrder">运费单</button>
<!-- <button class="yfd-btn" @click="cancelOrder">运费单</button> -->
<button class="pay-btn" @click="gotoPayment">立即支付</button>
</view>
<view class="bottom-buttons" v-if="status === '待发货'">
<button class="yfd-btn" @click="cancelOrder">运费单</button>
<view class="bottom-buttons" v-if="status === '3'">
<!-- <button class="yfd-btn" @click="cancelOrder">运费单</button> -->
<button class="cancel-btn" @click="cancelOrder">取消订单</button>
<!-- <button class="pay-btn" @click="gotoPayment">立即支付</button> -->
</view>
<view class="bottom-buttons" v-if="status === '配送中'">
<view class="bottom-buttons" v-if="status === '4'">
<button class="cancel-btn" @click="checkLogistics">查看物流</button>
<button class="yfd-btn" @click="cancelOrder">运费单</button>
<!-- <button class="yfd-btn" @click="cancelOrder">运费单</button> -->
<button class="pay-btn" @click="gotoPayment">立即支付</button>
</view>
<view class="bottom-buttons" v-if="status === '已完成'">
<view class="bottom-buttons" v-if="status === '5'">
<button class="cancel-btn" @click="orderEvaluate">服务评价</button>
<button class="yfd-btn" @click="cancelOrder">运费单</button>
<!-- <button class="yfd-btn" @click="cancelOrder">运费单</button> -->
<button class="pay-btn" @click="gotoPayment">立即支付</button>
</view>
<view class="bottom-buttons" v-if="status === '已取消'">
<button class="yfd-btn" @click="cancelOrder">运费单</button>
<view class="bottom-buttons" v-if="status === '6'">
<!-- <button class="yfd-btn" @click="cancelOrder">运费单</button> -->
<!-- <button class="cancel-btn" @click="cancelOrder">服务评价</button> -->
<button class="pay-btn" @click="gotoPayment">再来一单</button>
</view>
@ -172,57 +165,20 @@ export default {
return {
status: "",
countdown: "9:59:59",
orderInfo: {
totalAmount: "4704.00",
payAmount: "4704.00",
originalPrice: "4704.00",
orderAmount: "290.00",
goodsTotal: "4704.00",
freight: "4704.00",
deliveryType: "商家配送",
deliveryTime: "2021-04-16 20:00-22:00",
recipientName: "杜先生",
recipientPhone: "15901518415",
recipientAddress: "河北省衡水市桃城区上海公馆",
orderNumber: "159144551545654",
paymentMethod: "微信支付",
orderTime: "2021-03-16 20:00-22:00",
remark: "明天9点之前送到",
goodsList: [
{
image: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/myOrder/order_details.png",
name: "泰国金枕榴莲",
desc: "泰国金枕榴莲 软糯 香甜",
price: "125.9",
quantity: 1,
},
{
image: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/myOrder/order_details.png",
name: "泰国金枕榴莲",
desc: "泰国金枕榴莲 软糯 香甜",
price: "125.9",
quantity: 1,
},
{
image: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/myOrder/order_details.png",
name: "泰国金枕榴莲",
desc: "泰国金枕榴莲 软糯 香甜",
price: "125.9",
quantity: 1,
},
],
},
orderInfo: {},
};
},
onLoad(options) {
const item = JSON.parse(options?.item);
console.log("🚀 ~ onLoad ~ item:", item)
//
options?.status === "待付款" ? this.startCountdown() : "";
this.status = options?.status;
item.order_status == "1" ? this.startCountdown() : "";
this.status = JSON.stringify(item.order_status);
this.orderInfo = item;
},
methods: {
startCountdown() {
//
// 使
//
let seconds = 10 * 60; // 10
const timer = setInterval(() => {
seconds--;
@ -234,7 +190,7 @@ export default {
.padStart(2, "0")}`;
if (seconds <= 0) {
clearInterval(timer);
//
//
uni.showToast({ title: "订单已取消", icon: "none" });
setTimeout(() => uni.navigateBack(), 1500);
}

View File

@ -0,0 +1,322 @@
.page {
background-color: #f6f7fb;
min-height: 100vh;
padding-bottom: 120rpx;
}
.progress-container {
display: flex;
justify-content: space-between;
padding: 30rpx 20rpx;
background-color: #ffffff;
}
.progress-item {
display: flex;
flex-direction: column;
align-items: center;
width: 33%;
}
.progress-item.active .progress-text {
color: #ff4d4f;
}
.progress-text {
font-size: 24rpx;
color: #999999;
margin-top: 10rpx;
}
.progress-line {
width: 200rpx;
height: 2rpx;
background-color: #d9d9d9;
align-self: center;
flex-grow: 1;
margin-top: 10rpx;
}
.status-tip {
background-color: #ffffff;
padding: 30rpx 20rpx;
margin-bottom: 20rpx;
text-align: center;
}
.status-title {
font-size: 40rpx;
font-weight: bold;
color: #333333;
display: block;
margin-bottom: 10rpx;
}
.status-desc {
font-size: 24rpx;
color: #999999;
display: block;
margin-bottom: 5rpx;
}
.hr {
height: 20rpx;
background: #f5f7fb;
}
.goods-info {
background-color: #ffffff;
margin-bottom: 20rpx;
padding: 20rpx;
}
.goods-item {
display: flex;
padding: 10rpx 0;
border-bottom: 1rpx solid #eeeeee;
position: relative;
}
.goods-image {
width: 160rpx;
height: 160rpx;
border-radius: 10rpx;
margin-right: 20rpx;
}
.goods-details {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.asGoodTag {
background-color: #ff7d00;
color: white;
font-size: 22rpx;
padding: 5rpx 10rpx;
border-radius: 8rpx 0 8rpx 8rpx;
}
.asGoodTag1 {
margin-right: 15rpx;
}
.tag-img {
position: absolute;
top: 133rpx;
left: 80rpx;
z-index: 1;
}
.goods-name {
font-weight: bold;
font-size: 28rpx;
color: #333333;
margin-bottom: 10rpx;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.goods-desc {
font-size: 26rpx;
color: #ff4d4f;
background-color: #fff2f0;
padding: 4rpx 12rpx;
border-radius: 8rpx;
display: inline-block;
margin: 10rpx 0;
}
.goods-price {
font-size: 26rpx;
color: #ff4d4f;
margin-bottom: 5rpx;
}
.goods-count {
font-size: 24rpx;
color: #666666;
float: right;
}
.refund-amount {
font-size: 28rpx;
align-self: flex-start;
margin-top: 20rpx;
font-weight: 500;
position: relative;
left: 140rpx;
}
.refund-info {
background-color: #ffffff;
margin-bottom: 20rpx;
}
.info-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 25rpx 20rpx;
border-bottom: 1rpx solid #eeeeee;
}
.info-label {
font-size: 28rpx;
color: #666666;
width: 200rpx;
}
.info-value {
font-size: 28rpx;
color: #333333;
flex: 1;
text-align: right;
padding-right: 20rpx;
}
.amount {
color: #ff4d4f;
font-weight: bold;
}
.info-arrow {
width: 16rpx;
height: 16rpx;
border-top: 2rpx solid #999999;
border-right: 2rpx solid #999999;
transform: rotate(45deg);
}
.copy-icon {
width: 30rpx;
height: 30rpx;
background-image: url('https://wechat-img-file.oss-cn-beijing.aliyuncs.com/myOrder/copy.png');
background-size: cover;
}
.action-buttons {
display: flex;
justify-content: space-between;
padding: 20rpx;
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 999;
}
.cancel-btn {
width: 220rpx;
height: 80rpx;
background-color: #d9d9d9;
color: #333;
border-radius: 40rpx;
font-size: 28rpx;
line-height: 80rpx;
text-align: center;
}
.modify-btn {
width: 220rpx;
height: 80rpx;
background-color: #ffebcb;
color: #983012;
border-radius: 40rpx;
font-size: 28rpx;
line-height: 80rpx;
text-align: center;
}
.urge-btn {
width: 220rpx;
height: 80rpx;
background-color: #ff4d4f;
color: #ffffff;
border: none;
border-radius: 40rpx;
font-size: 28rpx;
line-height: 80rpx;
text-align: center;
}
/* 弹窗样式 */
.popup-content {
width: 600rpx;
background-color: #ffffff;
border-radius: 20rpx;
padding: 40rpx;
display: flex;
flex-direction: column;
align-items: center;
}
.success-icon {
margin: 20rpx 0;
}
.check-circle {
width: 120rpx;
height: 120rpx;
background-color: #00c853;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
}
.check-mark {
color: #ffffff;
font-size: 70rpx;
font-weight: bold;
}
.popup-title {
font-size: 36rpx;
font-weight: bold;
color: #333333;
margin: 20rpx 0;
}
.popup-desc {
font-size: 28rpx;
color: #666666;
text-align: center;
line-height: 40rpx;
margin-bottom: 30rpx;
padding: 0 20rpx;
}
.popup-buttons {
display: flex;
justify-content: space-between;
width: 100%;
margin-top: 20rpx;
}
.continue-btn {
width: 240rpx;
height: 80rpx;
background-color: #f6f7fb;
color: #333333;
border-radius: 40rpx;
font-size: 28rpx;
line-height: 80rpx;
text-align: center;
}
.know-btn {
width: 240rpx;
height: 80rpx;
background-color: #ff4d4f;
color: #ffffff;
border: none;
border-radius: 40rpx;
font-size: 28rpx;
line-height: 80rpx;
text-align: center;
}

View File

@ -0,0 +1,216 @@
<template>
<view class="container">
<!-- 进度条 -->
<view class="progress-container" v-if="false">
<view class="progress-item active">
<text class="progress-text">商家处理</text>
</view>
<view class="progress-line"></view>
<view class="progress-item">
<text class="progress-text">寄回商品</text>
</view>
<view class="progress-line"></view>
<view class="progress-item">
<text class="progress-text">退款结束</text>
</view>
</view>
<view class="progress-container">
<view class="progress-item active">
<text class="progress-text">商家处理</text>
</view>
<view class="progress-line"></view>
<view class="progress-item">
<text class="progress-text">退款结束</text>
</view>
</view>
<!-- 状态提示 -->
<view class="status-tip" v-if="false">
<text class="status-title">请等待商家处理</text>
<text class="status-desc"><text style="font-weight: bold;">2</text>后商家未处理将自动同意</text>
<text class="status-desc">您已成功发起退款申请请耐心等待商家处理</text>
</view>
<view class="status-tip">
<text class="status-title">商家拒绝申请,请您处理</text>
<text class="status-desc"><text style="color: #f63b08;">2</text>后未处理将自动关闭</text>
</view>
<view class="hr"></view>
<!-- 商品信息 -->
<view class="goods-info">
<view class="goods-item">
<view class="asGoodTag tag-img"
v-if="currentAfterSale.commodity_order_item[0].is_support_same_day === 1">当日达</view>
<image class="goods-image" :src="currentAfterSale.commodity_order_item[0].commodity_pic"></image>
<view class="goods-details">
<text class="goods-name">
<text class="asGoodTag asGoodTag1"
v-if="currentAfterSale.commodity_order_item[0].is_support_same_day === 1">当日达</text>
{{ currentAfterSale.commodity_order_item[0].goods_name }}
<text class="refund-amount">退款¥{{ currentAfterSale.refund_amount.toFixed(2) }}</text>
</text>
<text class="goods-desc">{{ ite.after_sales_reason }}</text>
<text class="goods-price">
{{ '¥' + currentAfterSale.commodity_order_item[0].sales_price.toFixed(2) + '/个' }}
<text class="goods-count">X{{ currentAfterSale.commodity_order_item[0].count }}</text>
</text>
</view>
</view>
</view>
<!-- 退款信息 -->
<view class="refund-info">
<view class="info-item">
<text class="info-label">服务类型<text style="color: #fc3811;">*</text></text>
<text class="info-value">{{ getServiceTypeText(currentAfterSale.after_sales_type) }}</text>
<text class="info-arrow"></text>
</view>
<view class="info-item">
<text class="info-label">退款原因<text style="color: #fc3811;">*</text></text>
<text class="info-value">{{ currentAfterSale.after_sales_reason }}</text>
<text class="info-arrow"></text>
</view>
<view class="info-item">
<text class="info-label">退款金额<text style="color: #fc3811;">*</text></text>
<text class="info-value amount">{{ '¥' + currentAfterSale.refund_amount.toFixed(2) }}</text>
</view>
<view class="info-item">
<text class="info-label">申请时间<text style="color: #fc3811;">*</text></text>
<text class="info-value">{{ formatDate(currentAfterSale.create_time) }}</text>
</view>
<view class="info-item">
<text class="info-label">退款编号<text style="color: #fc3811;">*</text></text>
<text class="info-value">{{ currentAfterSale.after_sales_no }}</text>
<text class="copy-icon" @click="copyRefundNo"></text>
</view>
</view>
<!-- 操作按钮 -->
<view class="action-buttons">
<button class="cancel-btn" @click="cancelRefund">撤销申请</button>
<button class="modify-btn" @click="modifyRefund">修改申请</button>
<button class="urge-btn" @click="urgeProcess">催处理</button>
</view>
<u-popup ref="popup" :show="showPopup" @close="closePopup" :mask-close-able="false"
:close-on-click-overlay="false">
<view class="popup-content">
<view class="success-icon">
<view class="check-circle">
<text class="check-mark"></text>
</view>
</view>
<view class="popup-title">已为您催处理</view>
<view class="popup-desc">平台客服已帮您催促卖家07月26日20:49前卖家未处理系统将自动退款</view>
<view class="popup-buttons">
<button class="continue-btn" @click="closePopup">继续联系卖家</button>
<button class="know-btn" @click="closePopup">我知道了</button>
</view>
</view>
</u-popup>
</view>
</template>
<script>
import {
isPhone,
picUrl,
request,
upload,
NavgateTo
} from '../../../utils';
export default {
data() {
return {
currentAfterSale: {},
pickerDefaultDate: new Date(),
showPopup: false
};
},
created() {
//
this.pickerDefaultDate = new Date(this.currentAfterSale.create_time);
},
onLoad(options) {
const item = JSON.parse(options?.item);
console.log("🚀 ~ onLoad ~ item:", item)
this.currentAfterSale = item;
},
methods: {
getServiceTypeText(type) {
return type === 1 ? '退货退款' : '仅退款';
},
//
formatDate(dateString) {
if (!dateString) return '';
const date = new Date(dateString);
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}:${String(date.getSeconds()).padStart(2, '0')}`;
},
// 退
copyRefundNo() {
// 使uni-appAPI
uni.setClipboardData({
data: this.currentAfterSale.after_sales_no,
success: () => {
uni.showToast({
title: '复制成功',
icon: 'success'
});
},
fail: () => {
uni.showToast({
title: '复制失败',
icon: 'none'
});
}
});
},
//
cancelRefund() {
uni.showModal({
title: "确定要撤销本次售后申请吗?",
showCancel: true,
cancelText: "暂不撤销",
confirmText: "确认撤销",
confirmColor: "#ff4d4f",
success: (res) => {
if (res.confirm) {
//
uni.showToast({
title: '订单撤销成功',
icon: 'success'
});
}
},
});
},
//
modifyRefund() {
NavgateTo(`../apply/index?item=${JSON.stringify(this.currentAfterSale)}`);
},
//
urgeProcess() {
this.showPopup = true;
},
//
closePopup() {
this.showPopup = false;
}
}
};
</script>
<style scoped>
@import url('./index.css')
</style>

View File

@ -0,0 +1,392 @@
.page {
background-color: #f6f7fb;
min-height: 100vh;
padding-bottom: 120rpx;
}
.progress-container {
display: flex;
justify-content: space-between;
padding: 30rpx 20rpx;
background-color: #ffffff;
}
.progress-item {
display: flex;
flex-direction: column;
align-items: center;
width: 33%;
}
.progress-item.active .progress-text {
color: #ff4d4f;
}
.progress-text {
font-size: 24rpx;
color: #999999;
margin-top: 10rpx;
}
.progress-line {
width: 200rpx;
height: 2rpx;
background-color: #d9d9d9;
align-self: center;
flex-grow: 1;
margin-top: 10rpx;
}
.status-tip {
background-color: #ffffff;
padding: 30rpx 20rpx;
margin-bottom: 20rpx;
text-align: center;
}
.status-title {
font-size: 40rpx;
font-weight: bold;
color: #333333;
display: block;
margin-bottom: 10rpx;
}
.status-desc {
font-size: 24rpx;
color: #999999;
display: block;
margin-bottom: 5rpx;
}
.status-desc2 {
font-size: 24rpx;
background-color: #ffeeeb;
color: #fe441a;
width: 80%;
margin: 20rpx auto 0;
padding: 20rpx;
border-radius: 8rpx;
}
.addOrderIdBtn{
width: 70%;
margin: 10rpx auto 0;
border-radius: 50rpx;
background-color: #ff3f14;
color: #ffffff;
}
.hr {
height: 20rpx;
background: #f5f7fb;
}
.goods-info {
background-color: #ffffff;
margin-bottom: 20rpx;
padding: 20rpx;
}
.goods-item {
display: flex;
padding: 10rpx 0;
border-bottom: 1rpx solid #eeeeee;
position: relative;
}
.goods-image {
width: 160rpx;
height: 160rpx;
border-radius: 10rpx;
margin-right: 20rpx;
}
.goods-details {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.asGoodTag {
background-color: #ff7d00;
color: white;
font-size: 22rpx;
padding: 5rpx 10rpx;
border-radius: 8rpx 0 8rpx 8rpx;
}
.asGoodTag1 {
margin-right: 15rpx;
}
.tag-img {
position: absolute;
top: 133rpx;
left: 80rpx;
z-index: 1;
}
.goods-name {
font-weight: bold;
font-size: 28rpx;
color: #333333;
margin-bottom: 10rpx;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.goods-desc {
font-size: 26rpx;
color: #ff4d4f;
background-color: #fff2f0;
padding: 4rpx 12rpx;
border-radius: 8rpx;
display: inline-block;
margin: 10rpx 0;
}
.goods-price {
font-size: 26rpx;
color: #ff4d4f;
margin-bottom: 5rpx;
}
.goods-count {
font-size: 24rpx;
color: #666666;
float: right;
}
.refund-amount {
font-size: 28rpx;
align-self: flex-start;
margin-top: 20rpx;
font-weight: 500;
position: relative;
left: 140rpx;
}
.refund-info {
background-color: #ffffff;
margin-bottom: 20rpx;
}
.info-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 25rpx 20rpx;
border-bottom: 1rpx solid #eeeeee;
}
.info-label {
font-size: 28rpx;
color: #666666;
width: 200rpx;
}
.info-value {
font-size: 28rpx;
color: #333333;
flex: 1;
text-align: right;
padding-right: 20rpx;
}
.amount {
color: #ff4d4f;
font-weight: bold;
}
.info-arrow {
width: 16rpx;
height: 16rpx;
border-top: 2rpx solid #999999;
border-right: 2rpx solid #999999;
transform: rotate(45deg);
}
.copy-icon {
width: 30rpx;
height: 30rpx;
background-image: url('https://wechat-img-file.oss-cn-beijing.aliyuncs.com/myOrder/copy.png');
background-size: cover;
}
.action-buttons {
display: flex;
padding: 20rpx;
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 999;
margin-bottom: 30rpx;
}
.cancel-btn {
width: 220rpx;
height: 80rpx;
background-color: #d9d9d9;
color: #333;
border-radius: 40rpx;
font-size: 28rpx;
line-height: 80rpx;
text-align: center;
}
.modify-btn {
width: 220rpx;
height: 80rpx;
background-color: #ffebcb;
color: #983012;
border-radius: 40rpx;
font-size: 28rpx;
line-height: 80rpx;
text-align: center;
}
.urge-btn {
width: 220rpx;
height: 80rpx;
background-color: #ffe8e5;
color: #ed4d1c;
border: none;
border-radius: 40rpx;
font-size: 28rpx;
line-height: 80rpx;
text-align: center;
}
.bottomImg{
width: 70rpx;
height: 80rpx;
}
/* 退款去向弹窗样式 */
.money-path-popup-content {
background-color: #ffffff;
border-top-left-radius: 30rpx;
border-top-right-radius: 30rpx;
padding: 20rpx;
height: 45vh;
overflow-y: auto;
}
.popup-header {
display: flex;
align-items: center;
padding: 20rpx 0;
margin-bottom: 30rpx;
}
.header-title {
font-size: 32rpx;
font-weight: bold;
color: #333333;
margin: 0 auto;
}
.close-btn {
font-size: 28rpx;
color: #999999;
}
.refund-method {
margin-bottom: 40rpx;
}
.method-item {
display: flex;
align-items: center;
padding: 20rpx;
}
.wechat-icon {
width: 40rpx;
height: 35rpx;
background-size: cover;
margin-right: 15rpx;
}
.method-text {
font-size: 30rpx;
color: #333333;
flex: 1;
}
.method-text2 {
font-size: 28rpx;
color: #9d9d9d;
flex: 1;
}
.method-amount {
font-size: 30rpx;
font-weight: bold;
}
.refund-status {
padding: 0 70rpx;
}
.status-item {
display: flex;
padding: 20rpx 0;
position: relative;
padding-left: 40rpx;
margin: 20rpx 0;
}
.status-item.active .status-dot {
border: 3rpx solid #e35e38;
}
.status-item.active .status-line {
/* background-color: #e35e38; */
}
.status-dot {
width: 15rpx;
height: 15rpx;
border-radius: 50%;
border: 2rpx solid #d9d9d9;
background-color: #ffffff;
position: absolute;
left: 0;
top: 20rpx;
z-index: 1;
}
.status-line {
border-left: 4rpx dotted #ea704b86;
height: 100%;
position: absolute;
left: 7rpx;
top: 40rpx;
}
.status-item:last-child .status-line {
display: none;
}
.status-info {
flex: 1;
}
.status-text {
font-size: 28rpx;
color: #333333;
display: block;
margin-bottom: 10rpx;
}
.status-desc {
font-size: 24rpx;
color: #999999;
display: block;
}

View File

@ -0,0 +1,270 @@
<template>
<view class="container">
<!-- 进度条 -->
<view class="progress-container" v-if="false">
<view class="progress-item">
<text class="progress-text">商家处理</text>
</view>
<view class="progress-line"></view>
<view class="progress-item">
<text class="progress-text">寄回商品</text>
</view>
<view class="progress-line"></view>
<view class="progress-item active">
<text class="progress-text">退款结束</text>
</view>
</view>
<view class="progress-container">
<view class="progress-item">
<text class="progress-text">商家处理</text>
</view>
<view class="progress-line"></view>
<view class="progress-item active">
<text class="progress-text">退款结束</text>
</view>
</view>
<!-- 状态提示 -->
<view class="status-tip">
<text class="status-title">退款成功</text>
<text class="status-desc">若您的问题未解决可在有效期内再次申请售后</text>
</view>
<view class="hr"></view>
<!-- 商品信息 -->
<view class="goods-info">
<view class="goods-item">
<view class="asGoodTag tag-img"
v-if="currentAfterSale.commodity_order_item[0].is_support_same_day === 1">当日达</view>
<image class="goods-image" :src="currentAfterSale.commodity_order_item[0].commodity_pic"></image>
<view class="goods-details">
<text class="goods-name">
<text class="asGoodTag asGoodTag1"
v-if="currentAfterSale.commodity_order_item[0].is_support_same_day === 1">当日达</text>
{{ currentAfterSale.commodity_order_item[0].goods_name }}
<text class="refund-amount">退款¥{{ currentAfterSale.refund_amount.toFixed(2) }}</text>
</text>
<text class="goods-desc">{{ ite.after_sales_reason }}</text>
<text class="goods-price">
{{ '¥' + currentAfterSale.commodity_order_item[0].sales_price.toFixed(2) + '/个' }}
<text class="goods-count">X{{ currentAfterSale.commodity_order_item[0].count }}</text>
</text>
</view>
</view>
</view>
<!-- 退款信息 -->
<view class="refund-info">
<view class="info-item">
<text class="info-label">服务类型</text>
<text class="info-value">{{ getServiceTypeText(currentAfterSale.after_sales_type) }}</text>
<text class="info-arrow"></text>
</view>
<view class="info-item">
<text class="info-label">退款原因</text>
<text class="info-value">{{ currentAfterSale.after_sales_reason }}</text>
<text class="info-arrow"></text>
</view>
<view class="info-item">
<text class="info-label">退款金额</text>
<text class="info-value amount">{{ '¥' + currentAfterSale.refund_amount.toFixed(2) }}</text>
</view>
<view class="info-item">
<text class="info-label">申请时间</text>
<text class="info-value">{{ formatDate(currentAfterSale.create_time) }}</text>
</view>
<view class="info-item">
<text class="info-label">退款编号</text>
<text class="info-value">{{ currentAfterSale.after_sales_no }}</text>
<text class="copy-icon" @click="copyRefundNo"></text>
</view>
<view class="info-item" v-if="false">
<text class="info-label">退款完结</text>
<text class="info-value">{{ formatDate(currentAfterSale.create_time) }}</text>
</view>
</view>
<!-- 操作按钮 -->
<view class="action-buttons" v-if="false">
<button class="modify-btn" @click="modifyRefund">寄件详情</button>
<button class="cancel-btn" @click="moneyGo">钱款去向</button>
</view>
<view class="action-buttons">
<button class="cancel-btn" @click="cancelRefund">撤销申请</button>
<button class="urge-btn" @click="modifyRefund">修改申请</button>
</view>
<view>
<u-popup ref="popup" :show="moneyGoPopup" :round="10" @close="closeMoneyGoPopup" :mask-close-able="false"
mode="bottom">
<view class="money-path-popup-content">
<!-- 弹窗头部 -->
<view class="popup-header">
<text class="header-title">退款总额 ¥{{ currentAfterSale.refund_amount ?
currentAfterSale.refund_amount.toFixed(2) : '34.18' }}</text>
<text class="close-btn" @click="closeMoneyGoPopup">取消</text>
</view>
<!-- 退款方式 -->
<view class="refund-method">
<view class="method-item">
<view class="wechat-icon">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_wechat.png"
class="icon-image"></image>
</view>
<text class="method-text">退回微信</text>
<text class="method-amount">{{ currentAfterSale.refund_amount ? '¥' +
currentAfterSale.refund_amount.toFixed(2) : '¥34.18' }}</text>
</view>
</view>
<!-- 退款状态 -->
<view class="refund-status">
<view class="method-text2">微信</view>
<view class="status-item active">
<view class="status-dot"></view>
<view class="status-line"></view>
<view class="status-info">
<text class="status-text">到账成功</text>
<text class="status-desc">钱已退回至微信账户</text>
</view>
</view>
<view class="status-item active">
<view class="status-dot"></view>
<view class="status-info">
<text class="status-text">卖家退款</text>
<text class="status-desc">卖家已退款</text>
</view>
</view>
</view>
</view>
</u-popup>
</view>
</view>
</template>
<script>
import {
isPhone,
picUrl,
request,
upload,
NavgateTo
} from '../../../utils';
export default {
data() {
return {
currentAfterSale: {},
pickerDefaultDate: new Date(),
moneyGoPopup: false
};
},
created() {
//
this.pickerDefaultDate = new Date(this.currentAfterSale.create_time);
},
onLoad(options) {
const item = JSON.parse(options?.item);
console.log("🚀 ~ onLoad ~ item:", item)
this.currentAfterSale = item;
},
methods: {
getServiceTypeText(type) {
return type === 1 ? '退货退款' : '仅退款';
},
//
formatDate(dateString) {
if (!dateString) return '';
const date = new Date(dateString);
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}:${String(date.getSeconds()).padStart(2, '0')}`;
},
//
copyAdress() {
uni.setClipboardData({
data: this.currentAfterSale.after_sales_no,
success: () => {
uni.showToast({
title: '复制成功',
icon: 'success'
});
},
fail: () => {
uni.showToast({
title: '复制失败',
icon: 'none'
});
}
});
},
addOrderId() {
NavgateTo(`../returnLogistics/index?item=${JSON.stringify(this.currentAfterSale)}`);
},
// 退
copyRefundNo() {
uni.setClipboardData({
data: this.currentAfterSale.after_sales_no,
success: () => {
uni.showToast({
title: '复制成功',
icon: 'success'
});
},
fail: () => {
uni.showToast({
title: '复制失败',
icon: 'none'
});
}
});
},
//
cancelRefund() {
uni.showModal({
title: "确定要撤销本次售后申请吗?",
showCancel: true,
cancelText: "暂不撤销",
confirmText: "确认撤销",
confirmColor: "#ff4d4f",
success: (res) => {
if (res.confirm) {
//
uni.showToast({
title: '订单撤销成功',
icon: 'success'
});
}
},
});
},
//
modifyRefund() {
NavgateTo(`../apply/index?item=${JSON.stringify(this.currentAfterSale)}`);
},
//
moneyGo() {
this.moneyGoPopup = true;
},
//
closeMoneyGoPopup() {
this.moneyGoPopup = false;
},
}
};
</script>
<style scoped>
@import url('./index.css')
</style>

View File

@ -0,0 +1,254 @@
page {
background-color: #f0f2f5;
}
.apply-container {
/* padding: 10rpx; */
}
/* 弹窗样式 */
.refund-info-container {
background-color: #ffffff;
border-radius: 10rpx;
padding: 30rpx;
}
.refund-title {
font-size: 32rpx;
font-weight: bold;
text-align: center;
margin-bottom: 30rpx;
}
.refund-item {
display: flex;
justify-content: space-between;
padding: 20rpx 0;
border-bottom: 1rpx solid #f0f0f0;
}
.refund-label {
font-size: 28rpx;
color: #333333;
}
.required {
color: #ff4500;
margin-left: 5rpx;
}
.refund-value {
font-size: 28rpx;
color: #666666;
text-align: right;
position: relative;
max-width: 60%;
}
.arrow-right {
display: inline-block;
width: 16rpx;
height: 16rpx;
border-top: 2rpx solid #999999;
border-right: 2rpx solid #999999;
transform: rotate(45deg);
margin-left: 10rpx;
vertical-align: middle;
}
.price {
color: #ff4500;
font-weight: bold;
}
.modify-btn {
color: #007aff;
margin-left: 10rpx;
font-size: 26rpx;
}
.refund-hint {
font-size: 24rpx;
color: #999999;
margin-top: 10rpx;
text-align: right;
}
.hr {
height: 20rpx;
background-color: #f5f5f5;
margin: 20rpx -30rpx;
}
.refund-item2 {
padding: 20rpx 0;
}
.refund-description {
width: 100%;
height: 300rpx;
border: 1rpx solid #e0e0e0;
border-radius: 8rpx;
padding: 15rpx;
font-size: 26rpx;
color: #333333;
box-sizing: border-box;
margin-top: 10rpx;
}
.imgCon {
font-size: 18rpx;
color: #222222;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 120rpx;
height: 120rpx;
background: #F6F7FB;
border: 1rpx solid #D1D1D1;
border-radius: 10rpx 10rpx 10rpx 10rpx;
margin: 20rpx 0;
}
.imgCon image {
width: 34rpx;
height: 34rpx;
margin-bottom: 8rpx;
}
.u-upload__wrap__preview {
width: 120rpx;
height: 120rpx;
border-radius: 10rpx 0rpx 10rpx 10rpx !important;
margin-top: 20rpx !important;
}
.u-upload__wrap__preview__image {
width: 100% !important;
height: 100% !important;
object-fit: cover;
}
.contact-info {
font-size: 24rpx;
color: #666666;
text-align: right;
margin-top: 10rpx;
margin-bottom: 10rpx;
}
.submit-btn {
width: 60%;
height: 88rpx;
background-color: #ff451b;
color: #fff;
font-size: 32rpx;
border-radius: 44rpx;
line-height: 88rpx;
text-align: center;
margin-top: 50rpx;
border: none;
}
/* 选择退款原因弹窗样式 */
.cancel-reason-container {
background-color: #ffffff;
border-radius: 10rpx;
padding: 30rpx;
}
.title {
font-size: 32rpx;
font-weight: bold;
text-align: center;
margin-bottom: 30rpx;
}
.asTabs2 {
display: flex;
border-bottom: 1rpx solid #f0f0f0;
margin-bottom: 20rpx;
}
.asTab2 {
flex: 1;
text-align: center;
padding: 15rpx 0;
font-size: 28rpx;
color: #666666;
position: relative;
}
.asTab2.active {
color: #ff451b;
}
.asTab2.active::after {
content: '';
position: absolute;
bottom: -1rpx;
left: 10%;
width: 80%;
height: 4rpx;
background-color: #ff451b;
}
.reason-list {
max-height: 500rpx;
overflow-y: auto;
}
.reason-item {
display: flex;
align-items: center;
padding: 20rpx 0;
border-bottom: 1rpx solid #f0f0f0;
}
.radio {
width: 28rpx;
height: 28rpx;
border: 2rpx solid #999999;
border-radius: 50%;
margin-right: 20rpx;
}
.radio.active {
border-color: #ff451b;
background-color: #ff451b;
position: relative;
}
.radio.active::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 12rpx;
height: 12rpx;
background-color: #ffffff;
border-radius: 50%;
}
.confirm-btn {
width: 100%;
height: 88rpx;
background-color: #ff451b;
color: #ffffff;
border-radius: 44rpx;
font-size: 32rpx;
margin-top: 30rpx;
}
/* 打开弹窗按钮样式 */
.open-popup-btn {
height: 88rpx;
background-color: #ff451b;
color: #ffffff;
border-radius: 44rpx;
font-size: 32rpx;
margin: 40rpx auto;
display: block;
}

View File

@ -0,0 +1,152 @@
<template>
<view class="apply-container">
<!-- 确认退款信息弹窗 -->
<view class="refund-info-container">
<view class="refund-item">
<view class="refund-label">物流单号<text class="required">*</text></view>
<input class="refund-value" v-model="selectedServiceType" placeholder="请填写物流单号" type="text">
</view>
<view class="refund-item">
<view class="refund-label">物流公司<text class="required">*</text></view>
<view class="refund-value" @click="openAfterSalePopup2('refundReason')">
{{ selectedRefundReason || '请选择' }}
<text class="arrow-right"></text>
</view>
</view>
<view class="refund-item" style="border-bottom: none;">
<view class="refund-label">联系电话</view>
<view class="refund-value">
111111111
</view>
</view>
<view class="hr"></view>
<view class="refund-item2">
<view class="refund-label">补充描述和凭证</view>
<textarea class="refund-description" placeholder="有助于小二更好的处理售后问题" v-model="refundDescription"
maxlength="200"></textarea>
<u-upload :fileList="imgList" @afterRead="afterReadImg" @delete="deletePic" name="1" multiple
:maxCount="3">
<view class="imgCon">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_imageImg.png"
mode="widthFix"></image>
上传凭证
</view>
</u-upload>
</view>
</view>
<button class="submit-btn" @click="submitRefundApplication">提交</button>
<!-- 选择退款原因弹窗 -->
<u-popup ref="popup2" :show="afterSalePopup2" :round="10" @close="closeAfterSalePopup2"
:mask-close-able="false">
<view class="cancel-reason-container">
<view class="title">选择物流公司</view>
<view class="reason-list">
<view v-for="(company, index) in logisticsCompanies" :key="index" class="reason-item"
@click="selectLogisticsCompany(index)">
<view :class="['radio', selectedRefundReason === company ? 'active' : '']"></view>
<text>{{ company }}</text>
</view>
</view>
</view>
</u-popup>
</view>
</template>
<script>
import {
isPhone,
picUrl,
request,
upload,
NavgateTo
} from '../../../utils';
export default {
data() {
return {
afterSalePopup2: false,
selectedServiceType: '',
selectedRefundReason: '',
refundDescription: '',
imgList: [],
logisticsCompanies: [
'顺丰速运',
'京东物流',
'中通快递',
'圆通速递',
'申通快递',
'韵达快递',
'百世快递',
'邮政EMS'
]
};
},
onLoad(options) {
//
},
methods: {
//
closeAfterSalePopup2() {
this.afterSalePopup2 = false;
},
//
openAfterSalePopup2(type) {
this.afterSalePopup2 = true;
},
//
afterReadImg(e) {
e.file.forEach(item => {
upload(item.url, res => {
this.imgList.push({ url: picUrl + res.data.path });
console.log('imgList:', this.imgList);
});
});
},
//
deletePic(e) {
this.imgList.splice(e.index, 1);
},
//
selectLogisticsCompany(index) {
this.selectedRefundReason = this.logisticsCompanies[index];
this.afterSalePopup2 = false;
},
//
submitRefundApplication() {
if (!this.selectedServiceType || !this.selectedRefundReason) {
uni.showToast({
title: '请完善物流信息',
icon: 'none'
});
return;
}
//
const logisticsInfo = {
serviceType: this.selectedServiceType,
refundReason: this.selectedRefundReason,
refundDescription: this.refundDescription,
imgList: this.imgList
};
console.log('提交物流信息:', logisticsInfo);
//
uni.showToast({
title: '物流信息提交成功',
icon: 'success'
});
}
}
};
</script>
<style>
@import url('./index.css');
</style>

View File

@ -0,0 +1,269 @@
.page {
background-color: #f6f7fb;
min-height: 100vh;
padding-bottom: 120rpx;
}
.progress-container {
display: flex;
justify-content: space-between;
padding: 30rpx 20rpx;
background-color: #ffffff;
margin-bottom: 20rpx;
}
.progress-item {
display: flex;
flex-direction: column;
align-items: center;
width: 33%;
}
.progress-item.active .progress-text {
color: #ff4d4f;
}
.progress-text {
font-size: 24rpx;
color: #999999;
margin-top: 10rpx;
}
.progress-line {
width: 200rpx;
height: 2rpx;
background-color: #d9d9d9;
align-self: center;
flex-grow: 1;
margin-top: 10rpx;
}
.status-tip {
background-color: #ffffff;
padding: 30rpx 20rpx;
margin-bottom: 20rpx;
text-align: center;
}
.status-title {
font-size: 40rpx;
font-weight: bold;
color: #333333;
display: block;
margin-bottom: 10rpx;
}
.status-desc {
font-size: 24rpx;
color: #999999;
display: block;
margin-bottom: 5rpx;
}
.status-desc2 {
font-size: 24rpx;
background-color: #ffeeeb;
color: #fe441a;
width: 80%;
margin: 20rpx auto 0;
padding: 20rpx;
border-radius: 8rpx;
}
.addOrderIdBtn{
width: 70%;
margin: 10rpx auto 0;
border-radius: 50rpx;
background-color: #ff3f14;
color: #ffffff;
}
.hr {
height: 20rpx;
background: #f5f7fb;
}
.goods-info {
background-color: #ffffff;
margin-bottom: 20rpx;
padding: 20rpx;
}
.goods-item {
display: flex;
padding: 10rpx 0;
border-bottom: 1rpx solid #eeeeee;
position: relative;
}
.goods-image {
width: 160rpx;
height: 160rpx;
border-radius: 10rpx;
margin-right: 20rpx;
}
.goods-details {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.asGoodTag {
background-color: #ff7d00;
color: white;
font-size: 22rpx;
padding: 5rpx 10rpx;
border-radius: 8rpx 0 8rpx 8rpx;
}
.asGoodTag1 {
margin-right: 15rpx;
}
.tag-img {
position: absolute;
top: 133rpx;
left: 80rpx;
z-index: 1;
}
.goods-name {
font-weight: bold;
font-size: 28rpx;
color: #333333;
margin-bottom: 10rpx;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.goods-desc {
font-size: 26rpx;
color: #ff4d4f;
background-color: #fff2f0;
padding: 4rpx 12rpx;
border-radius: 8rpx;
display: inline-block;
margin: 10rpx 0;
}
.goods-price {
font-size: 26rpx;
color: #ff4d4f;
margin-bottom: 5rpx;
}
.goods-count {
font-size: 24rpx;
color: #666666;
float: right;
}
.refund-amount {
font-size: 28rpx;
align-self: flex-start;
margin-top: 20rpx;
font-weight: 500;
position: relative;
left: 140rpx;
}
.refund-info {
background-color: #ffffff;
margin-bottom: 20rpx;
}
.info-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 25rpx 20rpx;
border-bottom: 1rpx solid #eeeeee;
}
.info-label {
font-size: 28rpx;
color: #666666;
width: 200rpx;
}
.info-value {
font-size: 28rpx;
color: #333333;
flex: 1;
text-align: right;
padding-right: 20rpx;
}
.amount {
color: #ff4d4f;
font-weight: bold;
}
.info-arrow {
width: 16rpx;
height: 16rpx;
border-top: 2rpx solid #999999;
border-right: 2rpx solid #999999;
transform: rotate(45deg);
}
.copy-icon {
width: 30rpx;
height: 30rpx;
background-image: url('https://wechat-img-file.oss-cn-beijing.aliyuncs.com/myOrder/copy.png');
background-size: cover;
}
.action-buttons {
display: flex;
padding: 20rpx;
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 999;
margin-bottom: 30rpx;
}
.cancel-btn {
width: 220rpx;
height: 80rpx;
background-color: #d9d9d9;
color: #333;
border-radius: 40rpx;
font-size: 28rpx;
line-height: 80rpx;
text-align: center;
}
.modify-btn {
width: 220rpx;
height: 80rpx;
background-color: #ffebcb;
color: #983012;
border-radius: 40rpx;
font-size: 28rpx;
line-height: 80rpx;
text-align: center;
}
.urge-btn {
width: 220rpx;
height: 80rpx;
background-color: #ff4d4f;
color: #ffffff;
border: none;
border-radius: 40rpx;
font-size: 28rpx;
line-height: 80rpx;
text-align: center;
}
.bottomImg{
width: 70rpx;
height: 80rpx;
}

View File

@ -0,0 +1,203 @@
<template>
<view class="container">
<!-- 进度条 -->
<view class="progress-container">
<view class="progress-item">
<text class="progress-text">商家处理</text>
</view>
<view class="progress-line"></view>
<view class="progress-item active">
<text class="progress-text">寄回商品</text>
</view>
<view class="progress-line"></view>
<view class="progress-item">
<text class="progress-text">退款结束</text>
</view>
</view>
<!-- 状态提示 -->
<view class="status-tip">
<text class="status-title">自行寄回</text>
<text class="status-desc"><text style="color: #ff481f;">2</text>后未寄出将撤销退货申请</text>
<view class="status-desc2">需您自行联系快递公司退回请不要邮寄到付</view>
<view class="info-item" style="border: none;">
<text class="info-label">商家地址</text>
<text class="info-value">{{ currentAfterSale.after_sales_no }}</text>
<text class="copy-icon" @click="copyAdress"></text>
</view>
<button class="addOrderIdBtn" @click="addOrderId">填写单号</button>
</view>
<view class="hr"></view>
<!-- 商品信息 -->
<view class="goods-info">
<view class="goods-item">
<view class="asGoodTag tag-img"
v-if="currentAfterSale.commodity_order_item[0].is_support_same_day === 1">当日达</view>
<image class="goods-image" :src="currentAfterSale.commodity_order_item[0].commodity_pic"></image>
<view class="goods-details">
<text class="goods-name">
<text class="asGoodTag asGoodTag1"
v-if="currentAfterSale.commodity_order_item[0].is_support_same_day === 1">当日达</text>
{{ currentAfterSale.commodity_order_item[0].goods_name }}
<text class="refund-amount">退款¥{{ currentAfterSale.refund_amount.toFixed(2) }}</text>
</text>
<text class="goods-desc">{{ ite.after_sales_reason }}</text>
<text class="goods-price">
{{ '¥' + currentAfterSale.commodity_order_item[0].sales_price.toFixed(2) + '/个' }}
<text class="goods-count">X{{ currentAfterSale.commodity_order_item[0].count }}</text>
</text>
</view>
</view>
</view>
<!-- 退款信息 -->
<view class="refund-info">
<view class="info-item">
<text class="info-label">服务类型<text style="color: #fc3811;">*</text></text>
<text class="info-value">{{ getServiceTypeText(currentAfterSale.after_sales_type) }}</text>
<text class="info-arrow"></text>
</view>
<view class="info-item">
<text class="info-label">退款原因<text style="color: #fc3811;">*</text></text>
<text class="info-value">{{ currentAfterSale.after_sales_reason }}</text>
<text class="info-arrow"></text>
</view>
<view class="info-item">
<text class="info-label">退款金额<text style="color: #fc3811;">*</text></text>
<text class="info-value amount">{{ '¥' + currentAfterSale.refund_amount.toFixed(2) }}</text>
</view>
<view class="info-item">
<text class="info-label">申请时间<text style="color: #fc3811;">*</text></text>
<text class="info-value">{{ formatDate(currentAfterSale.create_time) }}</text>
</view>
<view class="info-item">
<text class="info-label">退款编号<text style="color: #fc3811;">*</text></text>
<text class="info-value">{{ currentAfterSale.after_sales_no }}</text>
<text class="copy-icon" @click="copyRefundNo"></text>
</view>
</view>
<!-- 操作按钮 -->
<view class="action-buttons">
<view>
<image class="bottomImg" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/secdBack_bottom.png" alt=""/>
</view>
<button class="modify-btn" @click="modifyRefund">平台介入</button>
<button class="cancel-btn" @click="cancelRefund">撤销申请</button>
</view>
</view>
</template>
<script>
import {
isPhone,
picUrl,
request,
upload,
NavgateTo
} from '../../../utils';
export default {
data() {
return {
currentAfterSale: {},
pickerDefaultDate: new Date()
};
},
created() {
//
this.pickerDefaultDate = new Date(this.currentAfterSale.create_time);
},
onLoad(options) {
const item = JSON.parse(options?.item);
console.log("🚀 ~ onLoad ~ item:", item)
this.currentAfterSale = item;
},
methods: {
getServiceTypeText(type) {
return type === 1 ? '退货退款' : '仅退款';
},
//
formatDate(dateString) {
if (!dateString) return '';
const date = new Date(dateString);
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}:${String(date.getSeconds()).padStart(2, '0')}`;
},
//
copyAdress() {
uni.setClipboardData({
data: this.currentAfterSale.after_sales_no,
success: () => {
uni.showToast({
title: '复制成功',
icon: 'success'
});
},
fail: () => {
uni.showToast({
title: '复制失败',
icon: 'none'
});
}
});
},
addOrderId(){
NavgateTo(`../returnLogistics/index?item=${JSON.stringify(this.currentAfterSale)}`);
},
// 退
copyRefundNo() {
uni.setClipboardData({
data: this.currentAfterSale.after_sales_no,
success: () => {
uni.showToast({
title: '复制成功',
icon: 'success'
});
},
fail: () => {
uni.showToast({
title: '复制失败',
icon: 'none'
});
}
});
},
//
cancelRefund() {
uni.showModal({
title: "确定要撤销本次售后申请吗?",
showCancel: true,
cancelText: "暂不撤销",
confirmText: "确认撤销",
confirmColor: "#ff4d4f",
success: (res) => {
if (res.confirm) {
//
uni.showToast({
title: '订单撤销成功',
icon: 'success'
});
}
},
});
},
//
modifyRefund() {
NavgateTo(`../apply/index?item=${JSON.stringify(this.currentAfterSale)}`);
},
}
};
</script>
<style scoped>
@import url('./index.css')
</style>

View File

@ -0,0 +1,106 @@
page {
background-color: #f5f7fb;
padding-top: 30rpx;
}
.container {
background-color: #fff;
padding: 30rpx;
border-radius: 20rpx;
}
.title {
font-size: 30rpx;
margin-top: 10rpx;
margin-bottom: 30rpx;
text-align: center;
}
.btn {
width: 80%;
height: 90rpx;
line-height: 90rpx;
text-align: center;
background-color: #ff4016;
color: #fff;
font-size: 32rpx;
border-radius: 50rpx;
margin: 100rpx auto;
}
.selectColorBox{
width: 95%;
display: flex;
justify-content: space-between;
align-items: center;
margin: 30rpx auto 0;
}
.selectColor{
display: flex;
justify-content: space-between;
align-items: center;
}
.color{
margin-right: 10rpx;
}
/* 弹窗样式 */
.payIpt {
background-color: #fff;
border-radius: 30rpx 30rpx 0 0;
overflow: hidden;
}
.tit {
font-size: 32rpx;
text-align: center;
padding: 30rpx 0;
font-weight: bold;
border-bottom: 1rpx solid #eee;
}
/* 颜色列表样式 */
.color-list {
max-height: 500rpx;
padding: 20rpx 0;
}
.color-item {
font-size: 28rpx;
text-align: center;
padding: 30rpx 0;
border-bottom: 1rpx solid #f0f0f0;
}
.color-item:last-child {
border-bottom: none;
}
.color-item.active {
color: #ff4016;
}
/* 底部按钮样式 */
.popup-footer {
display: flex;
border-top: 1rpx solid #eee;
}
.cancel-btn,
.confirm-btn {
flex: 1;
text-align: center;
padding: 30rpx 0;
font-size: 32rpx;
}
.cancel-btn {
color: #666;
border-right: 1rpx solid #eee;
}
.confirm-btn {
color: #ff4016;
}

View File

@ -0,0 +1,127 @@
<template>
<view>
<view class="container">
<view class="title">请输入车牌号码</view>
<car-number-input @numberInputResult="numberInputResult" :defaultStr="defaultNum" ref="carNumberInput" />
<view class="selectColorBox" @click="show = true">
<view>车牌颜色</view>
<view class="selectColor">
<view class="color">{{ color }}</view>
<u-icon name="arrow-right" size="25"></u-icon>
</view>
</view>
</view>
<view class="btn" @click="submit">确定</view>
<!-- 选择车牌颜色 -->
<u-popup :show="show" :round="30" mode="bottom" @close="onClose">
<view class="payIpt">
<view class="tit">选择车牌颜色</view>
<!-- 颜色选择列表 -->
<scroll-view class="color-list" scroll-y>
<view class="color-item" :class="{ 'active': selectedColorIndex === index }"
v-for="(item, index) in colorOptions" :key="index" @click="selectColor(index)">
{{ item }}
</view>
</scroll-view>
<!-- 底部按钮 -->
<view class="popup-footer">
<view class="cancel-btn" @click="onClose">取消</view>
<view class="confirm-btn" @click="confirmColor">确定</view>
</view>
</view>
</u-popup>
</view>
</template>
<script>
import {
isPhone,
picUrl,
request,
upload,
NavgateTo
} from '../../../utils';
import { apiArr } from '@/api/park.js'
export default {
data() {
return {
defaultNum: '',
color: '请选择',
show: false,
//
colorOptions: ['蓝牌', '黄牌', '黑牌', '白牌', '绿牌', '渐变绿底黑字', '黄绿双拼底黑字'],
//
selectedColorIndex: -1
};
},
mounted() {
},
methods: {
numberInputResult(e) {
this.defaultNum = e;
},
onClose() {
this.show = false;
},
//
selectColor(index) {
this.selectedColorIndex = index;
},
//
confirmColor() {
if (this.selectedColorIndex !== -1) {
this.color = this.colorOptions[this.selectedColorIndex];
}
this.show = false;
},
//
submit() {
const actualNumber = this.defaultNum.replace(/\s/g, '');
if (this.defaultNum == '' || actualNumber.length < 7) {
uni.showToast({
title: '请输入正确的车牌号',
icon: 'none',
duration: 2000
})
return;
}
if (this.color == '请选择') {
uni.showToast({
title: '请选择车牌颜色',
icon: 'none',
duration: 2000
})
return;
}
const params = {
user_id: uni.getStorageSync('userId'),
car_number: this.defaultNum,
car_number_color: this.color
}
request(apiArr.carAdd, "POST", params).then((res) => {
uni.showToast({
title: '添加成功',
icon: 'success',
duration: 2000
})
if (this.$refs.carNumberInput) {
// inputList
for (let i = 0; i < 8; i++) {
this.$refs.carNumberInput.inputList[i] = ' ';
}
this.$refs.carNumberInput.$forceUpdate();
}
this.color = '请选择';
this.selectedColorIndex = -1;
});
}
}
}
</script>
<style>
@import url('./index.css')
</style>

View File

@ -0,0 +1,124 @@
page {
background-color: #f5f7fb;
padding-top: 20rpx;
}
/* 车辆信息容器样式 */
.container-box{
height: 83vh;
overflow-y: auto;
}
.car-info-container {
width: 92%;
background-color: #ffffff;
padding: 30rpx;
border-bottom: 1rpx solid #eeeeee;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
}
.car-info{
display: flex;
justify-content: space-between;
}
/* 车牌样式 */
.license-plate {
display: flex;
align-items: center;
gap: 20rpx;
}
/* 车牌类型标签样式 */
.plate-type-box{
padding: 11rpx 2rpx;
/* border: 1rpx solid #1890ff; */
border-radius: 8rpx;
}
.plate-type {
background-color: #1890ff;
color: white;
padding: 10rpx 20rpx;
border-radius: 8rpx;
font-size: 28rpx;
}
/* 车牌号样式 */
.plate-number {
font-size: 32rpx;
color: #333333;
font-weight: 500;
display: flex;
align-items: center;
padding: 15rpx 30rpx;
border-radius: 10rpx;
}
/* 蓝色车牌样式 */
.plate-color-blue {
background-color: #1890ff;
color: white;
}
/* 黄色车牌样式 */
.plate-color-yellow {
background-color: #ffc53d;
color: black;
}
/* 黑色车牌样式 */
.plate-color-black {
background-color: #333333;
color: white;
}
/* 白色车牌样式 */
.plate-color-white {
background-color: white;
color: black;
border: 1rpx solid #dddddd;
}
/* 绿色车牌样式 */
.plate-color-green {
background-color: #37bd75;
color: white;
}
/* 渐变绿底黑字车牌样式 */
.plate-color-gradient-green {
background: linear-gradient(180deg, #ffffff 0%, #2fe259 100%);
color: black;
}
/* 黄绿双拼底黑字车牌样式 */
.plate-color-yellow-green {
background: linear-gradient(90deg, #ffc53d 30%, #37bd75 0%);
color: black;
}
.plate-energy{
font-size: 24rpx;
padding: 7rpx 15rpx;
margin-left: 15rpx;
border-radius: 10rpx;
background-color: #f2f3f4;
color: #37bd75;
}
/* 添加车辆按钮样式 */
.add-car-btn {
height: 100rpx;
width: 80%;
background-color: #ff3f15;
line-height: 100rpx;
color: white;
border-radius: 50rpx;
font-size: 32rpx;
font-weight: 500;
position: absolute;
bottom: 100rpx;
left: 10%;
}

View File

@ -0,0 +1,105 @@
<template>
<view class="container">
<!-- 车辆信息区域 -->
<view class="container-box">
<view class="car-info-container" v-for="(item, index) in carList" :key="index">
<view class="car-info">
<view class="license-plate">
<view class="plate-type-box">
<text class="plate-type" :class="{
'plate-color-blue': item.car_number_color === '蓝牌',
'plate-color-yellow': item.car_number_color === '黄牌',
'plate-color-black': item.car_number_color === '黑牌',
'plate-color-white': item.car_number_color === '白牌',
'plate-color-green': item.car_number_color === '绿牌',
'plate-color-gradient-green': item.car_number_color === '渐变绿底黑字',
'plate-color-yellow-green': item.car_number_color === '黄绿双拼底黑字'
}">{{ item.car_number_color }}</text>
</view>
<view class="plate-number">
{{ item.car_number }}
<view class="plate-energy" v-if="getActualCarNumberLength(item.car_number) > 7">新能源</view>
</view>
</view>
<u-icon name="trash" size="45rpx" @click="deleteCar(item)"></u-icon>
</view>
</view>
</view>
<!-- 添加车辆按钮 -->
<button class="add-car-btn" @click="addCar">添加车辆</button>
</view>
</template>
<script>
import {
isPhone,
picUrl,
request,
upload,
NavgateTo
} from '../../../utils';
import { apiArr } from '@/api/park.js'
export default {
data() {
return {
carList: []
}
},
methods: {
getCarList() {
const params = {
user_id: uni.getStorageSync('userId')
}
request(apiArr.carList, "POST", params).then((res) => {
this.carList = res.car_list;
})
},
//
getActualCarNumberLength(carNumber) {
if (!carNumber) return 0;
//
const actualNumber = carNumber.replace(/\s/g, '');
return actualNumber.length;
},
deleteCar(item) {
uni.showModal({
title: '提示',
content: '确定删除该车辆吗?',
success: (res) => {
if (res.confirm) {
const params = {
car_id: item.id
}
request(apiArr.deleteCar, "POST", params).then((res) => {
uni.showToast({
title: '删除成功',
icon: 'success',
duration: 2000
});
this.getCarList();
})
}
}
})
},
addCar() {
//
uni.navigateTo({
url: '/packages/park/addCar/index'
})
}
},
onShow() {
this.getCarList();
}
}
</script>
<style>
@import url('./index.css');
</style>

View File

@ -0,0 +1,393 @@
/* 包月支付页面样式 */
page {
background-color: #f5f7fb;
}
.monthly-payment-container {
box-sizing: border-box;
width: 100%;
}
.overlay {
position: absolute;
top: 90rpx;
left: 0;
width: 100%;
height: 94vh;
background-color: rgba(0, 0, 0, 0.5);
z-index: 98;
}
/* 下拉停车场列表样式 */
.parking-list {
background-color: #ffffff;
padding: 20rpx 30rpx;
border-bottom: 1rpx solid #f0f0f0;
border-radius: 0 0 40rpx 40rpx;
position: fixed;
top: 80rpx;
left: 0;
right: 0;
z-index: 999;
}
/* 搜索框样式 */
.search-box {
display: flex;
align-items: center;
background-color: #f5f7fb;
border-radius: 50rpx;
padding: 20rpx 30rpx;
margin: 20rpx 0;
}
.search-icon {
margin-right: 15rpx;
}
.search-input {
flex: 1;
font-size: 26rpx;
color: #333333;
background-color: transparent;
}
/* 停车场列表项样式 */
.parking-items {
max-height: 600rpx;
overflow-y: auto;
}
.parking-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 25rpx 0;
border-bottom: 1rpx solid #f0f0f0;
}
.parking-item:last-child {
border-bottom: none;
}
.parking-item-right {
flex: 1;
}
.parking-name {
font-size: 32rpx;
font-weight: bold;
color: #333333;
margin-bottom: 10rpx;
display: block;
}
.parking-distance {
font-size: 26rpx;
color: #999999;
margin-right: 20rpx;
}
.parking-address {
font-size: 26rpx;
color: #999999;
display: block;
margin-top: 8rpx;
}
.parking-item-left {
display: flex;
align-items: flex-start;
position: relative;
}
.parking-selected {
font-size: 40rpx;
color: #ff4219;
position: relative;
right: 30rpx;
}
.parking-spaces {
background-color: #ffeeee;
border-radius: 20rpx;
padding: 8rpx 16rpx;
display: flex;
flex-direction: column;
align-items: center;
margin-right: 30rpx;
}
.spaces-label {
font-size: 22rpx;
color: #ff4219;
margin-bottom: 4rpx;
}
.spaces-number {
font-size: 30rpx;
font-weight: bold;
color: #ff4219;
}
/* 顶部标题样式 */
.header {
display: flex;
align-items: center;
justify-content: center;
position: relative;
background-color: #fff3f1;
padding: 20rpx 0;
height: 45rpx;
}
.header-title {
font-size: 32rpx;
font-weight: 500;
color: #333333;
text-align: center;
margin-right: 10rpx;
font-weight: bold;
}
.header-arrow {
width: 30rpx;
height: 30rpx;
margin-left: 10rpx;
}
/* 车辆信息样式 */
.car-info {
display: flex;
justify-content: center;
margin: 40rpx 0;
}
.car-image {
width: 50%;
height: 200rpx;
position: absolute;
top: 193rpx;
}
/* 停车场信息样式 */
.park-info {
margin-bottom: 20rpx;
margin-top: 50rpx;
}
.park-name {
font-size: 32rpx;
color: #333333;
}
.park-type {
font-size: 28rpx;
color: #ff4d4f;
margin-left: 30rpx;
font-weight: bold;
}
/* 支付金额样式 */
.payment-amount {
margin-bottom: 30rpx;
}
.amount-label {
display: block;
font-size: 26rpx;
color: #c8c7c7;
margin-bottom: 10rpx;
}
.amount-value {
font-size: 40rpx;
color: #ff4d4f;
}
/* 选项列表样式 */
.options-list {
background-color: #ffffff;
border-radius: 20rpx;
overflow: hidden;
border-radius: 30rpx;
margin: 200rpx 30rpx 0;
padding: 30rpx;
}
.option-item {
padding: 20rpx 30rpx;
border-radius: 50rpx;
margin-bottom: 25rpx;
background-color: #f5f7fb;
transition: all 0.3s ease;
}
.option-right {
display: flex;
align-items: center;
}
.option-box {
display: flex;
justify-content: space-between;
align-items: center;
}
.option-image {
width: 35rpx;
height: 35rpx;
margin-left: 20rpx;
}
.option-label {
font-size: 26rpx;
color: #333333;
font-weight: bold;
}
.option-val {
color: #ff370a;
}
.option-val2 {
margin: 0 auto;
}
.option-value {
font-size: 26rpx;
color: #999999;
flex: 1;
text-align: right;
margin-right: 20rpx;
}
.option-arrow {
width: 24rpx;
height: 24rpx;
}
/* 下一步按钮样式 */
.next-step-btn {
background-color: #ff4219;
color: #ffffff;
text-align: center;
padding: 20rpx;
border-radius: 100rpx;
margin: 40rpx 0;
}
.next-step-text {
font-size: 36rpx;
font-weight: 500;
}
/* 订单记录样式 */
.order-record {
text-align: center;
margin-top: 50rpx;
}
.order-record-text {
font-size: 28rpx;
color: #ff3f11;
}
/* 弹窗通用样式 */
.car-plate-popup {
padding: 30rpx;
box-sizing: border-box;
background-color: #ffffff;
border-radius: 30rpx 30rpx 0 0;
max-height: 80vh; /* 限制弹窗最大高度 */
}
.popup-header {
text-align: center;
margin-bottom: 30rpx;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #f0f0f0;
}
.popup-title {
font-size: 36rpx;
font-weight: bold;
color: #333333;
}
.car-plate-list {
max-height: 600rpx;
overflow-y: auto;
padding-right: 10rpx; /* 为滚动条留出空间 */
}
/* 美化滚动条样式 */
.car-plate-list::-webkit-scrollbar {
width: 8rpx;
}
.car-plate-list::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 4rpx;
}
.car-plate-list::-webkit-scrollbar-thumb {
background: #ccc;
border-radius: 4rpx;
}
.car-plate-list::-webkit-scrollbar-thumb:hover {
background: #999;
}
.car-plate-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx;
margin-bottom: 20rpx;
background-color: #f5f7fb;
border-radius: 20rpx;
transition: all 0.3s ease;
}
.car-plate-item.selected {
background-color: #ff431923;
border: 2rpx solid #ff4219;
}
.plate-number {
font-size: 28rpx;
font-weight: 500;
color: #333333;
flex: 1;
}
.rule-price {
font-size: 32rpx;
font-weight: bold;
color: #ff4219;
margin-right: 20rpx;
}
.popup-footer {
margin-top: 30rpx;
padding-top: 20rpx;
border-top: 1rpx solid #f0f0f0;
}
.close-btn {
width: 100%;
height: 90rpx;
line-height: 90rpx;
background-color: #ff4219;
color: #ffffff;
border: none;
border-radius: 45rpx;
font-size: 32rpx;
font-weight: 500;
}
.close-btn:active {
background-color: #e03a16;
}

View File

@ -0,0 +1,499 @@
<template>
<view class="monthly-payment-container">
<!-- 顶部标题 -->
<view class="header" @tap="toggleDropdown">
<text class="header-title">{{ headerTitle }}</text>
<u-icon :name="isDropdownOpen ? 'arrow-up' : 'arrow-down'" size="28"></u-icon>
</view>
<!-- 下拉停车场列表 -->
<view v-if="isDropdownOpen" class="parking-list">
<!-- 搜索框 -->
<view class="search-box">
<u-icon name="search" size="40" color="#999" class="search-icon" />
<input type="text" placeholder="搜索停车场" class="search-input" />
</view>
<!-- 停车场列表 -->
<view class="parking-items">
<view class="parking-item" v-for="(park, index) in parkingLots" :key="index"
@tap="selectParkingLot(park)">
<view class="parking-item-left">
<view class="parking-spaces">
<text class="spaces-label">剩余车位</text>
<text class="spaces-number">{{ park.space_count }}</text>
</view>
</view>
<view class="parking-item-right">
<text class="parking-name">{{ park.parking_name }}</text>
<text class="parking-distance">{{ park.distance }}km</text>
<text class="parking-address">{{ park.address }}</text>
</view>
<view class="parking-selected" v-if="park.isSelected"></view>
</view>
</view>
</view>
<view class="options-list">
<view class="overlay" v-if="isDropdownOpen" @tap="toggleDropdown"></view>
<!-- 车辆信息 -->
<view class="car-info">
<image class="car-image" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/park/car.png"
mode="aspectFit" />
</view>
<!-- 停车场信息 -->
<view class="park-info" v-if="headerTitle != '请选择停车场'">
<text class="park-name">{{ headerTitle }}</text>
<text class="park-type">{{ selectedParkType == 1 ? '地上' : '地下' }}</text>
</view>
<!-- 支付金额 -->
<view class="payment-amount">
<text class="amount-label">支付金额</text>
<text class="amount-value">¥{{ paymentAmount.toFixed(2) }}</text>
</view>
<!-- 选项列表 -->
<!-- 选择车牌 -->
<view class="option-item" @tap="selectCarPlate">
<view v-if="selectedCarPlate" class="option-box">
<view class="option-label option-val">{{ selectedCarPlate }}</view>
<view class="option-right">
<image class="option-image"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/park/park_refresh.png"
mode="aspectFit" />
<image class="option-image"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/park/park_finish.png"
mode="aspectFit" />
</view>
</view>
<view v-else class="option-box">
<text class="option-label">请选择车牌</text>
<u-icon name="arrow-right" size="30" />
</view>
</view>
<!-- 计费规则 -->
<view class="option-item" @tap="showPriceRule">
<view v-if="monthPrice !== ''" class="option-box">
<view class="option-label option-val2">{{ monthPrice + '元/月' }}</view>
</view>
<view v-else class="option-box">
<text class="option-label">计费规则</text>
<u-icon name="arrow-right" size="30" />
</view>
</view>
<!-- 包月月数 -->
<view class="option-item" @tap="selectMonthCount">
<view v-if="monthCount" class="option-box">
<view class="option-label option-val">{{ monthCount + '个月' }}</view>
<view class="option-right">
<image class="option-image"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/park/park_refresh.png"
mode="aspectFit" />
<image class="option-image"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/park/park_finish.png"
mode="aspectFit" />
</view>
</view>
<view v-else class="option-box">
<text class="option-label">包月月数</text>
<u-icon name="arrow-right" size="30" />
</view>
</view>
<!-- 开始时间 -->
<view class="option-item">
<view class="option-box">
<text class="option-label">开始时间</text>
<text class="option-value">{{ startTime }}</text>
</view>
</view>
<!-- 结束时间 -->
<view class="option-item">
<view class="option-box">
<text class="option-label">结束时间</text>
<text class="option-value">{{ endTime || '--年--月--日' }}</text>
</view>
</view>
<!-- 下一步按钮 -->
<view class="next-step-btn" @tap="goToNextStep">
<text class="next-step-text">下一步</text>
</view>
</view>
<!-- 订单记录 -->
<view class="order-record" @tap="viewOrderRecords">
<text class="order-record-text">订单记录>></text>
</view>
<!-- 车牌选择弹窗 -->
<u-popup :show="showCarPlatePopup" :round="30" mode="bottom" :closeable="true" close-icon-position="top-right"
@close="onCloseCarPlatePopup">
<view class="car-plate-popup">
<view class="popup-header">
<text class="popup-title">选择车牌</text>
</view>
<view class="car-plate-list">
<view class="car-plate-item" v-for="(plate, index) in carPlateList" :key="index"
@tap="onSelectCarPlate(plate)" :class="{ 'selected': selectedCarPlate === plate.car_number }">
<text class="plate-number">{{ plate.car_number }}</text>
<u-icon v-if="selectedCarPlate === plate.car_number" name="checkmark-circle" size="28"
color="#ff4219"></u-icon>
</view>
</view>
</view>
</u-popup>
<!-- 计费规则弹窗 -->
<u-popup :show="billingRulesPopup" :round="30" mode="bottom" :closeable="true" close-icon-position="top-right"
@close="onCloseBillingRulesPopup">
<view class="car-plate-popup">
<view class="popup-header">
<text class="popup-title">计费规则</text>
</view>
<view class="car-plate-list">
<view class="car-plate-item" v-for="(rule, index) in billingRulesList" :key="index"
@tap="onSelectBillingRule(rule)" :class="{ 'selected': monthPrice === rule.price }">
<text class="plate-number">{{ rule.billing_rule_name }}</text>
<text class="rule-price">¥{{ rule.month_price }}/</text>
<u-icon v-if="monthPrice === rule.month_price" name="checkmark-circle" size="28"
color="#ff4219"></u-icon>
</view>
</view>
</view>
</u-popup>
<!-- 包月月数选择弹窗 -->
<u-popup :show="showMonthCountPopup" :round="30" mode="bottom" :closeable="true" close-icon-position="top-right"
@close="onCloseMonthCountPopup">
<view class="car-plate-popup">
<view class="popup-header">
<text class="popup-title">选择包月月数</text>
</view>
<view class="car-plate-list">
<view class="car-plate-item" v-for="(month, index) in monthList" :key="index"
@tap="onSelectMonthCount(month)" :class="{ 'selected': monthCount === month.value }">
<text class="plate-number">{{ month.label }}</text>
<u-icon v-if="monthCount === month.value" name="checkmark-circle" size="28"
color="#ff4219"></u-icon>
</view>
</view>
</view>
</u-popup>
</view>
</template>
<script>
import {
isPhone,
picUrl,
request,
upload,
NavgateTo
} from '../../../utils';
import { apiArr } from '@/api/park.js'
export default {
data() {
return {
//
selectedCarPlate: '',
monthCount: '',
startTime: '',
endTime: '',
paymentAmount: 2400.00,
monthPrice: '',
//
isDropdownOpen: false,
headerTitle: '请选择停车场',
selectedParkType: '',
selectedParkId: '',//id
parkingLots: [],
//
showCarPlatePopup: false,
carPlateList: [],
selectedCarPlateId: '',//id
//
billingRulesPopup: false,
billingRulesList: [],
selectedBillingRule: '',//
//
showMonthCountPopup: false,
monthList: Array.from({ length: 12 }, (_, i) => ({
value: i + 1,
label: (i + 1) + '个月'
}))
}
},
computed: {
isAllFilled() {
return this.selectedParkId && this.selectedCarPlateId && this.monthCount > 0 && this.startTime;
}
},
methods: {
//
toggleDropdown() {
this.isDropdownOpen = !this.isDropdownOpen;
},
//
selectParkingLot(park) {
//
this.parkingLots.forEach(item => {
item.isSelected = false;
});
//
park.isSelected = true;
this.$set(this, 'headerTitle', park.parking_name);
this.$set(this, 'selectedParkType', park.space_type);
this.selectedParkId = park.id;
this.isDropdownOpen = false;
},
selectCarPlate() {
this.showCarPlatePopup = true;
},
onCloseCarPlatePopup() {
this.showCarPlatePopup = false;
},
//
onSelectCarPlate(plate) {
this.selectedCarPlate = plate.car_number;
this.selectedCarPlateId = plate.id;
this.showCarPlatePopup = false;
},
//
showPriceRule() {
if (!this.selectedParkId) {
uni.showToast({
title: '请选择停车场',
icon: 'none'
})
return;
}
this.getBillingRulesList();
this.billingRulesPopup = true;
},
//
onCloseBillingRulesPopup() {
this.billingRulesPopup = false;
},
//
onSelectBillingRule(rule) {
this.selectedBillingRule = rule.billing_rule_name;
this.monthPrice = rule.month_price;
this.paymentAmount = this.monthCount * this.monthPrice;
this.billingRulesPopup = false;
},
//
selectMonthCount() {
this.showMonthCountPopup = true;
},
//
onCloseMonthCountPopup() {
this.showMonthCountPopup = false;
},
//
onSelectMonthCount(month) {
this.monthCount = month.value;
if (this.startTime) {
const startDate = new Date(this.startTime);
//
const endDate = new Date(startDate);
endDate.setMonth(endDate.getMonth() + this.monthCount);
//
endDate.setDate(endDate.getDate() - 1);
// 23:59:59
endDate.setHours(23, 59, 59, 999);
// 使
const endYear = endDate.getFullYear();
const endMonth = String(endDate.getMonth() + 1).padStart(2, '0');
const endDay = String(endDate.getDate()).padStart(2, '0');
const endHours = String(endDate.getHours()).padStart(2, '0');
const endMinutes = String(endDate.getMinutes()).padStart(2, '0');
const endSeconds = String(endDate.getSeconds()).padStart(2, '0');
this.endTime = `${endYear}-${endMonth}-${endDay} ${endHours}:${endMinutes}:${endSeconds}`;
}
this.paymentAmount = this.monthCount * this.monthPrice;
this.showMonthCountPopup = false;
},
//
goToNextStep() {
if (!this.isAllFilled) {
uni.showModal({
title: "提示",
content: "请填写完整信息",
showCancel: false,
});
return;
}
//
// const params = {
// headerTitle: this.headerTitle,
// selectedParkType: this.selectedParkType,
// selectedParkId: this.selectedParkId,
// selectedCarPlateId: this.selectedCarPlateId,
// selectedCarPlate: this.selectedCarPlate,
// monthPrice: this.monthPrice,
// monthCount: this.monthCount,
// startTime: this.startTime,
// endTime: this.endTime,
// paymentAmount: this.paymentAmount,
// selectedBillingRule: this.selectedBillingRule,
// };
const params = {
user_id: uni.getStorageSync('userId'),
parking_id: this.selectedParkId,
car_id: this.selectedCarPlateId,
billing_rules: this.selectedBillingRule,
month_count: this.monthCount,
total_amount: this.paymentAmount,
start_time: this.startTime,
end_time: this.endTime,
}
request(apiArr.monthCardCreate, "POST", params).then((resVal) => {
// trans_type
// : 71, App: 51
const systemInfo = uni.getSystemInfoSync();
let trans_type = 51; // App
//
if (systemInfo.platform === 'devtools' || systemInfo.platform === 'unknown') {
trans_type = 71; //
}
//
// #ifdef MP
trans_type = 71; //
// #endif
// #ifdef APP-PLUS
trans_type = 51; // App
// #endif
const params = {
order_id: resVal.order_id,
user_id: uni.getStorageSync('userId'),
trans_type: trans_type,
headerTitle: this.headerTitle,
selectedParkType: this.selectedParkType,
selectedParkId: this.selectedParkId,
selectedCarPlateId: this.selectedCarPlateId,
selectedCarPlate: this.selectedCarPlate,
monthPrice: this.monthPrice,
monthCount: this.monthCount,
startTime: this.startTime,
endTime: this.endTime,
paymentAmount: this.paymentAmount,
selectedBillingRule: this.selectedBillingRule,
}
NavgateTo(`../parkOrderDetail/index?item=${encodeURIComponent(JSON.stringify(params))}`);
})
},
//
viewOrderRecords() {
NavgateTo('../monthlyPaymentOrder/index');
},
//
getParkList() {
request(apiArr.parkList, "POST", {}).then((res) => {
//
this.parkingLots = res.parking_list.map(park => {
try {
let locationData = uni.getStorageSync('location');
if (locationData) {
let location = locationData;
const userLat = location.lat;
const userLng = location.lng;
const parkLat = park.lat;
const parkLng = park.lng;
// 使Haversine
const R = 6371; //
const dLat = (parkLat - userLat) * Math.PI / 180;
const dLng = (parkLng - userLng) * Math.PI / 180;
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(userLat * Math.PI / 180) * Math.cos(parkLat * Math.PI / 180) *
Math.sin(dLng / 2) * Math.sin(dLng / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
const distance = (R * c).toFixed(1);
//
return { ...park, distance };
}
return park;
} catch (error) {
console.error('计算停车场距离时出错:', error);
return park;
}
});
//
this.parkingLots.sort((a, b) => {
//
if (a.distance !== undefined && b.distance !== undefined) {
return a.distance - b.distance;
}
if (a.distance !== undefined) return -1;
if (b.distance !== undefined) return 1;
return 0;
});
})
},
//
getCarPlateList() {
request(apiArr.carList, "POST", {}).then((res) => {
this.carPlateList = res.car_list;
})
},
//
getBillingRulesList() {
const params = {
parking_id: this.selectedParkId,
}
request(apiArr.billingRulesList, "POST", params).then((res) => {
this.billingRulesList = res.billing_rules_list;
})
},
},
onLoad() {
// 0:00:00
const today = new Date();
const year = today.getFullYear();
const month = String(today.getMonth() + 1).padStart(2, '0'); // 0+1
const day = String(today.getDate()).padStart(2, '0');
// 'YYYY-MM-DD HH:mm:ss'
this.startTime = `${year}-${month}-${day} 00:00:00`;
//
this.paymentAmount = this.monthCount * this.monthPrice;
this.getParkList();
this.getCarPlateList();
}
}
</script>
<style>
@import url('./index.css');
</style>

View File

@ -0,0 +1,147 @@
page{
background-color: #f4f7fb;
overflow-y: hidden;
}
.tabs {
display: flex;
align-items: center;
background: #ffffff;
height: 100rpx;
padding: 0 20rpx;
box-sizing: border-box;
display: flex;
overflow-x: auto;
white-space: nowrap;
}
.tabItem {
font-size: 25rpx;
color: #222222;
margin-right: 60rpx;
height: 42rpx;
}
.active2 {
font-size: 25rpx;
font-weight: 700;
position: relative;
}
.active2::after {
content: '';
background: url(https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_active.png) no-repeat;
background-size: 100% 100%;
width: 52rpx;
height: 22rpx;
position: absolute;
left: 50%;
bottom: -16rpx;
transform: translateX(-50%);
}
/* 订单列表样式 */
.order-list {
padding: 30rpx;
height: 85vh;
overflow-y: auto;
}
.order-card {
background-color: #ffffff;
border-radius: 20rpx;
margin-bottom: 30rpx;
overflow: hidden;
}
.order-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
background: linear-gradient(to right, #ffe7e7, #ffffff);
}
.order-number {
font-size: 26rpx;
color: #333;
font-weight: bold;
}
.order-status {
font-size: 26rpx;
padding: 5rpx 20rpx;
border-radius: 50rpx;
}
.order-status.pending {
color: #999999;
}
.order-status.using {
color: #ff4219;
}
.order-status.expired {
color: #999999;
}
.order-content {
padding: 30rpx;
}
.order-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx 0;
}
.order-item.amount {
padding-top: 30rpx;
}
.order-label {
font-size: 28rpx;
color: #666666;
}
.order-value {
font-size: 28rpx;
color: #333333;
text-align: right;
}
.amount-value {
color: #ff4219;
font-size: 32rpx;
font-weight: bold;
}
.order-value.paid {
color: #4CD964;
}
.order-footer {
display: flex;
justify-content: flex-end;
padding: 30rpx;
border-top: 1rpx solid #f0f0f0;
}
.cancel-button {
font-size: 28rpx;
color: #333;
background-color: #d9d9d9;
padding: 15rpx 40rpx;
border-radius: 50rpx;
margin-right: 20rpx;
}
.pay-button {
font-size: 28rpx;
color: #ffffff;
background-color: #ff4219;
padding: 15rpx 40rpx;
border-radius: 50rpx;
}

View File

@ -0,0 +1,141 @@
<template>
<view class="container">
<view class="tabs">
<view v-for="(item, index) in categoryList" :key="index"
:class="['tabItem', selectedTab === index ? 'active2' : '']" @click="selectTab(index, item)">
{{ item.category_name }}
</view>
</view>
<!-- 订单列表 -->
<view class="order-list">
<view v-for="(order, index) in orders" :key="index" class="order-card">
<view class="order-header">
<text class="order-number">订单编号{{ order.order_sn }}</text>
<text class="order-status" :class="{
'pending': order.status == 1,
'using': order.status == 2,
'expired': order.status == 3
}">
{{ order.status == 1 ? '待支付' : order.status == 2 ? '使用中' : order.status == 3 ? '已过期' : '' }}
</text>
</view>
<view class="order-content">
<view class="order-item">
<text class="order-label">车场名称</text>
<text class="order-value">{{ order.parkingInfo.parking_name }}</text>
</view>
<view class="order-item">
<text class="order-label">车牌号</text>
<text class="order-value">{{ order.carInfo.car_no }}</text>
</view>
<view class="order-item">
<text class="order-label">包月月数</text>
<text class="order-value">{{ order.month_num }}个月</text>
</view>
<view class="order-item">
<text class="order-label">开始时间</text>
<text class="order-value">{{ order.carInfo.enable_time }}</text>
</view>
<view class="order-item">
<text class="order-label">到期时间</text>
<text class="order-value">{{ order.carInfo.deadline_time }}</text>
</view>
<view class="order-item amount">
<text class="order-label">订单金额</text>
<text class="order-value amount-value">¥{{ order.amount }}</text>
</view>
<!-- 根据订单状态显示不同内容 -->
<view v-if="order.status == '2' || order.status === '3'" class="order-item">
<text class="order-label">付款时间</text>
<text class="order-value">{{ order.pay_time }}</text>
</view>
<view v-if="order.status == '2'" class="order-item">
<text class="order-label">支付状态</text>
<text class="order-value paid">已支付</text>
</view>
</view>
<!-- 待支付订单显示操作按钮 -->
<view v-if="order.status === 'pending'" class="order-footer">
<view class="cancel-button" @tap="cancelOrder(order)">取消订单</view>
<view class="pay-button" @tap="goToPayment(order)">去支付</view>
</view>
</view>
</view>
</view>
</template>
<script>
import {
isPhone,
picUrl,
request,
upload,
NavgateTo
} from '../../../utils';
import { apiArr } from '@/api/park.js'
export default {
data() {
return {
categoryList: [
{
category_name: '全部',
category_id: 0
},
{
category_name: '待支付',
category_id: 1
},
{
category_name: '使用中',
category_id: 2
},
{
category_name: '已过期',
category_id: 3
},
],
selectedTab: 0,
orders: []
}
},
methods: {
selectTab(index, item) {
this.selectedTab = index;
this.getOrderList()
},
//
cancelOrder(order) {
console.log('取消订单:', order);
},
//
goToPayment(order) {
NavgateTo('../parkOrderDetail/index');
},
//
getOrderList() {
const params = {
user_id: uni.getStorageSync('userId'),
order_status: this.selectedTab,
}
if (params.order_status == 0) {
params.order_status = ''
}
request(apiArr.monthCardOrderList, "POST", params).then(res => {
this.orders = res.month_card_order_list;
})
},
onLoad() {
this.getOrderList()
}
},
}
</script>
<style>
@import url('./index.css');
</style>

View File

@ -0,0 +1,166 @@
/* 订单详情页面样式 */
page{
background-color: #f5f7fb;
}
/* 容器样式 */
.order-detail-container {
width: 100%;
min-height: 100vh;
}
/* 订单状态区域 */
.order-status-section {
height: 200rpx;
display: flex;
justify-content: space-between;
align-items: center;
padding: 10rpx 50rpx;
background-color: #f5f7fb;
}
.status-left {
flex: 1;
}
.status-title {
font-size: 40rpx;
font-weight: 600;
color: #333333;
display: block;
margin-bottom: 10rpx;
}
.park-name {
font-size: 28rpx;
color: #333;
}
.status-right {
width: 250rpx;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.success-icon {
width: 100%;
height: 100%;
}
/* 金额信息区域 */
.amount-section {
background-color: #ffffff;
margin-bottom: 20rpx;
}
.amount-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx 40rpx;
border-bottom: 1rpx solid #eeeeee;
}
.amount-item:last-child {
border-bottom: none;
}
.amount-label {
font-size: 30rpx;
color: #333;
font-weight: bold;
}
.amount-label2 {
font-size: 26rpx;
color: #666666;
}
.amount-value {
display: flex;
align-items: center;
}
.amount-value text {
font-size: 40rpx;
font-weight: 600;
color: #333333;
margin-right: 10rpx;
}
.arrow-icon {
width: 24rpx;
height: 24rpx;
transition: transform 0.3s;
}
/* 服务信息区域 */
.service-section {
background-color: #ffffff;
padding-bottom: 30rpx;
}
.section-title {
font-size: 32rpx;
font-weight: 600;
color: #333333;
padding: 30rpx 40rpx 20rpx;
display: block;
}
.info-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 25rpx 40rpx;
}
.info-label {
font-size: 30rpx;
color: #666666;
}
.info-item text:last-child {
font-size: 30rpx;
color: #333333;
text-align: right;
flex: 1;
margin-left: 20rpx;
}
/* 订单号容器 */
.order-number-container {
display: flex;
align-items: center;
flex: 1;
justify-content: flex-end;
}
.order-number-container text {
font-size: 30rpx;
color: #333333;
margin-right: 10rpx;
}
.copy-icon {
width: 36rpx;
height: 36rpx;
cursor: pointer;
}
/* 触摸反馈效果 */
.amount-item:active,
.copy-icon:active {
background-color: rgba(0, 0, 0, 0.05);
}
/* 适配不同屏幕尺寸的响应式调整 */
@media screen and (min-width: 768px) {
.order-detail-container {
max-width: 768px;
margin: 0 auto;
box-shadow: 0 0 20rpx rgba(0, 0, 0, 0.1);
}
}

View File

@ -0,0 +1,158 @@
<template>
<view class="order-detail-container">
<!-- 订单状态区域 -->
<view class="order-status-section">
<view class="status-left">
<text class="status-title">订单已支付</text>
<text class="park-name">{{ orderDetail.parking.parking_name }}</text>
</view>
<view class="status-right">
<image class="success-icon" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/park/park_orderOk.png"
mode="aspectFit"></image>
</view>
</view>
<!-- 金额信息区域 -->
<view class="amount-section">
<view class="amount-item" @tap="toggleAmountExpand">
<text class="amount-label">实付金额</text>
<view class="amount-value">
<text>¥{{ orderDetail.pay_method }}</text>
<u-icon :name="amountExpanded ? 'arrow-up' : 'arrow-down'" size="28"></u-icon>
</view>
</view>
<view class="amount-item" v-show="amountExpanded">
<text class="amount-label2">订单金额</text>
<text>¥{{ orderDetail.pay_method }}</text>
</view>
</view>
<!-- 电商服务区域 -->
<view class="service-section">
<text class="section-title">电商服务</text>
<view class="info-item">
<text class="info-label">车牌号码</text>
<text>{{ orderDetail.parking_record.car_number }}</text>
</view>
<view class="info-item">
<text class="info-label">交易时间</text>
<text>{{ orderDetail.pay_time }}</text>
</view>
<view class="info-item">
<text class="info-label">停车时长</text>
<text>{{ calculateParkingDuration() }}</text>
</view>
<view class="info-item">
<text class="info-label">订单类型</text>
<text>停车</text>
</view>
<view class="info-item">
<text class="info-label">支付方式</text>
<text>{{ orderDetail.pay_method == 1 ? '微信' : orderDetail.pay_method == 2 ? '支付宝' : '其他' }}</text>
</view>
<view class="info-item">
<text class="info-label">订单号</text>
<view class="order-number-container">
<text>{{ orderDetail.order_no }}</text>
<image class="copy-icon" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/myOrder/copy.png"
mode="aspectFit" @tap="copyOrderNumber"></image>
</view>
</view>
</view>
</view>
</template>
<script>
import {
isPhone,
picUrl,
request,
upload,
NavgateTo
} from '../../../utils';
import { apiArr } from '@/api/park.js'
export default {
data() {
return {
//
amountExpanded: false,
//
orderDetail: {}
}
},
methods: {
//
toggleAmountExpand() {
this.amountExpanded = !this.amountExpanded;
},
//
copyOrderNumber() {
// 使uni.setClipboardData API
uni.setClipboardData({
data: this.orderDetail.order_no,
success: () => {
uni.showToast({
title: '复制成功',
icon: 'success',
duration: 2000
});
},
fail: () => {
uni.showToast({
title: '复制失败',
icon: 'none',
duration: 2000
});
}
});
},
//
calculateParkingDuration() {
if (!this.orderDetail || !this.orderDetail.parking_record) {
return '0分钟';
}
const inTime = new Date(this.orderDetail.parking_record.in_time);
const outTime = new Date(this.orderDetail.parking_record.out_time);
//
const diffMs = outTime - inTime;
//
const diffMinutes = Math.floor(diffMs / (1000 * 60));
if (diffMinutes < 60) {
return `${diffMinutes}分钟`;
} else {
const hours = Math.floor(diffMinutes / 60);
const minutes = diffMinutes % 60;
if (minutes === 0) {
return `${hours}小时`;
} else {
return `${hours}小时${minutes}分钟`;
}
}
}
},
onLoad(options) {
const order = options.order;
if (order) {
this.orderDetail = JSON.parse(order);
}
}
}
</script>
<style>
@import url('./index.css');
</style>

View File

@ -0,0 +1,181 @@
/* 页面基础样式 */
page {
background-color: #f5f7fb;
box-sizing: border-box;
}
.order-list {
width: 100%;
}
/* 月份分组样式 */
.month-group {
}
.month-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
font-size: 26rpx;
color: #999999;
}
.month-title {
}
.month-expense {
}
/* 订单项样式 */
.order-item {
background-color: #ffffff;
padding: 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
position: relative;
border-bottom: 1rpx solid #eeeeee;
}
.order-left {
flex: 1;
display: flex;
flex-direction: column;
}
/* 订单类型样式 */
.order-type {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20rpx;
}
.order-type1 {
display: flex;
align-items: center;
}
.order-icon {
width: 40rpx;
height: 40rpx;
margin-right: 10rpx;
}
.order-type-text {
font-size: 28rpx;
color: #333333;
margin-right: 15rpx;
}
.order-status {
font-size: 24rpx;
color: #333;
}
/* 停车场信息样式 */
.order-park-info {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15rpx;
}
.order-park-name {
font-size: 28rpx;
color: #333333;
font-weight: bold;
flex: 1;
}
.order-amount {
font-size: 36rpx;
color: #333;
font-weight: bold;
margin-left: 20rpx;
}
/* 车辆信息样式 */
.order-car-info {
display: flex;
align-items: center;
margin-bottom: 15rpx;
}
.order-car-number {
font-size: 28rpx;
color: #999999;
margin-right: 15rpx;
}
.order-car-type {
font-size: 24rpx;
padding: 4rpx 16rpx;
border-radius: 20rpx;
background-color: #fff1f0;
color: #ff4d4f;
}
/* 时间样式 */
.order-time {
font-size: 24rpx;
color: #999999;
}
/* 删除按钮样式 */
.delete-button {
width: 40rpx;
height: 40rpx;
position: absolute;
bottom: 30rpx;
right: 30rpx;
}
/* 空状态样式 */
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
}
.empty-icon {
width: 200rpx;
height: 200rpx;
margin-bottom: 30rpx;
}
.empty-text {
font-size: 28rpx;
color: #999999;
}
/* 响应式调整 */
@media screen and (min-width: 768px) {
.order-item {
padding: 40rpx;
}
.month-title {
font-size: 32rpx;
}
.order-park-name {
font-size: 36rpx;
}
.order-amount {
font-size: 40rpx;
}
}
/* 触摸反馈样式 */
.order-item:active {
background-color: #f8f8f8;
}
.delete-button:active {
opacity: 0.7;
}

View File

@ -0,0 +1,173 @@
<template>
<view class="order-list">
<!-- 订单按月分组显示 -->
<view class="month-group" v-for="monthGroup in orderData" :key="monthGroup.month">
<view class="month-header">
<text class="month-title">{{ monthGroup.pay_time }}</text>
<text class="month-expense">支出¥{{ monthGroup.amount }}</text>
</view>
<!-- 订单列表 -->
<view class="order-item" v-for="order in monthGroup.orders" :key="order.id" @tap="viewOrderDetail(order)">
<view class="order-left">
<view class="order-type">
<view class="order-type1">
<image class="order-icon"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/park/park_p.png"
mode="aspectFit"></image>
<text class="order-type-text">停车</text>
</view>
<text class="order-status">{{ order.status == 1 ? '待支付' : '已支付' }}</text>
</view>
<view class="order-park-info">
<text class="order-park-name">{{ order.record_info.parking_info.parking_name }}</text>
<text class="order-amount">¥{{ order.amount.toFixed(2) }}</text>
</view>
<view class="order-car-info">
<text class="order-car-number">{{ order.record_info.car_number }}</text>
<text class="order-car-type">{{ order.record_info.car_billing_type == 1 ? '月租车' :
(order.record_info.car_billing_type == 2) ? '临时车' : '贵宾车' }}</text>
</view>
<text class="order-time">{{ order.pay_time }}</text>
</view>
<view class="delete-button" @tap.stop="deleteOrder(order)">
<u-icon name="trash" size="45rpx"></u-icon>
</view>
</view>
</view>
<!-- 空状态显示 -->
<view class="empty-state" v-if="orderData.length === 0">
<image class="empty-icon" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/park/empty_order.png"
mode="aspectFit"></image>
<text class="empty-text">暂无停车订单</text>
</view>
</view>
</template>
<script>
import {
isPhone,
picUrl,
request,
upload,
NavgateTo
} from '../../../utils';
import { apiArr } from '@/api/park.js'
export default {
data() {
return {
orderData: [],
page_num: 1,
page_size: 20,
}
},
methods: {
//
viewOrderDetail(order) {
NavgateTo('../orderDetail/index?order=' + JSON.stringify(order))
},
//
deleteOrder(order) {
const that = this;
uni.showModal({
title: '确认删除订单',
content: '你确定删除订单吗?删除之后你将无法再找回该订单',
success: function (res) {
if (res.confirm) {
const params = {
order_id: order.id
}
request(apiArr.tempParkingOrderDelete, "POST", params).then((res) => {
uni.showToast({
title: '删除成功',
icon: 'success',
duration: 2000
});
setTimeout(() => {
that.getOrderData();
}, 1000);
})
}
}
});
},
//
groupOrdersByMonth(orderList) {
const monthMap = new Map();
orderList.forEach(order => {
let payTime;
try {
payTime = new Date(order.pay_time);
} catch (error) {
payTime = new Date(order.pay_time.replace(/T/, ' ').replace(/\+.*$/, ''));
}
//
const year = payTime.getFullYear();
const month = payTime.getMonth() + 1;
const monthKey = `${year}-${month.toString().padStart(2, '0')}`;
//
if (!monthMap.has(monthKey)) {
monthMap.set(monthKey, {
month: monthKey,
pay_time: `${year}${month}`,
amount: 0,
orders: []
});
}
//
const monthGroup = monthMap.get(monthKey);
monthGroup.orders.push(order);
monthGroup.amount += parseFloat(order.amount || 0);
});
// Map
const groupedArray = Array.from(monthMap.values());
groupedArray.sort((a, b) => b.month.localeCompare(a.month));
//
groupedArray.forEach(group => {
group.amount = group.amount.toFixed(2);
});
return groupedArray;
},
//
getOrderData() {
const params = {
page_num: this.page_num,
page_size: this.page_size,
user_id: uni.getStorageSync('userId')
}
request(apiArr.tempParkingOrderList, "POST", params).then((res) => {
this.orderData = this.groupOrdersByMonth(res.order_list);
})
}
},
onLoad() {
//
this.getOrderData();
},
//
onReachBottom() {
this.page_size += 10;
this.getOrderData();
}
}
</script>
<style>
@import url('./index.css');
</style>

View File

@ -0,0 +1,151 @@
/* 订单详情页面样式 */
page {
background-color: #f5f7fb;
}
/* 容器样式 */
.order-detail-container {
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
}
/* 支付金额头部 */
.payment-header {
background-color: #ffffff;
padding: 30rpx;
border-bottom: 1rpx solid #f0f0f0;
margin-top: 20rpx;
}
.amount-info {
display: flex;
align-items: baseline;
}
.amount-symbol {
font-size: 32rpx;
color: #333333;
}
.amount-value {
font-size: 40rpx;
font-weight: bold;
color: #333333;
margin-left: 10rpx;
}
.payment-status {
font-size: 24rpx;
color: #ffffff;
background-color: #ff4219;
padding: 2rpx 15rpx;
border-radius: 30rpx;
margin-left: 15rpx;
}
/* 订单详情内容 */
.order-content {
padding: 40rpx 40rpx 0 40rpx;
background-color: #ffffff;
}
.detail-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx 0;
}
.detail-label {
font-size: 26rpx;
color: #a7a7a7;
width: 180rpx;
}
.detail-value {
font-size: 26rpx;
color: #333333;
flex: 1;
text-align: right;
}
.park-type {
color: #ff4219;
margin-right: 10rpx;
}
/* 支付方式选择 */
.payment-method {
margin-top: 20rpx;
background-color: #ffffff;
padding: 30rpx 40rpx;
}
.method-item {
display: flex;
justify-content: space-between;
align-items: center;
}
.method-info {
display: flex;
align-items: center;
}
.method-info-img {
width: 50rpx;
height: 50rpx;
margin-right: 20rpx;
}
.method-text {
font-size: 32rpx;
color: #333333;
}
/* 底部支付栏 */
.bottom-payment {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx 40rpx;
background-color: #ffffff;
border-top: 1rpx solid #f0f0f0;
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 999;
}
.total-amount {
display: flex;
align-items: baseline;
}
.total-label {
font-size: 32rpx;
color: #666666;
}
.total-value {
font-size: 40rpx;
font-weight: bold;
color: #ff4219;
margin-left: 10rpx;
}
.pay-button {
background-color: #ff4219;
color: #ffffff;
padding: 20rpx 60rpx;
border-radius: 50rpx;
}
.pay-text {
font-size: 34rpx;
font-weight: bold;
color: #ffffff;
}

View File

@ -0,0 +1,146 @@
<template>
<view class="order-detail-container">
<!-- 支付金额头部 -->
<view class="payment-header">
<view class="amount-info">
<text class="amount-symbol">¥</text>
<text class="amount-value">{{ itemObj.paymentAmount }}</text>
<text class="payment-status">待付款</text>
</view>
</view>
<!-- 订单详情内容 -->
<view class="order-content">
<!-- 停车场信息 -->
<view class="detail-item">
<text class="detail-label">停车场</text>
<view class="detail-value">
<text class="park-type">{{ itemObj.selectedParkType == 1 ? '地上' : '地下' }}</text>
<text class="park-name">{{ itemObj.headerTitle }}</text>
</view>
</view>
<!-- 车牌号 -->
<view class="detail-item">
<text class="detail-label">车牌号</text>
<text class="detail-value">{{ itemObj.selectedCarPlate }}</text>
</view>
<!-- 开始时间 -->
<view class="detail-item">
<text class="detail-label">开始时间</text>
<text class="detail-value">{{ itemObj.startTime }}</text>
</view>
<!-- 结束时间 -->
<view class="detail-item">
<text class="detail-label">结束时间</text>
<text class="detail-value">{{ itemObj.endTime }}</text>
</view>
</view>
<!-- 支付方式选择 -->
<view class="payment-method">
<view class="method-item">
<view class="method-info">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_wechat.png"
mode="aspectFit" class="method-info-img"></image>
<text class="method-text">微信支付</text>
</view>
<!-- <view class="payment-select" v-if="selectedPayment === 'wechat'">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png"
mode="aspectFit" style="width: 40rpx; height: 40rpx;"></image>
</view>
<view class="payment-select" v-else>
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png"
mode="aspectFit" style="width: 40rpx; height: 40rpx;"></image>
</view> -->
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png"
mode="aspectFit" style="width: 30rpx; height: 30rpx;"></image>
</view>
</view>
<!-- 底部支付栏 -->
<view class="bottom-payment">
<view class="total-amount">
<text class="total-label">合计¥</text>
<text class="total-value">{{ itemObj.paymentAmount }}</text>
</view>
<view class="pay-button" @tap="submitPayment">
<text class="pay-text">立即支付</text>
</view>
</view>
</view>
</template>
<script>
import {
isPhone,
picUrl,
request,
upload,
NavgateTo
} from '../../../utils';
import { apiArr } from '@/api/park.js'
export default {
data() {
return {
itemObj: {}
}
},
methods: {
//
submitPayment() {
const param = {
order_id: this.itemObj.order_id,
user_id: uni.getStorageSync('userId'),
trans_type: this.itemObj.trans_type,
}
request(apiArr.monthCardOrderPreorder, "POST", param).then(res => {
if (res && res.timeStamp && res.nonceStr && res.package && res.signType && res.paySign) {
//
uni.requestPayment({
timeStamp: res.timeStamp,
nonceStr: res.nonceStr,
package: res.package,
signType: res.signType,
paySign: res.paySign,
success: (payRes) => {
const params = {
order_id: resVal.order_id,
}
request(apiArr.monthCardOrderQuery, "POST", params).then(res => {
this.boxshadow1 = true
})
},
fail: (payErr) => {
uni.showToast({
title: payErr.errMsg == 'requestPayment:fail cancel' ? '用户取消支付' : '支付失败',
icon: 'none'
})
},
complete: () => {
//
}
})
} else {
console.error("获取支付参数失败,缺少必要参数")
uni.showToast({
title: '获取支付信息失败',
icon: 'none'
})
}
})
}
},
onLoad(options) {
this.itemObj = JSON.parse(decodeURIComponent(options.item));
}
}
</script>
<style>
@import url('./index.css');
</style>

View File

@ -0,0 +1,479 @@
page {
background-color: #f5f7fb;
overflow-y: hidden;
}
.monthly-payment-container {
box-sizing: border-box;
width: 100%;
}
.header {
display: flex;
align-items: center;
justify-content: center;
position: relative;
background-color: #fff3f1;
padding: 20rpx 0;
height: 45rpx;
}
.header-title {
font-size: 32rpx;
font-weight: 500;
color: #333333;
text-align: center;
margin-right: 10rpx;
font-weight: bold;
}
.header-arrow {
width: 30rpx;
height: 30rpx;
margin-left: 10rpx;
}
/* 搜索框样式 */
.search-box {
display: flex;
align-items: center;
background-color: #f5f7fb;
border-radius: 50rpx;
padding: 20rpx 30rpx;
margin: 20rpx 0;
}
.search-icon {
margin-right: 15rpx;
}
.search-input {
flex: 1;
font-size: 26rpx;
color: #333333;
background-color: transparent;
}
/* 下拉停车场列表样式 */
.parking-list {
background-color: #ffffff;
padding: 20rpx 30rpx;
border-bottom: 1rpx solid #f0f0f0;
border-radius: 0 0 40rpx 40rpx;
position: fixed;
top: 80rpx;
left: 0;
right: 0;
z-index: 999;
}
.overlay {
position: absolute;
top: 90rpx;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 98;
}
.parking-items {
max-height: 600rpx;
overflow-y: auto;
}
.parking-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 25rpx 0;
border-bottom: 1rpx solid #f0f0f0;
}
.parking-item:last-child {
border-bottom: none;
}
.parking-item-right {
flex: 1;
}
.parking-name {
font-size: 32rpx;
font-weight: bold;
color: #333333;
margin-bottom: 10rpx;
display: block;
}
.parking-distance {
font-size: 26rpx;
color: #999999;
margin-right: 20rpx;
}
.parking-address {
font-size: 26rpx;
color: #999999;
display: block;
margin-top: 8rpx;
}
.parking-item-left {
display: flex;
align-items: flex-start;
position: relative;
}
.parking-selected {
font-size: 40rpx;
color: #ff4219;
position: relative;
right: 30rpx;
}
.parking-spaces {
background-color: #ffeeee;
border-radius: 20rpx;
padding: 8rpx 16rpx;
display: flex;
flex-direction: column;
align-items: center;
margin-right: 30rpx;
}
.spaces-label {
font-size: 22rpx;
color: #ff4219;
margin-bottom: 4rpx;
}
.spaces-number {
font-size: 30rpx;
font-weight: bold;
color: #ff4219;
}
/* 车辆选择器 */
.changeCar {
background-color: #fff;
border-bottom: 1rpx solid #eeeeee;
position: relative;
}
.car-selector {
width: 27%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 30rpx;
height: 100rpx;
}
.selected-car-text {
font-size: 28rpx;
color: #333333;
font-weight: bold;
}
/* 车辆下拉列表样式 */
.car-dropdown {
width: 33%;
height: 600rpx;
overflow-y: auto;
background-color: #ffffff;
border-top: 1rpx solid #f0f0f0;
position: absolute;
top: 100rpx;
left: 0;
right: 0;
z-index: 999;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
margin-left: 50rpx;
border-radius: 20rpx;
}
.dropdown-arrow {
position: absolute;
top: -8px;
left: 20%;
transform: translateX(-50%);
width: 0;
height: 0;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-bottom: 8px solid #fff;
}
/* 车辆选项样式 */
.car-item {
padding: 30rpx;
font-size: 28rpx;
color: #333333;
border-bottom: 1rpx solid #f0f0f0;
text-align: center;
font-weight: bold;
}
.car-item:last-child {
border-bottom: none;
}
.car-item:active {
background-color: #f5f7fb;
}
.container {
background-color: #fff;
padding: 30rpx;
}
.title {
font-size: 30rpx;
margin-top: 10rpx;
margin-bottom: 30rpx;
text-align: center;
}
.selectColorBox {
width: 95%;
display: flex;
justify-content: space-between;
align-items: center;
margin: 30rpx auto 0;
}
.selectColor {
display: flex;
justify-content: space-between;
align-items: center;
}
.color {
margin-right: 10rpx;
}
/* 弹窗样式 */
.payIpt {
background-color: #fff;
border-radius: 30rpx 30rpx 0 0;
overflow: hidden;
}
.tit {
font-size: 32rpx;
text-align: center;
padding: 30rpx 0;
font-weight: bold;
border-bottom: 1rpx solid #eee;
}
/* 颜色列表样式 */
.color-list {
max-height: 500rpx;
padding: 20rpx 0;
}
.color-item {
font-size: 28rpx;
text-align: center;
padding: 30rpx 0;
border-bottom: 1rpx solid #f0f0f0;
}
.color-item:last-child {
border-bottom: none;
}
.color-item.active {
color: #ff4016;
}
/* 底部按钮样式 */
.popup-footer {
display: flex;
border-top: 1rpx solid #eee;
}
.cancel-btn,
.confirm-btn {
flex: 1;
text-align: center;
padding: 30rpx 0;
font-size: 32rpx;
}
.cancel-btn {
color: #666;
border-right: 1rpx solid #eee;
}
.confirm-btn {
color: #ff4016;
}
/* 查询停车费 */
.order-record {
text-align: center;
padding: 30rpx 0;
border-top: 1rpx solid #eeeeee;
background-color: #ffffff;
}
.order-record-text {
font-size: 28rpx;
color: #ff3f11;
}
/* 停车费展示部分样式 */
.cost-container {
background-color: #ffffff;
padding: 40rpx 30rpx;
margin-top: 20rpx;
}
.not-found{
text-align: center;
font-size: 28rpx;
color: #999999;
}
.cost-image{
width: 100%;
height: 150rpx;
margin-bottom: 10rpx;
}
.cost-header {
text-align: center;
margin-bottom: 20rpx;
}
.cost-title {
font-size: 32rpx;
color: #333333;
font-weight: bold;
}
.cost-title2 {
color: #999999;
margin-left: 10rpx;
}
.cost-amount {
display: flex;
align-items: baseline;
justify-content: center;
margin-bottom: 20rpx;
font-size: 40rpx;
color: #ff3f11;
font-weight: bold;
}
.amount-symbol {
margin-right: 10rpx;
}
.amount-number {
}
.cost-info {
margin-bottom: 30rpx;
}
.info-item {
display: flex;
justify-content: center;
margin-bottom: 15rpx;
font-size: 24rpx;
color: #999999;
}
.info-label {
margin-right: 10rpx;
}
.info-value {
}
.notice {
background-color: #fff8f4;
padding: 20rpx;
border-radius: 10rpx;
margin-bottom: 30rpx;
}
.notice-text {
font-size: 26rpx;
color: #999999;
text-align: center;
display: block;
}
.payment-methods {
margin-bottom: 40rpx;
}
.payment-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx 0;
border-bottom: 1rpx solid #f0f0f0;
position: relative;
}
.payment-item:last-child {
border-bottom: none;
}
.payment-item-content {
display: flex;
align-items: center;
}
.payment-icon {
width: 50rpx;
height: 50rpx;
margin-right: 20rpx;
border-radius: 50%;
}
.payment-name {
font-size: 30rpx;
color: #333333;
font-weight: bold;
}
.payment-selected {
width: 30rpx;
height: 30rpx;
border: 3rpx solid #ff3f11;
border-radius: 50%;
position: absolute;
right: 50rpx;
}
.payment-selected::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 15rpx;
height: 15rpx;
background-color: #ff3f11;
border-radius: 50%;
}
.pay-button {
width: 70%;
margin: 0 auto;
background-color: #ff370b;
color: #ffffff;
text-align: center;
padding: 20rpx 0;
font-size: 32rpx;
font-weight: bold;
border-radius: 50rpx;
}

View File

@ -0,0 +1,489 @@
<template>
<view class="monthly-payment-container">
<!-- 顶部标题 -->
<view class="header" @tap="toggleDropdown">
<text class="header-title">{{ headerTitle }}</text>
<u-icon :name="isDropdownOpen ? 'arrow-up' : 'arrow-down'" size="28"></u-icon>
</view>
<!-- 下拉停车场列表 -->
<view v-if="isDropdownOpen" class="parking-list">
<!-- 搜索框 -->
<view class="search-box">
<u-icon name="search" size="40" color="#999" class="search-icon" />
<input type="text" placeholder="搜索停车场" class="search-input" />
</view>
<!-- 停车场列表 -->
<view class="parking-items">
<view class="parking-item" v-for="(park, index) in parkingLots" :key="index"
@tap="selectParkingLot(park)">
<view class="parking-item-left">
<view class="parking-spaces">
<text class="spaces-label">剩余车位</text>
<text class="spaces-number">{{ park.space_count }}</text>
</view>
</view>
<view class="parking-item-right">
<text class="parking-name">{{ park.parking_name }}</text>
<text class="parking-distance">{{ park.distance }}km</text>
<text class="parking-address">{{ park.address }}</text>
</view>
<view class="parking-selected" v-if="park.isSelected"></view>
</view>
</view>
</view>
<view>
<view class="overlay" v-if="isDropdownOpen" />
<!-- 车辆选择区域 -->
<view class="changeCar">
<view class="car-selector" @tap="toggleCarDropdown">
<text class="selected-car-text">{{ selectedCar || '选择车辆' }}</text>
<u-icon :name="isCarDropdownOpen ? 'arrow-up' : 'arrow-down'" size="28"></u-icon>
</view>
<!-- 车辆下拉列表 -->
<view v-if="isCarDropdownOpen" class="car-dropdown">
<view class="dropdown-arrow"></view>
<view class="car-item" v-for="(car, index) in cars" :key="index" @click="selectCar(car)">
{{ car.car_number }}
</view>
</view>
</view>
<view class="container">
<view class="title">请输入车牌号码</view>
<car-number-input @numberInputResult="numberInputResult" :defaultStr="defaultNum"
ref="carNumberInput" />
<view class="selectColorBox" @click="show = true">
<view>车牌颜色</view>
<view class="selectColor">
<view class="color">{{ color }}</view>
<u-icon name="arrow-right" size="25"></u-icon>
</view>
</view>
</view>
<view class="order-record" @tap="selectCost">
<text class="order-record-text">查询停车费>></text>
</view>
<!-- 停车费展示部分 -->
<view v-if="showCost1" class="cost-container">
<view>
<image class="cost-image"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/park/park_orderLoading.png"
mode="aspectFit" />
</view>
<view class="cost-header">
<text class="cost-title">{{ parkingLotName }} <text class="cost-title2">待支付</text></text>
</view>
<view class="cost-amount">
<text class="amount-symbol">¥</text>
<text class="amount-number">{{ costAmount }}</text>
</view>
<view class="cost-info">
<view class="info-item">
<text class="info-label">车牌号</text>
<text class="info-value">{{ currentCarNumber }}</text>
</view>
<view class="info-item">
<text class="info-label">进场时间</text>
<text class="info-value">{{ entryTime }}</text>
</view>
<view class="info-item">
<text class="info-label">计费时间</text>
<text class="info-value">{{ billingTime }}</text>
</view>
</view>
<view class="notice">
<text class="notice-text"> 请于付款后15分钟内离场否则将加收停车费</text>
</view>
<view class="payment-methods">
<view class="payment-item" :class="{ 'selected': paymentMethod === 'wechat' }"
@tap="selectPayment('wechat')">
<view class="payment-item-content">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_wechat.png"
mode="aspectFit" class="payment-icon"></image>
<text class="payment-name">微信支付</text>
</view>
<view v-if="paymentMethod === 'wechat'" class="payment-selected"></view>
</view>
</view>
<view class="pay-button" @tap="confirmPayment">立即付款</view>
</view>
<view v-if="showCost2" class="cost-container not-found">
未找到停车记录
</view>
<!-- 选择车牌颜色 -->
<u-popup :show="show" :round="30" mode="bottom" @close="onClose">
<view class="payIpt">
<view class="tit">选择车牌颜色</view>
<!-- 颜色选择列表 -->
<scroll-view class="color-list" scroll-y>
<view class="color-item" :class="{ 'active': selectedColorIndex === index }"
v-for="(item, index) in colorOptions" :key="index" @click="selectColor(index)">
{{ item }}
</view>
</scroll-view>
<!-- 底部按钮 -->
<view class="popup-footer">
<view class="cancel-btn" @click="onClose">取消</view>
<view class="confirm-btn" @click="confirmColor">确定</view>
</view>
</view>
</u-popup>
</view>
</view>
</template>
<script>
import {
isPhone,
picUrl,
request,
upload,
NavgateTo
} from '../../../utils';
import { apiArr } from '@/api/park.js'
export default {
data() {
return {
isDropdownOpen: false,
headerTitle: '请选择停车场',
parkingLots: [],
defaultNum: '',
color: '请选择',
show: false,
//
colorOptions: ['蓝牌', '黄牌', '黑牌', '白牌', '绿牌', '渐变绿底黑字', '黄绿双拼底黑字'],
//
selectedColorIndex: -1,
//
isCarDropdownOpen: false,
selectedCar: '',
cars: [],
//
showCost1: false,
showCost2: false,
parkingLotName: '',
costAmount: '',
currentCarNumber: '',
entryTime: '',
billingTime: '',
paymentMethod: 'wechat',
// ID
timerId: null
}
},
onLoad() {
this.getParkList();
},
//
onUnload() {
if (this.timerId) {
clearInterval(this.timerId);
this.timerId = null;
}
},
methods: {
//
toggleDropdown() {
this.isCarDropdownOpen = false
this.isDropdownOpen = !this.isDropdownOpen;
},
//
selectParkingLot(park) {
//
this.parkingLots.forEach(item => {
item.isSelected = false;
});
//
park.isSelected = true;
//
this.$set(this, 'headerTitle', park.parking_name);
//
this.isDropdownOpen = false;
},
numberInputResult(e) {
this.defaultNum = e;
// 使$nextTickDOM
this.$nextTick(() => {
if (this.$refs.carNumberInput) {
// inputList
const valList = e.split("");
if (e == '其他车辆') {
for (let i = 0; i < 8; i++) {
this.$refs.carNumberInput.inputList[i] = ' ';
}
} else {
for (let i in valList) {
this.$refs.carNumberInput.inputList[i] = valList[i];
}
}
//
this.$refs.carNumberInput.$forceUpdate();
}
});
},
onClose() {
this.show = false;
},
//
updateBillingTime() {
const entryDateTime = new Date(this.entryTime);
const currentDateTime = new Date();
const diff = currentDateTime - entryDateTime;
//
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((diff % (1000 * 60)) / 1000);
//
let timeStr = '';
if (days > 0) {
timeStr += days + '天';
}
if (hours > 0 || days > 0) {
timeStr += hours + '时';
}
if (minutes > 0 || hours > 0 || days > 0) {
timeStr += minutes + '分';
}
timeStr += seconds + '秒';
this.billingTime = timeStr;
},
//
selectColor(index) {
this.selectedColorIndex = index;
},
//
confirmColor() {
if (this.selectedColorIndex !== -1) {
this.color = this.colorOptions[this.selectedColorIndex];
}
this.show = false;
},
//
toggleCarDropdown() {
this.isCarDropdownOpen = !this.isCarDropdownOpen;
},
//
selectCar(car) {
this.selectedCar = car.car_number;
this.isCarDropdownOpen = false;
if (car.car_number == '其他车辆') {
NavgateTo('../addCar/index')
}
this.numberInputResult(car.car_number)
},
//
selectCost() {
const selectedParkingLot = this.parkingLots.find(park => park.isSelected);
if (!selectedParkingLot) {
uni.showToast({
title: '请先选择停车场',
icon: 'none'
});
return;
}
if (!this.defaultNum) {
uni.showToast({
title: '请输入车牌号',
icon: 'none'
});
return;
}
const params = {
parking_id: selectedParkingLot.id,
car_number: this.defaultNum,
}
request(apiArr.tempParkingInfo, "POST", params).then((res) => {
if (res) {
this.parkingLotName = res.parking.parking_name;
this.costAmount = res.fee_amount;
this.currentCarNumber = res.car_number;
this.entryTime = res.in_time;
//
if (this.timerId) {
clearInterval(this.timerId);
this.timerId = null;
}
if (res.car_billing_type == 1) {
this.billingTime = '月租车';
} else if (res.car_billing_type == 2) {
this.billingTime = '临时车';
} else {
//
this.updateBillingTime();
//
this.timerId = setInterval(() => {
this.updateBillingTime();
}, 1000);
}
this.showCost1 = true;
} else {
this.showCost2 = true;
}
})
},
//
selectPayment(method) {
this.paymentMethod = method;
},
//
confirmPayment() {
const selectedParkingLot = this.parkingLots.find(park => park.isSelected);
const params = {
car_number: this.defaultNum,
parking_id: selectedParkingLot.id,
user_id: uni.getStorageSync('userId'),
}
request(apiArr.tempParkingCreate, "POST", params).then((resVal) => {
// trans_type
// : 71, App: 51
const systemInfo = uni.getSystemInfoSync();
let trans_type = 51; // App
//
if (systemInfo.platform === 'devtools' || systemInfo.platform === 'unknown') {
trans_type = 71; //
}
//
// #ifdef MP
trans_type = 71; //
// #endif
// #ifdef APP-PLUS
trans_type = 51; // App
// #endif
const param = {
order_id: resVal.order_id,
user_id: uni.getStorageSync('userId'),
trans_type: trans_type
}
request(apiArr.tempParkingOrderPreorder, "POST", param).then(res => {
if (res && res.timeStamp && res.nonceStr && res.package && res.signType && res.paySign) {
//
uni.requestPayment({
timeStamp: res.timeStamp,
nonceStr: res.nonceStr,
package: res.package,
signType: res.signType,
paySign: res.paySign,
success: (payRes) => {
const params = {
order_id: resVal.order_id,
}
request(apiArr.tempParkingOrderQuery, "POST", params).then(res => {
this.boxshadow1 = true
})
},
fail: (payErr) => {
uni.showToast({
title: payErr.errMsg == 'requestPayment:fail cancel' ? '用户取消支付' : '支付失败',
icon: 'none'
})
//
}
})
} else {
console.error("获取支付参数失败,缺少必要参数")
uni.showToast({
title: '获取支付信息失败',
icon: 'none'
})
}
})
})
},
//
getCarList() {
const params = {
user_id: uni.getStorageSync('userId')
}
request(apiArr.carList, "POST", params).then((res) => {
this.cars = res.car_list;
this.cars.push({
car_number: '其他车辆'
})
})
},
//
getParkList() {
request(apiArr.parkList, "POST", {}).then((res) => {
//
this.parkingLots = res.parking_list.map(park => {
try {
let locationData = uni.getStorageSync('location');
if (locationData) {
let location = locationData;
const userLat = location.lat;
const userLng = location.lng;
const parkLat = park.lat;
const parkLng = park.lng;
// 使Haversine
const R = 6371; //
const dLat = (parkLat - userLat) * Math.PI / 180;
const dLng = (parkLng - userLng) * Math.PI / 180;
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(userLat * Math.PI / 180) * Math.cos(parkLat * Math.PI / 180) *
Math.sin(dLng / 2) * Math.sin(dLng / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
const distance = (R * c).toFixed(1);
//
return { ...park, distance };
}
return park;
} catch (error) {
console.error('计算停车场距离时出错:', error);
return park;
}
});
//
this.parkingLots.sort((a, b) => {
//
if (a.distance !== undefined && b.distance !== undefined) {
return a.distance - b.distance;
}
if (a.distance !== undefined) return -1;
if (b.distance !== undefined) return 1;
return 0;
});
})
},
},
onShow() {
this.getCarList();
}
}
</script>
<style>
@import url('./index.css');
</style>

View File

@ -0,0 +1,193 @@
page {
background-color: #f6f7fb;
}
.pay-container {
padding: 30rpx;
}
.header {
text-align: center;
padding: 30rpx 0;
background-color: #fff;
border-radius: 10rpx;
margin-bottom: 30rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
}
.title {
font-size: 40rpx;
font-weight: bold;
color: #333;
}
.form-container {
background-color: #fff;
border-radius: 10rpx;
padding: 30rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
}
.form-item {
margin-bottom: 40rpx;
}
.label {
font-size: 28rpx;
color: #666;
margin-bottom: 15rpx;
display: block;
}
.input {
width: 100%;
height: 80rpx;
border: 2rpx solid #e0e0e0;
border-radius: 8rpx;
padding: 0 20rpx;
box-sizing: border-box;
font-size: 30rpx;
}
.input:focus {
border-color: #ff6c00;
outline: none;
}
.operator-list {
display: flex;
justify-content: space-between;
margin-top: 20rpx;
}
.operator-item {
width: 200rpx;
height: 120rpx;
border: 2rpx solid #e0e0e0;
border-radius: 8rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 10rpx;
box-sizing: border-box;
}
.operator-item.active {
border-color: #ff6c00;
background-color: #ff6a0013;
}
.operator-icon {
width: 50rpx;
height: 50rpx;
margin-bottom: 10rpx;
}
.operator-item text {
font-size: 26rpx;
color: #333;
}
/* 自动识别运营商显示样式 */
.selected-operator {
display: flex;
align-items: center;
padding: 20rpx;
border: 2rpx solid #e0e0e0;
border-radius: 8rpx;
background-color: #f9f9f9;
}
.selected-operator .operator-icon {
width: 60rpx;
height: 60rpx;
margin-right: 20rpx;
margin-bottom: 0;
}
.selected-operator text {
font-size: 30rpx;
color: #333;
}
.change-btn {
margin-left: auto;
color: #ff6c00;
font-size: 28rpx;
padding: 10rpx 20rpx;
border-radius: 6rpx;
}
.amount-input {
margin-bottom: 20rpx;
}
.amount-list {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.amount-item {
width: 160rpx;
height: 70rpx;
background-color: #f5f5f5;
border-radius: 8rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
color: #333;
margin-bottom: 20rpx;
}
.amount-item:active {
background-color: #e0e0e0;
}
.pay-btn {
width: 100%;
height: 90rpx;
background-color: #ff6c00;
color: #fff;
border-radius: 45rpx;
font-size: 32rpx;
line-height: 90rpx;
text-align: center;
margin-top: 40rpx;
}
.pay-btn:disabled {
background-color: #cccccc;
color: #666666;
}
/* 响应式适配 */
@media screen and (min-width: 768px) {
.pay-container {
max-width: 600rpx;
margin: 0 auto;
padding: 40rpx;
}
.header {
padding: 40rpx 0;
}
.title {
font-size: 48rpx;
}
.form-container {
padding: 40rpx;
}
}
/* 错误提示样式 */
.error-message {
color: #ff4d4f;
font-size: 26rpx;
margin-top: 10rpx;
display: block;
}

View File

@ -0,0 +1,156 @@
<template>
<view class="pay-container">
<!-- <view class="header">
<text class="title">手机缴费</text>
</view> -->
<view class="form-container">
<!-- 手机号码输入 -->
<view class="form-item">
<view class="label">手机号码</view>
<input class="input" type="number" v-model="phoneNumber" placeholder="请输入手机号码" maxlength="11" @input="onPhoneInput" />
</view>
<!-- 运营商选择 -->
<view class="form-item" v-if="showOperatorSelect">
<view class="label">选择运营商</view>
<view class="operator-list">
<view class="operator-item" :class="{ 'active': selectedOperator === 'chinaMobile' }" @click="selectOperator('chinaMobile')">
<image class="operator-icon" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/payTheFees_yidong.png" mode="aspectFit" />
<text>移动</text>
</view>
<view class="operator-item" :class="{ 'active': selectedOperator === 'chinaUnicom' }" @click="selectOperator('chinaUnicom')">
<image class="operator-icon" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/payTheFees_liantong.png" mode="aspectFit" />
<text>中国联通</text>
</view>
<view class="operator-item" :class="{ 'active': selectedOperator === 'chinaTelecom' }" @click="selectOperator('chinaTelecom')">
<image class="operator-icon" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/payTheFees_dianxin.png" mode="aspectFit" />
<text>中国电信</text>
</view>
</view>
</view>
<!-- 自动识别的运营商显示 -->
<view class="form-item" v-else-if="selectedOperator">
<view class="label">运营商</view>
<view class="selected-operator">
<image class="operator-icon" :src="getOperatorIcon()" mode="aspectFit" />
<text>{{ getOperatorName() }}</text>
<text class="change-btn" @click="showOperatorSelect = true">更换</text>
</view>
</view>
<!-- 缴费金额 -->
<view class="form-item">
<view class="label">缴费金额</view>
<input class="input amount-input" type="number" v-model="amount" placeholder="请输入金额" />
<view class="amount-list">
<view class="amount-item" v-for="item in amountOptions" :key="item" @click="selectAmount(item)">{{ item }}</view>
</view>
</view>
<!-- 缴费按钮 -->
<button class="pay-btn" :disabled="!isFormValid" @click="handlePay">立即缴费</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
phoneNumber: '',
selectedOperator: '',
amount: '',
amountOptions: [10, 20, 30, 50, 100, 200],
showOperatorSelect: false
}
},
computed: {
isFormValid() {
// 110
return this.phoneNumber.length === 11 &&
this.selectedOperator &&
this.amount &&
Number(this.amount) > 0;
}
},
methods: {
onPhoneInput() {
if (this.phoneNumber.length >= 3) {
this.autoDetectOperator();
}
},
autoDetectOperator() {
// 34
const prefix = this.phoneNumber.substring(0, 3);
const prefix4 = this.phoneNumber.substring(0, 4);
//
const chinaMobilePrefixes = ['134', '135', '136', '137', '138', '139', '147', '150', '151', '152', '157', '158', '159', '178', '182', '183', '184', '187', '188', '198'];
//
const chinaUnicomPrefixes = ['130', '131', '132', '145', '155', '156', '166', '175', '176', '185', '186'];
//
const chinaTelecomPrefixes = ['133', '149', '153', '173', '177', '180', '181', '189', '199'];
if (chinaMobilePrefixes.includes(prefix) || chinaMobilePrefixes.includes(prefix4)) {
this.selectedOperator = 'chinaMobile';
this.showOperatorSelect = false;
} else if (chinaUnicomPrefixes.includes(prefix) || chinaUnicomPrefixes.includes(prefix4)) {
this.selectedOperator = 'chinaUnicom';
this.showOperatorSelect = false;
} else if (chinaTelecomPrefixes.includes(prefix) || chinaTelecomPrefixes.includes(prefix4)) {
this.selectedOperator = 'chinaTelecom';
this.showOperatorSelect = false;
} else {
//
this.showOperatorSelect = true;
}
},
selectOperator(operator) {
this.selectedOperator = operator;
this.showOperatorSelect = false;
},
selectAmount(amount) {
this.amount = amount;
},
handlePay() {
if (this.isFormValid) {
uni.showToast({
title: '缴费成功',
icon: 'success'
});
}
},
getOperatorName() {
switch (this.selectedOperator) {
case 'chinaMobile':
return '中国移动';
case 'chinaUnicom':
return '中国联通';
case 'chinaTelecom':
return '中国电信';
default:
return '';
}
},
getOperatorIcon() {
switch (this.selectedOperator) {
case 'chinaMobile':
return 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/payTheFees_yidong.png';
case 'chinaUnicom':
return 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/payTheFees_liantong.png';
case 'chinaTelecom':
return 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/payTheFees_dianxin.png';
default:
return '';
}
}
}
}
</script>
<style>
@import url("./index.css");
</style>

View File

@ -1,52 +1,52 @@
<template>
<view class="container">
<div class="row">
<div class="row_label"><span>*</span>收货人</div>
<div class="row_con">
<view class="row">
<view class="row_label"><span>*</span>收货人</view>
<view class="row_con">
<u--input placeholder="请输入姓名" clearable border="none" v-model="name"></u--input>
</div>
</div>
</view>
</view>
<div class="row">
<div class="row_label"><span>*</span>手机号</div>
<div class="row_con">
<view class="row">
<view class="row_label"><span>*</span>手机号</view>
<view class="row_con">
<u--input type="number" placeholder="请输入手机号" clearable border="none" v-model="phone" ></u--input>
</div>
</div>
</view>
</view>
<div class="tabList">
<div class="tabItem" :class="{ 'active': tab == 0 }" @click="changeTab(0)">地图选址</div>
<div class="tabItem" :class="{ 'active': tab == 1 }" @click="changeTab(1)">地区选择</div>
</div>
<view class="tabList">
<view class="tabItem" :class="{ 'active': tab == 0 }" @click="changeTab(0)">地图选址</view>
<view class="tabItem" :class="{ 'active': tab == 1 }" @click="changeTab(1)">地区选择</view>
</view>
<div class="tabItems" v-if="tab == 0">
<div class="row">
<div class="row_label">地址</div>
<div class="row_con">
<div class="choseAddress" @click="chooseAddress">
<view class="tabItems" v-if="tab == 0">
<view class="row">
<view class="row_label">地址</view>
<view class="row_con">
<view class="choseAddress" @click="chooseAddress">
<text v-if="showOrientation">请选择地址</text>
<text v-if="!showOrientation" style="color: #000;">{{ orientation.region }} {{orientation.district}}</text>
</div>
</view>
<div class="currentAddress" v-if="showOrientation">
<div class="currentAddress1">
<div class="currentAddress1_left">当前定位{{orientation.district}}</div>
<div class="currentAddress1_right" @click="headerConfirmClick">使用</div>
</div>
<div class="currentAddress2">{{orientation.region}}</div>
</div>
</div>
</div>
<div class="row">
<div class="row_label">门牌号</div>
<div class="row_con noneborder">
<view class="currentAddress" v-if="showOrientation">
<view class="currentAddress1">
<view class="currentAddress1_left">当前定位{{orientation.district}}</view>
<view class="currentAddress1_right" @click="headerConfirmClick">使用</view>
</view>
<view class="currentAddress2">{{orientation.region}}</view>
</view>
</view>
</view>
<view class="row">
<view class="row_label">门牌号</view>
<view class="row_con noneborder">
<u--input placeholder="例6栋201室" clearable border="none" v-model="houseNumber"></u--input>
<!-- <div class="tips">记得完善门牌号</div> -->
</div>
</div>
</div>
<!-- <view class="tips">记得完善门牌号</view> -->
</view>
</view>
</view>
<div class="tabItems" v-if="tab == 1">
<view class="tabItems" v-if="tab == 1">
<view>
<picker-view indicator-style="height: 50px;" style="width: 100%; height: 400rpx;" :value="id"
@change="bindChange">
@ -65,27 +65,27 @@
</picker-view>
</view>
<div class="row">
<div class="row_label"><span>*</span>详细地址</div>
<div class="row_con">
<view class="row">
<view class="row_label"><span>*</span>详细地址</view>
<view class="row_con">
<u--input placeholder="小区、门牌号" clearable border="none" v-model="houseNumber"></u--input>
</div>
</div>
</div>
</view>
</view>
</view>
<div class="line"></div>
<div class="isdef" @click="headerSettingDefaultAddressClick">
<div class="isdef_left">
<div class="isdef_left1">设置默认地址</div>
<div class="isdef_left2">提醒下单时会优先选择</div>
</div>
<div class="isdef_right">
<view class="line"></view>
<view class="isdef" @click="headerSettingDefaultAddressClick">
<view class="isdef_left">
<view class="isdef_left1">设置默认地址</view>
<view class="isdef_left2">提醒下单时会优先选择</view>
</view>
<view class="isdef_right">
<img v-if="isDefault == 2" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png" alt="" />
<img v-if="isDefault == 1" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png" alt="" />
</div>
</div>
</view>
</view>
<div class="btn" @click="headerSubmitClick">确定</div>
<view class="btn" @click="headerSubmitClick">确定</view>
</view>
</template>
@ -222,6 +222,7 @@ export default {
})
return
}
console.log("🚀 ~ headerSubmitClick ~ type:", this.type)
if(this.type === 'edit') {
const res = await request(apiArr2.updateAddress, "POST", {
user_id: this.id,

View File

@ -1,44 +1,44 @@
<template>
<view class="container">
<div class="hasAddress">
<div class="addressList">
<div class="addressItem" v-for="item, index in list" :key="index" :class="{ 'addressItem_def': index == 0 }">
<div class="addressItem_top">
{{item.name}} {{item.phone}} <div v-if="item.is_default === 1" class="is_def">默认</div>
</div>
<div class="addressItem_mid">{{item.address}}{{ item.house_number }}</div>
<div class="addressItem_footer">
<div class="addressItem_footer_left">
<div v-if="item.is_default !== 1" @click="headerSettingDefault(item.id)">
<view class="hasAddress">
<view class="addressList">
<view class="addressItem" v-for="item, index in list" :key="index" :class="{ 'addressItem_def': index == 0 }">
<view class="addressItem_top">
{{item.name}} {{item.phone}} <view v-if="item.is_default === 1" class="is_def">默认</view>
</view>
<view class="addressItem_mid">{{item.address}}{{ item.house_number }}</view>
<view class="addressItem_footer">
<view class="addressItem_footer_left">
<view v-if="item.is_default !== 1" @click="headerSettingDefault(item.id)">
<image src="http://192.168.0.172:5500/7.15/shop_checked1.png"></image>
设为默认
</div>
</view>
<div v-if="item.is_default === 1">
<view v-if="item.is_default === 1">
<image src="http://192.168.0.172:5500/7.15/shop_checked2.png"></image>
已默认
</div>
</view>
</div>
<div class="addressItem_footer_right">
<div class="btn1" @click="deleteItem(item.id )">删除</div>
<div class="btn2" @click="editItem(item)">修改</div>
</div>
</div>
</div>
</div>
<div class="footer">
<div class="footerBtn" @click="addAddress">新增收货地址</div>
</div>
</div>
</view>
<view class="addressItem_footer_right">
<view class="btn1" @click="deleteItem(item.id )">删除</view>
<view class="btn2" @click="editItem(item)">修改</view>
</view>
</view>
</view>
</view>
<view class="footer">
<view class="footerBtn" @click="addAddress">新增收货地址</view>
</view>
</view>
<div class="empty" v-if="false">
<view class="empty" v-if="false">
<image src="http://192.168.0.172:5500/7.15/shop_noAdd.png"></image>
<div class="empty_text">暂无收货地址</div>
<view class="empty_text">暂无收货地址</view>
<div class="addBtn" @click="addAddress">添加收货地址</div>
</div>
<view class="addBtn" @click="addAddress">添加收货地址</view>
</view>
</view>
</template>
@ -104,7 +104,7 @@ export default {
},
async init() {
const res = await request(apiArr.addressList, 'POST', {});
const res = await request(apiArr.addAddressList, 'POST', {});
this.list = res.address_list;
}
},

View File

@ -0,0 +1,102 @@
page {
background-color: #f6f7fb;
}
.credits-exchange-container {
padding: 20rpx;
min-height: 100vh;
}
.page-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
text-align: center;
}
.goods-list {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.goods-item {
width: 48%;
background-color: #fff;
border-radius: 10rpx;
overflow: hidden;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
}
.goods-image {
width: 100%;
height: 300rpx;
overflow: hidden;
}
.goods-image image {
width: 100%;
height: 100%;
object-fit: cover;
}
.goods-info {
padding: 20rpx;
}
.goods-name {
font-size: 26rpx;
color: #333;
margin-bottom: 10rpx;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
height: 64rpx;
}
.goods-points {
font-size: 32rpx;
color: #e64340;
font-weight: bold;
}
.goods-points text {
font-size: 24rpx;
}
/* 适配不同屏幕尺寸 */
@media screen and (min-width: 768px) {
.credits-exchange-container {
padding: 30rpx;
}
.page-title {
font-size: 44rpx;
margin-bottom: 30rpx;
}
.goods-item {
width: 32%;
margin-bottom: 30rpx;
}
.goods-image {
height: 400rpx;
}
.goods-name {
font-size: 32rpx;
height: 72rpx;
}
.goods-points {
font-size: 36rpx;
}
.goods-points text {
font-size: 28rpx;
}
}

View File

@ -0,0 +1,68 @@
<template>
<view class="credits-exchange-container">
<view class="goods-list">
<view class="goods-item" v-for="(item, index) in goodsList" :key="index">
<view class="goods-image">
<image :src="item.image" mode="aspectFill"></image>
</view>
<view class="goods-info">
<view class="goods-name">{{ item.name }}</view>
<view class="goods-points">{{ item.points }} <text>积分</text></view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'CreditsExchange',
data() {
return {
goodsList: [
{
id: 1,
name: '兰蔻持妆粉底液 持久遮瑕保湿',
points: 31800,
image: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_icon5.png'
},
{
id: 2,
name: '福临门一级小磨香油400ML',
points: 999999,
image: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_icon5.png'
},
{
id: 3,
name: '九阳Joyoung不用翻面 空气炸锅',
points: 999999,
image: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_icon5.png'
},
{
id: 4,
name: '福临门礼包(福临门自然香五常大米)',
points: 999999,
image: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_icon5.png'
},
{
id: 5,
name: '福临门礼包(福临门自然香五常大米)',
points: 999999,
image: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_icon5.png'
},
{
id: 6,
name: '福临门礼包(福临门自然香五常大米)',
points: 999999,
image: 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_icon5.png'
}
]
};
}
};
</script>
<style>
@import url("./index.css");
</style>

View File

@ -108,6 +108,7 @@ image {
color: #C7C7C7;
margin-left: 30rpx;
padding-bottom: 4rpx;
text-decoration: line-through;
}
.GGBox {
@ -332,6 +333,15 @@ image {
display: flex;
}
.shadowBox1Item_btn{
width: 150rpx;
height: 170rpx;
opacity:0;
position: absolute;
left: 100rpx;
top: 40rpx;
}
.shadowBox1Item {
flex: 1;
display: flex;
@ -597,15 +607,17 @@ image {
margin: 5rpx 5rpx 0 5rpx;
}
.itemSizeBox {
margin: 30rpx;
}
.itemSize {
width: 30%;
font-size: 26rpx;
color: #333;
background: #F6F7FB;
border-radius: 40rpx;
padding: 10rpx 15rpx;
white-space: nowrap;
margin:20rpx 30rpx;
}
.itemSize_active {
@ -618,7 +630,6 @@ image {
height: 100rpx;
margin-right: 30rpx;
border-radius: 20rpx;
border:1rpx solid red;
}
.itemSize_top {

View File

@ -39,12 +39,15 @@
{{ item.goods_spec }} / {{ item.goods_unit }}
</view>
</view>
<view class="GG_rigth">
<view class="GG_rigth" @click="showSizePopup">
{{ info.commodity_goods_info_list.length }}<u-icon size="26rpx" name="arrow-right"></u-icon>
</view>
</view>
<view class="Tit"><div class="isDay" v-if="currentGG.is_same_day">当日达</div><div>{{ currentGG.goods_name }}</div></view>
<view class="Tit">
<view class="isDay" v-if="currentGG.is_same_day">当日达</view>
<view>{{ currentGG.goods_name }}</view>
</view>
<view class="Msg">{{ currentGG.commodity_brief }}</view>
<view class="fenge"></view>
@ -92,22 +95,22 @@
<!-- 评价部分 -->
<view class="reviews-section">
<view class="reviews-header">
<h3>评价({{ comments.length }})</h3>
<h3>评价({{ comments.length ? comments.length : 0 }})</h3>
<view class="view-all" @click="showPopup">查看全部 ></view>
</view>
<view class="reviews-list" v-if="comments.length > 0">
<view class="review-item" v-for="(comment, index) in comments" :key="index">
<view class="review-user">
<image :src="comment.avatar" class="user-avatar"></image>
<image :src="comment.mpuser.avatar" class="user-avatar"></image>
<view class="user-info">
<view class="user-name">{{ comment.username }}</view>
<view class="user-name">{{ comment.mpuser.nick_name }}</view>
</view>
<view class="review-time">{{ comment.time }}</view>
<view class="review-time">{{ comment.create_time }}</view>
</view>
<view class="user-purchase">已购 {{ comment.product }}</view>
<view class="review-content">{{ comment.content }}</view>
<view class="review-images" v-if="comment.images.length > 0">
<image :src="img" class="review-img" v-for="(img, idx) in comment.images" :key="idx"></image>
<view class="user-purchase">已购 {{ comment.goods_name.goods_name }}{{ comment.goods_name.goods_spec }}</view>
<view class="review-content">{{ comment.user_review }}</view>
<view class="review-images" v-if="comment.review_image.length > 0">
<image :src="img" class="review-img" v-for="(img, idx) in comment.review_image" :key="idx"></image>
</view>
</view>
</view>
@ -178,7 +181,8 @@
<view class="car_right" v-if="info.commodity_goods_info_list[currentGGIndex].cart_count.count > 0">
<!-- <view class="car_right"> -->
<u-number-box v-model="info.commodity_goods_info_list[currentGGIndex].cart_count.count" @change="changeCar" min="0">
<u-number-box v-model="info.commodity_goods_info_list[currentGGIndex].cart_count.count"
@change="changeCar" min="0">
<!-- <u-number-box > -->
<view slot="minus" class="minus">
<u-icon name="minus" size="36" bold></u-icon>
@ -186,7 +190,7 @@
<text slot="input" style="width: 200rpx; text-align: center" class="input">
{{ info.commodity_goods_info_list[currentGGIndex].cart_count.count }}
</text>
<<!-- text slot="input" style="width: 200rpx; text-align: center" class="input">
<!-- text slot="input" style="width: 200rpx; text-align: center" class="input">
{{info.commodity_goods_info_list[currentGGIndex]}}
</text> -->
<view slot="plus" class="plus">
@ -199,6 +203,7 @@
<!-- 分享 -->
<view class="shadow" @click.stop="changeShadow" v-if="boxshadow1">
<view class="shadowBox1">
<button class="shadowBox1Item_btn" open-type="share" bindtap="onShareButtonClick"/>
<view class="shadowBox1Item" @click="shareFriend">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_WX.png"
mode="aspectFill"></image>
@ -217,15 +222,18 @@
<view class="shadowBox_img">
<view class="boxshadow_tit">今日商品推荐</view>
<view class="boxshadow_img">
<image
<image v-if="currentGG && currentGG.commodity_pic && currentGG.commodity_pic.length > 0"
:src="picUrl + currentGG.commodity_pic[0]">
</image>
<image v-else
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_share_img.png">
</image>
</view>
<view class="line"></view>
<view class="shadowBoxInfo">
<view class="shadowboxInfo_left">二维码</view>
<image class="shadowboxInfo_left" :src="qrcodePath || 'https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/qrcode_placeholder.png'" mode="aspectFill"></image>
<view class="shadowboxInfo_right">
<view class="shadowboxInfo_right_1">正鲜生</view>
<view class="shadowboxInfo_right_1">{{ currentGG && currentGG.goods_name ? currentGG.goods_name : '' }}</view>
<view class="shadowboxInfo_right_2">
长按识别小程序 <br />
数量有限马上抢购
@ -233,7 +241,7 @@
</view>
</view>
</view>
<view class="shadowBox_btn" @click.stop="saveImg">保存海报</view>
<view class="shadowBox_btn" @click.stop="saveImg(picUrl + currentGG.commodity_pic[0])">保存海报</view>
</view>
</view>
@ -257,16 +265,16 @@
<view class="reviews-list" v-if="comments.length > 0">
<view class="review-item" v-for="(comment, index) in comments" :key="index">
<view class="review-user">
<image :src="comment.avatar" class="user-avatar"></image>
<image :src="comment.mpuser.avatar" class="user-avatar"></image>
<view class="user-info">
<view class="user-name">{{ comment.username }}</view>
<view class="user-name">{{ comment.mpuser.nick_name }}</view>
</view>
<view class="review-time">{{ comment.time }}</view>
<view class="review-time">{{ comment.create_time }}</view>
</view>
<view class="user-purchase">已购 {{ comment.product }}</view>
<view class="review-content">{{ comment.content }}</view>
<view class="review-images" v-if="comment.images.length > 0">
<image :src="img" class="review-img" v-for="(img, idx) in comment.images" :key="idx">
<view class="user-purchase">已购 {{ comment.goods_name.goods_name }}{{ comment.goods_name.goods_spec }}</view>
<view class="review-content">{{ comment.user_review }}</view>
<view class="review-images" v-if="comment.review_image.length > 0">
<image :src="img" class="review-img" v-for="(img, idx) in comment.review_image" :key="idx">
</image>
</view>
</view>
@ -282,15 +290,20 @@
<view class="popup-header-view" @click="closeSize">取消</view>
</view>
<view class="itemSize_top">
<image :src="changeImg" class="itemSize-img"><view v-if="currentGG.is_same_day" class="isDay" style="position: absolute; font-size: 16rpx; height: 20rpx; z-index: 100;">当日达</view></image>
<image :src="changeImg" class="itemSize-img">
<view v-if="currentGG.is_same_day" class="isDay"
style="position: absolute; font-size: 16rpx; height: 20rpx; z-index: 100;">当日达</view>
</image>
<view class="itemSize_info">
<view class="itemSize_name" style="display: flex;"><view v-if="currentGG.is_same_day" class="isDay">当日达</view>{{ changeName }}</view>
<view class="itemSize_name" style="display: flex;">
<view v-if="currentGG.is_same_day" class="isDay">当日达</view>{{ changeName }}
</view>
<view class="itemSize_price">{{ changePrice }}/</view>
</view>
</view>
<view class="itemSize" v-for="(item, index) in info.commodity_goods_info_list" :key="item.id"
@click="changeGG(item, index)" :class="index == currentGGIndex ? 'itemSize_active' : ''">
{{ item.goods_name }} {{ item.goods_spec }} / {{ item.goods_unit }}
<view class="itemSizeBox" v-for="(item, index) in info.commodity_goods_info_list" :key="item.id"
@click="changeGG(item, index)">
<text class="itemSize" :class="index == currentGGIndex ? 'itemSize_active' : ''">{{ item.goods_name }} {{ item.goods_spec }} / {{ item.goods_unit }}</text>
</view>
</u-popup>
</view>
@ -328,33 +341,15 @@
carOrderList: [],
//
showReviewPopup: false,
comments: [{
avatar: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test.png",
username: "TP",
product: "库尔勒香梨 10kg/箱",
content: "踏入这家位于街角的餐厅,木质门框与暖黄灯光交织出温馨氛围,墙面上手绘的食材插画画透着文艺气息,开放式厨房的设计让食客能看见厨师处理食材的全过程,第一印象便给人以干净与安心。",
images: ["https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test.png"],
time: "2025-03-01 11:24:20",
},
{
avatar: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test.png",
username: "TP",
product: "库尔勒香梨 10kg/箱",
content: "踏入这家位于街角的餐厅木质门框与暖黄灯光交织出温馨氛围墙面上手绘的食材插_draw着文艺气息开放式厨房的设计让食客能看见厨师处理食材的全过程第一印象便给人以干净与安心。",
images: [
"https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test.png",
"https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test.png",
"https://wechat-img-file.oss-cn-beijing.aliyuncs.com/test.png",
],
time: "2025-03-01 11:24:20",
},
],
comments: [],
show: false,
showSize: false,
changeImg: "",
changeName: "",
changePrice: "",
selectedGoods: null, //
qrcodePath: null, //
};
},
methods: {
@ -401,11 +396,11 @@
this.boxshadow2 = true;
},
//
saveImg() {
saveImg(picUrl) {
this.boxshadow2 = false;
//
uni.downloadFile({
url: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_share_img.png",
url: picUrl,
success: (res) => {
if (res.statusCode === 200) {
uni.saveImageToPhotosAlbum({
@ -465,12 +460,23 @@
}
this.info = res;
console.log("this.info", this.info.commodity_goods_info_list);
// {{info.commodity_goods_info_list[currentGGIndex].cart_count.count}}
this.currentGG = res.commodity_goods_info_list[0];
console.log("this.currentGG", this.currentGG);
this.currentGGIndex = 0;
this.changeImg = this.currentGG.commodity_pic[0]
//
let selectedIndex = 0;
if (this.selectedGoods) {
for (let i = 0; i < res.commodity_goods_info_list.length; i++) {
if (res.commodity_goods_info_list[i].id === this.selectedGoods.id) {
selectedIndex = i;
break;
}
}
}
this.currentGG = res.commodity_goods_info_list[selectedIndex];
console.log("this.currentGG", this.currentGG);
this.currentGGIndex = selectedIndex;
this.changeImg = picUrl + this.currentGG.commodity_pic[0]
this.changeName = this.currentGG.goods_alias
this.changePrice = this.currentGG.sales_price
});
@ -491,7 +497,6 @@
//
changeGG(item, index) {
console.log("🚀 ~ changeGG ~ item:", item);
this.currentGG = item;
this.currentGGIndex = index;
if (this.currentGG.cart_count) {
@ -501,9 +506,10 @@
count: 0
};
}
this.changeImg = item.commodity_pic[0]
this.changeImg = picUrl + item.commodity_pic[0]
this.changeName = item.goods_alias
this.changePrice = item.sales_price
this.getComment(item.goods_id)
},
car() {
NavgateTo("../shopCar/index");
@ -525,20 +531,35 @@
addCar() {
let that = this;
//
const currentGoods = this.info.commodity_goods_info_list[this.currentGGIndex];
//
const currentQuantity = currentGoods.cart_count ? currentGoods.cart_count.count : 0;
const stockQuantity = currentGoods.stock_quantity || 0;
//
if (currentQuantity >= stockQuantity) {
uni.showToast({
title: "库存不足",
icon: "none",
duration: 2000
});
return;
}
//
let goods_id_and_count = [];
this.info.commodity_goods_info_list[this.currentGGIndex].cart_count = {
count: 1,
count: currentQuantity + 1,
};
this.info.commodity_goods_info_list.forEach((item) => {
console.log(item.cart_count);
goods_id_and_count.push({
goods_id: item.id,
count: item.cart_count ? item.cart_count.count : 0,
});
});
console.log(goods_id_and_count);
// update
request(apiArr.updateCar, "POST", {
goods_id_and_count,
@ -597,21 +618,42 @@
closeSize() {
this.showSize = false;
},
},
onLoad(options) {
console.log(JSON.parse(decodeURIComponent(options.item)));
//
getComment(id) {
let params = {}
if (id) {
params = {
commodity_id: this.id,
goods_id: id
}
} else {
params = {
commodity_id: this.id,
}
}
request(apiArr.getComment, "POST", params).then((res) => {
this.comments = res.commodity_evaluate_list.map(item => ({
...item,
review_image: item.review_image ? item.review_image.split(',') : []
}));
});
}
},onLoad(options) {
const itemObj = JSON.parse(decodeURIComponent(options.item));
const meun = menuButtonInfo();
this.top = meun.top;
this.localHeight = meun.height;
this.id = itemObj.id;
this.id = itemObj.commodity_id ? itemObj.commodity_id : itemObj.id;
this.selectedGoods = itemObj; //
},
onReachBottom() { },
onShow() {
this.getShopCarList();
this.getGoodsInfo();
this.getShopCar();
this.getComment();
},
//( id count 0 )

View File

@ -0,0 +1,311 @@
.group-purchase-container {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
max-width: 750rpx;
margin: 0 auto;
background-color: #ffffff;
}
/* 顶部横幅 */
.banner {
background: linear-gradient(to right, #fd8d3c, #fe4909);
color: white;
/* position: relative; */
overflow: hidden;
height: 350rpx;
display: flex;
align-items: center;
justify-content: space-between;
}
.banner image {
width: 100%;
height: 300rpx;
/* object-fit: cover; */
position: absolute;
top: 0;
left: 0;
z-index: 0;
}
.banner-content {
z-index: 1;
}
.banner-title {
font-size: 36rpx;
font-weight: bold;
margin-bottom: 10rpx;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
}
.banner-subtitle {
font-size: 18rpx;
background-color: rgba(255, 255, 255, 0.2);
padding: 5rpx 10rpx;
border-radius: 4rpx;
display: inline-block;
}
/* 商品列表 */
.goods-list {
background-color: #ffffff;
padding: 30rpx 20rpx;
margin-top: -50rpx;
border-radius: 50rpx 50rpx 0 0;
height: 60vh;
overflow-y: auto;
}
.goods-item {
border-radius: 10rpx;
padding: 15rpx;
margin-bottom: 25rpx;
display: flex;
}
.goods-item2 {
border-radius: 10rpx;
padding: 15rpx;
margin-bottom: 25rpx;
display: flex;
}
.goods-image {
width: 140rpx;
height: 140rpx;
border-radius: 15rpx;
overflow: hidden;
margin-right: 15rpx;
}
.goods-image image {
width: 100%;
height: 100%;
object-fit: cover;
}
.goods-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
position: relative;
}
.goods-name {
font-size: 28rpx;
font-weight: bold;
margin-bottom: 8rpx;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.goods-desc {
font-size: 22rpx;
color: #666;
margin-bottom: 10rpx;
}
.goods-price {
font-size: 28rpx;
color: #e63946;
margin-bottom: 10rpx;
}
.price-container {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10rpx;
}
.group-price {
font-size: 28rpx;
color: #e63946;
margin-right: 10rpx;
border-radius: 4rpx;
display: flex;
}
.group-price1{
width: 100rpx;
padding: 10rpx 15rpx;
color: #ffffff;
background-color: #fc5d15;
border-radius: 15rpx 0 0 15rpx;
}
.group-price2{
width: auto;
padding: 10rpx 15rpx;
background: linear-gradient(to bottom, #fef6d6, #fee8a9);
border-radius: 0 15rpx 15rpx 0;
}
.original-price {
font-size: 26rpx;
color: #999;
}
.countdown {
width: auto;
font-size: 22rpx;
padding: 10rpx 20rpx;
color: #ffffff;
margin-bottom: 15rpx;
border-radius: 50rpx;
background-color: #fe2f01;
position: absolute;
/* top: 120rpx; */
bottom: -30rpx;
right: 0;
}
.quantity-control {
display: flex;
align-items: center;
justify-content: flex-end;
}
.decrease-btn {
width: 40rpx;
height: 40rpx;
background-color: #f5f5f5;
border: 1rpx solid #ccc;
border-radius: 50%;
line-height: 33rpx;
text-align: center;
font-size: 28rpx;
color: #333;
}
.increase-btn {
width: 40rpx;
height: 40rpx;
background-color: #ff502a;
border-radius: 50%;
line-height: 33rpx;
text-align: center;
font-size: 28rpx;
color: #ffffff;
}
.quantity {
margin: 0 15rpx;
font-size: 24rpx;
width: 40rpx;
text-align: center;
}
/* 购物车按钮 */
.shop_car {
width: 140rpx;
height: 140rpx;
position: fixed;
right: 33rpx;
bottom: 80rpx;
z-index: 10;
}
.shop_car image {
width: 100%;
height: 100%;
}
.u-badge {
position: absolute;
right: 0;
top: -10rpx;
}
/* 规格标签样式 */
.specification-tag {
width: 130rpx;
display: flex;
align-items: center;
justify-content: center;
background-color: #feeceb;
padding: 10rpx 20rpx;
border-radius: 40rpx;
margin: 15rpx 0;
font-size: 26rpx;
color: #dd4020;
}
.specification-tag text {
margin-right: 5rpx;
}
/* 货品列表样式 */
.sku-list {
margin-top: 10rpx;
padding: 15rpx;
background-color: #f9f9f9;
border-radius: 10rpx;
}
.sku-item{
position: relative;
margin-bottom: 30rpx;
}
.sku-info{
display: flex;
align-items: center;
justify-content: center;
}
.sku-image{
width: 100rpx;
height: 100rpx;
border-radius: 15rpx;
overflow: hidden;
margin-right: 15rpx;
}
.sku-price {
font-size: 26rpx;
color: #e63946;
margin-right: 10rpx;
border-radius: 4rpx;
display: flex;
margin-top: 15rpx;
}
.sku-price1{
width: auto;
padding: 10rpx 15rpx;
color: #ffffff;
background-color: #fc5d15;
border-radius: 15rpx 0 0 15rpx;
}
.sku-price2{
width: auto;
padding: 10rpx 15rpx;
background: linear-gradient(to bottom, #fef6d6, #fee8a9);
border-radius: 0 15rpx 15rpx 0;
}
.sku-control {
display: flex;
align-items: center;
justify-content: flex-end;
margin-top: 15rpx;
}
.sku-countdown {
width: auto;
font-size: 22rpx;
padding: 5rpx 20rpx;
color: #ffffff;
margin-bottom: 15rpx;
border-radius: 50rpx;
background-color: #fe2f01;
position: absolute;
top: 170rpx;
right: 0;
}

View File

@ -0,0 +1,350 @@
m<template>
<view class="group-purchase-container">
<!-- 顶部横幅 -->
<view class="banner">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/gp_index_top.png"></image>
</view>
<!-- 商品列表 -->
<view class="goods-list">
<!-- 商品项 -->
<view v-for="(item, index) in goodsList" :key="index">
<!-- 有多个货品 -->
<view class="goods-item" v-if="item.group_buy_goods_list.length > 1">
<view class="goods-image">
<image :src="item.commodity_pic" mode="aspectFill"></image>
</view>
<view class="goods-info">
<view class="goods-name">{{ item.commodity_name }}</view>
<view class="goods-desc">{{ item.commodity_intro }}</view>
<view class="goods-price"> {{ getPriceRange(item.group_buy_goods_list) }} </view>
<!-- 选择规格标签 -->
<view class="specification-tag" @click.stop="toggleSkuList(index)">
<text>{{ item.showSkuList ? '收起' : '选择规格' }}</text>
<u-icon name="arrow-down" size="26rpx" color="#FF370B" v-if="!item.showSkuList"></u-icon>
<u-icon name="arrow-up" size="26rpx" color="#FF370B" v-else></u-icon>
</view>
<!-- 货品列表 -->
<view class="sku-list" v-if="item.showSkuList">
<view v-for="(sku, skuIndex) in item.group_buy_goods_list" :key="skuIndex">
<view class="sku-item" @click="toDetail(sku)">
<view class="sku-info">
<view class="sku-image">
<image :src="sku.commodity_pic" mode="aspectFill"></image>
</view>
<view class="goods-info">
<view class="goods-name">{{ sku.goods_name }}</view>
<view class="goods-desc">{{ sku.goods_spec }}</view>
</view>
</view>
<view class="price-container">
<view class="sku-price">
<view class="sku-price1">团购价</view>
<view class="sku-price2">{{ sku.group_buy_price }}/{{ sku.goods_unit }}
</view>
</view>
<view class="sku-control">
<view class="decrease-btn" @tap.stop="decreaseQuantity(index, skuIndex)">-
</view>
<view class="quantity">{{ sku.quantity }}</view>
<view class="increase-btn" @tap.stop="increaseQuantity(index, skuIndex)">+
</view>
</view>
</view>
<view class="original-price">单买价 {{ sku.sales_price }}/{{ sku.goods_unit }}</view>
<view class="sku-countdown">
{{
getEndTheCountdown(sku.group_buy_activity_info.end_time)
}}
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 只有一个货品 -->
<view v-else>
<view class="goods-item2" @click="toDetail(item)">
<view class="goods-image">
<image :src="item.commodity_pic" mode="aspectFill"></image>
</view>
<view class="goods-info">
<view class="goods-name">{{ item.commodity_name }}</view>
<view class="goods-desc">{{ item.commodity_intro }}</view>
<view class="price-container">
<view class="group-price">
<view class="group-price1">团购价</view>
<view class="group-price2">{{ item.group_buy_goods_list[0].group_buy_price }}/{{
item.group_buy_goods_list[0].goods_unit }}</view>
</view>
<view class="quantity-control">
<view class="decrease-btn" @tap.stop="decreaseQuantity(index, 0)">-</view>
<view class="quantity">{{ item.group_buy_goods_list[0].quantity }}</view>
<view class="increase-btn" @tap.stop="increaseQuantity(index, 0)">+</view>
</view>
</view>
<view class="original-price">单买价 {{ item.group_buy_goods_list[0].sales_price }}/{{
item.group_buy_goods_list[0].goods_unit }}</view>
<view class="countdown">
{{ getEndTheCountdown(item.group_buy_goods_list[0].group_buy_activity_info.end_time) }}
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 购物车按钮 -->
<view class="shop_car" @click="shopCar">
<u-badge numberType="limit" type="error" max="99" :value="carNum"></u-badge>
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_car_num.png"></image>
</view>
</view>
</template>
<script>
import { picUrl, menuButtonInfo, request, NavgateTo } from "../../../utils";
import { apiArr } from '@/api/groupPurchase.js'
import { apiArr as shopApi } from "../../../api/shop.js";
export default {
data() {
return {
goodsList: [],
carNum: 0,
quantity: 0,
timer: null, // ID
endTime: '', //
updateTime: Date.now(), //
goodsDetail: []
};
},
onLoad() {
// this.getGoodsList()
},
onShow() {
//
if (!this.timer) {
this.timer = setInterval(() => {
//
this.updateTime = Date.now();
}, 1000);
}
// getGoodsListgetShopdetailgetGoodsNum
Promise.all([
// getGoodsList
this.goodsList.length > 0 ? Promise.resolve() : this.getGoodsList(),
// getShopdetail
this.getShopdetail()
]).then(() => {
this.getGoodsNum();//
});
},
methods: {
getGoodsList() {
if(!uni.getStorageSync('userId')){
uni.showToast({
title: '请先登录',
icon: 'none'
})
return
}
const params = {
user_id: uni.getStorageSync('userId')
}
return request(apiArr.groupBuyList, 'POST', params).then(res => {
const list = res.group_buy_list.map(item => {
// quantity
const group_buy_goods_list = item.group_buy_goods_list.map(sku => ({
...sku,
commodity_pic: picUrl + sku.commodity_pic,
quantity: 0
}));
return {
...item,
commodity_pic: picUrl + item.commodity_pic,
showSkuList: false,
group_buy_goods_list
}
})
this.goodsList = list
return res;
})
},
getShopdetail() {
const params = {
is_group_buy: 1,
}
return request(shopApi.getCar, "POST", params).then((res) => {
this.carNum = res.total;
//
this.goodsDetail = [].concat(res.same_day_cart_list, res.normal_cart_list)
.flatMap(supplier => supplier.commodity_cart_and_goods_model);
return res;
});
},
getGoodsNum() {
if (!this.goodsDetail || !this.goodsList || this.goodsList.length === 0) {
return;
}
//
this.goodsList.forEach(goods => {
//
goods.group_buy_goods_list.forEach(sku => {
//
const matchedItem = this.goodsDetail.find(item => item.goods_id === sku.goods_id);
// quantity
if (matchedItem) {
sku.quantity = matchedItem.count;
} else {
// 0
sku.quantity = 0;
}
});
});
},
toDetail(itemObj) {
const item = {
...itemObj,
groupById: itemObj.group_buy_activity_info.id
};
NavgateTo(`/packages/shop/groupPurchaseDetail/index?item=${JSON.stringify(item)}`)
},
//
getPriceRange(goodsList) {
if (!goodsList || goodsList.length === 0) return '¥0';
const prices = goodsList.map(item => Number(item.sales_price));
const minPrice = Math.min(...prices);
const maxPrice = Math.max(...prices);
return minPrice === maxPrice ? `${minPrice}` : `${minPrice} ~ ¥${maxPrice}`;
},
// /
toggleSkuList(index) {
this.goodsList[index].showSkuList = !this.goodsList[index].showSkuList;
},
//
increaseQuantity(goodsIndex, skuIndex) {
if (this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity == 0) {
this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity += this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].min_order_quantity
this.carNum += this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].min_order_quantity
} else {
if (this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity == this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].total_stock) {
uni.showToast({
title: '库存不足',
icon: 'none'
});
return
}
if (this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity == this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].max_limit_quantity) {
uni.showToast({
title: '一次最多购买' + this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].max_limit_quantity + '件',
icon: 'none'
});
return
}
this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity++;
this.carNum++;
}
const params = {
goods_id_and_count: [
{
goods_id: this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].id,
count: this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity,
},
],
group_buy_id: this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].group_buy_activity_info.id
}
this.updateCar(params);
},
//
decreaseQuantity(goodsIndex, skuIndex) {
if (this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity > 0) {
if (this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity == this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].min_order_quantity) {
this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity = 0
this.carNum = 0
} else {
this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity--;
this.carNum--;
}
const params = {
goods_id_and_count: [
{
goods_id: this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].id,
count: this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].quantity,
},
],
group_buy_id: this.goodsList[goodsIndex].group_buy_goods_list[skuIndex].group_buy_activity_info.id
}
this.updateCar(params);
} else {
uni.showToast({
title: '已经没有了...',
icon: 'none'
});
}
},
//
async updateCar(params) {
return request(shopApi.updateCar, "POST", params).then((res) => {
this.getShopdetail();
uni.showToast({
title: "操作成功!",
success() { },
});
});
},
//
shopCar() {
const item = {
is_group_buy: 1,
}
NavgateTo("../shopCar/index?item=" + JSON.stringify(item));
},
//
getEndTheCountdown(endTime) {
//
const now = new Date().getTime();
const end = new Date(endTime).getTime();
//
let diff = end - now;
//
if (diff <= 0) {
return '团购已结束';
}
//
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
diff -= days * (1000 * 60 * 60 * 24);
const hours = Math.floor(diff / (1000 * 60 * 60));
diff -= hours * (1000 * 60 * 60);
const minutes = Math.floor(diff / (1000 * 60));
diff -= minutes * (1000 * 60);
//
return `${days}${hours}小时${minutes}分钟后结束`;
}
},
onHide() {
//
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
}
};
</script>
<style>
@import url("./index.css");
</style>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,874 @@
<template>
<view>
<view class="header">
<view class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }">
<view class="searchBox_left" @click="back">
<u-icon name="arrow-left" size="20px" color="#000"></u-icon>
</view>
</view>
</view>
<view class="swiper">
<view class="tag2 tag-img" v-if="
currentGG.is_same_day
">当日达</view>
<swiper :indicator-dots="false" :autoplay="true" :interval="3000" :duration="1000" @change="changeIndex">
<swiper-item v-for="(item, index) in currentGG.goods_carousel" :key="index">
<image :src="picUrl + item"></image>
</swiper-item>
</swiper>
<view class="NumDot" v-if="currentGG.goods_carousel && currentGG.goods_carousel.length > 0">
{{ currentIndex }} /{{ currentGG.goods_carousel.length }}
</view>
</view>
<view class="box_15">
<view class="section_2">
<view class="text-wrapper_4">
<text lines="1" class="text_31"></text>
<text lines="1" class="text_30">{{ currentGG.group_buy_price }}</text>
<text lines="1" class="text_33">/{{ currentGG.goods_unit }}</text>
</view>
<text lines="1" decode="true" class="text_32">单买价&nbsp;{{ currentGG.sales_price }}/{{
currentGG.goods_unit }}</text>
</view>
<view class="section_3">
<text lines="1" class="text_34">距结束还剩</text>
<view class="box_16">
<view class="timeBox">
<view class="dayTimeBox">{{ endTheCountdownDay }}</view>
<view class="timeBox">
<view class="time">{{ endTheCountdownHour }}</view>
<view></view>
</view>
<view class="timeBox">
<view class="time">{{ endTheCountdownMinute }}</view>
<view></view>
</view>
<view class="timeBox">
<view class="time">{{ endTheCountdownSecond }}</view>
</view>
</view>
</view>
</view>
</view>
<view class="Money">
<view class="MoneyMark"></view>
{{ currentGG.group_buy_price }}
<view class="MoneyUnit">/{{ currentGG.goods_unit }}</view>
<view class="num">已售{{ soldOutNum }} | 剩余{{ currentGG.total_stock }}</view>
</view>
<!-- 规格 -->
<!-- @click="changeGG2(item, index)" :class="index == currentGGIndex ? 'active' : ''"> -->
<view class="GGBox">
<view class="GG_left">
<view class="GG_Item" v-for="(item, index) in info.commodity_goods_info_list" :key="item.id"
@click="changeGG(item, index)" :class="index == currentGGIndex ? 'active' : ''">
{{ item.goods_spec }} / {{ item.goods_unit }}
</view>
</view>
<view class="GG_rigth" v-if="info.commodity_goods_info_list && info.commodity_goods_info_list.length > 0">
{{ info.commodity_goods_info_list.length }}
</view>
</view>
<view class="Tit">
<view class="tag tag-text" v-if="
currentGG.is_same_day
">当日达</view>
{{ currentGG.goods_name }}
</view>
<view class="Msg">{{ currentGG.commodity_brief }}</view>
<view class="fenge"></view>
<!-- 已购买区域 -->
<view>
<view class="purchase-area">
<view class="purchase-count">{{ totalCount }}人已购买</view>
<view class="view-more" @click="showPurchaseRecords">查看更多 &gt;</view>
</view>
<view class="record-list">
<view class="record-item" v-for="(record, index) in purchaseRecords" :key="index">
<view class="record-user">
<image :src="record.avatar" class="user-avatar"></image>
<view class="user-name">{{ record.nick_name }}</view>
</view>
<view class="record-amount">
{{ formatDate(record.buy_time) }}买了{{ record.count }}
</view>
<view class="record-time">
<button class="buy-btn" @click="goSubmit">去下单</button>
</view>
</view>
</view>
</view>
<view class="fenge"></view>
<h3 class="GoodsMsg">商品详情</h3>
<view class="Msg_Item">
<view class="Msg_ItemTit">货号</view>
<view class="Msg_ItemCon" @click="copys(currentGG.goods_no)">
{{ currentGG.goods_no }}
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_copy.png"></image>
</view>
</view>
<view class="Msg_Item">
<view class="Msg_ItemTit">规格说明</view>
<view class="Msg_ItemCon">{{ currentGG.goods_spec }}</view>
</view>
<view class="Msg_Item">
<view class="Msg_ItemTit">售卖单位</view>
<view class="Msg_ItemCon">{{ currentGG.goods_unit }}</view>
</view>
<view class="GoosMsg">
<image v-for="item in currentGG.goods_detail_pic" :src="picUrl + item" :key="item" mode="widthFix"></image>
</view>
<view class="priceInfo">
<h3 class="priceInfo-title">价格说明</h3>
<view class="priceInfo-content">
<view>
<text class="priceInfo-content-title">划线价格</text>
指商品的厂商指导价正品零售价市面常见价或该商品曾经展示过的销售价等并非原价仅供参考
</view>
<view>
<text class="priceInfo-content-title">未划线价格</text>
指商品的实时价格不因表述的差异改变性质具体成交价格根据商品参加活动或使用优惠券等发生变化最终以订单结算价格为准
</view>
</view>
</view>
<!-- 底部购物车 -->
<view class="Car">
<view class="car_left">
<view class="share" @click="share">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_share.png"
mode="widthFix"></image>
分享
</view>
<view class="cars" @click="car">
<u-badge numberType="limit" :type="type" max="99" :value="carNum"></u-badge>
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_car.png"
mode="widthFix"></image>
购物车
</view>
</view>
<view class="car_right2" v-if="info.commodity_goods_info_list[currentGGIndex].total_stock < 1">
已售罄
</view>
<view class="car_right" v-if="
info.commodity_goods_info_list[currentGGIndex].total_stock > 0 &&
(!info.commodity_goods_info_list[currentGGIndex].cart_count ||
info.commodity_goods_info_list[currentGGIndex].cart_count.count == 0)
" @click="addCar">
加入购物车
</view>
<view class="car_right" @click="changeCar" v-if="
info.commodity_goods_info_list[currentGGIndex].cart_count.count > 0
&& info.commodity_goods_info_list[currentGGIndex].total_stock > 0
">
加入购物车
</view>
</view>
<!-- 分享 -->
<view class="shadow" @click.stop="changeShadow" v-if="boxshadow1">
<view class="shadowBox1">
<view class="shadowBox1Item" @click="shareFriend">
<button class="shadowBox1Item_btn" open-type="share" bindtap="onShareButtonClick">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_WX.png"
mode="aspectFill"></image>
微信好友
</button>
</view>
<view class="shadowBox1Item" @click="openSave">
<button class="shadowBox1Item_btn">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_saveImg.png"
mode="aspectFill"></image>
生成海报
</button>
</view>
</view>
</view>
<!-- 海报 -->
<view class="shadow" @click="changeShadow2" v-if="boxshadow2">
<view class="shadowBox2">
<view class="shadowBox_img">
<view class="boxshadow_tit">今日商品推荐</view>
<view class="boxshadow_img">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_share_img.png">
</image>
</view>
<view class="line"></view>
<view class="shadowBoxInfo">
<view class="shadowboxInfo_left">二维码</view>
<view class="shadowboxInfo_right">
<view class="shadowboxInfo_right_1">正鲜生</view>
<view class="shadowboxInfo_right_2">
长按识别小程序 <br />
数量有限马上抢购
</view>
</view>
</view>
</view>
<view class="shadowBox_btn" @click.stop="saveImg">保存海报</view>
</view>
</view>
<!-- 评价 查看详情 -->
<!-- <u-popup :show="show" round="20rpx" mode="bottom" @close="close" @open="open" :z-index="10070">
<view class="reviews-section">
<view class="popup-header">
<h3 class="popup-header-h3">评价</h3>
<view class="popup-header-view" @click="close">取消</view>
</view>
<view class="temp">
<view class="temp1">
<img class="temp_img" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/pingjia.png" />
为你展示真实评价
</view>
<view class="temp1" @click="showSizePopup">
款式
<img class="temp_img1" src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/kuanshi.png" />
</view>
</view>
<view class="reviews-list" v-if="comments.length > 0">
<view class="review-item" v-for="(comment, index) in comments" :key="index">
<view class="review-user">
<image :src="comment.avatar" class="user-avatar"></image>
<view class="user-info">
<view class="user-name">{{ comment.username }}</view>
</view>
<view class="review-time">{{ comment.time }}</view>
</view>
<view class="user-purchase">已购 {{ comment.product }}</view>
<view class="review-content">{{ comment.content }}</view>
<view class="review-images" v-if="comment.images.length > 0">
<image :src="img" class="review-img" v-for="(img, idx) in comment.images" :key="idx"></image>
</view>
</view>
</view>
</view>
</u-popup> -->
<!-- 团购记录弹窗 -->
<u-popup :show="showPurchase" round="20rpx" mode="bottom" @close="closePurchase">
<view class="purchase-popup">
<view class="popup-header">
<h3 class="popup-header-h3">团购记录</h3>
<view class="popup-header-view" @click="closePurchase">取消</view>
</view>
<view class="purchase-records">
<view class="record-header">
<view class="record-header-item">买家</view>
<view class="record-header-item">数量</view>
<view class="record-header-item">购买时间</view>
</view>
<view class="record-list">
<view class="record-item" v-for="(record, index) in purchaseRecords" :key="index">
<view class="record-user">
<image :src="record.avatar" class="user-avatar"></image>
<view class="user-name">{{ record.nick_name }}</view>
</view>
<view class="record-amount">+{{ record.count }}</view>
<view class="record-time">{{ record.buy_time }}</view>
</view>
</view>
</view>
</view>
</u-popup>
<!-- 选择款式 -->
<u-popup :show="showSize" round="20rpx" mode="bottom" @close="closeSize">
<view class="popup-header">
<h3 class="popup-header-h3">选择款式</h3>
<view class="popup-header-view" @click="closeSize">取消</view>
</view>
<view class="itemSize_top">
<image :src="changeImg" class="itemSize-img"></image>
<view class="itemSize_info">
<view class="itemSize_name">{{ changeName }}</view>
<view class="itemSize_price">{{ changePrice }}/</view>
</view>
</view>
<view class="itemSize" v-for="(item, index) in info.commodity_goods_info_list" :key="item.id"
@click="changeGG(item, index)" :class="index == currentGGIndex ? 'itemSize_active' : ''">
{{ item.goods_name }} {{ item.goods_spec }} / {{ item.goods_unit }}
</view>
</u-popup>
</view>
</template>
<script>
import { apiArr } from "../../../api/shop";
import { apiArr as apiArr2 } from "../../../api/groupPurchase";
import { picUrl, menuButtonInfo, request, NavgateTo } from "../../../utils";
export default {
data() {
return {
itemObj: {},
picUrl,
top: "",
localHeight: "",
carNum: "",
prevCarNum: "",
currentNum: "0", //
type: "error",
boxshadow1: false,
boxshadow2: false,
id: "",
groupById: "",
info: "",
currentIndex: "1", //
currentGG: "", //
currentGGIndex: "", //index
carOrderList: [],
//
showReviewPopup: false,
soldOutNum: 0,
show: false,
showSize: false,
showPurchase: false,
purchaseRecords: [],
totalCount: 0,
changeImg: "",
changeName: "",
changePrice: "",
endTime: "",
endTheCountdownDay: '',
endTheCountdownHour: '',
endTheCountdownMinute: '',
endTheCountdownSecond: '',
timer: null, // ID
};
},
methods: {
//
showPurchaseRecords() {
if (this.purchaseRecords.length > 0) {
this.showPurchase = true;
} else {
uni.showToast({
title: '没有更多数据',
icon: 'none'
})
}
},
//
closePurchase() {
this.showPurchase = false;
},
//
goSubmit() {
NavgateTo('/packages/shop/groupPurchaseSubmit/index')
},
changeIndex(e) {
this.currentIndex = e.detail.current + 1;
},
back() {
uni.navigateBack({
delta: 1,
});
},
// -
shareFriend() {
this.boxshadow1 = false; //
//
const shareInfo = {
title: this.currentGG.goods_name || '商品分享', //
desc: this.currentGG.commodity_brief || '快来看看这款商品吧', //
link: `${window.location.origin}/pages/goodsDetail/index?id=${this.id}`, //
imageUrl: this.picUrl + (this.currentGG.goods_carousel && this.currentGG.goods_carousel[0] || '') //
};
//
if (typeof WeixinJSBridge === 'undefined') {
// 使uniAPI
if (typeof uni.share !== 'undefined') {
uni.share({
provider: 'weixin',
scene: 'WXSceneSession',
type: 0,
title: shareInfo.title,
summary: shareInfo.desc,
href: shareInfo.link,
imageUrl: shareInfo.imageUrl,
success: () => {
uni.showToast({
title: '分享成功',
icon: 'success',
duration: 2000
});
},
fail: (err) => {
console.error('分享失败', err);
uni.showToast({
title: '分享失败,请重试',
icon: 'none',
duration: 2000
});
}
});
} else {
uni.showToast({
title: '请在微信客户端打开',
icon: 'none'
});
}
return;
}
try {
//
WeixinJSBridge.invoke('sendAppMessage', {
title: shareInfo.title,
desc: shareInfo.desc,
link: shareInfo.link,
img_url: shareInfo.imageUrl,
img_width: '120',
img_height: '120',
type: 'link',
data_url: ''
}, (res) => {
if (res.err_msg === 'sendAppMessage:ok') {
uni.showToast({
title: '分享成功',
icon: 'success',
duration: 2000
});
} else if (res.err_msg === 'sendAppMessage:cancel') {
uni.showToast({
title: '已取消分享',
icon: 'none',
duration: 2000
});
} else {
console.error('分享失败', res);
uni.showToast({
title: '分享失败,请重试',
icon: 'none',
duration: 2000
});
}
});
} catch (error) {
console.error('调用微信分享接口失败', error);
// 使wx.ready
if (typeof wx !== 'undefined') {
wx.ready(() => {
//
wx.onMenuShareAppMessage({
title: shareInfo.title,
desc: shareInfo.desc,
link: shareInfo.link,
imgUrl: shareInfo.imageUrl,
type: 'link',
success: () => {
uni.showToast({
title: '分享成功',
icon: 'success',
duration: 2000
});
},
cancel: () => {
uni.showToast({
title: '已取消分享',
icon: 'none',
duration: 2000
});
},
fail: (err) => {
console.error('分享失败', err);
uni.showToast({
title: '分享失败,请重试',
icon: 'none',
duration: 2000
});
}
});
//
uni.showToast({
title: '请点击右上角分享按钮',
icon: 'none'
});
});
wx.error((err) => {
console.error('微信JS-SDK初始化失败', err);
uni.showToast({
title: '分享功能加载失败',
icon: 'none'
});
});
}
}
},
changeShadow() {
this.boxshadow1 = false;
},
openSave() {
this.boxshadow1 = false;
this.boxshadow2 = true;
},
//
saveImg() {
this.boxshadow2 = false;
//
uni.downloadFile({
url: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_share_img.png",
success: (res) => {
if (res.statusCode === 200) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: (res) => {
uni.showToast({
title: "保存成功",
icon: "success",
duration: 2000,
});
},
fail: (err) => {
console.log("保存失败", err);
},
});
}
},
fail: (err) => {
console.log("下载失败", err);
},
});
},
changeShadow2() {
this.boxshadow2 = false;
},
//
share() {
this.boxshadow1 = true;
},
//
getGoodsInfo() {
const params = {
id: this.id,
group_buy_activity_id: this.groupById
}
request(apiArr.getGoodsInfo, "POST", params).then((res) => {
//
res.commodity_goods_info_list.forEach((item) => {
item.goods_detail_pic = item.goods_detail_pic ? item.goods_detail_pic.split(",") : [];
item.goods_carousel = item.goods_carousel ? item.goods_carousel.split(",") : [];
item.commodity_pic = item.commodity_pic ? item.commodity_pic.split(",") : [];
});
//
if (this.carOrderList) {
this.carOrderList.forEach((items) => {
res.commodity_goods_info_list.forEach((item) => {
if (items.goods_id == item.id) {
item.cart_count = { count: 0 };
item.cart_count.count = items.count;
}
});
});
}
const currentTime = new Date().getTime();
// group_buy_activity_info
if (res.commodity_goods_info_list && Array.isArray(res.commodity_goods_info_list)) {
res.commodity_goods_info_list = res.commodity_goods_info_list.filter(item => {
const startTime = new Date(item.group_buy_activity_info?.start_time).getTime();
const endTime = new Date(item.group_buy_activity_info?.end_time).getTime();
return item.group_buy_activity_info !== null && currentTime >= startTime && currentTime <= endTime
});
}
this.info = res;
//
if (this.itemObj) {
// itemObj
this.itemObj.goods_detail_pic = this.itemObj.goods_detail_pic ? this.itemObj.goods_detail_pic.split(",") : [];
this.itemObj.goods_carousel = this.itemObj.goods_carousel ? this.itemObj.goods_carousel.split(",") : [];
this.itemObj.commodity_pic = this.itemObj.commodity_pic ? this.itemObj.commodity_pic.split(",") : [];
this.currentGG = this.itemObj;
// itemObj
this.currentGGIndex = this.info && this.info.commodity_goods_info_list
? this.info.commodity_goods_info_list.findIndex(item => item.id === this.itemObj.id)
: 0;
// 0
if (this.currentGGIndex === -1) {
this.currentGGIndex = 0;
}
this.changeImg = this.currentGG.commodity_pic[0];
this.changeName = this.currentGG.goods_alias;
this.changePrice = this.currentGG.sales_price;
} else {
//
this.currentGG = null;
this.currentGGIndex = 0;
this.changeImg = '';
this.changeName = '';
this.changePrice = '';
}
});
},
copys(e) {
uni.setClipboardData({
data: e,
success: (res) => {
uni.showToast({
title: "复制成功",
icon: "success",
duration: 2000,
});
},
});
},
//
changeGG(item, index) {
console.log("🚀 ~ changeGG ~ item:", item)
this.currentGG = item;
this.currentGGIndex = index;
if (this.currentGG.cart_count) {
this.currentNum = this.currentGG.cart_count.count;
} else {
this.currentGG.cart_count = { count: 0 };
}
this.changeImg = item.commodity_pic[0]
this.changeName = item.goods_alias
this.changePrice = item.sales_price
},
car() {
NavgateTo("../shopCar/index");
},
//
getShopCar() {
request(apiArr.getCarCount, "POST", {}).then((res) => {
this.carNum = res.total;
this.prevCarNum = res.total;
});
},
getShopCarList() {
const params = {
is_group_buy: 1,
}
return request(apiArr.getCar, "POST", params).then((res) => {
//
this.carOrderList = [].concat(res.same_day_cart_list, res.normal_cart_list)
.flatMap(supplier => supplier.commodity_cart_and_goods_model);
return res;
});
},
addCar() {
let that = this;
this.info.commodity_goods_info_list[this.currentGGIndex].cart_count = {
count: this.info.commodity_goods_info_list[this.currentGGIndex].min_order_quantity,
};
// this.info.commodity_goods_info_list.forEach((item) => {
// console.log(item.cart_count);
// goods_id_and_count.push({
// goods_id: item.id,
// count: item.cart_count ? item.cart_count.count : 0,
// });
// });
let countVal = this.info.commodity_goods_info_list[this.currentGGIndex].min_order_quantity
const params = {
goods_id_and_count: [
{
goods_id:
this.info.commodity_goods_info_list[this.currentGGIndex].id,
count: countVal,
},
],
}
request(apiArr.updateCar, "POST", params).then((res) => {
that.getShopCar();
that.getShopCarList();
});
},
//
changeCar() {
// 0
const currentCount = this.info.commodity_goods_info_list[this.currentGGIndex].cart_count?.count;
//
const newCount = currentCount + 1;
const params = {
user_id: uni.getStorageSync("userId"),
goods_id_and_count: [
{
goods_id: this.info.commodity_goods_info_list[this.currentGGIndex].id,
count: newCount,
},
],
};
request(apiArr.updateCar, "POST", params).then((res) => {
this.getShopCarList();
uni.showToast({
title: "操作成功!",
success() { },
});
this.getShopCar();
this.getGoodsInfo();
});
},
showPopup() {
this.show = true;
},
showSizePopup() {
this.showSize = true;
},
close() {
this.show = false;
},
closeSize() {
this.showSize = false;
},
//
getBuyRecord() {
const params = {
activity_id: 47,
goods_id: this.id
}
request(apiArr2.groupBuyRecord, 'POST', params).then(res => {
const record = res.group_buy_record.map(item => {
return {
...item,
avatar: picture + item.avatar
}
})
this.purchaseRecords = record
this.totalCount = res.total_count
// item.countsoldOutNum
this.soldOutNum = record.reduce((total, item) => total + (item.count || 0), 0)
})
},
formatDate(dateStr) {
if (!dateStr) return '';
const date = new Date(dateStr);
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${month}${day}`;
},
//
getEndTheCountdown(endTime) {
//
const now = new Date().getTime();
const end = new Date(endTime).getTime();
//
let diff = end - now;
//
if (diff <= 0) {
return '团购已结束';
}
//
this.endTheCountdownDay = Math.floor(diff / (1000 * 60 * 60 * 24));
diff -= this.endTheCountdownDay * (1000 * 60 * 60 * 24);
this.endTheCountdownHour = Math.floor(diff / (1000 * 60 * 60));
diff -= this.endTheCountdownHour * (1000 * 60 * 60);
this.endTheCountdownMinute = Math.floor(diff / (1000 * 60));
diff -= this.endTheCountdownMinute * (1000 * 60);
this.endTheCountdownSecond = Math.floor(diff / (1000));
}
},
onLoad(options) {
this.itemObj = JSON.parse(decodeURIComponent(options.item));
const meun = menuButtonInfo();
this.top = meun.top;
this.localHeight = meun.height;
this.id = this.itemObj.commodity_id ? this.itemObj.commodity_id : this.itemObj.id;
this.groupById = this.itemObj.groupById
if (this.itemObj.commodity_id) {
this.endTime = this.itemObj.group_buy_activity_info.end_time
} else {
this.endTime = this.itemObj.group_buy_goods_list[0].group_buy_activity_info.end_time
}
this.getBuyRecord()
this.getEndTheCountdown(this.endTime)
//
this.timer = setInterval(() => {
this.getEndTheCountdown(this.endTime)
}, 1000)
},
onReachBottom() { },
onShow() {
// getShopCarListgetGoodsInfo
this.getShopCarList().then(() => {
this.getGoodsInfo();
});
this.getShopCar();
},
//( id count 0 )
onHide() {
//
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
let goods_id_and_count = [];
this.info.commodity_goods_info_list.forEach((item) => {
goods_id_and_count.push({
goods_id: item.id,
count: item.cart_count ? item.cart_count.count : 0,
});
});
// request(apiArr.updateCar, "POST", {
// goods_id_and_count,
// }).then((res) => {
// console.log("Cart updated on hide");
// });
return;
},
};
</script>
<style>
@import url("./index.css");
</style>

View File

@ -0,0 +1,509 @@
page {
background-color: #f5f7fb;
}
.container {
padding: 0;
margin: 0;
font-size: 28rpx;
color: #333;
}
/* 顶部切换栏 */
.tab-bar {
display: flex;
background-color: #fff;
padding: 20rpx 0;
}
.tab-item {
width: 180rpx;
height: 70rpx;
line-height: 70rpx;
text-align: center;
border-radius: 15rpx;
margin: 0 20rpx;
font-size: 28rpx;
border: 1rpx solid #ddd;
}
.tab-item.active {
background-color: #ff370b;
color: #fff;
}
/* 分隔线 */
.divider {
height: 20rpx;
background-color: #f5f5f5;
}
/* 公共标题样式 */
.section-title {
font-size: 32rpx;
color: #333;
font-weight: bold;
padding: 20rpx 30rpx;
}
/* 收货地址区域 */
.info-section {
background: repeating-linear-gradient(to right,
#fe5355,
#fe5355 20px,
#549aff 20px,
#549aff 40px);
padding: 10rpx 0;
}
.address-section {
background-color: #fff;
}
.address-info {
padding: 30rpx;
display: flex;
justify-content: space-between;
align-items: flex-start;
border-bottom: 1rpx solid #eee;
}
.address-main {
flex: 1;
}
.address-name-phone {
display: flex;
align-items: center;
margin-bottom: 10rpx;
}
.name {
font-size: 32rpx;
margin-right: 20rpx;
}
.phone {
font-size: 30rpx;
color: #666;
}
.address-detail {
font-size: 28rpx;
color: #666;
line-height: 40rpx;
display: flex;
align-items: center;
}
.address-arrow {
color: #333;
}
/* 商品信息区域 */
.goods-section {
background-color: #fff;
margin-bottom: 20rpx;
}
.goods-item {
border-radius: 10rpx;
padding: 15rpx;
display: flex;
background-color: #fff;
}
.goods-image {
width: 140rpx;
height: 140rpx;
border-radius: 15rpx;
overflow: hidden;
margin-right: 15rpx;
}
.goods-image image {
width: 100%;
height: 100%;
object-fit: cover;
}
.goods-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
position: relative;
}
.goods-name {
font-size: 28rpx;
font-weight: bold;
margin-bottom: 8rpx;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.goods-desc {
font-size: 22rpx;
color: #666;
margin-bottom: 10rpx;
}
.price-container {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10rpx;
}
.group-price {
font-size: 28rpx;
color: #e63946;
margin-right: 10rpx;
border-radius: 4rpx;
/* display: flex; */
}
.group-price-box {
display: flex;
}
.group-price1 {
width: 100rpx;
padding: 10rpx 15rpx;
color: #ffffff;
background-color: #fc5d15;
border-radius: 15rpx 0 0 15rpx;
}
.group-price2 {
width: auto;
padding: 10rpx 15rpx;
background: linear-gradient(to bottom, #fef6d6, #fee8a9);
border-radius: 0 15rpx 15rpx 0;
}
.original-price {
font-size: 26rpx;
color: #999;
}
.countdown {
width: 250rpx;
font-size: 22rpx;
padding: 10rpx 15rpx;
color: #ffffff;
margin-bottom: 15rpx;
border-radius: 50rpx;
background-color: #fe2f01;
position: absolute;
top: 150rpx;
right: 0;
}
.quantity-control {
display: flex;
align-items: center;
justify-content: flex-end;
}
.decrease-btn {
width: 40rpx;
height: 40rpx;
background-color: #f5f5f5;
border: 1rpx solid #ccc;
border-radius: 50%;
line-height: 33rpx;
text-align: center;
font-size: 28rpx;
color: #333;
}
.increase-btn {
width: 40rpx;
height: 40rpx;
background-color: #ff502a;
border-radius: 50%;
line-height: 33rpx;
text-align: center;
font-size: 28rpx;
color: #ffffff;
}
.quantity {
margin: 0 15rpx;
font-size: 24rpx;
width: 40rpx;
text-align: center;
}
/* 运费和总金额区域 */
.fee-section,
.total-section {
background-color: #fff;
padding: 30rpx;
display: flex;
justify-content: space-between;
border-bottom: 1rpx solid #eee;
}
.fee-name,
.total-name {
font-size: 30rpx;
}
.fee-value,
.total-value {
font-size: 30rpx;
color: #333;
}
.total-value {
font-weight: bold;
color: #FF7658;
}
/* 复制 */
.copy-icon {
width: 30rpx;
height: 30rpx;
background-image: url('https://wechat-img-file.oss-cn-beijing.aliyuncs.com/myOrder/copy.png');
background-size: cover;
margin-left: 10rpx;
}
/* 支付方式区域 */
.payment-section {
background-color: #fff;
margin-bottom: 20rpx;
margin-top: 15rpx;
}
.payment-item {
padding: 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1rpx solid #eee;
}
.payment-icon {
width: 60rpx;
height: 60rpx;
margin-right: 20rpx;
}
.payment-icon image {
width: 100%;
height: 100%;
}
.payment-content {
flex: 1;
}
.payment-name {
font-size: 32rpx;
margin-bottom: 5rpx;
}
.payment-desc {
font-size: 26rpx;
color: #333;
}
.payment-select {
color: #FF7658;
}
/* 立即支付按钮 */
.pay-button {
height: 100rpx;
line-height: 100rpx;
text-align: center;
background: linear-gradient(91deg, #FF7658 0%, #FF370B 100%);
color: #fff;
font-size: 36rpx;
font-weight: bold;
border-radius: 50rpx;
position: fixed;
bottom: 50rpx;
left: 15%;
width: 70%;
z-index: 99;
}
/* 自提样式 */
.pickup-info {
padding: 30rpx;
background-color: #fff;
}
.pickup-address {
font-size: 30rpx;
margin-bottom: 10rpx;
}
.pickup-time {
font-size: 28rpx;
color: #999;
}
/* 弹窗 */
.shadow {
background: rgba(0, 0, 0, 0.4);
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 9;
}
.shadowBox2 {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: auto;
height: auto;
}
.shadowBox_img {
width: 600rpx;
height: 900rpx;
background-color: #fff;
border-radius: 20rpx;
}
.boxshadow_tit {
font-size: 32rpx;
color: #222222;
padding-top: 40rpx;
display: flex;
justify-content: center;
align-items: center;
}
.boxshadow_tit_img {
width: 70rpx;
height: 70rpx;
margin-right: 10rpx;
}
.boxshadow_img {
width: 300rpx;
height: 300rpx;
margin: 0 auto;
margin-top: 40rpx;
text-align: center;
}
.boxbottom {
width: 100%;
margin-top: 100rpx;
display: flex;
justify-content: center;
align-items: center;
}
.line1 {
width: 80rpx;
height: 1rpx;
margin: 0 10rpx;
background: linear-gradient(to left, #333, #fff);
}
.line2 {
width: 80rpx;
height: 1rpx;
margin: 0 10rpx;
background: linear-gradient(to right, #333, #fff);
}
.shadowBox1 {
width: 100%;
display: flex;
margin-top: 30rpx;
}
.shadowBox1Item_btn{
width: 110rpx;
height: 150rpx;
border: 1rpx solid red;
position: absolute;
left: 50rpx;
opacity:0;
}
.shadowBox1Item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 26rpx;
color: #000000;
}
.shadowBox1Item image {
width: 100rpx;
height: 100rpx;
margin-bottom: 26rpx;
}
.shadowBoxInfo {
display: flex;
align-items: center;
margin-left: 62rpx;
margin-top: 11rpx;
}
.shadowboxInfo_left {
width: 130rpx;
height: 130rpx;
background: #EFEFEF;
border-radius: 50%;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
margin-right: 36rpx;
}
.shadowboxInfo_right_1 {
font-size: 32rpx;
color: #222222;
margin-bottom: 10rpx;
}
.shadowboxInfo_right_2 {
font-size: 26rpx;
color: #999999;
}
.shadowBox_btn {
font-size: 36rpx;
color: #FFFFFF;
width: 600rpx;
height: 90rpx;
background: linear-gradient(91deg, #FF7658 0%, #FF370B 100%);
border-radius: 100rpx 100rpx 100rpx 100rpx;
display: flex;
align-items: center;
justify-content: center;
margin-top: 60rpx;
}
.empty-tip{
height: 200rpx;
font-size: 28rpx;
color: #999999;
text-align: center;
line-height: 200rpx;
background-color: #fff;
}

View File

@ -0,0 +1,732 @@
<template>
<view class="container">
<!-- 顶部切换栏 -->
<view class="tab-bar">
<!-- <view :class="{ active: activeTab === 'delivery' }" class="tab-item" @click="switchTab('delivery')">配送
</view> -->
<view :class="{ active: activeTab === 'pickup' }" class="tab-item" @click="switchTab('pickup')">自提</view>
</view>
<!-- 分隔线 -->
<view class="divider"></view>
<!-- 配送/自提信息 -->
<view class="info-section" v-if="activeTab === 'delivery'">
<view class="address-section">
<view class="section-title">收货地址</view>
<view class="address-info" @click="chooseAddress" v-if="defAddress">
<view class="address-main">
<view class="address-name-phone">
<text class="name">{{ defAddress.name }}</text>
<text class="phone">{{ defAddress.phone }}</text>
</view>
<view class="address-detail">
{{ defAddress.address }}{{ defAddress.house_number }}
<view class="copy-icon" @click.stop="copyAddress" />
</view>
</view>
<view class="address-arrow"><u-icon name="arrow-right" size="25"></u-icon></view>
</view>
</view>
</view>
<!-- 分隔线 -->
<view class="divider"></view>
<!-- 商品信息 -->
<view v-if="activeTab === 'delivery' && orderList1.length > 0">
<view class="goods-list">
<view class="goods-item" v-for="(item, index) in orderList1" :key="index">
<view class="goods-image">
<image :src="item.commodity_goods_info.commodity_pic" mode="aspectFill"></image>
</view>
<view class="goods-info">
<view class="goods-name">{{ item.commodity_goods_info.goods_name }}</view>
<view class="goods-desc">{{ item.commodity_goods_info.goods_spec }}</view>
<view class="price-container">
<view class="group-price">
<view>{{ item.commodity_goods_info.sales_price }}/{{
item.commodity_goods_info.goods_unit
}}</view>
<!-- 运费 -->
<view class="goods-desc" style="margin-top: 10rpx;">运费 {{
item.commodity_goods_info.freight }}</view>
</view>
<view class="quantity-control">
<view class="decrease-btn" @tap.stop="decreaseQuantity(item)">-</view>
<view class="quantity">{{ item.count }}</view>
<view class="increase-btn" @tap.stop="increaseQuantity(item)">+</view>
</view>
</view>
</view>
</view>
</view>
<!-- 运费 -->
<!-- <view class="fee-section">
<view class="fee-name">运费</view>
<view class="fee-value">{{ item.commodity_goods_info.freight }}</view>
</view> -->
<!-- 总金额 -->
<view class="total-section">
<view class="total-name">总金额</view>
<view class="total-value">{{ calculateTotal('order1') }}</view>
</view>
<!-- 支付方式 -->
<view class="payment-section">
<view class="payment-item" @click="selectPayment('wechat')">
<view class="payment-icon">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_wechat.png"
mode="aspectFit"></image>
</view>
<view class="payment-content">
<view class="payment-name">微信支付</view>
<view class="payment-desc"><text
style="color: #f03d0e;margin-right: 15rpx;">可用优惠券</text>单笔支付限额:¥10000.00</view>
</view>
<view class="payment-select" v-if="selectedPayment === 'wechat'">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png"
mode="aspectFit" style="width: 40rpx; height: 40rpx;"></image>
</view>
<view class="payment-select" v-else>
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png"
mode="aspectFit" style="width: 40rpx; height: 40rpx;"></image>
</view>
</view>
</view>
</view>
<view v-if="activeTab === 'delivery' && orderList1.length == 0" class="empty-tip">
暂无商品数据
</view>
<view v-if="activeTab === 'pickup' && orderList2.length > 0">
<!-- 按供应商分组 -->
<view v-for="(group, supplierId) in supplierGroups" :key="supplierId">
<view class="goods-list">
<view class="info-section">
<view class="address-section">
<view class="section-title">自提点</view>
<view @click="editAddress(group[0])">
<view v-if="defZTAddress.length > 0">
<view v-for="(adItem, adIndex) in defZTAddress" :key="adIndex">
<view class="address-info" v-if="adItem.id == supplierId">
<view class="address-main">
<view class="address-name-phone">
<text class="name">{{ adItem.name }}</text>
<text class="phone">{{ adItem.phone }}</text>
</view>
<view class="address-detail">
{{ adItem.address }}
<view class="copy-icon" @click.stop="copyZTAddress" />
</view>
</view>
<view class="address-arrow"><u-icon name="arrow-right" size="25"></u-icon>
</view>
</view>
</view>
<view class="address-info"
v-if="!defZTAddress.some(adItem => adItem.id == supplierId)">
<view class="address-main">
<view class="address-name-phone">
<text class="name">请选择自提点</text>
</view>
</view>
<view class="address-arrow"><u-icon name="arrow-right" size="25"></u-icon>
</view>
</view>
</view>
<view class="address-info" v-else>
<view class="address-main">
<view class="address-name-phone">
<text class="name">请选择自提点</text>
</view>
</view>
<view class="address-arrow"><u-icon name="arrow-right" size="25"></u-icon></view>
</view>
</view>
</view>
</view>
</view>
<!-- 该供应商下的所有商品 -->
<view class="goods-item" v-for="(item, index) in group" :key="index">
<view class="goods-image">
<image :src="item.commodity_goods_info.commodity_pic" mode="aspectFill"></image>
</view>
<view class="goods-info">
<view class="goods-name">{{ item.commodity_goods_info.goods_name }}</view>
<view class="goods-desc">{{ item.commodity_goods_info.goods_spec }}</view>
<view class="price-container">
<view class="group-price">
<view>
<view v-if="isWithinActivityTime(item)" class="group-price-box">
<view class="group-price1">团购价</view>
<view class="group-price2">
{{ '¥' + item.commodity_goods_info.group_buy_price }}
/{{ item.commodity_goods_info.goods_unit }}
</view>
</view>
<view v-else>
{{ '¥' + item.commodity_goods_info.sales_price }}
/{{ item.commodity_goods_info.goods_unit }}
</view>
</view>
<!-- 运费 -->
<!-- <view class="goods-desc" style="margin-top: 10rpx;">运费 {{
item.commodity_goods_info.freight }}</view> -->
</view>
<view class="quantity-control">
<view class="decrease-btn" @tap.stop="decreaseQuantity(item)">-</view>
<view class="quantity">{{ item.count }}</view>
<view class="increase-btn" @tap.stop="increaseQuantity(item)">+</view>
</view>
</view>
</view>
</view>
</view>
<!-- 运费 -->
<!-- <view class="fee-section">
<view class="fee-name">运费</view>
<view class="fee-value">{{ item.commodity_goods_info.freight }}</view>
</view> -->
<!-- 总金额 -->
<view class="total-section">
<view class="total-name">总金额</view>
<view class="total-value">{{ calculateTotal('order2') }}</view>
</view>
<!-- 支付方式 -->
<view class="payment-section">
<view class="payment-item" @click="selectPayment('wechat')">
<view class="payment-icon">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_wechat.png"
mode="aspectFit"></image>
</view>
<view class="payment-content">
<view class="payment-name">微信支付</view>
<view class="payment-desc"><text
style="color: #f03d0e;margin-right: 15rpx;">可用优惠券</text>单笔支付限额:¥10000.00</view>
</view>
<view class="payment-select" v-if="selectedPayment === 'wechat'">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png"
mode="aspectFit" style="width: 40rpx; height: 40rpx;"></image>
</view>
<view class="payment-select" v-else>
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png"
mode="aspectFit" style="width: 40rpx; height: 40rpx;"></image>
</view>
</view>
</view>
</view>
<view v-if="activeTab === 'pickup' && orderList2.length == 0" class="empty-tip">
暂无商品数据
</view>
<!-- 立即支付按钮 -->
<view class="pay-button" @click="submitPayment">立即支付</view>
<!-- 弹窗 - 支付成功 -->
<view class="shadow" @click="changeShadow" v-if="boxshadow1">
<view class="shadowBox2">
<view class="shadowBox_img">
<view class="boxshadow_tit">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/af_√.png"
class="boxshadow_tit_img">
</image>
已支付成功
</view>
<view class="boxshadow_img">
<view style="margin-bottom: 15rpx;">0230 7559 1358</view>
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_share_img.png">
</image>
</view>
<view class="boxbottom">
<view class="line1"></view>
赶快邀请好友来下单吧
<view class="line2"></view>
</view>
<view @click.stop="changeShadow">
<view class="shadowBox1">
<button class="shadowBox1Item_btn" open-type="share" bindtap="onShareButtonClick" />
<view class="shadowBox1Item" @click="shareFriend">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_WX.png"
mode="aspectFill"></image>
微信好友
</view>
<view class="shadowBox1Item" @click="shareFriend">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_WX.png"
mode="aspectFill"></image>
小程序链接
</view>
<view class="shadowBox1Item" @click="openSave">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_saveImg.png"
mode="aspectFill"></image>
二维码海报
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 海报 -->
<view class="shadow" @click="changeShadow2" v-if="boxshadow2">
<view class="shadowBox2">
<view class="shadowBox_img">
<view class="boxshadow_tit">今日商品推荐</view>
<view class="boxshadow_img">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_share_img.png">
</image>
</view>
<view class="shadowBoxInfo">
<view class="shadowboxInfo_left">二维码</view>
<view class="shadowboxInfo_right">
<view class="shadowboxInfo_right_1">正鲜生</view>
<view class="shadowboxInfo_right_2">
长按识别小程序 <br />
数量有限马上抢购
</view>
</view>
</view>
</view>
<view class="shadowBox_btn" @click.stop="saveImg">保存海报</view>
</view>
</view>
</view>
</template>
<script>
import { picUrl, menuButtonInfo, request, NavgateTo } from "../../../utils";
import { apiArr } from "../../../api/shop";
export default {
data() {
return {
activeTab: 'pickup', //
quantity: 1, //
selectedPayment: 'wechat',
boxshadow1: false,
boxshadow2: false,
defAddress: {},
defZTAddress: [],
orderList1: [],
orderList2: [],
carList: [],
// id
group_buy_activity_id: 0,
};
},
computed: {
// id
supplierGroups() {
const groups = {};
this.orderList2.forEach(item => {
const supplierId = item.supplier_id || 'default';
if (!groups[supplierId]) {
groups[supplierId] = [];
}
groups[supplierId].push(item);
});
return groups;
},
},
onLoad(options) {
this.carList = JSON.parse(options.shopCarList)
},
onShow() {
this.getUserAddress()
this.getZTAddress()
this.getGoodsList()
},
onUnload() {
uni.removeStorageSync('changeZTAddress')
},
methods: {
switchTab(tab) {
this.activeTab = tab;
},
//
getUserAddress() {
request(apiArr.getUserDefAddress, "POST", {}).then(res => {
this.defAddress = res.default_address
})
},
//
getGoodsList() {
this.orderList1 = []
this.orderList2 = []
this.carList.forEach(item => {
// URLhttpspicUrl
if (item.commodity_goods_info.commodity_pic && item.commodity_goods_info.commodity_pic.indexOf('https') !== 0) {
item.commodity_goods_info.commodity_pic = picUrl + item.commodity_goods_info.commodity_pic
}
// const list = item.commodity_goods_info.group_buy_activity_info
const list = true
if (list) {
this.orderList2.push(item)
} else {
this.orderList1.push(item)
}
})
},
getZTAddress() {
setTimeout(() => {
let changeAddress = uni.getStorageSync('changeZTAddress')
if (changeAddress) {
this.defZTAddress = changeAddress
}
}, 100)
},
chooseAddress() {
NavgateTo('../address/index')
},
editAddress(item) {
NavgateTo('../ztLocation/index?item=' + JSON.stringify(item));
},
decreaseQuantity(item) {
const currentTime = new Date().getTime();
const startTime = new Date(item.commodity_goods_info.group_buy_activity_info?.start_time).getTime();
const endTime = new Date(item.commodity_goods_info.group_buy_activity_info?.end_time).getTime();
if (item.count > 0) {
if (currentTime >= startTime && currentTime <= endTime) {
if (item.count == item.commodity_goods_info.min_order_quantity) {
uni.showToast({
title: '最少购买' + item.commodity_goods_info.min_order_quantity + '件',
icon: 'none'
});
item.count = 0
} else {
item.count--
}
} else {
item.count--
}
// 0carList
if (item.count === 0) {
const index = this.carList.findIndex(carItem => carItem.goods_id === item.goods_id);
if (index > -1) {
this.carList.splice(index, 1);
//
this.getGoodsList();
}
}
this.changeCart(item)
}
},
increaseQuantity(item) {
console.log("🚀 ~ increaseQuantity ~ item:", item)
const currentTime = new Date().getTime();
const startTime = new Date(item.commodity_goods_info.group_buy_activity_info?.start_time).getTime();
const endTime = new Date(item.commodity_goods_info.group_buy_activity_info?.end_time).getTime();
if (item.count >= item.commodity_goods_info.stock_quantity) {
uni.showToast({
title: '库存不足',
icon: 'none'
});
return
}
if (currentTime >= startTime && currentTime <= endTime) {
if (item.count == 0) {
item.count += item.commodity_goods_info.min_order_quantity
} else {
if (item.count >= item.commodity_goods_info.stock_quantity) {
uni.showToast({
title: '库存不足',
icon: 'none'
});
return
}
if (item.count == item.commodity_goods_info.max_limit_quantity) {
uni.showToast({
title: '一次最多购买' + item.commodity_goods_info.max_limit_quantity + '件',
icon: 'none'
});
return
}
}
}
item.count++;
this.changeCart(item);
},
//
changeCart(item) {
const params = {
goods_id_and_count: [
{
goods_id: item.goods_id,
count: item.count,
},
],
}
request(apiArr.updateCar, "POST", params).then(res => {
uni.showToast({
title: "操作成功!",
success() { },
});
})
},
//
calculateTotal(order) {
const currentTime = new Date().getTime();
if (order === 'order1') {
let total = 0;
this.orderList1.forEach(goods => {
//
const startTime = new Date(goods.commodity_goods_info.group_buy_activity_info?.start_time).getTime();
const endTime = new Date(goods.commodity_goods_info.group_buy_activity_info?.end_time).getTime();
if (currentTime >= startTime && currentTime <= endTime) {
// total += goods.commodity_goods_info.group_buy_price * goods.count + goods.commodity_goods_info.freight;
total += goods.commodity_goods_info.group_buy_price * goods.count;
} else {
// total += goods.commodity_goods_info.sales_price * goods.count + goods.commodity_goods_info.freight;
total += goods.commodity_goods_info.sales_price * goods.count;
}
});
//
return total.toFixed(2);
} else {
let total = 0;
this.orderList2.forEach(goods => {
//
const startTime = new Date(goods.commodity_goods_info.group_buy_activity_info?.start_time).getTime();
const endTime = new Date(goods.commodity_goods_info.group_buy_activity_info?.end_time).getTime();
if (currentTime >= startTime && currentTime <= endTime) {
// total += goods.commodity_goods_info.group_buy_price * goods.count + goods.commodity_goods_info.freight;
total += goods.commodity_goods_info.group_buy_price * goods.count;
} else {
// total += goods.commodity_goods_info.sales_price * goods.count + goods.commodity_goods_info.freight;
total += goods.commodity_goods_info.sales_price * goods.count;
}
});
//
return total.toFixed(2);
}
},
selectPayment(payment) {
this.selectedPayment = payment;
},
submitPayment() {
//
const supplierIds = [...new Set(this.orderList2.map(item =>
item.supplier_id || 'default'
))];
const allHaveZTAddress = supplierIds.every(supplierId => {
const ztAddress = this.defZTAddress.find(adItem => adItem.id == supplierId);
return !!ztAddress;
});
if (!allHaveZTAddress) {
uni.showToast({
title: '请选择所有货品的自提点',
icon: 'none'
});
return;
}
const params = {
user_id: uni.getStorageSync('userId'),
is_group_buy: true,
goods_list: Object.keys(this.supplierGroups).map(supplierId => {
const group = this.supplierGroups[supplierId];
const firstItem = group[0];
// id
this.group_buy_activity_id = firstItem.commodity_goods_info.group_buy_activity_id;
// id
const ztAddress = this.defZTAddress.find(adItem => adItem.id == supplierId) || {};
//
const currentTime = new Date().getTime();
return {
supplier_id: firstItem.supplier_id,
supplier_name: firstItem.supplier_name || '',
is_same_day: firstItem.commodity_goods_info.is_same_day,
receiving_name: ztAddress.name || '',
receiving_phone: ztAddress.phone || '',
receiving_address: ztAddress.address || '',
group_buy_activity_id: firstItem.commodity_goods_info.group_buy_activity_id,
goods_and_count: group.map(item => {
const startTime = new Date(item.commodity_goods_info.group_buy_activity_info?.start_time).getTime();
const endTime = new Date(item.commodity_goods_info.group_buy_activity_info?.end_time).getTime();
const isGroupBuy = currentTime >= startTime && currentTime <= endTime;
return {
goods_id: item.goods_id,
count: item.count,
price: isGroupBuy ? item.commodity_goods_info.group_buy_price : item.commodity_goods_info.sales_price,
freight: item.commodity_goods_info.freight,
}
})
}
})
}
request(apiArr.createOrder, "POST", params).then(resVal => {
// trans_type
// : 71, App: 51
const systemInfo = uni.getSystemInfoSync();
let trans_type = 51; // App
//
if (systemInfo.platform === 'devtools' || systemInfo.platform === 'unknown') {
trans_type = 71; //
}
//
// #ifdef MP
trans_type = 71; //
// #endif
// #ifdef APP-PLUS
trans_type = 51; // App
// #endif
const param = {
order_id: resVal.order_id,
user_id: uni.getStorageSync('userId'),
trans_type: trans_type
}
request(apiArr.mergePreorder, "POST", param).then(res => {
if (res && res.timeStamp && res.nonceStr && res.package && res.signType && res.paySign) {
//
uni.requestPayment({
timeStamp: res.timeStamp,
nonceStr: res.nonceStr,
package: res.package,
signType: res.signType,
paySign: res.paySign,
success: (payRes) => {
const params = {
order_id: resVal.order_id,
from: 2,
group_buy_activity_id: this.group_buy_activity_id,
}
request(apiArr.queryOrder, "POST", params).then(res => {
this.boxshadow1 = true
})
},
fail: (payErr) => {
uni.showToast({
title: payErr.errMsg == 'requestPayment:fail cancel' ? '用户取消支付' : '支付失败',
icon: 'none'
})
},
complete: () => {
//
}
})
} else {
console.error("获取支付参数失败,缺少必要参数")
uni.showToast({
title: '获取支付信息失败',
icon: 'none'
})
}
})
})
},
//
copyAddress() {
// 使uni-appAPI
uni.setClipboardData({
data: this.defAddress.address + this.defAddress.house_number,
success: () => {
uni.showToast({
title: '复制成功',
icon: 'success'
});
},
fail: () => {
uni.showToast({
title: '复制失败',
icon: 'none'
});
}
});
},
copyZTAddress() {
// 使uni-appAPI
uni.setClipboardData({
data: this.defZTAddress.address,
success: () => {
uni.showToast({
title: '复制成功',
icon: 'success'
});
},
fail: () => {
uni.showToast({
title: '复制失败',
icon: 'none'
});
}
});
},
openSave() {
this.boxshadow1 = false;
this.boxshadow2 = true;
},
changeShadow() {
this.boxshadow1 = false;
},
changeShadow2() {
this.boxshadow2 = false;
},
//
saveImg() {
this.boxshadow2 = false;
//
uni.downloadFile({
url: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_share_img.png",
success: (res) => {
if (res.statusCode === 200) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: (res) => {
uni.showToast({
title: "保存成功",
icon: "success",
duration: 2000,
});
},
fail: (err) => {
console.log("保存失败", err);
},
});
}
},
fail: (err) => {
console.log("下载失败", err);
},
});
},
//
isWithinActivityTime(item) {
if (!item || !item.commodity_goods_info || !item.commodity_goods_info.group_buy_activity_info) {
return false;
}
const now = new Date();
const startTime = new Date(item.commodity_goods_info.group_buy_activity_info?.start_time);
const endTime = new Date(item.commodity_goods_info.group_buy_activity_info?.end_time);
return now >= startTime && now <= endTime;
},
}
};
</script>
<style>
@import url('./index.css');
</style>

View File

@ -106,6 +106,10 @@ page {
white-space: nowrap;
}
.slide_item_active text {
color: #ff5f3c;
}
.Con {
flex: 1;
display: flex;
@ -158,7 +162,7 @@ page {
overflow: hidden;
position: relative;
overflow-y: auto;
margin-bottom: 150rpx;
padding-bottom: 260rpx;
}
.CateInfo_tit {
@ -311,11 +315,14 @@ page {
}
.CateList_Box {
width: 71.5%;
display: flex;
overflow: hidden;
position: relative;
z-index: 9;
/* position: relative; */
position: fixed;
z-index: 15;
padding: 20rpx 10rpx;
background-color: #ffffff;
}
.CateList {
@ -333,7 +340,7 @@ page {
height: 40rpx;
background: #F6F7FB;
border-radius: 10rpx 10rpx 10rpx 10rpx;
padding: 5rpx 30rpx;
padding: 5rpx 20rpx;
font-size: 26rpx;
color: #222222;
display: flex;
@ -360,6 +367,10 @@ page {
margin-left: 10rpx;
}
.CateIte {
margin-top: 80rpx;
}
.CateInfo {
margin: 0 10rpx;
padding: 10rpx 10rpx;
@ -392,8 +403,8 @@ page {
padding-bottom: 30rpx;
position: absolute;
left: 0;
top: 0;
z-index: 11;
top: 160rpx;
z-index: 20;
}
.header2 .slide .slide_con .slide_conBox:nth-child(5n) {
@ -418,7 +429,7 @@ page {
left: 0;
right: 0;
bottom: 0;
top: 0;
top: 160rpx;
background-color: rgba(0, 0, 0, 0.3);
z-index: 10;
}
@ -431,13 +442,14 @@ page {
padding: 20rpx 12rpx;
padding-right: 0;
position: absolute;
top: 85rpx;
z-index: 9;
width: 100%;
}
.activeCateList .CateList_Item {
margin-bottom: 16rpx;
margin-right: 28rpx;
margin-right: 20rpx;
}
.activeCateList .CateList_Item:nth-child(4n) {
@ -566,9 +578,9 @@ page {
.shop_car {
width: 140rpx;
height: 140rpx;
position: fixed;
right: 33rpx;
bottom: 180rpx;
position: absolute;
bottom: 100rpx;
right: 10rpx;
z-index: 10;
}
@ -579,6 +591,26 @@ page {
.u-badge {
position: absolute;
right: 0;
right: 70rpx;
/* 调整角标位置,使其在隐藏状态下也能看到 */
top: -10rpx;
z-index: 11;
}
.empty {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-weight: normal;
font-size: 28rpx;
color: #999999;
margin-top: 350rpx;
width: 100%;
}
.empty image {
width: 366rpx;
height: 226rpx;
margin-bottom: 27rpx;
}

View File

@ -1,101 +1,58 @@
<template>
<div class="container">
<view class="container">
<!-- 顶部展开后的阴影 -->
<div class="boxshadow" v-if="topShow"></div>
<div class="header" :class="topShow ? 'op0' : ''">
<div
class="searchBox"
:style="{ height: localHeight + 'px', paddingTop: top + 'px' }"
>
<div class="searchBox_left">
<!-- <u-icon name="arrow-left" size="20px" color="#000"></u-icon> -->
</div>
<div class="searchBox_ipt" @click="searchPage">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_communitySearchIcon.png"
mode="aspectFill"
></image>
<view class="boxshadow" v-if="topShow"></view>
<view class="header">
<view class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }">
<view class="searchBox_left" @click="back">
<u-icon name="arrow-left" size="20px" color="#000"></u-icon>
</view>
<view class="searchBox_ipt" @click="searchPage">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_communitySearchIcon.png"
mode="aspectFill"></image>
<input disabled type="text" placeholder="输入商品名称" />
</div>
</div>
<div class="slide">
<div class="slide_con">
<div
v-for="(item, index) in CateList"
:key="index"
class="slide_conBox"
@click="changeCate(item.id)"
>
<view class="slide_item">
<image
:src="picUrl + item.category_pic"
mode="aspectFill"
></image>
</view>
</view>
<view class="slide">
<view class="slide_con">
<view v-for="(item, index) in CateList" :key="index" class="slide_conBox" @click="changeCate(item.id)">
<view class="slide_item" :class="item.id === currentCategoryId ? 'slide_item_active' : ''">
<image :src="picUrl + item.category_pic" mode="aspectFill"></image>
<text>{{ item.category_name }}</text>
</view>
</div>
</div>
</view>
</view>
<div class="open" @click="topOpen" v-if="!topShow">
<view class="open" @click="topOpen" v-if="!topShow">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_openIcon.png"
mode="aspectFill"
></image>
</div>
</div>
</div>
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_openIcon.png"
mode="aspectFill"></image>
</view>
</view>
</view>
<!-- 整体展开的顶部 -->
<div class="header header2" v-if="topShow">
<div
class="searchBox"
:style="{ height: localHeight + 'px', paddingTop: top + 'px' }"
>
<div class="searchBox_left">
<u-icon name="arrow-left" size="20px" color="#000"></u-icon>
</div>
<div class="searchBox_ipt">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_communitySearchIcon.png"
mode="aspectFill"
></image>
<input type="text" placeholder="输入商品名称" />
</div>
</div>
<div class="slide">
<div class="slide_con">
<div
v-for="(item, index) in CateList"
:key="index"
class="slide_conBox"
>
<view class="slide_item">
<image
:src="picUrl + item.category_pic"
mode="aspectFill"
></image>
<view class="header header2" v-if="topShow">
<view class="slide">
<view class="slide_con">
<view v-for="(item, index) in CateList" :key="index" class="slide_conBox" @click="changeCate(item.id)">
<view class="slide_item" :class="item.id === currentCategoryId ? 'slide_item_active' : ''">
<image :src="picUrl + item.category_pic" mode="aspectFill"></image>
<text>{{ item.category_name }}</text>
</view>
</div>
</div>
</div>
</view>
</view>
</view>
<div class="hides" @click="topOpen">
<view class="hides" @click="topOpen">
收起 <u-icon name="arrow-up"></u-icon>
</div>
</div>
</view>
</view>
<div class="Con">
<div class="Con_left">
<div
class="CateItem"
:class="item.id === currentLeftCateId ? 'CateItem_active' : ''"
v-for="item in leftCateList"
:key="item.id"
@click="changeLeftCate(item.id)"
>
<view class="Con">
<view class="Con_left">
<view class="CateItem" :class="item.id === currentLeftCateId ? 'CateItem_active' : ''"
v-for="item in leftCateList" :key="item.id" @click="changeLeftCate(item.id)">
<!-- <image v-if="false" class="hot"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_hot.png"
mode="aspectFill">
@ -104,222 +61,157 @@
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_bao.png"
mode="aspectFill"></image> -->
{{ item.category_name }}
</div>
</div>
<div class="Con_right">
<div class="CateList_Box" :class="cateListShow ? 'bgf' : ''">
<div class="CateList" ref="cateListRef">
<div
class="CateList_Item"
v-for="(item, index) in tagList"
:key="item.id"
:class="index == rightTopActive ? 'CateList_Item_active' : ''"
@click="checkItem(index)"
>
</view>
</view>
<view class="Con_right" v-if="tagList1.length > 0">
<view class="CateList_Box" :class="cateListShow ? 'bgf' : ''">
<view class="CateList" ref="cateListRef">
<view class="CateList_Item" v-for="(item, index) in tagList" :key="item.id"
:class="index == rightTopActive ? 'CateList_Item_active' : ''" @click="checkItem(index)">
{{ item.tag_name }}
</div>
</div>
<div class="more" @click="changeCateListShow">
</view>
</view>
<view class="more" @click="changeCateListShow">
<u-icon v-if="!cateListShow" name="arrow-down"></u-icon>
<u-icon v-if="cateListShow" name="arrow-up"></u-icon>
</div>
</div>
</view>
</view>
<!-- 右下展开的内容 -->
<div class="activeCateList" v-if="cateListShow">
<div
class="CateList_Item"
v-for="(item, index) in tagList"
:key="index"
:class="index == rightTopActive ? 'CateList_Item_active' : ''"
@click="checkItem(index)"
>
<view class="activeCateList" v-if="cateListShow">
<view class="CateList_Item" v-for="(item, index) in tagList" :key="index"
:class="index == rightTopActive ? 'CateList_Item_active' : ''" @click="checkItem(index)">
{{ item.tag_name }}
</div>
</div>
</view>
</view>
<!-- 右下阴影 -->
<div class="boxshadow2" v-if="cateListShow"></div>
<view class="boxshadow2" v-if="cateListShow" @click="changeCateListShow"></view>
<div class="CateInfo" v-for="item in tagList" :key="item.id">
<div class="CateInfo_tit">
<view class="CateIte">
<view class="CateInfo"
v-for="item in (selectedTagId === 'all' ? tagList.slice(1) : [tagList.find(t => t.id === selectedTagId) || {}])"
:key="item.id">
<view class="CateInfo_tit">
{{ item.tag_name }}
</div>
<div
class="CateInfo_Item"
v-for="items in item.commodity_info_list"
:key="items.id"
>
<div class="CateInfo_Item_Box">
<div class="CateInfo_Item_left" @click="goods(items)">
<view
class="tag tag-img"
v-if="
</view>
<view class="CateInfo_Item" v-for="items in item.commodity_info_list" :key="items.id">
<view class="CateInfo_Item_Box">
<view class="CateInfo_Item_left" @click="goods(items)">
<view class="tag tag-img" v-if="
!items.commodity_goods_info_list[1] &&
items.commodity_goods_info_list[0].is_same_day
"
>当日达</view
>
<image
:src="picUrl + items.commodity_pic"
mode="aspectFill"
></image>
</div>
<div class="CateInfo_Item_right" :class="GGshow ? 'noneBor' : ''">
<div class="CateInfo_Item_right_Tit" @click="goods(items)">
<view
class="tag tag-text"
v-if="
">当日达</view>
<image :src="picUrl + items.commodity_pic" mode="aspectFill"></image>
</view>
<view class="CateInfo_Item_right" :class="GGshow ? 'noneBor' : ''">
<view class="CateInfo_Item_right_Tit" @click="goods(items)">
<view class="tag tag-text" v-if="
!items.commodity_goods_info_list[1] &&
items.commodity_goods_info_list[0].is_same_day
"
>当日达</view
>
">当日达</view>
{{ items.commodity_name }}
</div>
<div class="CateInfo_Item_right_subtit" @click="goods(items)">
</view>
<view class="CateInfo_Item_right_subtit" @click="goods(items)">
{{ items.commodity_intro }}
</div>
<div class="CateInfo_Item_Money">
<div class="CateInfo_Item_Money_left">
</view>
<view class="CateInfo_Item_Money">
<view class="CateInfo_Item_Money_left">
{{ getPriceRange(items.commodity_goods_info_list) }}
</div>
<div
class="CateInfo_Item_Money_right"
v-if="!(items.commodity_goods_info_list.length > 1)"
>
<u-number-box
:min="0"
v-model="items.commodity_goods_info_list[0].quantity"
@change="(value) => handleQuantityChange(value, items)"
>
</view>
<view class="CateInfo_Item_Money_right" v-if="!(items.commodity_goods_info_list.length > 1)">
<u-number-box :min="0" v-model="items.commodity_goods_info_list[0].quantity"
@change="(value) => handleQuantityChange(value, items)">
<view slot="minus" class="minus">
<u-icon name="minus" size="20"></u-icon>
</view>
<text
slot="input"
style="width: 50px; text-align: center"
class="input"
>{{
<text slot="input" style="width: 50px; text-align: center" class="input">{{
items.commodity_goods_info_list[0].quantity
? items.commodity_goods_info_list[0].quantity
: 0
}}</text
>
}}</text>
<view slot="plus" class="plus">
<u-icon name="plus" color="#FFFFFF" size="20"></u-icon>
</view>
</u-number-box>
</div>
</div>
</view>
</view>
<div
class="gg"
@click="chooseGG(items)"
v-if="
<view class="gg" @click="chooseGG(item,items)" v-if="
items.commodity_goods_info_list.length > 1 && !items.isShow
"
>
">
选择规格
<u-icon
name="arrow-down"
size="26rpx"
color="#FF370B"
></u-icon>
</div>
<u-icon name="arrow-down" size="26rpx" color="#FF370B"></u-icon>
</view>
<div
class="gg"
@click="chooseGG(items)"
v-if="
<view class="gg" @click="chooseGG(item,items)" v-if="
items.commodity_goods_info_list.length > 1 && items.isShow
"
>
">
收起
<u-icon name="arrow-up" size="26rpx" color="#FF370B"></u-icon>
</div>
</div>
</div>
</view>
</view>
</view>
<div class="GGList" v-if="items.isShow">
<div
class="GGItem"
v-for="ite in items.commodity_goods_info_list"
:key="ite.id"
@click="goods(items)"
>
<div class="GGItem_Image">
<view class="GGList" v-if="items.isShow">
<view class="GGItem" v-for="ite in items.commodity_goods_info_list" :key="ite.id" @click="goods(ite,items)">
<view class="GGItem_Image">
<view class="tag tag-img" v-if="ite.is_same_day">当日达</view>
<image
:src="picUrl + ite.commodity_pic"
mode="aspectFill"
></image>
</div>
<div class="GGItem_Con">
<div class="GGItem_Con_Tit">
<view class="tag tag-text" v-if="ite.is_same_day"
>当日达</view
>
<image :src="picUrl + ite.commodity_pic" mode="aspectFill"></image>
</view>
<view class="GGItem_Con">
<view class="GGItem_Con_Tit">
<view class="tag tag-text" v-if="ite.is_same_day">当日达</view>
{{ ite.goods_name }}
</div>
<div class="GGItem_Con_Msg">
<div class="GGItem_Con_Msg_left">
</view>
<view class="GGItem_Con_Msg">
<view class="GGItem_Con_Msg_left">
<span></span>{{ ite.sales_price }}
</div>
<div class="GGItem_Con_Msg_right">
<u-number-box
v-model="ite.quantity"
:min="0"
@change="(value) => handleQuantityChange(value, ite)"
>
</view>
<view class="GGItem_Con_Msg_right">
<u-number-box v-model="ite.quantity" :min="0"
@change="(value) => handleQuantityChange(value, ite)">
<view slot="minus" class="minus">
<u-icon name="minus" size="20"></u-icon>
</view>
<text
slot="input"
style="width: 50px; text-align: center"
class="input"
>{{ ite.quantity ? ite.quantity : 0 }}</text
>
<text slot="input" style="width: 50px; text-align: center" class="input">{{ ite.quantity ?
ite.quantity : 0 }}</text>
<view slot="plus" class="plus">
<u-icon
name="plus"
color="#FFFFFF"
size="20"
></u-icon>
<u-icon name="plus" color="#FFFFFF" size="20"></u-icon>
</view>
</u-number-box>
</div>
</div>
</div>
</div>
</div>
</div>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 按钮 -->
<!-- <div class="btn">
<!-- <view class="btn">
查看全部商品
<div class="cir">
<view class="cir">
<u-icon name="arrow-right" color="#fff" size="12px"></u-icon>
</div>
</div> -->
</div>
</div>
</div>
</view>
</view> -->
</view>
</view>
</view>
<view class="Con_right" v-else>
<view class="empty">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_nearbyList_empty.png"
mode="aspectFill"></image>
暂无数据
</view>
</view>
</view>
<!-- <nav-footer :current="3" /> -->
<div class="shop_car" @click="shopCar">
<u-badge
numberType="limit"
type="error"
max="99"
:value="carNum"
></u-badge>
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_car_num.png"
></image>
<view class="shop_car" @click="shopCar">
<u-badge numberType="limit" type="error" max="99" :value="carNum"></u-badge>
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_car_num.png"></image>
<!-- <image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_car_empty.png"></image> -->
</div>
</div>
</view>
</view>
</template>
<script>
@ -335,6 +227,7 @@ export default {
search: "",
value: "1",
cateListShow: false,
conRightElement: null,
iconList: [
{
icon: "https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_icon1.png",
@ -382,8 +275,11 @@ export default {
rightTopActive: 0,
currentLeftCateId: null,
topShow: false,
currentCategoryId: null,
GGshow: false,
originalTagList: [], // tagList
selectedTagId: null, // ID
CateList: [], //
currentFirstId: "",
leftCateList: [], //
@ -392,6 +288,7 @@ export default {
currentThirdId: "",
tagList: [],
tagList1: [],
carNum: "",
goodsDetail: [],
@ -400,15 +297,30 @@ export default {
};
},
methods: {
back() {
NavgateTo('1')
},
changeCate(id) {
this.checkItem(0)
// ID
this.currentCategoryId = id;
// id
const category = this.CateList.find((item) => item.id === id);
if (category) {
// leftCateListnull
this.leftCateList = category.level_two_category || [];
this.secondId = this.leftCateList[0]?.id;
this.tagList1 = category.level_three_category || [];
if (this.leftCateList.length > 0) {
this.currentLeftCateId = this.leftCateList[0].id;
this.secondId = this.leftCateList[0].id;
} else {
this.currentLeftCateId = null;
this.secondId = null;
}
this.getGoodsList();
}
this.topShow = false;
},
//
changeCateListShow() {
@ -416,25 +328,42 @@ export default {
},
//
checkItem(index) {
this.cateListShow = false
this.rightTopActive = index;
// ID
this.selectedTagId = this.tagList[index]?.id;
},
//
topOpen() {
this.topShow = !this.topShow;
},
//
chooseGG(e) {
e.isShow = !e.isShow;
chooseGG(item,targetItems) {
// id
if (item && targetItems && item.id) {
for (let i = 1; i < this.tagList.length; i++) {
const tagItem = this.tagList[i];
// item.idtagItem
if (tagItem.id === item.id) {
const infoIndex = tagItem.commodity_info_list.findIndex(infoItem => infoItem.id === targetItems.id);
if (infoIndex > -1) {
//
const currentItem = tagItem.commodity_info_list[infoIndex];
this.$set(currentItem, 'isShow', !currentItem.isShow);
console.log("修改后数据源中的isShow:", currentItem.isShow);
break;
}
}
}
}
},
//
searchPage() {
NavgateTo("../search/index");
},
//
goods(e) {
console.log(`${JSON.stringify(e)}`);
NavgateTo(`../goods/index?item=${JSON.stringify(e)}`);
// NavgateTo("../goods/index");
goods(ite,items) {
NavgateTo(`../goods/index?item=${JSON.stringify(ite)}`);
},
//
@ -447,6 +376,8 @@ export default {
console.log(res);
this.CateList = res.commodity_category_list;
this.firstId = res.commodity_category_list[0].id;
//
this.currentCategoryId = this.firstId;
this.leftCateList =
res.commodity_category_list[0].level_two_category || [];
if (this.leftCateList.length > 0) {
@ -463,33 +394,39 @@ export default {
getGoodsList() {
if (!this.secondId) {
this.tagList = [];
this.originalTagList = [];
return;
}
request(apiArr.getGoodsList, "POST", {
user_id: uni.getStorageSync("userId"),
id: this.secondId,
}).then((res) => {
console.log(123);
console.log(res)
res.commodity_list.forEach((item) => {
item.commodity_info_list.forEach((item) => {
item.commodity_goods_info_list.forEach((param) => {
//
const commodityList = JSON.parse(JSON.stringify(res.commodity_list));
commodityList.forEach((tagItem) => { //
tagItem.commodity_info_list.forEach((infoItem) => { //
// isShow
this.$set(infoItem, 'isShow', false);
infoItem.commodity_goods_info_list.forEach((param) => {
this.goodsDetail.forEach((goods) => {
if (goods.goods_id === param.id) {
param.quantity = goods.count;
this.$set(param, 'quantity', goods.count); // $set
}
});
});
item.isShow = false;
});
});
this.tagList = res.commodity_list;
this.originalTagList = commodityList;
this.tagList1 = commodityList;
// tagList使
this.tagList = [{ id: 'all', tag_name: '全部' }, ...commodityList];
this.rightTopActive = 0;
this.selectedTagId = 'all';
});
},
getShopCarList() {
request(apiArr.getCar, "POST").then((res) => {
console.log(res);
this.carNum = res.total;
//
this.goodsDetail = [].concat(res.same_day_cart_list, res.normal_cart_list)
@ -504,32 +441,88 @@ export default {
},
//
handleQuantityChange(val, item) {
const quantity = typeof val === 'object' && val !== null && 'value' in val ? val.value : val;
//
let currentQuantity = 0;
let stockQuantity = 0;
let goodsToUpdate = null;
// items.commodity_goods_info_list[0].quantity
if (
item.commodity_goods_info_list &&
item.commodity_goods_info_list.length
) {
this.goodsId = item.commodity_goods_info_list[0].id;
} else {
this.goodsId = item.id;
currentQuantity = item.commodity_goods_info_list[0].quantity || 0;
stockQuantity = item.commodity_goods_info_list[0].stock_quantity || 0;
goodsToUpdate = item.commodity_goods_info_list[0];
}
// ite.quantity
else {
this.goodsId = item.id;
currentQuantity = item.quantity || 0;
stockQuantity = item.stock_quantity || 0;
goodsToUpdate = item;
}
//
if (quantity > currentQuantity && currentQuantity >= stockQuantity) {
uni.showToast({
title: "库存不足",
icon: 'none'
});
return;
}
// 使$set
this.$set(goodsToUpdate, 'quantity', quantity);
const params = {
user_id: uni.getStorageSync("userId"),
goods_id_and_count: [
{
goods_id: this.goodsId,
count: val.value,
count: quantity,
},
],
};
//
request(apiArr.updateCar, "POST", params).then((res) => {
console.log(res);
//
this.getShopCarList();
// goodsDetail
setTimeout(() => {
//
this.syncGoodsQuantities();
}, 100);
uni.showToast({
title: "操作成功!",
success() { },
});
});
},
//
syncGoodsQuantities() {
//
this.tagList.forEach((tagItem) => {
if (tagItem.commodity_info_list) {
tagItem.commodity_info_list.forEach((infoItem) => {
infoItem.commodity_goods_info_list.forEach((param) => {
const goods = this.goodsDetail.find(g => g.goods_id === param.id);
if (goods) {
this.$set(param, 'quantity', goods.count);
}
});
});
}
});
},
getPriceRange(goodsList) {
if (!goodsList || goodsList.length === 0) return '¥0';
const prices = goodsList.map(item => Number(item.sales_price));
@ -549,6 +542,13 @@ export default {
this.getShopCarList();
this.getGoodsList();
},
onHide() {
//
if (this.conRightElement) {
this.conRightElement = null;
}
},
onReachBottom() {
if (this.flag) {
}

View File

@ -69,6 +69,12 @@ image {
margin-top: 48rpx;
}
.hisTop{
display: flex;
align-items: center;
justify-content: space-between;
}
.hisTit {
font-size: 33rpx;
color: #222222;
@ -182,12 +188,17 @@ image {
.tag-img {
position: absolute;
/* top: 1; */
bottom: 1;
left: 10;
top: 0;
left: 0;
z-index: 1;
}
.tag-text {
display: inline-block;
vertical-align: middle;
margin-right: 20rpx;
}
.tag-name {
background-color: #ff7d00;
color: white;
@ -209,6 +220,171 @@ image {
margin-top: 10rpx;
}
/* 商品信息样式 */
.CateInfo_Item_Box {
display: flex;
padding: 20rpx 40rpx;
border-bottom: 1rpx solid #EBEBEB;
position: relative;
}
.CateInfo_Item_left {
width: 140rpx;
min-width: 140rpx;
height: 140rpx;
border-radius: 20rpx 20rpx 20rpx 20rpx;
overflow: hidden;
margin-right: 15rpx;
position: relative;
}
.CateInfo_Item_left image {
width: 100%;
height: 100%;
}
.CateInfo_Item_right {
flex: 1;
}
.CateInfo_Item_right_Tit {
font-size: 30rpx;
color: #000000;
font-weight: bold;
margin-bottom: 10rpx;
}
.CateInfo_Item_right_subtit {
font-size: 26rpx;
color: #999999;
margin-top: 10rpx;
}
.CateInfo_Item_Money {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 27rpx;
}
.CateInfo_Item_Money_left {
font-size: 34rpx;
color: #FF370B;
}
.CateInfo_Item_Money_left span {
font-size: 28rpx;
}
.CateInfo_Item_Money_right .input {
padding: 0;
}
/* 数量选择器样式 */
.minus {
width: 22px;
height: 22px;
border-width: 1px;
border-color: #E6E6E6;
border-style: solid;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
}
.input {
padding: 0 10px;
}
.plus {
width: 22px;
height: 22px;
background-color: #FF0000;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
}
/* 规格选择样式 */
.gg {
width: 142rpx;
height: 40rpx;
background: #FFEBEB;
border-radius: 20rpx 20rpx 20rpx 20rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 24rpx;
color: #FF370B;
position: absolute;
right: 100rpx;
bottom: 20rpx;
}
.GGList {
width: 550rpx;
background: rgba(255, 239, 239, 0.5);
border-radius: 20rpx 20rpx 20rpx 20rpx;
padding: 25rpx 16rpx;
box-sizing: border-box;
margin-left: 26rpx;
position: relative;
left: 22%;
}
.noneBor {
border-bottom: none;
}
.GGItem {
display: flex;
align-items: center;
margin-bottom: 10rpx;
}
.GGItem_Image {
width: 120rpx;
height: 100rpx;
margin: 0 20rpx 20rpx 0;
position: relative;
}
.GGItem_Image image {
border-radius: 20rpx;
}
.GGItem_Con_Tit {
font-size: 28rpx;
color: #000000;
}
.GGItem_Con {
flex: 1;
}
.GGItem_Con_Msg_left {
display: flex;
font-size: 30rpx;
color: #FF370B;
}
.GGItem_Con_Msg_left span {
font-size: 24rpx;
}
.GGItem_Con_Msg {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 20rpx;
}
.GGItem_Con_Msg_right .input {
padding: 0;
}
.searchItem_right_Money {
display: flex;
align-items: center;

View File

@ -1,109 +1,152 @@
<template>
<view class="merchantList">
<div class="searchBox">
<div class="searchBox_left">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_communitySearchIcon.png"></image>
<u--input @focus="iptFocus" @blur="iptBlur" placeholder="搜索商品" border="surround" clearable></u--input>
<!-- 测试用 -->
<!-- <input type="text" v-model="searchQuery" placeholder="请输入搜索内容" @input="onSearch" @focus="showHistory = true" class="search-input" />
<view v-if="results.length" class="search-results">
<view class="result-item">
{{item}}
<view class="searchBox">
<view class="searchBox_left">
<image
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_communitySearchIcon.png"
@click="search">
</image>
<u--input v-model="searchQuery" @focus="iptFocus" @blur="iptBlur" @confirm="search" placeholder="搜索商品"
border="surround" clearable></u--input>
</view>
</view> -->
<!-- 测试用 -->
</div>
<div class="searchBox_right">
<div class="cars">
<view class="searchBox_right">
<view class="cars" @click="goCar">
<u-badge numberType="limit" type="error" max="99" :value="value"></u-badge>
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_car.png" mode="widthFix"></image>
</div>
</div>
</div>
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/shop_car.png"
mode="widthFix"></image>
</view>
</view>
</view>
<!-- 搜索联系 -->
<div class="searchMore" v-if="isSearch">
<div class="searchMoreItem">猪肉肠</div>
<div class="searchMoreItem">猪肉肠</div>
<div class="searchMoreItem">猪肉肠</div>
</div>
<!-- <view class="searchMore" v-if="!isSearched && searchHistory.length > 0">
<view class="searchMoreItem">猪肉肠</view>
<view class="searchMoreItem">猪肉肠</view>
<view class="searchMoreItem">猪肉肠</view>
</view> -->
<!-- 搜索历史 -->
<div class="his" v-if="isSearch">
<div class="hisTit">搜索历史</div>
<div class="HisList">
<div class="HisItem">羊肉</div>
<div class="HisItem">火锅底料</div>
<div class="HisItem">蒜蓉辣酱</div>
<div class="HisItem">蒜蓉辣酱</div>
<div class="HisItem">蒜蓉辣酱</div>
<div class="HisItem">蒜蓉辣酱</div>
</div>
</div>
<!-- 测试用 -->
<!-- <view v-if="showHistory && searchHistory.length > 0" class="history-list">
<view
v-for="(item, index) in searchHistory"
:key="index"
class="history-item"
@click="selectHistory(item)"
>
{{ item }}
<view class="his" v-if="!isSearched && searchHistory.length > 0">
<view class="hisTop">
<view class="hisTit">搜索历史</view>
<u-icon name="trash" color="#999999" size="40" class="history-trash" @click="deleteHistory"></u-icon>
</view>
<view class="HisList">
<view v-for="(item, index) in searchHistory" :key="index" class="HisItem" @click="selectHistory(item)">
{{ item }}</view>
</view>
</view>
</view> -->
<!-- 测试用 -->
<!-- 未搜索到 -->
<div class="empty" v-if="false">
<view class="empty" v-if="isSearched && searchGoodsLisat.length == 0">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_noSearch.png"></image>
对不起没有找到您想要的商品
</div>
<div class="searchList">
<div class="searchSubTit">
<div class="searchSubItem">综合</div>
<div class="searchSubItem">
价格
<div class="iconBox">
</div>
</div>
</div>
<div class="searchItem">
<div class="searchItem_left">
<view class="tag tag-img">当日达</view>
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_act2Img.png" mode="widthFix"></image>
</div>
<div class="searchItem_right">
<div class="searchItem_right_tit"><div class="tag-name" v-if="">当日达</div><div>泰国金枕榴莲</div></div>
<div class="searchItem_right_subTit">商品介绍商品介绍</div>
<div class="searchItem_right_Money">
<div class="Money_left">
<div class="money_unit"></div>
125.9
<div class="Money_dw">/</div>
</div>
<div class="Money_right">
<u-number-box v-model="value">
<view slot="minus" class="minus">
<u-icon name="minus" size="22" bold></u-icon>
</view>
<text slot="input" style="width: 80rpx;text-align: center;" class="input">{{ value
<view class="searchList" v-if="isSearched && searchGoodsLisat.length > 0">
<!-- <view class="searchSubTit">
<view class="searchSubItem">综合</view>
<view class="searchSubItem">
价格
<view class="iconBox">
</view>
</view>
</view> -->
<view v-for="(item, index) in searchGoodsLisat" :key="index">
<view class="CateInfo_Item_Box">
<view class="CateInfo_Item_left" @click="goods(item)">
<view class="tag tag-img" v-if="
!item.commodity_goods_info_list[1] &&
item.commodity_goods_info_list[0].is_same_day
">当日达</view>
<image :src="handleImageUrl(item.commodity_pic)" mode="aspectFill"></image>
</view>
<view class="CateInfo_Item_right" :class="GGshow ? 'noneBor' : ''">
<view class="CateInfo_Item_right_Tit" @click="goods(item)">
<view class="tag tag-text" v-if="
!item.commodity_goods_info_list[1] &&
item.commodity_goods_info_list[0].is_same_day
">当日达</view>
{{ item.commodity_name }}
</view>
<view class="CateInfo_Item_right_subtit" @click="goods(item)">
{{ item.commodity_intro }}
</view>
<view class="CateInfo_Item_Money">
<view class="CateInfo_Item_Money_left">
{{ getPriceRange(item.commodity_goods_info_list) }}
</view>
<view class="CateInfo_Item_Money_right" v-if="!(item.commodity_goods_info_list.length > 1)">
<u-number-box :min="0" v-model="item.commodity_goods_info_list[0].quantity"
@change="(value) => handleQuantityChange(value, item)">
<view slot="minus" class="minus">
<u-icon name="minus" size="20"></u-icon>
</view>
<text slot="input" style="width: 50px; text-align: center" class="input">{{
item.commodity_goods_info_list[0].quantity
? item.commodity_goods_info_list[0].quantity
: 0
}}</text>
<view slot="plus" class="plus">
<u-icon name="plus" color="#FFFFFF" size="22" bold></u-icon>
<u-icon name="plus" color="#FFFFFF" size="20"></u-icon>
</view>
</u-number-box>
</div>
</div>
</div>
</div>
</div>
</view>
</view>
<view class="gg" @click="chooseGG(item)" v-if="
item.commodity_goods_info_list.length > 1 && !item.isShow
">
选择规格
<u-icon name="arrow-down" size="26rpx" color="#FF370B"></u-icon>
</view>
<view class="gg" @click="chooseGG(item)" v-if="
item.commodity_goods_info_list.length > 1 && item.isShow
">
收起
<u-icon name="arrow-up" size="26rpx" color="#FF370B"></u-icon>
</view>
</view>
</view>
<view class="GGList" v-if="item.isShow">
<view class="GGItem" v-for="ite in item.commodity_goods_info_list" :key="ite.id"
@click="goods(item)">
<view class="GGItem_Image">
<view class="tag tag-img" v-if="ite.is_same_day">当日达</view>
<image :src="handleImageUrl(ite.commodity_pic)" mode="aspectFill"></image>
</view>
<view class="GGItem_Con">
<view class="GGItem_Con_Tit">
<view class="tag tag-text" v-if="ite.is_same_day">当日达</view>
{{ ite.goods_name }}
</view>
<view class="GGItem_Con_Msg">
<view class="GGItem_Con_Msg_left">
<span></span>{{ ite.sales_price }}
</view>
<view class="GGItem_Con_Msg_right">
<u-number-box v-model="ite.quantity" :min="0"
@change="(value) => handleQuantityChange(value, ite)">
<view slot="minus" class="minus">
<u-icon name="minus" size="20"></u-icon>
</view>
<text slot="input" style="width: 50px; text-align: center" class="input">{{
ite.quantity ?
ite.quantity : 0 }}</text>
<view slot="plus" class="plus">
<u-icon name="plus" color="#FFFFFF" size="20"></u-icon>
</view>
</u-number-box>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
@ -111,9 +154,9 @@
<script>
import {
apiArr
} from '../../../api/doorToDoor';
} from '../../../api/shop';
import {
picUrl,
picUrl as basePicUrl,
menuButtonInfo,
request,
NavgateTo
@ -122,82 +165,224 @@ export default {
data() {
return {
flag: false,
value: 3,
value: 0,
isSearch: false,
//
// searchQuery: '',
// results: [], //
// showHistory: false, //
// searchHistory: [] //
//
isSearched: false,
searchQuery: '',
searchHistory: [],
searchGoodsLisat: [],
goodsDetail: []
}
},
methods: {
goCar() {
NavgateTo('/packages/shop/shopCar/index')
},
getShopCar() {
request(apiArr.getCar, "POST", {}).then((res) => {
this.value = res.total;
});
},
//
getShopCarList() {
request(apiArr.getCar, "POST").then((res) => {
this.value = res.total;
//
this.goodsDetail = [].concat(res.same_day_cart_list || [], res.normal_cart_list || [])
.flatMap(supplier => supplier.commodity_cart_and_goods_model || []);
});
},
search() {
if (this.searchQuery.trim()) {
// storage
this.saveSearchHistory();
//
this.isSearched = true;
//
this.isSearch = false;
const params = {
query: this.searchQuery,
user_id: uni.getStorageSync('userId')
}
request(apiArr.goodsSearch, "POST", params).then((res) => {
//
const commodityList = JSON.parse(JSON.stringify(res.commodity_list));
commodityList.forEach((item) => {
// isShow
this.$set(item, 'isShow', false);
item.commodity_goods_info_list.forEach((param) => {
// 0
const goods = this.goodsDetail.find(g => g.goods_id === param.id);
this.$set(param, 'quantity', goods ? goods.count : 0);
});
});
this.searchGoodsLisat = commodityList;
});
}
},
ipt1(e) {
console.log(e);
},
iptFocus() {
this.isSearch = true
this.isSearch = true;
this.loadSearchHistory();
},
iptBlur() {
this.isSearch = false
if (this.searchQuery) {
this.search();
} else {
this.searchGoodsLisat = [];
this.isSearch = true
this.isSearched = false
}
},
//
saveSearchHistory() {
if (this.searchQuery && !this.searchHistory.includes(this.searchQuery)) {
//
this.searchHistory.unshift(this.searchQuery);
// 10
if (this.searchHistory.length > 10) {
this.searchHistory.pop();
}
// storage
uni.setStorageSync('shopSearchHistory', this.searchHistory);
}
},
//
loadSearchHistory() {
const history = uni.getStorageSync('shopSearchHistory') || [];
this.searchHistory = history;
},
//
selectHistory(item) {
this.searchQuery = item;
this.search();
this.isSearch = false;
},
//
deleteHistory() {
uni.showModal({
title: '提示',
content: '确定清除所有搜索历史吗?',
success: (res) => {
if (res.confirm) {
this.searchHistory = [];
uni.removeStorageSync('shopSearchHistory');
uni.showToast({
title: '搜索历史已清除',
icon: 'none'
});
}
}
});
},
//
goods(e) {
NavgateTo(`../goods/index?item=${JSON.stringify(e)}`);
},
//
chooseGG(targetItems) {
//
const itemIndex = this.searchGoodsLisat.findIndex(item => item.id === targetItems.id);
if (itemIndex > -1) {
//
const currentItem = this.searchGoodsLisat[itemIndex];
this.$set(currentItem, 'isShow', !currentItem.isShow);
}
},
//
handleQuantityChange(val, item) {
//
// valvalue
const quantity = typeof val === 'object' && val !== null && 'value' in val ? val.value : val;
// items.commodity_goods_info_list[0].quantity
if (item.commodity_goods_info_list && item.commodity_goods_info_list.length) {
this.goodsId = item.commodity_goods_info_list[0].id;
// 使$set
this.$set(item.commodity_goods_info_list[0], 'quantity', quantity);
}
// ite.quantity
else {
this.goodsId = item.id;
// 使$set
this.$set(item, 'quantity', quantity);
}
const params = {
user_id: uni.getStorageSync('userId'),
goods_id_and_count: [
{
goods_id: this.goodsId,
count: quantity,
},
],
};
request(apiArr.updateCar, 'POST', params).then((res) => {
console.log(res);
//
this.getShopCarList();
// goodsDetail
setTimeout(() => {
//
this.syncGoodsQuantities();
}, 100);
uni.showToast({
title: '操作成功!',
success() { },
});
});
},
//
syncGoodsQuantities() {
//
this.searchGoodsLisat.forEach((item) => {
item.commodity_goods_info_list.forEach((param) => {
const goods = this.goodsDetail.find(g => g.goods_id === param.id);
if (goods) {
this.$set(param, 'quantity', goods.count);
}
});
});
},
//
getPriceRange(goodsList) {
if (!goodsList || goodsList.length === 0) return '¥0';
const prices = goodsList.map(item => Number(item.sales_price));
const minPrice = Math.min(...prices);
const maxPrice = Math.max(...prices);
return minPrice === maxPrice ? `${minPrice}` : `${minPrice} ~ ¥${maxPrice}`;
},
//
//
// onSearch() {
// // searchQuery
// const fakeData = ['', '', '', '', ''];
// this.results = fakeData.filter(item => item.includes(this.searchQuery));
// if(this.searchQuery) {
// this.showHistory = true;
// } else {
// this.showHistory = false
// }
// },
// //
// selectHistory(item) {
// this.searchQuery = item;
// this.onSearch();
// this.showHistory = false;
// },
// //
// saveSearchHistory() {
// if(this.searchQuery && !this.searchHistory.includes(this.searchQuery)) {
// this.searchHistory.unshift(this.searchQuery); //
// if(this.searchHistory.length > 5) {
// this.searchHistory.pop(); //
// }
// }
// }
//
//
handleImageUrl(imagePath) {
return basePicUrl + imagePath;
}
},
watch: {
searchQuery: {
handler(newVal, oldVal) {
if (!newVal) {
this.searchGoodsLisat = [];
this.isSearch = true
this.isSearched = false
}
},
deep: true
}
},
//
// watch: {
// //
// searchQuery(newQuery) {
// if(newQuery !== '') {
// this.saveSearchHistory();
// }
// }
// },
//
onLoad(options) {
this.loadSearchHistory();
this.isSearch = false;
this.isSearched = false;
},
onShow() {
this.getShopCarList();
},
onReachBottom() {
if (this.flag) {

View File

@ -1,3 +1,8 @@
.main {
height: 77vh;
overflow-y: auto;
}
.searchBox {
display: flex;
align-items: center;
@ -57,8 +62,8 @@
}
.empty image {
width: 340rpx;
height: 253.51rpx;
width: 500rpx;
height: 500rpx;
}
.empty div {
@ -76,6 +81,17 @@
justify-content: flex-end;
}
.goodsItem_supplier {
display: flex;
align-items: center;
margin: 20rpx;
}
.goodsItem_tit {
font-size: 35rpx;
font-weight: bold;
}
.goodsItem {
display: flex;
align-items: center;

View File

@ -1,23 +1,25 @@
<template>
<view>
<div class="header">
<div class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }">
<div class="searchBox_left" @click="back">
<view class="header">
<view class="searchBox" :style="{ height: localHeight + 'px', paddingTop: top + 'px' }">
<view class="searchBox_left" @click="back">
<u-icon name="arrow-left" size="20px" color="#000"></u-icon>
</div>
<div class="searchBox_mid">购物车({{ shopCarTotal }})</div>
<div class="searchBox_right">
</view>
<view class="searchBox_mid">购物车({{ shopCarTotal }})</view>
<view class="searchBox_right">
<u-icon name="arrow-left" size="20px" color="#000"></u-icon>
</div>
</div>
</div>
<div class="main">
<div class="deleteIcon" @click="deleteItem">
</view>
</view>
</view>
<view class="empty" v-if="shopCarTotal == 0">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/shopCar_no.png"></image>
</view>
<view class="main" v-else>
<view class="deleteIcon" @click="deleteItem">
<u-icon name="trash" size="50rpx"></u-icon>
</div>
<div class="is_day " v-if="isDayshow">
<div class="footer_all" @click="is_day_checked"
</view>
<view class="is_day " v-if="isDayshow">
<view class="footer_all" @click="is_day_checked"
style="color: orange; font-size: 35rpx; font-weight: bolder;">
<image v-if="!isDaychecked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png">
@ -26,60 +28,78 @@
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png">
</image>
当日达
</div>
<div class="goodsList">
<div class="goodsItem" v-for="(item, index) in isDayCarList" :key="item.id">
<div class="goodsItem_left" @click="DayChecked(item, index)">
</view>
<view class="goodsList">
<view v-for="(carItem, carIndex) in isDayCarList" :key="carItem.id" :index="carIndex">
<view class="goodsItem_supplier">
<view class="goodsItem_left" @click="supplierCheck(carItem, true)">
<image v-if="!carItem.supplierChecked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png">
</image>
<image v-if="carItem.supplierChecked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png">
</image>
</view>
<view class="goodsItem_tit">
{{ carItem.supplier_name }}
</view>
</view>
<view class="goodsItem" v-for="(item, index) in carItem.commodity_cart_and_goods_model"
:key="item.id">
<view class="goodsItem_left" @click="DayChecked(item)">
<image v-if="!item.checked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png">
</image>
<image v-if="item.checked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png">
</image>
</div>
<div class="goodsItem_right">
<div class="goodsItem_msg">
<div class="goodsItem_msg_img">
</view>
<view class="goodsItem_right">
<view class="goodsItem_msg">
<view class="goodsItem_msg_img">
<view class="tag tag-img">当日达</view>
<image :src="picUrl + item.commodity_goods_info.commodity_pic">
</image>
</div>
<div class="goodsItem_msg_right">
<div class="goodsItem_msg_right_tit">
</view>
<view class="goodsItem_msg_right">
<view class="goodsItem_msg_right_tit">
{{ item.commodity_goods_info.goods_name }}
</div>
<div class="goodsItem_msg_right_subTit">
</view>
<view class="goodsItem_msg_right_subTit">
{{ item.commodity_goods_info.goods_intro }}
</div>
<div class="goodsItem_msg_right_msg">
<div class="goodsItem_msg_right_msg_left">
<span></span>{{ item.commodity_goods_info.sales_price }}
</view>
<view class="goodsItem_msg_right_msg">
<view class="goodsItem_msg_right_msg_left">
<span></span>{{ getPrice(item) }}
<!-- {{ item.commodity_goods_info.group_buy_price ?
item.commodity_goods_info.group_buy_price :
item.commodity_goods_info.sales_price }} -->
<span>/{{ item.commodity_goods_info.goods_unit }}</span>
</div>
<div class="goodsItem_msg_right_msg_right">
</view>
<view class="goodsItem_msg_right_msg_right">
<u-number-box v-model="item.count" :asyncChange="true" min="0">
<view slot="minus" class="minus" @click="minus(item, index)">
<view slot="minus" class="minus"
@click="minus(carItem, index, carItem.commodity_cart_and_goods_model)">
<u-icon name="minus" size="32" bold></u-icon>
</view>
<text slot="input" style="width: 80rpx; text-align: center"
class="input">{{ item.count }}</text>
<view slot="plus" class="plus" @click="add(item, index)">
<view slot="plus" class="plus" @click="add(carItem, index)">
<u-icon name="plus" color="#FFFFFF" size="32" bold></u-icon>
</view>
</u-number-box>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<div class="is_day" v-if="parcelPostshow" style="margin-top: 20rpx;">
<div class="footer_all" @click="parcel_post_checked"
<view class="is_day" v-if="parcelPostshow" style="margin-top: 20rpx;">
<view class="footer_all" @click="parcel_post_checked"
style="color: orange; font-size: 35rpx; font-weight: bolder;">
<image v-if="!isParcelPostchecked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png">
@ -88,40 +108,57 @@
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png">
</image>
包邮
</div>
<div class="goodsList">
<div class="goodsItem" v-for="(item, index) in shopCarList" :key="item.id">
<div class="goodsItem_left" @click="changeChecked(item, index)">
</view>
<view class="goodsList">
<view v-for="(carItem, carIndex) in shopCarList" :key="carItem.id" :index="carIndex">
<view class="goodsItem_supplier">
<view class="goodsItem_left" @click="supplierCheck(carItem, false)">
<image v-if="!carItem.supplierChecked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png">
</image>
<image v-if="carItem.supplierChecked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png">
</image>
</view>
<view class="goodsItem_tit">
{{ carItem.supplier_name }}
</view>
</view>
<view class="goodsItem" v-for="(item, index) in carItem.commodity_cart_and_goods_model"
:key="item.id">
<view class="goodsItem_left" @click="changeChecked(item)">
<image v-if="!item.checked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png">
</image>
<image v-if="item.checked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png">
</image>
</div>
<div class="goodsItem_right">
<div class="goodsItem_msg">
<div class="goodsItem_msg_img">
</view>
<view class="goodsItem_right">
<view class="goodsItem_msg">
<view class="goodsItem_msg_img">
<image :src="picUrl + item.commodity_goods_info.commodity_pic">
</image>
</div>
<div class="goodsItem_msg_right">
<div class="goodsItem_msg_right_tit">
</view>
<view class="goodsItem_msg_right">
<view class="goodsItem_msg_right_tit">
{{ item.commodity_goods_info.goods_name }}
</div>
<div class="goodsItem_msg_right_subTit">
</view>
<view class="goodsItem_msg_right_subTit">
{{ item.commodity_goods_info.goods_intro }}
</div>
<div class="goodsItem_msg_right_msg">
<div class="goodsItem_msg_right_msg_left">
<span></span>{{ item.commodity_goods_info.sales_price }}
</view>
<view class="goodsItem_msg_right_msg">
<view class="goodsItem_msg_right_msg_left">
<span></span>{{ getPrice(item) }}
<!-- {{ item.commodity_goods_info.group_buy_price ?
item.commodity_goods_info.group_buy_price :
item.commodity_goods_info.sales_price }} -->
<span>/{{ item.commodity_goods_info.goods_unit }}</span>
</div>
<div class="goodsItem_msg_right_msg_right">
</view>
<view class="goodsItem_msg_right_msg_right">
<u-number-box v-model="item.count" :asyncChange="true" min="0">
<view slot="minus" class="minus" @click="minus(item, index)">
<view slot="minus" class="minus"
@click="minus(item, index, carItem.commodity_cart_and_goods_model)">
<u-icon name="minus" size="32" bold></u-icon>
</view>
<text slot="input" style="width: 80rpx; text-align: center"
@ -130,23 +167,19 @@
<u-icon name="plus" color="#FFFFFF" size="32" bold></u-icon>
</view>
</u-number-box>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<div class="footer">
<div class="footer_left">
<div class="footer_all" @click="allChecked">
<view class="footer">
<view class="footer_left">
<view class="footer_all" @click="allChecked">
<image v-if="!isAllchecked"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png">
</image>
@ -154,23 +187,17 @@
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png">
</image>
全选
</div>
<div class="footer_total">
</view>
<view class="footer_total">
<span>合计</span>
{{ shopMoney }}
</div>
</div>
<div class="footer_right" @click="submitOrder">结算</div>
</div>
</div>
</view>
</view>
<view class="footer_right" @click="submitOrder">结算</view>
</view>
</view>
<div class="empty" v-if="shopCarTotal == 0">
<image src="http://192.168.0.172:5500/7.15/shop_empty.png"></image>
<div>
啥也没有 <br />
赶紧去shopping吧~
</div>
</div>
</view>
</template>
@ -201,7 +228,7 @@
isDayshow: false,
isParcelPostchecked: false,
parcelPostshow: false,
is_group_buy: ''
};
},
// watch: {
@ -221,164 +248,388 @@
NavgateTo("1");
},
// /
supplierCheck(carItem, isDay) {
carItem.supplierChecked = !carItem.supplierChecked;
carItem.commodity_cart_and_goods_model.forEach(goods => {
goods.checked = carItem.supplierChecked;
});
this.calcTotal();
//
if (isDay) {
this.isDaychecked = this.isDayCarList.every(item =>
item.commodity_cart_and_goods_model.every(goods => goods.checked)
);
} else {
this.isParcelPostchecked = this.shopCarList.every(item =>
item.commodity_cart_and_goods_model.every(goods => goods.checked)
);
}
//
this.isAllchecked = this.isDaychecked && this.isParcelPostchecked;
},
//
submitOrder() {
let arr = [];
//
this.shopCarList.forEach((item) => {
if (item.checked) {
arr.push(item);
item.commodity_cart_and_goods_model.forEach((ite) => {
if (ite.checked) {
ite.supplier_name = item.supplier_name;
arr.push(ite);
}
})
});
//
this.isDayCarList.forEach((item) => {
item.commodity_cart_and_goods_model.forEach((ite) => {
if (ite.checked) {
ite.supplier_name = item.supplier_name;
arr.push(ite);
}
})
});
NavgateTo(`../submitOrder/index?shopCarList=${JSON.stringify(arr)}`);
if (arr.length == 0) {
this.$u.toast("请选择商品");
return;
}
// NavgateTo(`../submitOrder/index?shopCarList=${JSON.stringify(arr)}`);
NavgateTo(`../groupPurchaseSubmit/index?shopCarList=${JSON.stringify(arr)}`);
},
//
getShopCar() {
request(apiArr.getCar, "POST", {}).then((res) => {
console.log(res.total);
// res.commodity_cart_list.forEach((item) => {
res.normal_cart_list.forEach((item) => {
console.log(item.commodity_cart_and_goods_model);
if(item.is_support_same_day == false) {
this.isDayshow = false;
this.parcelPostshow = true;
this.shopCarList = item.commodity_cart_and_goods_model;
item.checked = false;
} else {
this.isDayshow = true;
this.parcelPostshow = false;
this.isDayCarList = item.commodity_cart_and_goods_model;
item.checked = false;
const params = {
is_group_buy: this.is_group_buy
}
request(apiArr.getCar, "POST", params).then((res) => {
if (res.normal_cart_list.length > 0) {
res.normal_cart_list.forEach((item) => {
item.checked = false;
item.supplierChecked = false;
})
this.parcelPostshow = true;
this.shopCarList = res.normal_cart_list
} else {
res.normal_cart_list.forEach((item) => {
item.checked = false;
item.supplierChecked = false;
})
this.parcelPostshow = false;
this.shopCarList = []
}
});
// this.shopCarList = res.commodity_cart_list;
// this.shopCarList = res.normal_cart_list[0].commodity_cart_and_goods_model;
if (res.same_day_cart_list.length > 0) {
res.same_day_cart_list.forEach((item) => {
item.checked = false;
item.supplierChecked = false;
})
this.isDayshow = true;
this.isDayCarList = res.same_day_cart_list
} else {
res.normal_cart_list.forEach((item) => {
item.checked = false;
item.supplierChecked = false;
})
this.isDayshow = false;
this.isDayCarList = []
}
// res.normal_cart_list.forEach((item) => {
// if (item.is_support_same_day == false) {
// this.isDayshow = false;
// this.parcelPostshow = true;
// this.shopCarList = item.commodity_cart_and_goods_model;
// item.checked = false;
// } else {
// this.isDayshow = true;
// this.parcelPostshow = false;
// this.isDayCarList = item.commodity_cart_and_goods_model;
// item.checked = false;
// }
// });
this.shopCarTotal = res.total;
});
},
// ceshi() {
// console.log(this.shopCarTotal);
// console.log(this.shopCarList);
// },
//
changeChecked(item, index) {
this.shopCarList[index].checked = !this.shopCarList[index].checked;
changeChecked(item) {
item.checked = !item.checked;
this.calcTotal();
this.isParcelPostchecked = this.shopCarList.every((item) => item.checked);
if(this.isDayshow == false) {
this.isAllchecked = this.shopCarList.every((item) => item.checked);
//
this.shopCarList.forEach(carItem => {
if (carItem.commodity_cart_and_goods_model.includes(item)) {
carItem.supplierChecked = carItem.commodity_cart_and_goods_model.every(goods => goods.checked);
}
});
//
this.isDaychecked = this.isDayCarList.every(carItem =>
carItem.commodity_cart_and_goods_model.every(goods => goods.checked)
);
//
this.isParcelPostchecked = this.shopCarList.every(carItem =>
carItem.commodity_cart_and_goods_model.every(goods => goods.checked)
);
//
this.isAllchecked = this.isDaychecked && this.isParcelPostchecked;
},
DayChecked(item, index) {
this.isDayCarList[index].checked = !this.isDayCarList[index].checked;
DayChecked(item) {
item.checked = !item.checked;
this.calcTotal();
this.isDaychecked = this.isDayCarList.every((item) => item.checked);
if(this.parcelPostshow == false) {
this.isAllchecked = this.isDayCarList.every((item) => item.checked);
//
this.isDayCarList.forEach(carItem => {
if (carItem.commodity_cart_and_goods_model.includes(item)) {
carItem.supplierChecked = carItem.commodity_cart_and_goods_model.every(goods => goods.checked);
}
});
//
this.isDaychecked = this.isDayCarList.every(carItem =>
carItem.commodity_cart_and_goods_model.every(goods => goods.checked)
);
//
this.isParcelPostchecked = this.shopCarList.every(carItem =>
carItem.commodity_cart_and_goods_model.every(goods => goods.checked)
);
//
this.isAllchecked = this.isDaychecked && this.isParcelPostchecked;
},
//
allChecked() {
this.isAllchecked = !this.isAllchecked;
// this.isDaychecked = !this.isDaychecked;
// this.isParcelPostchecked = !this.isParcelPostchecked;
// Bug !this.allChecked !this.isAllchecked
if (this.isAllchecked) {
this.isDaychecked = true;
this.isParcelPostchecked = true;
this.shopCarList.forEach((item) => {
item.checked = true;
this.isDaychecked = this.isAllchecked;
this.isParcelPostchecked = this.isAllchecked;
//
this.isDayCarList.forEach(carItem => {
carItem.supplierChecked = this.isAllchecked;
carItem.commodity_cart_and_goods_model.forEach(goods => {
goods.checked = this.isAllchecked;
});
} else {
this.isDaychecked = false;
this.isParcelPostchecked = false;
this.shopCarList.forEach((item) => {
item.checked = false;
});
}
//
this.shopCarList.forEach(carItem => {
carItem.supplierChecked = this.isAllchecked;
carItem.commodity_cart_and_goods_model.forEach(goods => {
goods.checked = this.isAllchecked;
});
});
this.calcTotal();
},
//
is_day_checked() {
this.isDaychecked = !this.isDaychecked;
this.isAllchecked = !this.isAllchecked
if (this.isDaychecked) {
this.isDayCarList.forEach((item) => {
item.checked = true;
//
this.isDayCarList.forEach(carItem => {
carItem.supplierChecked = this.isDaychecked;
carItem.commodity_cart_and_goods_model.forEach(goods => {
goods.checked = this.isDaychecked;
});
} else {
this.isDayCarList.forEach((item) => {
item.checked = false;
});
}
//
this.isAllchecked = this.isDaychecked && this.isParcelPostchecked;
this.calcTotal();
console.log("全选当日达");
},
//
parcel_post_checked() {
this.isParcelPostchecked = !this.isParcelPostchecked;
this.isAllchecked = !this.isAllchecked
console.log(this.isParcelPostchecked);
if (this.isParcelPostchecked) {
this.shopCarList.forEach((item) => {
item.checked = true;
//
this.shopCarList.forEach(carItem => {
carItem.supplierChecked = this.isParcelPostchecked;
carItem.commodity_cart_and_goods_model.forEach(goods => {
goods.checked = this.isParcelPostchecked;
});
} else {
this.shopCarList.forEach((item) => {
item.checked = false;
});
}
//
this.isAllchecked = this.isDaychecked && this.isParcelPostchecked;
this.calcTotal();
console.log("全选包邮");
},
//
calcTotal() {
let total = 0;
this.shopCarList.forEach((item) => {
console.log(item);
const currentTime = new Date().getTime();
if (item.checked) {
total += item.commodity_goods_info.sales_price * item.count;
//
this.isDayCarList.forEach(carItem => {
carItem.commodity_cart_and_goods_model.forEach(goods => {
if (goods.checked) {
//
const startTime = new Date(goods.commodity_goods_info.group_buy_activity_info?.start_time).getTime();
const endTime = new Date(goods.commodity_goods_info.group_buy_activity_info?.end_time).getTime();
if (currentTime >= startTime && currentTime <= endTime) {
total += goods.commodity_goods_info.group_buy_price * goods.count;
} else {
total += goods.commodity_goods_info.sales_price * goods.count;
}
}
});
this.shopMoney = total;
});
//
this.shopCarList.forEach(carItem => {
carItem.commodity_cart_and_goods_model.forEach(goods => {
if (goods.checked) {
//
const startTime = new Date(goods.commodity_goods_info.group_buy_activity_info?.start_time).getTime();
const endTime = new Date(goods.commodity_goods_info.group_buy_activity_info?.end_time).getTime();
if (currentTime >= startTime && currentTime <= endTime) {
total += goods.commodity_goods_info.group_buy_price * goods.count;
} else {
total += goods.commodity_goods_info.sales_price * goods.count;
}
}
});
});
this.shopMoney = total.toFixed(2);
},
//
minus(item, index) {
let that = this;
if (item.count === 1) {
//
deleteCarItem(carItem, goodsIndex, item) {
const that = this;
request(apiArr.deleteCar, "POST", {
ids: [item.id],
ids: [carItem.id],
}).then((res) => {
that.shopCarList.splice(index, 1);
that.calcTotal();
});
//
item.splice(goodsIndex, 1);
//
if (item.length === 0) {
//
const dayCarIndex = that.isDayCarList.findIndex(dayItem =>
dayItem.commodity_cart_and_goods_model === item
);
const normalCarIndex = that.shopCarList.findIndex(normalItem =>
normalItem.commodity_cart_and_goods_model === item
);
if (dayCarIndex !== -1) {
that.isDayCarList.splice(dayCarIndex, 1);
//
if (that.isDayCarList.length === 0) {
that.isDayshow = false;
}
this.shopCarTotal = this.shopCarTotal - 1
this.shopCarList[index].count = this.shopCarList[index].count - 1;
this.handleQuantityChange(this.shopCarList[index].count, this.shopCarList[index])
}
if (normalCarIndex !== -1) {
that.shopCarList.splice(normalCarIndex, 1);
//
if (that.shopCarList.length === 0) {
that.parcelPostshow = false;
}
}
}
that.calcTotal();
}).catch(error => {
console.error('删除商品失败:', error);
uni.showToast({
title: '删除失败,请重试',
icon: 'none'
});
});
},
//
minus(carItem, goodsIndex, item) {
const that = this;
const currentTime = new Date().getTime();
//
const isGroupBuyActive = carItem.commodity_goods_info.group_buy_activity_info &&
currentTime >= new Date(carItem.commodity_goods_info.group_buy_activity_info?.start_time).getTime() &&
currentTime <= new Date(carItem.commodity_goods_info.group_buy_activity_info?.end_time).getTime();
if (carItem.count > 0) {
if (isGroupBuyActive && carItem.count === carItem.commodity_goods_info.min_order_quantity) {
//
uni.showToast({
title: '最少购买' + carItem.commodity_goods_info.min_order_quantity + '件',
icon: 'none'
});
//
that.shopCarTotal = Math.max(0, that.shopCarTotal - carItem.commodity_goods_info.min_order_quantity);
//
that.deleteCarItem(carItem, goodsIndex, item);
} else {
//
this.shopCarTotal = Math.max(0, this.shopCarTotal - 1);
carItem.count = carItem.count - 1;
this.handleQuantityChange(carItem.count, carItem);
// 0
if (carItem.count === 0) {
that.deleteCarItem(carItem, goodsIndex, item);
} else {
// 0
this.calcTotal();
}
}
}
},
//
add(item, index) {
this.shopCarTotal = this.shopCarTotal + 1
this.shopCarList[index].count = this.shopCarList[index].count + 1;
this.handleQuantityChange(this.shopCarList[index].count, this.shopCarList[index])
add(carItem, goodsIndex) {
const currentTime = new Date().getTime();
const isGroupBuyActive = carItem.commodity_goods_info.group_buy_activity_info &&
currentTime >= new Date(carItem.commodity_goods_info.group_buy_activity_info?.start_time).getTime() &&
currentTime <= new Date(carItem.commodity_goods_info.group_buy_activity_info?.end_time).getTime();
if (isGroupBuyActive) {
if (carItem.count == 0) {
carItem.count = carItem.commodity_goods_info.min_order_quantity
this.shopCarTotal += carItem.commodity_goods_info.min_order_quantity;
} else {
if (carItem.count == carItem.commodity_goods_info.total_stock) {
uni.showToast({
title: '库存不足',
icon: 'none'
});
return
}
if (carItem.count == carItem.commodity_goods_info.max_limit_quantity) {
uni.showToast({
title: '一次最多购买' + carItem.commodity_goods_info.max_limit_quantity + '件',
icon: 'none'
});
return
}
carItem.count++;
this.shopCarTotal++;
}
} else {
if (carItem.count >= carItem.commodity_goods_info.stock_quantity) {
uni.showToast({
title: '库存不足',
icon: 'none'
});
return
}
carItem.count++;
this.shopCarTotal++;
}
const item = carItem.commodity_cart_and_goods_model;
this.handleQuantityChange(carItem.count, carItem);
this.calcTotal();
},
@ -391,12 +642,36 @@
success: function (res) {
if (res.confirm) {
let ids = [];
that.shopCarList.forEach((item) => {
if (item.checked) {
ids.push(item.id);
item.checked = false;
// ID
that.isDayCarList.forEach(carItem => {
carItem.commodity_cart_and_goods_model.forEach(goods => {
if (goods.checked) {
ids.push(goods.id);
goods.checked = false;
}
});
});
// ID
that.shopCarList.forEach(carItem => {
carItem.commodity_cart_and_goods_model.forEach(goods => {
if (goods.checked) {
ids.push(goods.id);
goods.checked = false;
}
});
});
if (ids.length === 0) {
uni.showToast({
title: "请选择要删除的商品",
icon: "none",
duration: 2000,
});
return;
}
request(apiArr.deleteCar, "POST", {
ids,
})
@ -419,7 +694,6 @@
},
//
handleQuantityChange(val, item) {
const params = {
user_id: uni.getStorageSync("userId"),
goods_id_and_count: [{
@ -433,16 +707,37 @@
title: "操作成功!",
success() { },
});
return Promise.resolve();
});
},
// -
getPrice(item) {
const currentTime = new Date().getTime();
const startTime = new Date(item.commodity_goods_info.group_buy_activity_info?.start_time).getTime();
const endTime = new Date(item.commodity_goods_info.group_buy_activity_info?.end_time).getTime();
if (currentTime >= startTime && currentTime <= endTime) {
return item.commodity_goods_info.group_buy_price;
} else {
return item.commodity_goods_info.sales_price;
}
},
},
onLoad(options) {
const meun = menuButtonInfo();
this.top = meun.top;
this.localHeight = meun.height;
this.is_group_buy = options.item ? JSON.parse(options.item).is_group_buy : ''
this.getShopCar();
},
onShow() {
this.getShopCar();
//
this.isAllchecked = false;
this.isDaychecked = false;
this.isParcelPostchecked = false;
this.shopMoney = 0.00;
},
onReachBottom() { },

View File

@ -1,45 +1,44 @@
<template>
<view class="container">
<div class="address">
<div class="border">
<view class="address">
<view class="border">
<image src="http://192.168.0.172:5500/7.15/shop_border.png" mode="widthFix"></image>
</div>
<div class="address_Info" @click="choseAddress" v-if="defAddress">
<div class="address_Info_left">
<div class="address_Info_left_tit">收货地址</div>
<div class="address_Info_left_name">{{ defAddress.name }} {{ defAddress.phone }}</div>
<div class="address_Info_left_addr">{{ defAddress.address }}{{ defAddress.house_number }}</div>
</div>
</div>
</view>
<view class="address_Info" @click="choseAddress" v-if="defAddress">
<view class="address_Info_left">
<view class="address_Info_left_tit">收货地址</view>
<view class="address_Info_left_name">{{ defAddress.name }} {{ defAddress.phone }}</view>
<view class="address_Info_left_addr">{{ defAddress.address }}{{ defAddress.house_number }}</view>
</view>
</view>
<div class="address_Info" @click="addAddress" v-if="!defAddress">
<div class="address_Info_left noneDef">
<div class="address_Info_btn">添加收货地址</div>
</div>
<view class="address_Info" @click="addAddress" v-if="!defAddress">
<view class="address_Info_left noneDef">
<view class="address_Info_btn">添加收货地址</view>
</view>
</view>
</div>
<div class="border">
<view class="border">
<image src="http://192.168.0.172:5500/7.15/shop_border.png" mode="widthFix"></image>
</div>
</div>
</view>
</view>
<div class="goodsCate" v-for="items, indexs in carList" :key="indexs">
<div class="goodsItem">
<div class="goodsItem_msg_img">
<view class="goodsCate" v-for="items, indexs in carList" :key="indexs">
<view class="goodsItem">
<view class="goodsItem_msg_img">
<view class="tag tag-img" v-if="items.commodity_goods_info.is_same_day">当日达</view>
<image :src="picUrl + items.commodity_goods_info.commodity_pic">
</image>
</div>
<div class="goodsItem_msg_right">
<div class="goodsItem_msg_right_tit" style="display: flex"><div class="tag" style="margin-right: 10rpx" v-if="items.commodity_goods_info.is_same_day">当日达</div><div>{{ items.commodity_goods_info.goods_name }}</div></div>
<div class="goodsItem_msg_right_subTit">{{ items.commodity_goods_info.goods_intro }}</div>
<div class="goodsItem_msg_right_msg">
<div class="goodsItem_msg_right_msg_left">
</view>
<view class="goodsItem_msg_right">
<view class="goodsItem_msg_right_tit" style="display: flex"><view class="tag" style="margin-right: 10rpx" v-if="items.commodity_goods_info.is_same_day">当日达</view><view>{{ items.commodity_goods_info.goods_name }}</view></view>
<view class="goodsItem_msg_right_subTit">{{ items.commodity_goods_info.goods_intro }}</view>
<view class="goodsItem_msg_right_msg">
<view class="goodsItem_msg_right_msg_left">
<span></span>{{ items.commodity_goods_info.sales_price }}
<span>/{{ items.commodity_goods_info.goods_unit }}</span>
</div>
<div class="goodsItem_msg_right_msg_right">
</view>
<view class="goodsItem_msg_right_msg_right">
<u-number-box v-model="value">
<view slot="minus" class="minus" @click="minus(items, indexs)">
<u-icon name="minus" size="32" bold></u-icon>
@ -51,20 +50,20 @@
<u-icon name="plus" color="#FFFFFF" size="32" bold></u-icon>
</view>
</u-number-box>
</div>
</div>
</div>
</div>
<div class="yf">
</view>
</view>
</view>
</view>
<view class="yf">
<span>运费</span>9.9
</div>
<div class="line"></div>
</div>
</view>
<view class="line"></view>
</view>
<div class="footer">
<div class="btn">立即支付{{ totalMony }}</div>
</div>
<view class="footer">
<view class="btn">立即支付{{ totalMony }}</view>
</view>
</view>
</template>

View File

@ -0,0 +1,56 @@
page {
background-color: #fff;
}
.fenge{
height: 20rpx;
background-color: #f0f2f5;
}
.location-container {
padding-top: 20rpx;
}
.location-list {
background-color: #fff;
}
.location-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
border-bottom: 1rpx solid #eee;
}
.location-item:last-child {
border-bottom: none;
}
.location-info {
flex: 1;
}
.location-address {
font-size: 28rpx;
color: #333;
line-height: 44rpx;
}
/* 选中状态的样式 */
.location-item .location-address {
color: #333;
}
/* 增加优先级确保选中样式生效 */
.location-item .location-address.active {
color: #fd631a !important;
}
.location-select {
width: 60rpx;
height: 60rpx;
display: flex;
justify-content: center;
align-items: center;
}

View File

@ -0,0 +1,85 @@
<template>
<view class="location-container">
<view class="fenge"></view>
<view class="location-list">
<!-- 地址项 -->
<view class="location-item" v-for="(item, index) in locationList" :key="index"
@click="selectLocation(item, index)">
<view class="location-info">
<text :class="['location-address', { 'active': index === selectedIndex }]">{{ item.address }}</text>
</view>
<view class="location-select">
<image v-if="index !== selectedIndex"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check1.png" mode="aspectFit"
style="width: 40rpx; height: 40rpx;"></image>
<image v-if="index === selectedIndex"
src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_check2.png" mode="aspectFit"
style="width: 40rpx; height: 40rpx;"></image>
</view>
</view>
</view>
</view>
</template>
<script>
import { picUrl, menuButtonInfo, request, NavgateTo } from "../../../utils";
import { apiArr } from '../../../api/groupPurchase';
export default {
data() {
return {
locationList: [],
selectedIndex: -1
};
},
onLoad(options) {
const item = JSON.parse(options.item)
this.getLocationList(item.goods_id, item.supplier_id)
},
methods: {
async getLocationList(id, supplier_id) {
const params = {
goods_ids: id,
}
const res = await request(apiArr.groupBuyAddress, 'POST', params)
//
res.self_pickup_address_list[0].address.forEach(item => {
const [address, phone, name] = item.split(' ');
this.locationList.push({
id: supplier_id,
name: name || '',
phone: phone || '',
address: address || ''
});
});
},
selectLocation(item, index) {
//
this.selectedIndex = index;
//
let addressList = uni.getStorageSync('changeZTAddress') || [];
// id
const existingIndex = addressList.findIndex(addr => addr.id === item.id);
if (existingIndex > -1) {
// id
addressList[existingIndex] = item;
} else {
// id
addressList.push(item);
}
//
uni.setStorageSync('changeZTAddress', addressList);
NavgateTo("1")
}
}
};
</script>
<style>
@import url('./index.css');
</style>

View File

@ -1,90 +1,108 @@
<template>
<div class="container">
<div class="Msg">
<div class="row">
<div class="row_label">门店名称</div>
<div class="row_con">
<view class="container">
<view class="Msg">
<view class="row">
<view class="row_label">门店名称</view>
<view class="row_con">
<input type="text" v-model="store_name" placeholder="需与门牌照名称一致">
</div>
</div>
<div class="row">
<div class="row_label">所在省</div>
<div class="row_con" @click="chooseCity">
</view>
</view>
<view class="row">
<view class="row_label">所在省</view>
<view class="row_con" @click="chooseCity">
<input type="text" disabled v-model="confirmProv.ad_name" placeholder="请选择所在省">
<u-icon name="arrow-right" color="#999999" size="28"></u-icon>
</div>
</div>
<div class="row">
<div class="row_label">所在市</div>
<div class="row_con" @click="chooseCity2">
</view>
</view>
<view class="row">
<view class="row_label">所在市</view>
<view class="row_con" @click="chooseCity2">
<input type="text" disabled v-model="confirmCity.short_name" placeholder="请选择所在市">
<u-icon name="arrow-right" color="#999999" size="28"></u-icon>
</div>
</div>
<div class="row">
<div class="row_label">所在区</div>
<div class="row_con" @click="chooseCity3">
</view>
</view>
<view class="row">
<view class="row_label">所在区</view>
<view class="row_con" @click="chooseCity3">
<input type="text" disabled v-model="confirmBusiness.short_name" placeholder="请选择所在区">
<u-icon name="arrow-right" color="#999999" size="28"></u-icon>
</div>
</div>
<div class="row">
<div class="row_label">详细地址</div>
<div class="row_con">
</view>
</view>
<view class="row">
<view class="row_label">详细地址</view>
<view class="row_con">
<input type="text" v-model="address" placeholder="请输入详细地址">
</div>
</div>
<div class="row">
<div class="row_label">联系人</div>
<div class="row_con">
</view>
</view>
<view class="row">
<view class="row_label">联系人</view>
<view class="row_con">
<input type="text" v-model="contact_name" placeholder="请输入联系人">
</div>
</div>
<div class="row">
<div class="row_label">手机号</div>
<div class="row_con nonebor">
</view>
</view>
<view class="row">
<view class="row_label">手机号</view>
<view class="row_con">
<input type="text" v-model="contact_phone" placeholder="请输入联系方式">
</div>
</div>
</div>
</view>
</view>
<view class="row">
<view class="row_label">银行卡号</view>
<view class="row_con nonebor">
<input type="text" v-model="bank_card" placeholder="请输入银行卡号">
</view>
</view>
</view>
<div class="Msg mt">
<div class="row2">
<div class="row_label">门脸照</div>
<div class="row_con2">
<view class="Msg mt">
<view class="row2">
<view class="row_label">门脸照</view>
<view class="row_con2">
<u-upload :fileList="imgList" @afterRead="afterReadImg" @delete="deletePic" name="1" multiple
:maxCount="10">
<div class="imgCon">
<view class="imgCon">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_imageImg.png" mode="widthFix"></image>
上传图片
</div>
</view>
</u-upload>
</div>
</div>
</view>
</view>
<div class="row2 mt2">
<div class="row_label">店内环境</div>
<div class="row_con2">
<view class="row2 mt2">
<view class="row_label">店内环境</view>
<view class="row_con2">
<u-upload :fileList="imgList3" @afterRead="afterReadImg2" @delete="deletePic2" name="1" multiple
:maxCount="10">
<div class="imgCon">
<view class="imgCon">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_imageImg.png" mode="widthFix"></image>
上传图片
</div>
</view>
</u-upload>
</view>
</view>
</div>
</div>
</div>
<view class="row2 mt2">
<view class="row_label">营业执照</view>
<view class="row_con2">
<u-upload :fileList="imgList5" @afterRead="afterReadImg3" @delete="deletePic3" name="1" multiple
:maxCount="1">
<view class="imgCon">
<image src="https://wechat-img-file.oss-cn-beijing.aliyuncs.com/property-img-file/com_imageImg.png" mode="widthFix"></image>
上传图片
</view>
</u-upload>
</view>
</view>
</view>
<div class="addBtn" @click="submit">立即入驻</div>
<view class="addBtn" @click="submit">立即入驻</view>
<u-picker :show="show" :columns="[pro]" keyName="ad_name" @confirm="clickPro" @cancel="cancelPro"></u-picker>
<u-picker :show="show2" :columns="[city]" keyName="short_name" @confirm="clickCity"
@cancel="cancelCity"></u-picker>
<u-picker :show="show3" :columns="[buss]" keyName="short_name" @confirm="clickBuss"
@cancel="cancelBuss"></u-picker>
</div>
</view>
</template>
<script>
@ -113,9 +131,12 @@ export default {
imgList3: [],
imgList4: [],
imgList5: [],
imgList6: [],
contact_name: "",
contact_phone: "",
bank_card: "",
store_name: "",
address: "",
@ -191,10 +212,22 @@ export default {
})
})
},
afterReadImg3(e) {
e.file.forEach(item => {
upload(item.url, res => {
this.imgList5.push({ url: this.picUrl + res.data.path })
this.imgList6.push(res.data.path)
})
})
},
deletePic2(e) {
this.imgList3.splice(e.index, 1);
this.imgList4.splice(e.index, 1);
},
deletePic3(e) {
this.imgList5.splice(e.index, 1);
this.imgList6.splice(e.index, 1);
},
submit() {
let that = this
if (!that.contact_name) {
@ -239,20 +272,30 @@ export default {
duration: 2000
});
}
if (!that.imgList6.length) {
return uni.showToast({
title: '请上传营业执照',
duration: 2000
});
}
let interior_photo = that.imgList4.join(",")
let facade_photo = that.imgList2.join(",")
let license_photo = that.imgList6.join(",")
request(apiArr.createStore, "POST", {
contact_name: that.contact_name,
contact_phone: that.contact_phone,
bank_card: that.bank_card,
store_name: that.store_name,
address: that.address,
ad_code:that.confirmBusiness.ad_code,
facade_photo,
interior_photo,
license_photo,
}).then(res => {
that.contact_name = ''
that.contact_phone = ''
that.bank_card = ''
that.store_name = ''
that.address = ''
that.confirmProv = ''
@ -262,6 +305,8 @@ export default {
that.imgList2 = []
that.imgList3 = []
that.imgList4 = []
that.imgList5 = []
that.imgList6 = []
NavgateTo("../sucess/index")
})
},

View File

@ -56,10 +56,20 @@ image {
height: 200rpx;
}
.grid-item {
width: 80rpx;
height: 80rpx;
border-radius: 25rpx;
background-color: #f6f6f6;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 15rpx;
}
.nav_icon {
width: 50rpx;
height: 50rpx;
margin-bottom: 20rpx;
}
.community {

Some files were not shown because too many files have changed in this diff Show More