feat: 商品详情页面交互

This commit is contained in:
duanshuwen
2025-08-02 17:35:57 +08:00
parent 9d6abe3e2a
commit ea5841d594
28 changed files with 1967 additions and 268 deletions

View File

@@ -14,11 +14,7 @@
<view class="goods-description">
<text class="goods-title">{{ commodityName }}</text>
<!-- 门店地址 -->
<view class="store-address" @click="openMap">
<uni-icons type="location" size="18" color="#999" />
<text>{{ orderData.commodityAddress }}</text>
<uni-icons type="right" size="14" color="#999" />
</view>
<LocationInfo :orderData="orderData" />
<!-- 酒店类型 -->
<template v-if="orderData.orderType === '0'">
<view class="in-date" v-if="checkInData">
@@ -48,6 +44,7 @@
<script setup>
import { defineProps, computed } from "vue";
import LocationInfo from "@/components/LocationInfo/index.vue";
import iconHouse from "./images/icon_house.png";
import iconFood from "./images/food.png";
import iconTicket from "./images/ticket.png";
@@ -123,29 +120,6 @@ const formatServiceAmount = (amount) => {
if (!amount) return "";
return typeof amount === "number" ? `×${amount}` : amount;
};
// 打开地图
const openMap = () => {
const address = props.orderData.commodityAddress;
const latitude = Number(props.orderData.commodityLatitude);
const longitude = Number(props.orderData.commodityLongitude);
uni.getLocation({
type: "gcj02", //返回可以用于uni.openLocation的经纬度
success: (res) => {
console.log("当前经纬度", latitude, longitude);
uni.openLocation({
latitude: latitude,
longitude: longitude,
address: address,
success: () => {
console.log("success");
},
});
},
});
};
</script>
<style scoped lang="scss">

View File

@@ -99,19 +99,6 @@ $image-size-md: 65px;
line-height: 1.4;
}
.store-address {
@include flex-center;
@include text-style($font-size-xs, $color-primary);
text {
flex: 1;
padding: 0 6px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.in-date,
.out-date {
@include text-style($font-size-xs, $color-secondary);

View File

@@ -1,57 +0,0 @@
<template>
<view class="top-nav-bar" :style="{ paddingTop: statusBarHeight + 'px' }">
<view class="nav-content">
<view class="nav-left" @click="goBack">
<uni-icons class="icon-back" type="left" size="20" color="#333">
</uni-icons>
</view>
<view class="nav-center">
<slot name="title">
<text class="nav-title">{{ title }}</text>
</slot>
</view>
</view>
</view>
</template>
<script setup>
import { ref, onMounted } from "vue";
// Props
const props = defineProps({
title: {
type: String,
default: "",
},
showBack: {
type: Boolean,
default: true,
},
});
// Emits
const emit = defineEmits(["back"]);
// 状态栏高度
const statusBarHeight = ref(0);
// 获取系统信息
onMounted(() => {
const systemInfo = uni.getSystemInfoSync();
statusBarHeight.value = systemInfo.statusBarHeight || 44;
});
// 返回上一页
const goBack = () => {
if (props.showBack) {
emit("back");
uni.navigateBack({
delta: 1,
});
}
};
</script>
<style scoped>
@import "./styles/index.scss";
</style>

View File

@@ -1,114 +0,0 @@
## 顶部导航栏组件
组件名称:顶部导航栏组件
## 功能特性
1. **自适应状态栏高度**:自动获取设备状态栏高度并适配
2. **返回功能**:左侧返回按钮,支持自定义返回事件
3. **标题显示**:支持传入标题文本或使用插槽自定义标题内容
4. **右侧扩展**:支持右侧插槽,可添加自定义操作按钮
5. **响应式设计**:适配不同屏幕尺寸
## 使用方法
### 基础用法
```vue
<template>
<TopNavBar title="服务工单" />
</template>
<script setup>
import TopNavBar from './components/TopNavBar/index.vue'
</script>
```
### 自定义标题
```vue
<template>
<TopNavBar>
<template #title>
<text class="custom-title">自定义标题</text>
</template>
</TopNavBar>
</template>
```
### 自定义右侧操作
```vue
<template>
<TopNavBar title="服务工单">
<template #right>
<image class="menu-icon" src="./images/menu.png" @click="showMenu" />
</template>
</TopNavBar>
</template>
```
### 自定义返回事件
```vue
<template>
<TopNavBar title="服务工单" @back="handleBack" />
</template>
<script setup>
const handleBack = () => {
// 自定义返回逻辑
console.log('自定义返回')
}
</script>
```
## Props
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| title | String | '' | 导航栏标题 |
| showBack | Boolean | true | 是否显示返回按钮 |
## Events
| 事件名 | 说明 | 参数 |
|--------|------|------|
| back | 点击返回按钮时触发 | - |
## Slots
| 插槽名 | 说明 |
|--------|------|
| title | 自定义标题内容 |
| right | 自定义右侧操作区域 |
## 样式定制
组件支持通过CSS变量进行样式定制
```scss
.top-nav-bar {
--nav-bg-color: #fff; // 背景色
--nav-title-color: #333; // 标题颜色
--nav-border-color: #f0f0f0; // 边框颜色
}
```
## 技术实现
- 使用 uniapp + Vue3 组合式 API 开发
- 自动获取系统状态栏高度进行适配
- 使用 fixed 定位实现固定顶部效果
- 支持插槽扩展,提供良好的可定制性
- 响应式设计,适配不同设备屏幕
## 兼容性
- 微信小程序
- H5
- App
## 备注
仅供学习、交流使用,请勿用于商业用途。

View File

@@ -1,28 +0,0 @@
.nav-content {
display: flex;
align-items: center;
height: 40px;
box-sizing: border-box;
padding-top: 8px;
}
.nav-left {
display: flex;
align-items: center;
justify-content: center;
width: 30px;
height: 30px;
}
.nav-center {
flex: 1;
display: flex;
align-items: center;
}
.nav-title {
font-size: 18px;
font-weight: 600;
color: #333;
text-align: center;
}

View File

@@ -9,7 +9,7 @@
@query="queryList"
>
<template #top>
<TopNavBar>
<TopNavBar titleAlign="left">
<template #title>
<Tabs
:tabs="tabList"
@@ -35,7 +35,7 @@
<script setup>
import { ref } from "vue";
import TopNavBar from "./components/TopNavBar/index.vue";
import TopNavBar from "@/components/TopNavBar/index.vue";
import Tabs from "./components/Tabs/index.vue";
import OrderCard from "./components/OrderCard/index.vue";
import CustomEmpty from "./components/CustomEmpty/index.vue";

View File

@@ -3,5 +3,5 @@
background-position: 0 0;
background-size: 100% 242px;
background-repeat: no-repeat;
// padding: 60px 15px;
padding: 60px 15px;
}