开发: 部分页面兼容小屏幕
This commit is contained in:
@@ -6,6 +6,7 @@ import React, { useState } from 'react';
|
||||
interface IProps {
|
||||
body: React.ReactNode;
|
||||
footer: React.ReactNode;
|
||||
phoneBtns?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const SearchBarPlugin: React.FC<IProps> = (props) => {
|
||||
@@ -43,7 +44,7 @@ export const SearchBarPlugin: React.FC<IProps> = (props) => {
|
||||
<>
|
||||
{isPhone ? (
|
||||
<>
|
||||
<Drawer title="筛选条件" open={open} onClose={() => setOpen(false)} width={'80%'}>
|
||||
<Drawer title="筛选条件" open={open} onClose={() => setOpen(false)} width={'85%'}>
|
||||
<div>{props.body}</div>
|
||||
<div
|
||||
style={{ paddingBottom: 16 }}
|
||||
@@ -59,10 +60,11 @@ export const SearchBarPlugin: React.FC<IProps> = (props) => {
|
||||
background: '#fff',
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-end',
|
||||
padding: '8px 0',
|
||||
padding: '8px 12px',
|
||||
borderRadius: 6,
|
||||
}}
|
||||
>
|
||||
{props.phoneBtns}
|
||||
<Button
|
||||
type="default"
|
||||
onClick={() => {
|
||||
|
@@ -65,6 +65,7 @@ export interface ICustFollow {
|
||||
}
|
||||
|
||||
export interface IGroup {
|
||||
members_tot?: number;
|
||||
admin_list: string;
|
||||
avatar?: string;
|
||||
adminUserIDs: string[];
|
||||
|
@@ -5,6 +5,7 @@
|
||||
* @returns
|
||||
*/
|
||||
|
||||
import { Image } from 'antd';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { IGroup, IGroupMembers } from './ChatLogsType';
|
||||
import { AdminSvg, OwnerSvg } from './components/Svgs';
|
||||
@@ -52,6 +53,7 @@ export const groupMembersListItem = (item: IGroupMembers, selectGroup: IGroup) =
|
||||
verticalAlign: 'top',
|
||||
marginTop: 12,
|
||||
}}
|
||||
title={item.name}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
@@ -63,12 +65,12 @@ export const groupMembersListItem = (item: IGroupMembers, selectGroup: IGroup) =
|
||||
width: 56,
|
||||
height: 56,
|
||||
lineHeight: 1,
|
||||
background: '#69b1ff',
|
||||
background: '#cfd1d4',
|
||||
borderRadius: 4,
|
||||
}}
|
||||
>
|
||||
{item.avatar ? (
|
||||
<img
|
||||
<Image
|
||||
style={{
|
||||
maxWidth: '100%',
|
||||
maxHeight: '100%',
|
||||
@@ -96,7 +98,6 @@ export const groupMembersListItem = (item: IGroupMembers, selectGroup: IGroup) =
|
||||
width: 72,
|
||||
textAlign: 'center',
|
||||
}}
|
||||
title={item.name}
|
||||
>
|
||||
{item.name}
|
||||
</div>
|
||||
@@ -250,7 +251,7 @@ export const GroupIcon: React.FC<IGroupIcon> = (props) => {
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<div style={{ transform: 'scale(0.65)', lineHeight: 1 }}>{el.name[0]}</div>
|
||||
<div style={{ transform: 'scale(0.65)' }}>{el.name ? el.name[0] : ''}</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@@ -258,15 +258,9 @@ const ChatLogs: React.FC = () => {
|
||||
};
|
||||
|
||||
// 监听DOM变动
|
||||
const callback = function (mutationsList: any) {
|
||||
const callback = function () {
|
||||
// Use traditional 'for loops' for IE 11
|
||||
for (let mutation of mutationsList) {
|
||||
if (mutation.type === 'childList') {
|
||||
document.querySelector('.curr_page' + param.curr_page)?.scrollIntoView(true);
|
||||
} else if (mutation.type === 'attributes') {
|
||||
console.log('The ' + mutation.attributeName + ' attribute was modified.');
|
||||
}
|
||||
}
|
||||
document.querySelector('.curr_page' + param.curr_page)?.scrollIntoView(true);
|
||||
};
|
||||
const observer = new MutationObserver(callback);
|
||||
|
||||
|
@@ -3,7 +3,7 @@ import { formatTags } from '@/pages/ChatLogs/ChatUtils';
|
||||
import { Gender } from '@/pages/ChatLogs/components/Gender';
|
||||
import { post } from '@/services/ajax';
|
||||
import { AddWay, CustType } from '@/services/config';
|
||||
import { Spin, Steps } from 'antd';
|
||||
import { Image, Spin, Steps } from 'antd';
|
||||
import { stringify } from 'qs';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import styles from './index.module.scss';
|
||||
@@ -63,7 +63,7 @@ export const CustDetailContent: React.FC<IProps> = (props) => {
|
||||
}}
|
||||
>
|
||||
<div className={styles.modalAvatar}>
|
||||
<img src={record?.avatar} alt="" />
|
||||
<Image src={record?.avatar} alt="" />
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
||||
<div style={{ fontSize: 16, display: 'flex', alignItems: 'center' }}>
|
||||
@@ -77,7 +77,7 @@ export const CustDetailContent: React.FC<IProps> = (props) => {
|
||||
</div>
|
||||
</div>
|
||||
<div>添加方式:{record ? AddWay[record?.add_way] : ''}</div>
|
||||
<div>跟进员工:{record?.user_id}</div>
|
||||
<div>跟进员工:{record?.staff_name}</div>
|
||||
<div>添加时间:{record?.create_time}</div>
|
||||
<div
|
||||
style={{
|
||||
|
@@ -4,6 +4,7 @@ import { AddWay, CustType } from '@/services/config';
|
||||
import { PageContainer } from '@ant-design/pro-components';
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
Col,
|
||||
DatePicker,
|
||||
Drawer,
|
||||
@@ -14,6 +15,7 @@ import {
|
||||
Popover,
|
||||
Row,
|
||||
Select,
|
||||
Spin,
|
||||
Table,
|
||||
Tag,
|
||||
} from 'antd';
|
||||
@@ -188,182 +190,226 @@ const CustomList: React.FC = () => {
|
||||
</Row>
|
||||
}
|
||||
/>
|
||||
|
||||
<Table
|
||||
tableLayout="fixed"
|
||||
size="middle"
|
||||
dataSource={custsList}
|
||||
style={{ padding: 16, borderRadius: 6, background: '#fff', marginTop: 16 }}
|
||||
pagination={false}
|
||||
bordered={true}
|
||||
rowKey={(record) => {
|
||||
return `${record.cust_id}_${record.user_id}`;
|
||||
}}
|
||||
loading={loading}
|
||||
onRow={(record: ICustFollow) => {
|
||||
if (
|
||||
record?.add_staff_tot &&
|
||||
!isNaN(record?.add_staff_tot) &&
|
||||
Number(record?.add_staff_tot) > 1
|
||||
) {
|
||||
return {
|
||||
style: {
|
||||
background: '#fcffe6',
|
||||
},
|
||||
};
|
||||
}
|
||||
return {};
|
||||
}}
|
||||
>
|
||||
<Table.Column
|
||||
title="客户"
|
||||
width={200}
|
||||
dataIndex={'name'}
|
||||
render={(value, record: ICustFollow) => {
|
||||
{isPhone ? (
|
||||
<Spin spinning={loading}>
|
||||
{custsList.map((item) => {
|
||||
return (
|
||||
<div
|
||||
<Card
|
||||
key={`${item.cust_id}_${item.user_id}`}
|
||||
style={{ marginTop: 16 }}
|
||||
onClick={() => {
|
||||
setRecord(record);
|
||||
setRecord(item);
|
||||
setOpen(true);
|
||||
}}
|
||||
style={{ cursor: 'pointer', display: 'flex' }}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: 56,
|
||||
height: 56,
|
||||
flexShrink: 0,
|
||||
borderRadius: 4,
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
>
|
||||
<Image width={56} height={56} src={record.avatar} />
|
||||
</div>
|
||||
<div style={{ marginLeft: 8 }}>
|
||||
<div style={{ color: '#1890ff', wordBreak: 'break-all' }}>
|
||||
{value}[{record.remark}]
|
||||
<div style={{ display: 'flex' }}>
|
||||
<div
|
||||
style={{
|
||||
width: 56,
|
||||
height: 56,
|
||||
flexShrink: 0,
|
||||
borderRadius: 4,
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
>
|
||||
<Image width={56} height={56} src={item.avatar} />
|
||||
</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<Gender gender={record.gender} />
|
||||
<span style={{ marginLeft: 4, color: '#389e0d' }}>
|
||||
@{CustType[record.type]}
|
||||
</span>
|
||||
<div style={{ marginLeft: 8 }}>
|
||||
<div style={{ color: '#1890ff', wordBreak: 'break-all' }}>
|
||||
{item.name}[{item.remark}]
|
||||
</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<Gender gender={item.gender} />
|
||||
<span style={{ marginLeft: 4, color: '#389e0d' }}>
|
||||
@{CustType[item.type]}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
})}
|
||||
</Spin>
|
||||
) : (
|
||||
<Table
|
||||
tableLayout="fixed"
|
||||
size="middle"
|
||||
dataSource={custsList}
|
||||
style={{ padding: 16, borderRadius: 6, background: '#fff', marginTop: 16 }}
|
||||
pagination={false}
|
||||
bordered={true}
|
||||
rowKey={(record) => {
|
||||
return `${record.cust_id}_${record.user_id}`;
|
||||
}}
|
||||
/>
|
||||
<Table.Column
|
||||
title="客户标签"
|
||||
width={160}
|
||||
onCell={() => {
|
||||
return {
|
||||
style: {
|
||||
paddingBottom: 8,
|
||||
},
|
||||
};
|
||||
}}
|
||||
render={(value) => {
|
||||
try {
|
||||
let arr = JSON.parse(value);
|
||||
if (arr.length) {
|
||||
return (
|
||||
<>
|
||||
{arr.length >= 3 ? (
|
||||
<Popover
|
||||
content={() => {
|
||||
return (
|
||||
<>
|
||||
{arr.map((item: any) => {
|
||||
return (
|
||||
<Tag
|
||||
key={`${item?.group_name}:${item?.tag_name}`}
|
||||
color="green"
|
||||
title={`${item?.group_name}:${item?.tag_name}`}
|
||||
style={{ marginBottom: 4 }}
|
||||
>
|
||||
{item?.tag_name}
|
||||
</Tag>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}}
|
||||
>
|
||||
<Tag
|
||||
color="green"
|
||||
title={`${arr[0]?.group_name}:${arr[0]?.tag_name}`}
|
||||
style={{ marginBottom: 4 }}
|
||||
>
|
||||
{arr[0]?.tag_name}
|
||||
</Tag>
|
||||
{arr[1] ? (
|
||||
<Tag
|
||||
color="green"
|
||||
title={`${arr[1]?.group_name}:${arr[1]?.tag_name}`}
|
||||
style={{ marginBottom: 4 }}
|
||||
>
|
||||
{arr[1]?.tag_name}
|
||||
</Tag>
|
||||
) : null}
|
||||
<Tag color="green" style={{ marginBottom: 4 }}>
|
||||
...
|
||||
</Tag>
|
||||
</Popover>
|
||||
) : (
|
||||
<div>
|
||||
<Tag
|
||||
color="green"
|
||||
title={`${arr[0]?.group_name}:${arr[0]?.tag_name}`}
|
||||
style={{ marginBottom: 4 }}
|
||||
>
|
||||
{arr[0]?.tag_name}
|
||||
</Tag>
|
||||
{arr[1] ? (
|
||||
<Tag
|
||||
color="green"
|
||||
title={`${arr[1]?.group_name}:${arr[1]?.tag_name}`}
|
||||
style={{ marginBottom: 4 }}
|
||||
>
|
||||
{arr[1]?.tag_name}
|
||||
</Tag>
|
||||
) : null}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
/* empty */
|
||||
loading={loading}
|
||||
onRow={(record: ICustFollow) => {
|
||||
if (
|
||||
record?.add_staff_tot &&
|
||||
!isNaN(record?.add_staff_tot) &&
|
||||
Number(record?.add_staff_tot) > 1
|
||||
) {
|
||||
return {
|
||||
style: {
|
||||
background: '#fcffe6',
|
||||
},
|
||||
};
|
||||
}
|
||||
return <div style={{ marginBottom: 4 }}>无标签</div>;
|
||||
return {};
|
||||
}}
|
||||
dataIndex={'tags'}
|
||||
/>
|
||||
<Table.Column
|
||||
title="跟进员工"
|
||||
width={120}
|
||||
render={(v, record: ICustFollow) => {
|
||||
return <>{record?.staff_name}</>;
|
||||
}}
|
||||
dataIndex={'user_id'}
|
||||
/>
|
||||
{/* <Table.Column title="商机阶段" width={160} dataIndex={'position'} /> */}
|
||||
<Table.Column
|
||||
title="添加方式"
|
||||
width={120}
|
||||
dataIndex={'add_way'}
|
||||
render={(value) => {
|
||||
return <>{AddWay[value]}</>;
|
||||
}}
|
||||
/>
|
||||
<Table.Column title="添加时间" width={120} dataIndex={'create_time'} />
|
||||
{/* <Table.Column title="操作" width={160} dataIndex={'position'} /> */}
|
||||
</Table>
|
||||
>
|
||||
<Table.Column
|
||||
title="客户"
|
||||
width={200}
|
||||
dataIndex={'name'}
|
||||
render={(value, record: ICustFollow) => {
|
||||
return (
|
||||
<div
|
||||
onClick={() => {
|
||||
setRecord(record);
|
||||
setOpen(true);
|
||||
}}
|
||||
style={{ cursor: 'pointer', display: 'flex' }}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: 56,
|
||||
height: 56,
|
||||
flexShrink: 0,
|
||||
borderRadius: 4,
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
>
|
||||
<Image width={56} height={56} src={record.avatar} />
|
||||
</div>
|
||||
<div style={{ marginLeft: 8 }}>
|
||||
<div style={{ color: '#1890ff', wordBreak: 'break-all' }}>
|
||||
{value}[{record.remark}]
|
||||
</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<Gender gender={record.gender} />
|
||||
<span style={{ marginLeft: 4, color: '#389e0d' }}>
|
||||
@{CustType[record.type]}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Table.Column
|
||||
title="客户标签"
|
||||
width={160}
|
||||
onCell={() => {
|
||||
return {
|
||||
style: {
|
||||
paddingBottom: 8,
|
||||
},
|
||||
};
|
||||
}}
|
||||
render={(value) => {
|
||||
try {
|
||||
let arr = JSON.parse(value);
|
||||
if (arr.length) {
|
||||
return (
|
||||
<>
|
||||
{arr.length >= 3 ? (
|
||||
<Popover
|
||||
content={() => {
|
||||
return (
|
||||
<>
|
||||
{arr.map((item: any) => {
|
||||
return (
|
||||
<Tag
|
||||
key={`${item?.group_name}:${item?.tag_name}`}
|
||||
color="green"
|
||||
title={`${item?.group_name}:${item?.tag_name}`}
|
||||
style={{ marginBottom: 4 }}
|
||||
>
|
||||
{item?.tag_name}
|
||||
</Tag>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}}
|
||||
>
|
||||
<Tag
|
||||
color="green"
|
||||
title={`${arr[0]?.group_name}:${arr[0]?.tag_name}`}
|
||||
style={{ marginBottom: 4 }}
|
||||
>
|
||||
{arr[0]?.tag_name}
|
||||
</Tag>
|
||||
{arr[1] ? (
|
||||
<Tag
|
||||
color="green"
|
||||
title={`${arr[1]?.group_name}:${arr[1]?.tag_name}`}
|
||||
style={{ marginBottom: 4 }}
|
||||
>
|
||||
{arr[1]?.tag_name}
|
||||
</Tag>
|
||||
) : null}
|
||||
<Tag color="green" style={{ marginBottom: 4 }}>
|
||||
...
|
||||
</Tag>
|
||||
</Popover>
|
||||
) : (
|
||||
<div>
|
||||
<Tag
|
||||
color="green"
|
||||
title={`${arr[0]?.group_name}:${arr[0]?.tag_name}`}
|
||||
style={{ marginBottom: 4 }}
|
||||
>
|
||||
{arr[0]?.tag_name}
|
||||
</Tag>
|
||||
{arr[1] ? (
|
||||
<Tag
|
||||
color="green"
|
||||
title={`${arr[1]?.group_name}:${arr[1]?.tag_name}`}
|
||||
style={{ marginBottom: 4 }}
|
||||
>
|
||||
{arr[1]?.tag_name}
|
||||
</Tag>
|
||||
) : null}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
/* empty */
|
||||
}
|
||||
return <div style={{ marginBottom: 4 }}>无标签</div>;
|
||||
}}
|
||||
dataIndex={'tags'}
|
||||
/>
|
||||
<Table.Column
|
||||
title="跟进员工"
|
||||
width={120}
|
||||
render={(v, record: ICustFollow) => {
|
||||
return <>{record?.staff_name}</>;
|
||||
}}
|
||||
dataIndex={'user_id'}
|
||||
/>
|
||||
{/* <Table.Column title="商机阶段" width={160} dataIndex={'position'} /> */}
|
||||
<Table.Column
|
||||
title="添加方式"
|
||||
width={120}
|
||||
dataIndex={'add_way'}
|
||||
render={(value) => {
|
||||
return <>{AddWay[value]}</>;
|
||||
}}
|
||||
/>
|
||||
<Table.Column title="添加时间" width={120} dataIndex={'create_time'} />
|
||||
{/* <Table.Column title="操作" width={160} dataIndex={'position'} /> */}
|
||||
</Table>
|
||||
)}
|
||||
<Drawer
|
||||
title={`${record?.name} 客户详情`}
|
||||
open={open}
|
||||
@@ -373,6 +419,7 @@ const CustomList: React.FC = () => {
|
||||
<CustDetailContent record={record as ICustFollow} />
|
||||
</Drawer>
|
||||
<Pagination
|
||||
size={isPhone ? 'small' : 'default'}
|
||||
style={{
|
||||
background: '#fff',
|
||||
borderRadius: 6,
|
||||
@@ -386,7 +433,7 @@ const CustomList: React.FC = () => {
|
||||
pageSize={param.page_count}
|
||||
total={count}
|
||||
pageSizeOptions={[10, 20, 50, 100]}
|
||||
onShowSizeChange={(current, size) => {
|
||||
onShowSizeChange={(_current, size) => {
|
||||
param.page_count = size;
|
||||
page(1);
|
||||
}}
|
||||
|
@@ -1,9 +1,11 @@
|
||||
import { SearchBarPlugin } from '@/components/SearchBarPlugin';
|
||||
import { post } from '@/services/ajax';
|
||||
import { getDevice } from '@/services/utils';
|
||||
import { PageContainer } from '@ant-design/pro-components';
|
||||
import {
|
||||
App,
|
||||
Button,
|
||||
Card,
|
||||
Col,
|
||||
Drawer,
|
||||
Form,
|
||||
@@ -58,7 +60,9 @@ const DepartmentsList: React.FC = () => {
|
||||
const [loadingL, setLoadingL] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [phoneDepOpen, setPhoneDepOpen] = useState(false);
|
||||
const [record, setRecord] = useState<IStaffsItem>();
|
||||
const isPhone = getDevice() == 'phone';
|
||||
|
||||
const getStaffsList = () => {
|
||||
setLoading(true);
|
||||
@@ -145,26 +149,93 @@ const DepartmentsList: React.FC = () => {
|
||||
|
||||
return (
|
||||
<PageContainer>
|
||||
<div style={{ display: 'flex' }}>
|
||||
<div
|
||||
style={{
|
||||
width: 240,
|
||||
flexShrink: 0,
|
||||
minHeight: 'calc(100vh - 55px - 60px - 96px)',
|
||||
maxHeight: 'calc(100vh - 55px - 60px)',
|
||||
overflow: 'auto',
|
||||
marginRight: 12,
|
||||
background: '#fff',
|
||||
position: 'sticky',
|
||||
top: 64,
|
||||
padding: '12px 0',
|
||||
<Drawer
|
||||
title="部门"
|
||||
open={phoneDepOpen}
|
||||
onClose={() => setPhoneDepOpen(false)}
|
||||
width={'85%'}
|
||||
placement="left"
|
||||
>
|
||||
<Tree
|
||||
className={'department-tree'}
|
||||
blockNode
|
||||
key={departmentsList.length}
|
||||
selectedKeys={[departmentID]}
|
||||
defaultExpandAll
|
||||
treeData={departmentsList as any}
|
||||
fieldNames={{ title: 'name', key: 'id' }}
|
||||
onSelect={(selectedKeys) => {
|
||||
setPhoneDepOpen(false);
|
||||
if (selectedKeys.length) {
|
||||
setDepartmentsID(Number(selectedKeys[0]));
|
||||
param.dep_id = Number(selectedKeys[0]);
|
||||
page(1);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Spin spinning={loadingL} style={{ display: 'block' }}>
|
||||
{departmentsList.length ? (
|
||||
titleRender={(nodeData: any) => {
|
||||
// console.log(nodeData);
|
||||
return (
|
||||
<div className={styles.departmentItem}>
|
||||
<div className={styles.name} title={nodeData.name}>
|
||||
{nodeData.name}
|
||||
</div>
|
||||
{/* <div className={styles.btnsBox}>
|
||||
<FormOutlined
|
||||
title="修改"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setOpen(true);
|
||||
}}
|
||||
className={styles.edit}
|
||||
/>
|
||||
<Popconfirm
|
||||
title="确认删除?"
|
||||
open={popOpen == nodeData.id}
|
||||
onCancel={(e) => {
|
||||
setPopOpen(-1);
|
||||
e?.stopPropagation();
|
||||
}}
|
||||
onConfirm={(e) => {
|
||||
e?.stopPropagation();
|
||||
console.log(nodeData.id);
|
||||
}}
|
||||
>
|
||||
<DeleteOutlined
|
||||
title="删除"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setPopOpen(nodeData.id);
|
||||
}}
|
||||
className={styles.del}
|
||||
/>
|
||||
</Popconfirm>
|
||||
</div> */}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</Drawer>
|
||||
<div style={{ display: 'flex' }}>
|
||||
{isPhone ? null : (
|
||||
<div
|
||||
style={{
|
||||
width: 240,
|
||||
flexShrink: 0,
|
||||
minHeight: 'calc(100vh - 55px - 60px - 96px)',
|
||||
maxHeight: 'calc(100vh - 55px - 60px)',
|
||||
overflow: 'auto',
|
||||
marginRight: 12,
|
||||
background: '#fff',
|
||||
position: 'sticky',
|
||||
top: 64,
|
||||
padding: '12px 0',
|
||||
}}
|
||||
>
|
||||
<Spin spinning={loadingL} style={{ display: 'block' }}>
|
||||
<Tree
|
||||
className={'department-tree'}
|
||||
blockNode
|
||||
key={departmentsList.length}
|
||||
selectedKeys={[departmentID]}
|
||||
defaultExpandAll
|
||||
treeData={departmentsList as any}
|
||||
@@ -218,9 +289,9 @@ const DepartmentsList: React.FC = () => {
|
||||
);
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
</Spin>
|
||||
</div>
|
||||
</Spin>
|
||||
</div>
|
||||
)}
|
||||
<Modal
|
||||
title="系统提示"
|
||||
open={!!syncOpen}
|
||||
@@ -320,70 +391,127 @@ const DepartmentsList: React.FC = () => {
|
||||
</Button>
|
||||
</Row>
|
||||
}
|
||||
phoneBtns={
|
||||
isPhone ? (
|
||||
<Button
|
||||
type="primary"
|
||||
style={{ marginRight: 12 }}
|
||||
onClick={() => {
|
||||
setPhoneDepOpen(true);
|
||||
}}
|
||||
>
|
||||
选择部门
|
||||
</Button>
|
||||
) : null
|
||||
}
|
||||
/>
|
||||
|
||||
<Table
|
||||
tableLayout="fixed"
|
||||
size="middle"
|
||||
dataSource={staffsData.data}
|
||||
style={{ padding: 16, borderRadius: 6, background: '#fff', marginTop: 16 }}
|
||||
pagination={false}
|
||||
bordered={true}
|
||||
rowKey={'user_id'}
|
||||
loading={loading}
|
||||
>
|
||||
<Table.Column
|
||||
title="姓名"
|
||||
dataIndex={'name'}
|
||||
render={(value, record: IStaffsItem) => {
|
||||
{isPhone ? (
|
||||
<Spin spinning={loading}>
|
||||
{staffsData.data?.map((item) => {
|
||||
return (
|
||||
<div
|
||||
<Card
|
||||
onClick={() => {
|
||||
setRecord(record);
|
||||
setRecord(item);
|
||||
setOpen(true);
|
||||
}}
|
||||
style={{ color: '#1890ff', cursor: 'pointer' }}
|
||||
key={item.user_id}
|
||||
title={<span style={{ color: '#1890ff' }}>{item.name}</span>}
|
||||
style={{ marginTop: 16 }}
|
||||
extra={
|
||||
item.isleader == 1 ? (
|
||||
<span
|
||||
style={{
|
||||
color: '#999',
|
||||
fontSize: 12,
|
||||
border: '1px solid #ddd',
|
||||
borderRadius: 4,
|
||||
padding: '2px 4px',
|
||||
}}
|
||||
>
|
||||
负责人
|
||||
</span>
|
||||
) : null
|
||||
}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
marginRight: record.isleader == 1 ? 4 : 0,
|
||||
<div>职务:{item.position || '未设置'}</div>
|
||||
<div>部门:{item?.dep_name?.join(',') || '未设置'}</div>
|
||||
<div>手机号:{item.mobile || '未设置'}</div>
|
||||
<div>企业邮箱:{item.biz_mail || '未设置'}</div>
|
||||
</Card>
|
||||
);
|
||||
})}
|
||||
</Spin>
|
||||
) : (
|
||||
<Table
|
||||
tableLayout="fixed"
|
||||
size="middle"
|
||||
dataSource={staffsData.data}
|
||||
style={{ padding: 16, borderRadius: 6, background: '#fff', marginTop: 16 }}
|
||||
pagination={false}
|
||||
bordered={true}
|
||||
rowKey={'user_id'}
|
||||
loading={loading}
|
||||
>
|
||||
<Table.Column
|
||||
title="姓名"
|
||||
dataIndex={'name'}
|
||||
render={(value, record: IStaffsItem) => {
|
||||
return (
|
||||
<div
|
||||
onClick={() => {
|
||||
setRecord(record);
|
||||
setOpen(true);
|
||||
}}
|
||||
style={{ color: '#1890ff', cursor: 'pointer' }}
|
||||
>
|
||||
{value}
|
||||
</span>
|
||||
{record?.isleader == 1 ? (
|
||||
<span
|
||||
style={{
|
||||
color: '#999',
|
||||
fontSize: 12,
|
||||
border: '1px solid #ddd',
|
||||
borderRadius: 4,
|
||||
padding: '2px 4px',
|
||||
display: 'inline-block',
|
||||
marginRight: record.isleader == 1 ? 4 : 0,
|
||||
}}
|
||||
>
|
||||
负责人
|
||||
{value}
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Table.Column title="职务" width={160} dataIndex={'position'} />
|
||||
<Table.Column
|
||||
title="部门"
|
||||
dataIndex={'dep_name'}
|
||||
render={(val) => {
|
||||
return <>{val.join(',')}</>;
|
||||
}}
|
||||
/>
|
||||
<Table.Column title="手机号" width={160} dataIndex={'mobile'} />
|
||||
<Table.Column title="企业邮箱" dataIndex={'biz_mail'} />
|
||||
</Table>
|
||||
<Drawer title="成员详情" open={open} onClose={() => setOpen(false)} width={800}>
|
||||
{record?.isleader == 1 ? (
|
||||
<span
|
||||
style={{
|
||||
color: '#999',
|
||||
fontSize: 12,
|
||||
border: '1px solid #ddd',
|
||||
borderRadius: 4,
|
||||
padding: '2px 4px',
|
||||
}}
|
||||
>
|
||||
负责人
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Table.Column title="职务" width={160} dataIndex={'position'} />
|
||||
<Table.Column
|
||||
title="部门"
|
||||
dataIndex={'dep_name'}
|
||||
render={(val) => {
|
||||
return <>{val.join(',')}</>;
|
||||
}}
|
||||
/>
|
||||
<Table.Column title="手机号" width={160} dataIndex={'mobile'} />
|
||||
<Table.Column title="企业邮箱" dataIndex={'biz_mail'} />
|
||||
</Table>
|
||||
)}
|
||||
<Drawer
|
||||
title="成员详情"
|
||||
open={open}
|
||||
onClose={() => setOpen(false)}
|
||||
width={isPhone ? '90%' : 800}
|
||||
destroyOnClose
|
||||
>
|
||||
<DepartmentMembersDetail record={record as IStaffsItem} />
|
||||
</Drawer>
|
||||
<Pagination
|
||||
size={isPhone ? 'small' : 'default'}
|
||||
style={{
|
||||
background: '#fff',
|
||||
borderRadius: 6,
|
||||
|
@@ -9,6 +9,7 @@ import {
|
||||
groupMembersCount2,
|
||||
groupMembersListItem,
|
||||
} from '@/pages/ChatLogs/ChatUtils';
|
||||
import { getDevice } from '@/services/utils';
|
||||
import { Spin } from 'antd';
|
||||
import { stringify } from 'qs';
|
||||
import styles from './index.mudule.scss';
|
||||
@@ -22,7 +23,7 @@ export const GroupDetailContent: React.FC<Iprops> = (props) => {
|
||||
const [groupMembersList, setGroupMembersList] = useState<IGroupMembers[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const groupMembersObjRef = useRef<any>({});
|
||||
|
||||
const isPhone = getDevice() === 'phone';
|
||||
const getList = () => {
|
||||
setLoading(true);
|
||||
post({
|
||||
@@ -60,10 +61,10 @@ export const GroupDetailContent: React.FC<Iprops> = (props) => {
|
||||
}, [props.record]);
|
||||
|
||||
return (
|
||||
<Spin spinning={loading} style={{ minHeight: 400, display: 'block' }}>
|
||||
<Spin spinning={loading} style={{ minHeight: isPhone ? 'auto' : 400, display: 'block' }}>
|
||||
{groupMembersList.length ? (
|
||||
<div>
|
||||
<div className={styles.groupMsgBox}>
|
||||
<div className={styles.groupMsgBox} style={{ flexDirection: isPhone ? 'column' : 'row' }}>
|
||||
<div className={styles.groupMsg}>
|
||||
<div style={{ marginBottom: 8, textIndent: '2em' }}>
|
||||
群主:
|
||||
@@ -74,7 +75,10 @@ export const GroupDetailContent: React.FC<Iprops> = (props) => {
|
||||
</div>
|
||||
<div style={{ marginBottom: 8 }}>创建时间:{record?.create_time}</div>
|
||||
</div>
|
||||
<div className={styles.notice}>
|
||||
<div
|
||||
className={styles.notice}
|
||||
style={{ width: isPhone ? '100%' : '', marginTop: isPhone ? 16 : 0 }}
|
||||
>
|
||||
<div style={{ textIndent: '1em' }}>
|
||||
<div
|
||||
style={{
|
||||
|
@@ -1,7 +1,6 @@
|
||||
.groupMsgBox {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
min-height: 100px;
|
||||
}
|
||||
|
||||
.groupMsg {
|
||||
|
@@ -2,10 +2,24 @@ import { SearchBarPlugin } from '@/components/SearchBarPlugin';
|
||||
import { post } from '@/services/ajax';
|
||||
import { groupStatus } from '@/services/config';
|
||||
import { PageContainer } from '@ant-design/pro-components';
|
||||
import { Button, Col, DatePicker, Drawer, Form, Input, Pagination, Row, Select, Table } from 'antd';
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
Col,
|
||||
DatePicker,
|
||||
Drawer,
|
||||
Form,
|
||||
Input,
|
||||
Pagination,
|
||||
Row,
|
||||
Select,
|
||||
Spin,
|
||||
Table,
|
||||
} from 'antd';
|
||||
import { stringify } from 'qs';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { getDevice } from '@/services/utils';
|
||||
import { IGroup } from '../ChatLogs/ChatLogsType';
|
||||
import { GroupDetailContent } from './components/GroupDetailContent';
|
||||
|
||||
@@ -20,7 +34,7 @@ const GroupList: React.FC = () => {
|
||||
create_timeL: '',
|
||||
create_timeU: '',
|
||||
});
|
||||
|
||||
const isPhone = getDevice() === 'phone';
|
||||
const [groupsList, setGroupsList] = useState<IGroup[]>([]);
|
||||
const [count, setCount] = useState(0);
|
||||
const [loading, setLoading] = useState(false);
|
||||
@@ -145,33 +159,61 @@ const GroupList: React.FC = () => {
|
||||
</Row>
|
||||
}
|
||||
/>
|
||||
|
||||
<Table
|
||||
tableLayout="fixed"
|
||||
size="middle"
|
||||
dataSource={groupsList}
|
||||
style={{ padding: 16, borderRadius: 6, background: '#fff', marginTop: 16 }}
|
||||
pagination={false}
|
||||
bordered={true}
|
||||
rowKey={(record) => {
|
||||
return `${record.group_id}_${record.name}`;
|
||||
}}
|
||||
loading={loading}
|
||||
>
|
||||
<Table.Column
|
||||
title="群名"
|
||||
width={160}
|
||||
dataIndex={'name'}
|
||||
render={(value, record: IGroup) => {
|
||||
{isPhone ? (
|
||||
<Spin spinning={loading}>
|
||||
{groupsList.map((item) => {
|
||||
return (
|
||||
<div
|
||||
<Card
|
||||
key={`${item.group_id}_${item.name}`}
|
||||
onClick={() => {
|
||||
setRecord(record);
|
||||
setRecord(item);
|
||||
setOpen(true);
|
||||
}}
|
||||
style={{ cursor: 'pointer', display: 'flex' }}
|
||||
style={{ marginTop: 16 }}
|
||||
title={
|
||||
<div style={{ color: '#1890ff', wordBreak: 'break-all' }}>
|
||||
{item.name || '未知群名'}
|
||||
</div>
|
||||
}
|
||||
extra={
|
||||
<span style={{ color: '#999' }}>{item.state == 1 ? '正常' : '已解散'}</span>
|
||||
}
|
||||
>
|
||||
{/* <div
|
||||
<div>群主:{item.staff_name}</div>
|
||||
<div>群人数:{item?.members_tot}</div>
|
||||
<div>群状态:{groupStatus[item.status]}</div>
|
||||
<div>创建时间:{item.create_time}</div>
|
||||
</Card>
|
||||
);
|
||||
})}
|
||||
</Spin>
|
||||
) : (
|
||||
<Table
|
||||
tableLayout="fixed"
|
||||
size="middle"
|
||||
dataSource={groupsList}
|
||||
style={{ padding: 16, borderRadius: 6, background: '#fff', marginTop: 16 }}
|
||||
pagination={false}
|
||||
bordered={true}
|
||||
rowKey={(record) => {
|
||||
return `${record.group_id}_${record.name}`;
|
||||
}}
|
||||
loading={loading}
|
||||
>
|
||||
<Table.Column
|
||||
title="群名"
|
||||
width={160}
|
||||
dataIndex={'name'}
|
||||
render={(value, record: IGroup) => {
|
||||
return (
|
||||
<div
|
||||
onClick={() => {
|
||||
setRecord(record);
|
||||
setOpen(true);
|
||||
}}
|
||||
style={{ cursor: 'pointer', display: 'flex' }}
|
||||
>
|
||||
{/* <div
|
||||
style={{
|
||||
width: 56,
|
||||
height: 56,
|
||||
@@ -185,52 +227,54 @@ const GroupList: React.FC = () => {
|
||||
>
|
||||
<Image width={56} height={56} src={record.avatar}></Image>
|
||||
</div> */}
|
||||
<div style={{ marginLeft: 8 }}>
|
||||
|
||||
<div style={{ color: '#1890ff', wordBreak: 'break-all' }}>
|
||||
{value || '未知群名'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Table.Column
|
||||
title="群主"
|
||||
width={120}
|
||||
render={(v, r: IGroup) => {
|
||||
return <>{r?.staff_name}</>;
|
||||
}}
|
||||
dataIndex={'owner'}
|
||||
/>
|
||||
<Table.Column
|
||||
title="状态"
|
||||
width={120}
|
||||
render={(v) => {
|
||||
return <>{groupStatus[v]}</>;
|
||||
}}
|
||||
dataIndex={'status'}
|
||||
/>
|
||||
<Table.Column title="群人数" width={120} dataIndex={'members_tot'} />
|
||||
<Table.Column
|
||||
title="是否解散"
|
||||
width={140}
|
||||
render={(v) => {
|
||||
return <>{v == 1 ? '正常' : '已解散'}</>;
|
||||
}}
|
||||
dataIndex={'state'}
|
||||
/>
|
||||
<Table.Column title="创建时间" width={140} dataIndex={'create_time'} />
|
||||
{/* <Table.Column title="操作" width={160} dataIndex={'position'} /> */}
|
||||
</Table>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Table.Column
|
||||
title="群主"
|
||||
width={120}
|
||||
render={(v, r: IGroup) => {
|
||||
return <>{r?.staff_name}</>;
|
||||
}}
|
||||
dataIndex={'owner'}
|
||||
/>
|
||||
<Table.Column
|
||||
title="状态"
|
||||
width={120}
|
||||
render={(v) => {
|
||||
return <>{groupStatus[v]}</>;
|
||||
}}
|
||||
dataIndex={'status'}
|
||||
/>
|
||||
<Table.Column title="群人数" width={120} dataIndex={'members_tot'} />
|
||||
<Table.Column
|
||||
title="是否解散"
|
||||
width={140}
|
||||
render={(v) => {
|
||||
return <>{v == 1 ? '正常' : '已解散'}</>;
|
||||
}}
|
||||
dataIndex={'state'}
|
||||
/>
|
||||
<Table.Column title="创建时间" width={140} dataIndex={'create_time'} />
|
||||
{/* <Table.Column title="操作" width={160} dataIndex={'position'} /> */}
|
||||
</Table>
|
||||
)}
|
||||
|
||||
<Drawer
|
||||
title={`${record?.name} 群详情`}
|
||||
title={`${record?.name || '未知群名'} 群详情`}
|
||||
open={open}
|
||||
onClose={() => setOpen(false)}
|
||||
width={800}
|
||||
width={isPhone ? '90%' : 800}
|
||||
>
|
||||
<GroupDetailContent record={record as IGroup} />
|
||||
</Drawer>
|
||||
<Pagination
|
||||
size={isPhone ? 'small' : 'default'}
|
||||
style={{
|
||||
background: '#fff',
|
||||
borderRadius: 6,
|
||||
|
Reference in New Issue
Block a user