Skip to content

Commit

Permalink
Feat/0.3.1.4 (#655)
Browse files Browse the repository at this point in the history
  • Loading branch information
zgqgit committed Jun 18, 2024
2 parents d15b237 + 16c21a0 commit 532e0af
Show file tree
Hide file tree
Showing 13 changed files with 74 additions and 42 deletions.
8 changes: 6 additions & 2 deletions src/backend/bisheng/api/services/assistant.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,14 @@ def return_simple_assistant_info(cls, one: Assistant) -> AssistantSimpleInfo:
return AssistantSimpleInfo(**simple_dict)

@classmethod
def get_assistant_info(cls, assistant_id: UUID, user_id: str):
def get_assistant_info(cls, assistant_id: UUID, login_user: UserPayload):
assistant = AssistantDao.get_one_assistant(assistant_id)
if not assistant:
return AssistantNotExistsError.return_resp()
# 检查是否有权限获取信息
if not login_user.access_check(assistant.user_id, assistant.id.hex, AccessType.ASSISTANT_READ):
return UnAuthorizedError.return_resp()

tool_list = []
flow_list = []
knowledge_list = []
Expand Down Expand Up @@ -455,7 +459,7 @@ def update_tool_list(cls, assistant_id: UUID, tool_list: List[int],
def check_update_permission(cls, assistant: Assistant, user_payload: UserPayload) -> Any:
# 判断权限
if not user_payload.access_check(assistant.user_id, assistant.id.hex, AccessType.ASSISTANT_WRITE):
return AssistantNotExistsError.return_resp()
return UnAuthorizedError.return_resp()

# 已上线不允许改动
if assistant.status == AssistantStatus.ONLINE.value:
Expand Down
5 changes: 3 additions & 2 deletions src/backend/bisheng/api/services/user_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ class UserPayload:
def __init__(self, **kwargs):
self.user_id = kwargs.get('user_id')
self.user_role = kwargs.get('role')
if self.user_role != 'admin': # 非管理员用户,需要获取他的角色列表
roles = UserRoleDao.get_user_roles(self.user_id)
self.user_role = [one.role_id for one in roles]
self.user_name = kwargs.get('user_name')

def is_admin(self):
Expand Down Expand Up @@ -144,7 +147,6 @@ def get_knowledge_list_by_access(role_id: int, name: str, page_num: int, page_si


def get_flow_list_by_access(role_id: int, name: str, page_num: int, page_size: int):

count_filter = []
if name:
count_filter.append(Flow.name.like('%{}%'.format(name)))
Expand Down Expand Up @@ -172,7 +174,6 @@ def get_flow_list_by_access(role_id: int, name: str, page_num: int, page_size: i


def get_assistant_list_by_access(role_id: int, name: str, page_num: int, page_size: int):

count_filter = []
if name:
count_filter.append(Assistant.name.like('%{}%'.format(name)))
Expand Down
8 changes: 4 additions & 4 deletions src/backend/bisheng/api/v1/assistant.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import yaml
from bisheng_langchain.gpts.tools.api_tools.openapi import OpenApiTools

from bisheng.api.JWT import get_login_user
from bisheng.api.services.assistant import AssistantService
from bisheng.api.services.openapi import OpenApiSchema
from bisheng.api.services.user_service import UserPayload
Expand Down Expand Up @@ -42,10 +43,9 @@ def get_assistant(*,

# 获取某个助手的详细信息
@router.get('/info/{assistant_id}', response_model=UnifiedResponseModel[AssistantInfo])
def get_assistant_info(*, assistant_id: UUID, Authorize: AuthJWT = Depends()):
Authorize.jwt_required()
current_user = json.loads(Authorize.get_jwt_subject())
return AssistantService.get_assistant_info(assistant_id, current_user.get('user_id'))
def get_assistant_info(*, assistant_id: UUID, login_user: UserPayload = Depends(get_login_user)):
"""获取助手信息"""
return AssistantService.get_assistant_info(assistant_id, login_user)


@router.post('/delete', response_model=UnifiedResponseModel)
Expand Down
17 changes: 10 additions & 7 deletions src/backend/bisheng/api/v1/flows.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from uuid import UUID

from bisheng.api.JWT import get_login_user
from bisheng.api.errcode.base import UnAuthorizedError
from bisheng.api.services.flow import FlowService
from bisheng.api.services.user_service import UserPayload
from bisheng.api.utils import build_flow_no_yield, get_L2_param_from_flow, remove_api_keys
Expand Down Expand Up @@ -161,13 +162,15 @@ def read_flows(*,


@router.get('/{flow_id}', response_model=UnifiedResponseModel[FlowReadWithStyle], status_code=200)
def read_flow(*, flow_id: UUID):
def read_flow(*, flow_id: UUID, login_user: UserPayload = Depends(get_login_user)):
"""Read a flow."""
with session_getter() as session:
if flow := session.get(Flow, flow_id):
return resp_200(flow)

raise HTTPException(status_code=404, detail='Flow not found')
db_flow = FlowDao.get_flow_by_id(flow_id.hex)
if not db_flow:
raise HTTPException(status_code=404, detail='Flow not found')
# 判断授权
if not login_user.access_check(db_flow.user_id, flow_id.hex, AccessType.FLOW):
return UnAuthorizedError.return_resp()
return resp_200(db_flow)


@router.patch('/{flow_id}', response_model=UnifiedResponseModel[FlowRead], status_code=200)
Expand All @@ -183,7 +186,7 @@ async def update_flow(*,
raise HTTPException(status_code=404, detail='Flow not found')

if not login_user.access_check(db_flow.user_id, flow_id, AccessType.FLOW_WRITE):
raise HTTPException(status_code=500, detail='No right access this flow')
return UnAuthorizedError.return_resp()

flow_data = flow.model_dump(exclude_unset=True)

Expand Down
5 changes: 3 additions & 2 deletions src/backend/bisheng/api/v1/knowledge.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from uuid import uuid4

from bisheng.api.JWT import get_login_user
from bisheng.api.errcode.base import UnAuthorizedError
from bisheng.api.services.knowledge_imp import (addEmbedding, decide_vectorstores,
delete_knowledge_file_vectors, retry_files)
from bisheng.api.services.user_service import UserPayload
Expand Down Expand Up @@ -105,7 +106,7 @@ async def process_knowledge(*,

knowledge = KnowledgeDao.query_by_id(knowledge_id)
if not login_user.access_check(knowledge.user_id, str(knowledge.id), AccessType.KNOWLEDGE_WRITE):
raise HTTPException(status_code=500, detail='当前用户无此知识库操作权限')
return UnAuthorizedError.return_resp()

collection_name = knowledge.collection_name
files = []
Expand Down Expand Up @@ -298,7 +299,7 @@ def get_filelist(*,
if not db_knowledge:
raise HTTPException(status_code=500, detail='当前知识库不可用,返回上级目录')
if not login_user.access_check(db_knowledge.user_id, str(knowledge_id), AccessType.KNOWLEDGE):
raise HTTPException(status_code=500, detail='没有访问权限')
return UnAuthorizedError.return_resp()

# 查找上传的文件信息
count_sql = select(func.count(
Expand Down
10 changes: 5 additions & 5 deletions src/backend/bisheng/chat/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ async def handle_websocket(
if context.get('status') == 'init':
erro_resp.intermediate_steps = f'LLM 技能执行错误. error={str(e)}'
elif context.get('has_file'):
erro_resp.intermediate_steps = f'File is parsed fail. error={str(e)}'
erro_resp.intermediate_steps = f'文件解析失败. error={str(e)}'
else:
erro_resp.intermediate_steps = f'Input data is parsed fail. error={str(e)}'
context['status'] = 'init'
Expand Down Expand Up @@ -469,7 +469,7 @@ async def preper_payload(self, payload, graph_data, langchain_obj_key, client_id
self.set_cache(langchain_obj_key, None) # rebuild object
has_file = any(['InputFile' in nd.get('id', '') for nd in node_data])
if has_file:
step_resp.intermediate_steps = 'File upload complete and begin to parse'
step_resp.intermediate_steps = '文件上传完成,开始解析'
await self.send_json(client_id, chat_id, start_resp)
await self.send_json(client_id, chat_id, step_resp, add=False)
await self.send_json(client_id, chat_id, start_resp)
Expand All @@ -485,7 +485,7 @@ async def preper_action(self, client_id, chat_id, langchain_obj_key, payload,
over = False
if isinstance(langchain_obj, Report):
action = 'report'
step_resp.intermediate_steps = 'File parsing complete, generate begin'
step_resp.intermediate_steps = '文件解析完成,开始生成报告'
await self.send_json(client_id, chat_id, step_resp)
elif 'action' in payload:
action = 'autogen'
Expand All @@ -510,13 +510,13 @@ async def preper_action(self, client_id, chat_id, langchain_obj_key, payload,
user_id=step_resp.user_id)
self.chat_history.add_message(client_id, chat_id, file)
step_resp.message = ''
step_resp.intermediate_steps = 'File parsing complete'
step_resp.intermediate_steps = '文件解析完成'
await self.send_json(client_id, chat_id, step_resp)
start_resp.type = 'close'
await self.send_json(client_id, chat_id, start_resp)
over = True
else:
step_resp.intermediate_steps = 'File parsing complete. Analysis starting'
step_resp.intermediate_steps = '文件解析完成,开始执行'
await self.send_json(client_id, chat_id, step_resp, add=False)
await asyncio.sleep(-1) # 快速的跳过
return action, over
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bisheng",
"version": "0.3.1",
"version": "0.3.1.3",
"private": true,
"dependencies": {
"@emotion/react": "^11.11.1",
Expand Down
5 changes: 3 additions & 2 deletions src/frontend/src/controllers/API/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ export async function getRolesApi(searchkey = ""): Promise<{ data: ROLE[] }> {
.then(res => res.data);
}
// 用户组下角色列表
export async function getRolesByGroupApi(searchkey = "", group_id): Promise<{ data: ROLE[] }> {
return await axios.get(`/api/v1/group/roles?keyword=${searchkey}&group_id=${group_id}`)
export async function getRolesByGroupApi(searchkey = "", groupIds:any[]): Promise<{ data: ROLE[] }> {
const groupStr = groupIds?.reduce((pre, id) => `${pre}&group_id=${id}`, '') || ''
return await axios.get(`/api/v1/group/roles?keyword=${searchkey}${groupStr}`)
.then(res => res.data);
}
/**
Expand Down
12 changes: 6 additions & 6 deletions src/frontend/src/layout/MainLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export default function MainLayout() {
{user.user_name} <DropDownIcon className=" inline-block mt-[-2px]"/>
</span>
}>
{/* <SelectHoverItem onClick={JumpResetPage}><LockClosedIcon className="w-4 h-4 mr-1" /><span>修改密码</span></SelectHoverItem> */}
<SelectHoverItem onClick={JumpResetPage}><LockClosedIcon className="w-4 h-4 mr-1" /><span>修改密码</span></SelectHoverItem>
<SelectHoverItem onClick={handleLogout}><QuitIcon className="w-4 h-4 mr-1" /><span>退出登录</span></SelectHoverItem>
</SelectHover>
</div>
Expand Down Expand Up @@ -122,11 +122,11 @@ export default function MainLayout() {
</>
}
{
// user.role === 'admin' && <>
// <NavLink to='/log' className={`navlink inline-flex rounded-lg w-full px-6 hover:bg-nav-hover h-12 mb-[3.5px]`}>
// <LogIcon className="h-6 w-6 my-[12px]" /><span className="mx-[14px] max-w-[48px] text-[14px] leading-[48px]">{t('menu.log')}</span>
// </NavLink>
// </>
user.role === 'admin' && <>
<NavLink to='/log' className={`navlink inline-flex rounded-lg w-full px-6 hover:bg-nav-hover h-12 mb-[3.5px]`}>
<LogIcon className="h-6 w-6 my-[12px]" /><span className="mx-[14px] max-w-[48px] text-[14px] leading-[48px]">{t('menu.log')}</span>
</NavLink>
</>
}
</nav>
<div className="absolute left-0 bottom-0 w-[180px] p-2">
Expand Down
14 changes: 7 additions & 7 deletions src/frontend/src/pages/SystemPage/components/Roles.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import React, { useEffect, useRef, useState, useCallback, useReducer } from "react";
import { PlusIcon } from "@/components/bs-icons/plus";
import { bsConfirm } from "@/components/bs-ui/alertDialog/useConfirm";
import { Label } from "@/components/bs-ui/label";
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/bs-ui/select";
import React, { useCallback, useEffect, useReducer, useRef } from "react";
import { useTranslation } from "react-i18next";
import { Button } from "../../../components/bs-ui/button";
import { bsConfirm } from "@/components/bs-ui/alertDialog/useConfirm";
import { SearchInput } from "../../../components/bs-ui/input";
import {
Table,
TableBody,
Expand All @@ -11,14 +15,10 @@ import {
TableHeader,
TableRow
} from "../../../components/bs-ui/table";
import { delRoleApi, getRolesApi, getRolesByGroupApi, getUserGroupsApi } from "../../../controllers/API/user";
import { delRoleApi, getRolesByGroupApi, getUserGroupsApi } from "../../../controllers/API/user";
import { captureAndAlertRequestErrorHoc } from "../../../controllers/request";
import { ROLE } from "../../../types/api/user";
import EditRole from "./EditRole";
import { SearchInput } from "../../../components/bs-ui/input";
import { PlusIcon } from "@/components/bs-icons/plus";
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "@/components/bs-ui/select";
import { Label } from "@/components/bs-ui/label";

interface State {
roles: ROLE[];
Expand Down
10 changes: 9 additions & 1 deletion src/frontend/src/pages/SystemPage/components/UserRoleModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useToast } from "@/components/bs-ui/toast/use-toast"
import { useEffect, useMemo, useState } from "react"
import { useTranslation } from "react-i18next"
import { Button } from "../../../components/bs-ui/button"
import { getRolesApi, getUserGroupsApi, updateUserGroups, updateUserRoles } from "../../../controllers/API/user"
import { getRolesApi, getUserGroupsApi, getRolesByGroupApi, updateUserGroups, updateUserRoles } from "../../../controllers/API/user"
import { captureAndAlertRequestErrorHoc } from "../../../controllers/request"
import { ROLE } from "../../../types/api/user"

Expand Down Expand Up @@ -42,6 +42,14 @@ export default function UserRoleModal({ user, onClose, onChange }) {
})
}, [user])

useEffect(() => {
getRolesByGroupApi('', userGroupSelected).then(data => {
//@ts-ignore
const roleOptions = data.map(role => ({ ...role, role_id: role.id }))
setRoles(roleOptions);
})
},[userGroupSelected])

const { message } = useToast()
const handleSave = async () => {
if (!selected.length) return message({ title: t('prompt'), variant: 'warning', description: '请选择角色' })
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/src/pages/SystemPage/components/Users.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ export default function Users(params) {
{user.user_id === el.user_id ? <Button variant="link" className="text-gray-400 px-0">{t('edit')}</Button> :
<Button variant="link" onClick={() => setCurrentUser(el)} className="px-0">{t('edit')}</Button>}
{/* 重置密码 */}
{/* {user.role === 'admin' && <Button variant="link" className="px-0 pl-4" onClick={() => userPwdModalRef.current.open(el.user_id)}>重置密码</Button>} */}
{user.role === 'admin' && <Button variant="link" className="px-0 pl-4" onClick={() => userPwdModalRef.current.open(el.user_id)}>重置密码</Button>}
{/* 禁用 */}
{
el.delete === 1 ? <Button variant="link" onClick={() => handleEnableUser(el)} className="text-green-500 px-0 pl-4">{t('enable')}</Button> :
Expand Down
18 changes: 16 additions & 2 deletions src/frontend/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,24 @@ import { visualizer } from "rollup-plugin-visualizer";
import { defineConfig } from "vite";
import { viteStaticCopy } from 'vite-plugin-static-copy';
import svgr from "vite-plugin-svgr";
const apiRoutes = ["^/api/", "/health"];
const apiRoutes = ["^/api/", "^/gw/", "/health"];
import path from "path";
// Use environment variable to determine the target.
const target = process.env.VITE_PROXY_TARGET || "http://127.0.0.1:7860";
const target = process.env.VITE_PROXY_TARGET || "http://192.168.106.120:3002";
// const target = process.env.VITE_PROXY_TARGET || "http://192.168.106.115:8098";
// const target = process.env.VITE_PROXY_TARGET || "http://192.168.106.116:7861";
// const target = process.env.VITE_PROXY_TARGET || "http://192.168.2.7:7860";

const proxyTargets = apiRoutes.reduce((proxyObj, route) => {

proxyObj['/gw/api/v1/group'] = {
target: target,
changeOrigin: true,
withCredentials: true,
rewrite: (path) => path.replace(/^\/gw\/api\/v1\/group/, '/group'),
secure: false,
ws: true,
};
proxyObj[route] = {
target: target,
changeOrigin: true,
Expand All @@ -28,7 +40,9 @@ const proxyTargets = apiRoutes.reduce((proxyObj, route) => {

export default defineConfig(() => {
return {
// base: '/poo',
build: {
// minify: 'esbuild', // 使用 esbuild 进行 Tree Shaking 和压缩
outDir: "build",
rollupOptions: {
output: {
Expand Down

0 comments on commit 532e0af

Please sign in to comment.