feat: 团队管理

This commit is contained in:
wangdan-fit2cloud 2023-12-05 16:30:22 +08:00
parent ddb7344828
commit 0592d70f97
11 changed files with 80 additions and 123 deletions

View File

@ -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,

View File

@ -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
} }

View File

@ -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);

View File

@ -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">

View File

@ -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">

View File

@ -75,7 +75,7 @@ const dayOptions = [
label: '过去90天' label: '过去90天'
}, },
{ {
value: 188, value: 183,
label: '过去半年' label: '过去半年'
} }
] ]

View File

@ -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>

View File

@ -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]"

View File

@ -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)

View File

@ -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>

View File

@ -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>