| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659 |
- import * as React from 'react';
- import { observer } from 'mobx-react';
- import { List, Button, Divider, Flex, Layout, Empty, Image, Modal, Tag, message, Tooltip, Select, Form } from 'antd';
- import { PlusOutlined, FileOutlined, SettingOutlined, DeleteOutlined, StepForwardOutlined } from '@ant-design/icons';
- import { apis } from '@/apis';
- import './style.less';
- import { PaginationConfig } from 'antd/es/pagination';
- import router from '@/router';
- import LocalStorage from '@/LocalStorage';
- import { create } from 'domain';
- import audit from '../../audit';
- import { set } from 'mobx';
- const { Header, Footer, Sider, Content } = Layout;
- const { Option } = Select;
- const FormItem = Form.Item;
- const headerStyle: React.CSSProperties = {
- textAlign: 'center',
- height: 24,
- paddingInline: 48,
- lineHeight: '30px',
- backgroundColor: '#fff',
- };
- const contentStyle: React.CSSProperties = {
- textAlign: 'center',
- lineHeight: '40px',
- backgroundColor: '#fff',
- };
- const siderStyle: React.CSSProperties = {
- paddingLeft: 30,
- paddingTop: 30,
- height: 80,
- backgroundColor: '#fff',
- };
- const footerStyle: React.CSSProperties = {
- textAlign: 'center',
- color: '#fff',
- height: 24,
- backgroundColor: '#4096ff',
- };
- const layoutStyle = {
- borderRadius: 8,
- overflow: 'hidden',
- width: 'calc(10% - 8px)',
- maxWidth: 'calc(20% - 8px)',
- };
- const QuestionAnswerList: React.FC = () => {
- const [form] = Form.useForm();
- interface Item {
- name: string,
- desc: string,
- appId: number,
- createBy: string,
- typeId: string;
- status: string;
- comment: string;
- auditStatus: string;
- projectName: string;
- };
- interface PageInfo {
- pageNumber: number,
- pageSize: number,
- total: number,
- };
- type AppTypeList = {
- label: string,
- value: string,
- }[];
- type ProjectTypeList = {
- label: string,
- value: string,
- }[];
- const [listLoading, setListLoading] = React.useState(false);
- const [list, setList] = React.useState<Item[]>([]);
- const [page, setPage] = React.useState<PageInfo>({
- pageNumber: 1,
- pageSize: 10,
- total: 0,
- });
- const [appCount, setAppCount] = React.useState<string>();
- const [knowCount, setKnowCount] = React.useState<string>();
- const { Header, Footer, Sider, Content } = Layout;
- const [appTypeList, setAppTypeList] = React.useState<AppTypeList>([]);
- const [createFlag, setCreateFlag] = React.useState(false);
- const [deleteFlag, setDeleteFlag] = React.useState(false);
- const [updateFlag, setUpdateFlag] = React.useState(false);
- const [projectList, setProjectList] = React.useState<ProjectTypeList>([]);
- const [appProjectList, setAppProjectList] = React.useState<AppTypeList>([]);
- const [showSubPanel, setShowSubPanel] = React.useState(false);
- const [selectedType, setSelectedType] = React.useState<number | null>(null);
- const wrapperRef = React.useRef<HTMLDivElement>(null);
- const selectRef = React.useRef<any>(null);
- const [levelTypeList, setLevelTypeList] = React.useState<AppTypeList>([]);
- const appApi = {
- fetchList: async (typeId: any, projectId: any) => {
- setListLoading(true);
- try {
- const userInfo = LocalStorage.getUserInfo();
- const userId = (userInfo?.id ?? '').toString();
- const res = await apis.fetchTakaiAppList({
- pageSize: page.pageSize,
- pageNumber: page.pageNumber,
- userId: userId,
- typeId: typeId,
- projectId: projectId,
- })
- const list = res.rows.map((item: any) => {
- return {
- name: item.name,
- desc: item.desc,
- appId: item.appId,
- createBy: item.createBy,
- typeId: item.typeId,
- status: item.status,
- comment: item.comment,
- auditStatus: item.auditStatus,
- projectName: item.projectName
- }
- });
- const c = LocalStorage.getStatusFlag('deepseek:application:create');
- const u = LocalStorage.getStatusFlag('deepseek:application:delete');
- const filteredList = list.filter((item: any) => {
- // 如果有 createFlag 或 updateFlag 权限,显示所有数据
- if (c || u) {
- return true;
- }
- // 没有权限时排除 status='5' 的数据
- return item.status !== '5';
- });
- setList(filteredList);
- setPage({
- pageNumber: page.pageNumber,
- pageSize: page.pageSize,
- total: res.total,
- });
- } catch (error) {
- console.error(error);
- } finally {
- setListLoading(false);
- }
- },
- auditApplication: async (appId: string, userId: string) => {
- const res = await apis.auditTakaiApplicationLibApi(appId, userId);
- if (res.data === 9) {
- message.error('您没有添加审核人');
- }
- await appApi.fetchList(null, null);
- }
- };
- // 删除应用
- const delApplication = async (appId: string) => {
- try {
- await apis.deleteTakaiApplicationApi(appId);
- await appApi.fetchList(null, null);
- } catch (error) {
- console.error(error);
- }
- }
- const indexApi = {
- fetchIndex: async (typeId: any, projectId: any) => {
- try {
- const userInfo = LocalStorage.getUserInfo();
- const userId = (userInfo?.id ?? '').toString();
- const res = await apis.fetchTakaiIndexCount({
- pageSize: page.pageSize,
- pageNumber: page.pageNumber,
- userId: userId,
- typeId: typeId,
- projectId: projectId,
- })
- setAppCount(res.data.applicationCount);
- setKnowCount(res.data.knowledgeCount);
- } catch (error) {
- console.error(error);
- } finally {
- setListLoading(false);
- }
- }
- };
- // 获取应用类型
- const appTypeApi = {
- fetchAppType: async () => {
- try {
- const res = await apis.fetchTakaiAppTypeList('app_type');
- const list = res.data.map((item: any) => {
- return {
- label: item.dictLabel,
- value: item.dictCode,
- }
- });
- setAppTypeList(list);
- } catch (error: any) {
- console.error(error);
- }
- },
- };
- // 项目级应用下的类型
- const appProTypeApi = {
- fetchAppProType: async () => {
- try {
- const res = await apis.fetchTakaiAppTypeList('project_type');
- const list = res.data.map((item: any) => {
- return {
- label: item.dictLabel,
- value: item.dictCode,
- }
- });
- setAppProjectList(list);
- } catch (error: any) {
- console.error(error);
- }
- },
- };
- const projectApi = {
- fetchProject: async () => {
- try {
- const res = await apis.fetchTakaiProjectLibApi();
- const list = res.data.map((item: any) => {
- return {
- label: item.projectName,
- value: item.projectId,
- }
- });
- setProjectList(list);
- } catch (error: any) {
- console.error(error);
- }
- },
- };
- // 获取应用类型
- const levelTypeApi = {
- fetchLevelAppType: async () => {
- try {
- const res = await apis.fetchTakaiAppTypeList('project_type');
- const list = res.data.map((item: any) => {
- return {
- label: item.dictLabel,
- value: item.dictCode,
- }
- });
- setLevelTypeList(list);
- } catch (error: any) {
- console.error(error);
- }
- },
- };
- const init = async () => {
- await appApi.fetchList(null, null);
- await indexApi.fetchIndex(null, null);
- await appTypeApi.fetchAppType();
- await projectApi.fetchProject();
- await appProTypeApi.fetchAppProType();
- await levelTypeApi.fetchLevelAppType();
- }
- React.useEffect(() => {
- setCreateFlag(LocalStorage.getStatusFlag('deepseek:application:create'));
- setDeleteFlag(LocalStorage.getStatusFlag('deepseek:application:delete'));
- setUpdateFlag(LocalStorage.getStatusFlag('deepseek:application:update'));
- init();
- }, [page.pageSize, page.pageNumber])
- const paginationConfig: PaginationConfig = {
- // 显示数据总量
- showTotal: (total: number) => {
- return `共 ${total} 条`;
- },
- // 展示分页条数切换
- showSizeChanger: true,
- // 指定每页显示条数
- // pageSizeOptions: ['2', '20', '50', '100'],
- // 快速跳转至某页
- showQuickJumper: true,
- current: page.pageNumber,
- pageSize: page.pageSize,
- total: page.total,
- onChange: (pageNumber, pageSize) => {
- setPage({
- pageNumber: pageNumber,
- pageSize: pageSize,
- total: page.total,
- });
- },
- };
- // 点击查询
- const handleClickSearch = async () => {
- form.validateFields().then(async (values) => {
- if(values.proTypeId){
- values.typeId = values.proTypeId;
- }
- await indexApi.fetchIndex(values.typeId, values.projectId);
- await appApi.fetchList(values.typeId, values.projectId);
- }).catch((error) => {
- console.error(error);
- });
- };
- // 点击重置
- const handleClickReset = async () => {
- form.resetFields();
- setShowSubPanel(false);
- page.pageNumber = 1;
- page.pageSize = 10;
- await appApi.fetchList(null, null);
- await indexApi.fetchIndex(null, null);
- };
- /** 点击外部关闭面板 */
- React.useEffect(() => {
- const handleClickOutside = (event: MouseEvent) => {
- if (wrapperRef.current && !wrapperRef.current.contains(event.target as Node)) {
- setShowSubPanel(false);
- }
- };
- document.addEventListener('mousedown', handleClickOutside, true);
- return () => {
- document.removeEventListener('mousedown', handleClickOutside, true);
- };
- }, []);
- const handleAppTypeChange = (value: number) => {
- console.log(value, 'sssss');
- if (value === 41) {
- // 如果是项目级应用,切换面板状态
- // setShowSubPanel(prev => !prev);
- setShowSubPanel(true);
- } else {
- // 其他选项,隐藏面板
- setShowSubPanel(false);
- }
- setSelectedType(value);
- form.setFieldsValue({ typeId: value });
- };
- const handleAppProTypeChange = (value: number) => {
- console.log(value, 'valuevalue');
- setSelectedType(value);
- form.setFieldsValue({ typeId: value });
- };
- return (
- <div >
- <div >
- <Form form={form} layout='inline' colon={false}>
- <div style={{ display: 'flex', alignItems: 'center', position: 'relative' }} >
- {/* 主选择器 */}
- <FormItem label="应用类型" name="typeId" style={{ marginBottom: 0 }}>
- <Select
- ref={selectRef}
- style={{ width: 200 }}
- placeholder="请选择应用类型"
- onChange={handleAppTypeChange}
- value={selectedType}
- allowClear
- >
- {appTypeList.map(item => (
- <Option key={item.value} value={item.value}>
- {item.label}
- </Option>
- ))}
- </Select>
- </FormItem>
- {/* 子选项面板 */}
- {showSubPanel && selectedType === 41 && (
- // <div
- // style={{
- // position: 'absolute',
- // left: '68%',
- // top: 35,
- // marginLeft: 10,
- // padding: 12,
- // background: '#fff',
- // border: '1px solid #d9d9d9',
- // borderRadius: 4,
- // boxShadow: '0 2px 8px rgba(0,0,0,0.15)',
- // zIndex: 1000,
- // width: 200
- // }}
- // >
- <FormItem
- label='类型'
- name='proTypeId'
- rules={[{ required: true, message: '类型不能为空' }]}
- >
- <Select
- placeholder='请选择'
- allowClear
- style={{ width: 200 }}
- // onChange={handleAppProTypeChange}
- >
- {
- appProjectList.map((item, index) => {
- return <Option value={item.value} key={index}>
- {item.label}
- </Option>
- })
- }
- </Select>
- </FormItem>
- // </div>
- )}
- </div>
- {/* {
- appProjectList.map((subItem, index) => (
- <div key={index}>
- {subItem.label}
- </div>
- ))
- } */}
- <FormItem
- label='项目'
- name='projectId'
- >
- <Select
- style={{ width: '200px' }}
- placeholder='请选择项目'
- allowClear
- >
- {
- projectList.map((item, index) => {
- return <Option value={item.value} key={index}>
- {item.label}
- </Option>
- })
- }
- </Select>
- </FormItem>
- <FormItem>
- <Button
- style={{ marginRight: 16 }}
- type='primary'
- onClick={handleClickSearch}
- >
- 查询
- </Button>
- <Button onClick={handleClickReset}>
- 重置
- </Button>
- </FormItem>
- </Form>
- </div>
- {
- list.length
- ?
- <div className='questionAnswerList'>
- <div style={{ overflow: 'auto' }}>
- <Flex gap="middle" wrap>
- <Layout style={layoutStyle}>
- <Sider width="25%" style={siderStyle}>
- <FileOutlined />
- </Sider>
- <Layout>
- <Header style={headerStyle}>问答应用总数</Header>
- <Content style={contentStyle}>{appCount}个</Content>
- </Layout>
- </Layout>
- <Layout style={layoutStyle}>
- <Sider width="25%" style={siderStyle}>
- <FileOutlined />
- </Sider>
- <Layout>
- <Header style={headerStyle}>知识库总数</Header>
- <Content style={contentStyle}>{knowCount} 个</Content>
- </Layout>
- </Layout>
- </Flex>
- </div>
- <div style={{ display: 'flex', justifyContent: 'space-between' }}>
- <div>所有问答应用</div>
- {
- createFlag &&
- <Button type='primary'
- icon={<PlusOutlined />}
- onClick={() => {
- router.navigate({ pathname: '/deepseek/questionAnswer/create' });
- }}>创建问答应用</Button>
- }
- </div>
- <div className='applicationList'>
- <List style={{ height: 400 }}
- grid={{
- gutter: 16,
- xs: 1,
- sm: 2,
- md: 4,
- lg: 4,
- xl: 6,
- xxl: 2, // 展示的列数
- }}
- dataSource={list}
- renderItem={(item) => (
- <List.Item>
- <div className='card'>
- <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', overflow: 'auto' }}>
- <div style={{ display: 'flex', alignItems: 'center', overflow: 'auto' }}>
- <div style={{ marginRight: 10, overflow: 'auto' }}>
- <Image
- width={30}
- height={30}
- src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
- />
- </div>
- <div style={{ overflow: 'auto' }}>
- {item.name}
- </div>
- </div>
- <div >
- <>
- {item.projectName}
- {
- (item.status !== null && item.status !== '3') &&
- < Tag style={{ marginLeft: 16, width: 65, color: '#fff', height: 25, backgroundColor: item.status === '1' ? '#D26900' : item.status === '2' ? '#408080' : item.auditStatus === '4' ? '#CE0000' : item.status === '5' ? '#5151A2' : '' }}>
- {item.status === '1' ? '待审核' : item.status === '2' ? '审核中' : item.auditStatus === '4' ? '审核拒绝' : item.status === '5' ? '待提交' : '未知'}
- </Tag>
- }
- {
- (item.auditStatus === '4') &&
- <Tooltip title={item.comment}>
- {
- item.comment !== '' && item.comment !== null && item.comment.length > 10 ?
- item.comment.substring(0, 10) + '......' :
- item.comment
- }
- </Tooltip>
- }
- </>
- </div>
- </div>
- <Divider plain></Divider>
- <div className='desc'>
- {
- item.desc !== '' && item.desc !== null && item.desc.length > 35 ? item.desc.substring(0, 35) + '......' : item.desc
- }
- </div>
- <div style={{ display: 'flex', justifyContent: 'space-between', overflow: 'auto' }}>
- <div style={{ overflow: 'auto' }}>
- {
- (item.status === '5' || item.status === '4' || item.status === '3' || item.status === '' || item.status === null) &&
- <>
- {
- updateFlag &&
- <a style={{ marginRight: 16 }} onClick={() => {
- router.navigate({ pathname: '/deepseek/questionAnswer/modify' }, { state: { id: item.appId } });
- }}>
- <SettingOutlined /> 编辑
- </a>
- }
- {
- deleteFlag &&
- <a className='text-error' onClick={() => {
- Modal.confirm({
- title: '删除',
- content: `确定删除应用名称: ` + item.name + ` 吗?`,
- okType: 'danger',
- onOk: async () => {
- await delApplication(item.appId.toString());
- }
- });
- }}>
- <DeleteOutlined /> 删除
- </a>
- }
- </>
- }
- {
- createFlag && item.status === '5' &&
- <a style={{ marginLeft: 16 }} onClick={() => {
- Modal.confirm({
- title: '提交审核',
- content: `确认提交审核应用名称: ` + item.name + `吗?`,
- okType: 'danger',
- onOk: async () => {
- const userInfo = LocalStorage.getUserInfo();
- const userId = (userInfo?.id ?? '').toString();
- appApi.auditApplication(item.appId.toString(), userId);
- }
- });
- }}>
- <StepForwardOutlined /> 提交审核
- </a>
- }
- </div>
- <div>
- <Tag
- style={{
- padding: '4px 8px',
- fontSize: 14,
- fontWeight: 'bold',
- background: '#f0f0f0',
- border: '1px solid #d9d9d9'
- }}
- >
- {
- appTypeList
- .find(item1 => item1.value.toString() === item.typeId)?.label || levelTypeList.find(item2 => item2.value.toString() === item.typeId)?.label || '未分类'
- }
- </Tag>
- </div>
- </div>
- </div>
- </List.Item>
- )}
- pagination={paginationConfig} // 分页
- />
- </div>
- </div>
- :
- <div>
- {
- createFlag &&
- <Button type='primary'
- icon={<PlusOutlined />}
- onClick={() => {
- router.navigate({ pathname: '/deepseek/questionAnswer/create' });
- }}>创建问答应用</Button>
- }
- <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
- </div>
- }
- </div >
- )
- };
- export default observer(QuestionAnswerList);
|