|
@@ -1,4 +1,6 @@
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
|
|
+import type { Dayjs } from 'dayjs';
|
|
|
|
|
+
|
|
|
import { computed, ref, watch } from 'vue';
|
|
import { computed, ref, watch } from 'vue';
|
|
|
|
|
|
|
|
import {
|
|
import {
|
|
@@ -13,11 +15,22 @@ import {
|
|
|
Table,
|
|
Table,
|
|
|
Upload,
|
|
Upload,
|
|
|
} from 'antdv-next';
|
|
} from 'antdv-next';
|
|
|
|
|
+import dayjs from 'dayjs';
|
|
|
|
|
|
|
|
import {
|
|
import {
|
|
|
addApplicationApi,
|
|
addApplicationApi,
|
|
|
|
|
+ addUserToApplicationApi,
|
|
|
|
|
+ associateUserApi,
|
|
|
|
|
+ deleteUserFromApplicationApi,
|
|
|
|
|
+ generateSystemSecretApi,
|
|
|
|
|
+ getAddUsersApi,
|
|
|
|
|
+ getApplicationDetailApi,
|
|
|
|
|
+ getAssociatedUsersApi,
|
|
|
getCloneApplicationsApi,
|
|
getCloneApplicationsApi,
|
|
|
|
|
+ getCustomerRelationsApi,
|
|
|
getPartnersApi,
|
|
getPartnersApi,
|
|
|
|
|
+ getSystemSecretApi,
|
|
|
|
|
+ updateApplicationApi,
|
|
|
} from '#/api';
|
|
} from '#/api';
|
|
|
|
|
|
|
|
interface Props {
|
|
interface Props {
|
|
@@ -38,9 +51,12 @@ const activeMenu = ref('basic');
|
|
|
const token = localStorage.getItem('token_a');
|
|
const token = localStorage.getItem('token_a');
|
|
|
|
|
|
|
|
const formData = ref({
|
|
const formData = ref({
|
|
|
|
|
+ code: '',
|
|
|
|
|
+ id: '',
|
|
|
logo: null,
|
|
logo: null,
|
|
|
fileId: '',
|
|
fileId: '',
|
|
|
imgPhotoFileId: '',
|
|
imgPhotoFileId: '',
|
|
|
|
|
+ fileList: [] as any[],
|
|
|
partner: '',
|
|
partner: '',
|
|
|
projectCode: '',
|
|
projectCode: '',
|
|
|
cloneProject: '',
|
|
cloneProject: '',
|
|
@@ -62,8 +78,8 @@ const formData = ref({
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
const keyData = ref({
|
|
const keyData = ref({
|
|
|
- startTime: null,
|
|
|
|
|
- encryptionType: '',
|
|
|
|
|
|
|
+ startTime: null as Dayjs | null,
|
|
|
|
|
+ encryptionType: 'DES3',
|
|
|
validDays: 0,
|
|
validDays: 0,
|
|
|
isPermanent: false,
|
|
isPermanent: false,
|
|
|
errorDescription: '',
|
|
errorDescription: '',
|
|
@@ -83,12 +99,23 @@ const menuItems = [
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
const roleOptions = [
|
|
const roleOptions = [
|
|
|
- { value: 'normal', label: '普通人员' },
|
|
|
|
|
- { value: 'parttime', label: '兼职人员' },
|
|
|
|
|
|
|
+ { value: '普通人员', label: '普通人员' },
|
|
|
|
|
+ { value: '兼职人员', label: '兼职人员' },
|
|
|
|
|
+ { value: '内部人员', label: '内部人员' },
|
|
|
|
|
+ { value: '管理员', label: '管理员' },
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
const applicationMenu = ref<Array<{ label: string; value: string }>>([]);
|
|
const applicationMenu = ref<Array<{ label: string; value: string }>>([]);
|
|
|
const applications = ref<Array<{ label: string; value: string }>>([]);
|
|
const applications = ref<Array<{ label: string; value: string }>>([]);
|
|
|
|
|
+const customerRelationsOptions = ref<Array<{ label: string; value: string }>>(
|
|
|
|
|
+ [],
|
|
|
|
|
+);
|
|
|
|
|
+const allUsers = ref<any[]>([]);
|
|
|
|
|
+const userPagination = ref({
|
|
|
|
|
+ currentPage: 1,
|
|
|
|
|
+ pageSize: 10,
|
|
|
|
|
+ total: 0,
|
|
|
|
|
+});
|
|
|
|
|
|
|
|
async function fetchPartners() {
|
|
async function fetchPartners() {
|
|
|
try {
|
|
try {
|
|
@@ -101,9 +128,7 @@ async function fetchPartners() {
|
|
|
}),
|
|
}),
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
|
- } catch (error) {
|
|
|
|
|
- console.error('获取合作伙伴失败:', error);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ } catch {}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
async function fetchCloneApplications() {
|
|
async function fetchCloneApplications() {
|
|
@@ -125,22 +150,142 @@ async function fetchCloneApplications() {
|
|
|
}),
|
|
}),
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
|
- } catch (error) {
|
|
|
|
|
- console.error('获取可以克隆的项目失败:', error);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ } catch {}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-const allUsers = ref<any[]>([]);
|
|
|
|
|
|
|
+async function fetchCustomerRelations() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const result = await getCustomerRelationsApi();
|
|
|
|
|
+ if (result?.result) {
|
|
|
|
|
+ customerRelationsOptions.value = result.result.map(
|
|
|
|
|
+ (item: { code: string; name: string }) => ({
|
|
|
|
|
+ value: item.code,
|
|
|
|
|
+ label: item.name,
|
|
|
|
|
+ }),
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch {}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+async function fetchApplicationDetail() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const result = await getApplicationDetailApi(formData.value.code);
|
|
|
|
|
+ if (result?.result) {
|
|
|
|
|
+ const data = result.result;
|
|
|
|
|
+ formData.value.code = data.code;
|
|
|
|
|
+ formData.value.projectCode = data.code;
|
|
|
|
|
+ formData.value.cloneProject = data.from_code;
|
|
|
|
|
+ formData.value.contact = data.contact;
|
|
|
|
|
+ formData.value.phone = data.cellPhone;
|
|
|
|
|
+ formData.value.email = data.email;
|
|
|
|
|
+ formData.value.address = data.address;
|
|
|
|
|
+ formData.value.description = data.memo;
|
|
|
|
|
+ formData.value.isEnabled = data.isEnable;
|
|
|
|
|
+ formData.value.processCount = data.number0fWorkFlow;
|
|
|
|
|
+ formData.value.pageCount = data.number0fPages;
|
|
|
|
|
+ formData.value.tableCount = data.number0fTables;
|
|
|
|
|
+ formData.value.designerCount = data.number0fDesigners;
|
|
|
|
|
+ formData.value.scenarioCount = data.number0fBusinessScenarios;
|
|
|
|
|
+ formData.value.userCount = data.number0fCSiteMaxUser;
|
|
|
|
|
+ formData.value.fileId = data.imgPhotoFileId;
|
|
|
|
|
+ formData.value.imgPhotoFileId = data.imgPhotoFileId;
|
|
|
|
|
+ formData.value.partner = data.partner_id;
|
|
|
|
|
+ formData.value.id = data.id;
|
|
|
|
|
+ formData.value.customerRelation = data.client_code;
|
|
|
|
|
+ formData.value.nameEn =
|
|
|
|
|
+ data.langNameList.find((item: any) => item.name === 'en')?.value || '';
|
|
|
|
|
+ if (data.name) {
|
|
|
|
|
+ formData.value.nameCn = data.name;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (data.imgPhotoFileId) {
|
|
|
|
|
+ formData.value.fileList = [
|
|
|
|
|
+ {
|
|
|
|
|
+ uid: '-1',
|
|
|
|
|
+ name: 'logo.png',
|
|
|
|
|
+ status: 'done',
|
|
|
|
|
+ url: `/File/Download?fileId=${data.imgPhotoFileId}`,
|
|
|
|
|
+ response: {
|
|
|
|
|
+ result: [
|
|
|
|
|
+ {
|
|
|
|
|
+ id: data.imgPhotoFileId,
|
|
|
|
|
+ },
|
|
|
|
|
+ ],
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch {}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+async function fetchSystemSecret() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const result = await getSystemSecretApi(formData.value.code);
|
|
|
|
|
+ if (result?.result?.generateSystemEncryptInfo) {
|
|
|
|
|
+ keyData.value.startTime = result.result.generateSystemEncryptInfo
|
|
|
|
|
+ .begin_date
|
|
|
|
|
+ ? dayjs(result.result.generateSystemEncryptInfo.begin_date)
|
|
|
|
|
+ : null;
|
|
|
|
|
+ keyData.value.validDays =
|
|
|
|
|
+ result.result.generateSystemEncryptInfo.period_day;
|
|
|
|
|
+ keyData.value.isPermanent =
|
|
|
|
|
+ result.result.generateSystemEncryptInfo.is_permanent;
|
|
|
|
|
+ keyData.value.errorDescription =
|
|
|
|
|
+ result.result.generateSystemEncryptInfo.error_msg;
|
|
|
|
|
+ keyData.value.systemKey = result.result.encryptInfo ?? '';
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch {}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+async function getAssociatedUsers() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const result = await getAssociatedUsersApi(formData.value.code);
|
|
|
|
|
+ if (result?.result) {
|
|
|
|
|
+ relatedUsers.value = result.result;
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch {}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+async function getAddUsers() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const result = await getAddUsersApi({
|
|
|
|
|
+ currentPage: userPagination.value.currentPage,
|
|
|
|
|
+ pageSize: userPagination.value.pageSize,
|
|
|
|
|
+ orderByProperty: 'name',
|
|
|
|
|
+ Ascending: true,
|
|
|
|
|
+ filters: [
|
|
|
|
|
+ {
|
|
|
|
|
+ name: 'filterText',
|
|
|
|
|
+ value: userSearchKeyword.value,
|
|
|
|
|
+ },
|
|
|
|
|
+ ],
|
|
|
|
|
+ });
|
|
|
|
|
+ if (result?.result?.model) {
|
|
|
|
|
+ allUsers.value = result.result.model;
|
|
|
|
|
+ userPagination.value.total = result.result.totalCount;
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch {}
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
watch(
|
|
watch(
|
|
|
() => props.open,
|
|
() => props.open,
|
|
|
(val) => {
|
|
(val) => {
|
|
|
if (val && props.mode === 'edit' && props.applicationData) {
|
|
if (val && props.mode === 'edit' && props.applicationData) {
|
|
|
Object.assign(formData.value, props.applicationData);
|
|
Object.assign(formData.value, props.applicationData);
|
|
|
|
|
+ fetchApplicationDetail();
|
|
|
|
|
+ fetchSystemSecret();
|
|
|
|
|
+ getAssociatedUsers();
|
|
|
|
|
+ getAddUsers();
|
|
|
}
|
|
}
|
|
|
if (val) {
|
|
if (val) {
|
|
|
|
|
+ if (props.mode === 'add') {
|
|
|
|
|
+ resetFormData();
|
|
|
|
|
+ }
|
|
|
fetchPartners();
|
|
fetchPartners();
|
|
|
fetchCloneApplications();
|
|
fetchCloneApplications();
|
|
|
|
|
+ fetchCustomerRelations();
|
|
|
|
|
+ activeMenu.value = 'basic';
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
);
|
|
);
|
|
@@ -166,6 +311,7 @@ function handleLogoUpload(info: any) {
|
|
|
|
|
|
|
|
async function handleSave() {
|
|
async function handleSave() {
|
|
|
const data = {
|
|
const data = {
|
|
|
|
|
+ id: formData.value.id,
|
|
|
langNameList: [
|
|
langNameList: [
|
|
|
{
|
|
{
|
|
|
name: 'zh-CN',
|
|
name: 'zh-CN',
|
|
@@ -176,6 +322,7 @@ async function handleSave() {
|
|
|
value: formData.value.nameEn,
|
|
value: formData.value.nameEn,
|
|
|
},
|
|
},
|
|
|
],
|
|
],
|
|
|
|
|
+ client_code: formData.value.customerRelation,
|
|
|
code: formData.value.projectCode,
|
|
code: formData.value.projectCode,
|
|
|
fileId: formData.value.fileId,
|
|
fileId: formData.value.fileId,
|
|
|
imgPhotoFileId: formData.value.imgPhotoFileId,
|
|
imgPhotoFileId: formData.value.imgPhotoFileId,
|
|
@@ -195,15 +342,15 @@ async function handleSave() {
|
|
|
number0fCSiteMaxUser: formData.value.userCount,
|
|
number0fCSiteMaxUser: formData.value.userCount,
|
|
|
};
|
|
};
|
|
|
try {
|
|
try {
|
|
|
- const result = await addApplicationApi(data);
|
|
|
|
|
|
|
+ const result = formData.value.id
|
|
|
|
|
+ ? await updateApplicationApi(data)
|
|
|
|
|
+ : await addApplicationApi(data);
|
|
|
if (result?.isSuccess) {
|
|
if (result?.isSuccess) {
|
|
|
emit('save', data);
|
|
emit('save', data);
|
|
|
isOpen.value = false;
|
|
isOpen.value = false;
|
|
|
message.success('应用保存成功');
|
|
message.success('应用保存成功');
|
|
|
}
|
|
}
|
|
|
- } catch (error) {
|
|
|
|
|
- console.error('保存应用失败:', error);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ } catch {}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function handleCancel() {
|
|
function handleCancel() {
|
|
@@ -216,37 +363,132 @@ function handleAddUser() {
|
|
|
selectedUsers.value = [];
|
|
selectedUsers.value = [];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function handleUserSearch() {}
|
|
|
|
|
|
|
+function handleUserSearch() {
|
|
|
|
|
+ userPagination.value.currentPage = 1;
|
|
|
|
|
+ getAddUsers();
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
-function handleUserSelect(user: any) {
|
|
|
|
|
- if (!selectedUsers.value.some((u) => u.id === user.id)) {
|
|
|
|
|
- selectedUsers.value.push(user);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+function handleUserPageChange(pagination: any) {
|
|
|
|
|
+ userPagination.value.currentPage = pagination.current;
|
|
|
|
|
+ userPagination.value.pageSize = pagination.pageSize;
|
|
|
|
|
+ getAddUsers();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function handleUserRemove(user: any) {
|
|
|
|
|
- selectedUsers.value = selectedUsers.value.filter((u) => u.id !== user.id);
|
|
|
|
|
|
|
+async function handleUserSelect(user: any) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const result = await addUserToApplicationApi(
|
|
|
|
|
+ user.account,
|
|
|
|
|
+ formData.value.code,
|
|
|
|
|
+ );
|
|
|
|
|
+ if (result?.isSuccess) {
|
|
|
|
|
+ message.success('用户添加成功');
|
|
|
|
|
+ getAssociatedUsers();
|
|
|
|
|
+ userModalOpen.value = false;
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch {}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function handleUserSave() {
|
|
|
|
|
- relatedUsers.value = [...relatedUsers.value, ...selectedUsers.value];
|
|
|
|
|
- userModalOpen.value = false;
|
|
|
|
|
|
|
+async function handleUserDelete(user: any) {
|
|
|
|
|
+ Modal.confirm({
|
|
|
|
|
+ title: 'Are you sure delete this task?',
|
|
|
|
|
+ content: 'Some descriptions',
|
|
|
|
|
+ okText: 'Yes',
|
|
|
|
|
+ okType: 'danger',
|
|
|
|
|
+ cancelText: 'No',
|
|
|
|
|
+ async onOk() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const result = await deleteUserFromApplicationApi(user.id, [
|
|
|
|
|
+ formData.value.id,
|
|
|
|
|
+ ]);
|
|
|
|
|
+ if (result?.isSuccess) {
|
|
|
|
|
+ message.success('用户删除成功');
|
|
|
|
|
+ getAssociatedUsers();
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch {}
|
|
|
|
|
+ },
|
|
|
|
|
+ onCancel() {},
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function handleUserCancel() {
|
|
|
|
|
- userModalOpen.value = false;
|
|
|
|
|
|
|
+async function handleAssociateUser(user: any) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const data = {
|
|
|
|
|
+ enterpriseId: formData.value.id,
|
|
|
|
|
+ userId: user.id,
|
|
|
|
|
+ roleTypes: user.roleTypes,
|
|
|
|
|
+ };
|
|
|
|
|
+ const result = await associateUserApi(data);
|
|
|
|
|
+ if (result?.isSuccess) {
|
|
|
|
|
+ message.success('用户保存成功');
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch {}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function handleUserDelete(user: any) {
|
|
|
|
|
- relatedUsers.value = relatedUsers.value.filter((u) => u.id !== user.id);
|
|
|
|
|
|
|
+async function handleGenerateKey() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const data = {
|
|
|
|
|
+ begin_date: keyData.value.startTime
|
|
|
|
|
+ ? (keyData.value.startTime as Dayjs).format('YYYY-MM-DD')
|
|
|
|
|
+ : '',
|
|
|
|
|
+ encrypt_type: 1,
|
|
|
|
|
+ enterprise_code: 'SL_tsex1',
|
|
|
|
|
+ error_msg: keyData.value.errorDescription,
|
|
|
|
|
+ is_permanent: keyData.value.isPermanent,
|
|
|
|
|
+ period_day: keyData.value.validDays,
|
|
|
|
|
+ };
|
|
|
|
|
+ const result = await generateSystemSecretApi(data);
|
|
|
|
|
+ if (result?.result) {
|
|
|
|
|
+ message.success('系统密钥生成成功');
|
|
|
|
|
+ fetchSystemSecret();
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch {}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function handleGenerateKey() {
|
|
|
|
|
- keyData.value.systemKey = `generated-key-${Date.now()}`;
|
|
|
|
|
|
|
+function handleCopyKey() {
|
|
|
|
|
+ if (keyData.value.systemKey) {
|
|
|
|
|
+ navigator.clipboard.writeText(keyData.value.systemKey);
|
|
|
|
|
+ message.success('系统密钥已复制');
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function handleKeyCancel() {
|
|
|
|
|
- activeMenu.value = 'basic';
|
|
|
|
|
|
|
+function resetFormData() {
|
|
|
|
|
+ formData.value = {
|
|
|
|
|
+ code: '',
|
|
|
|
|
+ id: '',
|
|
|
|
|
+ logo: null,
|
|
|
|
|
+ fileId: '',
|
|
|
|
|
+ imgPhotoFileId: '',
|
|
|
|
|
+ fileList: [] as any[],
|
|
|
|
|
+ partner: '',
|
|
|
|
|
+ projectCode: '',
|
|
|
|
|
+ cloneProject: '',
|
|
|
|
|
+ nameCn: '',
|
|
|
|
|
+ nameEn: '',
|
|
|
|
|
+ customerRelation: '',
|
|
|
|
|
+ contact: '',
|
|
|
|
|
+ phone: '',
|
|
|
|
|
+ email: '',
|
|
|
|
|
+ address: '',
|
|
|
|
|
+ description: '',
|
|
|
|
|
+ isEnabled: true,
|
|
|
|
|
+ processCount: 0,
|
|
|
|
|
+ pageCount: 0,
|
|
|
|
|
+ tableCount: 0,
|
|
|
|
|
+ designerCount: 0,
|
|
|
|
|
+ scenarioCount: 0,
|
|
|
|
|
+ userCount: 0,
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ keyData.value = {
|
|
|
|
|
+ startTime: null,
|
|
|
|
|
+ encryptionType: 'DES3',
|
|
|
|
|
+ validDays: 0,
|
|
|
|
|
+ isPermanent: false,
|
|
|
|
|
+ errorDescription: '',
|
|
|
|
|
+ systemKey: '',
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ relatedUsers.value = [];
|
|
|
}
|
|
}
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
@@ -274,9 +516,10 @@ function handleKeyCancel() {
|
|
|
<div class="flex flex-col gap-2">
|
|
<div class="flex flex-col gap-2">
|
|
|
<label class="text-sm font-medium">企业Logo</label>
|
|
<label class="text-sm font-medium">企业Logo</label>
|
|
|
<Upload
|
|
<Upload
|
|
|
|
|
+ v-model:file-list="formData.fileList"
|
|
|
:headers="{ Authorization: String(token) }"
|
|
:headers="{ Authorization: String(token) }"
|
|
|
:max-count="1"
|
|
:max-count="1"
|
|
|
- action="/fileApi/File/UploadFiles"
|
|
|
|
|
|
|
+ action="http://a.dev.jbpm.shalu.com/fileApi/File/UploadFiles"
|
|
|
list-type="picture-card"
|
|
list-type="picture-card"
|
|
|
@change="handleLogoUpload"
|
|
@change="handleLogoUpload"
|
|
|
>
|
|
>
|
|
@@ -297,6 +540,7 @@ function handleKeyCancel() {
|
|
|
<label class="text-sm font-medium">合作伙伴</label>
|
|
<label class="text-sm font-medium">合作伙伴</label>
|
|
|
<Select
|
|
<Select
|
|
|
v-model:value="formData.partner"
|
|
v-model:value="formData.partner"
|
|
|
|
|
+ :disabled="props.mode === 'edit'"
|
|
|
:options="applicationMenu"
|
|
:options="applicationMenu"
|
|
|
class="h-[32px]"
|
|
class="h-[32px]"
|
|
|
placeholder="请选择合作伙伴"
|
|
placeholder="请选择合作伙伴"
|
|
@@ -306,6 +550,7 @@ function handleKeyCancel() {
|
|
|
<label class="text-sm font-medium">项目代码</label>
|
|
<label class="text-sm font-medium">项目代码</label>
|
|
|
<Input
|
|
<Input
|
|
|
v-model:value="formData.projectCode"
|
|
v-model:value="formData.projectCode"
|
|
|
|
|
+ :disabled="props.mode === 'edit'"
|
|
|
placeholder="请输入项目代码"
|
|
placeholder="请输入项目代码"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
@@ -313,6 +558,7 @@ function handleKeyCancel() {
|
|
|
<label class="text-sm font-medium">克隆项目</label>
|
|
<label class="text-sm font-medium">克隆项目</label>
|
|
|
<Select
|
|
<Select
|
|
|
v-model:value="formData.cloneProject"
|
|
v-model:value="formData.cloneProject"
|
|
|
|
|
+ :disabled="props.mode === 'edit'"
|
|
|
:options="applications"
|
|
:options="applications"
|
|
|
class="h-[32px]"
|
|
class="h-[32px]"
|
|
|
placeholder="请选择克隆项目"
|
|
placeholder="请选择克隆项目"
|
|
@@ -334,9 +580,11 @@ function handleKeyCancel() {
|
|
|
</div>
|
|
</div>
|
|
|
<div class="flex flex-col gap-2">
|
|
<div class="flex flex-col gap-2">
|
|
|
<label class="text-sm font-medium">客户关系</label>
|
|
<label class="text-sm font-medium">客户关系</label>
|
|
|
- <Input
|
|
|
|
|
|
|
+ <Select
|
|
|
v-model:value="formData.customerRelation"
|
|
v-model:value="formData.customerRelation"
|
|
|
- placeholder="请输入客户关系"
|
|
|
|
|
|
|
+ :options="customerRelationsOptions"
|
|
|
|
|
+ class="h-[32px]"
|
|
|
|
|
+ placeholder="请选择客户关系"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="flex flex-col gap-2">
|
|
<div class="flex flex-col gap-2">
|
|
@@ -411,24 +659,38 @@ function handleKeyCancel() {
|
|
|
<Table
|
|
<Table
|
|
|
:columns="[
|
|
:columns="[
|
|
|
{ title: '账户', dataIndex: 'account', key: 'account' },
|
|
{ title: '账户', dataIndex: 'account', key: 'account' },
|
|
|
- { title: '角色', dataIndex: 'role', key: 'role' },
|
|
|
|
|
- { title: '操作', key: 'action', width: 100 },
|
|
|
|
|
|
|
+ { title: '角色', dataIndex: 'roleTypes', key: 'roleTypes' },
|
|
|
|
|
+ { title: '操作', key: 'action', width: 200 },
|
|
|
]"
|
|
]"
|
|
|
:data-source="relatedUsers"
|
|
:data-source="relatedUsers"
|
|
|
:pagination="false"
|
|
:pagination="false"
|
|
|
>
|
|
>
|
|
|
<template #bodyCell="{ column, record }">
|
|
<template #bodyCell="{ column, record }">
|
|
|
- <template v-if="column.key === 'role'">
|
|
|
|
|
|
|
+ <template v-if="column.key === 'roleTypes'">
|
|
|
<Select
|
|
<Select
|
|
|
- v-model:value="record.role"
|
|
|
|
|
|
|
+ v-model:value="record.roleTypes"
|
|
|
:options="roleOptions"
|
|
:options="roleOptions"
|
|
|
style="width: 120px"
|
|
style="width: 120px"
|
|
|
/>
|
|
/>
|
|
|
</template>
|
|
</template>
|
|
|
<template v-if="column.key === 'action'">
|
|
<template v-if="column.key === 'action'">
|
|
|
- <Button danger size="small" @click="handleUserDelete(record)">
|
|
|
|
|
- 删除
|
|
|
|
|
- </Button>
|
|
|
|
|
|
|
+ <div class="flex">
|
|
|
|
|
+ <Button
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ type="primary"
|
|
|
|
|
+ @click="handleAssociateUser(record)"
|
|
|
|
|
+ >
|
|
|
|
|
+ 保存
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ <Button
|
|
|
|
|
+ class="ml-[10px]"
|
|
|
|
|
+ danger
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ @click="handleUserDelete(record)"
|
|
|
|
|
+ >
|
|
|
|
|
+ 删除
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ </div>
|
|
|
</template>
|
|
</template>
|
|
|
</template>
|
|
</template>
|
|
|
</Table>
|
|
</Table>
|
|
@@ -440,6 +702,7 @@ function handleKeyCancel() {
|
|
|
<label class="text-sm font-medium">开始时间</label>
|
|
<label class="text-sm font-medium">开始时间</label>
|
|
|
<DatePicker
|
|
<DatePicker
|
|
|
v-model:value="keyData.startTime"
|
|
v-model:value="keyData.startTime"
|
|
|
|
|
+ format="YYYY-MM-DD"
|
|
|
style="width: 100%"
|
|
style="width: 100%"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
@@ -447,6 +710,7 @@ function handleKeyCancel() {
|
|
|
<label class="text-sm font-medium">加密类型</label>
|
|
<label class="text-sm font-medium">加密类型</label>
|
|
|
<Input
|
|
<Input
|
|
|
v-model:value="keyData.encryptionType"
|
|
v-model:value="keyData.encryptionType"
|
|
|
|
|
+ disabled
|
|
|
placeholder="请输入加密类型"
|
|
placeholder="请输入加密类型"
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
@@ -479,14 +743,23 @@ function handleKeyCancel() {
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="mt-6 flex justify-end gap-2">
|
|
<div class="mt-6 flex justify-end gap-2">
|
|
|
- <Button @click="handleKeyCancel">取消</Button>
|
|
|
|
|
<Button type="primary" @click="handleGenerateKey">生成</Button>
|
|
<Button type="primary" @click="handleGenerateKey">生成</Button>
|
|
|
|
|
+ <Button
|
|
|
|
|
+ v-if="keyData.systemKey"
|
|
|
|
|
+ type="primary"
|
|
|
|
|
+ @click="handleCopyKey"
|
|
|
|
|
+ >
|
|
|
|
|
+ 复制
|
|
|
|
|
+ </Button>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
- <div class="flex justify-end gap-2 border-t pt-4">
|
|
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-if="activeMenu === 'basic'"
|
|
|
|
|
+ class="flex justify-end gap-2 border-t pt-4"
|
|
|
|
|
+ >
|
|
|
<Button @click="handleCancel">取消</Button>
|
|
<Button @click="handleCancel">取消</Button>
|
|
|
<Button type="primary" @click="handleSave">保存</Button>
|
|
<Button type="primary" @click="handleSave">保存</Button>
|
|
|
</div>
|
|
</div>
|
|
@@ -495,7 +768,7 @@ function handleKeyCancel() {
|
|
|
v-model:open="userModalOpen"
|
|
v-model:open="userModalOpen"
|
|
|
:footer="null"
|
|
:footer="null"
|
|
|
title="添加用户"
|
|
title="添加用户"
|
|
|
- width="600px"
|
|
|
|
|
|
|
+ width="670px"
|
|
|
>
|
|
>
|
|
|
<div class="space-y-4">
|
|
<div class="space-y-4">
|
|
|
<Input
|
|
<Input
|
|
@@ -503,33 +776,48 @@ function handleKeyCancel() {
|
|
|
placeholder="搜索用户"
|
|
placeholder="搜索用户"
|
|
|
@change="handleUserSearch"
|
|
@change="handleUserSearch"
|
|
|
/>
|
|
/>
|
|
|
- <div class="h-[300px] overflow-y-auto rounded border p-2">
|
|
|
|
|
- <div
|
|
|
|
|
- v-for="user in allUsers"
|
|
|
|
|
- :key="user.id"
|
|
|
|
|
- class="flex cursor-pointer items-center justify-between p-2 hover:bg-gray-100"
|
|
|
|
|
- @click="handleUserSelect(user)"
|
|
|
|
|
- >
|
|
|
|
|
- <div class="flex items-center gap-2">
|
|
|
|
|
- <input
|
|
|
|
|
- :checked="selectedUsers.some((u) => u.id === user.id)"
|
|
|
|
|
- type="checkbox"
|
|
|
|
|
- @change="
|
|
|
|
|
- (e: any) =>
|
|
|
|
|
- e.target.checked
|
|
|
|
|
- ? handleUserSelect(user)
|
|
|
|
|
- : handleUserRemove(user)
|
|
|
|
|
- "
|
|
|
|
|
- />
|
|
|
|
|
- <span>{{ user.account }}</span>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="mt-4 flex justify-end gap-2">
|
|
|
|
|
- <Button @click="handleUserCancel">取消</Button>
|
|
|
|
|
- <Button type="primary" @click="handleUserSave">保存</Button>
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ <Table
|
|
|
|
|
+ :columns="[
|
|
|
|
|
+ { title: '账户', dataIndex: 'account', key: 'account' },
|
|
|
|
|
+ { title: '姓名', dataIndex: 'name', key: 'name' },
|
|
|
|
|
+ { title: '邮箱', dataIndex: 'emailAddress', key: 'emailAddress' },
|
|
|
|
|
+ { title: '电话号码', dataIndex: 'cellPhone', key: 'cellPhone' },
|
|
|
|
|
+ { title: '操作', key: 'action', width: 200 },
|
|
|
|
|
+ ]"
|
|
|
|
|
+ :data-source="allUsers"
|
|
|
|
|
+ :pagination="{
|
|
|
|
|
+ current: userPagination.currentPage,
|
|
|
|
|
+ pageSize: userPagination.pageSize,
|
|
|
|
|
+ total: userPagination.total,
|
|
|
|
|
+ showSizeChanger: true,
|
|
|
|
|
+ showTotal: (total: number) => `共 ${total} 条`,
|
|
|
|
|
+ }"
|
|
|
|
|
+ @change="handleUserPageChange"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #bodyCell="{ column, record }">
|
|
|
|
|
+ <template v-if="column.key === 'action'">
|
|
|
|
|
+ <Button
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ type="primary"
|
|
|
|
|
+ @click="handleUserSelect(record)"
|
|
|
|
|
+ >
|
|
|
|
|
+ 选择
|
|
|
|
|
+ </Button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </Table>
|
|
|
</div>
|
|
</div>
|
|
|
</Modal>
|
|
</Modal>
|
|
|
</Modal>
|
|
</Modal>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
+
|
|
|
|
|
+<style lang="scss">
|
|
|
|
|
+.ant-menu-light .ant-menu-item-selected,
|
|
|
|
|
+.ant-menu-light > .ant-menu .ant-menu-item-selected {
|
|
|
|
|
+ background-color: #f4f2f2;
|
|
|
|
|
+
|
|
|
|
|
+ .ant-menu-title-content {
|
|
|
|
|
+ color: #462424;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|