| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- <script setup lang="ts">
- import { computed, ref, watch } from 'vue';
- import { useAccessStore } from '@vben/stores';
- import { $t } from '@/locales';
- import {
- Button,
- DatePicker,
- Input,
- message,
- Modal,
- Switch,
- Upload,
- } from 'antdv-next';
- import md5 from 'crypto-js/md5';
- import dayjs from 'dayjs';
- import { createPartnerApi, getLangByKeyApi, updatePartnerApi } from '#/api';
- interface Props {
- open: boolean;
- mode: 'add' | 'edit';
- partnerData?: any;
- }
- const props = defineProps<Props>();
- const emit = defineEmits<{
- (e: 'save', data: any): void;
- (e: 'update:open', value: boolean): void;
- }>();
- const accessStore = useAccessStore();
- const token = accessStore.accessToken;
- const formData = ref({
- id: '',
- logo: null,
- fileId: '',
- imgLogoFileId: '',
- fileList: [] as any[],
- account: '',
- password: '',
- nameCn: '',
- nameEn: '',
- langName: '',
- isEnabled: true,
- expiredTime: null as any,
- number0fEnterprise: 0,
- number0fWorkFlow: 0,
- number0fPages: 0,
- number0fTables: 0,
- number0fDesigners: 0,
- number0fBusinessScenarios: 0,
- number0fCSiteMaxUser: 0,
- });
- const isOpen = computed({
- get: () => props.open,
- set: (value) => emit('update:open', value),
- });
- watch(
- () => props.open,
- (newValue) => {
- if (newValue && props.partnerData) {
- fetchPartnerDetail();
- } else if (newValue) {
- resetForm();
- }
- },
- );
- async function fetchPartnerDetail() {
- if (!props.partnerData) {
- return;
- }
- formData.value.id = props.partnerData.id || '';
- formData.value.account = props.partnerData.account || '';
- formData.value.langName = props.partnerData.langName || '';
- formData.value.isEnabled = props.partnerData.status ?? true;
- formData.value.expiredTime = props.partnerData.expiredTime
- ? dayjs(props.partnerData.expiredTime)
- : null;
- formData.value.number0fEnterprise = props.partnerData.number0fEnterprise || 0;
- formData.value.number0fWorkFlow = props.partnerData.number0fWorkFlow || 0;
- formData.value.number0fPages = props.partnerData.number0fPages || 0;
- formData.value.number0fTables = props.partnerData.number0fTables || 0;
- formData.value.number0fDesigners = props.partnerData.number0fDesigners || 0;
- formData.value.number0fBusinessScenarios =
- props.partnerData.number0fBusinessScenarios || 0;
- formData.value.number0fCSiteMaxUser =
- props.partnerData.number0fCSiteMaxUser || 0;
- if (props.partnerData.imgLogoFileId) {
- formData.value.imgLogoFileId = props.partnerData.imgLogoFileId;
- formData.value.fileList = [
- {
- uid: '-1',
- name: 'logo.png',
- status: 'done',
- url: `/File/Download?fileId=${props.partnerData.imgLogoFileId}`,
- },
- ];
- }
- if (props.mode === 'edit' && props.partnerData.langName) {
- try {
- const result = await getLangByKeyApi(props.partnerData.langName);
- if (result?.result) {
- formData.value.nameCn = result.result['zh-CN'] || '';
- formData.value.nameEn = result.result.en || '';
- }
- } catch {}
- } else {
- formData.value.nameCn =
- props.partnerData.langNameList?.find((item: any) => item.name === 'zh-CN')
- ?.value || '';
- formData.value.nameEn =
- props.partnerData.langNameList?.find((item: any) => item.name === 'en')
- ?.value || '';
- }
- }
- function resetForm() {
- formData.value = {
- id: '',
- logo: null,
- fileId: '',
- imgLogoFileId: '',
- fileList: [] as any[],
- account: '',
- password: '',
- nameCn: '',
- nameEn: '',
- langName: '',
- isEnabled: true,
- expiredTime: null,
- number0fEnterprise: 0,
- number0fWorkFlow: 0,
- number0fPages: 0,
- number0fTables: 0,
- number0fDesigners: 0,
- number0fBusinessScenarios: 0,
- number0fCSiteMaxUser: 0,
- };
- }
- function handleLogoUpload(info: any) {
- if (info.file.status === 'done') {
- formData.value.logo = info.file;
- if (info.file.response?.result?.[0]?.id) {
- formData.value.fileId = info.file.response.result[0].id;
- formData.value.imgLogoFileId = info.file.response.result[0].id;
- }
- }
- }
- async function handleSave() {
- const data = {
- id: formData.value.id,
- langNameList: [
- {
- name: 'zh-CN',
- value: formData.value.nameCn,
- },
- {
- name: 'en',
- value: formData.value.nameEn,
- },
- ],
- fileId: formData.value.fileId,
- imgLogoFileId: formData.value.imgLogoFileId,
- version: 'v1',
- account: formData.value.account,
- langName:
- props.mode === 'edit' ? formData.value.langName : formData.value.nameCn,
- password:
- props.mode === 'add' ? md5(formData.value.password).toString() : '',
- expiredTime: formData.value.expiredTime
- ? formData.value.expiredTime.format('YYYY-MM-DD')
- : '',
- number0fEnterprise: formData.value.number0fEnterprise,
- number0fPages: formData.value.number0fPages,
- number0fDesigners: formData.value.number0fDesigners,
- number0fCSiteMaxUser: formData.value.number0fCSiteMaxUser,
- number0fBusinessScenarios: formData.value.number0fBusinessScenarios,
- number0fTables: formData.value.number0fTables,
- number0fWorkFlow: formData.value.number0fWorkFlow,
- status: formData.value.isEnabled,
- };
- try {
- const result =
- props.mode === 'add'
- ? await createPartnerApi(data)
- : await updatePartnerApi(data);
- if (result?.isSuccess) {
- message.success($t('salesPartners.saveSuccess'));
- emit('save', data);
- }
- } catch (error) {
- console.error('保存失败:', error);
- }
- }
- function handleCancel() {
- isOpen.value = false;
- }
- </script>
- <template>
- <Modal
- v-model:open="isOpen"
- :footer="null"
- :title="
- mode === 'add'
- ? $t('salesPartners.modal.addTitle')
- : $t('salesPartners.modal.editTitle')
- "
- class="mt-[-50px]"
- width="1200px"
- >
- <div class="">
- <div class="flex-1 overflow-y-auto p-6">
- <div class="space-y-4">
- <div class="flex items-center gap-4">
- <div class="flex flex-col gap-2">
- <label class="text-sm font-medium">{{
- $t('salesPartners.modal.enterpriseLogo')
- }}</label>
- <Upload
- v-model:file-list="formData.fileList"
- :action="`/fileApi/File/UploadFiles?Authorization=${token}`"
- :headers="{ Authorization: String(token) }"
- :max-count="1"
- list-type="picture-card"
- @change="handleLogoUpload"
- >
- <div
- class="flex h-[100px] w-[200px] items-center justify-center border-2 border-dashed"
- >
- <div class="text-center">
- <div class="text-4xl">+</div>
- <div class="text-sm text-gray-500">
- {{ $t('salesPartners.modal.uploadLogo') }}
- </div>
- </div>
- </div>
- </Upload>
- </div>
- </div>
- <div class="grid grid-cols-2 gap-4">
- <div class="flex flex-col gap-2">
- <label class="text-sm font-medium">{{
- $t('salesPartners.modal.account')
- }}</label>
- <Input
- v-model:value="formData.account"
- :placeholder="$t('salesPartners.modal.enterAccount')"
- />
- </div>
- <div v-if="mode === 'add'" class="flex flex-col gap-2">
- <label class="text-sm font-medium">{{
- $t('salesPartners.modal.password')
- }}</label>
- <Input
- v-model:value="formData.password"
- :placeholder="$t('salesPartners.modal.enterPassword')"
- />
- </div>
- <div class="flex flex-col gap-2">
- <label class="text-sm font-medium">{{
- $t('salesPartners.modal.nameCn')
- }}</label>
- <Input
- v-model:value="formData.nameCn"
- :placeholder="$t('salesPartners.modal.enterName')"
- />
- </div>
- <div class="flex flex-col gap-2">
- <label class="text-sm font-medium">{{
- $t('salesPartners.modal.nameEn')
- }}</label>
- <Input
- v-model:value="formData.nameEn"
- :placeholder="$t('salesPartners.modal.enterName')"
- />
- </div>
- <div class="flex flex-col gap-2">
- <label class="text-sm font-medium">{{
- $t('salesPartners.modal.expiredTime')
- }}</label>
- <DatePicker
- v-model:value="formData.expiredTime"
- :placeholder="$t('salesPartners.modal.selectExpiredTime')"
- class="h-[32px] w-full"
- format="YYYY-MM-DD"
- />
- </div>
- <div class="flex flex-col gap-2">
- <label class="text-sm font-medium">{{
- $t('salesPartners.modal.isEnabled')
- }}</label>
- <Switch v-model:checked="formData.isEnabled" class="w-[40px]" />
- </div>
- <div class="flex flex-col gap-2">
- <label class="text-sm font-medium">{{
- $t('salesPartners.modal.number0fEnterprise')
- }}</label>
- <Input
- v-model:value="formData.number0fEnterprise"
- type="number"
- />
- </div>
- <div class="flex flex-col gap-2">
- <label class="text-sm font-medium">{{
- $t('salesPartners.modal.number0fWorkFlow')
- }}</label>
- <Input v-model:value="formData.number0fWorkFlow" type="number" />
- </div>
- <div class="flex flex-col gap-2">
- <label class="text-sm font-medium">{{
- $t('salesPartners.modal.number0fPages')
- }}</label>
- <Input v-model:value="formData.number0fPages" type="number" />
- </div>
- <div class="flex flex-col gap-2">
- <label class="text-sm font-medium">{{
- $t('salesPartners.modal.number0fTables')
- }}</label>
- <Input v-model:value="formData.number0fTables" type="number" />
- </div>
- <div class="flex flex-col gap-2">
- <label class="text-sm font-medium">{{
- $t('salesPartners.modal.number0fDesigners')
- }}</label>
- <Input v-model:value="formData.number0fDesigners" type="number" />
- </div>
- <div class="flex flex-col gap-2">
- <label class="text-sm font-medium">{{
- $t('salesPartners.modal.number0fBusinessScenarios')
- }}</label>
- <Input
- v-model:value="formData.number0fBusinessScenarios"
- type="number"
- />
- </div>
- <div class="flex flex-col gap-2">
- <label class="text-sm font-medium">{{
- $t('salesPartners.modal.number0fCSiteMaxUser')
- }}</label>
- <Input
- v-model:value="formData.number0fCSiteMaxUser"
- type="number"
- />
- </div>
- </div>
- </div>
- </div>
- <div class="flex justify-end gap-4">
- <Button @click="handleCancel">
- {{ $t('salesPartners.modal.cancel') }}
- </Button>
- <Button type="primary" @click="handleSave">
- {{ $t('salesPartners.modal.save') }}
- </Button>
- </div>
- </div>
- </Modal>
- </template>
- <style lang="scss" scoped>
- :deep(.ant-upload-list-picture-card-container) {
- .ant-upload-list-item {
- width: 80px;
- height: 80px;
- }
- }
- </style>
|