优化模板界面内容
This commit is contained in:
parent
76e0db644d
commit
f0200ac849
@ -56,169 +56,191 @@
|
|||||||
</u-popup>
|
</u-popup>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import provinces from "./province.js";
|
import { ref, computed, onMounted, PropType } from 'vue';
|
||||||
import citys from "./city.js";
|
import provincesSource from "./province.js";
|
||||||
import areas from "./area.js";
|
import citysSource from "./city.js";
|
||||||
/**
|
import areasSource from "./area.js";
|
||||||
* city-select 省市区级联选择器
|
|
||||||
* @property {String Number} z-index 弹出时的z-index值(默认1075)
|
// 定义接口
|
||||||
* @property {Boolean} mask-close-able 是否允许通过点击遮罩关闭Picker(默认true)
|
interface Region {
|
||||||
* @property {String} default-region 默认选中的地区,中文形式
|
label: string;
|
||||||
* @property {String} default-code 默认选中的地区,编号形式
|
value: string;
|
||||||
*/
|
}
|
||||||
export default {
|
|
||||||
name: 'u-city-select',
|
interface CitySelectResult {
|
||||||
props: {
|
province: Region;
|
||||||
// 通过双向绑定控制组件的弹出与收起
|
city: Region;
|
||||||
modelValue: {
|
area: Region;
|
||||||
type: Boolean,
|
}
|
||||||
default: false
|
|
||||||
},
|
interface TabItem {
|
||||||
// 默认显示的地区,可传类似["河北省", "秦皇岛市", "北戴河区"]
|
name: string;
|
||||||
defaultRegion: {
|
}
|
||||||
type: Array,
|
|
||||||
default() {
|
// Props 定义
|
||||||
return [];
|
const props = defineProps({
|
||||||
}
|
// 通过双向绑定控制组件的弹出与收起
|
||||||
},
|
modelValue: {
|
||||||
// 默认显示地区的编码,defaultRegion和areaCode同时存在,areaCode优先,可传类似["13", "1303", "130304"]
|
type: Boolean,
|
||||||
areaCode: {
|
default: false
|
||||||
type: Array,
|
|
||||||
default() {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 是否允许通过点击遮罩关闭Picker
|
|
||||||
maskCloseAble: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
// 弹出的z-index值
|
|
||||||
zIndex: {
|
|
||||||
type: [String, Number],
|
|
||||||
default: 0
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
data() {
|
// 默认显示的地区,可传类似["河北省", "秦皇岛市", "北戴河区"]
|
||||||
return {
|
defaultRegion: {
|
||||||
cityValue: "",
|
type: Array as PropType<string[]>,
|
||||||
isChooseP: false, //是否已经选择了省
|
default: () => []
|
||||||
province: 0, //省级下标
|
|
||||||
provinces: provinces,
|
|
||||||
isChooseC: false, //是否已经选择了市
|
|
||||||
city: 0, //市级下标
|
|
||||||
citys: citys[0],
|
|
||||||
isChooseA: false, //是否已经选择了区
|
|
||||||
area: 0, //区级下标
|
|
||||||
areas: areas[0][0],
|
|
||||||
tabsIndex: 0,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
mounted() {
|
// 默认显示地区的编码,defaultRegion和areaCode同时存在,areaCode优先,可传类似["13", "1303", "130304"]
|
||||||
this.init();
|
areaCode: {
|
||||||
|
type: Array as PropType<string[]>,
|
||||||
|
default: () => []
|
||||||
},
|
},
|
||||||
computed: {
|
// 是否允许通过点击遮罩关闭Picker
|
||||||
isChange() {
|
maskCloseAble: {
|
||||||
return this.tabsIndex > 1;
|
type: Boolean,
|
||||||
},
|
default: true
|
||||||
genTabsList() {
|
|
||||||
let tabsList = [{
|
|
||||||
name: "请选择"
|
|
||||||
}];
|
|
||||||
if (this.isChooseP) {
|
|
||||||
tabsList[0]['name'] = this.provinces[this.province]['label'];
|
|
||||||
tabsList[1] = {
|
|
||||||
name: "请选择"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (this.isChooseC) {
|
|
||||||
tabsList[1]['name'] = this.citys[this.city]['label'];
|
|
||||||
tabsList[2] = {
|
|
||||||
name: "请选择"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (this.isChooseA) {
|
|
||||||
tabsList[2]['name'] = this.areas[this.area]['label'];
|
|
||||||
}
|
|
||||||
return tabsList;
|
|
||||||
},
|
|
||||||
uZIndex() {
|
|
||||||
// 如果用户有传递z-index值,优先使用
|
|
||||||
return this.zIndex ? this.zIndex : this.$u.zIndex.popup;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
emits: ['city-change'],
|
// 弹出的z-index值
|
||||||
methods: {
|
zIndex: {
|
||||||
init() {
|
type: [String, Number],
|
||||||
if (this.areaCode.length == 3) {
|
default: 0
|
||||||
this.setProvince("", this.areaCode[0]);
|
}
|
||||||
this.setCity("", this.areaCode[1]);
|
});
|
||||||
this.setArea("", this.areaCode[2]);
|
|
||||||
} else if (this.defaultRegion.length == 3) {
|
// 事件定义
|
||||||
this.setProvince(this.defaultRegion[0], "");
|
const emit = defineEmits<{
|
||||||
this.setCity(this.defaultRegion[1], "");
|
(e: 'update:modelValue', value: boolean): void;
|
||||||
this.setArea(this.defaultRegion[2], "");
|
(e: 'close'): void;
|
||||||
};
|
(e: 'city-change', result: CitySelectResult): void;
|
||||||
},
|
}>();
|
||||||
setProvince(label = "", value = "") {
|
|
||||||
this.provinces.map((v, k) => {
|
const cityValue = ref("");
|
||||||
if (value ? v.value == value : v.label == label) {
|
const isChooseP = ref(false); // 是否已经选择了省
|
||||||
this.provinceChange(k);
|
const province = ref(0); // 省级下标
|
||||||
}
|
const provinces = ref<Region[]>(provincesSource);
|
||||||
})
|
const isChooseC = ref(false); // 是否已经选择了市
|
||||||
},
|
const city = ref(0); // 市级下标
|
||||||
setCity(label = "", value = "") {
|
const citys = ref<Region[]>(citysSource[0]);
|
||||||
this.citys.map((v, k) => {
|
const isChooseA = ref(false); // 是否已经选择了区
|
||||||
if (value ? v.value == value : v.label == label) {
|
const area = ref(0); // 区级下标
|
||||||
this.cityChange(k);
|
const areas = ref<Region[]>(areasSource[0][0]);
|
||||||
}
|
const tabsIndex = ref(0);
|
||||||
})
|
const tabs = ref();
|
||||||
},
|
|
||||||
setArea(label = "", value = "") {
|
// 计算属性
|
||||||
this.areas.map((v, k) => {
|
const isChange = computed(() => {
|
||||||
if (value ? v.value == value : v.label == label) {
|
return tabsIndex.value > 1;
|
||||||
this.isChooseA = true;
|
});
|
||||||
this.area = k;
|
|
||||||
}
|
const genTabsList = computed((): TabItem[] => {
|
||||||
})
|
let tabsList: TabItem[] = [{
|
||||||
},
|
name: "请选择"
|
||||||
close() {
|
}];
|
||||||
this.$emit('update:modelValue', false);
|
|
||||||
this.$emit('close');
|
if (isChooseP.value) {
|
||||||
},
|
tabsList[0].name = provinces.value[province.value].label;
|
||||||
tabsChange(value) {
|
tabsList[1] = {
|
||||||
this.tabsIndex = value.index;
|
name: "请选择"
|
||||||
},
|
};
|
||||||
provinceChange(index) {
|
|
||||||
this.isChooseP = true;
|
|
||||||
this.isChooseC = false;
|
|
||||||
this.isChooseA = false;
|
|
||||||
this.province = index;
|
|
||||||
this.citys = citys[index];
|
|
||||||
this.tabsIndex = 1;
|
|
||||||
},
|
|
||||||
cityChange(index) {
|
|
||||||
this.isChooseC = true;
|
|
||||||
this.isChooseA = false;
|
|
||||||
this.city = index;
|
|
||||||
this.areas = areas[this.province][index];
|
|
||||||
this.tabsIndex = 2;
|
|
||||||
},
|
|
||||||
areaChange(index) {
|
|
||||||
this.isChooseA = true;
|
|
||||||
this.area = index;
|
|
||||||
let result = {};
|
|
||||||
result.province = this.provinces[this.province];
|
|
||||||
result.city = this.citys[this.city];
|
|
||||||
result.area = this.areas[this.area];
|
|
||||||
this.$emit('city-change', result);
|
|
||||||
this.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
if (isChooseC.value) {
|
||||||
|
tabsList[1].name = citys.value[city.value].label;
|
||||||
|
tabsList[2] = {
|
||||||
|
name: "请选择"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isChooseA.value) {
|
||||||
|
tabsList[2].name = areas.value[area.value].label;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tabsList;
|
||||||
|
});
|
||||||
|
|
||||||
|
const uZIndex = computed(() => {
|
||||||
|
// 如果用户有传递z-index值,优先使用
|
||||||
|
return props.zIndex ? props.zIndex : 1075; // 假设$u.zIndex.popup为1075
|
||||||
|
});
|
||||||
|
|
||||||
|
// 方法
|
||||||
|
const setProvince = (label = "", value = "") => {
|
||||||
|
provinces.value.map((v, k) => {
|
||||||
|
if (value ? v.value == value : v.label == label) {
|
||||||
|
provinceChange(k);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const setCity = (label = "", value = "") => {
|
||||||
|
citys.value.map((v, k) => {
|
||||||
|
if (value ? v.value == value : v.label == label) {
|
||||||
|
cityChange(k);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const setArea = (label = "", value = "") => {
|
||||||
|
areas.value.map((v, k) => {
|
||||||
|
if (value ? v.value == value : v.label == label) {
|
||||||
|
isChooseA.value = true;
|
||||||
|
area.value = k;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
emit('update:modelValue', false);
|
||||||
|
emit('close');
|
||||||
|
};
|
||||||
|
|
||||||
|
const tabsChange = (value: { index: number }) => {
|
||||||
|
tabsIndex.value = value.index;
|
||||||
|
};
|
||||||
|
|
||||||
|
const provinceChange = (index: number) => {
|
||||||
|
isChooseP.value = true;
|
||||||
|
isChooseC.value = false;
|
||||||
|
isChooseA.value = false;
|
||||||
|
province.value = index;
|
||||||
|
citys.value = citysSource[index];
|
||||||
|
tabsIndex.value = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
const cityChange = (index: number) => {
|
||||||
|
isChooseC.value = true;
|
||||||
|
isChooseA.value = false;
|
||||||
|
city.value = index;
|
||||||
|
areas.value = areasSource[province.value][index];
|
||||||
|
tabsIndex.value = 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
const areaChange = (index: number) => {
|
||||||
|
isChooseA.value = true;
|
||||||
|
area.value = index;
|
||||||
|
const result: CitySelectResult = {
|
||||||
|
province: provinces.value[province.value],
|
||||||
|
city: citys.value[city.value],
|
||||||
|
area: areas.value[area.value]
|
||||||
|
};
|
||||||
|
emit('city-change', result);
|
||||||
|
close();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 生命周期钩子
|
||||||
|
onMounted(() => {
|
||||||
|
if (props.areaCode.length == 3) {
|
||||||
|
setProvince("", props.areaCode[0]);
|
||||||
|
setCity("", props.areaCode[1]);
|
||||||
|
setArea("", props.areaCode[2]);
|
||||||
|
} else if (props.defaultRegion.length == 3) {
|
||||||
|
setProvince(props.defaultRegion[0], "");
|
||||||
|
setCity(props.defaultRegion[1], "");
|
||||||
|
setArea(props.defaultRegion[2], "");
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.area-box {
|
.area-box {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@ -2,22 +2,24 @@
|
|||||||
import { ref, reactive, onMounted } from 'vue';
|
import { ref, reactive, onMounted } from 'vue';
|
||||||
import tab from '@/plugins/tab';
|
import tab from '@/plugins/tab';
|
||||||
import citySelect from '@/components/u-city-select/u-city-select.vue';
|
import citySelect from '@/components/u-city-select/u-city-select.vue';
|
||||||
|
import { useAddressEditPage } from './index';
|
||||||
|
|
||||||
// 页面状态变量
|
// 使用编辑页面Hook
|
||||||
const show = ref(false);
|
const {
|
||||||
const defaultAddress = ref(false);
|
isEdit,
|
||||||
const selectedTag = ref('家');
|
form,
|
||||||
const isEdit = ref(false); // 是否为编辑模式
|
defaultAddress,
|
||||||
const editId = ref(''); // 编辑地址的ID
|
selectedTag,
|
||||||
|
addressTags,
|
||||||
|
initEditPage,
|
||||||
|
saveAddress,
|
||||||
|
deleteAddress
|
||||||
|
} = useAddressEditPage();
|
||||||
|
|
||||||
// 表单数据和验证状态
|
// 地区选择器显示状态
|
||||||
const form = reactive({
|
const showRegionPicker = ref(false);
|
||||||
name: '',
|
|
||||||
phone: '',
|
|
||||||
region: '',
|
|
||||||
address: ''
|
|
||||||
});
|
|
||||||
|
|
||||||
|
// 表单错误状态 - 移到Vue组件中
|
||||||
const formErrors = reactive({
|
const formErrors = reactive({
|
||||||
name: false,
|
name: false,
|
||||||
phone: false,
|
phone: false,
|
||||||
@ -25,101 +27,69 @@ const formErrors = reactive({
|
|||||||
address: false
|
address: false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 重置表单错误
|
||||||
|
function resetFormErrors() {
|
||||||
|
formErrors.name = false;
|
||||||
|
formErrors.phone = false;
|
||||||
|
formErrors.region = false;
|
||||||
|
formErrors.address = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化页面数据
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 获取传递过来的地址数据(如果是编辑模式)
|
|
||||||
const pages = getCurrentPages();
|
const pages = getCurrentPages();
|
||||||
const currentPage = pages[pages.length - 1];
|
const currentPage: any = pages[pages.length - 1];
|
||||||
const options = currentPage.$page?.options;
|
const options = currentPage.$page?.options;
|
||||||
|
|
||||||
if (options && options.id) {
|
// 调用hook的初始化方法
|
||||||
isEdit.value = true;
|
initEditPage(options?.id);
|
||||||
editId.value = options.id;
|
// 重置表单错误状态
|
||||||
loadAddressData(options.id);
|
resetFormErrors();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 加载要编辑的地址数据
|
|
||||||
const loadAddressData = (id: string) => {
|
|
||||||
try {
|
|
||||||
const addressList = uni.getStorageSync('addressList') || [];
|
|
||||||
const address = addressList.find((item: any) => item.id === id);
|
|
||||||
|
|
||||||
if (address) {
|
|
||||||
form.name = address.name;
|
|
||||||
form.phone = address.phoneOriginal || address.phone; // 使用原始手机号,而不是隐藏处理后的号码
|
|
||||||
form.region = address.region;
|
|
||||||
form.address = address.address;
|
|
||||||
selectedTag.value = address.tag || '家';
|
|
||||||
defaultAddress.value = address.isDefault;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error('加载地址数据失败', e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 设置默认地址
|
// 设置默认地址
|
||||||
const setDefault = (e: any) => {
|
function handleSetDefault(e: any) {
|
||||||
defaultAddress.value = e.detail.value;
|
defaultAddress.value = e.detail.value;
|
||||||
};
|
}
|
||||||
|
|
||||||
// 显示地区选择器
|
// 显示地区选择器
|
||||||
const showRegionPicker = () => {
|
function handleShowRegionPicker() {
|
||||||
show.value = true;
|
showRegionPicker.value = true;
|
||||||
};
|
}
|
||||||
|
|
||||||
// 确认选择地区
|
// 确认选择地区
|
||||||
const cityChange = (e) => {
|
function handleCityChange(e: any) {
|
||||||
form.region = e.province.label + e.city.label + e.area.label;
|
form.region = e.province.label + e.city.label + e.area.label;
|
||||||
formErrors.region = false;
|
formErrors.region = false;
|
||||||
};
|
}
|
||||||
|
|
||||||
// 选择标签
|
// 选择标签
|
||||||
const selectTag = (tag: string) => {
|
function handleSelectTag(tag: string) {
|
||||||
selectedTag.value = tag;
|
selectedTag.value = tag;
|
||||||
};
|
}
|
||||||
|
|
||||||
// 表单验证
|
// 表单验证
|
||||||
const validateForm = () => {
|
function validateForm(): boolean {
|
||||||
let isValid = true;
|
|
||||||
|
|
||||||
// 验证姓名
|
// 验证姓名
|
||||||
if (!form.name.trim()) {
|
formErrors.name = !form.name.trim();
|
||||||
formErrors.name = true;
|
|
||||||
isValid = false;
|
|
||||||
} else {
|
|
||||||
formErrors.name = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证手机号
|
// 验证手机号
|
||||||
const phoneReg = /^1[3-9]\d{9}$/;
|
const phoneReg = /^1[3-9]\d{9}$/;
|
||||||
if (!phoneReg.test(form.phone)) {
|
formErrors.phone = !phoneReg.test(form.phone);
|
||||||
formErrors.phone = true;
|
|
||||||
isValid = false;
|
|
||||||
} else {
|
|
||||||
formErrors.phone = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证地区
|
// 验证地区
|
||||||
if (!form.region) {
|
formErrors.region = !form.region;
|
||||||
formErrors.region = true;
|
|
||||||
isValid = false;
|
|
||||||
} else {
|
|
||||||
formErrors.region = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证详细地址
|
// 验证详细地址
|
||||||
if (!form.address.trim()) {
|
formErrors.address = !form.address.trim();
|
||||||
formErrors.address = true;
|
|
||||||
isValid = false;
|
// 如果有任何错误,返回false
|
||||||
} else {
|
return !(formErrors.name || formErrors.phone || formErrors.region || formErrors.address);
|
||||||
formErrors.address = false;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return isValid;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 保存地址
|
// 保存地址
|
||||||
const saveAddress = () => {
|
function handleSaveAddress() {
|
||||||
|
// 使用本地验证方法
|
||||||
if (!validateForm()) {
|
if (!validateForm()) {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '请填写完整信息',
|
title: '请填写完整信息',
|
||||||
@ -127,53 +97,26 @@ const saveAddress = () => {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 获取现有地址列表
|
const success = saveAddress();
|
||||||
let addressList = uni.getStorageSync('addressList') || [];
|
|
||||||
|
if (success) {
|
||||||
// 创建新地址对象
|
uni.showToast({
|
||||||
const addressData = {
|
title: isEdit.value ? '修改成功' : '添加成功',
|
||||||
id: isEdit.value ? editId.value : Date.now().toString(),
|
icon: 'success'
|
||||||
name: form.name,
|
});
|
||||||
phone: form.phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2'), // 隐藏中间4位
|
|
||||||
phoneOriginal: form.phone, // 保存原始手机号码用于编辑
|
// 延迟返回,让用户看到提示
|
||||||
region: form.region,
|
setTimeout(() => {
|
||||||
address: form.address,
|
tab.navigateBack();
|
||||||
tag: selectedTag.value,
|
}, 1000);
|
||||||
isDefault: defaultAddress.value
|
} else {
|
||||||
};
|
uni.showToast({
|
||||||
|
title: '保存失败',
|
||||||
if (defaultAddress.value) {
|
icon: 'none'
|
||||||
// 如果设为默认,将其他地址设为非默认
|
|
||||||
addressList = addressList.map((item: any) => {
|
|
||||||
return { ...item, isDefault: false };
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEdit.value) {
|
|
||||||
// 更新现有地址
|
|
||||||
const index = addressList.findIndex((item: any) => item.id === editId.value);
|
|
||||||
if (index !== -1) {
|
|
||||||
addressList[index] = addressData;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 添加新地址
|
|
||||||
addressList.push(addressData);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 保存到本地存储
|
|
||||||
uni.setStorageSync('addressList', addressList);
|
|
||||||
|
|
||||||
uni.showToast({
|
|
||||||
title: isEdit.value ? '修改成功' : '添加成功',
|
|
||||||
icon: 'success'
|
|
||||||
});
|
|
||||||
|
|
||||||
// 延迟返回,让用户看到提示
|
|
||||||
setTimeout(() => {
|
|
||||||
tab.navigateBack();
|
|
||||||
}, 1000);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('保存地址失败', e);
|
console.error('保存地址失败', e);
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
@ -181,30 +124,35 @@ const saveAddress = () => {
|
|||||||
icon: 'none'
|
icon: 'none'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
// 删除地址
|
// 删除地址
|
||||||
const deleteAddress = () => {
|
function handleDeleteAddress() {
|
||||||
if (!isEdit.value) return;
|
if (!isEdit.value) return;
|
||||||
|
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
content: '确定要删除此地址吗?',
|
content: '确定要删除此地址吗?',
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
if (res.confirm) {
|
if (res.confirm) {
|
||||||
try {
|
try {
|
||||||
let addressList = uni.getStorageSync('addressList') || [];
|
const success = deleteAddress();
|
||||||
addressList = addressList.filter((item: any) => item.id !== editId.value);
|
|
||||||
uni.setStorageSync('addressList', addressList);
|
if (success) {
|
||||||
|
uni.showToast({
|
||||||
uni.showToast({
|
title: '删除成功',
|
||||||
title: '删除成功',
|
icon: 'success'
|
||||||
icon: 'success'
|
});
|
||||||
});
|
|
||||||
|
setTimeout(() => {
|
||||||
setTimeout(() => {
|
tab.navigateBack();
|
||||||
tab.navigateBack();
|
}, 1000);
|
||||||
}, 1000);
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: '删除失败',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('删除地址失败', e);
|
console.error('删除地址失败', e);
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
@ -215,8 +163,9 @@ const deleteAddress = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<view class="wrap">
|
<view class="wrap">
|
||||||
<view class="container">
|
<view class="container">
|
||||||
@ -225,71 +174,50 @@ const deleteAddress = () => {
|
|||||||
<view class="left">
|
<view class="left">
|
||||||
<text class="required">*</text>收货人
|
<text class="required">*</text>收货人
|
||||||
</view>
|
</view>
|
||||||
<input
|
<input type="text" v-model="form.name" placeholder-class="line" placeholder="请填写收货人姓名"
|
||||||
type="text"
|
:class="{ 'error-input': formErrors.name }" />
|
||||||
v-model="form.name"
|
|
||||||
placeholder-class="line"
|
|
||||||
placeholder="请填写收货人姓名"
|
|
||||||
:class="{ 'error-input': formErrors.name }"
|
|
||||||
/>
|
|
||||||
<u-icon name="account" size="36rpx" color="#999"></u-icon>
|
<u-icon name="account" size="36rpx" color="#999"></u-icon>
|
||||||
</view>
|
</view>
|
||||||
<view class="error-msg" v-if="formErrors.name">请输入收货人姓名</view>
|
<view class="error-msg" v-if="formErrors.name">请输入收货人姓名</view>
|
||||||
|
|
||||||
<view class="item">
|
<view class="item">
|
||||||
<view class="left">
|
<view class="left">
|
||||||
<text class="required">*</text>手机号码
|
<text class="required">*</text>手机号码
|
||||||
</view>
|
</view>
|
||||||
<input
|
<input type="number" v-model="form.phone" placeholder-class="line" placeholder="请填写收货人手机号" maxlength="11"
|
||||||
type="number"
|
:class="{ 'error-input': formErrors.phone }" />
|
||||||
v-model="form.phone"
|
|
||||||
placeholder-class="line"
|
|
||||||
placeholder="请填写收货人手机号"
|
|
||||||
maxlength="11"
|
|
||||||
:class="{ 'error-input': formErrors.phone }"
|
|
||||||
/>
|
|
||||||
<u-icon name="phone" size="36rpx" color="#999"></u-icon>
|
<u-icon name="phone" size="36rpx" color="#999"></u-icon>
|
||||||
</view>
|
</view>
|
||||||
<view class="error-msg" v-if="formErrors.phone">请输入正确的手机号码</view>
|
<view class="error-msg" v-if="formErrors.phone">请输入正确的手机号码</view>
|
||||||
|
|
||||||
<view class="item" @tap="showRegionPicker">
|
<view class="item" @tap="handleShowRegionPicker">
|
||||||
<view class="left">
|
<view class="left">
|
||||||
<text class="required">*</text>所在地区
|
<text class="required">*</text>所在地区
|
||||||
</view>
|
</view>
|
||||||
<input
|
<input disabled v-model="form.region" type="text" placeholder-class="line" placeholder="省市区县、乡镇等"
|
||||||
disabled
|
:class="{ 'error-input': formErrors.region }" />
|
||||||
v-model="form.region"
|
|
||||||
type="text"
|
|
||||||
placeholder-class="line"
|
|
||||||
placeholder="省市区县、乡镇等"
|
|
||||||
:class="{ 'error-input': formErrors.region }"
|
|
||||||
/>
|
|
||||||
<u-icon name="arrow-right" size="36rpx" color="#999"></u-icon>
|
<u-icon name="arrow-right" size="36rpx" color="#999"></u-icon>
|
||||||
</view>
|
</view>
|
||||||
<view class="error-msg" v-if="formErrors.region">请选择所在地区</view>
|
<view class="error-msg" v-if="formErrors.region">请选择所在地区</view>
|
||||||
|
|
||||||
<view class="item address">
|
<view class="item address">
|
||||||
<view class="left">
|
<view class="left">
|
||||||
<text class="required">*</text>详细地址
|
<text class="required">*</text>详细地址
|
||||||
</view>
|
</view>
|
||||||
<textarea
|
<textarea v-model="form.address" type="text" placeholder-class="line" placeholder="街道、楼牌等"
|
||||||
v-model="form.address"
|
:class="{ 'error-textarea': formErrors.address }" />
|
||||||
type="text"
|
|
||||||
placeholder-class="line"
|
|
||||||
placeholder="街道、楼牌等"
|
|
||||||
:class="{ 'error-textarea': formErrors.address }"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="error-msg" v-if="formErrors.address">请输入详细地址</view>
|
<view class="error-msg" v-if="formErrors.address">请输入详细地址</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="bottom">
|
<view class="bottom">
|
||||||
<view class="tag">
|
<view class="tag">
|
||||||
<view class="left">标签</view>
|
<view class="left">标签</view>
|
||||||
<view class="right">
|
<view class="right">
|
||||||
<text class="tags" :class="{'active': selectedTag === '家'}" @tap="selectTag('家')">家</text>
|
<text v-for="tag in addressTags" :key="tag" class="tags" :class="{ 'active': selectedTag === tag }"
|
||||||
<text class="tags" :class="{'active': selectedTag === '公司'}" @tap="selectTag('公司')">公司</text>
|
@tap="handleSelectTag(tag)">
|
||||||
<text class="tags" :class="{'active': selectedTag === '学校'}" @tap="selectTag('学校')">学校</text>
|
{{ tag }}
|
||||||
|
</text>
|
||||||
<view class="tags plus"><u-icon size="22" name="plus" color="#999"></u-icon></view>
|
<view class="tags plus"><u-icon size="22" name="plus" color="#999"></u-icon></view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -299,22 +227,22 @@ const deleteAddress = () => {
|
|||||||
<view class="tips">提醒:每次下单会默认推荐该地址</view>
|
<view class="tips">提醒:每次下单会默认推荐该地址</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="right">
|
<view class="right">
|
||||||
<switch color="#fa3534" :checked="defaultAddress" @change="setDefault" />
|
<switch color="#fa3534" :checked="defaultAddress" @change="handleSetDefault" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="button-group">
|
<view class="button-group">
|
||||||
<view class="save-btn" @tap="saveAddress">
|
<view class="save-btn" @tap="handleSaveAddress">
|
||||||
{{ isEdit ? '保存修改' : '保存地址' }}
|
{{ isEdit ? '保存修改' : '保存地址' }}
|
||||||
</view>
|
</view>
|
||||||
<view v-if="isEdit" class="delete-btn" @tap="deleteAddress">
|
<view v-if="isEdit" class="delete-btn" @tap="handleDeleteAddress">
|
||||||
删除地址
|
删除地址
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<city-select v-model="show" @city-change="cityChange"></city-select>
|
<city-select v-model="showRegionPicker" @city-change="handleCityChange"></city-select>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -352,7 +280,7 @@ const deleteAddress = () => {
|
|||||||
width: 180rpx;
|
width: 180rpx;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #333;
|
color: #333;
|
||||||
|
|
||||||
.required {
|
.required {
|
||||||
color: #fa3534;
|
color: #fa3534;
|
||||||
margin-right: 4rpx;
|
margin-right: 4rpx;
|
||||||
@ -364,17 +292,17 @@ const deleteAddress = () => {
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
height: 100rpx;
|
height: 100rpx;
|
||||||
font-size: 30rpx;
|
font-size: 30rpx;
|
||||||
|
|
||||||
&.error-input {
|
&.error-input {
|
||||||
border-bottom: 1px solid #fa3534;
|
border-bottom: 1px solid #fa3534;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u-icon {
|
u-icon {
|
||||||
margin-left: 10rpx;
|
margin-left: 10rpx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.error-msg {
|
.error-msg {
|
||||||
color: #fa3534;
|
color: #fa3534;
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
@ -400,7 +328,7 @@ const deleteAddress = () => {
|
|||||||
padding: 20rpx;
|
padding: 20rpx;
|
||||||
border-radius: 12rpx;
|
border-radius: 12rpx;
|
||||||
font-size: 30rpx;
|
font-size: 30rpx;
|
||||||
|
|
||||||
&.error-textarea {
|
&.error-textarea {
|
||||||
border: 1px solid #fa3534;
|
border: 1px solid #fa3534;
|
||||||
}
|
}
|
||||||
@ -444,7 +372,7 @@ const deleteAddress = () => {
|
|||||||
color: #333;
|
color: #333;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
background-color: #ffebec;
|
background-color: #ffebec;
|
||||||
color: #fa3534;
|
color: #fa3534;
|
||||||
@ -471,7 +399,7 @@ const deleteAddress = () => {
|
|||||||
color: #333;
|
color: #333;
|
||||||
font-size: 30rpx;
|
font-size: 30rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tips {
|
.tips {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
color: #999;
|
color: #999;
|
||||||
@ -480,12 +408,12 @@ const deleteAddress = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-group {
|
.button-group {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
margin-top: 60rpx;
|
margin-top: 60rpx;
|
||||||
|
|
||||||
.save-btn {
|
.save-btn {
|
||||||
background: linear-gradient(90deg, #ff4034, #fa3534);
|
background: linear-gradient(90deg, #ff4034, #fa3534);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
@ -498,7 +426,7 @@ const deleteAddress = () => {
|
|||||||
box-shadow: 0 10rpx 20rpx rgba(250, 53, 52, 0.2);
|
box-shadow: 0 10rpx 20rpx rgba(250, 53, 52, 0.2);
|
||||||
letter-spacing: 2rpx;
|
letter-spacing: 2rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.delete-btn {
|
.delete-btn {
|
||||||
margin-top: 30rpx;
|
margin-top: 30rpx;
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
|
|||||||
256
src/pages_template/pages/address/index.ts
Normal file
256
src/pages_template/pages/address/index.ts
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
import { ref, reactive, computed } from 'vue';
|
||||||
|
import { onShow } from '@dcloudio/uni-app';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地址信息接口
|
||||||
|
*/
|
||||||
|
export interface AddressInfo {
|
||||||
|
id: string; // 地址ID
|
||||||
|
name: string; // 收货人姓名
|
||||||
|
phone: string; // 手机号码(已脱敏)
|
||||||
|
region: string; // 地区(如: 广东省深圳市南山区)
|
||||||
|
address: string; // 详细地址
|
||||||
|
tag: string; // 地址标签(如: 家、公司、学校)
|
||||||
|
isDefault: boolean; // 是否为默认地址
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 示例地址数据
|
||||||
|
*/
|
||||||
|
const sampleAddresses: AddressInfo[] = [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
name: '张三',
|
||||||
|
phone: '13712348888',
|
||||||
|
region: '广东省深圳市南山区',
|
||||||
|
address: '科技园南路888号创新大厦A座10楼',
|
||||||
|
tag: '公司',
|
||||||
|
isDefault: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
name: '李四',
|
||||||
|
phone: '13912345678',
|
||||||
|
region: '广东省深圳市福田区',
|
||||||
|
address: '福中路1000号海城大厦B座20楼2001室',
|
||||||
|
tag: '家',
|
||||||
|
isDefault: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '3',
|
||||||
|
name: '王五',
|
||||||
|
phone: '15812342233',
|
||||||
|
region: '广东省广州市天河区',
|
||||||
|
address: '天河路100号天河城购物中心附近小区A栋3单元701室',
|
||||||
|
tag: '学校',
|
||||||
|
isDefault: false
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// 共享的地址数据
|
||||||
|
const addressStore = {
|
||||||
|
list: ref<AddressInfo[]>([]),
|
||||||
|
tags: ref(['家', '公司', '学校'])
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化手机号,中间4位用星号代替
|
||||||
|
*/
|
||||||
|
export function formatPhoneNumber(phone: string): string {
|
||||||
|
return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地址列表页面Hook
|
||||||
|
* @description 提供地址列表页面所需的状态和方法
|
||||||
|
*/
|
||||||
|
export function useAddressListPage() {
|
||||||
|
// 从共享store获取响应式数据
|
||||||
|
const addressList = addressStore.list;
|
||||||
|
|
||||||
|
// 使用计算属性计算是否为空状态
|
||||||
|
const emptyStatus = computed(() => addressList.value.length === 0);
|
||||||
|
|
||||||
|
// 更新地址列表
|
||||||
|
function refreshAddressList() {
|
||||||
|
addressList.value = sampleAddresses
|
||||||
|
// 实际项目中,这里应该调用API获取最新的地址列表
|
||||||
|
// const response = await api.getAddressList();
|
||||||
|
// addressList.value = response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置默认地址
|
||||||
|
function setDefaultAddress(id: string): boolean {
|
||||||
|
const index = addressList.value.findIndex(item => item.id === id);
|
||||||
|
|
||||||
|
if (index === -1) return false;
|
||||||
|
|
||||||
|
// 更新所有地址的默认状态
|
||||||
|
addressList.value = addressList.value.map(item => ({
|
||||||
|
...item,
|
||||||
|
isDefault: item.id === id
|
||||||
|
}));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除地址
|
||||||
|
function deleteAddress(id: string): boolean {
|
||||||
|
const initialLength = addressList.value.length;
|
||||||
|
addressList.value = addressList.value.filter(item => item.id !== id);
|
||||||
|
return addressList.value.length !== initialLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 页面显示时刷新数据
|
||||||
|
onShow(() => {
|
||||||
|
refreshAddressList();
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
// 响应式状态
|
||||||
|
addressList,
|
||||||
|
emptyStatus,
|
||||||
|
// 方法
|
||||||
|
setDefaultAddress,
|
||||||
|
deleteAddress,
|
||||||
|
refreshAddressList
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 地址编辑页面Hook
|
||||||
|
* @description 提供地址编辑页面所需的状态和方法
|
||||||
|
*/
|
||||||
|
export function useAddressEditPage() {
|
||||||
|
// 从共享store获取响应式数据
|
||||||
|
const addressList = addressStore.list;
|
||||||
|
const addressTags = addressStore.tags;
|
||||||
|
|
||||||
|
// 页面状态
|
||||||
|
const isEdit = ref(false);
|
||||||
|
const editId = ref('');
|
||||||
|
const defaultAddress = ref(false);
|
||||||
|
const selectedTag = ref('家');
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const form = reactive({
|
||||||
|
name: '',
|
||||||
|
phone: '',
|
||||||
|
region: '',
|
||||||
|
address: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
// 加载编辑数据
|
||||||
|
function loadAddressData(id: string): boolean {
|
||||||
|
const address = addressList.value.find(item => item.id === id);
|
||||||
|
|
||||||
|
if (!address) return false;
|
||||||
|
|
||||||
|
// 填充表单数据
|
||||||
|
form.name = address.name;
|
||||||
|
form.phone = address.phone;
|
||||||
|
form.region = address.region;
|
||||||
|
form.address = address.address;
|
||||||
|
selectedTag.value = address.tag;
|
||||||
|
defaultAddress.value = address.isDefault;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化页面
|
||||||
|
function initEditPage(id?: string) {
|
||||||
|
// 重置状态
|
||||||
|
isEdit.value = !!id;
|
||||||
|
editId.value = id || '';
|
||||||
|
defaultAddress.value = false;
|
||||||
|
selectedTag.value = '家';
|
||||||
|
|
||||||
|
form.name = '';
|
||||||
|
form.phone = '';
|
||||||
|
form.region = '';
|
||||||
|
form.address = '';
|
||||||
|
|
||||||
|
// 如果是编辑模式,加载地址数据
|
||||||
|
if (id) {
|
||||||
|
loadAddressData(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存地址
|
||||||
|
function saveAddress(): boolean {
|
||||||
|
if (isEdit.value) {
|
||||||
|
// 编辑现有地址
|
||||||
|
const index = addressList.value.findIndex(item => item.id === editId.value);
|
||||||
|
if (index === -1) return false;
|
||||||
|
|
||||||
|
// 如果设为默认,更新其他地址
|
||||||
|
if (defaultAddress.value) {
|
||||||
|
addressList.value = addressList.value.map(item => {
|
||||||
|
if (item.id !== editId.value) {
|
||||||
|
return { ...item, isDefault: false };
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新当前地址
|
||||||
|
addressList.value[index] = {
|
||||||
|
...addressList.value[index],
|
||||||
|
name: form.name,
|
||||||
|
phone: form.phone,
|
||||||
|
region: form.region,
|
||||||
|
address: form.address,
|
||||||
|
tag: selectedTag.value,
|
||||||
|
isDefault: defaultAddress.value
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// 添加新地址
|
||||||
|
const newId = Date.now().toString();
|
||||||
|
|
||||||
|
// 如果设为默认,更新其他地址
|
||||||
|
if (defaultAddress.value) {
|
||||||
|
addressList.value = addressList.value.map(item => ({
|
||||||
|
...item,
|
||||||
|
isDefault: false
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加新地址
|
||||||
|
addressList.value.push({
|
||||||
|
id: newId,
|
||||||
|
name: form.name,
|
||||||
|
phone: form.phone,
|
||||||
|
region: form.region,
|
||||||
|
address: form.address,
|
||||||
|
tag: selectedTag.value,
|
||||||
|
isDefault: defaultAddress.value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除地址
|
||||||
|
function deleteAddress(): boolean {
|
||||||
|
if (!isEdit.value) return false;
|
||||||
|
|
||||||
|
const initialLength = addressList.value.length;
|
||||||
|
addressList.value = addressList.value.filter(item => item.id !== editId.value);
|
||||||
|
|
||||||
|
return addressList.value.length !== initialLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
// 响应式状态
|
||||||
|
isEdit,
|
||||||
|
editId,
|
||||||
|
form,
|
||||||
|
defaultAddress,
|
||||||
|
selectedTag,
|
||||||
|
addressTags,
|
||||||
|
// 方法
|
||||||
|
initEditPage,
|
||||||
|
saveAddress,
|
||||||
|
deleteAddress
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -1,30 +1,14 @@
|
|||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import { ref, onMounted } from 'vue';
|
|
||||||
import { onShow } from '@dcloudio/uni-app';
|
|
||||||
import tab from '@/plugins/tab';
|
import tab from '@/plugins/tab';
|
||||||
|
import { AddressInfo, useAddressListPage } from './index';
|
||||||
|
|
||||||
const siteList = ref([]);
|
// 使用列表页面Hook
|
||||||
const emptyStatus = ref(false);
|
const {
|
||||||
|
addressList,
|
||||||
// 使用onShow钩子确保每次页面显示时都刷新地址列表
|
emptyStatus,
|
||||||
onShow(() => {
|
setDefaultAddress,
|
||||||
getData();
|
deleteAddress
|
||||||
});
|
} = useAddressListPage();
|
||||||
|
|
||||||
// 从本地存储获取地址数据
|
|
||||||
function getData() {
|
|
||||||
try {
|
|
||||||
const addressList = uni.getStorageSync('addressList') || [];
|
|
||||||
siteList.value = addressList;
|
|
||||||
emptyStatus.value = addressList.length === 0;
|
|
||||||
} catch (e) {
|
|
||||||
console.error('获取地址列表失败', e);
|
|
||||||
uni.showToast({
|
|
||||||
title: '获取地址列表失败',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 跳转到添加地址页面
|
// 跳转到添加地址页面
|
||||||
function toAddSite() {
|
function toAddSite() {
|
||||||
@ -32,25 +16,26 @@ function toAddSite() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 跳转到编辑地址页面
|
// 跳转到编辑地址页面
|
||||||
function toEditSite(id) {
|
function toEditSite(id: string) {
|
||||||
tab.navigateTo(`/pages_template/pages/address/addSite?id=${id}`);
|
tab.navigateTo(`/pages_template/pages/address/addSite?id=${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置为默认地址
|
// 设置为默认地址
|
||||||
function setAsDefault(id) {
|
function handleSetDefault(id: string) {
|
||||||
try {
|
try {
|
||||||
let addressList = uni.getStorageSync('addressList') || [];
|
const success = setDefaultAddress(id);
|
||||||
addressList = addressList.map(item => {
|
|
||||||
return { ...item, isDefault: item.id === id };
|
|
||||||
});
|
|
||||||
|
|
||||||
uni.setStorageSync('addressList', addressList);
|
if (success) {
|
||||||
getData(); // 刷新列表
|
uni.showToast({
|
||||||
|
title: '设置成功',
|
||||||
uni.showToast({
|
icon: 'success'
|
||||||
title: '设置成功',
|
});
|
||||||
icon: 'success'
|
} else {
|
||||||
});
|
uni.showToast({
|
||||||
|
title: '设置失败',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('设置默认地址失败', e);
|
console.error('设置默认地址失败', e);
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
@ -61,22 +46,26 @@ function setAsDefault(id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 删除地址
|
// 删除地址
|
||||||
function deleteAddress(id) {
|
function handleDeleteAddress(id: string) {
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
content: '确定要删除此地址吗?',
|
content: '确定要删除此地址吗?',
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
if (res.confirm) {
|
if (res.confirm) {
|
||||||
try {
|
try {
|
||||||
let addressList = uni.getStorageSync('addressList') || [];
|
const success = deleteAddress(id);
|
||||||
addressList = addressList.filter(item => item.id !== id);
|
|
||||||
uni.setStorageSync('addressList', addressList);
|
|
||||||
getData(); // 刷新列表
|
|
||||||
|
|
||||||
uni.showToast({
|
if (success) {
|
||||||
title: '删除成功',
|
uni.showToast({
|
||||||
icon: 'success'
|
title: '删除成功',
|
||||||
});
|
icon: 'success'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: '删除失败',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('删除地址失败', e);
|
console.error('删除地址失败', e);
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
@ -90,9 +79,9 @@ function deleteAddress(id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 选择并返回地址(用于从订单页面选择地址的场景)
|
// 选择并返回地址(用于从订单页面选择地址的场景)
|
||||||
function selectAddress(address) {
|
function selectAddress(address: AddressInfo) {
|
||||||
const pages = getCurrentPages();
|
const pages = getCurrentPages();
|
||||||
const prevPage = pages[pages.length - 2];
|
const prevPage: any = pages[pages.length - 2];
|
||||||
|
|
||||||
// 检查页面是否从订单页面跳转而来
|
// 检查页面是否从订单页面跳转而来
|
||||||
if (prevPage && prevPage.$page?.options?.from === 'order') {
|
if (prevPage && prevPage.$page?.options?.from === 'order') {
|
||||||
@ -102,6 +91,7 @@ function selectAddress(address) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<view class="address-container">
|
<view class="address-container">
|
||||||
<!-- 空状态 -->
|
<!-- 空状态 -->
|
||||||
@ -112,7 +102,7 @@ function selectAddress(address) {
|
|||||||
|
|
||||||
<!-- 地址列表 -->
|
<!-- 地址列表 -->
|
||||||
<view v-else>
|
<view v-else>
|
||||||
<view class="item" v-for="(address, index) in siteList" :key="address.id">
|
<view class="item" v-for="(address, index) in addressList" :key="address.id">
|
||||||
<view class="top" @tap="selectAddress(address)">
|
<view class="top" @tap="selectAddress(address)">
|
||||||
<view class="name">{{ address.name }}</view>
|
<view class="name">{{ address.name }}</view>
|
||||||
<view class="phone">{{ address.phone }}</view>
|
<view class="phone">{{ address.phone }}</view>
|
||||||
@ -125,7 +115,7 @@ function selectAddress(address) {
|
|||||||
{{ address.region }} {{ address.address }}
|
{{ address.region }} {{ address.address }}
|
||||||
</view>
|
</view>
|
||||||
<view class="actions">
|
<view class="actions">
|
||||||
<view class="action-btn" @tap="setAsDefault(address.id)" v-if="!address.isDefault">
|
<view class="action-btn" @tap="handleSetDefault(address.id)" v-if="!address.isDefault">
|
||||||
<u-icon name="checkmark-circle" color="#999" size="40rpx"></u-icon>
|
<u-icon name="checkmark-circle" color="#999" size="40rpx"></u-icon>
|
||||||
<text>设为默认</text>
|
<text>设为默认</text>
|
||||||
</view>
|
</view>
|
||||||
@ -133,7 +123,7 @@ function selectAddress(address) {
|
|||||||
<u-icon name="edit-pen" color="#999" size="40rpx"></u-icon>
|
<u-icon name="edit-pen" color="#999" size="40rpx"></u-icon>
|
||||||
<text>编辑</text>
|
<text>编辑</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="action-btn" @tap="deleteAddress(address.id)">
|
<view class="action-btn" @tap="handleDeleteAddress(address.id)">
|
||||||
<u-icon name="trash" color="#999" size="40rpx"></u-icon>
|
<u-icon name="trash" color="#999" size="40rpx"></u-icon>
|
||||||
<text>删除</text>
|
<text>删除</text>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@ -1,11 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import citySelect from '@/components/u-city-select/u-city-select.vue';
|
import citySelect from '@/components/u-city-select/u-city-select.vue';
|
||||||
|
|
||||||
const height = ref(30);
|
|
||||||
const bgColor = ref(uni.$u.color.bgColor);
|
|
||||||
const marginTop = ref(30);
|
|
||||||
const marginBottom = ref(30);
|
|
||||||
const value = ref(false);
|
const value = ref(false);
|
||||||
const input = ref('');
|
const input = ref('');
|
||||||
|
|
||||||
|
|||||||
@ -126,29 +126,43 @@ const getComment = () => {
|
|||||||
.comment {
|
.comment {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 30rpx;
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
.left {
|
.left {
|
||||||
image {
|
image {
|
||||||
width: 64rpx;
|
width: 72rpx;
|
||||||
height: 64rpx;
|
height: 72rpx;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: #f2f2f2;
|
background-color: #f2f2f2;
|
||||||
|
border: 2rpx solid #eaeaea;
|
||||||
|
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.right {
|
.right {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding-left: 20rpx;
|
padding-left: 24rpx;
|
||||||
font-size: 30rpx;
|
font-size: 28rpx;
|
||||||
|
line-height: 1.6;
|
||||||
|
|
||||||
.top {
|
.top {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 10rpx;
|
margin-bottom: 12rpx;
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
color: #5677fc;
|
color: #5677fc;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 30rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.like {
|
.like {
|
||||||
@ -156,9 +170,16 @@ const getComment = () => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
color: #9a9a9a;
|
color: #9a9a9a;
|
||||||
font-size: 26rpx;
|
font-size: 26rpx;
|
||||||
|
padding: 4rpx 12rpx;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
transition: all 0.2s;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: rgba(86, 119, 252, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
.num {
|
.num {
|
||||||
margin-right: 4rpx;
|
margin-right: 8rpx;
|
||||||
color: #9a9a9a;
|
color: #9a9a9a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,20 +194,32 @@ const getComment = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
margin-bottom: 10rpx;
|
margin-bottom: 16rpx;
|
||||||
|
color: #333333;
|
||||||
|
line-height: 1.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reply-box {
|
.reply-box {
|
||||||
background-color: rgb(242, 242, 242);
|
background-color: #f7f7f7;
|
||||||
border-radius: 12rpx;
|
border-radius: 12rpx;
|
||||||
|
margin-top: 12rpx;
|
||||||
|
margin-bottom: 8rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
padding: 20rpx;
|
padding: 20rpx;
|
||||||
border-bottom: solid 2rpx $u-border-color;
|
border-bottom: solid 1rpx rgba(0, 0, 0, 0.05);
|
||||||
|
|
||||||
.username {
|
.username {
|
||||||
font-size: 24rpx;
|
font-size: 26rpx;
|
||||||
color: #999999;
|
color: #5677fc;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-bottom: 6rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333333;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,6 +228,12 @@ const getComment = () => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
color: #5677fc;
|
color: #5677fc;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
font-size: 26rpx;
|
||||||
|
transition: all 0.2s;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: rgba(86, 119, 252, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
.more {
|
.more {
|
||||||
margin-left: 6rpx;
|
margin-left: 6rpx;
|
||||||
@ -207,10 +246,18 @@ const getComment = () => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
color: #9a9a9a;
|
color: #9a9a9a;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
.reply {
|
.reply {
|
||||||
color: #5677fc;
|
color: #5677fc;
|
||||||
margin-left: 10rpx;
|
margin-left: 16rpx;
|
||||||
|
padding: 4rpx 16rpx;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
transition: all 0.2s;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: rgba(86, 119, 252, 0.1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
197
src/pages_template/pages/order/OrderItem.vue
Normal file
197
src/pages_template/pages/order/OrderItem.vue
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
<script setup>
|
||||||
|
import { defineProps } from 'vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
order: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 价格小数
|
||||||
|
const priceDecimal = (val) => {
|
||||||
|
if (val !== parseInt(val)) return val.slice(-2);
|
||||||
|
else return '00';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 价格整数
|
||||||
|
const priceInt = (val) => {
|
||||||
|
if (val !== parseInt(val)) return val.split('.')[0];
|
||||||
|
else return val;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 总价
|
||||||
|
const totalPrice = (item) => {
|
||||||
|
let price = 0;
|
||||||
|
item.forEach(val => {
|
||||||
|
price += parseFloat(val.price);
|
||||||
|
});
|
||||||
|
return price.toFixed(2);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 总件数
|
||||||
|
const totalNum = (item) => {
|
||||||
|
let num = 0;
|
||||||
|
item.forEach(val => {
|
||||||
|
num += val.number;
|
||||||
|
});
|
||||||
|
return num;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view class="order">
|
||||||
|
<view class="top">
|
||||||
|
<view class="left">
|
||||||
|
<u-icon name="home" :size="30" color="rgb(94,94,94)"></u-icon>
|
||||||
|
<view class="store">{{ order.store }}</view>
|
||||||
|
<u-icon name="arrow-right" color="rgb(203,203,203)" :size="26"></u-icon>
|
||||||
|
</view>
|
||||||
|
<view class="right">{{ order.deal }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="item" v-for="(item, index) in order.goodsList" :key="index">
|
||||||
|
<view class="left">
|
||||||
|
<image :src="item.goodsUrl" mode="aspectFill"></image>
|
||||||
|
</view>
|
||||||
|
<view class="content">
|
||||||
|
<view class="title u-line-2">{{ item.title }}</view>
|
||||||
|
<view class="type">{{ item.type }}</view>
|
||||||
|
<view class="delivery-time">发货时间 {{ item.deliveryTime }}</view>
|
||||||
|
</view>
|
||||||
|
<view class="right">
|
||||||
|
<view class="price">
|
||||||
|
¥{{ priceInt(item.price) }}
|
||||||
|
<text class="decimal">.{{ priceDecimal(item.price) }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="number">x{{ item.number }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="total">
|
||||||
|
共{{ totalNum(order.goodsList) }}件商品 合计:
|
||||||
|
<text class="total-price">
|
||||||
|
¥{{ priceInt(totalPrice(order.goodsList)) }}.
|
||||||
|
<text class="decimal">{{ priceDecimal(totalPrice(order.goodsList)) }}</text>
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
<view class="bottom">
|
||||||
|
<view class="more"><u-icon name="more-dot-fill" color="rgb(203,203,203)"></u-icon></view>
|
||||||
|
<view class="logistics btn">查看物流</view>
|
||||||
|
<view class="exchange btn">卖了换钱</view>
|
||||||
|
<view class="evaluate btn">评价</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.order {
|
||||||
|
width: 710rpx;
|
||||||
|
background-color: #ffffff;
|
||||||
|
margin: 20rpx auto;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 20rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
|
||||||
|
.top {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.store {
|
||||||
|
margin: 0 10rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
color: $u-warning-dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
margin: 20rpx 0 0;
|
||||||
|
|
||||||
|
.left {
|
||||||
|
margin-right: 20rpx;
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 200rpx;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
.title {
|
||||||
|
font-size: 28rpx;
|
||||||
|
line-height: 50rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.type {
|
||||||
|
margin: 10rpx 0;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: $u-tips-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delivery-time {
|
||||||
|
color: #e5d001;
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
margin-left: 10rpx;
|
||||||
|
padding-top: 20rpx;
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
|
.decimal {
|
||||||
|
font-size: 24rpx;
|
||||||
|
margin-top: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.number {
|
||||||
|
color: $u-tips-color;
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.total {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
text-align: right;
|
||||||
|
font-size: 24rpx;
|
||||||
|
|
||||||
|
.total-price {
|
||||||
|
font-size: 32rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom {
|
||||||
|
display: flex;
|
||||||
|
margin-top: 40rpx;
|
||||||
|
padding: 0 10rpx;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
line-height: 52rpx;
|
||||||
|
width: 160rpx;
|
||||||
|
border-radius: 26rpx;
|
||||||
|
border: 2rpx solid $u-border-color;
|
||||||
|
font-size: 26rpx;
|
||||||
|
text-align: center;
|
||||||
|
color: $u-info-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
.evaluate {
|
||||||
|
color: $u-warning-dark;
|
||||||
|
border-color: $u-warning-dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,5 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, onMounted } from 'vue';
|
import { ref, reactive, onMounted } from 'vue';
|
||||||
|
import OrderItem from './OrderItem.vue';
|
||||||
|
|
||||||
const orderList = ref([[], [], [], []]);
|
const orderList = ref([[], [], [], []]);
|
||||||
const dataList = reactive([
|
const dataList = reactive([
|
||||||
@ -119,18 +120,6 @@ onMounted(() => {
|
|||||||
getOrderList(3);
|
getOrderList(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 价格小数
|
|
||||||
const priceDecimal = (val) => {
|
|
||||||
if (val !== parseInt(val)) return val.slice(-2);
|
|
||||||
else return '00';
|
|
||||||
};
|
|
||||||
|
|
||||||
// 价格整数
|
|
||||||
const priceInt = (val) => {
|
|
||||||
if (val !== parseInt(val)) return val.split('.')[0];
|
|
||||||
else return val;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 触底懒加载
|
// 触底懒加载
|
||||||
const reachBottom = () => {
|
const reachBottom = () => {
|
||||||
loadStatus.value.splice(current.value, 1, "loading");
|
loadStatus.value.splice(current.value, 1, "loading");
|
||||||
@ -151,34 +140,21 @@ const getOrderList = (idx) => {
|
|||||||
loadStatus.value.splice(current.value, 1, "loadmore");
|
loadStatus.value.splice(current.value, 1, "loadmore");
|
||||||
};
|
};
|
||||||
|
|
||||||
// 总价
|
|
||||||
const totalPrice = (item) => {
|
|
||||||
let price = 0;
|
|
||||||
item.forEach(val => {
|
|
||||||
price += parseFloat(val.price);
|
|
||||||
});
|
|
||||||
return price.toFixed(2);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 总件数
|
|
||||||
const totalNum = (item) => {
|
|
||||||
let num = 0;
|
|
||||||
item.forEach(val => {
|
|
||||||
num += val.number;
|
|
||||||
});
|
|
||||||
return num;
|
|
||||||
};
|
|
||||||
|
|
||||||
// tab栏切换
|
// tab栏切换
|
||||||
const change = ({ index }) => {
|
const change = ({ index }) => {
|
||||||
|
current.value = index; // 更新current变量
|
||||||
swiperCurrent.value = index;
|
swiperCurrent.value = index;
|
||||||
getOrderList(index);
|
getOrderList(index);
|
||||||
};
|
};
|
||||||
|
|
||||||
const animationfinish = ({ detail: { current } }) => {
|
const animationfinish = (e) => {
|
||||||
swiperCurrent.value = current;
|
const currentIndex = e.detail.current;
|
||||||
current.value = current;
|
swiperCurrent.value = currentIndex;
|
||||||
|
current.value = currentIndex; // 将current的值正确更新为swiper的current
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 获取tabs组件的ref
|
||||||
|
const tabs = ref(null);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -193,62 +169,20 @@ const animationfinish = ({ detail: { current } }) => {
|
|||||||
<scroll-view scroll-y style="height: 100%;width: 100%;" @scrolltolower="reachBottom"
|
<scroll-view scroll-y style="height: 100%;width: 100%;" @scrolltolower="reachBottom"
|
||||||
v-if="orderlist.length !== 0">
|
v-if="orderlist.length !== 0">
|
||||||
<view class="page-box">
|
<view class="page-box">
|
||||||
<view class="order" v-for="(res, index) in orderlist" :key="res.id">
|
<OrderItem v-for="res in orderlist" :key="res.id" :order="res" />
|
||||||
<view class="top">
|
|
||||||
<view class="left">
|
|
||||||
<u-icon name="home" :size="30" color="rgb(94,94,94)"></u-icon>
|
|
||||||
<view class="store">{{ res.store }}</view>
|
|
||||||
<u-icon name="arrow-right" color="rgb(203,203,203)" :size="26"></u-icon>
|
|
||||||
</view>
|
|
||||||
<view class="right">{{ res.deal }}</view>
|
|
||||||
</view>
|
|
||||||
<view class="item" v-for="(item, index) in res.goodsList" :key="index">
|
|
||||||
<view class="left">
|
|
||||||
<image :src="item.goodsUrl" mode="aspectFill"></image>
|
|
||||||
</view>
|
|
||||||
<view class="content">
|
|
||||||
<view class="title u-line-2">{{ item.title }}</view>
|
|
||||||
<view class="type">{{ item.type }}</view>
|
|
||||||
<view class="delivery-time">发货时间 {{ item.deliveryTime }}</view>
|
|
||||||
</view>
|
|
||||||
<view class="right">
|
|
||||||
<view class="price">
|
|
||||||
¥{{ priceInt(item.price) }}
|
|
||||||
<text class="decimal">.{{ priceDecimal(item.price) }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="number">x{{ item.number }}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="total">
|
|
||||||
共{{ totalNum(res.goodsList) }}件商品 合计:
|
|
||||||
<text class="total-price">
|
|
||||||
¥{{ priceInt(totalPrice(res.goodsList)) }}.
|
|
||||||
<text class="decimal">{{ priceDecimal(totalPrice(res.goodsList)) }}</text>
|
|
||||||
</text>
|
|
||||||
</view>
|
|
||||||
<view class="bottom">
|
|
||||||
<view class="more"><u-icon name="more-dot-fill" color="rgb(203,203,203)"></u-icon>
|
|
||||||
</view>
|
|
||||||
<view class="logistics btn">查看物流</view>
|
|
||||||
<view class="exchange btn">卖了换钱</view>
|
|
||||||
<view class="evaluate btn">评价</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<u-loadmore :status="loadStatus[0]" bgColor="#f2f2f2"></u-loadmore>
|
<u-loadmore :status="loadStatus[0]" bgColor="#f2f2f2"></u-loadmore>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
<scroll-view scroll-y style="height: 100%;width: 100%;" v-else>
|
<scroll-view scroll-y style="height: 100%;width: 100%;" v-else>
|
||||||
<view class="page-box">
|
<view class="page-box">
|
||||||
<view>
|
<view class="centre">
|
||||||
<view class="centre">
|
<image src="https://cdn.uviewui.com/uview/template/taobao-order.png" mode="aspectFit" class="empty-image">
|
||||||
<image src="https://cdn.uviewui.com/uview/template/taobao-order.png" mode="">
|
</image>
|
||||||
</image>
|
<view class="explain">
|
||||||
<view class="explain">
|
您还没有相关的订单
|
||||||
您还没有相关的订单
|
<view class="tips">可以去看看有那些想买的</view>
|
||||||
<view class="tips">可以去看看有那些想买的</view>
|
|
||||||
</view>
|
|
||||||
<view class="btn">随便逛逛</view>
|
|
||||||
</view>
|
</view>
|
||||||
|
<view class="btn">随便逛逛</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
@ -268,128 +202,18 @@ page {
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.order {
|
|
||||||
width: 710rpx;
|
|
||||||
background-color: #ffffff;
|
|
||||||
margin: 20rpx auto;
|
|
||||||
border-radius: 20rpx;
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 20rpx;
|
|
||||||
font-size: 28rpx;
|
|
||||||
|
|
||||||
.top {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
.left {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.store {
|
|
||||||
margin: 0 10rpx;
|
|
||||||
font-size: 32rpx;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.right {
|
|
||||||
color: $u-warning-dark;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.item {
|
|
||||||
display: flex;
|
|
||||||
margin: 20rpx 0 0;
|
|
||||||
|
|
||||||
.left {
|
|
||||||
margin-right: 20rpx;
|
|
||||||
|
|
||||||
image {
|
|
||||||
width: 200rpx;
|
|
||||||
height: 200rpx;
|
|
||||||
border-radius: 10rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
.title {
|
|
||||||
font-size: 28rpx;
|
|
||||||
line-height: 50rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.type {
|
|
||||||
margin: 10rpx 0;
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: $u-tips-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.delivery-time {
|
|
||||||
color: #e5d001;
|
|
||||||
font-size: 24rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.right {
|
|
||||||
margin-left: 10rpx;
|
|
||||||
padding-top: 20rpx;
|
|
||||||
text-align: right;
|
|
||||||
|
|
||||||
.decimal {
|
|
||||||
font-size: 24rpx;
|
|
||||||
margin-top: 4rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.number {
|
|
||||||
color: $u-tips-color;
|
|
||||||
font-size: 24rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.total {
|
|
||||||
margin-top: 20rpx;
|
|
||||||
text-align: right;
|
|
||||||
font-size: 24rpx;
|
|
||||||
|
|
||||||
.total-price {
|
|
||||||
font-size: 32rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom {
|
|
||||||
display: flex;
|
|
||||||
margin-top: 40rpx;
|
|
||||||
padding: 0 10rpx;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
line-height: 52rpx;
|
|
||||||
width: 160rpx;
|
|
||||||
border-radius: 26rpx;
|
|
||||||
border: 2rpx solid $u-border-color;
|
|
||||||
font-size: 26rpx;
|
|
||||||
text-align: center;
|
|
||||||
color: $u-info-dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
.evaluate {
|
|
||||||
color: $u-warning-dark;
|
|
||||||
border-color: $u-warning-dark;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.centre {
|
.centre {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 200rpx auto;
|
margin: 200rpx auto;
|
||||||
font-size: 32rpx;
|
font-size: 32rpx;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
image {
|
.empty-image {
|
||||||
width: 164rpx;
|
width: 164rpx;
|
||||||
height: 164rpx;
|
height: 164rpx;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
margin-bottom: 20rpx;
|
margin: 0 auto 20rpx;
|
||||||
|
display: block; /* 确保图片作为块级元素 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.tips {
|
.tips {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user