| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- <template>
- <cl-page>
- <view class="p-3">
- <view class="p-4 bg-white rounded-2xl dark:!bg-surface-800 mb-3">
- <cl-form ref="formRef" v-model="formData" :rules="rules" :disabled="saving">
- <cl-form-item :label="t('收货人')" prop="contact" required>
- <cl-input
- v-model="formData.contact"
- :placeholder="t('请输入收货人姓名')"
- ></cl-input>
- </cl-form-item>
- <cl-form-item :label="t('手机号')" prop="phone" required>
- <cl-input
- v-model="formData.phone"
- :placeholder="t('请输入手机号')"
- :maxlength="11"
- ></cl-input>
- </cl-form-item>
- <cl-form-item :label="t('地区')" prop="province" required>
- <cl-cascader
- v-model="regions"
- :placeholder="t('选择省市区')"
- :options="pcaOptions"
- @change="onRegionsChange"
- ></cl-cascader>
- </cl-form-item>
- <cl-form-item :label="t('详细地址')" prop="address" required>
- <cl-input
- v-model="formData.address"
- :placeholder="t('小区楼栋、门牌号、村等')"
- ></cl-input>
- </cl-form-item>
- </cl-form>
- </view>
- <cl-list>
- <cl-list-item :label="t('默认地址')">
- <cl-switch v-model="formData.isDefault"></cl-switch>
- </cl-list-item>
- </cl-list>
- </view>
- <cl-footer>
- <cl-button @tap="save()">{{ t("保存") }}</cl-button>
- </cl-footer>
- </cl-page>
- </template>
- <script lang="ts" setup>
- import { router, isEmpty, type Response, request, parse } from "@/cool";
- import { t } from "@/locale";
- import { useCascader, useForm, useUi, type ClFormRule } from "@/uni_modules/cool-ui";
- import { type Ref, ref } from "vue";
- import pca from "@/data/pca.json";
- import type { UserAddress } from "../types";
- const props = defineProps({
- id: {
- type: String,
- default: ""
- }
- });
- const ui = useUi();
- const { formRef, validate } = useForm();
- // 省市区级联选项数据
- const pcaOptions = useCascader(pca);
- // 地区选择的值,格式为 [省, 市, 区]
- const regions = ref<string[]>([]);
- // 表单数据,包含收货人、手机号、地区、详细地址、是否默认等字段
- const formData = ref<UserAddress>({
- contact: "",
- phone: "",
- province: "",
- city: "",
- district: "",
- address: "",
- isDefault: false
- }) as Ref<UserAddress>;
- // 表单验证规则,校验收货人、手机号、详细地址、地区等必填项
- const rules = new Map<string, ClFormRule[]>([
- ["contact", [{ required: true, message: t("收货人不能为空") }]],
- [
- "phone",
- [
- { required: true, message: t("手机号不能为空") },
- { pattern: /^1[3-9]\d{9}$/, message: t("手机号格式不正确") }
- ]
- ],
- ["address", [{ required: true, message: t("详细地址不能为空") }]],
- ["province", [{ required: true, message: t("所在地区不能为空") }]]
- ]);
- // 保存按钮loading状态
- const saving = ref(false);
- /**
- * 保存地址信息
- * 1. 校验表单
- * 2. 组装数据
- * 3. 请求后端接口,新增或更新地址
- */
- function save() {
- validate(async (valid, errors) => {
- if (valid) {
- ui.showLoading(t("保存中"));
- // 解构地区信息
- const [province, city, district] = regions.value;
- saving.value = true;
- // 合并表单数据和地区信息
- const data = {
- ...formData.value,
- province,
- city,
- district
- };
- // 根据是否有id判断是新增还是编辑
- request({
- url: `/app/user/address/${props.id != "" ? "update" : "add"}`,
- method: "POST",
- data
- })
- .then(() => {
- // 保存成功返回上一页
- router.back();
- })
- .catch((err) => {
- // 保存失败提示错误信息
- ui.showToast({ message: (err as Response).message! });
- })
- .finally(() => {
- ui.hideLoading();
- saving.value = false;
- });
- } else {
- // 校验失败提示第一个错误
- ui.showToast({ message: errors[0].message });
- }
- });
- }
- /**
- * 获取地址详情(编辑时调用)
- * 1. 请求后端接口获取地址详情
- * 2. 回填表单和地区选择
- */
- function getInfo() {
- request({
- url: "/app/user/address/info",
- data: { id: props.id }
- })
- .then((res) => {
- if (res != null) {
- // 解析并赋值表单数据
- formData.value = parse<UserAddress>(res)!;
- // 回填地区选择
- regions.value = [
- formData.value.province,
- formData.value.city,
- formData.value.district
- ];
- }
- })
- .catch((err) => {
- ui.showToast({ message: (err as Response).message! });
- });
- }
- /**
- * 地区选择变化时触发
- * @param value 选中的地区数组 [省, 市, 区]
- */
- function onRegionsChange(value: string[]) {
- const [province, city, district] = isEmpty(value) ? ["", "", ""] : value;
- formData.value.province = province;
- formData.value.city = city;
- formData.value.district = district;
- }
- onReady(() => {
- if (props.id != "") {
- getInfo();
- }
- });
- </script>
|