Commit b2203c5d authored by Ylg's avatar Ylg

resolve file conflict

parents cad06772 a252c5a5
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* @see https://umijs.org/zh-CN/plugins/plugin-access * @see https://umijs.org/zh-CN/plugins/plugin-access
* */ * */
export default function access(initialState: { currentUser?: API.CurrentUser } | undefined) { export default function access(initialState: { currentUser?: API.CurrentUser } | undefined) {
console.log(initialState)
const { currentUser } = initialState ?? {}; const { currentUser } = initialState ?? {};
return { return {
canAdmin: currentUser && currentUser.access === 'admin', canAdmin: currentUser && currentUser.access === 'admin',
......
import Footer from '@/components/Footer'; import Footer from '@/components/Footer';
import RightContent from '@/components/RightContent'; import RightContent from '@/components/RightContent';
import type { Settings as LayoutSettings } from '@ant-design/pro-components';
import { PageLoading, SettingDrawer } from '@ant-design/pro-components'; import { PageLoading, SettingDrawer } from '@ant-design/pro-components';
import type { RunTimeLayoutConfig } from 'umi'; import { isEmpty } from 'lodash';
import { history } from 'umi'; import { history } from 'umi';
import defaultSettings from '../config/defaultSettings';
import { currentUser as queryCurrentUser } from './services/ant-design-pro/api';
const loginPath = '/chat'; const loginPath = '/chat';
/** 获取用户信息比较慢的时候会展示一个 loading */ /** 获取用户信息比较慢的时候会展示一个 loading */
...@@ -18,52 +13,24 @@ export const initialStateConfig = { ...@@ -18,52 +13,24 @@ export const initialStateConfig = {
/** /**
* @see https://umijs.org/zh-CN/plugins/plugin-initial-state * @see https://umijs.org/zh-CN/plugins/plugin-initial-state
* */ * */
export async function getInitialState(): Promise<{ export async function getInitialState() {
settings?: Partial<LayoutSettings>; const userMessage = JSON.parse(localStorage.getItem('user'));
currentUser?: API.CurrentUser;
loading?: boolean; if (isEmpty(userMessage)) {
fetchUserInfo?: () => Promise<API.CurrentUser | undefined>;
}> {
const fetchUserInfo = async () => {
try {
const msg = await queryCurrentUser();
return msg.data;
} catch (error) {
history.push(loginPath); history.push(loginPath);
return {};
} }
return undefined;
}; return { userMessage };
// 如果不是登录页面,执行
if (history.location.pathname !== loginPath) {
const currentUser = await fetchUserInfo();
return {
fetchUserInfo,
currentUser,
settings: defaultSettings,
};
}
return {
fetchUserInfo,
settings: defaultSettings,
};
} }
// ProLayout 支持的api https://procomponents.ant.design/components/layout // ProLayout 支持的api https://procomponents.ant.design/components/layout
export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) => { export const layout = ({ initialState, setInitialState }) => {
return { return {
rightContentRender: () => <RightContent />, rightContentRender: () => <RightContent />,
disableContentMargin: false, disableContentMargin: false,
waterMarkProps: {
content: initialState?.currentUser?.name,
},
footerRender: () => <Footer />, footerRender: () => <Footer />,
onPageChange: () => {
const { location } = history;
// 如果没有登录,重定向到 login
if (!initialState?.currentUser && location.pathname !== loginPath) {
history.push(loginPath);
}
},
menuHeaderRender: undefined, menuHeaderRender: undefined,
// 自定义 403 页面 // 自定义 403 页面
// unAccessible: <div>unAccessible</div>, // unAccessible: <div>unAccessible</div>,
......
@import (reference) '~antd/es/style/themes/index';
.headerSearch {
display: inline-flex;
align-items: center;
.input {
width: 0;
min-width: 0;
overflow: hidden;
background: transparent;
border-radius: 0;
transition: width 0.3s, margin-left 0.3s;
:global(.ant-select-selection) {
background: transparent;
}
input {
box-shadow: none !important;
}
&.show {
width: 210px;
margin-left: 8px;
}
}
}
import { SearchOutlined } from '@ant-design/icons';
import type { InputRef } from 'antd';
import { AutoComplete, Input } from 'antd';
import type { AutoCompleteProps } from 'antd/es/auto-complete';
import classNames from 'classnames';
import useMergedState from 'rc-util/es/hooks/useMergedState';
import React, { useRef } from 'react';
import styles from './index.less';
export type HeaderSearchProps = {
onSearch?: (value?: string) => void;
onChange?: (value?: string) => void;
onVisibleChange?: (b: boolean) => void;
className?: string;
placeholder?: string;
options: AutoCompleteProps['options'];
defaultVisible?: boolean;
visible?: boolean;
defaultValue?: string;
value?: string;
};
const HeaderSearch: React.FC<HeaderSearchProps> = (props) => {
const {
className,
defaultValue,
onVisibleChange,
placeholder,
visible,
defaultVisible,
...restProps
} = props;
const inputRef = useRef<InputRef | null>(null);
const [value, setValue] = useMergedState<string | undefined>(defaultValue, {
value: props.value,
onChange: props.onChange,
});
const [searchMode, setSearchMode] = useMergedState(defaultVisible ?? false, {
value: props.visible,
onChange: onVisibleChange,
});
const inputClass = classNames(styles.input, {
[styles.show]: searchMode,
});
return (
<div
className={classNames(className, styles.headerSearch)}
onClick={() => {
setSearchMode(true);
if (searchMode && inputRef.current) {
inputRef.current.focus();
}
}}
onTransitionEnd={({ propertyName }) => {
if (propertyName === 'width' && !searchMode) {
if (onVisibleChange) {
onVisibleChange(searchMode);
}
}
}}
>
<SearchOutlined
key="Icon"
style={{
cursor: 'pointer',
}}
/>
<AutoComplete
key="AutoComplete"
className={inputClass}
value={value}
options={restProps.options}
onChange={(completeValue) => setValue(completeValue)}
>
<Input
size="small"
ref={inputRef}
defaultValue={defaultValue}
aria-label={placeholder}
placeholder={placeholder}
onKeyDown={(e) => {
if (e.key === 'Enter') {
if (restProps.onSearch) {
restProps.onSearch(value);
}
}
}}
onBlur={() => {
setSearchMode(false);
}}
/>
</AutoComplete>
</div>
);
};
export default HeaderSearch;
import { QuestionCircleOutlined } from '@ant-design/icons';
import { Space } from 'antd'; import { Space } from 'antd';
import React from 'react'; import React from 'react';
import { SelectLang, useModel } from 'umi'; import { SelectLang, useModel } from 'umi';
import HeaderSearch from '../HeaderSearch';
import Avatar from './AvatarDropdown'; import Avatar from './AvatarDropdown';
import styles from './index.less'; import styles from './index.less';
...@@ -23,37 +21,6 @@ const GlobalHeaderRight: React.FC = () => { ...@@ -23,37 +21,6 @@ const GlobalHeaderRight: React.FC = () => {
} }
return ( return (
<Space className={className}> <Space className={className}>
<HeaderSearch
className={`${styles.action} ${styles.search}`}
placeholder="站内搜索"
defaultValue="umi ui"
options={[
{ label: <a href="https://umijs.org/zh/guide/umi-ui.html">umi ui</a>, value: 'umi ui' },
{
label: <a href="next.ant.design">Ant Design</a>,
value: 'Ant Design',
},
{
label: <a href="https://protable.ant.design/">Pro Table</a>,
value: 'Pro Table',
},
{
label: <a href="https://prolayout.ant.design/">Pro Layout</a>,
value: 'Pro Layout',
},
]}
// onSearch={value => {
// console.log('input', value);
// }}
/>
<span
className={styles.action}
onClick={() => {
window.open('https://pro.ant.design/docs/getting-started');
}}
>
<QuestionCircleOutlined />
</span>
<Avatar /> <Avatar />
<SelectLang className={styles.action} /> <SelectLang className={styles.action} />
</Space> </Space>
......
...@@ -52,57 +52,6 @@ export default () => { ...@@ -52,57 +52,6 @@ export default () => {
}; };
``` ```
## HeaderSearch 头部搜索框
一个带补全数据的输入框,支持收起和展开 Input
```tsx
/**
* background: '#f0f2f5'
*/
import HeaderSearch from '@/components/HeaderSearch';
import React from 'react';
export default () => {
return (
<HeaderSearch
placeholder="站内搜索"
defaultValue="umi ui"
options={[
{ label: 'Ant Design Pro', value: 'Ant Design Pro' },
{
label: 'Ant Design',
value: 'Ant Design',
},
{
label: 'Pro Table',
value: 'Pro Table',
},
{
label: 'Pro Layout',
value: 'Pro Layout',
},
]}
onSearch={(value) => {
console.log('input', value);
}}
/>
);
};
```
### API
| 参数 | 说明 | 类型 | 默认值 |
| --------------- | ---------------------------------- | ---------------------------- | ------ |
| value | 输入框的值 | `string` | - |
| onChange | 值修改后触发 | `(value?: string) => void` | - |
| onSearch | 查询后触发 | `(value?: string) => void` | - |
| options | 选项菜单的的列表 | `{label,value}[]` | - |
| defaultVisible | 输入框默认是否显示,只有第一次生效 | `boolean` | - |
| visible | 输入框是否显示 | `boolean` | - |
| onVisibleChange | 输入框显示隐藏的回调函数 | `(visible: boolean) => void` | - |
## NoticeIcon 通知工具 ## NoticeIcon 通知工具
通知工具提供一个展示多种通知信息的界面。 通知工具提供一个展示多种通知信息的界面。
......
/* eslint-disable @typescript-eslint/no-unused-expressions */ /* eslint-disable @typescript-eslint/no-unused-expressions */
import { Form, Button, Col, Row, Input, Typography } from 'antd'; import { Form, Button, Col, Row, Input, Typography, Grid } from 'antd';
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import styles from './index.less'; import styles from './index.less';
import ChatFirstContent from './components/content'; import ChatFirstContent from './components/content';
import { import {
DeleteOutlined,
FieldTimeOutlined, FieldTimeOutlined,
MenuOutlined, MenuOutlined,
PlusOutlined, PlusOutlined,
...@@ -13,7 +12,7 @@ import { ...@@ -13,7 +12,7 @@ import {
WechatOutlined, WechatOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
import classNames from 'classnames'; import classNames from 'classnames';
import { Grid } from 'antd'; import { history } from 'umi';
import LoginModal from '@/components/loginModal'; import LoginModal from '@/components/loginModal';
import NewSession from '@/components/newSession'; import NewSession from '@/components/newSession';
...@@ -31,7 +30,7 @@ const Chat: React.FC = () => { ...@@ -31,7 +30,7 @@ const Chat: React.FC = () => {
const [selectSiderTabs, setSelectSiderTabs] = useState(''); const [selectSiderTabs, setSelectSiderTabs] = useState('');
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const tabShow = showSider && !isMobile ; const tabShow = showSider;
const questionValue = form.getFieldValue('chatInput'); const questionValue = form.getFieldValue('chatInput');
...@@ -59,25 +58,20 @@ const Chat: React.FC = () => { ...@@ -59,25 +58,20 @@ const Chat: React.FC = () => {
}; };
const setInput = (value: any) => { const setInput = (value: any) => {
setChat(value?.firstInput);
form.setFieldValue('chatInput', value?.firstInput); form.setFieldValue('chatInput', value?.firstInput);
}; };
const onChange = (value: any) => { const onChange = (value: any) => {
console.log(value);
value?.chatInput && setChat(value?.chatInput); value?.chatInput && setChat(value?.chatInput);
value?.firstInput && setInput(value); value?.firstInput && setInput(value);
}; };
const siderTabsList = [ const siderTabsList = [
{
icons: <DeleteOutlined />,
text: '清空所有会话',
checked: 'clear',
},
{ {
icons: <SettingOutlined />, icons: <SettingOutlined />,
text: '预留功能', text: '后台',
checked: 'moreFunction', checked: 'gotoAdmin',
}, },
{ {
icons: <WechatOutlined />, icons: <WechatOutlined />,
...@@ -93,6 +87,9 @@ const Chat: React.FC = () => { ...@@ -93,6 +87,9 @@ const Chat: React.FC = () => {
const selectSliderTabsHandleClick = (value: string) => { const selectSliderTabsHandleClick = (value: string) => {
setSelectSiderTabs(value); setSelectSiderTabs(value);
if (value === 'gotoAdmin') {
history.push('/admin/user');
}
}; };
const renderMobileHeader = () => { const renderMobileHeader = () => {
...@@ -192,10 +189,7 @@ const Chat: React.FC = () => { ...@@ -192,10 +189,7 @@ const Chat: React.FC = () => {
onFinish={onSend} onFinish={onSend}
> >
{firstChat ? ( {firstChat ? (
<NewSession <NewSession questionValue={chat} answerValue="" />
questionValue={chat}
answerValue=''
/>
) : ( ) : (
<div className={classNames(isMobile && styles.mobileContent)}> <div className={classNames(isMobile && styles.mobileContent)}>
<Item name="firstInput"> <Item name="firstInput">
...@@ -218,11 +212,7 @@ const Chat: React.FC = () => { ...@@ -218,11 +212,7 @@ const Chat: React.FC = () => {
<Col span={4} push={isMobile ? 0 : 4}> <Col span={4} push={isMobile ? 0 : 4}>
<div className={styles.outputButtonWrapper}> <div className={styles.outputButtonWrapper}>
<Item name="outputButton"> <Item name="outputButton">
<Button <Button htmlType="submit" type="primary" size="large">
htmlType="submit"
type="primary"
size="large"
>
发送 发送
</Button> </Button>
</Item> </Item>
......
import { EllipsisOutlined, PlusOutlined } from '@ant-design/icons'; import { PlusOutlined } from '@ant-design/icons';
import { ActionType, PageContainer, ProColumns } from '@ant-design/pro-components'; import type { ActionType } from '@ant-design/pro-components';
import { ProTable, TableDropdown } from '@ant-design/pro-components'; import { PageContainer } from '@ant-design/pro-components';
import { Button, Dropdown, Space, Tag } from 'antd'; import { ProTable } from '@ant-design/pro-components';
import { Button } from 'antd';
import { useRef } from 'react'; import { useRef } from 'react';
import request from 'umi-request'; import request from 'umi-request';
export const waitTimePromise = async (time: number = 100) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(true);
}, time);
});
};
export const waitTime = async (time: number = 100) => {
await waitTimePromise(time);
};
type GithubIssueItem = {
url: string;
id: number;
number: number;
title: string;
labels: {
name: string;
color: string;
}[];
state: string;
comments: number;
created_at: string;
updated_at: string;
closed_at?: string;
};
const columns: ProColumns<GithubIssueItem>[] = [ const columns: any[] = [
{ {
dataIndex: 'index', title: '用户',
valueType: 'indexBorder', dataIndex: 'name',
width: 48, ellipsis: true,
}, },
{ {
title: '标题', title: '用户账号',
dataIndex: 'title', dataIndex: 'username',
copyable: true,
ellipsis: true, ellipsis: true,
tip: '标题过长会自动收缩',
formItemProps: {
rules: [
{
required: true,
message: '此项为必填项',
},
],
},
}, },
{ {
disable: true, title: '角色',
title: '状态', dataIndex: 'role',
dataIndex: 'state', hideInSearch: true,
filters: true,
onFilter: true,
ellipsis: true, ellipsis: true,
valueType: 'select',
valueEnum: {
all: { text: '超长'.repeat(50) },
open: {
text: '未解决',
status: 'Error',
},
closed: {
text: '已解决',
status: 'Success',
disabled: true,
},
processing: {
text: '解决中',
status: 'Processing',
},
},
}, },
{ {
disable: true, title: '账号状态',
title: '标签', dataIndex: 'iaActive',
dataIndex: 'labels', hideInSearch: true,
search: false,
renderFormItem: (_, { defaultRender }) => {
return defaultRender(_);
},
render: (_, record) => (
<Space>
{record.labels.map(({ name, color }) => (
<Tag color={color} key={name}>
{name}
</Tag>
))}
</Space>
),
}, },
{ {
title: '创建时间', title: '创建时间',
key: 'showTime', dataIndex: 'creationTime',
dataIndex: 'created_at',
valueType: 'date',
sorter: true,
hideInSearch: true, hideInSearch: true,
valueType: 'date',
}, },
{ {
title: '创建时间', title: '备注',
dataIndex: 'created_at', hideInSearch: true,
valueType: 'dateRange', dataIndex: 'creationTime',
hideInTable: true, valueType: 'date',
search: {
transform: (value) => {
return {
startTime: value[0],
endTime: value[1],
};
},
},
}, },
{ {
title: '操作', title: '操作',
...@@ -132,16 +54,11 @@ const columns: ProColumns<GithubIssueItem>[] = [ ...@@ -132,16 +54,11 @@ const columns: ProColumns<GithubIssueItem>[] = [
编辑 编辑
</a>, </a>,
<a href={record.url} target="_blank" rel="noopener noreferrer" key="view"> <a href={record.url} target="_blank" rel="noopener noreferrer" key="view">
查看 重置
</a>,
<a href={record.url} target="_blank" rel="noopener noreferrer" key="view">
删除
</a>, </a>,
<TableDropdown
key="actionGroup"
onSelect={() => action?.reload()}
menus={[
{ key: 'copy', name: '复制' },
{ key: 'delete', name: '删除' },
]}
/>,
], ],
}, },
]; ];
...@@ -150,54 +67,36 @@ const UserManage = () => { ...@@ -150,54 +67,36 @@ const UserManage = () => {
const actionRef = useRef<ActionType>(); const actionRef = useRef<ActionType>();
return ( return (
<PageContainer> <PageContainer>
<ProTable<GithubIssueItem> <ProTable
columns={columns} columns={columns}
actionRef={actionRef} actionRef={actionRef}
cardBordered cardBordered
request={async (params = {}, sort, filter) => { request={async (params = {}, sort, filter) => {
const defaultParams = {
name: '',
Enabled: false,
PageSize: 9,
PageIndex: 1,
};
return request<{ return request<{
data: GithubIssueItem[]; data: any[];
}>('https://proapi.azurewebsites.net/github/issues', { }>('https://glm-mangement-api.baibaomen.com/User/page', {
params, method: 'POST',
headers: {
'Content-Type': 'application/json',
__tenant: '3a0a90fe-9a0d-70f4-200d-a80a41fb6195',
},
data: defaultParams,
}); });
}} }}
editable={{
type: 'multiple',
}}
columnsState={{
persistenceKey: 'pro-table-singe-demos',
persistenceType: 'localStorage',
onChange(value) {
console.log('value: ', value);
},
}}
rowKey="id" rowKey="id"
search={{
labelWidth: 'auto',
}}
options={{
setting: {
listsHeight: 400,
},
}}
form={{
// 由于配置了 transform,提交的参与与定义的不同这里需要转化一下
syncToUrl: (values, type) => {
if (type === 'get') {
return {
...values,
created_at: [values.startTime, values.endTime],
};
}
return values;
},
}}
pagination={{ pagination={{
pageSize: 5, pageSize: 5,
onChange: (page) => console.log(page), onChange: (page) => {},
}} }}
options={false}
dateFormatter="string" dateFormatter="string"
headerTitle="高级表格" headerTitle="账号列表"
toolBarRender={() => [ toolBarRender={() => [
<Button <Button
key="button" key="button"
...@@ -207,31 +106,8 @@ const UserManage = () => { ...@@ -207,31 +106,8 @@ const UserManage = () => {
}} }}
type="primary" type="primary"
> >
新建 添加账号
</Button>, </Button>,
<Dropdown
key="menu"
menu={{
items: [
{
label: '1st item',
key: '1',
},
{
label: '2nd item',
key: '1',
},
{
label: '3rd item',
key: '1',
},
],
}}
>
<Button>
<EllipsisOutlined />
</Button>
</Dropdown>,
]} ]}
/> />
</PageContainer> </PageContainer>
......
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