Browse Source

Merge branch 'space2'

qin_26
han2015 2 months ago
parent
commit
284168f5b0
  1. 16
      src/api/doc/space.ts
  2. 20
      src/store/modules/orgMember.ts
  3. 122
      src/views/doc/agent.vue
  4. 58
      src/views/doc/manage.vue
  5. 28
      src/views/doc/onlyoffice.vue
  6. 4
      src/views/doc/recentVisited.vue
  7. 113
      src/views/doc/space.vue
  8. 103
      src/views/doc/spacePermission.vue

16
src/api/doc/space.ts

@ -74,6 +74,22 @@ export function doDelSpace(uid:string,data?: any){
}); });
} }
/**
*
*/
export function spaceMatterRename(uid:string,data?: any){
return request({
url: '/hxpan/api/space/rename',
method: 'post',
headers: {
'Identifier':uid,
'Content-Type': 'application/x-www-form-urlencoded'
},
data: data
});
}
/** /**
* *
*/ */

20
src/store/modules/orgMember.ts

@ -1,33 +1,35 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { ref} from 'vue'; import { ref} from 'vue';
import request from "@/utils/request"; import request from "@/utils/request";
import { id } from 'element-plus/es/locale';
export const useOrgMemberStore = defineStore('orgMember', () => { export const useOrgMemberStore = defineStore('orgMember', () => {
interface OrgMemberItem { interface OrgMemberItem {
id: string; id: string;
label: string; name: string;
children?:OrgMemberItem[]; child?:OrgMemberItem[];
} }
const listMap = ref<Record<string, string>>({}) const listMap = ref<Record<string, string>>({})
const dataTree = ref<OrgMemberItem>({ id: '', label: '', children: [] }) const dataTree = ref<OrgMemberItem>({ id: '', name: '', child: [] })
async function init() { async function init() {
await request({ await request({
url: "/javasys/lowCode/transfer/getOrgAndManTree", url: "/systemapi/app/get_org_everyone_people",//"172.20.2.87:39168",
method: "post", method: "post",
data:{id:"313",all: 1}
}).then((response) => { }).then((response) => {
// assuming response.data is an array of OrgMemberItem // assuming response.data is an array of OrgMemberItem
dataTree.value=response.data dataTree.value={id:"313",name:"集团公司",child:response.data}
handleChildren(response.data.children) handleChildren(response.data)
}); });
} }
function handleChildren(childs:any[]){ function handleChildren(childs:any[]){
childs.forEach(item => { childs.forEach(item => {
listMap.value[item.id] = item.label; listMap.value[item.id] = item.name;
if(item.children){ if(item.child){
handleChildren(item.children) handleChildren(item.child)
} }
}); });
} }

122
src/views/doc/agent.vue

@ -26,7 +26,7 @@ const inputState=ref(true)
const conversations=ref<chatRecord[]>([]) const conversations=ref<chatRecord[]>([])
const centHoverItem=ref("") const centHoverItem=ref("")
const interact_msg=ref<{ask:boolean,think:string,content:string}[]>([]) const interact_msg=ref<{ask:boolean,think:string,content:string,docinfo?:any[]}[]>([])
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
userid:string, userid:string,
closefunc:()=>void, closefunc:()=>void,
@ -75,7 +75,7 @@ async function onSendTextToAI(){
}else{ }else{
interact_msg.value.push({ask:true,think:"", content:myquestion.value}) interact_msg.value.push({ask:true,think:"", content:myquestion.value})
} }
let docinfo:any=[]
controller.value = new AbortController(); controller.value = new AbortController();
try{ try{
const res= await doAiChat(`${baseURL}/aibot/agents/${props.agent.uuid}/chat`,{ const res= await doAiChat(`${baseURL}/aibot/agents/${props.agent.uuid}/chat`,{
@ -98,7 +98,6 @@ async function onSendTextToAI(){
let chunk = ''; // let chunk = ''; //
while (true) { while (true) {
const {done, value} = await reader.read() const {done, value} = await reader.read()
if (done) break;
// //
chunk += decoder.decode(value, {stream: true}); chunk += decoder.decode(value, {stream: true});
@ -112,9 +111,13 @@ async function onSendTextToAI(){
if(json.event==="message"){ if(json.event==="message"){
conversation.value=json.conversation_id conversation.value=json.conversation_id
respMsg.value+=json.answer respMsg.value+=json.answer
}else if(json.event==="message_end"){
docinfo=json.metadata.retriever_resources
} }
} }
} }
if (done) break;//
} }
}catch (e: any) { }catch (e: any) {
if (e.name === 'AbortError') { if (e.name === 'AbortError') {
@ -126,14 +129,13 @@ async function onSendTextToAI(){
const arr=respMsg.value.split("</think>") const arr=respMsg.value.split("</think>")
if(arr.length===1){ if(arr.length===1){
interact_msg.value.push({ask:false,think:"",content:arr[0]}) interact_msg.value.push({ask:false,think:"",content:arr[0],docinfo:docinfo})
}else{ }else{
// //
interact_msg.value.push({ask:false,think:arr[0],content:arr[1]}) interact_msg.value.push({ask:false,think:arr[0],content:arr[1],docinfo:docinfo})
} }
respMsg.value="" respMsg.value=""
setAiChat({ setAiChat({
"userid":atob(props.userid), "userid":atob(props.userid),
"uuid":conversation.value, "uuid":conversation.value,
@ -180,6 +182,16 @@ function handleMouseLeave(){
} }
function newContext(){ function newContext(){
const c =conversations.value.find(c=>c.uuid==conversation.value)
if(!c){
conversations.value.push({
"agentuuid":props.agent.uuid,
"uuid":conversation.value,
"brief":interact_msg.value[0].content,
"messages":interact_msg.value
})
}
inputState.value=true inputState.value=true
interact_msg.value=[] interact_msg.value=[]
conversation.value="" conversation.value=""
@ -192,6 +204,13 @@ function resetContext(){
props.closefunc() props.closefunc()
} }
//ai
function formatRefContent(content:string){
let result=content.replaceAll(/"/g,'')
result=result.replaceAll(/Unnamed: /g,' ')
return result
}
// //
onMounted(() => { onMounted(() => {
loadKnownLibList() loadKnownLibList()
@ -212,7 +231,8 @@ onMounted(() => {
<li class="action_menu" @click="newContext"> <li class="action_menu" @click="newContext">
新建会话 新建会话
</li> </li>
<li class="list_item" v-for="item in conversations" @mouseover="handleMouseEnter(item)" @mouseleave="handleMouseLeave()" @click="showChat(item.uuid)">{{ item.brief }} <li class="list_item" v-for="item in conversations" @mouseover="handleMouseEnter(item)" @mouseleave="handleMouseLeave()" @click="showChat(item.uuid)">
<span>{{ item.brief }}</span>
<el-button v-show="centHoverItem == item.uuid" icon="Delete" size="small" circle @click="(e)=>{e.stopPropagation();onDelChat(item.uuid)}"></el-button> <el-button v-show="centHoverItem == item.uuid" icon="Delete" size="small" circle @click="(e)=>{e.stopPropagation();onDelChat(item.uuid)}"></el-button>
</li> </li>
</ul> </ul>
@ -224,6 +244,15 @@ onMounted(() => {
<div v-else class="t_resp"> <div v-else class="t_resp">
<el-text style="white-space: pre-line" v-html="msg.think"></el-text> <el-text style="white-space: pre-line" v-html="msg.think"></el-text>
<VueMarkdown :markdown="msg.content" :rehype-plugins="[rehypeRaw]" :remark-plugins="[remarkGfm]" ></VueMarkdown> <VueMarkdown :markdown="msg.content" :rehype-plugins="[rehypeRaw]" :remark-plugins="[remarkGfm]" ></VueMarkdown>
<div v-if="msg.docinfo?.length>0" class="doc_ref">
引用<hr>
<el-tooltip v-for="doc in msg.docinfo" placement="top" effect="dark">
<template #content>
<div v-html="formatRefContent(doc.content)" />
</template>
<span>{{doc.document_name}}</span>
</el-tooltip>
</div>
</div> </div>
</template> </template>
@ -306,14 +335,38 @@ onMounted(() => {
background-color: #dddddd; background-color: #dddddd;
padding: 10px 8px; padding: 10px 8px;
margin: 3px 14px 3px 0; margin: 3px 14px 3px 0;
overflow: hidden;
text-overflow: ellipsis;
border-radius: 8px; border-radius: 8px;
text-wrap-mode: nowrap; span{
width: 90%;
overflow: hidden;
text-overflow: ellipsis;
text-wrap-mode: nowrap;
}
button{ button{
margin-left: auto; margin-left: auto;
} }
} }
.doc_ref{
margin: 16px;
display: flex;
flex-wrap: wrap;
hr{
width: 90%;
margin: inherit;
border: none;
border-top: .5px solid rgb(26 25 25 / 23%);
}
span{
width: 300px;
overflow: hidden;
text-overflow: ellipsis;
text-wrap-mode: nowrap;
margin: 2px 10px;
padding: 0 10px;
background-color: #d7d5d5;
border-radius: 6px;
}
}
</style> </style>
<style> <style>
@ -322,4 +375,53 @@ onMounted(() => {
margin-bottom: 8px; margin-bottom: 8px;
display: block; display: block;
} }
.t_resp{
h2,h3,h4,h5{
margin: 12px 0;
}
p{
margin-left: 16px;
}
p+ul{
margin-left: 56px;
}
li p{
margin-left: 0;
}
ol{
margin-left: 14px;
ul{
margin-left: 30px;
li{
list-style: disc;
}
}
}
ol>li{
list-style-type: decimal;
}
ul{
margin-left: 30px;
list-style: disc;
ul{
margin-left: 30px;
}
}
table{
border: 0px solid;
border-spacing: 1px;
border-collapse: collapse;
th{
background-color: #e5e5e5;
border: 1px solid;
min-width: 180px;
}
td{
border: 1px solid;
min-width: 180px;
}
}
}
</style> </style>

58
src/views/doc/manage.vue

@ -22,7 +22,7 @@ import preview from './preview.vue';
import space from './space.vue'; import space from './space.vue';
import spacePermission from './spacePermission.vue'; import spacePermission from './spacePermission.vue';
import SvgIcon from "@/components/SvgIcon/index.vue"; import SvgIcon from "@/components/SvgIcon/index.vue";
import {doDelSpace} from "@/api/doc/space" import {doDelSpace,doAccessManage} from "@/api/doc/space"
import Space from "./space.vue"; import Space from "./space.vue";
//TODO: add file icons done! //TODO: add file icons done!
@ -254,10 +254,12 @@ function onMatterRename(row:matterInfo){
}, },
}), }),
}).then(() => { }).then(() => {
postMatterRename(uid,{ if(newname.value&&newname.value!=""){
uuid:row.uuid, postMatterRename(uid,{
name:newname.value, uuid:row.uuid,
}).then(()=>onLoadMatterList()) name:newname.value,
}).then(()=>onLoadMatterList())
}
}) })
} }
@ -658,6 +660,31 @@ function flushSpaceTree(uuid:string,data:matterTree[]){
spaceTreeRef.value.updateKeyChildren(uuid,data) spaceTreeRef.value.updateKeyChildren(uuid,data)
} }
//
function onAccessManage(){
dynamicVNode.value = h(sharePermission, {
uid: uid,
uuid: "",
spaceid:SpaceID.value.uuid, //
confirmFunc: (_list: string[],_infos:string[]) => {
//
//_len=_list.length
let permited = btoa(_list.join("|"))
doAccessManage(uid,{
"space":SpaceID.value.uuid,
"roles":permited,
"owner":SpaceID.value.userUuid,
"len":_list.length
}).then(()=>{
})
},
closeFunc: () => {
dynamicVNode.value=null
}
})
}
// //
function onDeleteSpace(row:matterInfo){ function onDeleteSpace(row:matterInfo){
ElMessageBox.confirm(`确认删除空间 ( ${row.name}) ? 空间内所有文件将不可恢复!取消则放弃删除操作。`, "警告", { ElMessageBox.confirm(`确认删除空间 ( ${row.name}) ? 空间内所有文件将不可恢复!取消则放弃删除操作。`, "警告", {
@ -763,6 +790,7 @@ const handleSelectionChange = (val:matterInfo[]) => {
<el-button size="small" :icon="Setting" circle ></el-button> <el-button size="small" :icon="Setting" circle ></el-button>
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item @click="(e)=>{ e.stopPropagation(); onAccessManage(data)}">空间成员管理</el-dropdown-item>
<el-dropdown-item @click="(e)=>{ e.stopPropagation(); onDelSpaceMatter(data)}">删除</el-dropdown-item> <el-dropdown-item @click="(e)=>{ e.stopPropagation(); onDelSpaceMatter(data)}">删除</el-dropdown-item>
<el-dropdown-item @click="(e)=>{ e.stopPropagation(); onSpacePManage(data)}">权限管理</el-dropdown-item> <el-dropdown-item @click="(e)=>{ e.stopPropagation(); onSpacePManage(data)}">权限管理</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
@ -815,7 +843,7 @@ const handleSelectionChange = (val:matterInfo[]) => {
</el-button-group> </el-button-group>
</el-row> </el-row>
<el-row :gutter="24" style="overflow-y: auto;"> <el-row :gutter="24" style="overflow-y: auto; height: 90%;">
<el-table v-if="modListOrGrild" <el-table v-if="modListOrGrild"
stripe stripe
:data="matterList" :data="matterList"
@ -839,7 +867,7 @@ const handleSelectionChange = (val:matterInfo[]) => {
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column width="250" align="center"> <el-table-column width="360" align="center">
<template #default="scope"> <template #default="scope">
<div v-show="currentHoverRow === scope.row.name"> <div v-show="currentHoverRow === scope.row.name">
<!-- <el-button size="small" :icon="Promotion" circle ></el-button> --> <!-- <el-button size="small" :icon="Promotion" circle ></el-button> -->
@ -848,6 +876,7 @@ const handleSelectionChange = (val:matterInfo[]) => {
<el-button size="small" :icon="Download" circle @click="onDownload(scope.row)"></el-button> <el-button size="small" :icon="Download" circle @click="onDownload(scope.row)"></el-button>
<el-button size="small" :icon="Edit" circle @click="onlyOfficeEdit(scope.row)"></el-button> <el-button size="small" :icon="Edit" circle @click="onlyOfficeEdit(scope.row)"></el-button>
<el-button size="small" :icon="Delete" circle @click="onDelMatter(scope.row)"></el-button> <el-button size="small" :icon="Delete" circle @click="onDelMatter(scope.row)"></el-button>
<el-button size="small" circle @click="onMatterRename(scope.row)"></el-button>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
@ -876,10 +905,11 @@ const handleSelectionChange = (val:matterInfo[]) => {
</div> </div>
<ul v-if="row.name!=''" class="grid-menus" v-show="currentHoverRow === row.name" @mouseleave="currentHoverRow=''"> <ul v-if="row.name!=''" class="grid-menus" v-show="currentHoverRow === row.name" @mouseleave="currentHoverRow=''">
<li v-if="getFileIcon(row.name)!='img'" @click="onPrivateView(row)">预览</li> <li v-if="getFileIcon(row.name)!='img'" @click="onPrivateView(row)">预览</li>
<li size="small" :icon="Share" @click="onShareMatter(row)">分享</li> <li @click="onShareMatter(row)">分享</li>
<li size="small" :icon="Download" @click="onDownload(row)">下载</li> <li @click="onDownload(row)">下载</li>
<li size="small" :icon="Edit" @click="onlyOfficeEdit(row)">编辑</li> <li @click="onlyOfficeEdit(row)">编辑</li>
<li size="small" :icon="Delete" @click="onDelMatter(row)">删除</li> <li @click="onDelMatter(row)">删除</li>
<li @click="onMatterRename(row)">重命名</li>
</ul> </ul>
</div> </div>
</div> </div>
@ -976,12 +1006,13 @@ const handleSelectionChange = (val:matterInfo[]) => {
.table-grid{ .table-grid{
display: flex; display: flex;
flex-wrap: wrap; /* 关键属性,允许子元素自动换行 */ flex-wrap: wrap; /* 关键属性,允许子元素自动换行 */
align-content: flex-start;
.grid-item{ .grid-item{
position: relative; position: relative;
width: 134px; width: 134px;
height: 145px;
margin: 5px; margin: 5px;
.grid-box{ .grid-box{
height: 150px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: hidden;
@ -997,6 +1028,7 @@ const handleSelectionChange = (val:matterInfo[]) => {
line-height: 27px; line-height: 27px;
text-align: center; text-align: center;
color: #878989; color: #878989;
z-index: 90;
box-shadow:0px 0px 12px rgba(0,0,0,0.12); box-shadow:0px 0px 12px rgba(0,0,0,0.12);
li{ li{
cursor: pointer; cursor: pointer;

28
src/views/doc/onlyoffice.vue

@ -53,22 +53,22 @@ onMounted(()=>{
const _url=decodeURIComponent(window.atob(query.fileurl)) const _url=decodeURIComponent(window.atob(query.fileurl))
const name=query.name?.toString()??"" const name=query.name?.toString()??""
const dtype=query.dtype?.toString()??"word" const dtype=query.dtype?.toString()??"word"
// //
if (_info.includes(name)){ config.value.document.url=_url
config.value.document.url=_url config.value.document.title=name
config.value.document.title=name const _key=_url.match(/(\w+-\w+-\w+)/)![0]
const _key=_url.match(/(\w+-\w+-\w+)/)![0] if(_key) config.value.document.key=_key+(new Date().getTime().toString()) //unique key
if(_key) config.value.document.key=_key+(new Date().getTime().toString()) //unique key config.value.documentType=dtype
config.value.documentType=dtype config.value.editorConfig.callbackUrl+=`?info=${_info}`
config.value.editorConfig.callbackUrl+=`?info=${_info}` //
// if(!query.verify) return;
if(!query.verify) return; const _verify = atob(query.verify)
const _verify = atob(query.verify) //1true 2uuid
//1true 2uuid if(_verify.endsWith("true") && _key.includes(_verify.replace("true",""))){
if(_verify.endsWith("true") && _key.includes(_verify.replace("true",""))){ config.value.editorConfig.mode="edit"
config.value.editorConfig.mode="edit"
}
} }
} }
}) })

4
src/views/doc/recentVisited.vue

@ -24,9 +24,9 @@ const props = withDefaults(defineProps<{
function onlyOfficeView(row:shareItem){ function onlyOfficeView(row:shareItem){
const _type=fileType(row.name!) const _type=fileType(row.name!)
if(_type!==""){ //office file if(_type!==""){ //office file
const info =btoa(encodeURIComponent(`${row.userUuid}/root${row.matters[0].path}`)) const info =btoa(encodeURIComponent(`${row.name}`))
const _url=`${siteHost}${apiURL}/share/zip?shareUuid=${row.uuid}&code=${row.code}&uid=${props.uid}&dprt=${props.udprt}&puuid=root&rootUuid=root` const _url=`${siteHost}${apiURL}/share/zip?shareUuid=${row.uuid}&code=${row.code}&uid=${props.uid}&dprt=${props.udprt}&puuid=root&rootUuid=root`
window.open(`/#/onlyoffice?name=${row.name}&dtype=${_type}&info=${info}&fileurl=`+encodeURIComponent(_url),"_blank") window.open(`/#/onlyoffice?name=${row.name}&dtype=${_type}&info=${info}&fileurl=`+window.btoa(encodeURIComponent(_url)),"_blank")
}else{ }else{
//by kkFilePreview //by kkFilePreview
let a = row.name ?? ''; let a = row.name ?? '';

113
src/views/doc/space.vue

@ -9,16 +9,16 @@ import sharePermission from './sharePermission.vue';
import spacePermission from './spacePermission.vue'; import spacePermission from './spacePermission.vue';
import { matterPage,matterInfo,matterTree,doFileUpload,matterPermit} from "@/api/doc/type" import { matterPage,matterInfo,matterTree,doFileUpload,matterPermit} from "@/api/doc/type"
import { doAccessManage,getSpaceMatterList,doCreateSpaceDir,doDelSpaceMatter, import { doAccessManage,getSpaceMatterList,doCreateSpaceDir,doDelSpaceMatter,
doAiTraining ,doCreateAiagent} from "@/api/doc/space" doAiTraining ,doCreateAiagent,spaceMatterRename} from "@/api/doc/space"
import { h } from 'vue' import { h } from 'vue'
import { import {
Delete, Delete,
View, View,
Download, Download,
Plus, Plus,Search,
Edit, Edit,
Setting, Setting,
Promotion, Grid,List,
} from '@element-plus/icons-vue' } from '@element-plus/icons-vue'
import {ElMessage,UploadFile,UploadFiles,ElPagination} from "element-plus"; import {ElMessage,UploadFile,UploadFiles,ElPagination} from "element-plus";
import aiagent from './agent.vue'; import aiagent from './agent.vue';
@ -29,6 +29,7 @@ const orgMembers = useOrgMemberStore() //为了初始化
const defaultAiAgent=import.meta.env.VITE_DEFAULT_AI_AGENT const defaultAiAgent=import.meta.env.VITE_DEFAULT_AI_AGENT
const matterList = ref<matterInfo[]>([]) const matterList = ref<matterInfo[]>([])
const searchname=ref("") //
const newdirName=ref("") // const newdirName=ref("") //
const currentHoverRow=ref("") //table const currentHoverRow=ref("") //table
const breadcrumbList=ref<matterInfo[]>([{name:"根目录",uuid:"root", dir:true}]) // const breadcrumbList=ref<matterInfo[]>([{name:"根目录",uuid:"root", dir:true}]) //
@ -41,6 +42,7 @@ const dynamicVNode = ref<VNode | null>(null) //permission 组件的父组件
const paginInfo = ref({ page: 0, total: 0 }) const paginInfo = ref({ page: 0, total: 0 })
const CutLevelPermit=ref(0) const CutLevelPermit=ref(0)
const modListOrGrild=ref(true) //
enum PERMITS { enum PERMITS {
FORBID, //0 FORBID, //0
VIEW, //1 VIEW, //1
@ -88,8 +90,18 @@ const uploadFormData = computed(() => {
} }
}); });
function updateListOrGrid(val:boolean){
modListOrGrild.value=val
if(val){
localStorage.setItem("listOrGrid","true")
}else{
localStorage.setItem("listOrGrid","false")
}
}
//--------------&------------- //--------------&-------------
function onAccessManage(){ function onAccessManage(){
//manage
dynamicVNode.value = h(sharePermission, { dynamicVNode.value = h(sharePermission, {
uid: props.uid, uid: props.uid,
uuid: "", uuid: "",
@ -159,10 +171,9 @@ function onDownload(row:matterInfo){
}) })
} }
// //
function onLoadMatterList(){ function onLoadMatterList(name?:string){
let _page: matterPage = { let _page: matterPage= {
page: paginInfo.value.page, page: paginInfo.value.page,
pageSize: 50, pageSize: 50,
orderCreateTime: "DESC", orderCreateTime: "DESC",
@ -172,6 +183,18 @@ function onLoadMatterList(){
space:props.spaceid, space:props.spaceid,
}; };
if(name){
_page={
pageSize: 50,
orderCreateTime: "DESC",
orderDir: "DESC",
deleted:false,
name:name,
space:props.spaceid,
}
}
getSpaceMatterList(props.uid,_page).then((resp)=>{ getSpaceMatterList(props.uid,_page).then((resp)=>{
//page+1 index1apiindex0 //page+1 index1apiindex0
paginInfo.value={total:resp.data.totalPages, page:resp.data.page} paginInfo.value={total:resp.data.totalPages, page:resp.data.page}
@ -251,6 +274,31 @@ function onCreateDir(){
}) })
} }
//
function onMatterRename(row:matterInfo){
const newname=ref(row.name)
ElMessageBox({
title:"请输入新的文件名",
confirmButtonText: "确定",
cancelButtonText: "取消",
message: () => h(ElInput, {
style: { width:'360px' },
modelValue: newname.value,
'onUpdate:modelValue': (val) => {
newname.value = val
},
}),
}).then(() => {
if(newname.value&&newname.value!=""){
spaceMatterRename(props.uid,{
space:props.spaceid,
uuid:row.uuid,
name:newname.value,
}).then(()=>onLoadMatterList())
}
})
}
//------------------------------------------ //------------------------------------------
// @cell-dblclick="handleDoubleClick" // @cell-dblclick="handleDoubleClick"
// //
@ -445,7 +493,11 @@ function handleAiUpload(info:matterInfo){
// //
if (info.path?.startsWith(currentAgent.value.path)){ if (info.path?.startsWith(currentAgent.value.path)){
doAiTraining(`/agents/${currentAgent.value.uuid}/updates`,{"matter":info.uuid}).then(resp=>{ doAiTraining(`/agents/${currentAgent.value.uuid}/updates`,{"matter":info.uuid}).then(resp=>{
console.log(resp) ElMessage({
message: '已成功安排训练',
type: 'success',
plain: true,
})
}) })
}else{ }else{
alert("当前路径没有智能体") alert("当前路径没有智能体")
@ -508,6 +560,13 @@ onMounted(() => {
//AI //AI
currentAgent.value={name:"通用AI",model:false,uuid:defaultAiAgent,path:"root"} currentAgent.value={name:"通用AI",model:false,uuid:defaultAiAgent,path:"root"}
let val =localStorage.getItem("listOrGrid")
if(val&&val=="false"){
modListOrGrild.value=false
}else{
modListOrGrild.value=true
}
if (props.ismanager) { if (props.ismanager) {
CutLevelPermit.value=PERMITS.MANAGER CutLevelPermit.value=PERMITS.MANAGER
}else{ }else{
@ -537,7 +596,6 @@ function isOwner(){
</script> </script>
<template> <template>
<div>
<el-row :gutter="24" style="margin: 12px 0px;"> <el-row :gutter="24" style="margin: 12px 0px;">
<span class="el-breadcrumb" style="font-weight: bold; align-content: center;">[ {{ props.spacename }} ] : </span> <span class="el-breadcrumb" style="font-weight: bold; align-content: center;">[ {{ props.spacename }} ] : </span>
<el-breadcrumb separator="/" style="align-content: center;"> <el-breadcrumb separator="/" style="align-content: center;">
@ -547,6 +605,11 @@ function isOwner(){
</el-breadcrumb-item> </el-breadcrumb-item>
</el-breadcrumb> </el-breadcrumb>
<span v-if="currentNode.uuid!='root'" style="font-weight: bold;margin:0 5px;align-content:center;">/ {{ currentNode.name }}</span> <span v-if="currentNode.uuid!='root'" style="font-weight: bold;margin:0 5px;align-content:center;">/ {{ currentNode.name }}</span>
<el-col :span="6" class="search">
<el-input placeholder="搜索文件" v-model="searchname" @blur="searchname===''?onLoadMatterList():''"/>
<el-button :icon="Search" @click="onLoadMatterList(searchname)"></el-button>
</el-col>
</el-row> </el-row>
<el-row :gutter="24"> <el-row :gutter="24">
@ -568,15 +631,18 @@ function isOwner(){
<el-button @click="createDir">新建目录</el-button> <el-button @click="createDir">新建目录</el-button>
</el-col> </el-col>
<el-button style="margin-left: auto;" @click="()=>currentAgent.model=true">AI助手</el-button> <el-button style="margin-left: auto;" @click="()=>currentAgent.model=true">AI助手</el-button>
<el-button-group v-if="isOwner()" class="control" style="margin: 0 10px;"> <el-button-group v-if="isOwner()" class="control" style="margin: 0 10px;">
<el-button :icon="Plus" @click="onAccessManage">成员</el-button>
<el-button :icon="Plus" @click="onAiAgent">创建智能体</el-button> <el-button :icon="Plus" @click="onAiAgent">创建智能体</el-button>
<!-- <el-button :icon="Delete" @click="onDeleteSpace">删除</el-button> --> </el-button-group>
<el-button-group style="margin-right:20px;">
<el-button :icon="List" @click="updateListOrGrid(true)"></el-button>
<el-button :icon="Grid" @click="updateListOrGrid(false)"></el-button>
</el-button-group> </el-button-group>
</el-row> </el-row>
<el-row :gutter="24" style="height: 84%;overflow-y: auto;"> <el-row :gutter="24" style="overflow-y: auto;height: 90%;">
<el-table v-if="listOrGrid" <el-table v-if="modListOrGrild"
stripe stripe
:data="matterList" :data="matterList"
:header-cell-style="{ background: '#f5f8fd' }" :header-cell-style="{ background: '#f5f8fd' }"
@ -603,12 +669,15 @@ function isOwner(){
<div v-show="currentHoverRow === scope.row.name" style="display:inline; margin-left:15px"> <div v-show="currentHoverRow === scope.row.name" style="display:inline; margin-left:15px">
<el-button v-if="getFileIcon(scope.row.name)!='img'" size="small" :icon="View" circle @click="onPrivateView(scope.row)"></el-button> <el-button v-if="getFileIcon(scope.row.name)!='img'" size="small" :icon="View" circle @click="onPrivateView(scope.row)"></el-button>
<el-button v-if="scope.row.permitVal>=PERMITS.DOWNLOAD" size="small" :icon="Download" circle @click="onDownload(scope.row)"></el-button> <el-button v-if="scope.row.permitVal>=PERMITS.DOWNLOAD" size="small" :icon="Download" circle @click="onDownload(scope.row)"></el-button>
<el-button v-if="scope.row.permitVal>=PERMITS.EDIT" size="small" :icon="Edit" circle @click="onlyOfficeEdit(scope.row)"></el-button>
<span v-if="scope.row.permitVal>=PERMITS.MANAGER" class="manager_span" > <span v-if="scope.row.permitVal>=PERMITS.MANAGER" class="manager_span" >
<el-button v-if="!scope.row.dir" size="small" circle @click="handleAiUpload(scope.row)">AI</el-button> <el-button v-if="!scope.row.dir" size="small" circle @click="handleAiUpload(scope.row)">AI</el-button>
<el-button size="small" :icon="Delete" circle @click="onDelMatter(scope.row)"></el-button> <el-button size="small" :icon="Delete" circle @click="onDelMatter(scope.row)"></el-button>
<el-button size="small" :icon="Setting" circle @click="onSpacePManage(scope.row)"></el-button> <el-button size="small" :icon="Setting" circle @click="onSpacePManage(scope.row)"></el-button>
</span> </span>
<span v-if="scope.row.permitVal>=PERMITS.EDIT" class="manager_span">
<el-button size="small" :icon="Edit" circle @click="onlyOfficeEdit(scope.row)"></el-button>
<el-button size="small" circle @click="onMatterRename(scope.row)"></el-button>
</span>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
@ -640,10 +709,13 @@ function isOwner(){
<ul v-if="row.name!=''" class="grid-menus" v-show="currentHoverRow === row.name" @mouseleave="currentHoverRow=''"> <ul v-if="row.name!=''" class="grid-menus" v-show="currentHoverRow === row.name" @mouseleave="currentHoverRow=''">
<li v-if="getFileIcon(row.name)!='img'" @click="onPrivateView(row)">预览</li> <li v-if="getFileIcon(row.name)!='img'" @click="onPrivateView(row)">预览</li>
<li v-if="row.permitVal! >= PERMITS.DOWNLOAD" @click="onDownload(row)">下载</li> <li v-if="row.permitVal! >= PERMITS.DOWNLOAD" @click="onDownload(row)">下载</li>
<li v-if="row.permitVal! >= PERMITS.EDIT" @click="onlyOfficeEdit(row)">编辑</li> <span v-if="row.permitVal! >= PERMITS.EDIT" >
<li @click="onlyOfficeEdit(row)">编辑</li>
<li @click="onMatterRename(row)">重命名</li>
</span>
<span v-if="row.permitVal! >= PERMITS.MANAGER" > <span v-if="row.permitVal! >= PERMITS.MANAGER" >
<li @click="onDelMatter(row)">删除</li> <li @click="onDelMatter(row)">删除</li>
<li @click="onSpacePManage(row)">权限</li> <li @click="onSpacePManage(row)">权限</li>
</span> </span>
</ul> </ul>
</div> </div>
@ -653,7 +725,6 @@ function isOwner(){
<el-row v-if="paginInfo.total>1" style="justify-content: center;"> <el-row v-if="paginInfo.total>1" style="justify-content: center;">
<el-pagination size="small" background layout="prev, pager, next" :current-page="paginInfo.page+1" @current-change="(value:number)=>{paginInfo.page=value-1;onLoadMatterList();}" :page-count="paginInfo.total" class="mt-4"/> <el-pagination size="small" background layout="prev, pager, next" :current-page="paginInfo.page+1" @current-change="(value:number)=>{paginInfo.page=value-1;onLoadMatterList();}" :page-count="paginInfo.total" class="mt-4"/>
</el-row> </el-row>
</div>
<aiagent :agent="currentAgent" :userid="uid" :uuid="currentAgent" :closefunc="()=>{currentAgent.model=false}"></aiagent> <aiagent :agent="currentAgent" :userid="uid" :uuid="currentAgent" :closefunc="()=>{currentAgent.model=false}"></aiagent>
@ -671,16 +742,22 @@ function isOwner(){
align-self: flex-start; align-self: flex-start;
} }
} }
.search{
margin-left: auto;
margin-right: 20px;
display:inherit;
}
.table-grid{ .table-grid{
display: flex; display: flex;
flex-wrap: wrap; /* 关键属性,允许子元素自动换行 */ flex-wrap: wrap; /* 关键属性,允许子元素自动换行 */
align-content: flex-start;
.grid-item{ .grid-item{
position: relative; position: relative;
width: 134px; width: 134px;
height: 135px;
margin: 5px; margin: 5px;
.grid-box{ .grid-box{
height: 150px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: hidden;
@ -696,7 +773,7 @@ function isOwner(){
line-height: 27px; line-height: 27px;
text-align: center; text-align: center;
color: #878989; color: #878989;
z-index: 999; z-index: 90;
box-shadow:0px 0px 12px rgba(0,0,0,0.12); box-shadow:0px 0px 12px rgba(0,0,0,0.12);
li{ li{
cursor: pointer; cursor: pointer;

103
src/views/doc/spacePermission.vue

@ -8,6 +8,7 @@ import {
import { ElDialog, ElMessageBox,ElStep,TreeInstance} from 'element-plus'; import { ElDialog, ElMessageBox,ElStep,TreeInstance} from 'element-plus';
import { useOrgMemberStore } from "@/store/modules/orgMember"; import { useOrgMemberStore } from "@/store/modules/orgMember";
import { dataTool } from 'echarts';
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
uid:string, //uuid uid:string, //uuid
uuid:string, //uuid uuid:string, //uuid
@ -21,16 +22,17 @@ const spacePermit=ref<{id:number,data:string,matterUid:string}>({}) //权限
const treeRef=ref<TreeInstance>() //tree const treeRef=ref<TreeInstance>() //tree
const managerMode=ref(false) const managerMode=ref(false)
const managers=ref<string[]>([]) const managers=ref<string[]>([])
const firstLevelKeys = ref<string[]>([]) //
let resultPermits: Record<string, number> = {}; let resultPermits: Record<string, number> = {};
interface Tree { interface Tree {
id: string id: string
label:string name:string
parentId?:string superior?:string
indeterminate?:boolean, indeterminate?:boolean,
radio?:number[]; radio?:number[];
children?: Tree[] child?: Tree[]
ismanager?:boolean, ismanager?:boolean,
} }
@ -48,7 +50,7 @@ async function onSavePermChange(){
managers.value.push("p0"+item.id) managers.value.push("p0"+item.id)
} }
if(item.children) collectManager(item) if(item.child) collectManager(item)
}) })
await addSpaceManager(btoa(props.uid),{ await addSpaceManager(btoa(props.uid),{
@ -69,7 +71,7 @@ async function onSavePermChange(){
resultPermits[item.id]=item.radio[0] resultPermits[item.id]=item.radio[0]
} }
if(item.children) collectNodePermits(item) if(item.child) collectNodePermits(item)
}) })
spacePermit.value.data=JSON.stringify(resultPermits) spacePermit.value.data=JSON.stringify(resultPermits)
@ -85,18 +87,18 @@ async function onSavePermChange(){
} }
function collectManager(node:Tree){ function collectManager(node:Tree){
node.children?.forEach(ele => { node.child?.forEach(ele => {
if(ele.ismanager){ if(ele.ismanager){
managers.value.push("p0"+ele.id) managers.value.push("p0"+ele.id)
} }
if(ele.children) collectManager(ele) if(ele.child) collectManager(ele)
}); });
} }
// //
function collectNodePermits(node:Tree){ function collectNodePermits(node:Tree){
node.children?.forEach(ele => { node.child?.forEach(ele => {
if(ele.radio&&ele.radio.length>0){ if(ele.radio&&ele.radio.length>0){
if(ele.indeterminate) { if(ele.indeterminate) {
ele.radio[0]+=10 ele.radio[0]+=10
@ -104,7 +106,7 @@ function collectNodePermits(node:Tree){
resultPermits[ele.id]=ele.radio[0] resultPermits[ele.id]=ele.radio[0]
} }
if(ele.children){ if(ele.child){
collectNodePermits(ele) collectNodePermits(ele)
} }
}); });
@ -114,25 +116,25 @@ function collectNodePermits(node:Tree){
// //
function onGroupValueChange(node:Tree, val:number[]){ function onGroupValueChange(node:Tree, val:number[]){
if(node.indeterminate) node.indeterminate=false; if(node.indeterminate) node.indeterminate=false;
node.children?.forEach(ele => { node.child?.forEach(ele => {
ele.radio=val ele.radio=val
if(ele.children){ if(ele.child){
onGroupValueChange(ele,val) onGroupValueChange(ele,val)
} }
}); });
if(node.parentId){ if(node.superior){
updateParentNode(node) updateParentNode(node)
} }
} }
// //
function updateParentNode(node:Tree){ function updateParentNode(node:Tree){
if(node.parentId){ if(node.superior){
const pnode = treeRef.value?.getNode(node.parentId); const pnode = treeRef.value?.getNode(node.superior);
if(pnode){ if(pnode){
const tdata=pnode.data as Tree const tdata=pnode.data as Tree
if (tdata.children?.every(ele=>{ if (tdata.child?.every(ele=>{
if(ele.indeterminate) return !ele.indeterminate;// if(ele.indeterminate) return !ele.indeterminate;//
if(ele.radio?.length==0) return ele.radio.length==tdata.radio?.length; if(ele.radio?.length==0) return ele.radio.length==tdata.radio?.length;
@ -165,10 +167,23 @@ function onShowManagers(){
const node = treeRef.value?.getNode(item.replace("p0","")); const node = treeRef.value?.getNode(item.replace("p0",""));
if(node && node.data){ if(node && node.data){
node.data.ismanager=true node.data.ismanager=true
setParentIndeterminate(node.data as Tree)
} }
}) })
} }
function setParentIndeterminate(node:Tree){
if(node.superior){
const pnode = treeRef.value?.getNode(node.superior);
if(pnode){
const tdata=pnode.data as Tree
tdata.indeterminate=true
setParentIndeterminate(tdata)
}
}
}
function refreshSpaceData(){ function refreshSpaceData(){
getSpaceMemberList( getSpaceMemberList(
btoa(props.uid), btoa(props.uid),
@ -183,13 +198,17 @@ function refreshSpaceData(){
addNode(item,orgMembers.dataTree) addNode(item,orgMembers.dataTree)
}); });
if(dataSource.value.length>0){//
firstLevelKeys.value.push(dataSource.value[0].id)
}
resp.data?.members?.forEach(item=>{ resp.data?.members?.forEach(item=>{
const mid=item.replace("p0","") const mid=item.replace("p0","")
for(let data of dataSource.value){ for(let data of dataSource.value){
if(checkNode(mid,data)) return; if(checkNode(mid,data)) return;
} }
dataSource.value.push({id:mid,label:orgMembers.listMap[mid],radio:[2]}) dataSource.value.push({id:mid,name:orgMembers.listMap[mid],radio:[]})
}); });
managers.value=resp.data?.managers.split("|") managers.value=resp.data?.managers.split("|")
@ -197,7 +216,6 @@ function refreshSpaceData(){
spacePermit.value.matterUid=resp.data?.permits.MatterUuid spacePermit.value.matterUid=resp.data?.permits.MatterUuid
spacePermit.value.data=resp.data.permits.data!="" ? resp.data.permits.data : "{}" spacePermit.value.data=resp.data.permits.data!="" ? resp.data.permits.data : "{}"
nextTick(() => { nextTick(() => {
const permitJson = JSON.parse(spacePermit.value.data) //object const permitJson = JSON.parse(spacePermit.value.data) //object
Object.keys(permitJson).forEach(key=>{ Object.keys(permitJson).forEach(key=>{
@ -217,28 +235,28 @@ function refreshSpaceData(){
} }
function addNode(key:string,node:Tree){ function addNode(key:string,node:Tree){
node.children?.forEach(ele => { node.child?.forEach(ele => {
if(ele.id==key){ if(ele.id==key){
const eleClone=structuredClone(toRaw(ele)) //eleProxyclonetoRawobject const eleClone=structuredClone(toRaw(ele)) //eleProxyclonetoRawobject
eleClone.radio=[2] //eleClone.radio=[2]
eleClone.parentId=ele.parentId eleClone.superior=ele.superior
dataSource.value.push(eleClone) //{id:ele.id,label:ele.label,radio:2,stage:level,children:ele.children} dataSource.value.push(eleClone) //{id:ele.id,name:ele.name,radio:2,stage:level,children:ele.children}
return return
} }
if(ele.children){ if(ele.child){
addNode(key,ele) addNode(key,ele)
} }
}); });
} }
function checkNode(key:string,node:Tree):boolean{ function checkNode(key:string,node:Tree):boolean{
for (const child of node.children||[]) { for (const ch of node.child||[]) {
if(child.id==key){ if(ch.id==key){
return true return true
} }
if(child.children){ if(ch.child){
//returnreturnfortruereturn //returnreturnfortruereturn
if(checkNode(key,child)) return true; if(checkNode(key,ch)) return true;
} }
} }
@ -266,11 +284,26 @@ onMounted(()=>{
<span>管理员</span> <span>管理员</span>
</div> </div>
<div v-else class="buttons"> <div v-else class="buttons">
<span>禁止</span> <el-tooltip placement="top" effect="dark"
<span>仅预览</span> content="禁止访问">
<span>可下载</span> <span>不可见</span>
<span>上传下载</span> </el-tooltip>
<span>编辑</span> <el-tooltip placement="top" effect="dark"
content="仅可预览,不可下载">
<span>仅预览</span>
</el-tooltip>
<el-tooltip placement="top" effect="dark"
content="可下载可见文件,不可上传文件">
<span>可下载</span>
</el-tooltip>
<el-tooltip placement="top" effect="dark"
content="可上传和下载可见文件">
<span>上传下载</span>
</el-tooltip>
<el-tooltip placement="top" effect="dark"
content="可上传、下载、编辑文档">
<span>编辑</span>
</el-tooltip>
</div> </div>
</div> </div>
<div class="tablelist"> <div class="tablelist">
@ -278,15 +311,17 @@ onMounted(()=>{
ref="treeRef" ref="treeRef"
:data="dataSource" :data="dataSource"
node-key="id" node-key="id"
default-expand-all accordion
:props="{label: 'name',children:'child'}"
:default-expanded-keys="firstLevelKeys"
:expand-on-click-node="false" :expand-on-click-node="false"
> >
<template #default="{ node, data }"> <template #default="{ node, data }">
<div class="tree-node"> <div class="tree-node">
<span>{{ node.label }}</span> <span>{{ data.name }}</span>
<div v-if="managerMode" class="buttons"> <div v-if="managerMode" class="buttons">
<el-checkbox v-if="!data.children" v-model="data.ismanager" /> <el-checkbox v-model="data.ismanager" :indeterminate="data.indeterminate" />
</div> </div>
<div v-else class="buttons"> <div v-else class="buttons">
<el-checkbox-group :min="0" :max="1" v-model="data.radio" @change="(val)=>onGroupValueChange(data,val)"> <el-checkbox-group :min="0" :max="1" v-model="data.radio" @change="(val)=>onGroupValueChange(data,val)">

Loading…
Cancel
Save