feat: 商品详情的调整
This commit is contained in:
@@ -61,8 +61,8 @@ const ERROR_MESSAGES = {
|
||||
* @typedef {Object} FormCardProps
|
||||
* @property {string} title - 表单标题
|
||||
* @property {Object} form - 表单数据对象
|
||||
* @property {string} form.name - 姓名
|
||||
* @property {string} form.phone - 手机号
|
||||
* @property {string} form.visitorName - 姓名
|
||||
* @property {string} form.contactPhone - 手机号
|
||||
* @property {boolean} showDeleteIcon - 是否显示删除图标
|
||||
*/
|
||||
const props = defineProps({
|
||||
@@ -73,12 +73,16 @@ const props = defineProps({
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
name: "",
|
||||
phone: "",
|
||||
visitorName: "",
|
||||
contactPhone: "",
|
||||
}),
|
||||
validator: (value) => {
|
||||
return value && typeof value === 'object' &&
|
||||
'name' in value && 'phone' in value;
|
||||
return (
|
||||
value &&
|
||||
typeof value === "object" &&
|
||||
"visitorName" in value &&
|
||||
"contactPhone" in value
|
||||
);
|
||||
},
|
||||
},
|
||||
showDeleteIcon: {
|
||||
@@ -90,11 +94,15 @@ const props = defineProps({
|
||||
/**
|
||||
* FormCard 组件事件
|
||||
* @typedef {Object} FormCardEmits
|
||||
* @property {Function} update:name - 更新姓名事件
|
||||
* @property {Function} update:phone - 更新手机号事件
|
||||
* @property {Function} update:visitorName - 更新姓名事件
|
||||
* @property {Function} update:contactPhone - 更新手机号事件
|
||||
* @property {Function} delete - 删除表单事件
|
||||
*/
|
||||
const emit = defineEmits(["update:name", "update:phone", "delete"]);
|
||||
const emit = defineEmits([
|
||||
"update:visitorName",
|
||||
"update:contactPhone",
|
||||
"delete",
|
||||
]);
|
||||
|
||||
// 响应式状态
|
||||
const nameError = ref("");
|
||||
@@ -102,16 +110,16 @@ const phoneError = ref("");
|
||||
|
||||
// 计算属性 - 双向绑定
|
||||
const nameValue = computed({
|
||||
get: () => props.form?.name || "",
|
||||
set: (value) => emit("update:name", value?.trim() || ""),
|
||||
get: () => props.form?.visitorName || "",
|
||||
set: (value) => emit("update:visitorName", value?.trim() || ""),
|
||||
});
|
||||
|
||||
const phoneValue = computed({
|
||||
get: () => props.form?.phone || "",
|
||||
get: () => props.form?.contactPhone || "",
|
||||
set: (value) => {
|
||||
// 只允许数字输入
|
||||
const numericValue = value.replace(/\D/g, "");
|
||||
emit("update:phone", numericValue);
|
||||
emit("update:contactPhone", numericValue);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -145,11 +153,11 @@ const getPhoneError = (phone) => {
|
||||
|
||||
// 验证方法
|
||||
const validateName = () => {
|
||||
nameError.value = getNameError(props.form?.name);
|
||||
nameError.value = getNameError(props.form?.visitorName);
|
||||
};
|
||||
|
||||
const validatePhone = () => {
|
||||
phoneError.value = getPhoneError(props.form?.phone);
|
||||
phoneError.value = getPhoneError(props.form?.contactPhone);
|
||||
};
|
||||
|
||||
// 事件处理
|
||||
|
||||
45
components/LocationCard/index.vue
Normal file
45
components/LocationCard/index.vue
Normal file
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<view class="store-address" @click="openMap">
|
||||
<text class="location-label">位于 [{{ orderData.commodityAddress }}]</text>
|
||||
<text class="address-text">{{ orderData.commodityAddress }}</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineProps } from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
orderData: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
|
||||
// 打开地图
|
||||
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">
|
||||
@import "./styles/index.scss";
|
||||
</style>
|
||||
49
components/LocationCard/styles/index.scss
Normal file
49
components/LocationCard/styles/index.scss
Normal file
@@ -0,0 +1,49 @@
|
||||
.store-address {
|
||||
display: flex;
|
||||
align-items: start;
|
||||
flex-direction: column;
|
||||
padding: 16px 12px;
|
||||
background-color: #f0f0f0;
|
||||
background-image: url(""); // 预留背景图片位置,用户手动导入
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
border-radius: 12px;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
// 添加半透明遮罩层确保文字可读性
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
// 确保内容在遮罩层之上
|
||||
.location-label,
|
||||
.address-text {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.location-label {
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
margin-right: 4px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.address-text {
|
||||
margin-top: 4px;
|
||||
flex: 1;
|
||||
color: #666;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
@@ -83,8 +83,12 @@
|
||||
:form="item"
|
||||
:showDeleteIcon="userFormList.length > 1"
|
||||
:key="index"
|
||||
@update:name="(value) => updateUserForm(index, 'name', value)"
|
||||
@update:phone="(value) => updateUserForm(index, 'phone', value)"
|
||||
@update:visitorName="
|
||||
(value) => updateUserForm(index, 'visitorName', value)
|
||||
"
|
||||
@update:contactPhone="
|
||||
(value) => updateUserForm(index, 'contactPhone', value)
|
||||
"
|
||||
@delete="() => deleteUserForm(index)"
|
||||
/>
|
||||
</scroll-view>
|
||||
@@ -126,10 +130,10 @@ const showToast = (title, icon = "none", duration = 2000) => {
|
||||
const isValidUserForm = (user) => {
|
||||
return (
|
||||
user &&
|
||||
typeof user.name === "string" &&
|
||||
user.name.trim() !== "" &&
|
||||
typeof user.phone === "string" &&
|
||||
user.phone.trim() !== ""
|
||||
typeof user.visitorName === "string" &&
|
||||
user.visitorName.trim() !== "" &&
|
||||
typeof user.contactPhone === "string" &&
|
||||
user.contactPhone.trim() !== ""
|
||||
);
|
||||
};
|
||||
|
||||
@@ -165,7 +169,7 @@ const emits = defineEmits(["confirm", "close"]);
|
||||
|
||||
// 工具函数
|
||||
const createEmptyUserForm = () => {
|
||||
return { name: "", phone: "" };
|
||||
return { visitorName: "", contactPhone: "" };
|
||||
};
|
||||
|
||||
// 响应式数据
|
||||
@@ -243,7 +247,7 @@ const updateUserForm = (index, field, value) => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!["name", "phone"].includes(field)) {
|
||||
if (!["visitorName", "contactPhone"].includes(field)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -308,8 +312,8 @@ const confirmOrder = () => {
|
||||
quantity: quantity.value,
|
||||
totalPrice: parseFloat(totalPrice.value),
|
||||
userFormList: userFormList.value.map((user) => ({
|
||||
name: user.name.trim(),
|
||||
phone: user.phone.trim(),
|
||||
visitorName: user.visitorName.trim(),
|
||||
contactPhone: user.contactPhone.trim(),
|
||||
})),
|
||||
commodityType: props.goodsData?.commodityTypeCode,
|
||||
timestamp: Date.now(),
|
||||
@@ -349,4 +353,4 @@ defineExpose({
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "./styles/index.scss";
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
<!-- 地址区域 -->
|
||||
<view class="address-section">
|
||||
<LocationInfo :orderData="goodsData" />
|
||||
<LocationCard :orderData="goodsData" />
|
||||
</view>
|
||||
|
||||
<!-- 设施信息区域 -->
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
<script setup>
|
||||
import { computed, defineProps, defineEmits } from "vue";
|
||||
import LocationInfo from "@/components/LocationInfo/index.vue";
|
||||
import LocationCard from "@/components/LocationCard/index.vue";
|
||||
|
||||
// 事件定义
|
||||
const emits = defineEmits(["showCalendar"]);
|
||||
@@ -77,4 +77,4 @@ const isShowCalendar = computed(() => {
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "./styles/index.scss";
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -38,9 +38,7 @@
|
||||
|
||||
// 地址区域
|
||||
.address-section {
|
||||
padding: 12px 0;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
padding: 6px 0;
|
||||
|
||||
.address-item {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user