feat(系统设置): 项目创建编辑

This commit is contained in:
RubyLiu 2023-08-22 14:46:10 +08:00 committed by fit2-zhao
parent 0221a76d45
commit f1f99af196
11 changed files with 209 additions and 85 deletions

View File

@ -5,6 +5,7 @@ import { AddUserToOrgOrProjectParams } from '@/models/setting/systemOrg';
import { import {
CreateOrUpdateSystemOrgParams, CreateOrUpdateSystemOrgParams,
CreateOrUpdateSystemProjectParams, CreateOrUpdateSystemProjectParams,
SystemGetUserByOrgOrProjectIdParams,
} from '@/models/setting/system/orgAndProject'; } from '@/models/setting/system/orgAndProject';
// 获取组织列表 // 获取组织列表
@ -52,9 +53,9 @@ export function postProjectTableByOrgId(data: TableQueryParams) {
return MSR.post({ url: orgUrl.postProjectTableByOrgUrl, data }); return MSR.post({ url: orgUrl.postProjectTableByOrgUrl, data });
} }
// 根据组织id获取用户列表 // 根据 orgId 或 projectId 获取用户列表
export function postUserTableByOrgId(data: TableQueryParams) { export function postUserTableByOrgIdOrProjectId(data: SystemGetUserByOrgOrProjectIdParams) {
return MSR.post({ url: orgUrl.postOrgMemberUrl, data }); return MSR.post({ url: data.organizationId ? orgUrl.postOrgMemberUrl : orgUrl.postProjectMemberUrl, data });
} }
// 给组织或项目添加成员 // 给组织或项目添加成员
export function addUserToOrgOrProject(data: AddUserToOrgOrProjectParams) { export function addUserToOrgOrProject(data: AddUserToOrgOrProjectParams) {
@ -71,7 +72,22 @@ export function deleteUserFromOrgOrProject(sourceId: string, userId: string, isO
}); });
} }
// TODO: 等待后端同学的接口 启用或禁用项目 // 启用或禁用项目
export function enableOrDisableProject(id: string, isEnable = true) { export function enableOrDisableProject(id: string, isEnable = true) {
return MSR.get({ url: `${isEnable ? orgUrl.getEnableProjectUrl : orgUrl.getDisableProjectUrl}${id}` }); return MSR.get({ url: `${isEnable ? orgUrl.getEnableProjectUrl : orgUrl.getDisableProjectUrl}${id}` });
} }
// 获取组织下拉选项
export function getSystemOrgOption() {
return MSR.post({ url: orgUrl.postOrgOptionsUrl });
}
// 创建或更新项目
export function createOrUpdateProject(data: CreateOrUpdateSystemProjectParams) {
return MSR.post({ url: data.id ? orgUrl.postModifyProjectUrl : orgUrl.postAddProjectUrl, data });
}
// 创建项目或组织时获取所有用户
export function getAllUser() {
return MSR.get({ url: orgUrl.getOrgOrProjectAdminUrl });
}

View File

@ -50,3 +50,5 @@ export const getUserByOrgOrProjectUrl = '/system/user/get-option/';
export const getEnableProjectUrl = '/system/project/enable/'; export const getEnableProjectUrl = '/system/project/enable/';
// 禁用项目 // 禁用项目
export const getDisableProjectUrl = '/system/project/disable/'; export const getDisableProjectUrl = '/system/project/disable/';
// 获取组织或项目的管理员
export const getOrgOrProjectAdminUrl = '/system/project/user-list';

View File

