jcloud/dashboard/src2/components/billing/NewAddressForm.vue
2025-04-12 17:39:38 +08:00

214 lines
5.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<div class="flex flex-col gap-5">
<div
v-for="section in sections"
:key="section.name"
class="grid gap-4"
:class="'grid-cols-' + section.columns"
>
<div v-for="field in section.fields" :key="field.name">
<FormControl
v-model="billingInformation[field.fieldname]"
:label="field.label || field.fieldname"
:type="getInputType(field)"
:name="field.fieldname"
:options="field.options"
:disabled="props.disableForm"
:required="field.required"
/>
</div>
</div>
</div>
<ErrorMessage class="mt-2" :message="updateBillingInformation.error" />
</div>
</template>
<script setup>
import { FormControl, ErrorMessage, createResource } from 'jingrow-ui';
import { ref, computed, inject, watch, onMounted } from 'vue';
import { toast } from 'vue-sonner';
import { DashboardError } from '../../utils/error';
import { countryNameMap, chinaStates } from '@/utils/billing';
const emit = defineEmits(['success']);
const team = inject('team');
const billingInformation = defineModel();
const props = defineProps({
disableForm: { type: Boolean, default: false },
});
// 获取团队当前国家信息
const getBillingInformation = createResource({
url: 'jcloud.api.account.get_billing_information',
onSuccess(data) {
console.log("获取到的账单信息:", data);
if (data.country) {
// 设置当前国家,确保使用后端的准确值
billingInformation.value.country = data.country;
} else {
// 只有没有国家信息时才设置默认值
billingInformation.value.country = 'China';
}
}
});
const updateBillingInformation = createResource({
url: 'jcloud.api.account.update_billing_information',
makeParams: () => {
const billingData = { ...billingInformation.value };
// 确保国家名称正确,如果用户选择了'cn'代码,需要转换为'China'
if (billingData.country === 'cn') {
billingData.country = 'China';
}
return { billing_details: billingData };
},
validate: async () => {
let error = await validate();
if (error) throw new DashboardError(error);
},
onSuccess: () => {
toast.success('账单信息已更新');
emit('success');
},
});
// 组件挂载时获取当前账单信息
onMounted(() => {
// 获取当前账单信息,包括国家
getBillingInformation.submit();
});
// 反向映射:从代码到名称
const codeToNameMap = computed(() => {
const map = {};
Object.entries(countryNameMap).forEach(([code, name]) => {
map[code] = name;
});
return map;
});
// 国家选择列表 - 包含英文代码映射到中文显示
const countryList = computed(() => {
// 由于后端限制,目前只提供中国选项
return [{ label: '中国', value: 'China' }];
// 如果未来允许其他国家,可以恢复这个:
// return Object.entries({
// 'China': '中国',
// 'United States': '美国',
// // 其他国家...
// }).map(([code, name]) => ({
// label: name,
// value: code
// }));
});
const stateOptions = computed(() => {
return chinaStates.map((state) => ({
label: state,
value: state,
}));
});
const sections = computed(() => {
return [
{
name: '国家和城市',
columns: 2,
fields: [
{
fieldtype: 'Select',
label: '国家',
fieldname: 'country',
options: countryList.value,
required: true,
disabled: true, // 禁用国家选择
},
{
fieldtype: 'Data',
label: '城市',
fieldname: 'city',
required: true,
},
],
},
{
name: '地址',
columns: 1,
fields: [
{
fieldtype: 'Data',
label: '地址',
fieldname: 'address',
required: true,
},
],
},
{
name: '州和邮政编码',
columns: 2,
fields: [
{
fieldtype:
billingInformation.value.country === 'China' ? 'Select' : 'Data',
label: '州/省/地区',
fieldname: 'state',
required: true,
options:
billingInformation.value.country === 'China'
? stateOptions.value
: null,
},
{
fieldtype: 'Data',
label: '邮政编码',
fieldname: 'postal_code',
required: true,
},
],
},
];
});
function getInputType(field) {
return {
Data: 'text',
Int: 'number',
Select: 'select',
Check: 'checkbox',
Password: 'password',
Text: 'textarea',
Date: 'date',
}[field.fieldtype || 'Data'];
}
async function validate() {
// 验证必填字段
for (let field of sections.value.flatMap((s) => s.fields)) {
if (field.required && !billingInformation.value[field.fieldname]) {
return `${field.label} 是必填项`;
}
}
return null; // 返回null表示没有错误
}
// 组件加载时设置默认国家
watch(() => team.pg?.country, (country) => {
if (country) {
const countryOption = countryList.value.find(
(c) => c.label === country || c.value === country
);
if (countryOption) {
billingInformation.value.country = countryOption.value;
}
} else {
// 如果team.pg中没有country默认设置为中国
billingInformation.value.country = 'China';
}
}, { immediate: true });
defineExpose({ updateBillingInformation, validate });
</script>