123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- <template>
- <a-modal
- :visible="visible"
- :title="editMode ? $t('customer.editCustomer') : $t('customer.addCustomer')"
- :loading="loading"
- @ok="handleSubmit"
- @cancel="handleCancel"
- :width="720"
- :okText="$t('customer.confirm')"
- >
- <a-tabs>
- <!-- 基本信息 Tab -->
- <a-tab-pane key="1" :title="$t('customer.basicInfo')">
- <a-form :model="formData" :rules="rules" ref="formRef" :label-col-props="{ span: 6 }"
- :wrapper-col-props="{ span: 18 }">
- <a-divider>{{ $t('customer.basicInfoSection') }}</a-divider>
- <!-- Customer Code -->
- <a-form-item field="zip" :label="$t('customer.customerCode')" required validate-trigger="blur">
- <a-input v-model="formData.zip" :placeholder="$t('customer.enterCustomerCode')" :max-length="60"
- show-word-limit/>
- </a-form-item>
- <a-form-item field="email" :label="$t('customer.emailName')" required validate-trigger="blur">
- <a-input v-model="formData.email" :placeholder="$t('customer.emailType')" :max-length="60"
- show-word-limit/>
- </a-form-item>
- <a-form-item field="phone" :label="$t('customer.phoneName')" required validate-trigger="blur">
- <a-input v-model="formData.phone" :placeholder="$t('customer.phoneType')" show-word-limit/>
- </a-form-item>
- <!-- Customer Name -->
- <a-form-item field="name" :label="$t('customer.customerName')" required validate-trigger="blur">
- <a-input v-model="formData.name" :placeholder="$t('customer.enterCustomerName')" :max-length="60"
- show-word-limit/>
- </a-form-item>
- <!-- Account Number -->
- <a-form-item field="username" :label="$t('customer.accountNumber')" required validate-trigger="blur">
- <a-input v-model="formData.username" :placeholder="$t('customer.enterAccountNumber')" :max-length="60"
- show-word-limit/>
- </a-form-item>
- <!-- Password -->
- <a-form-item field="password" :label="$t('customer.password')" required validate-trigger="blur">
- <a-input-password v-model="formData.password" :placeholder="$t('customer.enterPassword')" :max-length="60"
- show-word-limit/>
- <a-button type="primary" @click="generatePassword">{{ $t('customer.generatePassword') }}</a-button>
- </a-form-item>
- <!-- role-->
- <a-form-item field="roleIds" :label="$t('customer.roleldsName')" required validate-trigger="blur">
- <a-select multiple v-model="formData.roleIds" :style="{width:'100%'}"
- :placeholder="$t('customer.roleldsNamedType')">
- <a-option v-for="item of roles" :value="item.id" :label="item.name"/>
- </a-select>
- </a-form-item>
- <a-form-item field="userType" :label="$t('customer.userTypeName')" required validate-trigger="blur">
- <a-select v-model="formData.userType" :style="{width:'100%'}"
- :placeholder="$t('customer.userTypeNameType')">
- <a-option v-for="item of userTypeList" :value="item.value" :label="item.label"/>
- </a-select>
- </a-form-item>
- <!-- Remark -->
- <a-form-item field="note" :label="$t('customer.remark')" required validate-trigger="blur">
- <a-input v-model="formData.note" :placeholder="$t('customer.enterRemark')" :max-length="60"
- show-word-limit/>
- </a-form-item>
- <!-- Account Balance -->
- <a-form-item field="amount" :label="$t('customer.accountBalance')" required validate-trigger="blur">
- <a-input-number v-model="formData.amount" :min="0" :precision="2" :step="100"
- :suffix="$t('customer.currency')"/>
- </a-form-item>
- <!-- Address -->
- <a-form-item field="addr" :label="$t('customer.address')" required validate-trigger="blur">
- <a-input v-model="formData.addr" :placeholder="$t('customer.addressMessage')" :max-length="50"
- show-word-limit/>
- </a-form-item>
- <!-- Status -->
- <a-form-item field="state" :label="$t('customer.statusName')" required validate-trigger="blur">
- <a-radio-group v-model="formData.state">
- <a-radio value="1">{{ $t('customer.status.normal') }}</a-radio>
- <a-radio value="2">{{ $t('customer.status.disabled') }}</a-radio>
- <a-radio value="3">{{ $t('customer.status.pending') }}</a-radio>
- <a-radio value="4">{{ $t('customer.status.suspended') }}</a-radio>
- </a-radio-group>
- </a-form-item>
- </a-form>
- </a-tab-pane>
- <!-- SMS 信息 Tab -->
- <a-tab-pane key="2" :title="$t('customer.smsInfoSection')">
- <a-form :model="formData" :rules="rules" ref="formRef" :label-col-props="{ span: 6 }"
- :wrapper-col-props="{ span: 18 }">
- <a-divider>{{ $t('customer.smsInfoSection') }}</a-divider>
- <a-form-item field="sms" :label="$t('customer.smsSubCode')" required validate-trigger="blur">
- <a-input v-model="formData.sms" :placeholder="$t('customer.enterSmsSubCode')" :max-length="60"
- show-word-limit/>
- </a-form-item>
- <a-form-item field="smsSignature" :label="$t('customer.smsName')" required validate-trigger="blur">
- <a-input v-model="formData.smsSignature" :placeholder="$t('customer.enterSmsName')" :max-length="60"
- show-word-limit/>
- </a-form-item>
- <a-form-item field="loginSms" :label="$t('customer.loginSmsTemplate')" required validate-trigger="blur">
- <a-input v-model="formData.loginSms" :placeholder="$t('customer.enterLoginSmsTemplate')" :max-length="60"
- show-word-limit/>
- </a-form-item>
- <a-form-item field="warnSms" :label="$t('customer.alarmSmsTemplate')" required validate-trigger="blur">
- <a-input v-model="formData.warnSms" :placeholder="$t('customer.enterAlarmSmsTemplate')" :max-length="60"
- show-word-limit/>
- </a-form-item>
- </a-form>
- </a-tab-pane>
- <!-- Billing Information Tab -->
- <a-tab-pane key="3" :title="$t('customer.billingInfo')">
- <a-form :model="formData" :rules="rules" ref="formRef" :label-col-props="{ span: 6 }"
- :wrapper-col-props="{ span: 18 }">
- <a-divider>{{ $t('customer.InvoiceInformation') }}</a-divider>
- <a-form-item field="invoiceTitle" :label="$t('customer.invoiceTitle')" required validate-trigger="blur">
- <a-input v-model="formData.invoiceTitle" :placeholder="$t('customer.enterInvoiceTitle')" :max-length="60"
- show-word-limit/>
- </a-form-item>
- <a-form-item field="invoice_type" :label="$t('customer.invoice_vatTextType')" required
- validate-trigger="blur">
- <a-select v-model="formData.invoiceType" :style="{width:'100%'}"
- :placeholder="$t('customer.invoice_vatTextTypeSelect')">
- <a-option v-for="item of invoiceList" :value="item.value" :label="item.label"/>
- </a-select>
- </a-form-item>
- <a-form-item field="invoiceAddr" :label="$t('customer.registeredAddress')" required validate-trigger="blur">
- <a-input v-model="formData.invoiceAddr" :placeholder="$t('customer.enterRegisteredAddress')"
- :max-length="60" show-word-limit/>
- </a-form-item>
- <a-form-item field="invoiceZip" :label="$t('customer.invoiceCode')" required validate-trigger="blur">
- <a-input v-model="formData.invoiceZip" :placeholder="$t('customer.InvoiceCodeName')" :max-length="60"
- show-word-limit/>
- </a-form-item>
- <a-form-item field="invoiceEmail" :label="$t('customer.invoiceEmailName')" required validate-trigger="blur">
- <a-input v-model="formData.invoiceEmail" :placeholder="$t('customer.invoiceEmailNameType')"
- :max-length="60" show-word-limit/>
- </a-form-item>
- <a-form-item field="bankName" :label="$t('customer.bankName')" required validate-trigger="blur">
- <a-input v-model="formData.bankName" :placeholder="$t('customer.enterBankName')" :max-length="60"
- show-word-limit/>
- </a-form-item>
- <a-form-item field="bankAccount" :label="$t('customer.BankNumber')" required validate-trigger="blur">
- <a-input v-model="formData.bankAccount" :placeholder="$t('customer.BankNumberName')" :max-length="60"
- show-word-limit/>
- </a-form-item>
- <a-form-item field="bankBranch" :label="$t('customer.bank_branchName')" required validate-trigger="blur">
- <a-input v-model="formData.bankBranch" :placeholder="$t('customer.bank_branchNameType')" show-word-limit/>
- </a-form-item>
- <a-form-item field="businessLicense" :label="$t('customer.BusinessLicense')" required
- validate-trigger="blur">
- <upload v-model="formData.businessLicense"/>
- </a-form-item>
- </a-form>
- </a-tab-pane>
- <!-- Tax Registration Tab -->
- <a-tab-pane key="4" :title="$t('customer.TaxRegistration')">
- <a-form :model="formData" :rules="rules" ref="formRef" :label-col-props="{ span: 8 }"
- :wrapper-col-props="{ span: 16 }">
- <a-divider>{{ $t('customer.TaxRegistrationText') }}</a-divider>
- <a-form-item field="taxRegistrationCertificate" :label="$t('customer.photocopy')" required
- validate-trigger="blur">
- <upload v-model:modelValue="formData.taxRegistrationCertificate"/>
- </a-form-item>
- <a-form-item field="taxpayerQualification" :label="$t('customer.CertificationQualification')" required
- validate-trigger="blur">
- <upload v-model:modelValue="formData.taxpayerQualification"/>
- </a-form-item>
- </a-form>
- </a-tab-pane>
- </a-tabs>
- </a-modal>
- </template>
- <script setup>
- import {ref, watch, onMounted} from 'vue';
- import {Message} from '@arco-design/web-vue';
- import {useI18n} from 'vue-i18n';
- import {useSystemStore} from '@/store/modules/systemStore'
- import {dictionaryDetail} from '@/api/path/dict.js'
- import Upload from "@/components/upload/index.vue";
- import {systemFindRoleList} from "@/api/path/system.api";
- import {addCustomer, updateCustomer} from "@/api/customer.js";
- const {t} = useI18n();
- const systemStore = useSystemStore()
- import { encryptByDES } from '@/utils/crypto'
- const props = defineProps({
- visible: Boolean,
- editMode: Boolean,
- editData: Object,
- loading: Boolean,
- });
- const invoiceList = ref([])
- const roles = ref([])
- const userTypeList = ref([])
- watch(
- () => props.editData,
- (newVal) => {
- if (newVal && props.editMode) {
- // 深拷贝编辑数据
- const editDataCopy = JSON.parse(JSON.stringify(newVal));
- // 将 formData 中嵌套的 info 展平为一层
- const flattenedFormData = ref(Object.fromEntries(Object.entries(editDataCopy).flatMap(([key, value]) => typeof value === 'object' && value !== null && !Array.isArray(value) ? Object.entries(value) : [[key, value]])));
- if(editDataCopy.info) {
- delete editDataCopy.info;
- }
- const formDataList = {...editDataCopy,...flattenedFormData.value}
- console.log(formDataList)
- formData.value = formDataList
- // Object.keys(formData.value).forEach(key => {
- // if (formDataList[key]) {
- // formData.value[key] = formDataList[key];
- // }
- // });
- }
- },
- {deep: true, immediate: true}
- );
- const emit = defineEmits(['update:visible', 'submit']);
- const formRef = ref(null);
- const formData = ref({
- username: "",
- state: "",
- name: "",
- password: "",
- roleIds: [],
- userType: '',
- phone: "",
- email: "",
- addr: "",
- zip: "",
- note: "",
- sms: "",
- smsSignature: "",
- loginSms: "",
- warnSms: "",
- amount: "",
- invoiceTitle: "",
- invoiceType: "",
- invoiceAddr: "",
- invoiceZip: "",
- invoiceEmail: "",
- bankName: "",
- bankAccount: "",
- bankBranch: "",
- businessLicense: "",
- taxRegistrationCertificate: "",
- taxpayerQualification: ""
- });
- const rules = {
- userName: [{required: true, message: t('customer.enterAccountNumber')}],
- state: [{required: true, message: t('customer.stateType')}],
- name: [{required: true, message: t('customer.nameType')}],
- password: [{required: true, message: t('customer.passwordRequired')}],
- roleIds: [{required: true, message: t('customer.roleIdsType')}],
- userType: [{required: true, message: t('customer.userTypeType')}],
- phone: [{required: true, message: t('customer.phoneType')}],
- email: [{required: true, message: t('customer.emailType')}],
- addr: [{required: true, message: t('customer.addressRequired')}],
- amount: [{required: true, message: t('customer.amountRequired')}],
- bankAccount: [{required: true, message: t('customer.bankAccountRequired')}],
- bankBranch: [{required: true, message: t('customer.bankBranchRequired')}],
- bankName: [{required: true, message: t('customer.bankNameRequired')}],
- businessLicense: [{required: true, message: t('customer.businessLicenseRequired')}],
- invoiceAddr: [{required: true, message: t('customer.invoiceAddressRequired')}],
- invoiceEmail: [{required: true, message: t('customer.invoiceEmailRequired')}],
- invoiceTitle: [{required: true, message: t('customer.invoiceTitleRequired')}],
- invoiceType: [{required: true, message: t('customer.invoiceTypeRequired')}],
- invoiceZip: [{required: true, message: t('customer.invoiceZipRequired')}],
- loginSms: [{required: true, message: t('customer.loginSMSTemplateRequired')}],
- note: [{required: true, message: t('customer.noteRequired')}],
- sms: [{required: true, message: t('customer.smsRequired')}],
- smsSignature: [{required: true, message: t('customer.smsSignatureRequired')}],
- warnSms: [{required: true, message: t('customer.warnSMSTemplateRequired')}],
- zip: [{required: true, message: t('customer.zipCodeRequired')}],
- taxRegistrationCertificate: [{required: true, message: t('customer.taxRegistrationCertificateRequired')}],
- taxpayerQualification: [{required: true, message: t('customer.taxpayerQualificationRequired')}]
- };
- const handleSubmit = () => {
- formRef.value.validate(async (errors) => {
- if (!errors) {
- let response;
- formData.value.password = encryptByDES(formData.value.password);
- if (props.editMode) {
- response = await updateCustomer(formData.value);
- } else {
- response = await addCustomer(formData.value);
- }
- if (response.code === 200) {
- Message.success(props.editMode ? t('customer.updateSuccess') : t('customer.addSuccess'));
- Object.keys(formData.value).forEach(key => {
- formData.value[key] = ''
- })
- emit('submit', true);
- emit('update:visible', false);
- } else {
- Message.error(response.message || (props.editMode ? t('customer.updateFailed') : t('customer.addFailed')));
- }
- }
- });
- };
- const handleCancel = () => {
- Object.keys(formData.value).forEach(key => {
- formData.value[key] = ''
- })
- formRef.value = null
- emit('update:visible', false);
- };
- const generatePassword = () => {
- formData.password = Math.random().toString(36).slice(-8);
- Message.success(t('customer.passwordGenerated'));
- };
- const getDistList = async () => {
- let code = ['invoice_vat', 'user_type'];
- for (let i = 0; i < code.length; i++) {
- let res = await dictionaryDetail({ typeKey: code[i] });
- if (res.code === 200) {
- if (code[i] === 'invoice_vat') {
- invoiceList.value = res.data;
- } else if (code[i] === 'user_type') {
- userTypeList.value = res.data;
- }
- }
- }
- }
- const getRolesData = async () => {
- let res = await systemFindRoleList()
- if (res.code === 200) {
- roles.value = res.data
- }
- }
- onMounted(() => {
- getDistList();
- getRolesData()
- })
- </script>
- <style scoped>
- .upload-description {
- font-size: 12px;
- color: #999;
- margin-top: 4px;
- }
- </style>
|