@ -23,8 +23,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { ref, onMounted, watch } from 'vue'; import { ref, onMounted, watch } from 'vue';
import { getUserList } from '@/api/modules/setting/usergroup'; import { getUserByOrganizationOrProject, getAllUser } from '@/api/modules/setting/system/organizationAndProject';
import { getUserByOrganizationOrProject } from '@/api/modules/setting/system/organizationAndProject';
export interface MsUserSelectorProps { export interface MsUserSelectorProps {
value: string[]; value: string[];
@ -66,7 +65,7 @@
} }
res = await getUserByOrganizationOrProject(props.sourceId); res = await getUserByOrganizationOrProject(props.sourceId);
} else { } else {
res = await getUserList(); res = await getAllUser();
} }
res.forEach((item) => { res.forEach((item) => {
item.disabled = item[props.disabledKey]; item.disabled = item[props.disabledKey];

View File

@ -1,3 +1,5 @@
import { TableQueryParams } from '@/models/common';
export interface CreateOrUpdateSystemOrgParams { export interface CreateOrUpdateSystemOrgParams {
id?: string; id?: string;
name: string; name: string;
@ -6,13 +8,26 @@ export interface CreateOrUpdateSystemOrgParams {
} }
export interface CreateOrUpdateSystemProjectParams { export interface CreateOrUpdateSystemProjectParams {
id?: string; id?: string;
// 项目名称
name: string; name: string;
// 项目描述
description: string; description: string;
// 启用或禁用
enable: boolean; enable: boolean;
// 项目成员
userIds: string[]; userIds: string[];
// 模块配置 后端需要的字段 JSON string // 模块配置
moduleSetting?: string; moduleIds?: string[];
// 前端展示的模块配置 string[] // 所属组织
module?: string[]; organizationId?: string;
// 列表里的
}
export interface SystemOrgOption {
id: string;
name: string;
}
export interface SystemGetUserByOrgOrProjectIdParams extends TableQueryParams {
projectId?: string;
organizationId?: string; organizationId?: string;
} }

View File

@ -13,7 +13,7 @@
<span class="text-[var(--color-text-4)]">({{ props.currentProject?.name }})</span> <span class="text-[var(--color-text-4)]">({{ props.currentProject?.name }})</span>
</span> </span>
<span v-else> <span v-else>
{{ t('system.project.create') }} {{ t('system.project.createProject') }}
</span> </span>
</template> </template>
<div class="form"> <div class="form">
@ -26,8 +26,21 @@
> >
<a-input v-model="form.name" :placeholder="t('system.project.projectNamePlaceholder')" /> <a-input v-model="form.name" :placeholder="t('system.project.projectNamePlaceholder')" />
</a-form-item> </a-form-item>
<a-form-item field="organizationId" :label="t('system.project.affiliatedOrg')"> <a-form-item
<a-input v-model="form.organizationId" :placeholder="t('system.project.affiliatedOrgPlaceholder')" /> required
field="organizationId"
:label="t('system.project.affiliatedOrg')"
:rules="[{ required: true, message: t('system.project.affiliatedOrgRequired') }]"
>
<a-select
v-model="form.organizationId"
:disabled="!isXpack"
allow-search
:options="affiliatedOrgOption"
:placeholder="t('system.project.affiliatedOrgPlaceholder')"
:field-names="{ label: 'name', value: 'id' }"
>
</a-select>
</a-form-item> </a-form-item>
<a-form-item field="userIds" :label="t('system.project.projectAdmin')"> <a-form-item field="userIds" :label="t('system.project.projectAdmin')">
<MsUserSelector v-model:value="form.userIds" placeholder="system.project.projectAdminPlaceholder" /> <MsUserSelector v-model:value="form.userIds" placeholder="system.project.projectAdminPlaceholder" />
@ -35,18 +48,33 @@
<a-form-item field="description" :label="t('system.organization.description')"> <a-form-item field="description" :label="t('system.organization.description')">
<a-input v-model="form.description" :placeholder="t('system.organization.descriptionPlaceholder')" /> <a-input v-model="form.description" :placeholder="t('system.organization.descriptionPlaceholder')" />
</a-form-item> </a-form-item>
<a-form-item field="enable" :label="t('system.organization.description')"> <a-form-item field="module" :label="t('system.organization.description')">
<a-switch v-model="form.enable" :placeholder="t('system.organization.descriptionPlaceholder')" /> <a-checkbox-group v-model="form.moduleIds" :options="moduleOption">
<template #label="{ data }">
<span>{{ t(data.label) }}</span>
</template>
</a-checkbox-group>
</a-form-item> </a-form-item>
</a-form> </a-form>
</div> </div>
<template #footer> <template #footer>
<div class="flex flex-row justify-between">
<div class="flex flex-row items-center gap-[4px]">
<a-switch v-model="form.enable" />
<span>{{ t('system.organization.status') }}</span>
<a-tooltip :content="t('system.project.createTip')" position="top">
<MsIcon type="icon-icon-maybe_outlined" class="text-[var(--color-text-4)]" />
</a-tooltip>
</div>
<div class="flex flex-row gap-[14px]">
<a-button type="secondary" :loading="loading" @click="handleCancel"> <a-button type="secondary" :loading="loading" @click="handleCancel">
{{ t('common.cancel') }} {{ t('common.cancel') }}
</a-button> </a-button>
<a-button type="primary" :loading="loading" @click="handleBeforeOk"> <a-button type="primary" :loading="loading" @click="handleBeforeOk">
{{ isEdit ? t('common.confirm') : t('common.create') }} {{ isEdit ? t('common.confirm') : t('common.create') }}
</a-button> </a-button>
</div>
</div>
</template> </template>
</a-modal> </a-modal>
</template> </template>
@ -56,9 +84,11 @@
import { reactive, ref, watchEffect, computed } from 'vue'; import { reactive, ref, watchEffect, computed } from 'vue';
import type { FormInstance, ValidatedError } from '@arco-design/web-vue'; import type { FormInstance, ValidatedError } from '@arco-design/web-vue';
import MsUserSelector from '@/components/business/ms-user-selector/index.vue'; import MsUserSelector from '@/components/business/ms-user-selector/index.vue';
import { createOrUpdateOrg } from '@/api/modules/setting/system/organizationAndProject'; import { createOrUpdateProject, getSystemOrgOption } from '@/api/modules/setting/system/organizationAndProject';
import { Message } from '@arco-design/web-vue'; import { Message } from '@arco-design/web-vue';
import { CreateOrUpdateSystemProjectParams } from '@/models/setting/system/orgAndProject'; import MsIcon from '@/components/pure/ms-icon-font/index.vue';
import { CreateOrUpdateSystemProjectParams, SystemOrgOption } from '@/models/setting/system/orgAndProject';
import useLicenseStore from '@/store/modules/setting/license';
const { t } = useI18n(); const { t } = useI18n();
const props = defineProps<{ const props = defineProps<{
@ -70,6 +100,17 @@
const loading = ref(false); const loading = ref(false);
const isEdit = computed(() => !!props.currentProject?.id); const isEdit = computed(() => !!props.currentProject?.id);
const affiliatedOrgOption = ref<SystemOrgOption[]>([]);
const licenseStore = useLicenseStore();
const moduleOption = [
{ label: 'menu.workplace', value: 'workstation' },
{ label: 'menu.testPlan', value: 'testPlan' },
{ label: 'menu.bugManagement', value: 'bugManagement' },
{ label: 'menu.featureTest', value: 'caseManagement' },
{ label: 'menu.apiTest', value: 'apiTest' },
{ label: 'menu.uiTest', value: 'uiTest' },
{ label: 'menu.performanceTest', value: 'loadTest' },
];
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'cancel'): void; (e: 'cancel'): void;
@ -81,49 +122,64 @@
organizationId: '', organizationId: '',
description: '', description: '',
enable: true, enable: true,
module: [], moduleIds: [],
}); });
const currentVisible = ref(props.visible); const currentVisible = ref(props.visible);
const isXpack = computed(() => {
return licenseStore.hasLicense();
});
watchEffect(() => { watchEffect(() => {
currentVisible.value = props.visible; currentVisible.value = props.visible;
}); });
const handleCancel = () => { const handleCancel = () => {
formRef.value?.resetFields();
emit('cancel'); emit('cancel');
}; };
const handleBeforeOk = () => { const handleBeforeOk = async () => {
formRef.value?.validate(async (errors: undefined | Record<string, ValidatedError>) => { await formRef.value?.validate(async (errors: undefined | Record<string, ValidatedError>) => {
if (errors) { if (errors) {
return false; return;
} }
try { try {
loading.value = true; loading.value = true;
await createOrUpdateOrg({ id: props.currentProject?.id, ...form }); await createOrUpdateProject({ id: props.currentProject?.id, ...form });
Message.success( Message.success(
isEdit.value isEdit.value
? t('system.organization.updateOrganizationSuccess') ? t('system.organization.updateOrganizationSuccess')
: t('system.organization.createOrganizationSuccess') : t('system.organization.createOrganizationSuccess')
); );
handleCancel(); handleCancel();
return true;
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.error(error); console.error(error);
return false;
} finally { } finally {
loading.value = false; loading.value = false;
} }
}); });
}; };
const initAffiliatedOrgOption = async () => {
try {
const res = await getSystemOrgOption();
affiliatedOrgOption.value = res;
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
}
};
watchEffect(() => { watchEffect(() => {
initAffiliatedOrgOption();
if (props.currentProject) { if (props.currentProject) {
form.id = props.currentProject.id;
form.name = props.currentProject.name; form.name = props.currentProject.name;
form.userIds = props.currentProject.userIds;
form.description = props.currentProject.description; form.description = props.currentProject.description;
form.organizationId = props.currentProject.organizationId;
form.enable = props.currentProject.enable; form.enable = props.currentProject.enable;
form.userIds = props.currentProject.userIds;
form.organizationId = props.currentProject.organizationId;
form.moduleIds = props.currentProject.moduleIds;
} }
}); });
</script> </script>

View File

@ -54,7 +54,7 @@
import useTable from '@/components/pure/ms-table/useTable'; import useTable from '@/components/pure/ms-table/useTable';
import MsBaseTable from '@/components/pure/ms-table/base-table.vue'; import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
import { useTableStore } from '@/store'; import { useTableStore } from '@/store';
import { ref, reactive, watch } from 'vue'; import { ref, reactive } from 'vue';
import type { ActionsItem } from '@/components/pure/ms-table-more-action/types'; import type { ActionsItem } from '@/components/pure/ms-table-more-action/types';
import { import {
postOrgTable, postOrgTable,
@ -140,7 +140,6 @@
scroll: { y: 'auto', x: '1300px' }, scroll: { y: 'auto', x: '1300px' },
selectable: false, selectable: false,
noDisable: false, noDisable: false,
debug: true,
size: 'default', size: 'default',
showSetting: true, showSetting: true,
}); });
@ -208,6 +207,7 @@
Message.success(isEnable ? t('common.enableSuccess') : t('common.closeSuccess')); Message.success(isEnable ? t('common.enableSuccess') : t('common.closeSuccess'));
fetchData(); fetchData();
} catch (error) { } catch (error) {
// eslint-disable-next-line no-console
console.log(error); console.log(error);
} }
}, },
@ -274,14 +274,6 @@
setLoading(false); setLoading(false);
} }
}; };
watch(
() => props.keyword,
() => {
fetchData();
},
{ immediate: true }
);
defineExpose({ defineExpose({
fetchData, fetchData,
}); });

