Compare commits

...

10 Commits

8 changed files with 52 additions and 19 deletions
+1 -1
View File
@@ -8,7 +8,7 @@
"description": "",
"scripts": {
"test": "jest",
"build": "set NODE_OPTIONS=--max-old-space-size=4096 && lerna run build --scope=core --stream --verbose ",
"build": "set NODE_OPTIONS=--max-old-space-size=8192 && lerna run build --scope=core --stream --verbose ",
"serve": "lerna run preview --parallel",
"serve:remotes": "lerna run serve --scope=remote --parallel",
"dev": "lerna run dev --scope=core --stream",
@@ -19,7 +19,7 @@ export type MemberTableListItem = {
enable:boolean
departmentId:string
roles:EntityItem[]
form: string
from: string
};
export type AddToDepartmentProps = {
@@ -41,7 +41,7 @@ export type MemberDropdownModalFieldType = {
export type MemberDropdownModalProps = {
type:'addDep'|'addChild'|'addMember'|'editMember'|'rename'
entity?:(MemberTableListItem & {departmentIds:string[]}) | ({id?:string, departmentIds?:string[],name?:string,form?:string})
entity?:(MemberTableListItem & {departmentIds:string[]}) | ({id?:string, departmentIds?:string[],name?:string,from?:string})
selectedMemberGroupId?:string
}
+23 -3
View File
@@ -93,6 +93,11 @@ const Login: FC = () => {
const code = query.get('code')
if (code) {
feishuLogin(code)
setSpinning(false)
return
}
if (isInFeishuClient() && feishu) {
openFeishuLogin(feishu.config.client_id)
}
setSpinning(false)
}
@@ -161,10 +166,25 @@ const Login: FC = () => {
fetchLogin({ username: 'guest', password: '12345678' })
}
const isInFeishuClient = () => {
// 方法1:检查User-Agent
const ua = navigator.userAgent.toLowerCase();
const isLark = ua.includes('lark') || ua.includes('feishu');
// 方法2:检查全局对象
const hasSDK = typeof window.h5sdk !== 'undefined' || typeof window.tt !== 'undefined';
// 方法3:检查URL参数
const params = new URLSearchParams(window.location.search);
const hasFeishuParams = params.has('from') || params.has('required_launch_ability');
return isLark || hasSDK || hasFeishuParams;
}
// 打开飞书授权页面
const openFeishuLogin = () => {
const openFeishuLogin = (id?: string) => {
const href = window.location.origin + window.location.pathname
const authUrl = `https://accounts.feishu.cn/open-apis/authen/v1/authorize?client_id=${feishuAppId}&redirect_uri=${href}`
const authUrl = `https://accounts.feishu.cn/open-apis/authen/v1/authorize?client_id=${id || feishuAppId}&redirect_uri=${href}`
localStorage.setItem('feishuCallbackUrl', href)
window.location.href = authUrl
}
@@ -336,7 +356,7 @@ const Login: FC = () => {
loading={loading}
className="h-[40px] w-full inline-flex justify-center items-center"
type="default"
onClick={openFeishuLogin}
onClick={() => openFeishuLogin(feishuAppId)}
>
<img className="h-[30px]" src={FeishuLogo} />
{$t('飞书授权登录')}
@@ -14,8 +14,7 @@ export const MemberDropdownModal = forwardRef<MemberDropdownModalHandle,MemberDr
const {fetchData} = useFetch()
const [departmentList, setDepartmentList] = useState<DepartmentListItem[]>([])
const { state } = useGlobalContext()
const [disableEditMemberData] = useState<boolean>(entity?.form !== 'self-build')
const [disableEditMemberData] = useState<boolean>(entity?.from === 'feishu')
const save:()=>Promise<boolean | string> = ()=>{
let url:string
let method:string
@@ -95,14 +95,15 @@ const AddToDepartment = forwardRef<AddToDepartmentHandle, AddToDepartmentProps>(
treeData?.map((x: DataNode) => ({
...x,
name: $t((x as unknown as { name: string }).name),
checkable: false,
children: x.children?.map(y => ({ ...y, checkable: false }))
checkable: false, // 根节点不可选中
children: x.children?.map(y => ({ ...y, checkable: true })) // 子节点可以选中
})),
[state.language, treeData]
)
const onCheck: TreeProps['onCheck'] = (checkedKeys: string[]) => {
setSelectedKeys(checkedKeys.checked)
const onCheck: TreeProps['onCheck'] = (checkedKeys, info) => {
const selectedIds = Array.isArray(checkedKeys) ? checkedKeys : checkedKeys.checked || []
setSelectedKeys(selectedIds)
}
useEffect(() => {
@@ -153,11 +154,12 @@ const MemberList = () => {
const [tableHttpReload, setTableHttpReload] = useState(true)
const [tableListDataSource, setTableListDataSource] = useState<MemberTableListItem[]>([])
const pageListRef = useRef<ActionType>(null)
const { topGroupId, selectedDepartmentIds, refreshGroup } = useOutletContext<{
const { topGroupId, selectedDepartmentIds, refreshGroup, refreshTableCount } = useOutletContext<{
topGroupId: string
departmentList: DepartmentListItem[]
selectedDepartmentIds: string[]
refreshGroup: () => void
refreshTableCount: number
}>()
const AddMemberRef = useRef<MemberDropdownModalHandle>(null)
const EditMemberRef = useRef<MemberDropdownModalHandle>(null)
@@ -396,7 +398,7 @@ const MemberList = () => {
width: 600,
okText: $t('确认'),
okButtonProps: {
disabled: isActionAllowed(type) || (type === 'editMember' && entity?.form !== 'self-build')
disabled: isActionAllowed(type) || (type === 'editMember' && entity?.from === 'feishu')
},
cancelText: $t('取消'),
closable: true,
@@ -415,6 +417,13 @@ const MemberList = () => {
getDepartmentList()
}, [])
// 监听外部刷新触发器
useEffect(() => {
if (refreshTableCount > 0) {
manualReloadTable()
}
}, [refreshTableCount])
const getDepartmentList = async () => {
setDepartmentValueEnum([])
const { code, data, msg } = await fetchData<BasicResponse<{ department: DepartmentListItem }>>(
@@ -36,6 +36,11 @@ const MemberPage = ()=>{
const [selectedDepartmentId, setSelectedDepartmentId] = useState<string>('-1')
const {accessData,state} = useGlobalContext()
const [refreshMemberCount, setRefreshMemberCount] = useState<number>(0)
const [refreshTableCount, setRefreshTableCount] = useState<number>(0)
const refreshMemberTable = () => {
setRefreshTableCount(prev => prev + 1)
}
const onSearchWordChange = (e:string)=>{
setSearchWord(e || '')
}
@@ -90,7 +95,7 @@ const MemberPage = ()=>{
case 'addChild':
return AddChildRef.current?.save().then((res)=>{if(res === true)getDepartmentList()})
case 'addMember':
return AddMemberRef.current?.save().then((res)=>{if(res === true){getDepartmentList();setRefreshMemberCount(pre=>pre+1)}})
return AddMemberRef.current?.save().then((res)=>{if(res === true){getDepartmentList();setRefreshMemberCount(pre=>pre+1);refreshMemberTable()}})
case 'rename':
return RenameRef.current?.save().then((res)=>{if(res === true)getDepartmentList()})
case 'delete':
@@ -262,7 +267,7 @@ const MemberPage = ()=>{
</div>
</div>
<div className="flex-1 p-btnbase pr-PAGE_INSIDE_X overflow-x-hidden">
<Outlet context={{refreshMemberCount, selectedDepartmentIds,refreshGroup:()=>getDepartmentList()}}/>
<Outlet context={{refreshMemberCount, selectedDepartmentIds,refreshGroup:()=>getDepartmentList(), refreshTableCount}}/>
</div>
</div>
</InsidePage>);
@@ -20,7 +20,7 @@ export default function ManagementInsidePage() {
const { message } = App.useApp()
const { fetchData } = useFetch()
const { setBreadcrumb } = useBreadcrumb()
const [activeMenu, setActiveMenu] = useState<string>('service')
const [activeMenu, setActiveMenu] = useState<string>('authorization')
const { appId, teamId } = useParams<RouterParams>()
const navigateTo = useNavigate()
const currentUrl = useLocation().pathname
@@ -56,7 +56,7 @@ export default function ManagementInsidePage() {
}, [accessData, accessInit, TENANT_MANAGEMENT_APP_MENU])
useEffect(() => {
setActiveMenu(currentUrl.split('/').pop() || 'service')
setActiveMenu(currentUrl.split('/').pop() || 'authorization')
}, [currentUrl])
const onMenuClick: MenuProps['onClick'] = (node) => {
@@ -336,7 +336,7 @@ export default function ServiceHubManagement() {
setTableSearchWord={setTableSearchWord}
editApp={(row: ServiceHubAppListItem) => {
setAppName(row.name)
navigateTo(`/consumer/${row.team.id}/inside/${row.id}/service`)
navigateTo(`/consumer/${row.team.id}/inside/${row.id}/authorization`)
}}
/>
)}