Compare commits
No commits in common. "f6821ade2d844169a4f8ce8d89f84bdd678f08e5" and "e2fe0a365b6935f775a78671a5ec811587235089" have entirely different histories.
f6821ade2d
...
e2fe0a365b
@ -61,8 +61,8 @@ const ERROR_MESSAGES = {
|
|||||||
* @typedef {Object} FormCardProps
|
* @typedef {Object} FormCardProps
|
||||||
* @property {string} title - 表单标题
|
* @property {string} title - 表单标题
|
||||||
* @property {Object} form - 表单数据对象
|
* @property {Object} form - 表单数据对象
|
||||||
* @property {string} form.visitorName - 姓名
|
* @property {string} form.name - 姓名
|
||||||
* @property {string} form.contactPhone - 手机号
|
* @property {string} form.phone - 手机号
|
||||||
* @property {boolean} showDeleteIcon - 是否显示删除图标
|
* @property {boolean} showDeleteIcon - 是否显示删除图标
|
||||||
*/
|
*/
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -73,16 +73,12 @@ const props = defineProps({
|
|||||||
form: {
|
form: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({
|
default: () => ({
|
||||||
visitorName: "",
|
name: "",
|
||||||
contactPhone: "",
|
phone: "",
|
||||||
}),
|
}),
|
||||||
validator: (value) => {
|
validator: (value) => {
|
||||||
return (
|
return value && typeof value === 'object' &&
|
||||||
value &&
|
'name' in value && 'phone' in value;
|
||||||
typeof value === "object" &&
|
|
||||||
"visitorName" in value &&
|
|
||||||
"contactPhone" in value
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
showDeleteIcon: {
|
showDeleteIcon: {
|
||||||
@ -94,15 +90,11 @@ const props = defineProps({
|
|||||||
/**
|
/**
|
||||||
* FormCard 组件事件
|
* FormCard 组件事件
|
||||||
* @typedef {Object} FormCardEmits
|
* @typedef {Object} FormCardEmits
|
||||||
* @property {Function} update:visitorName - 更新姓名事件
|
* @property {Function} update:name - 更新姓名事件
|
||||||
* @property {Function} update:contactPhone - 更新手机号事件
|
* @property {Function} update:phone - 更新手机号事件
|
||||||
* @property {Function} delete - 删除表单事件
|
* @property {Function} delete - 删除表单事件
|
||||||
*/
|
*/
|
||||||
const emit = defineEmits([
|
const emit = defineEmits(["update:name", "update:phone", "delete"]);
|
||||||
"update:visitorName",
|
|
||||||
"update:contactPhone",
|
|
||||||
"delete",
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 响应式状态
|
// 响应式状态
|
||||||
const nameError = ref("");
|
const nameError = ref("");
|
||||||
@ -110,16 +102,16 @@ const phoneError = ref("");
|
|||||||
|
|
||||||
// 计算属性 - 双向绑定
|
// 计算属性 - 双向绑定
|
||||||
const nameValue = computed({
|
const nameValue = computed({
|
||||||
get: () => props.form?.visitorName || "",
|
get: () => props.form?.name || "",
|
||||||
set: (value) => emit("update:visitorName", value?.trim() || ""),
|
set: (value) => emit("update:name", value?.trim() || ""),
|
||||||
});
|
});
|
||||||
|
|
||||||
const phoneValue = computed({
|
const phoneValue = computed({
|
||||||
get: () => props.form?.contactPhone || "",
|
get: () => props.form?.phone || "",
|
||||||
set: (value) => {
|
set: (value) => {
|
||||||
// 只允许数字输入
|
// 只允许数字输入
|
||||||
const numericValue = value.replace(/\D/g, "");
|
const numericValue = value.replace(/\D/g, "");
|
||||||
emit("update:contactPhone", numericValue);
|
emit("update:phone", numericValue);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -153,11 +145,11 @@ const getPhoneError = (phone) => {
|
|||||||
|
|
||||||
// 验证方法
|
// 验证方法
|
||||||
const validateName = () => {
|
const validateName = () => {
|
||||||
nameError.value = getNameError(props.form?.visitorName);
|
nameError.value = getNameError(props.form?.name);
|
||||||
};
|
};
|
||||||
|
|
||||||
const validatePhone = () => {
|
const validatePhone = () => {
|
||||||
phoneError.value = getPhoneError(props.form?.contactPhone);
|
phoneError.value = getPhoneError(props.form?.phone);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 事件处理
|
// 事件处理
|
||||||
|
|||||||
@ -1,45 +0,0 @@
|
|||||||
<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>
|
|
||||||
@ -1,49 +0,0 @@
|
|||||||
.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,12 +83,8 @@
|
|||||||
:form="item"
|
:form="item"
|
||||||
:showDeleteIcon="userFormList.length > 1"
|
:showDeleteIcon="userFormList.length > 1"
|
||||||
:key="index"
|
:key="index"
|
||||||
@update:visitorName="
|
@update:name="(value) => updateUserForm(index, 'name', value)"
|
||||||
(value) => updateUserForm(index, 'visitorName', value)
|
@update:phone="(value) => updateUserForm(index, 'phone', value)"
|
||||||
"
|
|
||||||
@update:contactPhone="
|
|
||||||
(value) => updateUserForm(index, 'contactPhone', value)
|
|
||||||
"
|
|
||||||
@delete="() => deleteUserForm(index)"
|
@delete="() => deleteUserForm(index)"
|
||||||
/>
|
/>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
@ -130,10 +126,10 @@ const showToast = (title, icon = "none", duration = 2000) => {
|
|||||||
const isValidUserForm = (user) => {
|
const isValidUserForm = (user) => {
|
||||||
return (
|
return (
|
||||||
user &&
|
user &&
|
||||||
typeof user.visitorName === "string" &&
|
typeof user.name === "string" &&
|
||||||
user.visitorName.trim() !== "" &&
|
user.name.trim() !== "" &&
|
||||||
typeof user.contactPhone === "string" &&
|
typeof user.phone === "string" &&
|
||||||
user.contactPhone.trim() !== ""
|
user.phone.trim() !== ""
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -169,7 +165,7 @@ const emits = defineEmits(["confirm", "close"]);
|
|||||||
|
|
||||||
// 工具函数
|
// 工具函数
|
||||||
const createEmptyUserForm = () => {
|
const createEmptyUserForm = () => {
|
||||||
return { visitorName: "", contactPhone: "" };
|
return { name: "", phone: "" };
|
||||||
};
|
};
|
||||||
|
|
||||||
// 响应式数据
|
// 响应式数据
|
||||||
@ -247,7 +243,7 @@ const updateUserForm = (index, field, value) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!["visitorName", "contactPhone"].includes(field)) {
|
if (!["name", "phone"].includes(field)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,8 +308,8 @@ const confirmOrder = () => {
|
|||||||
quantity: quantity.value,
|
quantity: quantity.value,
|
||||||
totalPrice: parseFloat(totalPrice.value),
|
totalPrice: parseFloat(totalPrice.value),
|
||||||
userFormList: userFormList.value.map((user) => ({
|
userFormList: userFormList.value.map((user) => ({
|
||||||
visitorName: user.visitorName.trim(),
|
name: user.name.trim(),
|
||||||
contactPhone: user.contactPhone.trim(),
|
phone: user.phone.trim(),
|
||||||
})),
|
})),
|
||||||
commodityType: props.goodsData?.commodityTypeCode,
|
commodityType: props.goodsData?.commodityTypeCode,
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
|
|||||||
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
<!-- 地址区域 -->
|
<!-- 地址区域 -->
|
||||||
<view class="address-section">
|
<view class="address-section">
|
||||||
<LocationCard :orderData="goodsData" />
|
<LocationInfo :orderData="goodsData" />
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 设施信息区域 -->
|
<!-- 设施信息区域 -->
|
||||||
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, defineProps, defineEmits } from "vue";
|
import { computed, defineProps, defineEmits } from "vue";
|
||||||
import LocationCard from "@/components/LocationCard/index.vue";
|
import LocationInfo from "@/components/LocationInfo/index.vue";
|
||||||
|
|
||||||
// 事件定义
|
// 事件定义
|
||||||
const emits = defineEmits(["showCalendar"]);
|
const emits = defineEmits(["showCalendar"]);
|
||||||
|
|||||||
@ -38,7 +38,9 @@
|
|||||||
|
|
||||||
// 地址区域
|
// 地址区域
|
||||||
.address-section {
|
.address-section {
|
||||||
padding: 6px 0;
|
padding: 12px 0;
|
||||||
|
border-top: 1px solid #f0f0f0;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
|
||||||
.address-item {
|
.address-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -59,8 +61,8 @@
|
|||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
|
|
||||||
.facilities-grid {
|
.facilities-grid {
|
||||||
display: flex;
|
display: grid;
|
||||||
flex-wrap: wrap;
|
grid-template-columns: repeat(3, 1fr);
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
|
||||||
.facility-item {
|
.facility-item {
|
||||||
|
|||||||
@ -15,42 +15,9 @@
|
|||||||
<!-- 商品信息组件 -->
|
<!-- 商品信息组件 -->
|
||||||
<GoodInfo :goodsData="goodsData" @showCalendar="showCalendar" />
|
<GoodInfo :goodsData="goodsData" @showCalendar="showCalendar" />
|
||||||
|
|
||||||
<view v-if="goodsData.commodityPurchaseInstruction" class="use-notice">
|
<ModuleTitle title="购买须知" />
|
||||||
<ModuleTitle
|
|
||||||
:title="goodsData.commodityPurchaseInstruction.templateTitle"
|
|
||||||
/>
|
|
||||||
<view
|
|
||||||
class="use-notice-content"
|
|
||||||
v-for="(moduleItem, index) in goodsData.commodityPurchaseInstruction
|
|
||||||
.commodityPurchaseInstructionModuleEntityList"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<view
|
|
||||||
class="module-item"
|
|
||||||
:class="{
|
|
||||||
'border-bottom':
|
|
||||||
index <
|
|
||||||
goodsData.commodityPurchaseInstruction
|
|
||||||
.commodityPurchaseInstructionModuleEntityList.length -
|
|
||||||
1,
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<view class="module-icon">
|
|
||||||
<uni-icons fontFamily="znicons" size="20" color="#333">{{
|
|
||||||
zniconsMap[moduleItem.moduleIcon]
|
|
||||||
}}</uni-icons>
|
|
||||||
<text class="module-title">{{ moduleItem.moduleTitle }}</text>
|
|
||||||
</view>
|
|
||||||
<text class="module-desc">{{ moduleItem.moduleContent }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<zero-markdown-view
|
<zero-markdown-view :markdown="goodsData.commodityTip" :aiMode='true' />
|
||||||
v-else
|
|
||||||
:markdown="goodsData.commodityTip"
|
|
||||||
:aiMode="true"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
|
||||||
@ -96,7 +63,6 @@ import GoodInfo from "./components/GoodInfo/index.vue";
|
|||||||
import ModuleTitle from "@/components/ModuleTitle/index.vue";
|
import ModuleTitle from "@/components/ModuleTitle/index.vue";
|
||||||
import GoodConfirm from "./components/GoodConfirm/index.vue";
|
import GoodConfirm from "./components/GoodConfirm/index.vue";
|
||||||
import Calender from "@/components/Calender/index.vue";
|
import Calender from "@/components/Calender/index.vue";
|
||||||
import { zniconsMap } from "@/static/fonts/znicons.js";
|
|
||||||
|
|
||||||
const calendarVisible = ref(false);
|
const calendarVisible = ref(false);
|
||||||
const goodsData = ref({});
|
const goodsData = ref({});
|
||||||
@ -280,8 +246,4 @@ const handleDateSelect = (data) => {
|
|||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "./styles/index.scss";
|
@import "./styles/index.scss";
|
||||||
@font-face {
|
|
||||||
font-family: znicons;
|
|
||||||
src: url("@/static/fonts/znicons.ttf");
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -15,47 +15,6 @@ $button-hover-color: darken($button-color, 8%);
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用须知样式
|
|
||||||
.use-notice {
|
|
||||||
margin: 16px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.use-notice-content {
|
|
||||||
.module-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 12px 0;
|
|
||||||
|
|
||||||
.module-icon {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
margin-right: 8px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
|
|
||||||
.module-title {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #333;
|
|
||||||
text-align: center;
|
|
||||||
word-wrap: break-word;
|
|
||||||
margin-left: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.module-desc {
|
|
||||||
flex: 1;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #666;
|
|
||||||
line-height: 1.5;
|
|
||||||
margin-top: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.border-bottom {
|
|
||||||
border-bottom: 1px solid #f0f0f0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-wrapper {
|
.content-wrapper {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 0; // 关键:让flex子项能够正确计算高度
|
height: 0; // 关键:让flex子项能够正确计算高度
|
||||||
|
|||||||
@ -1,19 +0,0 @@
|
|||||||
export const zniconsMap = {
|
|
||||||
"zn-wifi": "\ue681",
|
|
||||||
"zn-bath": "\ue682",
|
|
||||||
"zn-frame": "\ue683",
|
|
||||||
"zn-shower-gel": "\ue684",
|
|
||||||
"zn-a-washingmachine": "\ue685",
|
|
||||||
"zn-live": "\ue686",
|
|
||||||
"zn-user": "\ue687",
|
|
||||||
"zn-dish-cover": "\ue688",
|
|
||||||
"zn-glass-cup": "\ue689",
|
|
||||||
"zn-check-circle": "\ue68a",
|
|
||||||
"zn-send-filled": "\ue68b",
|
|
||||||
"zn-nav-arrow-right": "\ue68c",
|
|
||||||
"zn-nav-arrow-left": "\ue68d",
|
|
||||||
"zn-nav-arrow-down": "\ue68e",
|
|
||||||
"zn-fast-arrow-down": "\ue68f",
|
|
||||||
"zn-nav-arrow-up": "\ue690",
|
|
||||||
"zn-microphone": "\ue691",
|
|
||||||
};
|
|
||||||
Loading…
Reference in New Issue
Block a user