View File

@ -28,7 +28,7 @@
<MsButton @click="handleDelete(record)">{{ t('common.delete') }}</MsButton> <MsButton @click="handleDelete(record)">{{ t('common.delete') }}</MsButton>
</template> </template>
<template v-else> <template v-else>
<MsButton @click="showOrganizationModal(record)">{{ t('common.edit') }}</MsButton> <MsButton @click="showAddProjectModal(record)">{{ t('common.edit') }}</MsButton>
<MsButton @click="showAddUserModal(record)">{{ t('system.organization.addMember') }}</MsButton> <MsButton @click="showAddUserModal(record)">{{ t('system.organization.addMember') }}</MsButton>
<MsButton @click="handleEnableOrDisableProject(record, false)">{{ t('common.end') }}</MsButton> <MsButton @click="handleEnableOrDisableProject(record, false)">{{ t('common.end') }}</MsButton>
<MsTableMoreAction :list="tableActions" @select="handleMoreAction($event, record)"></MsTableMoreAction> <MsTableMoreAction :list="tableActions" @select="handleMoreAction($event, record)"></MsTableMoreAction>
@ -36,18 +36,12 @@
</template> </template>
</MsBaseTable> </MsBaseTable>
<AddProjectModal <AddProjectModal
type="edit" :current-project="currentUpdateProject"
:current-organization="currentUpdateOrganization" :visible="addProjectVisible"
:visible="orgVisible" @cancel="handleAddProjectModalCancel"
@cancel="handleAddOrgModalCancel"
/> />
<AddUserModal :project-id="currentProjectId" :visible="userVisible" @cancel="handleAddUserModalCancel" /> <AddUserModal :project-id="currentProjectId" :visible="userVisible" @cancel="handleAddUserModalCancel" />
<UserDrawer <UserDrawer :project-id="currentProjectId" v-bind="currentUserDrawer" @cancel="handleUserDrawerCancel" />
:project-id="currentProjectId"
type="project"
v-bind="currentUserDrawer"
@cancel="handleUserDrawerCancel"
/>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
@ -55,7 +49,7 @@
import useTable from '@/components/pure/ms-table/useTable'; import useTable from '@/components/pure/ms-table/useTable';
import MsBaseTable from '@/components/pure/ms-table/base-table.vue'; import MsBaseTable from '@/components/pure/ms-table/base-table.vue';
import { useTableStore } from '@/store'; import { useTableStore } from '@/store';
import { ref, reactive, watch } from 'vue'; import { ref, reactive } from 'vue';
import type { ActionsItem } from '@/components/pure/ms-table-more-action/types'; import type { ActionsItem } from '@/components/pure/ms-table-more-action/types';
import { import {
postProjectTable, postProjectTable,
@ -71,8 +65,9 @@
import UserDrawer from './userDrawer.vue'; import UserDrawer from './userDrawer.vue';
import AddUserModal from './addUserModal.vue'; import AddUserModal from './addUserModal.vue';
import useModal from '@/hooks/useModal'; import useModal from '@/hooks/useModal';
import { CreateOrUpdateSystemOrgParams } from '@/models/setting/system/orgAndProject'; import { CreateOrUpdateSystemProjectParams } from '@/models/setting/system/orgAndProject';
import AddProjectModal from './addProjectModal.vue'; import AddProjectModal from './addProjectModal.vue';
import { UserItem } from '@/components/bussiness/ms-user-selector/index.vue';
export interface SystemOrganizationProps { export interface SystemOrganizationProps {
keyword: string; keyword: string;
@ -83,9 +78,9 @@
const { t } = useI18n(); const { t } = useI18n();
const tableStore = useTableStore(); const tableStore = useTableStore();
const userVisible = ref(false); const userVisible = ref(false);
const orgVisible = ref(false); const addProjectVisible = ref(false);
const currentProjectId = ref(''); const currentProjectId = ref('');
const currentUpdateOrganization = ref<CreateOrUpdateSystemOrgParams>(); const currentUpdateProject = ref<CreateOrUpdateSystemProjectParams>();
const { openDeleteModal, openModal } = useModal(); const { openDeleteModal, openModal } = useModal();
const organizationColumns: MsTableColumn = [ const organizationColumns: MsTableColumn = [
@ -145,7 +140,6 @@
scroll: { y: 'auto', x: '1300px' }, scroll: { y: 'auto', x: '1300px' },
selectable: false, selectable: false,
noDisable: false, noDisable: false,
debug: true,
size: 'default', size: 'default',
showSetting: true, showSetting: true,
}); });
@ -215,14 +209,17 @@
}); });
}; };
const showOrganizationModal = (record: any) => { const showAddProjectModal = (record: any) => {
currentProjectId.value = record.id; const { id, name, description, enable, adminList, organizationId, moduleIds } = record;
orgVisible.value = true; addProjectVisible.value = true;
currentUpdateOrganization.value = { currentUpdateProject.value = {
id: record.id, id,
name: record.name, name,
description: record.description, description,
memberIds: record.orgAdmins.map((item: any) => item.id) || [], enable,
userIds: adminList.map((item: UserItem) => item.id),
organizationId,
moduleIds,
}; };
}; };
@ -245,8 +242,8 @@
userVisible.value = false; userVisible.value = false;
fetchData(); fetchData();
}; };
const handleAddOrgModalCancel = () => { const handleAddProjectModalCancel = () => {
orgVisible.value = false; addProjectVisible.value = false;
fetchData(); fetchData();
}; };
@ -270,14 +267,6 @@
hideCancel: false, hideCancel: false,
}); });
}; };
watch(
() => props.keyword,
() => {
fetchData();
},
{ immediate: true }
);
defineExpose({ defineExpose({
fetchData, fetchData,
}); });

