2025-12-28 00:20:10 +08:00

175 lines
3.6 KiB
Vue

<template>
<div>
<Form
class="mt-4"
:fields="fields"
:modelValue="address"
@update:modelValue="$emit('update:address', $event)"
/>
<div class="mt-4" v-show="address.country == 'china'">
<FormControl
label="我有GSTIN"
type="checkbox"
v-model="gstApplicable"
/>
<FormControl
class="mt-2"
label="GSTIN"
v-if="gstApplicable"
type="text"
v-model="address.gstin"
:disabled="!gstApplicable"
/>
</div>
</div>
</template>
<script>
import Form from '@/components/Form.vue';
import { chinaStates } from '@/utils/billing.js';
import { DashboardError } from '../utils/error';
export default {
name: 'AddressForm',
props: ['address'],
emits: ['update:address'],
components: {
Form
},
data() {
return {
gstApplicable: false
};
},
mounted() {
if (this.address?.gstin && this.address.gstin !== 'Not Applicable') {
this.gstApplicable = true;
} else {
this.update('gstin', 'Not Applicable');
}
},
watch: {
'address.gstin'(gstin) {
this.update('gstin', gstin);
},
gstApplicable(gstApplicable) {
if (gstApplicable) {
this.update(
'gstin',
this.address.gstin === 'Not Applicable' ? '' : this.address.gstin
);
} else {
this.update('gstin', 'Not Applicable');
}
}
},
resources: {
countryList: {
url: 'jcloud.api.account.country_list',
auto: true,
onSuccess() {
let userCountry = this.$team?.pg.country;
if (userCountry) {
let country = this.countryList.find(d => d.label === userCountry);
if (country) {
this.update('country', country.value);
}
}
}
},
validateGST() {
return {
url: 'jcloud.api.billing.validate_gst',
makeParams() {
return {
address: this.address
};
}
};
}
},
methods: {
update(key, value) {
this.$emit('update:address', {
...this.address,
[key]: value
});
},
async validateGST() {
this.update(
'gstin',
this.gstApplicable ? this.address.gstin : 'Not Applicable'
);
await this.$resources.validateGST.submit();
},
async validateValues() {
let { country } = this.address;
let is_china = country == 'china';
let values = this.fields
.flat()
.filter(df => df.fieldname != 'gstin' || is_china)
.map(df => this.address[df.fieldname]);
if (!values.every(Boolean)) {
throw new DashboardError('请填写必填项');
}
try {
await this.validateGST();
} catch (error) {
throw new DashboardError(error.messages?.join('\n'));
}
}
},
computed: {
countryList() {
return (this.$resources.countryList.data || []).map(d => ({
label: d.name,
value: d.name
}));
},
chinaStates() {
return chinaStates.map(d => ({
label: d,
value: d
}));
},
fields() {
return [
{
fieldtype: 'Select',
label: '国家',
fieldname: 'country',
options: this.countryList,
required: 1
},
{
fieldtype: 'Data',
label: '地址',
fieldname: 'address',
required: 1
},
{
fieldtype: 'Data',
label: '城市',
fieldname: 'city',
required: 1
},
{
fieldtype: this.address.country === 'china' ? 'Select' : 'Data',
label: '州/省/地区',
fieldname: 'state',
required: 1,
options: this.address.country === 'china' ? this.chinaStates : null
},
{
fieldtype: 'Data',
label: '邮政编码',
fieldname: 'postal_code',
required: 1
}
];
}
}
};
</script>