feat: 团队管理
This commit is contained in:
parent
ddb7344828
commit
0592d70f97
@ -13,10 +13,10 @@ const getTeamMember: () => Promise<Result<TeamMember[]>> = () => {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加成员
|
* 添加成员
|
||||||
* @param 参数 { "username_or_email": "string" }
|
* @param 参数 []
|
||||||
*/
|
*/
|
||||||
const postCreatTeamMember: (data: String) => Promise<Result<boolean>> = (data) => {
|
const postCreatTeamMember: (data: Array<String>) => Promise<Result<boolean>> = (data) => {
|
||||||
return post(`${prefix}`, { username_or_email: data })
|
return post(`${prefix}/_batch`, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,7 +58,6 @@ const putMemberPermissions: (member_id: String, body: any) => Promise<Result<any
|
|||||||
return put(`${prefix}/${member_id}`, body)
|
return put(`${prefix}/${member_id}`, body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getTeamMember,
|
getTeamMember,
|
||||||
postCreatTeamMember,
|
postCreatTeamMember,
|
||||||
|
|||||||
@ -112,6 +112,18 @@ const resetPassword: (
|
|||||||
return post('/user/re_password', request, undefined, loading)
|
return post('/user/re_password', request, undefined, loading)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加团队需要查询用户列表
|
||||||
|
* @param loading 接口加载器
|
||||||
|
* email_or_username
|
||||||
|
*/
|
||||||
|
const getUserList: (email_or_username: string, loading?: Ref<boolean>) => Promise<Result<any>> = (
|
||||||
|
email_or_username,
|
||||||
|
loading
|
||||||
|
) => {
|
||||||
|
return get('/user/list', { email_or_username }, loading)
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
login,
|
login,
|
||||||
register,
|
register,
|
||||||
@ -121,5 +133,6 @@ export default {
|
|||||||
resetPassword,
|
resetPassword,
|
||||||
sendEmailToCurrent,
|
sendEmailToCurrent,
|
||||||
resetCurrentUserPassword,
|
resetCurrentUserPassword,
|
||||||
logout
|
logout,
|
||||||
|
getUserList
|
||||||
}
|
}
|
||||||
|
|||||||
@ -74,24 +74,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (min-width: 1400px) {
|
// @media only screen and (min-width: 1400px) {
|
||||||
.app-list-row {
|
// .app-list-row {
|
||||||
.el-col-lg-6 {
|
// .el-col-lg-6 {
|
||||||
display: block;
|
// display: block;
|
||||||
max-width: 20.8333333333%;
|
// max-width: 20.8333333333%;
|
||||||
flex: 0 0 20.8333333333%;
|
// flex: 0 0 20.8333333333%;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
@media only screen and (min-width: 1920px) {
|
// @media only screen and (min-width: 1920px) {
|
||||||
.app-list-row {
|
// .app-list-row {
|
||||||
.el-col-xl-4 {
|
// .el-col-xl-4 {
|
||||||
display: block;
|
// display: block;
|
||||||
max-width: 16.6666666667%;
|
// max-width: 16.6666666667%;
|
||||||
flex: 0 0 16.6666666667%;
|
// flex: 0 0 16.6666666667%;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
.el-card {
|
.el-card {
|
||||||
--el-card-padding: calc(var(--app-base-px) * 2);
|
--el-card-padding: calc(var(--app-base-px) * 2);
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<LayoutContainer header="概览" back-to="-1">
|
<LayoutContainer header="概览">
|
||||||
<div class="main-calc-height p-24">
|
<div class="main-calc-height p-24">
|
||||||
<h4 class="title-decoration-1 mb-16">应用信息</h4>
|
<h4 class="title-decoration-1 mb-16">应用信息</h4>
|
||||||
<el-card shadow="never" class="overview-card">
|
<el-card shadow="never" class="overview-card">
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<LayoutContainer :header="id ? '设置' : '创建应用'" back-to="-1" class="create-application">
|
<LayoutContainer
|
||||||
|
:header="id ? '设置' : '创建应用'"
|
||||||
|
:back-to="id ? '' : -1"
|
||||||
|
class="create-application"
|
||||||
|
>
|
||||||
<el-row v-loading="loading">
|
<el-row v-loading="loading">
|
||||||
<el-col :span="10">
|
<el-col :span="10">
|
||||||
<div class="p-24 mb-16" style="padding-bottom: 0">
|
<div class="p-24 mb-16" style="padding-bottom: 0">
|
||||||
|
|||||||
@ -75,7 +75,7 @@ const dayOptions = [
|
|||||||
label: '过去90天'
|
label: '过去90天'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 188,
|
value: 183,
|
||||||
label: '过去半年'
|
label: '过去半年'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
>
|
>
|
||||||
<el-form-item label="用户名/邮箱" prop="users">
|
<el-form-item label="用户名/邮箱" prop="users">
|
||||||
<el-select
|
<el-select
|
||||||
|
ref="SelectRemoteRef"
|
||||||
class="custom-select-multiple"
|
class="custom-select-multiple"
|
||||||
v-model="memberForm.users"
|
v-model="memberForm.users"
|
||||||
multiple
|
multiple
|
||||||
@ -28,14 +29,16 @@
|
|||||||
remote
|
remote
|
||||||
reserve-keyword
|
reserve-keyword
|
||||||
placeholder="请输入成员的用户名或邮箱"
|
placeholder="请输入成员的用户名或邮箱"
|
||||||
|
no-data-text="用户不存在"
|
||||||
:remote-method="remoteMethod"
|
:remote-method="remoteMethod"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
|
@change="changeSelectHandle"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in options"
|
v-for="item in userOptions"
|
||||||
:key="item.value"
|
:key="item?.id"
|
||||||
:label="item.label"
|
:label="item?.username"
|
||||||
:value="item.value"
|
:value="item?.id"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -53,115 +56,55 @@ import { ref, watch, onMounted } from 'vue'
|
|||||||
import type { FormInstance, FormRules } from 'element-plus'
|
import type { FormInstance, FormRules } from 'element-plus'
|
||||||
import { MsgSuccess } from '@/utils/message'
|
import { MsgSuccess } from '@/utils/message'
|
||||||
import TeamApi from '@/api/team'
|
import TeamApi from '@/api/team'
|
||||||
|
import UserApi from '@/api/user'
|
||||||
interface ListItem {
|
|
||||||
value: string
|
|
||||||
label: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const states = [
|
|
||||||
'Alabama',
|
|
||||||
'Alaska',
|
|
||||||
'Arizona',
|
|
||||||
'Arkansas',
|
|
||||||
'California',
|
|
||||||
'Colorado',
|
|
||||||
'Connecticut',
|
|
||||||
'Delaware',
|
|
||||||
'Florida',
|
|
||||||
'Georgia',
|
|
||||||
'Hawaii',
|
|
||||||
'Idaho',
|
|
||||||
'Illinois',
|
|
||||||
'Indiana',
|
|
||||||
'Iowa',
|
|
||||||
'Kansas',
|
|
||||||
'Kentucky',
|
|
||||||
'Louisiana',
|
|
||||||
'Maine',
|
|
||||||
'Maryland',
|
|
||||||
'Massachusetts',
|
|
||||||
'Michigan',
|
|
||||||
'Minnesota',
|
|
||||||
'Mississippi',
|
|
||||||
'Missouri',
|
|
||||||
'Montana',
|
|
||||||
'Nebraska',
|
|
||||||
'Nevada',
|
|
||||||
'New Hampshire',
|
|
||||||
'New Jersey',
|
|
||||||
'New Mexico',
|
|
||||||
'New York',
|
|
||||||
'North Carolina',
|
|
||||||
'North Dakota',
|
|
||||||
'Ohio',
|
|
||||||
'Oklahoma',
|
|
||||||
'Oregon',
|
|
||||||
'Pennsylvania',
|
|
||||||
'Rhode Island',
|
|
||||||
'South Carolina',
|
|
||||||
'South Dakota',
|
|
||||||
'Tennessee',
|
|
||||||
'Texas',
|
|
||||||
'Utah',
|
|
||||||
'Vermont',
|
|
||||||
'Virginia',
|
|
||||||
'Washington',
|
|
||||||
'West Virginia',
|
|
||||||
'Wisconsin',
|
|
||||||
'Wyoming'
|
|
||||||
]
|
|
||||||
|
|
||||||
const emit = defineEmits(['refresh'])
|
const emit = defineEmits(['refresh'])
|
||||||
|
|
||||||
const dialogVisible = ref<boolean>(false)
|
const dialogVisible = ref<boolean>(false)
|
||||||
|
|
||||||
const memberForm = ref({
|
const memberForm = ref({
|
||||||
users: [],
|
users: []
|
||||||
user: ''
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const options = ref<ListItem[]>([])
|
const SelectRemoteRef = ref()
|
||||||
const list = ref<ListItem[]>([])
|
|
||||||
|
|
||||||
const addMemberFormRef = ref<FormInstance>()
|
const addMemberFormRef = ref<FormInstance>()
|
||||||
|
|
||||||
const loading = ref<boolean>(false)
|
const loading = ref<boolean>(false)
|
||||||
|
const userOptions = ref([])
|
||||||
|
|
||||||
const validateUsers = (rule: any, value: any, callback: any) => {
|
|
||||||
if (value?.length == 0 && !memberForm.value.user) {
|
|
||||||
callback(new Error('请输入用户名/邮箱'))
|
|
||||||
} else {
|
|
||||||
callback()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const rules = ref<FormRules>({
|
const rules = ref<FormRules>({
|
||||||
users: [{ type: 'array', validator: validateUsers }]
|
users: [
|
||||||
|
{
|
||||||
|
type: 'array',
|
||||||
|
required: true,
|
||||||
|
message: '请输入用户名/邮箱',
|
||||||
|
trigger: 'change'
|
||||||
|
}
|
||||||
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(dialogVisible, (bool) => {
|
watch(dialogVisible, (bool) => {
|
||||||
if (!bool) {
|
if (!bool) {
|
||||||
memberForm.value = {
|
memberForm.value = {
|
||||||
users: [],
|
users: []
|
||||||
user: ''
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const remoteMethod = (query: string) => {
|
const remoteMethod = (query: string) => {
|
||||||
if (query) {
|
if (query) {
|
||||||
loading.value = true
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
loading.value = false
|
getUser(query)
|
||||||
options.value = list.value.filter((item) => {
|
|
||||||
return item.label.toLowerCase().includes(query.toLowerCase())
|
|
||||||
})
|
|
||||||
}, 200)
|
}, 200)
|
||||||
} else {
|
} else {
|
||||||
options.value = []
|
userOptions.value = []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const changeSelectHandle = () => {
|
||||||
|
SelectRemoteRef.value.query = ''
|
||||||
|
}
|
||||||
|
|
||||||
const open = () => {
|
const open = () => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
}
|
}
|
||||||
@ -170,10 +113,7 @@ const submitMember = async (formEl: FormInstance | undefined) => {
|
|||||||
await formEl.validate((valid, fields) => {
|
await formEl.validate((valid, fields) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
const submitValue: string = memberForm.value.users?.length
|
TeamApi.postCreatTeamMember(memberForm.value.users).then(() => {
|
||||||
? memberForm.value.users.toString()
|
|
||||||
: memberForm.value.user
|
|
||||||
TeamApi.postCreatTeamMember(submitValue).then(() => {
|
|
||||||
MsgSuccess('提交成功')
|
MsgSuccess('提交成功')
|
||||||
emit('refresh')
|
emit('refresh')
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
@ -184,11 +124,13 @@ const submitMember = async (formEl: FormInstance | undefined) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
const getUser = (val: string) => {
|
||||||
list.value = states.map((item) => {
|
UserApi.getUserList(val, loading).then((res) => {
|
||||||
return { value: `value:${item}`, label: `label:${item}` }
|
userOptions.value = res.data
|
||||||
})
|
})
|
||||||
})
|
}
|
||||||
|
|
||||||
|
onMounted(() => {})
|
||||||
|
|
||||||
defineExpose({ open, close })
|
defineExpose({ open, close })
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="管理" align="center">
|
<el-table-column label="管理" align="center" width="60">
|
||||||
<!-- <template #header>
|
<!-- <template #header>
|
||||||
<el-checkbox
|
<el-checkbox
|
||||||
v-model="allChecked[MANAGE]"
|
v-model="allChecked[MANAGE]"
|
||||||
@ -32,7 +32,7 @@
|
|||||||
<el-checkbox v-model="row.operate[MANAGE]" @change="checkedOperateChange(MANAGE, row)" />
|
<el-checkbox v-model="row.operate[MANAGE]" @change="checkedOperateChange(MANAGE, row)" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="使用" align="center">
|
<el-table-column label="使用" align="center" width="60">
|
||||||
<!-- <template #header>
|
<!-- <template #header>
|
||||||
<el-checkbox
|
<el-checkbox
|
||||||
v-model="allChecked[USE]"
|
v-model="allChecked[USE]"
|
||||||
|
|||||||
@ -22,7 +22,6 @@
|
|||||||
<div>
|
<div>
|
||||||
<span class="mr-8">{{ row.username }}</span>
|
<span class="mr-8">{{ row.username }}</span>
|
||||||
<el-tag v-if="isManage(row.type)" class="default-tag">所有者</el-tag>
|
<el-tag v-if="isManage(row.type)" class="default-tag">所有者</el-tag>
|
||||||
<el-tag type="warning" v-else>用户</el-tag>
|
|
||||||
</div>
|
</div>
|
||||||
<div @click.stop style="margin-top: 5px">
|
<div @click.stop style="margin-top: 5px">
|
||||||
<el-dropdown trigger="click" v-if="!isManage(row.type)">
|
<el-dropdown trigger="click" v-if="!isManage(row.type)">
|
||||||
@ -71,7 +70,7 @@ import type { TeamMember } from '@/api/type/team'
|
|||||||
import CreateMemberDialog from './component/CreateMemberDialog.vue'
|
import CreateMemberDialog from './component/CreateMemberDialog.vue'
|
||||||
import PermissionSetting from './component/PermissionSetting.vue'
|
import PermissionSetting from './component/PermissionSetting.vue'
|
||||||
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||||
import { DATASET, APPLICATION} from './utils'
|
import { DATASET, APPLICATION } from './utils'
|
||||||
|
|
||||||
const CreateMemberRef = ref<InstanceType<typeof CreateMemberDialog>>()
|
const CreateMemberRef = ref<InstanceType<typeof CreateMemberDialog>>()
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
>
|
>
|
||||||
<el-breadcrumb-item
|
<el-breadcrumb-item
|
||||||
><span class="active-breadcrumb">{{
|
><span class="active-breadcrumb">{{
|
||||||
`添加 ${providerValue?.name} 模型`
|
`添加 ${providerValue?.name}`
|
||||||
}}</span></el-breadcrumb-item
|
}}</span></el-breadcrumb-item
|
||||||
>
|
>
|
||||||
</el-breadcrumb>
|
</el-breadcrumb>
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
<el-breadcrumb separator=">">
|
<el-breadcrumb separator=">">
|
||||||
<el-breadcrumb-item
|
<el-breadcrumb-item
|
||||||
><span class="active-breadcrumb">{{
|
><span class="active-breadcrumb">{{
|
||||||
`编辑 ${providerValue?.name} 模型`
|
`编辑 ${providerValue?.name}`
|
||||||
}}</span></el-breadcrumb-item
|
}}</span></el-breadcrumb-item
|
||||||
>
|
>
|
||||||
</el-breadcrumb>
|
</el-breadcrumb>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user