View File

@ -48,7 +48,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { import {
postUserTableByOrgId, postUserTableByOrgIdOrProjectId,
deleteUserFromOrgOrProject, deleteUserFromOrgOrProject,
} from '@/api/modules/setting/system/organizationAndProject'; } from '@/api/modules/setting/system/organizationAndProject';
import { MsTableColumn } from '@/components/pure/ms-table/type'; import { MsTableColumn } from '@/components/pure/ms-table/type';
@ -95,7 +95,7 @@
{ title: 'system.organization.operation', slotName: 'operation' }, { title: 'system.organization.operation', slotName: 'operation' },
]; ];
const { propsRes, propsEvent, loadList, setLoadListParams, setKeyword } = useTable(postUserTableByOrgId, { const { propsRes, propsEvent, loadList, setLoadListParams, setKeyword } = useTable(postUserTableByOrgIdOrProjectId, {
columns: projectColumn, columns: projectColumn,
showSetting: false, showSetting: false,
scroll: { y: 'auto', x: '600px' }, scroll: { y: 'auto', x: '600px' },
@ -148,6 +148,12 @@
fetchData(); fetchData();
} }
); );
watch(
() => props.projectId,
() => {
fetchData();
}
);
watch( watch(
() => props.visible, () => props.visible,
(visible) => { (visible) => {

View File

@ -33,7 +33,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref } from 'vue'; import { ref, onMounted, watch, nextTick } from 'vue';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import MsCard from '@/components/pure/ms-card/index.vue'; import MsCard from '@/components/pure/ms-card/index.vue';
import AddOrganizationModal from './components/addOrganizationModal.vue'; import AddOrganizationModal from './components/addOrganizationModal.vue';
@ -51,11 +51,31 @@
const projectTabeRef = ref(); const projectTabeRef = ref();
const projectVisible = ref(false); const projectVisible = ref(false);
const tableSearch = () => {
if (currentTable.value === 'organization') {
if (orgTableRef.value) {
orgTableRef.value.fetchData();
} else {
nextTick(() => {
orgTableRef.value?.fetchData();
});
}
} else if (projectTabeRef.value) {
projectTabeRef.value.fetchData();
} else {
nextTick(() => {
projectTabeRef.value?.fetchData();
});
}
};
const handleSearch = (value: string) => { const handleSearch = (value: string) => {
currentKeyword.value = value; currentKeyword.value = value;
tableSearch();
}; };
const handleEnter = (eve: Event) => { const handleEnter = (eve: Event) => {
currentKeyword.value = (eve.target as HTMLInputElement).value; currentKeyword.value = (eve.target as HTMLInputElement).value;
tableSearch();
}; };
const handleAddOrganization = () => { const handleAddOrganization = () => {
@ -67,14 +87,20 @@
}; };
const handleAddProjectCancel = () => { const handleAddProjectCancel = () => {
tableSearch();
projectVisible.value = false; projectVisible.value = false;
}; };
const handleAddOrganizationCancel = () => { const handleAddOrganizationCancel = () => {
if (currentTable.value === 'organization') { tableSearch();
orgTableRef.value?.fetchData();
} else {
projectTabeRef.value?.fetchData();
}
organizationVisible.value = false; organizationVisible.value = false;
}; };
watch(
() => currentTable.value,
() => {
tableSearch();
}
);
onMounted(() => {
tableSearch();
});
</script> </script>

View File

@ -59,4 +59,16 @@ export default {
'system.project.endTitle': 'Close project', 'system.project.endTitle': 'Close project',
'system.project.enableContent': 'The project after opening is displayed in the organization switching list', 'system.project.enableContent': 'The project after opening is displayed in the organization switching list',
'system.project.endContent': 'The project after closing is not displayed in the project switching list', 'system.project.endContent': 'The project after closing is not displayed in the project switching list',
'system.project.projectNamePlaceholder':
'Please enter the project name, which cannot be duplicated with other project names',
'system.project.updateProject': 'Update project',
'system.project.createProject': 'Create project',
'system.project.affiliatedOrg': 'Affiliated organization',
'system.project.affiliatedOrgPlaceholder': 'Please select affiliated organization',
'system.project.projectAdmin': 'Project administrator',
'system.project.projectAdminPlaceholder': 'The project administrator defaults to the person who created the project',
'system.project.moduleSetting': 'Module setting',
'system.project.projectNameRequired': 'Project name cannot be empty',
'system.project.createTip': 'After the project is enabled, it will be displayed in the project switching list',
'system.project.affiliatedOrgRequired': 'Affiliated organization cannot be empty',
}; };

View File

@ -55,4 +55,15 @@ export default {
'system.project.endTitle': '关闭项目', 'system.project.endTitle': '关闭项目',
'system.project.enableContent': '开启后的项目展示在项目切换列表', 'system.project.enableContent': '开启后的项目展示在项目切换列表',
'system.project.endContent': '关闭后的项目不展示在项目切换列表', 'system.project.endContent': '关闭后的项目不展示在项目切换列表',
'system.project.projectNamePlaceholder': '请输入项目名称,不可与其他项目名称重复',
'system.project.updateProject': '更新项目',
'system.project.createProject': '创建项目',
'system.project.affiliatedOrg': '所属组织',
'system.project.affiliatedOrgPlaceholder': '请选择所属组织',
'system.project.projectAdmin': '项目管理员',
'system.project.projectAdminPlaceholder': '默认选择创建项目人为项目管理员',
'system.project.moduleSetting': '模块设置',
'system.project.projectNameRequired': '项目名称不能为空',
'system.project.createTip': '项目启用后,将展示在项目切换列表',
'system.project.affiliatedOrgRequired': '所属组织不能为空',
}; };