| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541 |
- <template>
- <div class="tab-content">
- <div class="info-section">
- <div class="section-title-row">
- <div class="section-title-left">
- <span class="section-title-text">企业基本信息</span>
- <span class="section-title-divider">/</span>
- <span class="supplier-no">供应商编码:{{ detailData.supplierNo }}</span>
- <el-tag
- v-if="detailData?.supplyStatus !== undefined && detailData?.supplyStatus !== null"
- :type="getStatusConfig(detailData.supplyStatus).type"
- effect="light"
- style="margin-left: 8px;"
- >
- {{ getStatusConfig(detailData.supplyStatus).text }}
- </el-tag>
- </div>
- <div v-if="!isViewMode" class="section-title-actions">
- <el-button type="primary" :icon="isEditing ? 'Document' : 'Edit'" @click="onPrimaryAction">
- {{ isEditing ? '保存' : '编辑' }}
- </el-button>
- <el-button v-if="isEditing" @click="onCancelEdit">取消</el-button>
- </div>
- </div>
- <el-form :model="detailData" label-width="120px" class="detail-form">
- <el-row :gutter="12" class="form-row">
- <el-col :span="8">
- <el-form-item label="所属公司:" required>
- <el-select v-model="detailData.ownedCompany" placeholder="请选择" clearable filterable style="width: 100%;" :disabled="!isAddMode || !isEditing">
- <el-option v-for="company in companyOptions" :key="company.id" :label="company.companyName" :value="company.id" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="企业名称:" required>
- <el-input v-model="detailData.enterpriseName" placeholder="请输入企业名称" :disabled="!isAddMode || !isEditing" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="工商名称:" required>
- <el-input
- v-model="detailData.businessName"
- placeholder="请输入工商名称"
- :disabled="!isEditing"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="12" class="form-row">
- <el-col :span="8">
- <el-form-item label="企业简称:" required>
- <el-input v-model="detailData.shortName" placeholder="请输入企业简称" :disabled="!isEditing" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="供应商等级:" required>
- <el-select v-model="detailData.cooperateLevel" placeholder="请选择" clearable filterable style="width: 100%;" :disabled="!isAddMode || !isEditing">
- <el-option v-for="level in supplierLevelOptions" :key="level.id" :label="level.supplierLevelName" :value="String(level.id)" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="企业规模:" required>
- <el-select v-model="detailData.membershipSize" placeholder="请选择" clearable filterable style="width: 100%;" :disabled="!isEditing">
- <el-option v-for="scale in enterpriseScaleOptions" :key="scale.id" :label="scale.enterpriseScaleName" :value="scale.id" />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="12" class="form-row">
- <el-col :span="8">
- <el-form-item label="行业类别:" required>
- <el-select v-model="detailData.industrCategory" placeholder="请选择" clearable filterable style="width: 100%;" :disabled="!isAddMode || !isEditing">
- <el-option v-for="industry in industryCategoryOptions" :key="industry.id" :label="industry.industryCategoryName" :value="industry.id" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="供应商类型:" required>
- <el-select v-model="detailData.supplierType" placeholder="请选择" clearable filterable style="width: 100%;" :disabled="!isAddMode || !isEditing">
- <el-option v-for="type in supplierTypeOptions" :key="type.id" :label="type.supplierTypeName" :value="type.id" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="固定电话:">
- <el-input
- v-model="detailData.fixedPhone"
- placeholder="请输入固定电话"
- type="tel"
- @input="onFixedPhoneInput"
- :disabled="!isEditing"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="12" class="form-row">
- <el-col :span="8">
- <el-form-item label="传真:">
- <el-input v-model="detailData.fax" placeholder="请输入传真" :disabled="!isEditing" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="企业邮箱:">
- <el-input v-model="detailData.mailbox" placeholder="请输入企业邮箱" :disabled="!isEditing" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="开始时间:">
- <el-date-picker v-model="detailData.validityFromDate" type="date" placeholder="请选择" style="width: 100%;" :disabled="!isAddMode || !isEditing" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="12" class="form-row">
- <el-col :span="8">
- <el-form-item label="结束时间:">
- <el-date-picker v-model="detailData.validityToDate" type="date" placeholder="请选择" style="width: 100%;" :disabled="!isAddMode || !isEditing" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="邮政编码:">
- <el-input v-model="detailData.postCode" placeholder="请输入邮政编码" :disabled="!isEditing" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="网址:">
- <el-input v-model="detailData.url" placeholder="请输入网址" :disabled="!isEditing" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="12" class="form-row">
- <el-col :span="8">
- <el-form-item label="详细地址:" required>
- <el-cascader v-model="selectedOfficeRegionProxy" :options="regionOptions" placeholder="请选择省市区" clearable filterable style="width: 100%;" @change="onOfficeRegionChange" :disabled="!isEditing" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label=" " label-width="0">
- <el-input v-model="detailData.officeAddress" placeholder="请输入详细地址" :disabled="!isEditing" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="12" class="form-row">
- <el-col :span="8">
- <el-form-item label="营业执照:">
- <ImageUpload
- v-model="detailData.businessLicense"
- :limit="1"
- :disabled="isViewMode || !isEditing"
- :file-size="5"
- :file-type="['png', 'jpg', 'jpeg']"
- :is-show-tip="false"
- />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="法人身份证照片:">
- <ImageUpload
- v-model="detailData.personImage"
- :limit="1"
- :disabled="isViewMode || !isEditing"
- :file-size="5"
- :file-type="['png', 'jpg', 'jpeg']"
- :is-show-tip="false"
- />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- </div>
- <div class="info-section">
- <div class="section-title">工商信息</div>
- <el-row :gutter="12" class="form-row">
- <el-col :span="8">
- <div class="form-item">
- <span class="label">企业工商名称:</span>
- <span class="value">{{ businessInfo?.businessName || detailData.businessName || '' }}</span>
- </div>
- </el-col>
- <el-col :span="8">
- <div class="form-item">
- <span class="label">登记机关:</span>
- <span class="value">{{ businessInfo?.registrationAuthority || '' }}</span>
- </div>
- </el-col>
- <el-col :span="8">
- <div class="form-item">
- <span class="label">成立日期:</span>
- <span class="value">{{ formatDate(businessInfo?.establishmentDate) || '' }}</span>
- </div>
- </el-col>
- </el-row>
- <el-row :gutter="12" class="form-row">
- <el-col :span="8">
- <div class="form-item">
- <span class="label">登记状态:</span>
- <span class="value">{{ businessInfo?.registrationStatus || '' }}</span>
- </div>
- </el-col>
- <el-col :span="8">
- <div class="form-item">
- <span class="label">实缴资本:</span>
- <span class="value">{{ businessInfo?.paidInCapital || '' }}</span>
- </div>
- </el-col>
- <el-col :span="8">
- <div class="form-item">
- <span class="label">社会信用代码:</span>
- <span class="value">{{ businessInfo?.socialCreditCode || detailData.socialCreditCode || '' }}</span>
- </div>
- </el-col>
- </el-row>
- <el-row :gutter="12" class="form-row">
- <el-col :span="8">
- <div class="form-item">
- <span class="label">法人姓名:</span>
- <span class="value">{{ businessInfo?.legalPersonName || '' }}</span>
- </div>
- </el-col>
- <el-col :span="8">
- <div class="form-item">
- <span class="label">注册资本:</span>
- <span class="value">{{ businessInfo?.registeredCapital || '' }}</span>
- </div>
- </el-col>
- </el-row>
- <el-row :gutter="12" class="form-row">
- <el-col :span="24">
- <div class="form-item">
- <span class="label">工商地址:</span>
- <el-input v-model="businessInfo.businessAddress" placeholder="工商地址" style="width: 70%;" :disabled="!isEditing" />
- </div>
- </el-col>
- </el-row>
- </div>
- <div class="info-section">
- <div class="section-title-row">
- <div class="section-title-left">
- <span class="section-title-text">付款信息</span>
- </div>
- </div>
- <el-table :data="paymentInfoList" border style="width: 100%">
- <el-table-column prop="isture" label="是否主账号" align="center">
- <template #default="scope">
- <span>{{ Number(scope.row.isture) === 1 ? '是' : '否' }}</span>
- </template>
- </el-table-column>
- <el-table-column prop="bankName" label="开户银行" align="center" />
- <el-table-column prop="bankNo" label="银行账户" align="center" />
- </el-table>
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import ImageUpload from '@/components/ImageUpload/index.vue';
- import { scmEditInfo } from '@/api/supplier/info';
- import { ref, computed, watch } from 'vue';
- import { useRoute } from 'vue-router';
- const props = defineProps<{
- detailData: any;
- companyOptions: any[];
- enterpriseScaleOptions: any[];
- industryCategoryOptions: any[];
- supplierLevelOptions: any[];
- supplierTypeOptions: any[];
- isAddMode: boolean;
- isViewMode: boolean;
- isBasicInfoSaved: boolean;
- businessInfo?: any;
- businessInfoLoading?: boolean;
- regionOptions: any[];
- selectedOfficeRegion: string[];
- paymentInfoList: any[];
- formatDate: (date: any) => string;
- }>();
- const emit = defineEmits<{
- (e: 'save'): void;
- (e: 'officeRegionChange', value: string[]): void;
- (e: 'update:selectedOfficeRegion', value: string[]): void;
- (e: 'addPayment'): void;
- (e: 'viewPayment', row: any): void;
- (e: 'editPayment', row: any): void;
- }>();
- const selectedOfficeRegionProxy = computed({
- get: () => props.selectedOfficeRegion,
- set: (value) => emit('update:selectedOfficeRegion', value)
- });
- const onOfficeRegionChange = (val: unknown) => {
- emit('officeRegionChange', (val || []) as string[]);
- };
- const onFixedPhoneInput = (val: string) => {
- const next = (val || '').replace(/\D+/g, '');
- if (next !== props.detailData.fixedPhone) {
- props.detailData.fixedPhone = next;
- }
- };
- const safeFormatDate = (date: any) => {
- return typeof props.formatDate === 'function' ? props.formatDate(date) : '';
- };
- const isEditing = ref(false);
- const getStatusConfig = (status: string | number) => {
- const s = String(status);
- const map: Record<string, { text: string; type: 'success' | 'info' | 'warning' | 'primary' | 'danger' }> = {
- '0': { text: '待审核', type: 'warning' },
- '1': { text: '生效', type: 'success' },
- '2': { text: '停止合作', type: 'danger' },
- '3': { text: '审核不通过', type: 'danger' },
- '4': { text: '待修改审核', type: 'warning' }
- };
- return map[s] || { text: '未知状态', type: 'info' };
- };
- const route = useRoute();
- const saveLoading = ref(false);
- const backupDetailData = ref<any>(null);
- const backupOfficeRegion = ref<string[] | null>(null);
- const backupBusinessAddress = ref<string | null>(null);
- const originDetailData = ref<any>(null);
- const makeSnapshot = (data: any) => {
- try {
- return JSON.parse(JSON.stringify(data ?? {}));
- } catch (e) {
- return data;
- }
- };
- const getChangedFields = (origin: any, current: any) => {
- const o = origin ?? {};
- const c = current ?? {};
- const changed: any = {};
- Object.keys(c).forEach((k) => {
- const ov = (o as any)[k];
- const cv = (c as any)[k];
- try {
- if (JSON.stringify(ov) !== JSON.stringify(cv)) {
- changed[k] = cv;
- }
- } catch (e) {
- if (ov !== cv) {
- changed[k] = cv;
- }
- }
- });
- return changed;
- };
- watch(
- () => (props.detailData as any)?.id,
- () => {
- originDetailData.value = makeSnapshot(props.detailData);
- },
- { immediate: true }
- );
- const applySnapshot = (target: any, snapshot: any) => {
- if (!target || !snapshot || typeof target !== 'object') return;
- Object.keys(target).forEach((k) => {
- delete target[k];
- });
- Object.assign(target, makeSnapshot(snapshot));
- };
- const onPrimaryAction = () => {
- if (!isEditing.value) {
- backupDetailData.value = makeSnapshot(props.detailData);
- backupOfficeRegion.value = makeSnapshot(props.selectedOfficeRegion);
- backupBusinessAddress.value = props.businessInfo?.businessAddress ?? null;
- isEditing.value = true;
- return;
- }
- if (saveLoading.value) return;
- saveLoading.value = true;
- const id = (route.query.id as string) || (props.detailData as any)?.id;
- const changed = getChangedFields(originDetailData.value, props.detailData);
- scmEditInfo({
- ...changed,
- id
- } as any)
- .then(() => {
- originDetailData.value = makeSnapshot(props.detailData);
- emit('save');
- isEditing.value = false;
- })
- .finally(() => {
- saveLoading.value = false;
- });
- };
- const onCancelEdit = () => {
- if (!isEditing.value) return;
- applySnapshot(props.detailData, backupDetailData.value);
- if (backupOfficeRegion.value) {
- emit('update:selectedOfficeRegion', makeSnapshot(backupOfficeRegion.value));
- emit('officeRegionChange', makeSnapshot(backupOfficeRegion.value));
- }
- if (props.businessInfo && backupBusinessAddress.value !== null) {
- props.businessInfo.businessAddress = backupBusinessAddress.value;
- }
- isEditing.value = false;
- };
- </script>
- <style scoped>
- .tab-content {
- --el-component-size: 24px;
- padding: 16px;
- }
- .detail-form :deep(.el-form-item__label) {
- white-space: nowrap;
- }
- .detail-form :deep(.form-row) {
- margin-bottom: 2px;
- }
- .detail-form :deep(.el-form-item) {
- margin-bottom: 8px;
- }
- .tab-content :deep(.form-row) {
- margin-bottom: 2px;
- }
- .tab-content :deep(.el-form-item) {
- margin-bottom: 8px;
- }
- .tab-content :deep(.info-section) {
- margin-bottom: 20px;
- }
- .tab-content :deep(.section-title),
- .tab-content :deep(.section-title-row) {
- margin-bottom: 12px;
- padding-bottom: 8px;
- }
- .tab-content :deep(.section-title-text) {
- font-size: 14px;
- }
- .tab-content :deep(.section-title-actions) {
- display: flex;
- gap: 8px;
- }
- .tab-content :deep(.supplier-no) {
- font-size: 13px;
- }
- .tab-content :deep(.el-form-item__label) {
- font-size: 13px;
- height: var(--el-component-size);
- line-height: var(--el-component-size);
- padding-top: 0;
- padding-bottom: 0;
- }
- .tab-content :deep(.form-item) {
- line-height: 24px;
- font-size: 13px;
- }
- .detail-form :deep(.el-input),
- .detail-form :deep(.el-select),
- .detail-form :deep(.el-date-editor),
- .detail-form :deep(.el-cascader) {
- width: 100%;
- }
- .detail-form :deep(.el-input__wrapper),
- .detail-form :deep(.el-select__wrapper),
- .detail-form :deep(.el-date-editor),
- .detail-form :deep(.el-cascader) {
- min-height: var(--el-component-size);
- }
- .detail-form :deep(.el-input__inner) {
- height: var(--el-component-size);
- line-height: var(--el-component-size);
- }
- .detail-form :deep(.el-form-item__content) {
- align-items: center;
- min-height: var(--el-component-size);
- }
- .detail-form :deep(.el-input__wrapper),
- .detail-form :deep(.el-select__wrapper),
- .detail-form :deep(.el-date-editor),
- .detail-form :deep(.el-cascader) {
- height: var(--el-component-size);
- align-items: center;
- padding-top: 0;
- padding-bottom: 0;
- }
- .detail-form :deep(.el-select__selected-item),
- .detail-form :deep(.el-select__input),
- .detail-form :deep(.el-range-input) {
- line-height: var(--el-component-size);
- }
- :deep(.component-upload-image .el-upload--picture-card),
- :deep(.component-upload-image .el-upload-list--picture-card .el-upload-list__item) {
- width: 64px;
- height: 64px;
- }
- :deep(.component-upload-image .el-upload-list--picture-card .el-upload-list__item-thumbnail) {
- width: 64px;
- height: 64px;
- }
- </style>
|