Commit 91566d89 authored by 罗超's avatar 罗超

成员管理剩余邀请,导入,转让超级管理员

parent 896ce41b
...@@ -749,6 +749,13 @@ page { ...@@ -749,6 +749,13 @@ page {
bottom: 0; bottom: 0;
z-index: 9; z-index: 9;
} }
.el-dialog{
border-radius: 10px !important;
-webkit-border-radius: 10px !important;
-moz-border-radius: 10px !important;
-ms-border-radius: 10px !important;
-o-border-radius: 10px !important;
}
.opacity0{ .opacity0{
opacity: 0; opacity: 0;
} }
......
...@@ -140,7 +140,8 @@ import { ...@@ -140,7 +140,8 @@ import {
Peoples, Peoples,
Dashboard, Dashboard,
Tag, Tag,
SettingOne SettingOne,
Pencil
} from '@icon-park/vue-next' } from '@icon-park/vue-next'
export interface Icons { export interface Icons {
...@@ -285,7 +286,8 @@ export const icons: Icons = { ...@@ -285,7 +286,8 @@ export const icons: Icons = {
IconPeoples:Peoples, IconPeoples:Peoples,
IconDashBoard:Dashboard, IconDashBoard:Dashboard,
IconTag:Tag, IconTag:Tag,
IconSettingOne:SettingOne IconSettingOne:SettingOne,
IconPencli:Pencil
} }
export default { export default {
......
...@@ -21,5 +21,9 @@ class OrgService{ ...@@ -21,5 +21,9 @@ class OrgService{
static async GetMembersAsync(params:any):Promise<HttpResponse>{ static async GetMembersAsync(params:any):Promise<HttpResponse>{
return Api.Post("travel_manager_members",params) return Api.Post("travel_manager_members",params)
} }
static async GetMembersUsedStatusAsync():Promise<HttpResponse>{
return Api.Post("travel_manager_member_used",{})
}
} }
export default OrgService; export default OrgService;
\ No newline at end of file
...@@ -23,5 +23,15 @@ class UserServices{ ...@@ -23,5 +23,15 @@ class UserServices{
let msg = {pageIndex:1,pageSize:100} let msg = {pageIndex:1,pageSize:100}
return Api.Post("ppt_GetPPTProduct",msg) return Api.Post("ppt_GetPPTProduct",msg)
} }
//
static async SetMemberInfoAsync(nk:string,id:string,ia:0|1|-1):Promise<HttpResponse>{
let msg = {nk,id,ia}
return Api.Post("travel_set_member_info",msg)
}
static async RemoveMemberAsync(id:string):Promise<HttpResponse>{
let msg = {id}
return Api.Post("travel_remove_member",msg)
}
} }
export default UserServices; export default UserServices;
\ No newline at end of file
...@@ -95,7 +95,7 @@ const applyAllSlide = () => { ...@@ -95,7 +95,7 @@ const applyAllSlide = () => {
overflow: hidden; overflow: hidden;
@mixin elAnimation($animationType) { @mixin elAnimation($animationType) {
content: 'PPTist'; content: 'Travel Design';
width: 100%; width: 100%;
height: 100%; height: 100%;
position: absolute; position: absolute;
......
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
<div class="q-mt-xl"> <div class="q-mt-xl">
<div class="user-label text-weight-bold" style="font-size: 16px;">快速管理</div> <div class="user-label text-weight-bold" style="font-size: 16px;">快速管理</div>
<div class="q-mt-lg row"> <div class="q-mt-lg row">
<el-card class="enter-card col" shadow="never"> <el-card class="enter-card col" shadow="never" @click="rediceTo('/a/order')">
<div class="title">快速开票</div> <div class="title">快速开票</div>
<div class="text-small q-mt-md q-mb-lg text-grey-8">开票入口及开票进度查询</div> <div class="text-small q-mt-md q-mb-lg text-grey-8">开票入口及开票进度查询</div>
</el-card> </el-card>
...@@ -94,7 +94,7 @@ ...@@ -94,7 +94,7 @@
<div class="title">团队共享协作</div> <div class="title">团队共享协作</div>
<div class="text-small q-mt-md q-mb-lg text-grey-8">与团队共享内容,文件规范存放,多人协同编辑</div> <div class="text-small q-mt-md q-mb-lg text-grey-8">与团队共享内容,文件规范存放,多人协同编辑</div>
</el-card> </el-card>
<el-card class="enter-card col q-mx-lg" shadow="never"> <el-card class="enter-card col q-mx-lg" shadow="never" @click="rediceTo('/a/u')">
<div class="title">团队成员管理</div> <div class="title">团队成员管理</div>
<div class="text-small q-mt-md q-mb-lg text-grey-8">邀请团队成员,团队私有模板管理</div> <div class="text-small q-mt-md q-mb-lg text-grey-8">邀请团队成员,团队私有模板管理</div>
</el-card> </el-card>
...@@ -112,6 +112,7 @@ import { ENT_USER_THEME, VIP_USER_THEME } from "@/configs/customer"; ...@@ -112,6 +112,7 @@ import { ENT_USER_THEME, VIP_USER_THEME } from "@/configs/customer";
import { useUserStore } from "@/store"; import { useUserStore } from "@/store";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import { ref } from "vue"; import { ref } from "vue";
import { useRouter } from "vue-router";
const useUser = useUserStore() const useUser = useUserStore()
const { userInfo } = storeToRefs(useUser) const { userInfo } = storeToRefs(useUser)
...@@ -119,7 +120,11 @@ const userTheme = useUser.getUserTheme ...@@ -119,7 +120,11 @@ const userTheme = useUser.getUserTheme
console.log(userTheme) console.log(userTheme)
const vipTheme = VIP_USER_THEME const vipTheme = VIP_USER_THEME
const enTheme = ENT_USER_THEME const enTheme = ENT_USER_THEME
const router = useRouter()
const rediceTo = (path:string)=>{
router.push({path})
}
</script> </script>
<style scoped> <style scoped>
...@@ -158,5 +163,7 @@ const enTheme = ENT_USER_THEME ...@@ -158,5 +163,7 @@ const enTheme = ENT_USER_THEME
font-size: 15px; font-size: 15px;
font-weight: bold; font-weight: bold;
color: #000; color: #000;
user-select: none;
cursor: pointer;
} }
</style> </style>
\ No newline at end of file
<template> <template>
<div class="full-height full-width column"> <div class="full-height full-width column" ref="memberListRef">
<div class="row items-center"> <div class="row items-center">
<div class="text-dark text-weight-bolder col">成员管理</div> <div class="text-dark text-weight-bolder col">成员管理</div>
<el-button class="ppt-button" type="primary">邀请成员</el-button> <el-button class="ppt-button" type="primary">邀请成员</el-button>
...@@ -18,14 +18,22 @@ ...@@ -18,14 +18,22 @@
<el-table class="dark-table" v-load-more="tableScrollHandler" :data="data" style="width: 100%" height="100%" v-loading="loading"> <el-table class="dark-table" v-load-more="tableScrollHandler" :data="data" style="width: 100%" height="100%" v-loading="loading">
<el-table-column width="248"> <el-table-column width="248">
<template #header> <template #header>
<span style="padding-left: 42px;">企业成员 ({{ currentMember }}/{{ 500 }})</span> <span style="padding-left: 42px;">企业成员 ({{ used[0] }}/{{ used[1] }})</span>
</template> </template>
<template #default="scope"> <template #default="scope">
<div class="row items-center"> <div class="row items-center">
<el-avatar shape="square" :src="scope.row.photo.includes('http://')||scope.row.photo.includes('https://')?scope.row.photo:USER_DEFAULT_HEADER" :size="32"></el-avatar> <el-avatar shape="square" :src="scope.row.photo.includes('http://')||scope.row.photo.includes('https://')?scope.row.photo:USER_DEFAULT_HEADER" :size="32"></el-avatar>
<span class="q-ml-md"> <div class="col row items-center user-nickname" v-if="editorTarget!=scope.row.id">
{{ scope.row.name }} <span class="q-ml-md">
</span> {{ scope.row.name }} {{ scope.row.ism?'(我自己)':'' }}
</span>
<IconPencli size="14" style="color:#000;" class="q-ml-md cusor-pointer editor-pencli" @click="setNickNameHandler(scope.row)"></IconPencli>
</div>
<div class="col row items-center" v-else>
<el-input v-model="nickNameModel" placeholder="请输入用户昵称" size="small" class="col q-ml-md" />
<el-button link size="small" class="q-ml-sm" type="primary" @click="setMemberNickName(scope.row)">确认</el-button>
<el-button link size="small" style="margin-left: 5px;" @click="setNickNameHandler">取消</el-button>
</div>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
...@@ -46,8 +54,8 @@ ...@@ -46,8 +54,8 @@
</div> </div>
</template> </template>
<el-menu mode="vertical" class="no-border md-menu"> <el-menu mode="vertical" class="no-border md-menu">
<el-menu-item index="1">设为管理员</el-menu-item> <el-menu-item index="1" :disabled="scope.row.isa" @click="setMemberManagerStatus(scope.row,1)">设为管理员</el-menu-item>
<el-menu-item index="2">设为成员</el-menu-item> <el-menu-item index="2" :disabled="!scope.row.isa" @click="setMemberManagerStatus(scope.row,0)">设为成员</el-menu-item>
</el-menu> </el-menu>
</el-popover> </el-popover>
</template> </template>
...@@ -55,18 +63,35 @@ ...@@ -55,18 +63,35 @@
<el-table-column prop="" label="操作" width="150"> <el-table-column prop="" label="操作" width="150">
<template #default="scope"> <template #default="scope">
<el-button v-if="scope.row.ic" link type="primary" class="ppt-button">转让</el-button> <el-button v-if="scope.row.ic" link type="primary" class="ppt-button">转让</el-button>
<el-button v-else link type="primary" class="ppt-button">移除</el-button> <el-button v-else link type="primary" class="ppt-button" @click="removeMemeberHandler(scope.row)">移除</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</div> </div>
</div> </div>
<el-dialog v-model="removeVisible" title="移除成员" style="width:400px;">
<main>
<el-alert type="warning" show-icon :closable="false">
<template #title>
<span class="text-normal text-dark">你正在移除成员<span class="text-weight-bolder">{{ removeMemberModel.name }}</span>,移除后,该成员将无法访问本团队/企业,其在「我的空间」中的所有内容将被清空,且不可恢复,请谨慎操作</span>
</template>
</el-alert>
<div class="text-dark q-my-md">如确认移除成员并清空内容,请输入「移除并清空」</div>
<el-input v-model="removeTokenStr" size="large" class="full-width" input-style="font-family:pingfangr" placeholder="请输入:移除并清空" />
</main>
<template #footer>
<el-button @click="removeVisible = false" size="large" class="ppt-button" :disabled="loading">我再想想</el-button>
<el-button :type="removeTokenStr!='移除并清空'?'info':'primary'" size="large" @click="removeMember" :disabled="removeTokenStr!='移除并清空' || loading" class="ppt-button text-grey-8">移除并清空</el-button>
</template>
</el-dialog>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ApiResult } from "@/configs/axios"; import { ApiResult } from "@/configs/axios";
import { USER_DEFAULT_HEADER } from "@/configs/customer"; import { USER_DEFAULT_HEADER } from "@/configs/customer";
import OrgService from "@/services/OrgService"; import OrgService from "@/services/OrgService";
import UserServices from "@/services/UserService";
import { ElLoading, ElMessage } from "element-plus";
import { ref } from "vue"; import { ref } from "vue";
const userGroup = ref<{id:number,name:string}[]>([ const userGroup = ref<{id:number,name:string}[]>([
...@@ -77,47 +102,116 @@ const userGroup = ref<{id:number,name:string}[]>([ ...@@ -77,47 +102,116 @@ const userGroup = ref<{id:number,name:string}[]>([
const data = ref<any[]>([]) const data = ref<any[]>([])
const loading = ref(false) const loading = ref(false)
const pageCount = ref(0) const pageCount = ref(0)
const currentMember= ref(0) const used = ref<number[]>([0,0])
const memberListRef = ref()
const editorTarget = ref('')
const nickNameModel = ref('')
const removeVisible = ref(false)
const removeTokenStr = ref('')
const removeMemberModel = ref<any>()
const parameters = ref<any>({ const parameters = ref<any>({
t:0, t:0,
k:'', k:'',
pageIndex:1, pageIndex:1,
pageSize:20 pageSize:20
}) })
const setNickNameHandler = (target:any) =>{
if(target){
editorTarget.value = target.id
nickNameModel.value = target.name
}else{
editorTarget.value = ''
nickNameModel.value = ''
}
}
const getMembers = async ()=>{ const getMembers = async ()=>{
if(loading.value) return if(loading.value) return
loading.value=true loading.value=true
//data.value = [] //data.value = []
//currentMember.value = 0,
//pageCount.value = 0 //pageCount.value = 0
const response = await OrgService.GetMembersAsync(parameters.value) const response = await OrgService.GetMembersAsync(parameters.value)
if(response.data.resultCode == ApiResult.SUCCESS && response.data.data.pageData){ if(response.data.resultCode == ApiResult.SUCCESS && response.data.data.pageData){
data.value = data.value.concat(response.data.data.pageData) data.value = data.value.concat(response.data.data.pageData)
currentMember.value = response.data.data.count
pageCount.value = response.data.data.pageCount pageCount.value = response.data.data.pageCount
} }
loading.value=false loading.value=false
} }
const removeMemeberHandler = (target:any)=>{
removeMemberModel.value=target
removeVisible.value=true
removeTokenStr.value=''
}
const getMemberUsedStatus = async ()=>{
const response = await OrgService.GetMembersUsedStatusAsync()
if(response.data.resultCode == ApiResult.SUCCESS){
used.value = response.data.data
}
}
const changeSearch = ()=>{ const changeSearch = ()=>{
data.value = [] data.value = []
currentMember.value = 0
pageCount.value = 0 pageCount.value = 0
parameters.value.pageIndex=1 parameters.value.pageIndex=1
getMembers() getMembers()
} }
const setMemberManagerStatus = async (target:any,value:0|1)=>{
memberListRef.value.click()
if(loading.value) return
loading.value=true
const response = await UserServices.SetMemberInfoAsync('',target.id,value)
if(response.data.resultCode == ApiResult.SUCCESS){
ElMessage.success({message:'更新成功'})
target.isa =value==1
}else{
ElMessage.error({message:'更新失败'})
}
loading.value=false
}
const setMemberNickName = async (target:any)=>{
if(loading.value || nickNameModel.value=='') return
loading.value=true
const response = await UserServices.SetMemberInfoAsync(nickNameModel.value,target.id,-1)
if(response.data.resultCode == ApiResult.SUCCESS){
ElMessage.success({message:'更新成功'})
target.name =nickNameModel.value
setNickNameHandler(null)
}else{
ElMessage.error({message:'更新失败'})
}
loading.value=false
}
const tableScrollHandler = ()=>{ const tableScrollHandler = ()=>{
if(pageCount.value>parameters.value.pageIndex){ if(pageCount.value>parameters.value.pageIndex){
parameters.value.pageIndex++ parameters.value.pageIndex++
getMembers() getMembers()
} }
} }
const removeMember = async ()=>{
removeVisible.value = false
const loadingInstanct = ElLoading.service({text:'正在删除用户数据'})
const response = await UserServices.RemoveMemberAsync(removeMemberModel.value.id)
if(response.data.resultCode == ApiResult.SUCCESS){
ElMessage.success({message:'用户已被移除团队/企业'})
}else{
ElMessage.error({message:'移除失败'})
}
loadingInstanct.close()
changeSearch()
getMemberUsedStatus()
}
getMembers() getMembers()
getMemberUsedStatus()
</script> </script>
<style> <style>
...@@ -130,4 +224,10 @@ getMembers() ...@@ -130,4 +224,10 @@ getMembers()
border-color: #e8eaec; border-color: #e8eaec;
color:#000; color:#000;
} }
.user-nickname .editor-pencli{
visibility: hidden;
}
.user-nickname:hover .editor-pencli{
visibility:visible;
}
</style> </style>
\ No newline at end of file
...@@ -50,8 +50,8 @@ module.exports = { ...@@ -50,8 +50,8 @@ module.exports = {
msTileImage: null, msTileImage: null,
}, },
manifestOptions: { manifestOptions: {
name: 'PPTist', name: 'Travel Design',
short_name: 'PPTist', short_name: 'Travel_Design',
theme_color: '#564bec', theme_color: '#564bec',
icons: [{ icons: [{
src: 'icons/android-chrome-192x192.png', src: 'icons/android-chrome-192x192.png',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment