Commit 6f8cab2a authored by 陈宗胤(贵阳日报)'s avatar 陈宗胤(贵阳日报)
parents 6af8d534 f8bb17e0
This diff is collapsed.
......@@ -24,6 +24,7 @@
"@dcloudio/uni-quickapp-webview": "3.0.0-4000720240327002",
"@typescript-eslint/parser": "6.15.0",
"pinia": "2.0.36",
"qrcode": "^1.5.3",
"vue": "^3.3.11",
"vue-i18n": "^9.1.9",
"wot-design-uni": "^1.2.26"
......
......@@ -8,3 +8,30 @@ export function getOrderList(data) {
data,
});
}
// 订单列表接口
export function getOrderDetail(data) {
return request({
url: '/sgyrdd/sgyOrder/groupBuy/orderInfo',
method: 'GET',
data,
});
}
// 商品详情接口
export function getProdDetail(data) {
return request({
url: '/sgyrdd/prod/getProd',
method: 'GET',
data,
});
}
// 商铺详情接口
export function getShopDetail(data) {
return request({
url: '/sgyrdd/shop/getById',
method: 'GET',
data,
});
}
import { request } from '../utils/request';
// 套餐详情
export function getProdDetail(data) {
return request({
url: `/sgyrdd/prod/getProd?prodId=${data}`,
method: 'GET',
});
}
// 套餐详情
export function getCollect(data) {
return request({
url: `/sgyrdd/shop/collect?shopId=${data}`,
method: 'GET',
});
}
import { request } from '../utils/request';
// 分类
// 店铺信息
export function getStoreInformation(data) {
return request({
url: `/sgyrdd/shop/getById?shopId=${data}`,
method: 'GET',
});
}
// 店铺信息
export function groupBuyList(data) {
return request({
url: `/sgyrdd/prod/groupBuyList?shopId=${data}`,
method: 'GET',
});
}
// 商家评论列表分页
export function getEvaluationPage(data) {
return request({
url: `/sgyrdd/evaluation/page`,
method: 'GET',
data,
});
}
// 获取商家优惠券
export function couponShopList(data) {
return request({
url: `/sgyrdd/coupon/couponShopList/${data}`,
method: 'GET',
});
}
// 评论
export function likeOrDislike(data) {
return request({
url: `/sgyrdd/evaluation/likeOrDislike`,
method: 'POST',
data,
});
}
// 周边推荐
export function peripheryRecom(data) {
return request({
url: `/sgyrdd/category/peripheryRecomm`,
method: 'GET',
data,
});
}
// 商家列表分页-搜索列表
export function sgyrddShopPage(data) {
return request({
url: `/sgyrdd/shop/page`,
method: 'GET',
data,
});
}
@font-face {
font-family: "iconfont"; /* Project id 4633414 */
src: url('//at.alicdn.com/t/c/font_4633414_xeh7f81eleh.woff2?t=1722311537248') format('woff2'),
url('//at.alicdn.com/t/c/font_4633414_xeh7f81eleh.woff?t=1722311537248') format('woff'),
url('//at.alicdn.com/t/c/font_4633414_xeh7f81eleh.ttf?t=1722311537248') format('truetype');
src: url('//at.alicdn.com/t/c/font_4633414_jxzjjul419.woff2?t=1722502888587') format('woff2'),
url('//at.alicdn.com/t/c/font_4633414_jxzjjul419.woff?t=1722502888587') format('woff'),
url('//at.alicdn.com/t/c/font_4633414_jxzjjul419.ttf?t=1722502888587') format('truetype');
}
.iconfont {
......@@ -13,6 +13,22 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-shuangxiajiantou:before {
content: "\e660";
}
.icon-dianzan:before {
content: "\e602";
}
.icon-dianzan_kuai:before {
content: "\ec8c";
}
.icon-xiai:before {
content: "\e601";
}
.icon-tongzhi:before {
content: "\e60d";
}
......
......@@ -21,7 +21,8 @@
{
"path": "pages/shop/shop",
"style": {
"navigationBarTitleText": "店铺首页"
"navigationBarTitleText": "店铺首页",
"onReachBottomDistance":50
}
},
{
......@@ -81,6 +82,13 @@
"navigationBarTitleText": "支付成功"
}
}
,
{
"path": "pages/order/remark",
"style": {
"navigationBarTitleText": "美食评论"
}
}
],
"globalStyle": {
"navigationStyle": "custom"
......
......@@ -37,6 +37,7 @@ const handleBack = () => {
position: fixed;
z-index: 999;
width: 375 * 2rpx;
top: 0;
.headbox {
position: relative;
......
<template>
<view class="content">
<view class="box">
<view class="header">
<view class="content" v-if="dataList.length > 0">
<view class="box" v-for="(item, index) in dataList" :key="index">
<view class="header" @click="handleDetail(item.orderNumber)">
<view class="left">
<image src="@/static/order/shop.png" />
<view class="title">宽带融合5G 169套餐</view>
<view class="title">{{ item.shopName }}</view>
</view>
<span class="status">待消费</span>
<span class="status">{{ statusList[item.status] }}</span>
</view>
<view class="info">
<image
mode="aspectFill"
src="https://registry.npmmirror.com/wot-design-uni-assets/*/files/redpanda.jpg"
/>
<view class="info" @click="handleDetail(item.orderNumber)">
<image mode="aspectFill" :src="fileDomain + item.orderItems[0].pic" />
<view class="info-box">
<view class="text">下单时间:2023-06-27 15:53</view>
<view class="text">预约时间:2023-07-04 10:00-12:00</view>
<view class="text">数量:1</view>
<view class="text">实付:¥169</view>
<view class="text">下单时间:{{ item.createTime }}</view>
<view class="text">预约时间:{{ item.receiverTime }}</view>
<view class="text">数量:{{ item.orderItems[0].prodCount }}</view>
<view class="text">实付:¥{{ item.actualTotal }}</view>
</view>
</view>
<view class="btn">
<view class="btn-info">删除</view>
<view class="btn-info">查看预约</view>
<view class="btn-error">再来一单</view>
<view class="btn-info" v-if="item.status == 5 || item.status == 6">删除</view>
<view class="btn-info" v-if="item.status == 3" @click="handleDetail(item.orderNumber)">
查看预约
</view>
<view class="btn-info" v-if="item.status == 1">取消订单</view>
<view class="btn-info">联系商家</view>
<view class="btn-error" v-if="item.status == 7">售后详情</view>
<view class="btn-error" v-if="item.status == 2 || item.status == 3 || item.status == 4">
申请退款
</view>
<view class="btn-error" v-if="item.status == 5">再来一单</view>
<view class="btn-error" v-if="item.status == 1">立即支付</view>
</view>
</view>
<wd-loadmore :state="state" @reload="loadmore" />
<wd-loadmore :state="state" @reload="getList" />
</view>
<wd-status-tip image="content" tip="暂无内容" v-else />
</template>
<script setup>
import { getOrderList } from '@/api/order';
const fileDomain = import.meta.env.VITE_APP_IMG_URL;
const emits = defineEmits(['refresh']);
const state = ref('loading');
const page = reactive({
pageNum: 0,
pageSize: 10,
const catalog = reactive({
current: 0,
size: 10,
startDate: '',
endDate: '',
keyword: '',
status: '', // 订单状态,1-待付款,2-待接单,3-待取货,4-待评价,5-完成,6-取消,7-退款
});
const statusList = ref({
1: '待付款',
3: '待消费',
4: '待评价',
5: '已完成',
6: '已取消',
7: '已退款',
});
const total = ref(0);
const dataList = ref([]);
const num = ref(0);
const max = ref(60);
onReachBottom(() => {
if (num.value === 45) {
const getList = async () => {
catalog.current++;
state.value = 'loading';
const res = await getOrderList(catalog);
if (res.code === 0) {
if (res.data.records.length > 0) {
dataList.value.push(...res.data.records);
total.value = res.data.total;
console.log(total.value);
} else {
state.value = 'finished';
}
} else {
state.value = 'error';
} else if (num.value < max.value) {
getList();
} else if (num.value === max.value) {
}
};
getList();
onReachBottom(() => {
if (dataList.value.length >= total.value) {
state.value = 'finished';
} else {
getList();
}
});
const getList = async () => {
const res = await getOrderList();
state.value = 'loading';
console.log(res);
const handleDetail = (id) => {
uni.navigateTo({
url: `/pages/order/detail?orderNumber=${id}`,
});
};
getList();
const handleRefresh = (e) => {
catalog.status = e;
if (e === '0') {
catalog.status = '';
}
catalog.current = 0;
dataList.value = [];
total.value = 0;
getList();
};
defineExpose({
refresh: handleRefresh,
});
</script>
<style lang="scss" scoped>
......@@ -69,6 +120,7 @@ getList();
align-items: center;
justify-content: center;
padding: 20rpx;
gap: 24rpx;
.box {
background-color: #fff;
......
This diff is collapsed.
......@@ -2,13 +2,12 @@
<view class="container">
<Header title="全部订单"></Header>
<view class="tabs">
<wd-tabs v-model="tab" animated lineWidth="38" lineHeight="3">
<block v-for="item in tabs" :key="item">
<wd-tab :title="`${item}`" :name="item">
<OrderList></OrderList>
</wd-tab>
<wd-tabs v-model="tab" animated :lineWidth="38" :lineHeight="3" @change="handleChange">
<block v-for="item in tabs" :key="item.value">
<wd-tab :title="`${item.name}`" :name="item.value"></wd-tab>
</block>
</wd-tabs>
<OrderList ref="OrderListRef"></OrderList>
</view>
</view>
</template>
......@@ -17,8 +16,37 @@
import Header from './components/Header/index.vue';
import OrderList from './components/OrderList/index.vue';
const tabs = ref(['全部', '待付款', '待收货', '待使用', '待评价', '退款/售后']);
const tab = ref('待使用');
const tabs = ref([
{
name: '全部',
value: '0',
},
{
name: '待付款',
value: '1',
},
{
name: '待使用',
value: '3',
},
{
name: '待评价',
value: '4',
},
{
name: '退款/售后',
value: '7',
},
]);
const tab = ref('0');
onReachBottom(() => {});
const OrderListRef = ref(null);
const handleChange = (e) => {
tab.value = e.name;
OrderListRef.value.refresh(tab.value);
};
</script>
<style scoped lang="scss">
......
<template>
<view class="container">
<Header title="评论"></Header>
<view class="content">
<view class="remake">
<wd-row>
<wd-col :span="24" custom-class="text">
<h5>老凯里酸汤鱼(花果园M区店)</h5>
</wd-col>
</wd-row>
<wd-row>
<wd-col :span="16">
<span>评分:</span>
<wd-rate v-model="value" />
</wd-col>
<wd-col :span="8"></wd-col>
</wd-row>
</view>
<wd-button type="error" block>发布</wd-button>
</view>
</view>
</template>
<script setup>
import Header from './components/Header/index.vue';
</script>
<style lang="scss" scoped>
.container {
width: 100%;
height: auto;
background: #f4f4f4;
margin-top: 88rpx;
min-height: calc(100vh - 88rpx);
display: flex;
flex-direction: column;
}
.content {
margin: 0 20rpx;
.remake {
width: auto;
height: auto;
background: #ffffff;
border-radius: 16rpx;
margin-top: 25rpx;
margin-bottom: 172rpx;
padding: 20rpx;
.text h5 {
font-weight: 400;
font-size: 32rpx;
color: #333333;
line-height: 32rpx;
text-align: left;
}
}
}
</style>
......@@ -4,13 +4,14 @@
<view class="swiper">
<wd-swiper
customClass="swiper-custom"
:list="swiperList"
:list="prodInfo.imgs"
autoplay
height="512rpx"
customStyle="border-radius: 0rpx;"
:current="current"
@click="handleClick"
@change="onChange"
:indicator="{ type: 'dots-bar' }"
></wd-swiper>
</view>
<!-- 轮播-end -->
......@@ -19,12 +20,12 @@
<view class="package-details-num">
<view class="num">
<text class="icon"></text>
<text class="amount-of-money">88</text>
<text class="amount-of-money">{{ prodInfo.price }}</text>
</view>
<view class="num2">128</view>
<view class="num3">共省¥30</view>
<view class="num2">{{ prodInfo.oriPrice }}</view>
<view class="num3">共省¥{{ (prodInfo.oriPrice - prodInfo.price).toFixed(2) }}</view>
</view>
<view class="title">双人田蛙尝鲜餐(30元代金券一张,除酒水 饮料外全场通用,仅能使用一张)</view>
<view class="title">{{ prodInfo.prodName }}</view>
<view class="info-card">
<view class="yh">
<text class="yh-name">优惠:</text>
......@@ -62,14 +63,33 @@
<!-- card-end -->
<view class="rich-text-card">
<text class="title">商品详情</text>
<rich-text :nodes="'nodes'"></rich-text>
<rich-text :nodes="prodInfo.content"></rich-text>
</view>
<view class="rich-text-card">
<text class="title">购买须知</text>
<rich-text :nodes="'nodes'"></rich-text>
<view class="rich-more-btn">
收起
<image src="@/static/shop/more.png"></image>
<!-- <rich-text :nodes="'nodes'"></rich-text> -->
<view class="purchase-information" v-if="showRlue">
<view class="purchase-box">
<text class="title">开始时间</text>
<text class="content">{{ prodRlue.createTime }}</text>
</view>
<view class="purchase-box">
<text class="title">结束时间</text>
<text class="content">{{ prodRlue.endTime }}</text>
</view>
<view class="purchase-box">
<text class="title">标签</text>
<text class="content">{{ prodRlue.labelNames }}</text>
</view>
<view class="purchase-box">
<text class="title">规则</text>
<text class="content">{{ prodRlue.rule }}</text>
</view>
</view>
<view class="rich-more-btn" @click="showRlueFn">
{{ showRlue ? '收起' : '展开' }}
<i v-if="showRlue" class="iconfont icon-shuangshangjiantou-"></i>
<i v-else class="iconfont xia icon-shuangxiajiantou"></i>
</view>
</view>
<!-- 使用方法-start -->
......@@ -101,21 +121,21 @@
<!-- 适用门店 -->
<view class="applicable-stores-card">
<text class="title">适用门店</text>
<text class="goods-name">川心美蛙鱼头火锅(中环广场店)</text>
<text class="goods-name">{{ shopInfo.shopName }}</text>
<view class="goods-pf-rs">
<text class="goods-fs">4.3</text>
<text class="goods-fs">{{ shopInfo.grade }}</text>
<text class="goods-type">火锅</text>
<text class="goods-rs">36/人</text>
<!-- <text class="goods-rs">36/人</text> -->
</view>
<text class="distance">距你129m</text>
<text class="address">后巢乡花果园中环广场3号(M区4栋)3层114号</text>
<text class="distance">距你{{ distance }}</text>
<text class="address">{{ shopInfo.shopAddress }}</text>
</view>
<!-- 适用门店-end -->
<!-- 底部 -->
<view class="bottom-operation-bar">
<view class="start">
<view class="start" @click="collectionFn">
<image src="@/static/shop/start.png"></image>
241
{{ shopInfo.privateIntFcount }}
</view>
<view class="start">
<image src="@/static/shop/share.png"></image>
......@@ -128,11 +148,117 @@
</template>
<script setup>
const swiperList = ref([
'https://registry.npmmirror.com/wot-design-uni-assets/*/files/redpanda.jpg',
'https://registry.npmmirror.com/wot-design-uni-assets/*/files/capybara.jpg',
'https://registry.npmmirror.com/wot-design-uni-assets/*/files/panda.jpg',
]);
import { getProdDetail, getCollect } from '@/api/packageDetail';
import { getStoreInformation } from '@/api/shop';
const prodInfo = ref({});
const prodRlue = ref({});
const myProdId = ref('');
const current = ref(0);
const showRlue = ref(true);
const imgUrl = import.meta.env.VITE_APP_IMG_URL;
const shopInfo = ref({});
const currentLatitudeAndLongitude = ref({});
const shopId = ref('');
onLoad((options) => {
const { prodId } = options;
myProdId.value = prodId;
getProdDetailFn(prodId).then((shopId) => {
getStoreInformationFn(shopId);
});
});
onShow(() => {
// 获取位置
getLocationFn();
});
/**
* 获取套餐详情
* @param {String} prodId
*/
function getProdDetailFn(prodId) {
return new Promise((resolve, reject) => {
getProdDetail(prodId).then((res) => {
if (res.code === 0) {
res.data.data.prod.imgs = res.data.data.prod.imgs.split(',');
res.data.data.prod.imgs.push(res.data.data.prod.pic);
res.data.data.prod.imgs = res.data.data.prod.imgs
.map((item) => {
if (item !== '') {
item = imgUrl + item;
}
return item;
})
.filter((item) => {
return item !== '';
});
prodInfo.value = res.data.data.prod;
prodRlue.value = res.data.data.groupPurchasePackageRule;
shopId.value = res.data.data.prod.shopId;
resolve(res.data.data.prod.shopId);
}
});
});
}
/**
* 获取收藏
*/
function getCollectFn(shopId) {
getCollect(shopId).then((res) => {
if (res.code === 0) {
console.log('111');
}
});
}
function collectionFn() {
console.log('shopInfo.value', shopId.value);
getCollectFn(shopId.value);
}
function getLocationFn() {
xma.getLocation({
type: 'wgs84',
success: function (res) {
const myLatitude = currentLatitudeAndLongitude.value.latitude;
const myLongitude = currentLatitudeAndLongitude.value.longitude;
const distance = getDistance(res.latitude, res.longitude, myLatitude, myLongitude, 1);
shopInfo.value.distance = distance;
},
fail: function (err) {
return err;
},
});
}
const showRlueFn = () => {
showRlue.value = !showRlue.value;
};
const handleClick = (e) => {
const { index } = e;
const imgSrc = prodInfo.value.imgs[index];
previewImage(imgSrc);
};
const onChange = (e) => {};
/**
* 图片预览
*/
function previewImage(imgSrc) {
xma.previewImage({
current: imgSrc, // 当前显示图片的链接,不填则默认为 urls 的第一张
urls: [imgSrc], // 需要预览的图片链接列表
});
}
// 获取店铺信息
const getStoreInformationFn = (id) => {
return new Promise((resolve, reject) => {
getStoreInformation(id).then((res) => {
if (res.code === 0) {
shopInfo.value = res.data.shop;
shopInfo.value.tagList = res.data.shop.labels.split(',');
currentLatitudeAndLongitude.value.latitude = res.data.shop.location.lat;
currentLatitudeAndLongitude.value.longitude = res.data.shop.location.lon;
resolve();
}
});
});
};
</script>
<style lang="scss" scoped>
......@@ -151,6 +277,9 @@ page {
:deep(.wd-swiper__track) {
border-radius: 0;
}
:deep(.wd-swiper-nav--bottom) {
bottom: 100rpx;
}
}
.package-details-card {
width: 710rpx;
......@@ -190,7 +319,7 @@ page {
border-radius: 14rpx 14rpx 14rpx 0rpx;
font-size: 10 * 2rpx;
margin-left: 10rpx;
padding: 2rpx;
padding: 4rpx;
color: #ff494e;
}
}
......@@ -279,11 +408,37 @@ page {
margin-top: 10rpx;
border-radius: 8 * 2rpx;
box-shadow: 0 -8rpx 22 * 2rpx 0 rgba(255, 255, 255, 0.6);
.purchase-information {
display: flex;
flex-direction: column;
align-content: flex-start;
.purchase-box {
display: flex;
flex-wrap: wrap;
margin-top: 20rpx;
.title {
font-size: 11 * 2rpx;
color: #767676;
}
.content {
font-size: 11 * 2rpx;
margin-left: 32rpx;
color: #3d3d3d;
}
}
}
.title {
font-size: 13 * 2rpx;
color: #151515;
font-weight: 500;
}
img {
width: 100%;
height: auto;
}
p {
font-size: 22rpx;
}
.rich-more-btn {
width: 315 * 2rpx;
display: flex;
......@@ -295,6 +450,10 @@ page {
box-sizing: border-box;
padding: 20rpx 0 0 0;
margin-top: 20rpx;
.xia {
font-size: 20rpx;
margin-left: 10rpx;
}
image {
width: 18rpx;
height: 18rpx;
......@@ -362,7 +521,7 @@ page {
}
}
.bottom-operation-bar {
width: 100%;
width: 750rpx;
background: #fff;
border-radius: 16rpx 16rpx 0 0;
display: flex;
......
This diff is collapsed.
// 根据经纬度计算距离,参数分别为第一点的纬度、经度;第二点的纬度、经度
/**
*
* @param {*} lat1 第一个纬度
* @param {*} lng1 第一个经度
* @param {*} lat2 第二个纬度
* @param {*} lng2 第二个经度
* @param {*} type 0 中文 1 英文
* @returns
*/
export function getDistance(lat1, lng1, lat2, lng2, type = 1) {
const R = 6371; // 地球半径,单位为千米
const dLat = deg2rad(lat2 - lat1);
const dLng = deg2rad(lng2 - lng1);
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.sin(dLng / 2) * Math.sin(dLng / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
const distance = R * c;
return distance >= 1
? type === 0
? distance.toFixed(2) + '千米'
: distance.toFixed(2) + 'km'
: type === 1
? (distance * 1000).toFixed(2) + '米'
: (distance * 1000).toFixed(2) + 'm';
}
// 将角度转换为弧度
function deg2rad(deg) {
return deg * (Math.PI / 180);
}
/**
* 更具图片路径返回全路径还是拼接的路径
* @param {*} imgUrl
* @param {*} avatarUrl
* @returns
*/
export function addImgUrlPrefix(imgUrl, avatarUrl) {
// 使用正则表达式检查是否是全路径
const isFullUrl = /^https?:\/\//i.test(avatarUrl);
// 如果不是全路径,添加 imgUrl 前缀
if (!isFullUrl) {
return imgUrl + avatarUrl;
}
// 如果是全路径,直接返回
return avatarUrl;
}
export function addImgUrlPrefixToImages(imgUrl, imagePaths) {
if (imagePaths !== '') {
// 使用逗号分隔的图片路径
const pathsArray = imagePaths.split(',');
// 在每个路径前面添加 imgUrl 前缀
const prefixedPaths = pathsArray.map((path) => imgUrl + path.trim());
// 返回组装好的数组
return prefixedPaths;
} else {
return [];
}
}
// 防抖
export function debounce(func, wait) {
let timeout;
return function (...args) {
clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(this, args);
}, wait);
};
}
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment