Merge branch 'dev' of codeup.aliyun.com:61c14a7efa282c88e103c23f/oak-general-business into dev
This commit is contained in:
commit
986aa17d48
|
|
@ -4,5 +4,6 @@ declare const _default: (props: import("oak-frontend-base").ReactComponentProps<
|
|||
onSelect: (id: string) => void;
|
||||
key: string;
|
||||
entityFilter: {};
|
||||
name: undefined;
|
||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||
export default _default;
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ export default OakComponent({
|
|||
onSelect: (id) => { },
|
||||
key: '',
|
||||
entityFilter: {},
|
||||
name: undefined,
|
||||
},
|
||||
methods: {
|
||||
getAvatarUrl() {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ export default function render(props: WebComponentProps<EntityDict, 'session', f
|
|||
userType: string;
|
||||
selectedId: string;
|
||||
onSelect: (id: string) => void;
|
||||
name: string;
|
||||
}, {
|
||||
getName: () => string;
|
||||
getAvatarUrl: () => string;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import classNames from 'classnames';
|
|||
import Style from './web.module.less';
|
||||
export default function render(props) {
|
||||
const { methods, data } = props;
|
||||
const { selectedId, onSelect, userType, id, unreadLength, sessiontMessages = [], } = data;
|
||||
const { selectedId, onSelect, userType, id, unreadLength, sessiontMessages = [], name, } = data;
|
||||
const { t, getName, getAvatarUrl } = methods;
|
||||
const sessiontMessage = sessiontMessages && sessiontMessages[0];
|
||||
const createAt = sessiontMessage?.$$createAt$$;
|
||||
|
|
@ -17,7 +17,7 @@ export default function render(props) {
|
|||
[Style.cell_selected]: id === selectedId,
|
||||
}), onClick: () => {
|
||||
onSelect(id);
|
||||
}, children: [_jsx(Badge, { dot: id === selectedId ? false : true, count: unreadLength || 0, children: _jsx(Image, { className: Style.avatar, src: getAvatarUrl(), preview: false }) }), _jsxs("div", { className: Style.inner, children: [_jsxs("div", { className: Style.top, children: [_jsx("div", { className: Style.title, children: getName() }), _jsx("div", { className: Style.date, children: sessiontMessage &&
|
||||
}, children: [_jsx(Badge, { dot: id === selectedId ? false : true, count: unreadLength || 0, children: _jsx(Image, { className: Style.avatar, src: getAvatarUrl(), preview: false }) }), _jsxs("div", { className: Style.inner, children: [_jsxs("div", { className: Style.top, children: [_jsx("div", { className: Style.title, children: name || getName() }), _jsx("div", { className: Style.date, children: sessiontMessage &&
|
||||
(today === createAt2
|
||||
? dayjs(createAt).format('HH:mm')
|
||||
: dayjs(createAt).format('YYYY-MM-DD')) })] }), _jsx("div", { className: Style.message, children: type &&
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
type HeaderProps = {
|
||||
showBack: boolean;
|
||||
/// <reference types="react" />
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, keyof import("../../../oak-app-domain").EntityDict, false, {
|
||||
sessionId: string;
|
||||
userId: string;
|
||||
};
|
||||
declare function Header(props: HeaderProps): import("react/jsx-runtime").JSX.Element;
|
||||
export default Header;
|
||||
isEntity: boolean;
|
||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||
export default _default;
|
||||
|
|
|
|||
|
|
@ -1,23 +1,104 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Button, Image } from 'antd';
|
||||
import { LeftOutlined } from '@ant-design/icons';
|
||||
import useFeatures from '../../..//hooks/useFeatures';
|
||||
import classNames from 'classnames';
|
||||
import Style from './index.module.less';
|
||||
import { useWidth } from 'oak-frontend-base/es/platforms/web';
|
||||
function Header(props) {
|
||||
const features = useFeatures();
|
||||
const width = useWidth();
|
||||
const { showBack = true, sessionId, userId } = props;
|
||||
const [name, setName] = useState('');
|
||||
const [url, setUrl] = useState('');
|
||||
useEffect(() => {
|
||||
export default OakComponent({
|
||||
// entity: 'session',
|
||||
// projection: {
|
||||
// id: 1,
|
||||
// userId: 1,
|
||||
// entity: 1,
|
||||
// entityId: 1,
|
||||
// lmts: 1,
|
||||
// user: {
|
||||
// id: 1,
|
||||
// name: 1,
|
||||
// nickname: 1,
|
||||
// mobile$user: {
|
||||
// $entity: 'mobile',
|
||||
// data: {
|
||||
// id: 1,
|
||||
// mobile: 1,
|
||||
// userId: 1,
|
||||
// },
|
||||
// },
|
||||
// extraFile$entity: {
|
||||
// $entity: 'extraFile',
|
||||
// data: {
|
||||
// id: 1,
|
||||
// tag1: 1,
|
||||
// origin: 1,
|
||||
// bucket: 1,
|
||||
// objectId: 1,
|
||||
// filename: 1,
|
||||
// extra1: 1,
|
||||
// extension: 1,
|
||||
// type: 1,
|
||||
// entity: 1,
|
||||
// },
|
||||
// filter: {
|
||||
// tag1: {
|
||||
// $in: ['avatar'],
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
isList: false,
|
||||
// formData({ data, features }) {
|
||||
// const session = Object.assign(
|
||||
// {},
|
||||
// data
|
||||
// ) as any;
|
||||
// console.log(session)
|
||||
// Object.assign(session, {
|
||||
// userUrl: features.extraFile.getUrl(
|
||||
// session?.user?.extraFile$entity &&
|
||||
// session?.user?.extraFile$entity[0]
|
||||
// ),
|
||||
// });
|
||||
// // if (session?.sessionMessage$session) {
|
||||
// // Object.assign(session, {
|
||||
// // wechatMessages: session?.sessionMessage$session,
|
||||
// // // unreadLength: session?.sessionMessage$session?.filter(
|
||||
// // // (ele: any) => ele.isRead === false
|
||||
// // // )?.length,
|
||||
// // });
|
||||
// // }
|
||||
// return session;
|
||||
// },
|
||||
// filters: [
|
||||
// {
|
||||
// filter() {
|
||||
// const { sessionId } = this.props;
|
||||
// if (sessionId) {
|
||||
// return {
|
||||
// id: sessionId,
|
||||
// };
|
||||
// }
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
lifetimes: {
|
||||
ready() {
|
||||
const { sessionId } = this.props;
|
||||
if (sessionId) {
|
||||
const [session] = features.cache?.get('session', {
|
||||
this.getSession(sessionId);
|
||||
}
|
||||
},
|
||||
},
|
||||
listeners: {
|
||||
sessionId(prev, next) {
|
||||
if (prev.sessionId !== next.sessionId) {
|
||||
this.getSession(next.sessionId);
|
||||
}
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
sessionId: '',
|
||||
isEntity: false,
|
||||
},
|
||||
methods: {
|
||||
getSession(sessionId) {
|
||||
const [session] = this.features.cache.get('session', {
|
||||
data: {
|
||||
id: 1,
|
||||
uerId: 1,
|
||||
user: {
|
||||
id: 1,
|
||||
name: 1,
|
||||
|
|
@ -43,7 +124,6 @@ function Header(props) {
|
|||
extension: 1,
|
||||
type: 1,
|
||||
entity: 1,
|
||||
entityId: 1,
|
||||
},
|
||||
filter: {
|
||||
tag1: {
|
||||
|
|
@ -54,35 +134,30 @@ function Header(props) {
|
|||
},
|
||||
},
|
||||
filter: {
|
||||
id: sessionId,
|
||||
},
|
||||
id: sessionId
|
||||
}
|
||||
});
|
||||
if (session) {
|
||||
const url2 = getAvatarUrl(session);
|
||||
setUrl(url2);
|
||||
const name2 = getName(session);
|
||||
setName(name2);
|
||||
}
|
||||
}
|
||||
}, [sessionId, userId]);
|
||||
const getAvatarUrl = (session) => {
|
||||
const { entity, user } = session || {};
|
||||
this.setState({ session });
|
||||
},
|
||||
getAvatarUrl() {
|
||||
const { userUrl, entity } = this.state;
|
||||
const { isEntity } = this.props;
|
||||
const defaultUrl = 'http://qiniu.gecomebox.com/static/defaultAvatar.png';
|
||||
if (user) {
|
||||
const userAvatar = features.extraFile.getUrl(session?.user?.extraFile$entity &&
|
||||
session?.user?.extraFile$entity[0]);
|
||||
return userAvatar || defaultUrl;
|
||||
if (isEntity) {
|
||||
return userUrl || defaultUrl;
|
||||
}
|
||||
else {
|
||||
return defaultUrl;
|
||||
};
|
||||
const getName = (session) => {
|
||||
const { user } = session || {};
|
||||
if (user) {
|
||||
const userName = user?.name || '';
|
||||
const userNickname = user?.name || user?.nickname || '';
|
||||
const userMobile = (user?.mobile$user &&
|
||||
user?.mobile$user[0]?.mobile) ||
|
||||
'';
|
||||
}
|
||||
},
|
||||
getName() {
|
||||
const { session, entity } = this.state;
|
||||
const { isEntity } = this.props;
|
||||
if (isEntity) {
|
||||
const userName = session?.user?.name;
|
||||
const userNickname = session?.user?.name || session?.user?.nickname;
|
||||
const userMobile = session?.user?.mobile$user &&
|
||||
session?.user?.mobile$user[0]?.mobile;
|
||||
if (userName) {
|
||||
return userName;
|
||||
}
|
||||
|
|
@ -91,12 +166,9 @@ function Header(props) {
|
|||
}
|
||||
return userNickname;
|
||||
}
|
||||
else {
|
||||
return '未知';
|
||||
};
|
||||
return (_jsxs("div", { className: classNames(Style.header, {
|
||||
[Style.header_mobile]: width === 'xs'
|
||||
}), children: [showBack && (_jsx(Button, { type: "text", onClick: () => {
|
||||
features.navigator.navigateBack();
|
||||
}, children: _jsx(LeftOutlined, { className: Style.backIcon }) })), _jsxs("div", { className: Style.middle, children: [_jsx(Image, { src: url, className: Style.icon, preview: false }), _jsx("div", { className: Style.name, children: name })] })] }));
|
||||
}
|
||||
export default Header;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
import { WebComponentProps } from 'oak-frontend-base';
|
||||
import { EntityDict } from '../../../oak-app-domain';
|
||||
export default function render(props: WebComponentProps<EntityDict, 'session', false, {
|
||||
avatarUrl: string;
|
||||
nickname: string;
|
||||
name: string;
|
||||
showBack: boolean;
|
||||
sessionId: string;
|
||||
}, {
|
||||
getName: () => string;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
// import { UserOutlined } from '@ant-design/icons';
|
||||
import Style from './web.module.less';
|
||||
import { Button } from 'antd';
|
||||
import { LeftOutlined } from '@ant-design/icons';
|
||||
import useFeatures from '../../../hooks/useFeatures';
|
||||
import classNames from 'classnames';
|
||||
import { useWidth } from 'oak-frontend-base/es/platforms/web';
|
||||
export default function render(props) {
|
||||
const { methods, data } = props;
|
||||
const { nickname, avatarUrl, name, showBack } = data;
|
||||
const { getName } = methods;
|
||||
const defaultUrl = 'http://qiniu.gecomebox.com/static/defaultAvatar.png';
|
||||
const features = useFeatures();
|
||||
const width = useWidth();
|
||||
return (_jsxs("div", { className: classNames(Style.header, {
|
||||
[Style.header_mobile]: width === 'xs'
|
||||
}), children: [showBack && (_jsx(Button, { type: "text", onClick: () => {
|
||||
features.navigator.navigateBack();
|
||||
}, children: _jsx(LeftOutlined, { className: Style.backIcon }) })), _jsx("div", { className: Style.middle, children: _jsx("div", { className: Style.name, children: getName() }) })] }));
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
.name {
|
||||
font-size: 16px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,4 +3,5 @@ import { EntityDict } from '../../../oak-app-domain';
|
|||
export default function render(props: WebComponentProps<EntityDict, 'session', false, {
|
||||
avatarUrl: string;
|
||||
nickname: string;
|
||||
name: string;
|
||||
}, {}>): import("react/jsx-runtime").JSX.Element;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { Avatar } from 'antd';
|
|||
import Style from './web.module.less';
|
||||
export default function render(props) {
|
||||
const { methods, data } = props;
|
||||
const { nickname, avatarUrl } = data;
|
||||
const { nickname, avatarUrl, name } = data;
|
||||
const defaultUrl = 'http://qiniu.gecomebox.com/static/defaultAvatar.png';
|
||||
return (_jsxs("div", { className: Style.header, children: [_jsx(Avatar, { shape: "square", className: Style.avatar, src: avatarUrl || defaultUrl }), _jsx("div", { className: Style.nickname, children: nickname })] }));
|
||||
return (_jsxs("div", { className: Style.header, children: [_jsx(Avatar, { shape: "square", className: Style.avatar, src: avatarUrl || defaultUrl }), _jsx("div", { className: Style.nickname, children: nickname || name })] }));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, "session", true, {
|
||||
entity: string;
|
||||
entityFilter: any;
|
||||
entityDisplay: (entity: string, entityId: string) => "";
|
||||
entityDisplay: (data: any) => "";
|
||||
entityProjection: any;
|
||||
sessionId: string;
|
||||
dialog: boolean;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
export default OakComponent({
|
||||
entity: 'session',
|
||||
projection: {
|
||||
projection() {
|
||||
const { entityProjection } = this.props;
|
||||
const proj = {
|
||||
id: 1,
|
||||
entity: 1,
|
||||
entityId: 1,
|
||||
|
|
@ -63,9 +65,21 @@ export default OakComponent({
|
|||
count: 1,
|
||||
},
|
||||
$$createAt$$: 1,
|
||||
};
|
||||
if (entityProjection) {
|
||||
Object.assign(proj, { ...entityProjection });
|
||||
}
|
||||
return proj;
|
||||
},
|
||||
isList: true,
|
||||
formData: function ({ data: sessions, features, props }) {
|
||||
const { entityDisplay, entityProjection } = this.props;
|
||||
if (entityProjection && entityDisplay && sessions && sessions.length > 0) {
|
||||
const sessions1 = entityDisplay(sessions);
|
||||
return {
|
||||
sessions: sessions1,
|
||||
};
|
||||
}
|
||||
// const unReadLength = wechatSessions?.filter(
|
||||
// (ele) => ele.isRead
|
||||
// )
|
||||
|
|
@ -100,8 +114,8 @@ export default OakComponent({
|
|||
},
|
||||
properties: {
|
||||
entity: '',
|
||||
entityFilter: {},
|
||||
entityDisplay: (entity, entityId) => '',
|
||||
entityFilter: undefined,
|
||||
entityDisplay: (data) => '',
|
||||
entityProjection: {},
|
||||
sessionId: '',
|
||||
dialog: false,
|
||||
|
|
@ -165,7 +179,7 @@ export default OakComponent({
|
|||
{
|
||||
sorter: {
|
||||
$attr: {
|
||||
$$updateAt$$: 1,
|
||||
lmts: 1,
|
||||
},
|
||||
$direction: 'desc',
|
||||
},
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
}
|
||||
|
||||
.bothContainer {
|
||||
margin: 0 auto;
|
||||
margin-top: 5vh;
|
||||
margin: 5vh auto;
|
||||
// margin-top: 5vh;
|
||||
width: 90%;
|
||||
min-width: 600px;
|
||||
height: 80vh;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { WebComponentProps } from 'oak-frontend-base';
|
||||
import { EntityDict } from '../../../oak-app-domain';
|
||||
export default function Render(props: WebComponentProps<EntityDict, 'session', false, {
|
||||
sessions: EntityDict['session']['Schema'][];
|
||||
sessions: any;
|
||||
selectedSessionId: string;
|
||||
className: string;
|
||||
dialog: boolean;
|
||||
|
|
|
|||
|
|
@ -13,14 +13,14 @@ export default function Render(props) {
|
|||
return (_jsx("div", { className: Style.container, children: _jsxs("div", { className: classNames(Style.bothContainer, className, {
|
||||
[Style.dialogContainer]: dialog,
|
||||
}), children: [_jsxs("div", { className: Style.conversationContainer, children: [_jsx(Header, {}), _jsx("div", { className: Style.inner, children: sessions?.map((session, index) => {
|
||||
return (_jsx(SessionCell, { entityFilter: entityFilter, selectedId: selectedSessionId, onSelect: (id) => {
|
||||
return (_jsx(SessionCell, { entityFilter: entityFilter, name: session?.name, selectedId: selectedSessionId, onSelect: (id) => {
|
||||
setSelectedSessionId(id);
|
||||
}, oakId: session.id, oakPath: oakFullpath
|
||||
? `${oakFullpath}.${session.id}`
|
||||
: '' }, session.id));
|
||||
}) })] }), selectedSessionId && (_jsx(MessageList, { sessionId: selectedSessionId,
|
||||
// isCombine={true}
|
||||
isEntity: !!entityFilter, oakAutoUnmount: true, oakPath: oakFullpath
|
||||
isEntity: entityFilter ? true : false, isUser: entityFilter ? false : true, oakAutoUnmount: true, oakPath: oakFullpath
|
||||
? `$$sessionMessage/list`
|
||||
: undefined }))] }) }));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,5 +2,6 @@
|
|||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, "sessionMessage", false, {
|
||||
key: string;
|
||||
isEntity: boolean;
|
||||
isUser: boolean;
|
||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||
export default _default;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,38 @@ export default OakComponent({
|
|||
id: 1,
|
||||
entity: 1,
|
||||
entityId: 1,
|
||||
userId: 1,
|
||||
user: {
|
||||
id: 1,
|
||||
name: 1,
|
||||
mobile$user: {
|
||||
$entity: 'mobile',
|
||||
data: {
|
||||
id: 1,
|
||||
mobile: 1,
|
||||
},
|
||||
},
|
||||
extraFile$entity: {
|
||||
$entity: 'extraFile',
|
||||
data: {
|
||||
id: 1,
|
||||
tag1: 1,
|
||||
origin: 1,
|
||||
bucket: 1,
|
||||
objectId: 1,
|
||||
filename: 1,
|
||||
extra1: 1,
|
||||
extension: 1,
|
||||
type: 1,
|
||||
entity: 1,
|
||||
},
|
||||
filter: {
|
||||
tag1: {
|
||||
$in: ['avatar'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
aaoe: 1,
|
||||
extraFile$entity: {
|
||||
|
|
@ -43,7 +75,7 @@ export default OakComponent({
|
|||
formData({ data: sessionMessage, features }) {
|
||||
const type = sessionMessage?.type;
|
||||
// const data = wechatMessage?.data;
|
||||
// const session = sessionMessage?.session;
|
||||
const session = sessionMessage?.session;
|
||||
const newSessionMessage = {
|
||||
type,
|
||||
aaoe: sessionMessage?.aaoe,
|
||||
|
|
@ -52,15 +84,12 @@ export default OakComponent({
|
|||
id: sessionMessage?.id,
|
||||
$$createAt$$: sessionMessage?.$$createAt$$,
|
||||
sessionId: sessionMessage?.sessionId,
|
||||
// employerId: conversation?.employerId,
|
||||
// employerMobile:
|
||||
// conversation?.employer?.mobile$user &&
|
||||
// conversation?.employer?.mobile$user[0]?.mobile,
|
||||
userId: session?.userId,
|
||||
userMobile: session?.user?.mobile$user &&
|
||||
session?.user?.mobile$user[0]?.mobile,
|
||||
// companyName: conversation?.company?.name,
|
||||
// employerAvatar: this.features.extraFile.getUrl(
|
||||
// conversation?.employer?.extraFile$entity &&
|
||||
// conversation?.employer?.extraFile$entity[0]
|
||||
// ),
|
||||
userAvatar: this.features.extraFile.getUrl(session?.user?.extraFile$entity &&
|
||||
session?.user?.extraFile$entity[0]),
|
||||
};
|
||||
// if (type === 'image') {
|
||||
// const extraFile$entity =
|
||||
|
|
@ -74,25 +103,35 @@ export default OakComponent({
|
|||
properties: {
|
||||
key: '',
|
||||
isEntity: false,
|
||||
isUser: false,
|
||||
},
|
||||
methods: {
|
||||
getAvatarUrl(type) {
|
||||
getAvatarUrl(aaoe) {
|
||||
const defaultUrl = 'http://qiniu.gecomebox.com/static/defaultAvatar.png';
|
||||
const { companyLogoUrl, employerAvatar, parkLogoUrl } = this.state;
|
||||
switch (type) {
|
||||
case 'company': {
|
||||
return companyLogoUrl || defaultUrl;
|
||||
}
|
||||
case 'employer': {
|
||||
return employerAvatar || defaultUrl;
|
||||
}
|
||||
case 'platformProvider': {
|
||||
return process.env.PUBLIC_URL + '/logo192.png';
|
||||
}
|
||||
case 'park': {
|
||||
return parkLogoUrl || defaultUrl;
|
||||
const { companyLogoUrl, userAvatar, parkLogoUrl } = this.state;
|
||||
if (aaoe) {
|
||||
return defaultUrl;
|
||||
}
|
||||
else {
|
||||
return userAvatar || defaultUrl;
|
||||
}
|
||||
// switch (type) {
|
||||
// case 'company': {
|
||||
// return companyLogoUrl || defaultUrl;
|
||||
// }
|
||||
// case 'user': {
|
||||
// return userAvatar || defaultUrl;
|
||||
// }
|
||||
// case 'platformProvider': {
|
||||
// return process.env.PUBLIC_URL + '/logo192.png';
|
||||
// }
|
||||
// case 'park': {
|
||||
// return parkLogoUrl || defaultUrl;
|
||||
// }
|
||||
// default: {
|
||||
// return defaultUrl
|
||||
// }
|
||||
// }
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { WebComponentProps } from 'oak-frontend-base';
|
|||
import { EntityDict } from '../../../oak-app-domain';
|
||||
export default function render(props: WebComponentProps<EntityDict, 'sessionMessage', false, {
|
||||
isEntity: boolean;
|
||||
isUser: boolean;
|
||||
$$createAt$$: number;
|
||||
text: string;
|
||||
type: string;
|
||||
|
|
@ -10,5 +11,5 @@ export default function render(props: WebComponentProps<EntityDict, 'sessionMess
|
|||
sessionId: string;
|
||||
id: string;
|
||||
}, {
|
||||
getAvatarUrl: (type: string) => string;
|
||||
getAvatarUrl: (aaoe: boolean) => string;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@ import classNames from 'classnames';
|
|||
import Style from './web.module.less';
|
||||
export default function render(props) {
|
||||
const { data, methods } = props;
|
||||
const { $$createAt$$, text, type, picUrl, isEntity, aaoe, sessionId, } = data;
|
||||
const { $$createAt$$, text, type, picUrl, isEntity, isUser, aaoe, sessionId, } = data;
|
||||
const { t, getAvatarUrl } = methods;
|
||||
return (_jsx(ICell, { time: $$createAt$$, children: _jsxs("div", { className: classNames(Style.myMessage, {
|
||||
[Style.notMyMessage]: isEntity !== aaoe,
|
||||
}), children: [_jsx(Image, { preview: false, className: Style.avatar, src: getAvatarUrl(type) }), _jsxs("div", { className: classNames({
|
||||
[Style.notMyMessage]: (isEntity && !aaoe) || (isUser && aaoe),
|
||||
}), children: [_jsx(Image, { preview: false, className: Style.avatar, src: getAvatarUrl(aaoe) }), _jsxs("div", { className: classNames({
|
||||
[Style.messageType_text]: type === 'text',
|
||||
[Style.messageType_text_no]: isEntity !== aaoe,
|
||||
[Style.messageType_text_no]: (isEntity && !aaoe) || (isUser && aaoe),
|
||||
}), children: [type === 'text' && _jsx(IText, { value: text }), type === 'image' && _jsx(IImage, { url: picUrl })] })] }) }));
|
||||
}
|
||||
function ICell(props) {
|
||||
|
|
@ -23,7 +23,12 @@ function ICell(props) {
|
|||
}
|
||||
function IText(props) {
|
||||
const { value } = props;
|
||||
return _jsx("div", { children: value });
|
||||
return _jsx("div", { style: { whiteSpace: 'pre-wrap' }, children: value });
|
||||
// return <div>
|
||||
// <Typography.Paragraph>
|
||||
// {value}
|
||||
// </Typography.Paragraph>
|
||||
// </div>;
|
||||
}
|
||||
function IImage(props) {
|
||||
const { url } = props;
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
}
|
||||
|
||||
.avatar {
|
||||
margin: 10px;
|
||||
margin: 0 10px;
|
||||
height: 30px !important;
|
||||
width: 30px !important;
|
||||
padding: 0 !important;
|
||||
|
|
@ -93,7 +93,8 @@
|
|||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: flex-start;
|
||||
align-items: baseline;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.notMyMessage {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { EntityDict } from '../../../oak-app-domain';
|
|||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<EntityDict, "sessionMessage", true, {
|
||||
sessionId: string;
|
||||
isEntity: boolean;
|
||||
isUser: boolean;
|
||||
dialog: boolean;
|
||||
entity: string;
|
||||
entityId: string;
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ export default OakComponent({
|
|||
lifetimes: {
|
||||
async ready() {
|
||||
const { sessionId } = this.props;
|
||||
this.subData([
|
||||
await this.subData([
|
||||
{
|
||||
entity: 'sessionMessage',
|
||||
filter: {
|
||||
|
|
@ -51,7 +51,7 @@ export default OakComponent({
|
|||
},
|
||||
id: `${DATA_SUBSCRIBER_KEYS.sessionMessageList}-${sessionId}`,
|
||||
}
|
||||
]);
|
||||
], async () => { await this.pageScroll('comment'); });
|
||||
// const userId = this.features.token.getUserId(true);
|
||||
// const applicationId = this.features.application.getApplicationId();
|
||||
// if (!sessionId) {
|
||||
|
|
@ -118,6 +118,7 @@ export default OakComponent({
|
|||
properties: {
|
||||
sessionId: '',
|
||||
isEntity: false,
|
||||
isUser: false,
|
||||
dialog: false,
|
||||
entity: '',
|
||||
entityId: '',
|
||||
|
|
@ -266,7 +267,7 @@ export default OakComponent({
|
|||
fileType: type,
|
||||
size,
|
||||
extension,
|
||||
entity: 'wechatMessage',
|
||||
entity: 'sessionMessage',
|
||||
bucket: '',
|
||||
id: generateNewId(),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
display: flex;
|
||||
overflow: scroll;
|
||||
flex-direction: column;
|
||||
// margin-top: 50px;
|
||||
margin-top: 50px;
|
||||
overflow-x: hidden;
|
||||
height: 100%;
|
||||
}
|
||||
|
|
@ -37,6 +37,8 @@
|
|||
position: absolute;
|
||||
z-index: 100;
|
||||
|
||||
// resize: both;
|
||||
// cursor: nwse-resize;
|
||||
.toolbar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
|
@ -56,14 +58,17 @@
|
|||
|
||||
padding: 0 10px;
|
||||
|
||||
|
||||
.textarea {
|
||||
border: none;
|
||||
outline: none;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.textarea:focus {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.btn {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ export default function Render(props: WebComponentProps<EntityDict, 'sessionMess
|
|||
buttonHidden: boolean;
|
||||
sessionId: string;
|
||||
isEntity: boolean;
|
||||
isUser: boolean;
|
||||
employerId: string;
|
||||
}, {
|
||||
setButtonHidden: (isHidden: boolean) => void;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,19 @@
|
|||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import { Button, Input, Upload } from 'antd';
|
||||
import { PictureOutlined } from '@ant-design/icons';
|
||||
import MessageCell from '../../../components/sessionMessage/cell';
|
||||
import Header from '../../../components/session/forMessage';
|
||||
import Style from './web.module.less';
|
||||
export default function Render(props) {
|
||||
const { data, methods } = props;
|
||||
const { sessionId, isEntity, sessionMessageList, oakFullpath, text, employerId, buttonHidden, } = data;
|
||||
const { sessionId, isEntity, isUser, sessionMessageList, oakFullpath, text, employerId, buttonHidden, } = data;
|
||||
const { setButtonHidden, customUpload, setContent, pageScroll, createMessage, } = methods;
|
||||
const [bottomHeight, setBottomHeight] = useState(0);
|
||||
const textareaRef = useRef(null);
|
||||
// const [text1, setText1] = useState("");
|
||||
// const newBottomHeight =
|
||||
// window.document.getElementById('bottom')?.offsetHeight!;
|
||||
useEffect(() => {
|
||||
if (buttonHidden) {
|
||||
const newBottomHeight = window.document.getElementById('bottom')?.offsetHeight;
|
||||
|
|
@ -18,7 +23,42 @@ export default function Render(props) {
|
|||
setBottomHeight(0);
|
||||
}
|
||||
}, [buttonHidden]);
|
||||
return (_jsxs("div", { className: Style.container, children: [_jsx("div", { className: Style.inner, style: {
|
||||
const handleKeyDown = (event) => {
|
||||
// if (event.key === "Enter" && event.shiftKey) {
|
||||
// event.preventDefault(); // 阻止默认的换行行为
|
||||
// 执行你的换行逻辑
|
||||
// setContent(text + "\n");
|
||||
// if (textareaRef && textareaRef.current && textareaRef.current!.resizableTextArea) {
|
||||
// const textArea = textareaRef.current.resizableTextArea.textAreaRef; // 获取 Input.TextArea 的原生 textarea 元素
|
||||
// console.log(textArea)
|
||||
// if (textArea) {
|
||||
// console.log(textArea)
|
||||
// const selectionStart = textArea?.selectionStart;
|
||||
// const value = textArea?.value;
|
||||
// const newValue =
|
||||
// value?.substring(0, selectionStart) +
|
||||
// "\n" +
|
||||
// value?.substring(selectionStart);
|
||||
// textArea.value = newValue;
|
||||
// textArea.selectionStart = textArea.selectionEnd = selectionStart + 1;
|
||||
// // 触发 onChange 事件,更新 Input.TextArea 的值
|
||||
// textArea.dispatchEvent(new Event("input"));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
if (event.key === "Enter" && !event.shiftKey) {
|
||||
event.preventDefault();
|
||||
createMessage();
|
||||
pageScroll('comment');
|
||||
}
|
||||
};
|
||||
return (_jsxs("div", { className: Style.container, children: [_jsx(Header
|
||||
// showBack={false}
|
||||
, {
|
||||
// showBack={false}
|
||||
sessionId: sessionId, isEntity: isEntity,
|
||||
// userId={employerId}
|
||||
oakPath: 'session:header1', oakAutoUnmount: true }), _jsx("div", { className: Style.inner, style: {
|
||||
marginBottom: bottomHeight ? `${bottomHeight}px` : '168px',
|
||||
}, id: "comment", onClick: () => setButtonHidden(true), children: sessionMessageList
|
||||
?.sort((a, b) => a.$$createAt$$ -
|
||||
|
|
@ -26,18 +66,22 @@ export default function Render(props) {
|
|||
.map((sessionMessage, index) => {
|
||||
return (_jsx(MessageCell, { oakId: sessionMessage.id, oakPath: oakFullpath
|
||||
? `${oakFullpath}.${sessionMessage.id}`
|
||||
: '', isEntity: isEntity }, sessionMessage.id));
|
||||
: '', isEntity: isEntity, isUser: isUser }, sessionMessage.id));
|
||||
}) }), _jsxs("div", { className: Style.bottom, id: "bottom", children: [_jsx("div", { className: Style.toolbar, children: _jsx(Upload, { accept: 'image/*', multiple: false, showUploadList: false, customRequest: () => { }, onChange: ({ file }) => {
|
||||
customUpload(file);
|
||||
}, children: _jsx(PictureOutlined, { className: Style.icon }) }) }), _jsxs("div", { className: Style.textareaBox, children: [_jsx(Input.TextArea, { className: Style.textarea, rows: 5, onChange: (e) => {
|
||||
}, children: _jsx(PictureOutlined, { className: Style.icon }) }) }), _jsxs("div", { className: Style.textareaBox, children: [_jsx(Input.TextArea, { ref: textareaRef, className: Style.textarea,
|
||||
// autoSize={{ minRows: 2, maxRows: 15 }}
|
||||
maxLength: 500, placeholder: "Enter \u53D1\u9001\uFF0CShift + Enter\u6362\u884C", rows: 5, onChange: (e) => {
|
||||
setContent(e.target.value);
|
||||
}, onFocus: () => {
|
||||
setButtonHidden(true);
|
||||
}, onPressEnter: (e) => {
|
||||
e.preventDefault();
|
||||
createMessage();
|
||||
pageScroll('comment');
|
||||
}, value: text }), _jsx("div", { className: Style.btn, children: _jsx(Button, { type: "primary", disabled: text ? false : true, onClick: () => {
|
||||
},
|
||||
// onPressEnter={(e) => {
|
||||
// e.preventDefault();
|
||||
// createMessage();
|
||||
// pageScroll('comment');
|
||||
// }}
|
||||
onKeyDown: handleKeyDown, value: text }), _jsx("div", { className: Style.btn, children: _jsx(Button, { type: "primary", disabled: text ? false : true, onClick: () => {
|
||||
createMessage();
|
||||
pageScroll('comment');
|
||||
}, children: "\u53D1\u9001" }) })] })] })] }));
|
||||
|
|
|
|||
|
|
@ -6,5 +6,6 @@ export interface Schema extends EntityShape {
|
|||
entityId: String<64>;
|
||||
user?: User;
|
||||
lmts?: Datetime;
|
||||
openId?: String<64>;
|
||||
}
|
||||
export type Relation = 'partner';
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ const entityDesc = {
|
|||
entityId: '关联对象id',
|
||||
user: '发送者',
|
||||
lmts: '最后一条消息的发送时间',
|
||||
openId: 'openId'
|
||||
},
|
||||
r: {
|
||||
partner: '所有者',
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ export type OpSchema = EntityShape & {
|
|||
entityId: String<64>;
|
||||
userId?: ForeignKey<"user"> | null;
|
||||
lmts?: Datetime | null;
|
||||
openId?: String<64> | null;
|
||||
};
|
||||
export type OpAttr = keyof OpSchema;
|
||||
export type Schema = EntityShape & {
|
||||
|
|
@ -24,6 +25,7 @@ export type Schema = EntityShape & {
|
|||
entityId: String<64>;
|
||||
userId?: ForeignKey<"user"> | null;
|
||||
lmts?: Datetime | null;
|
||||
openId?: String<64> | null;
|
||||
user?: User.Schema | null;
|
||||
application?: Application.Schema;
|
||||
readRemark$session?: Array<ReadRemark.Schema>;
|
||||
|
|
@ -49,6 +51,7 @@ type AttrFilter = {
|
|||
userId: Q_StringValue;
|
||||
user: User.Filter;
|
||||
lmts: Q_DateValue;
|
||||
openId: Q_StringValue;
|
||||
application: Application.Filter;
|
||||
readRemark$session: ReadRemark.Filter & SubQueryPredicateMetadata;
|
||||
sessionMessage$session: SessionMessage.Filter & SubQueryPredicateMetadata;
|
||||
|
|
@ -69,6 +72,7 @@ export type Projection = {
|
|||
userId?: number;
|
||||
user?: User.Projection;
|
||||
lmts?: number;
|
||||
openId?: number;
|
||||
application?: Application.Projection;
|
||||
readRemark$session?: ReadRemark.Selection & {
|
||||
$entity: "readRemark";
|
||||
|
|
@ -128,6 +132,8 @@ export type SortAttr = {
|
|||
user: User.SortAttr;
|
||||
} | {
|
||||
lmts: number;
|
||||
} | {
|
||||
openId: number;
|
||||
} | {
|
||||
application: Application.SortAttr;
|
||||
} | {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,12 @@ export const desc = {
|
|||
},
|
||||
lmts: {
|
||||
type: "datetime"
|
||||
},
|
||||
openId: {
|
||||
type: "varchar",
|
||||
params: {
|
||||
length: 64
|
||||
}
|
||||
}
|
||||
},
|
||||
actionType: "crud",
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{ "name": "会话", "attr": { "entity": "关联对象", "entityId": "关联对象id", "user": "发送者", "lmts": "最后一条消息的发送时间" }, "r": { "partner": "所有者" } }
|
||||
{ "name": "会话", "attr": { "entity": "关联对象", "entityId": "关联对象id", "user": "发送者", "lmts": "最后一条消息的发送时间", "openId": "openId" }, "r": { "partner": "所有者" } }
|
||||
|
|
|
|||
|
|
@ -4,5 +4,6 @@ declare const _default: (props: import("oak-frontend-base").ReactComponentProps<
|
|||
onSelect: (id: string) => void;
|
||||
key: string;
|
||||
entityFilter: {};
|
||||
name: undefined;
|
||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||
export default _default;
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ exports.default = OakComponent({
|
|||
onSelect: (id) => { },
|
||||
key: '',
|
||||
entityFilter: {},
|
||||
name: undefined,
|
||||
},
|
||||
methods: {
|
||||
getAvatarUrl() {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ export default function render(props: WebComponentProps<EntityDict, 'session', f
|
|||
userType: string;
|
||||
selectedId: string;
|
||||
onSelect: (id: string) => void;
|
||||
name: string;
|
||||
}, {
|
||||
getName: () => string;
|
||||
getAvatarUrl: () => string;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const classnames_1 = tslib_1.__importDefault(require("classnames"));
|
|||
const web_module_less_1 = tslib_1.__importDefault(require("./web.module.less"));
|
||||
function render(props) {
|
||||
const { methods, data } = props;
|
||||
const { selectedId, onSelect, userType, id, unreadLength, sessiontMessages = [], } = data;
|
||||
const { selectedId, onSelect, userType, id, unreadLength, sessiontMessages = [], name, } = data;
|
||||
const { t, getName, getAvatarUrl } = methods;
|
||||
const sessiontMessage = sessiontMessages && sessiontMessages[0];
|
||||
const createAt = sessiontMessage?.$$createAt$$;
|
||||
|
|
@ -20,7 +20,7 @@ function render(props) {
|
|||
[web_module_less_1.default.cell_selected]: id === selectedId,
|
||||
}), onClick: () => {
|
||||
onSelect(id);
|
||||
}, children: [(0, jsx_runtime_1.jsx)(antd_1.Badge, { dot: id === selectedId ? false : true, count: unreadLength || 0, children: (0, jsx_runtime_1.jsx)(antd_1.Image, { className: web_module_less_1.default.avatar, src: getAvatarUrl(), preview: false }) }), (0, jsx_runtime_1.jsxs)("div", { className: web_module_less_1.default.inner, children: [(0, jsx_runtime_1.jsxs)("div", { className: web_module_less_1.default.top, children: [(0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.title, children: getName() }), (0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.date, children: sessiontMessage &&
|
||||
}, children: [(0, jsx_runtime_1.jsx)(antd_1.Badge, { dot: id === selectedId ? false : true, count: unreadLength || 0, children: (0, jsx_runtime_1.jsx)(antd_1.Image, { className: web_module_less_1.default.avatar, src: getAvatarUrl(), preview: false }) }), (0, jsx_runtime_1.jsxs)("div", { className: web_module_less_1.default.inner, children: [(0, jsx_runtime_1.jsxs)("div", { className: web_module_less_1.default.top, children: [(0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.title, children: name || getName() }), (0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.date, children: sessiontMessage &&
|
||||
(today === createAt2
|
||||
? (0, dayjs_1.default)(createAt).format('HH:mm')
|
||||
: (0, dayjs_1.default)(createAt).format('YYYY-MM-DD')) })] }), (0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.message, children: type &&
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
type HeaderProps = {
|
||||
showBack: boolean;
|
||||
/// <reference types="react" />
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, keyof import("../../../oak-app-domain").EntityDict, false, {
|
||||
sessionId: string;
|
||||
userId: string;
|
||||
};
|
||||
declare function Header(props: HeaderProps): import("react/jsx-runtime").JSX.Element;
|
||||
export default Header;
|
||||
isEntity: boolean;
|
||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||
export default _default;
|
||||
|
|
|
|||
|
|
@ -1,26 +1,106 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const tslib_1 = require("tslib");
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
const react_1 = require("react");
|
||||
const antd_1 = require("antd");
|
||||
const icons_1 = require("@ant-design/icons");
|
||||
const useFeatures_1 = tslib_1.__importDefault(require("../../..//hooks/useFeatures"));
|
||||
const classnames_1 = tslib_1.__importDefault(require("classnames"));
|
||||
const index_module_less_1 = tslib_1.__importDefault(require("./index.module.less"));
|
||||
const web_1 = require("oak-frontend-base/es/platforms/web");
|
||||
function Header(props) {
|
||||
const features = (0, useFeatures_1.default)();
|
||||
const width = (0, web_1.useWidth)();
|
||||
const { showBack = true, sessionId, userId } = props;
|
||||
const [name, setName] = (0, react_1.useState)('');
|
||||
const [url, setUrl] = (0, react_1.useState)('');
|
||||
(0, react_1.useEffect)(() => {
|
||||
exports.default = OakComponent({
|
||||
// entity: 'session',
|
||||
// projection: {
|
||||
// id: 1,
|
||||
// userId: 1,
|
||||
// entity: 1,
|
||||
// entityId: 1,
|
||||
// lmts: 1,
|
||||
// user: {
|
||||
// id: 1,
|
||||
// name: 1,
|
||||
// nickname: 1,
|
||||
// mobile$user: {
|
||||
// $entity: 'mobile',
|
||||
// data: {
|
||||
// id: 1,
|
||||
// mobile: 1,
|
||||
// userId: 1,
|
||||
// },
|
||||
// },
|
||||
// extraFile$entity: {
|
||||
// $entity: 'extraFile',
|
||||
// data: {
|
||||
// id: 1,
|
||||
// tag1: 1,
|
||||
// origin: 1,
|
||||
// bucket: 1,
|
||||
// objectId: 1,
|
||||
// filename: 1,
|
||||
// extra1: 1,
|
||||
// extension: 1,
|
||||
// type: 1,
|
||||
// entity: 1,
|
||||
// },
|
||||
// filter: {
|
||||
// tag1: {
|
||||
// $in: ['avatar'],
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
isList: false,
|
||||
// formData({ data, features }) {
|
||||
// const session = Object.assign(
|
||||
// {},
|
||||
// data
|
||||
// ) as any;
|
||||
// console.log(session)
|
||||
// Object.assign(session, {
|
||||
// userUrl: features.extraFile.getUrl(
|
||||
// session?.user?.extraFile$entity &&
|
||||
// session?.user?.extraFile$entity[0]
|
||||
// ),
|
||||
// });
|
||||
// // if (session?.sessionMessage$session) {
|
||||
// // Object.assign(session, {
|
||||
// // wechatMessages: session?.sessionMessage$session,
|
||||
// // // unreadLength: session?.sessionMessage$session?.filter(
|
||||
// // // (ele: any) => ele.isRead === false
|
||||
// // // )?.length,
|
||||
// // });
|
||||
// // }
|
||||
// return session;
|
||||
// },
|
||||
// filters: [
|
||||
// {
|
||||
// filter() {
|
||||
// const { sessionId } = this.props;
|
||||
// if (sessionId) {
|
||||
// return {
|
||||
// id: sessionId,
|
||||
// };
|
||||
// }
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
lifetimes: {
|
||||
ready() {
|
||||
const { sessionId } = this.props;
|
||||
if (sessionId) {
|
||||
const [session] = features.cache?.get('session', {
|
||||
this.getSession(sessionId);
|
||||
}
|
||||
},
|
||||
},
|
||||
listeners: {
|
||||
sessionId(prev, next) {
|
||||
if (prev.sessionId !== next.sessionId) {
|
||||
this.getSession(next.sessionId);
|
||||
}
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
sessionId: '',
|
||||
isEntity: false,
|
||||
},
|
||||
methods: {
|
||||
getSession(sessionId) {
|
||||
const [session] = this.features.cache.get('session', {
|
||||
data: {
|
||||
id: 1,
|
||||
uerId: 1,
|
||||
user: {
|
||||
id: 1,
|
||||
name: 1,
|
||||
|
|
@ -46,7 +126,6 @@ function Header(props) {
|
|||
extension: 1,
|
||||
type: 1,
|
||||
entity: 1,
|
||||
entityId: 1,
|
||||
},
|
||||
filter: {
|
||||
tag1: {
|
||||
|
|
@ -57,35 +136,30 @@ function Header(props) {
|
|||
},
|
||||
},
|
||||
filter: {
|
||||
id: sessionId,
|
||||
},
|
||||
id: sessionId
|
||||
}
|
||||
});
|
||||
if (session) {
|
||||
const url2 = getAvatarUrl(session);
|
||||
setUrl(url2);
|
||||
const name2 = getName(session);
|
||||
setName(name2);
|
||||
}
|
||||
}
|
||||
}, [sessionId, userId]);
|
||||
const getAvatarUrl = (session) => {
|
||||
const { entity, user } = session || {};
|
||||
this.setState({ session });
|
||||
},
|
||||
getAvatarUrl() {
|
||||
const { userUrl, entity } = this.state;
|
||||
const { isEntity } = this.props;
|
||||
const defaultUrl = 'http://qiniu.gecomebox.com/static/defaultAvatar.png';
|
||||
if (user) {
|
||||
const userAvatar = features.extraFile.getUrl(session?.user?.extraFile$entity &&
|
||||
session?.user?.extraFile$entity[0]);
|
||||
return userAvatar || defaultUrl;
|
||||
if (isEntity) {
|
||||
return userUrl || defaultUrl;
|
||||
}
|
||||
else {
|
||||
return defaultUrl;
|
||||
};
|
||||
const getName = (session) => {
|
||||
const { user } = session || {};
|
||||
if (user) {
|
||||
const userName = user?.name || '';
|
||||
const userNickname = user?.name || user?.nickname || '';
|
||||
const userMobile = (user?.mobile$user &&
|
||||
user?.mobile$user[0]?.mobile) ||
|
||||
'';
|
||||
}
|
||||
},
|
||||
getName() {
|
||||
const { session, entity } = this.state;
|
||||
const { isEntity } = this.props;
|
||||
if (isEntity) {
|
||||
const userName = session?.user?.name;
|
||||
const userNickname = session?.user?.name || session?.user?.nickname;
|
||||
const userMobile = session?.user?.mobile$user &&
|
||||
session?.user?.mobile$user[0]?.mobile;
|
||||
if (userName) {
|
||||
return userName;
|
||||
}
|
||||
|
|
@ -94,12 +168,9 @@ function Header(props) {
|
|||
}
|
||||
return userNickname;
|
||||
}
|
||||
else {
|
||||
return '未知';
|
||||
};
|
||||
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(index_module_less_1.default.header, {
|
||||
[index_module_less_1.default.header_mobile]: width === 'xs'
|
||||
}), children: [showBack && ((0, jsx_runtime_1.jsx)(antd_1.Button, { type: "text", onClick: () => {
|
||||
features.navigator.navigateBack();
|
||||
}, children: (0, jsx_runtime_1.jsx)(icons_1.LeftOutlined, { className: index_module_less_1.default.backIcon }) })), (0, jsx_runtime_1.jsxs)("div", { className: index_module_less_1.default.middle, children: [(0, jsx_runtime_1.jsx)(antd_1.Image, { src: url, className: index_module_less_1.default.icon, preview: false }), (0, jsx_runtime_1.jsx)("div", { className: index_module_less_1.default.name, children: name })] })] }));
|
||||
}
|
||||
exports.default = Header;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
import { WebComponentProps } from 'oak-frontend-base';
|
||||
import { EntityDict } from '../../../oak-app-domain';
|
||||
export default function render(props: WebComponentProps<EntityDict, 'session', false, {
|
||||
avatarUrl: string;
|
||||
nickname: string;
|
||||
name: string;
|
||||
showBack: boolean;
|
||||
sessionId: string;
|
||||
}, {
|
||||
getName: () => string;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const tslib_1 = require("tslib");
|
||||
const jsx_runtime_1 = require("react/jsx-runtime");
|
||||
// import { UserOutlined } from '@ant-design/icons';
|
||||
const web_module_less_1 = tslib_1.__importDefault(require("./web.module.less"));
|
||||
const antd_1 = require("antd");
|
||||
const icons_1 = require("@ant-design/icons");
|
||||
const useFeatures_1 = tslib_1.__importDefault(require("../../../hooks/useFeatures"));
|
||||
const classnames_1 = tslib_1.__importDefault(require("classnames"));
|
||||
const web_1 = require("oak-frontend-base/es/platforms/web");
|
||||
function render(props) {
|
||||
const { methods, data } = props;
|
||||
const { nickname, avatarUrl, name, showBack } = data;
|
||||
const { getName } = methods;
|
||||
const defaultUrl = 'http://qiniu.gecomebox.com/static/defaultAvatar.png';
|
||||
const features = (0, useFeatures_1.default)();
|
||||
const width = (0, web_1.useWidth)();
|
||||
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(web_module_less_1.default.header, {
|
||||
[web_module_less_1.default.header_mobile]: width === 'xs'
|
||||
}), children: [showBack && ((0, jsx_runtime_1.jsx)(antd_1.Button, { type: "text", onClick: () => {
|
||||
features.navigator.navigateBack();
|
||||
}, children: (0, jsx_runtime_1.jsx)(icons_1.LeftOutlined, { className: web_module_less_1.default.backIcon }) })), (0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.middle, children: (0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.name, children: getName() }) })] }));
|
||||
}
|
||||
exports.default = render;
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
.header {
|
||||
display: flex;
|
||||
background: #eee;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
z-index: 20;
|
||||
height: 50px;
|
||||
position: absolute;
|
||||
|
||||
.middle {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
|
||||
.icon {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 16px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.header_mobile {
|
||||
background: var(--oak-color-primary);
|
||||
|
||||
.backIcon {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,4 +3,5 @@ import { EntityDict } from '../../../oak-app-domain';
|
|||
export default function render(props: WebComponentProps<EntityDict, 'session', false, {
|
||||
avatarUrl: string;
|
||||
nickname: string;
|
||||
name: string;
|
||||
}, {}>): import("react/jsx-runtime").JSX.Element;
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ const antd_1 = require("antd");
|
|||
const web_module_less_1 = tslib_1.__importDefault(require("./web.module.less"));
|
||||
function render(props) {
|
||||
const { methods, data } = props;
|
||||
const { nickname, avatarUrl } = data;
|
||||
const { nickname, avatarUrl, name } = data;
|
||||
const defaultUrl = 'http://qiniu.gecomebox.com/static/defaultAvatar.png';
|
||||
return ((0, jsx_runtime_1.jsxs)("div", { className: web_module_less_1.default.header, children: [(0, jsx_runtime_1.jsx)(antd_1.Avatar, { shape: "square", className: web_module_less_1.default.avatar, src: avatarUrl || defaultUrl }), (0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.nickname, children: nickname })] }));
|
||||
return ((0, jsx_runtime_1.jsxs)("div", { className: web_module_less_1.default.header, children: [(0, jsx_runtime_1.jsx)(antd_1.Avatar, { shape: "square", className: web_module_less_1.default.avatar, src: avatarUrl || defaultUrl }), (0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.nickname, children: nickname || name })] }));
|
||||
}
|
||||
exports.default = render;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, "session", true, {
|
||||
entity: string;
|
||||
entityFilter: any;
|
||||
entityDisplay: (entity: string, entityId: string) => "";
|
||||
entityDisplay: (data: any) => "";
|
||||
entityProjection: any;
|
||||
sessionId: string;
|
||||
dialog: boolean;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.default = OakComponent({
|
||||
entity: 'session',
|
||||
projection: {
|
||||
projection() {
|
||||
const { entityProjection } = this.props;
|
||||
const proj = {
|
||||
id: 1,
|
||||
entity: 1,
|
||||
entityId: 1,
|
||||
|
|
@ -65,9 +67,21 @@ exports.default = OakComponent({
|
|||
count: 1,
|
||||
},
|
||||
$$createAt$$: 1,
|
||||
};
|
||||
if (entityProjection) {
|
||||
Object.assign(proj, { ...entityProjection });
|
||||
}
|
||||
return proj;
|
||||
},
|
||||
isList: true,
|
||||
formData: function ({ data: sessions, features, props }) {
|
||||
const { entityDisplay, entityProjection } = this.props;
|
||||
if (entityProjection && entityDisplay && sessions && sessions.length > 0) {
|
||||
const sessions1 = entityDisplay(sessions);
|
||||
return {
|
||||
sessions: sessions1,
|
||||
};
|
||||
}
|
||||
// const unReadLength = wechatSessions?.filter(
|
||||
// (ele) => ele.isRead
|
||||
// )
|
||||
|
|
@ -102,8 +116,8 @@ exports.default = OakComponent({
|
|||
},
|
||||
properties: {
|
||||
entity: '',
|
||||
entityFilter: {},
|
||||
entityDisplay: (entity, entityId) => '',
|
||||
entityFilter: undefined,
|
||||
entityDisplay: (data) => '',
|
||||
entityProjection: {},
|
||||
sessionId: '',
|
||||
dialog: false,
|
||||
|
|
@ -167,7 +181,7 @@ exports.default = OakComponent({
|
|||
{
|
||||
sorter: {
|
||||
$attr: {
|
||||
$$updateAt$$: 1,
|
||||
lmts: 1,
|
||||
},
|
||||
$direction: 'desc',
|
||||
},
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
}
|
||||
|
||||
.bothContainer {
|
||||
margin: 0 auto;
|
||||
margin-top: 5vh;
|
||||
margin: 5vh auto;
|
||||
// margin-top: 5vh;
|
||||
width: 90%;
|
||||
min-width: 600px;
|
||||
height: 80vh;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { WebComponentProps } from 'oak-frontend-base';
|
||||
import { EntityDict } from '../../../oak-app-domain';
|
||||
export default function Render(props: WebComponentProps<EntityDict, 'session', false, {
|
||||
sessions: EntityDict['session']['Schema'][];
|
||||
sessions: any;
|
||||
selectedSessionId: string;
|
||||
className: string;
|
||||
dialog: boolean;
|
||||
|
|
|
|||
|
|
@ -16,14 +16,14 @@ function Render(props) {
|
|||
return ((0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.container, children: (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(web_module_less_1.default.bothContainer, className, {
|
||||
[web_module_less_1.default.dialogContainer]: dialog,
|
||||
}), children: [(0, jsx_runtime_1.jsxs)("div", { className: web_module_less_1.default.conversationContainer, children: [(0, jsx_runtime_1.jsx)(header_1.default, {}), (0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.inner, children: sessions?.map((session, index) => {
|
||||
return ((0, jsx_runtime_1.jsx)(cell_1.default, { entityFilter: entityFilter, selectedId: selectedSessionId, onSelect: (id) => {
|
||||
return ((0, jsx_runtime_1.jsx)(cell_1.default, { entityFilter: entityFilter, name: session?.name, selectedId: selectedSessionId, onSelect: (id) => {
|
||||
setSelectedSessionId(id);
|
||||
}, oakId: session.id, oakPath: oakFullpath
|
||||
? `${oakFullpath}.${session.id}`
|
||||
: '' }, session.id));
|
||||
}) })] }), selectedSessionId && ((0, jsx_runtime_1.jsx)(list_1.default, { sessionId: selectedSessionId,
|
||||
// isCombine={true}
|
||||
isEntity: !!entityFilter, oakAutoUnmount: true, oakPath: oakFullpath
|
||||
isEntity: entityFilter ? true : false, isUser: entityFilter ? false : true, oakAutoUnmount: true, oakPath: oakFullpath
|
||||
? `$$sessionMessage/list`
|
||||
: undefined }))] }) }));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,5 +2,6 @@
|
|||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, "sessionMessage", false, {
|
||||
key: string;
|
||||
isEntity: boolean;
|
||||
isUser: boolean;
|
||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||
export default _default;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,38 @@ exports.default = OakComponent({
|
|||
id: 1,
|
||||
entity: 1,
|
||||
entityId: 1,
|
||||
userId: 1,
|
||||
user: {
|
||||
id: 1,
|
||||
name: 1,
|
||||
mobile$user: {
|
||||
$entity: 'mobile',
|
||||
data: {
|
||||
id: 1,
|
||||
mobile: 1,
|
||||
},
|
||||
},
|
||||
extraFile$entity: {
|
||||
$entity: 'extraFile',
|
||||
data: {
|
||||
id: 1,
|
||||
tag1: 1,
|
||||
origin: 1,
|
||||
bucket: 1,
|
||||
objectId: 1,
|
||||
filename: 1,
|
||||
extra1: 1,
|
||||
extension: 1,
|
||||
type: 1,
|
||||
entity: 1,
|
||||
},
|
||||
filter: {
|
||||
tag1: {
|
||||
$in: ['avatar'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
aaoe: 1,
|
||||
extraFile$entity: {
|
||||
|
|
@ -45,7 +77,7 @@ exports.default = OakComponent({
|
|||
formData({ data: sessionMessage, features }) {
|
||||
const type = sessionMessage?.type;
|
||||
// const data = wechatMessage?.data;
|
||||
// const session = sessionMessage?.session;
|
||||
const session = sessionMessage?.session;
|
||||
const newSessionMessage = {
|
||||
type,
|
||||
aaoe: sessionMessage?.aaoe,
|
||||
|
|
@ -54,15 +86,12 @@ exports.default = OakComponent({
|
|||
id: sessionMessage?.id,
|
||||
$$createAt$$: sessionMessage?.$$createAt$$,
|
||||
sessionId: sessionMessage?.sessionId,
|
||||
// employerId: conversation?.employerId,
|
||||
// employerMobile:
|
||||
// conversation?.employer?.mobile$user &&
|
||||
// conversation?.employer?.mobile$user[0]?.mobile,
|
||||
userId: session?.userId,
|
||||
userMobile: session?.user?.mobile$user &&
|
||||
session?.user?.mobile$user[0]?.mobile,
|
||||
// companyName: conversation?.company?.name,
|
||||
// employerAvatar: this.features.extraFile.getUrl(
|
||||
// conversation?.employer?.extraFile$entity &&
|
||||
// conversation?.employer?.extraFile$entity[0]
|
||||
// ),
|
||||
userAvatar: this.features.extraFile.getUrl(session?.user?.extraFile$entity &&
|
||||
session?.user?.extraFile$entity[0]),
|
||||
};
|
||||
// if (type === 'image') {
|
||||
// const extraFile$entity =
|
||||
|
|
@ -76,25 +105,35 @@ exports.default = OakComponent({
|
|||
properties: {
|
||||
key: '',
|
||||
isEntity: false,
|
||||
isUser: false,
|
||||
},
|
||||
methods: {
|
||||
getAvatarUrl(type) {
|
||||
getAvatarUrl(aaoe) {
|
||||
const defaultUrl = 'http://qiniu.gecomebox.com/static/defaultAvatar.png';
|
||||
const { companyLogoUrl, employerAvatar, parkLogoUrl } = this.state;
|
||||
switch (type) {
|
||||
case 'company': {
|
||||
return companyLogoUrl || defaultUrl;
|
||||
}
|
||||
case 'employer': {
|
||||
return employerAvatar || defaultUrl;
|
||||
}
|
||||
case 'platformProvider': {
|
||||
return process.env.PUBLIC_URL + '/logo192.png';
|
||||
}
|
||||
case 'park': {
|
||||
return parkLogoUrl || defaultUrl;
|
||||
const { companyLogoUrl, userAvatar, parkLogoUrl } = this.state;
|
||||
if (aaoe) {
|
||||
return defaultUrl;
|
||||
}
|
||||
else {
|
||||
return userAvatar || defaultUrl;
|
||||
}
|
||||
// switch (type) {
|
||||
// case 'company': {
|
||||
// return companyLogoUrl || defaultUrl;
|
||||
// }
|
||||
// case 'user': {
|
||||
// return userAvatar || defaultUrl;
|
||||
// }
|
||||
// case 'platformProvider': {
|
||||
// return process.env.PUBLIC_URL + '/logo192.png';
|
||||
// }
|
||||
// case 'park': {
|
||||
// return parkLogoUrl || defaultUrl;
|
||||
// }
|
||||
// default: {
|
||||
// return defaultUrl
|
||||
// }
|
||||
// }
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { WebComponentProps } from 'oak-frontend-base';
|
|||
import { EntityDict } from '../../../oak-app-domain';
|
||||
export default function render(props: WebComponentProps<EntityDict, 'sessionMessage', false, {
|
||||
isEntity: boolean;
|
||||
isUser: boolean;
|
||||
$$createAt$$: number;
|
||||
text: string;
|
||||
type: string;
|
||||
|
|
@ -10,5 +11,5 @@ export default function render(props: WebComponentProps<EntityDict, 'sessionMess
|
|||
sessionId: string;
|
||||
id: string;
|
||||
}, {
|
||||
getAvatarUrl: (type: string) => string;
|
||||
getAvatarUrl: (aaoe: boolean) => string;
|
||||
}>): import("react/jsx-runtime").JSX.Element;
|
||||
|
|
|
|||
|
|
@ -8,13 +8,13 @@ const classnames_1 = tslib_1.__importDefault(require("classnames"));
|
|||
const web_module_less_1 = tslib_1.__importDefault(require("./web.module.less"));
|
||||
function render(props) {
|
||||
const { data, methods } = props;
|
||||
const { $$createAt$$, text, type, picUrl, isEntity, aaoe, sessionId, } = data;
|
||||
const { $$createAt$$, text, type, picUrl, isEntity, isUser, aaoe, sessionId, } = data;
|
||||
const { t, getAvatarUrl } = methods;
|
||||
return ((0, jsx_runtime_1.jsx)(ICell, { time: $$createAt$$, children: (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(web_module_less_1.default.myMessage, {
|
||||
[web_module_less_1.default.notMyMessage]: isEntity !== aaoe,
|
||||
}), children: [(0, jsx_runtime_1.jsx)(antd_1.Image, { preview: false, className: web_module_less_1.default.avatar, src: getAvatarUrl(type) }), (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)({
|
||||
[web_module_less_1.default.notMyMessage]: (isEntity && !aaoe) || (isUser && aaoe),
|
||||
}), children: [(0, jsx_runtime_1.jsx)(antd_1.Image, { preview: false, className: web_module_less_1.default.avatar, src: getAvatarUrl(aaoe) }), (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)({
|
||||
[web_module_less_1.default.messageType_text]: type === 'text',
|
||||
[web_module_less_1.default.messageType_text_no]: isEntity !== aaoe,
|
||||
[web_module_less_1.default.messageType_text_no]: (isEntity && !aaoe) || (isUser && aaoe),
|
||||
}), children: [type === 'text' && (0, jsx_runtime_1.jsx)(IText, { value: text }), type === 'image' && (0, jsx_runtime_1.jsx)(IImage, { url: picUrl })] })] }) }));
|
||||
}
|
||||
exports.default = render;
|
||||
|
|
@ -27,7 +27,12 @@ function ICell(props) {
|
|||
}
|
||||
function IText(props) {
|
||||
const { value } = props;
|
||||
return (0, jsx_runtime_1.jsx)("div", { children: value });
|
||||
return (0, jsx_runtime_1.jsx)("div", { style: { whiteSpace: 'pre-wrap' }, children: value });
|
||||
// return <div>
|
||||
// <Typography.Paragraph>
|
||||
// {value}
|
||||
// </Typography.Paragraph>
|
||||
// </div>;
|
||||
}
|
||||
function IImage(props) {
|
||||
const { url } = props;
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
}
|
||||
|
||||
.avatar {
|
||||
margin: 10px;
|
||||
margin: 0 10px;
|
||||
height: 30px !important;
|
||||
width: 30px !important;
|
||||
padding: 0 !important;
|
||||
|
|
@ -93,7 +93,8 @@
|
|||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: flex-start;
|
||||
align-items: baseline;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.notMyMessage {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { EntityDict } from '../../../oak-app-domain';
|
|||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<EntityDict, "sessionMessage", true, {
|
||||
sessionId: string;
|
||||
isEntity: boolean;
|
||||
isUser: boolean;
|
||||
dialog: boolean;
|
||||
entity: string;
|
||||
entityId: string;
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ exports.default = OakComponent({
|
|||
lifetimes: {
|
||||
async ready() {
|
||||
const { sessionId } = this.props;
|
||||
this.subData([
|
||||
await this.subData([
|
||||
{
|
||||
entity: 'sessionMessage',
|
||||
filter: {
|
||||
|
|
@ -53,7 +53,7 @@ exports.default = OakComponent({
|
|||
},
|
||||
id: `${constants_1.DATA_SUBSCRIBER_KEYS.sessionMessageList}-${sessionId}`,
|
||||
}
|
||||
]);
|
||||
], async () => { await this.pageScroll('comment'); });
|
||||
// const userId = this.features.token.getUserId(true);
|
||||
// const applicationId = this.features.application.getApplicationId();
|
||||
// if (!sessionId) {
|
||||
|
|
@ -120,6 +120,7 @@ exports.default = OakComponent({
|
|||
properties: {
|
||||
sessionId: '',
|
||||
isEntity: false,
|
||||
isUser: false,
|
||||
dialog: false,
|
||||
entity: '',
|
||||
entityId: '',
|
||||
|
|
@ -268,7 +269,7 @@ exports.default = OakComponent({
|
|||
fileType: type,
|
||||
size,
|
||||
extension,
|
||||
entity: 'wechatMessage',
|
||||
entity: 'sessionMessage',
|
||||
bucket: '',
|
||||
id: (0, uuid_1.generateNewId)(),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
display: flex;
|
||||
overflow: scroll;
|
||||
flex-direction: column;
|
||||
// margin-top: 50px;
|
||||
margin-top: 50px;
|
||||
overflow-x: hidden;
|
||||
height: 100%;
|
||||
}
|
||||
|
|
@ -37,6 +37,8 @@
|
|||
position: absolute;
|
||||
z-index: 100;
|
||||
|
||||
// resize: both;
|
||||
// cursor: nwse-resize;
|
||||
.toolbar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
|
@ -56,14 +58,17 @@
|
|||
|
||||
padding: 0 10px;
|
||||
|
||||
|
||||
.textarea {
|
||||
border: none;
|
||||
outline: none;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.textarea:focus {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.btn {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ export default function Render(props: WebComponentProps<EntityDict, 'sessionMess
|
|||
buttonHidden: boolean;
|
||||
sessionId: string;
|
||||
isEntity: boolean;
|
||||
isUser: boolean;
|
||||
employerId: string;
|
||||
}, {
|
||||
setButtonHidden: (isHidden: boolean) => void;
|
||||
|
|
|
|||
|
|
@ -6,12 +6,17 @@ const react_1 = require("react");
|
|||
const antd_1 = require("antd");
|
||||
const icons_1 = require("@ant-design/icons");
|
||||
const cell_1 = tslib_1.__importDefault(require("../../../components/sessionMessage/cell"));
|
||||
const forMessage_1 = tslib_1.__importDefault(require("../../../components/session/forMessage"));
|
||||
const web_module_less_1 = tslib_1.__importDefault(require("./web.module.less"));
|
||||
function Render(props) {
|
||||
const { data, methods } = props;
|
||||
const { sessionId, isEntity, sessionMessageList, oakFullpath, text, employerId, buttonHidden, } = data;
|
||||
const { sessionId, isEntity, isUser, sessionMessageList, oakFullpath, text, employerId, buttonHidden, } = data;
|
||||
const { setButtonHidden, customUpload, setContent, pageScroll, createMessage, } = methods;
|
||||
const [bottomHeight, setBottomHeight] = (0, react_1.useState)(0);
|
||||
const textareaRef = (0, react_1.useRef)(null);
|
||||
// const [text1, setText1] = useState("");
|
||||
// const newBottomHeight =
|
||||
// window.document.getElementById('bottom')?.offsetHeight!;
|
||||
(0, react_1.useEffect)(() => {
|
||||
if (buttonHidden) {
|
||||
const newBottomHeight = window.document.getElementById('bottom')?.offsetHeight;
|
||||
|
|
@ -21,7 +26,42 @@ function Render(props) {
|
|||
setBottomHeight(0);
|
||||
}
|
||||
}, [buttonHidden]);
|
||||
return ((0, jsx_runtime_1.jsxs)("div", { className: web_module_less_1.default.container, children: [(0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.inner, style: {
|
||||
const handleKeyDown = (event) => {
|
||||
// if (event.key === "Enter" && event.shiftKey) {
|
||||
// event.preventDefault(); // 阻止默认的换行行为
|
||||
// 执行你的换行逻辑
|
||||
// setContent(text + "\n");
|
||||
// if (textareaRef && textareaRef.current && textareaRef.current!.resizableTextArea) {
|
||||
// const textArea = textareaRef.current.resizableTextArea.textAreaRef; // 获取 Input.TextArea 的原生 textarea 元素
|
||||
// console.log(textArea)
|
||||
// if (textArea) {
|
||||
// console.log(textArea)
|
||||
// const selectionStart = textArea?.selectionStart;
|
||||
// const value = textArea?.value;
|
||||
// const newValue =
|
||||
// value?.substring(0, selectionStart) +
|
||||
// "\n" +
|
||||
// value?.substring(selectionStart);
|
||||
// textArea.value = newValue;
|
||||
// textArea.selectionStart = textArea.selectionEnd = selectionStart + 1;
|
||||
// // 触发 onChange 事件,更新 Input.TextArea 的值
|
||||
// textArea.dispatchEvent(new Event("input"));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
if (event.key === "Enter" && !event.shiftKey) {
|
||||
event.preventDefault();
|
||||
createMessage();
|
||||
pageScroll('comment');
|
||||
}
|
||||
};
|
||||
return ((0, jsx_runtime_1.jsxs)("div", { className: web_module_less_1.default.container, children: [(0, jsx_runtime_1.jsx)(forMessage_1.default
|
||||
// showBack={false}
|
||||
, {
|
||||
// showBack={false}
|
||||
sessionId: sessionId, isEntity: isEntity,
|
||||
// userId={employerId}
|
||||
oakPath: 'session:header1', oakAutoUnmount: true }), (0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.inner, style: {
|
||||
marginBottom: bottomHeight ? `${bottomHeight}px` : '168px',
|
||||
}, id: "comment", onClick: () => setButtonHidden(true), children: sessionMessageList
|
||||
?.sort((a, b) => a.$$createAt$$ -
|
||||
|
|
@ -29,18 +69,22 @@ function Render(props) {
|
|||
.map((sessionMessage, index) => {
|
||||
return ((0, jsx_runtime_1.jsx)(cell_1.default, { oakId: sessionMessage.id, oakPath: oakFullpath
|
||||
? `${oakFullpath}.${sessionMessage.id}`
|
||||
: '', isEntity: isEntity }, sessionMessage.id));
|
||||
: '', isEntity: isEntity, isUser: isUser }, sessionMessage.id));
|
||||
}) }), (0, jsx_runtime_1.jsxs)("div", { className: web_module_less_1.default.bottom, id: "bottom", children: [(0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.toolbar, children: (0, jsx_runtime_1.jsx)(antd_1.Upload, { accept: 'image/*', multiple: false, showUploadList: false, customRequest: () => { }, onChange: ({ file }) => {
|
||||
customUpload(file);
|
||||
}, children: (0, jsx_runtime_1.jsx)(icons_1.PictureOutlined, { className: web_module_less_1.default.icon }) }) }), (0, jsx_runtime_1.jsxs)("div", { className: web_module_less_1.default.textareaBox, children: [(0, jsx_runtime_1.jsx)(antd_1.Input.TextArea, { className: web_module_less_1.default.textarea, rows: 5, onChange: (e) => {
|
||||
}, children: (0, jsx_runtime_1.jsx)(icons_1.PictureOutlined, { className: web_module_less_1.default.icon }) }) }), (0, jsx_runtime_1.jsxs)("div", { className: web_module_less_1.default.textareaBox, children: [(0, jsx_runtime_1.jsx)(antd_1.Input.TextArea, { ref: textareaRef, className: web_module_less_1.default.textarea,
|
||||
// autoSize={{ minRows: 2, maxRows: 15 }}
|
||||
maxLength: 500, placeholder: "Enter \u53D1\u9001\uFF0CShift + Enter\u6362\u884C", rows: 5, onChange: (e) => {
|
||||
setContent(e.target.value);
|
||||
}, onFocus: () => {
|
||||
setButtonHidden(true);
|
||||
}, onPressEnter: (e) => {
|
||||
e.preventDefault();
|
||||
createMessage();
|
||||
pageScroll('comment');
|
||||
}, value: text }), (0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.btn, children: (0, jsx_runtime_1.jsx)(antd_1.Button, { type: "primary", disabled: text ? false : true, onClick: () => {
|
||||
},
|
||||
// onPressEnter={(e) => {
|
||||
// e.preventDefault();
|
||||
// createMessage();
|
||||
// pageScroll('comment');
|
||||
// }}
|
||||
onKeyDown: handleKeyDown, value: text }), (0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.btn, children: (0, jsx_runtime_1.jsx)(antd_1.Button, { type: "primary", disabled: text ? false : true, onClick: () => {
|
||||
createMessage();
|
||||
pageScroll('comment');
|
||||
}, children: "\u53D1\u9001" }) })] })] })] }));
|
||||
|
|
|
|||
|
|
@ -6,5 +6,6 @@ export interface Schema extends EntityShape {
|
|||
entityId: String<64>;
|
||||
user?: User;
|
||||
lmts?: Datetime;
|
||||
openId?: String<64>;
|
||||
}
|
||||
export type Relation = 'partner';
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ const entityDesc = {
|
|||
entityId: '关联对象id',
|
||||
user: '发送者',
|
||||
lmts: '最后一条消息的发送时间',
|
||||
openId: 'openId'
|
||||
},
|
||||
r: {
|
||||
partner: '所有者',
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ export type OpSchema = EntityShape & {
|
|||
entityId: String<64>;
|
||||
userId?: ForeignKey<"user"> | null;
|
||||
lmts?: Datetime | null;
|
||||
openId?: String<64> | null;
|
||||
};
|
||||
export type OpAttr = keyof OpSchema;
|
||||
export type Schema = EntityShape & {
|
||||
|
|
@ -24,6 +25,7 @@ export type Schema = EntityShape & {
|
|||
entityId: String<64>;
|
||||
userId?: ForeignKey<"user"> | null;
|
||||
lmts?: Datetime | null;
|
||||
openId?: String<64> | null;
|
||||
user?: User.Schema | null;
|
||||
application?: Application.Schema;
|
||||
readRemark$session?: Array<ReadRemark.Schema>;
|
||||
|
|
@ -49,6 +51,7 @@ type AttrFilter = {
|
|||
userId: Q_StringValue;
|
||||
user: User.Filter;
|
||||
lmts: Q_DateValue;
|
||||
openId: Q_StringValue;
|
||||
application: Application.Filter;
|
||||
readRemark$session: ReadRemark.Filter & SubQueryPredicateMetadata;
|
||||
sessionMessage$session: SessionMessage.Filter & SubQueryPredicateMetadata;
|
||||
|
|
@ -69,6 +72,7 @@ export type Projection = {
|
|||
userId?: number;
|
||||
user?: User.Projection;
|
||||
lmts?: number;
|
||||
openId?: number;
|
||||
application?: Application.Projection;
|
||||
readRemark$session?: ReadRemark.Selection & {
|
||||
$entity: "readRemark";
|
||||
|
|
@ -128,6 +132,8 @@ export type SortAttr = {
|
|||
user: User.SortAttr;
|
||||
} | {
|
||||
lmts: number;
|
||||
} | {
|
||||
openId: number;
|
||||
} | {
|
||||
application: Application.SortAttr;
|
||||
} | {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,12 @@ exports.desc = {
|
|||
},
|
||||
lmts: {
|
||||
type: "datetime"
|
||||
},
|
||||
openId: {
|
||||
type: "varchar",
|
||||
params: {
|
||||
length: 64
|
||||
}
|
||||
}
|
||||
},
|
||||
actionType: "crud",
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{ "name": "会话", "attr": { "entity": "关联对象", "entityId": "关联对象id", "user": "发送者", "lmts": "最后一条消息的发送时间" }, "r": { "partner": "所有者" } }
|
||||
{ "name": "会话", "attr": { "entity": "关联对象", "entityId": "关联对象id", "user": "发送者", "lmts": "最后一条消息的发送时间", "openId": "openId" }, "r": { "partner": "所有者" } }
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ export default OakComponent({
|
|||
onSelect: (id: string) => { },
|
||||
key: '' as string,
|
||||
entityFilter: {},
|
||||
name: undefined,
|
||||
},
|
||||
methods: {
|
||||
getAvatarUrl() {
|
||||
|
|
@ -164,6 +165,7 @@ export default OakComponent({
|
|||
return '用户' + userMobile;
|
||||
}
|
||||
|
||||
|
||||
return userNickname;
|
||||
} else {
|
||||
return '未知';
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ export default function render(
|
|||
userType: string;
|
||||
selectedId: string;
|
||||
onSelect: (id: string) => void;
|
||||
name: string;
|
||||
},
|
||||
{
|
||||
getName: () => string;
|
||||
|
|
@ -34,6 +35,7 @@ export default function render(
|
|||
id,
|
||||
unreadLength,
|
||||
sessiontMessages = [],
|
||||
name,
|
||||
} = data;
|
||||
const { t, getName, getAvatarUrl } = methods;
|
||||
const sessiontMessage = sessiontMessages && sessiontMessages[0];
|
||||
|
|
@ -67,7 +69,7 @@ export default function render(
|
|||
</Badge>
|
||||
<div className={Style.inner}>
|
||||
<div className={Style.top}>
|
||||
<div className={Style.title}>{getName()}</div>
|
||||
<div className={Style.title}>{name || getName()}</div>
|
||||
<div className={Style.date}>
|
||||
{sessiontMessage &&
|
||||
(today === createAt2
|
||||
|
|
|
|||
|
|
@ -0,0 +1,183 @@
|
|||
import { OpSchema as ExtraFile } from '../../../oak-app-domain/ExtraFile/Schema';
|
||||
|
||||
export default OakComponent({
|
||||
// entity: 'session',
|
||||
// projection: {
|
||||
// id: 1,
|
||||
// userId: 1,
|
||||
// entity: 1,
|
||||
// entityId: 1,
|
||||
// lmts: 1,
|
||||
// user: {
|
||||
// id: 1,
|
||||
// name: 1,
|
||||
// nickname: 1,
|
||||
// mobile$user: {
|
||||
// $entity: 'mobile',
|
||||
// data: {
|
||||
// id: 1,
|
||||
// mobile: 1,
|
||||
// userId: 1,
|
||||
// },
|
||||
// },
|
||||
// extraFile$entity: {
|
||||
// $entity: 'extraFile',
|
||||
// data: {
|
||||
// id: 1,
|
||||
// tag1: 1,
|
||||
// origin: 1,
|
||||
// bucket: 1,
|
||||
// objectId: 1,
|
||||
// filename: 1,
|
||||
// extra1: 1,
|
||||
// extension: 1,
|
||||
// type: 1,
|
||||
// entity: 1,
|
||||
// },
|
||||
// filter: {
|
||||
// tag1: {
|
||||
// $in: ['avatar'],
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
isList: false,
|
||||
// formData({ data, features }) {
|
||||
// const session = Object.assign(
|
||||
// {},
|
||||
// data
|
||||
// ) as any;
|
||||
// console.log(session)
|
||||
|
||||
// Object.assign(session, {
|
||||
// userUrl: features.extraFile.getUrl(
|
||||
// session?.user?.extraFile$entity &&
|
||||
// session?.user?.extraFile$entity[0]
|
||||
// ),
|
||||
// });
|
||||
// // if (session?.sessionMessage$session) {
|
||||
// // Object.assign(session, {
|
||||
// // wechatMessages: session?.sessionMessage$session,
|
||||
// // // unreadLength: session?.sessionMessage$session?.filter(
|
||||
// // // (ele: any) => ele.isRead === false
|
||||
// // // )?.length,
|
||||
// // });
|
||||
// // }
|
||||
// return session;
|
||||
// },
|
||||
// filters: [
|
||||
// {
|
||||
// filter() {
|
||||
// const { sessionId } = this.props;
|
||||
// if (sessionId) {
|
||||
// return {
|
||||
// id: sessionId,
|
||||
// };
|
||||
|
||||
// }
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
lifetimes: {
|
||||
ready() {
|
||||
const { sessionId } = this.props;
|
||||
if (sessionId) {
|
||||
this.getSession(sessionId)
|
||||
}
|
||||
},
|
||||
},
|
||||
listeners: {
|
||||
sessionId(prev, next) {
|
||||
if (prev.sessionId !== next.sessionId) {
|
||||
this.getSession(next.sessionId);
|
||||
}
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
sessionId: '' as string,
|
||||
isEntity: false,
|
||||
},
|
||||
methods: {
|
||||
getSession(sessionId: string) {
|
||||
const [session] = this.features.cache.get(
|
||||
'session',
|
||||
{
|
||||
data: {
|
||||
id: 1,
|
||||
user: {
|
||||
id: 1,
|
||||
name: 1,
|
||||
nickname: 1,
|
||||
mobile$user: {
|
||||
$entity: 'mobile',
|
||||
data: {
|
||||
id: 1,
|
||||
mobile: 1,
|
||||
userId: 1,
|
||||
},
|
||||
},
|
||||
extraFile$entity: {
|
||||
$entity: 'extraFile',
|
||||
data: {
|
||||
id: 1,
|
||||
tag1: 1,
|
||||
origin: 1,
|
||||
bucket: 1,
|
||||
objectId: 1,
|
||||
filename: 1,
|
||||
extra1: 1,
|
||||
extension: 1,
|
||||
type: 1,
|
||||
entity: 1,
|
||||
},
|
||||
filter: {
|
||||
tag1: {
|
||||
$in: ['avatar'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
filter: {
|
||||
id: sessionId
|
||||
}
|
||||
}
|
||||
);
|
||||
this.setState({ session })
|
||||
},
|
||||
getAvatarUrl() {
|
||||
const { userUrl, entity } = this.state;
|
||||
const { isEntity } = this.props;
|
||||
const defaultUrl =
|
||||
'http://qiniu.gecomebox.com/static/defaultAvatar.png';
|
||||
if (isEntity) {
|
||||
return userUrl || defaultUrl;
|
||||
} else {
|
||||
return defaultUrl;
|
||||
}
|
||||
},
|
||||
getName() {
|
||||
const { session, entity } = this.state;
|
||||
const { isEntity } = this.props;
|
||||
if (isEntity) {
|
||||
const userName = session?.user?.name;
|
||||
const userNickname = session?.user?.name || session?.user?.nickname;
|
||||
const userMobile =
|
||||
session?.user?.mobile$user &&
|
||||
session?.user?.mobile$user[0]?.mobile;
|
||||
if (userName) {
|
||||
return userName;
|
||||
}
|
||||
if (userMobile) {
|
||||
return '用户' + userMobile;
|
||||
}
|
||||
|
||||
return userNickname;
|
||||
} else {
|
||||
return '未知';
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { Button, Image } from 'antd';
|
||||
|
||||
import { LeftOutlined } from '@ant-design/icons';
|
||||
import useFeatures from '../../..//hooks/useFeatures';
|
||||
import classNames from 'classnames';
|
||||
import { EntityDict } from '../../../oak-app-domain';
|
||||
import Style from './index.module.less';
|
||||
import { useWidth } from 'oak-frontend-base/es/platforms/web';
|
||||
|
||||
type HeaderProps = {
|
||||
showBack: boolean;
|
||||
sessionId: string;
|
||||
userId: string; //雇主
|
||||
};
|
||||
|
||||
function Header(props: HeaderProps) {
|
||||
const features = useFeatures();
|
||||
const width = useWidth();
|
||||
|
||||
const { showBack = true, sessionId, userId } = props;
|
||||
|
||||
const [name, setName] = useState('');
|
||||
const [url, setUrl] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
if (sessionId) {
|
||||
const [session] = features.cache?.get(
|
||||
'session',
|
||||
{
|
||||
data: {
|
||||
id: 1,
|
||||
uerId: 1, //顾客
|
||||
user: {
|
||||
id: 1,
|
||||
name: 1,
|
||||
nickname: 1,
|
||||
mobile$user: {
|
||||
$entity: 'mobile',
|
||||
data: {
|
||||
id: 1,
|
||||
mobile: 1,
|
||||
userId: 1,
|
||||
},
|
||||
},
|
||||
extraFile$entity: {
|
||||
$entity: 'extraFile',
|
||||
data: {
|
||||
id: 1,
|
||||
tag1: 1,
|
||||
origin: 1,
|
||||
bucket: 1,
|
||||
objectId: 1,
|
||||
filename: 1,
|
||||
extra1: 1,
|
||||
extension: 1,
|
||||
type: 1,
|
||||
entity: 1,
|
||||
entityId: 1,
|
||||
},
|
||||
filter: {
|
||||
tag1: {
|
||||
$in: ['avatar'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
filter: {
|
||||
id: sessionId!,
|
||||
},
|
||||
}
|
||||
);
|
||||
if (session) {
|
||||
const url2 = getAvatarUrl(session);
|
||||
setUrl(url2);
|
||||
const name2 = getName(session);
|
||||
setName(name2);
|
||||
}
|
||||
|
||||
}
|
||||
}, [sessionId, userId]);
|
||||
|
||||
const getAvatarUrl = (
|
||||
session: Partial<EntityDict['session']['Schema']>
|
||||
) => {
|
||||
const { entity, user } = session || {};
|
||||
const defaultUrl = 'http://qiniu.gecomebox.com/static/defaultAvatar.png';
|
||||
|
||||
if (user) {
|
||||
const userAvatar = features.extraFile.getUrl(
|
||||
session?.user?.extraFile$entity &&
|
||||
session?.user?.extraFile$entity[0]
|
||||
);
|
||||
return userAvatar || defaultUrl;
|
||||
}
|
||||
return defaultUrl;
|
||||
|
||||
};
|
||||
const getName = (
|
||||
session: Partial<EntityDict['session']['Schema']>
|
||||
): string => {
|
||||
const { user } =
|
||||
session || {};
|
||||
if (user) {
|
||||
const userName = user?.name || '';
|
||||
const userNickname = user?.name || user?.nickname || '';
|
||||
const userMobile =
|
||||
(user?.mobile$user &&
|
||||
user?.mobile$user[0]?.mobile) ||
|
||||
'';
|
||||
if (userName) {
|
||||
return userName;
|
||||
}
|
||||
if (userMobile) {
|
||||
return '用户' + userMobile;
|
||||
}
|
||||
|
||||
return userNickname;
|
||||
}
|
||||
return '未知';
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={classNames(Style.header, {
|
||||
[Style.header_mobile]: width === 'xs'
|
||||
})}>
|
||||
{showBack && (
|
||||
<Button
|
||||
type="text"
|
||||
onClick={() => {
|
||||
features.navigator.navigateBack();
|
||||
}}
|
||||
>
|
||||
<LeftOutlined className={Style.backIcon} />
|
||||
</Button>
|
||||
)}
|
||||
<div className={Style.middle}>
|
||||
<Image src={url} className={Style.icon} preview={false} />
|
||||
<div className={Style.name}>{name}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Header;
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
.header {
|
||||
display: flex;
|
||||
background: #eee;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
z-index: 20;
|
||||
height: 50px;
|
||||
position: absolute;
|
||||
|
||||
.middle {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
|
||||
.icon {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 16px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.header_mobile {
|
||||
background: var(--oak-color-primary);
|
||||
|
||||
.backIcon {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
import React from "react";
|
||||
import { Avatar } from 'antd';
|
||||
// import { UserOutlined } from '@ant-design/icons';
|
||||
import Style from './web.module.less';
|
||||
import { WebComponentProps } from 'oak-frontend-base';
|
||||
import { EntityDict } from '../../../oak-app-domain';
|
||||
import { Button, Image } from 'antd';
|
||||
import { LeftOutlined } from '@ant-design/icons';
|
||||
import useFeatures from '../../../hooks/useFeatures';
|
||||
import classNames from 'classnames';
|
||||
import { useWidth } from 'oak-frontend-base/es/platforms/web';
|
||||
export default function render(props: WebComponentProps<
|
||||
EntityDict,
|
||||
'session',
|
||||
false,
|
||||
{
|
||||
avatarUrl: string,
|
||||
nickname: string,
|
||||
name: string,
|
||||
showBack: boolean;
|
||||
sessionId: string;
|
||||
},
|
||||
{
|
||||
getName: () => string;
|
||||
}
|
||||
>) {
|
||||
const { methods, data } = props;
|
||||
const { nickname, avatarUrl, name, showBack } = data;
|
||||
const { getName } = methods;
|
||||
const defaultUrl = 'http://qiniu.gecomebox.com/static/defaultAvatar.png'
|
||||
const features = useFeatures();
|
||||
const width = useWidth();
|
||||
|
||||
return (
|
||||
<div className={classNames(Style.header, {
|
||||
[Style.header_mobile]: width === 'xs'
|
||||
})}>
|
||||
{showBack && (
|
||||
<Button
|
||||
type="text"
|
||||
onClick={() => {
|
||||
features.navigator.navigateBack();
|
||||
}}
|
||||
>
|
||||
<LeftOutlined className={Style.backIcon} />
|
||||
</Button>
|
||||
)}
|
||||
<div className={Style.middle}>
|
||||
{/* <Image src={url} className={Style.icon} preview={false} /> */}
|
||||
<div className={Style.name}>{getName()}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -11,7 +11,6 @@ export default OakComponent({
|
|||
(ele: ExtraFile) => ele.tag1 === 'avatar'
|
||||
);
|
||||
const avatarUrl = features.extraFile.getUrl(extraFile);
|
||||
|
||||
return {
|
||||
mobile,
|
||||
avatarUrl,
|
||||
|
|
|
|||
|
|
@ -13,13 +13,14 @@ export default function render(props: WebComponentProps<
|
|||
{
|
||||
avatarUrl: string,
|
||||
nickname: string,
|
||||
name: string,
|
||||
},
|
||||
{
|
||||
|
||||
}
|
||||
>) {
|
||||
const { methods, data } = props;
|
||||
const { nickname, avatarUrl } = data;
|
||||
const { nickname, avatarUrl, name } = data;
|
||||
const defaultUrl = 'http://qiniu.gecomebox.com/static/defaultAvatar.png'
|
||||
|
||||
return (
|
||||
|
|
@ -43,7 +44,7 @@ export default function render(props: WebComponentProps<
|
|||
src={avatarUrl || defaultUrl}
|
||||
/>
|
||||
|
||||
<div className={Style.nickname}>{nickname}</div>
|
||||
<div className={Style.nickname}>{nickname || name}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -2,7 +2,9 @@ import assert from "assert";
|
|||
|
||||
export default OakComponent({
|
||||
entity: 'session',
|
||||
projection: {
|
||||
projection() {
|
||||
const { entityProjection } = this.props;
|
||||
const proj = {
|
||||
id: 1,
|
||||
entity: 1,
|
||||
entityId: 1,
|
||||
|
|
@ -65,9 +67,23 @@ export default OakComponent({
|
|||
count: 1,
|
||||
},
|
||||
$$createAt$$: 1,
|
||||
};
|
||||
if (entityProjection) {
|
||||
Object.assign(proj, { ...entityProjection })
|
||||
}
|
||||
return proj;
|
||||
},
|
||||
isList: true,
|
||||
formData: function ({ data: sessions, features, props }) {
|
||||
const { entityDisplay, entityProjection } = this.props;
|
||||
if (entityProjection && entityDisplay && sessions && sessions.length > 0) {
|
||||
|
||||
const sessions1 = entityDisplay(sessions)
|
||||
|
||||
return {
|
||||
sessions: sessions1,
|
||||
}
|
||||
}
|
||||
// const unReadLength = wechatSessions?.filter(
|
||||
// (ele) => ele.isRead
|
||||
// )
|
||||
|
|
@ -102,8 +118,8 @@ export default OakComponent({
|
|||
},
|
||||
properties: {
|
||||
entity: '' as string, // entity端,指示相应的entity
|
||||
entityFilter: {} as any, // entity端,指示相应的entity查询条件
|
||||
entityDisplay: (entity: string, entityId: string) => '', // user端,指示如何显示entity对象名称
|
||||
entityFilter: undefined as any, // entity端,指示相应的entity查询条件
|
||||
entityDisplay: (data: any) => '', // user端,指示如何显示entity对象名称
|
||||
entityProjection: {} as any, // user端,指示需要取哪些entity的属性来显示entityDisplay
|
||||
sessionId: '' as string, // 指示需要打开的默认session
|
||||
dialog: false as boolean,
|
||||
|
|
@ -168,7 +184,7 @@ export default OakComponent({
|
|||
{
|
||||
sorter: {
|
||||
$attr: {
|
||||
$$updateAt$$: 1,
|
||||
lmts: 1,
|
||||
},
|
||||
$direction: 'desc',
|
||||
},
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
}
|
||||
|
||||
.bothContainer {
|
||||
margin: 0 auto;
|
||||
margin-top: 5vh;
|
||||
margin: 5vh auto;
|
||||
// margin-top: 5vh;
|
||||
width: 90%;
|
||||
min-width: 600px;
|
||||
height: 80vh;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export default function Render(
|
|||
'session',
|
||||
false,
|
||||
{
|
||||
sessions: EntityDict['session']['Schema'][];
|
||||
sessions: any;
|
||||
selectedSessionId: string;
|
||||
// unReadConversation: number;
|
||||
className: string;
|
||||
|
|
@ -52,10 +52,11 @@ export default function Render(
|
|||
// clear={clearUnRead}
|
||||
/> */}
|
||||
<div className={Style.inner}>
|
||||
{sessions?.map((session, index: number) => {
|
||||
{sessions?.map((session: any, index: number) => {
|
||||
return (
|
||||
<SessionCell
|
||||
entityFilter={entityFilter}
|
||||
name={session?.name}
|
||||
selectedId={selectedSessionId}
|
||||
onSelect={(id: string) => {
|
||||
setSelectedSessionId(id);
|
||||
|
|
@ -76,7 +77,8 @@ export default function Render(
|
|||
<MessageList
|
||||
sessionId={selectedSessionId}
|
||||
// isCombine={true}
|
||||
isEntity={!!entityFilter}
|
||||
isEntity={entityFilter ? true : false}
|
||||
isUser={entityFilter ? false : true}
|
||||
oakAutoUnmount={true}
|
||||
oakPath={
|
||||
oakFullpath
|
||||
|
|
|
|||
|
|
@ -17,6 +17,38 @@ export default OakComponent({
|
|||
id: 1,
|
||||
entity: 1,
|
||||
entityId: 1,
|
||||
userId: 1,
|
||||
user: {
|
||||
id: 1,
|
||||
name: 1,
|
||||
mobile$user: {
|
||||
$entity: 'mobile',
|
||||
data: {
|
||||
id: 1,
|
||||
mobile: 1,
|
||||
},
|
||||
},
|
||||
extraFile$entity: {
|
||||
$entity: 'extraFile',
|
||||
data: {
|
||||
id: 1,
|
||||
tag1: 1,
|
||||
origin: 1,
|
||||
bucket: 1,
|
||||
objectId: 1,
|
||||
filename: 1,
|
||||
extra1: 1,
|
||||
extension: 1,
|
||||
type: 1,
|
||||
entity: 1,
|
||||
},
|
||||
filter: {
|
||||
tag1: {
|
||||
$in: ['avatar'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
aaoe: 1,
|
||||
extraFile$entity: {
|
||||
|
|
@ -44,7 +76,7 @@ export default OakComponent({
|
|||
formData({ data: sessionMessage, features }) {
|
||||
const type = sessionMessage?.type;
|
||||
// const data = wechatMessage?.data;
|
||||
// const session = sessionMessage?.session;
|
||||
const session = sessionMessage?.session;
|
||||
const newSessionMessage = {
|
||||
type,
|
||||
aaoe: sessionMessage?.aaoe,
|
||||
|
|
@ -53,15 +85,15 @@ export default OakComponent({
|
|||
id: sessionMessage?.id,
|
||||
$$createAt$$: sessionMessage?.$$createAt$$,
|
||||
sessionId: sessionMessage?.sessionId,
|
||||
// employerId: conversation?.employerId,
|
||||
// employerMobile:
|
||||
// conversation?.employer?.mobile$user &&
|
||||
// conversation?.employer?.mobile$user[0]?.mobile,
|
||||
userId: session?.userId,
|
||||
userMobile:
|
||||
session?.user?.mobile$user &&
|
||||
session?.user?.mobile$user[0]?.mobile,
|
||||
// companyName: conversation?.company?.name,
|
||||
// employerAvatar: this.features.extraFile.getUrl(
|
||||
// conversation?.employer?.extraFile$entity &&
|
||||
// conversation?.employer?.extraFile$entity[0]
|
||||
// ),
|
||||
userAvatar: this.features.extraFile.getUrl(
|
||||
session?.user?.extraFile$entity &&
|
||||
session?.user?.extraFile$entity[0]
|
||||
),
|
||||
};
|
||||
|
||||
// if (type === 'image') {
|
||||
|
|
@ -78,26 +110,36 @@ export default OakComponent({
|
|||
properties: {
|
||||
key: '' as string,
|
||||
isEntity: false,
|
||||
isUser: false,
|
||||
},
|
||||
methods: {
|
||||
getAvatarUrl(type: string) {
|
||||
getAvatarUrl(aaoe: boolean) {
|
||||
const defaultUrl =
|
||||
'http://qiniu.gecomebox.com/static/defaultAvatar.png';
|
||||
const { companyLogoUrl, employerAvatar, parkLogoUrl } = this.state;
|
||||
switch (type) {
|
||||
case 'company': {
|
||||
return companyLogoUrl || defaultUrl;
|
||||
}
|
||||
case 'employer': {
|
||||
return employerAvatar || defaultUrl;
|
||||
}
|
||||
case 'platformProvider': {
|
||||
return process.env.PUBLIC_URL + '/logo192.png';
|
||||
}
|
||||
case 'park': {
|
||||
return parkLogoUrl || defaultUrl;
|
||||
const { companyLogoUrl, userAvatar, parkLogoUrl } = this.state;
|
||||
if (aaoe) {
|
||||
return defaultUrl
|
||||
}
|
||||
else {
|
||||
return userAvatar || defaultUrl;
|
||||
}
|
||||
// switch (type) {
|
||||
// case 'company': {
|
||||
// return companyLogoUrl || defaultUrl;
|
||||
// }
|
||||
// case 'user': {
|
||||
// return userAvatar || defaultUrl;
|
||||
// }
|
||||
// case 'platformProvider': {
|
||||
// return process.env.PUBLIC_URL + '/logo192.png';
|
||||
// }
|
||||
// case 'park': {
|
||||
// return parkLogoUrl || defaultUrl;
|
||||
// }
|
||||
// default: {
|
||||
// return defaultUrl
|
||||
// }
|
||||
// }
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
}
|
||||
|
||||
.avatar {
|
||||
margin: 10px;
|
||||
margin: 0 10px;
|
||||
height: 30px !important;
|
||||
width: 30px !important;
|
||||
padding: 0 !important;
|
||||
|
|
@ -93,7 +93,8 @@
|
|||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: flex-start;
|
||||
align-items: baseline;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.notMyMessage {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { Image } from 'antd';
|
||||
import { Image, Typography } from 'antd';
|
||||
import dayjs from 'dayjs';
|
||||
import classNames from 'classnames';
|
||||
import { WebComponentProps } from 'oak-frontend-base';
|
||||
|
|
@ -13,6 +13,7 @@ export default function render(
|
|||
false,
|
||||
{
|
||||
isEntity: boolean;
|
||||
isUser: boolean;
|
||||
$$createAt$$: number;
|
||||
text: string;
|
||||
type: string;
|
||||
|
|
@ -22,7 +23,7 @@ export default function render(
|
|||
id: string;
|
||||
},
|
||||
{
|
||||
getAvatarUrl: (type: string) => string;
|
||||
getAvatarUrl: (aaoe: boolean) => string;
|
||||
}
|
||||
>
|
||||
) {
|
||||
|
|
@ -33,6 +34,7 @@ export default function render(
|
|||
type,
|
||||
picUrl,
|
||||
isEntity,
|
||||
isUser,
|
||||
aaoe,
|
||||
sessionId,
|
||||
} = data;
|
||||
|
|
@ -41,18 +43,18 @@ export default function render(
|
|||
<ICell time={$$createAt$$}>
|
||||
<div
|
||||
className={classNames(Style.myMessage, {
|
||||
[Style.notMyMessage]: isEntity !== aaoe,
|
||||
[Style.notMyMessage]: (isEntity && !aaoe) || (isUser && aaoe),
|
||||
})}
|
||||
>
|
||||
<Image
|
||||
preview={false}
|
||||
className={Style.avatar}
|
||||
src={getAvatarUrl(type)}
|
||||
src={getAvatarUrl(aaoe)}
|
||||
/>
|
||||
<div
|
||||
className={classNames({
|
||||
[Style.messageType_text]: type === 'text',
|
||||
[Style.messageType_text_no]: isEntity !== aaoe,
|
||||
[Style.messageType_text_no]: (isEntity && !aaoe) || (isUser && aaoe),
|
||||
})}
|
||||
>
|
||||
|
||||
|
|
@ -91,7 +93,12 @@ type ITextProps = {
|
|||
|
||||
function IText(props: ITextProps) {
|
||||
const { value } = props;
|
||||
return <div>{value}</div>;
|
||||
return <div style={{ whiteSpace: 'pre-wrap' }}>{value}</div>;
|
||||
// return <div>
|
||||
// <Typography.Paragraph>
|
||||
// {value}
|
||||
// </Typography.Paragraph>
|
||||
// </div>;
|
||||
}
|
||||
|
||||
type IImageProps = {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ export default OakComponent({
|
|||
lifetimes: {
|
||||
async ready() {
|
||||
const { sessionId } = this.props;
|
||||
this.subData([
|
||||
await this.subData([
|
||||
{
|
||||
entity: 'sessionMessage',
|
||||
filter: {
|
||||
|
|
@ -52,7 +52,9 @@ export default OakComponent({
|
|||
},
|
||||
id: `${DATA_SUBSCRIBER_KEYS.sessionMessageList}-${sessionId}`,
|
||||
}
|
||||
])
|
||||
],
|
||||
async () => { await this.pageScroll('comment') }
|
||||
)
|
||||
// const userId = this.features.token.getUserId(true);
|
||||
// const applicationId = this.features.application.getApplicationId();
|
||||
// if (!sessionId) {
|
||||
|
|
@ -121,6 +123,7 @@ export default OakComponent({
|
|||
properties: {
|
||||
sessionId: '' as string,
|
||||
isEntity: false as boolean,
|
||||
isUser: false as boolean,
|
||||
dialog: false as boolean,
|
||||
entity: '',
|
||||
entityId: '',
|
||||
|
|
@ -281,7 +284,7 @@ export default OakComponent({
|
|||
fileType: type,
|
||||
size,
|
||||
extension,
|
||||
entity: 'wechatMessage',
|
||||
entity: 'sessionMessage',
|
||||
bucket: '',
|
||||
id: generateNewId(),
|
||||
} as EntityDict['extraFile']['CreateSingle']['data'];
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
display: flex;
|
||||
overflow: scroll;
|
||||
flex-direction: column;
|
||||
// margin-top: 50px;
|
||||
margin-top: 50px;
|
||||
overflow-x: hidden;
|
||||
height: 100%;
|
||||
}
|
||||
|
|
@ -37,6 +37,8 @@
|
|||
position: absolute;
|
||||
z-index: 100;
|
||||
|
||||
// resize: both;
|
||||
// cursor: nwse-resize;
|
||||
.toolbar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
|
@ -56,14 +58,17 @@
|
|||
|
||||
padding: 0 10px;
|
||||
|
||||
|
||||
.textarea {
|
||||
border: none;
|
||||
outline: none;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.textarea:focus {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.btn {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { Button, Image, Input, Upload, Modal } from 'antd';
|
||||
import { PictureOutlined, ShoppingCartOutlined } from '@ant-design/icons';
|
||||
import MessageCell from '../../../components/sessionMessage/cell';
|
||||
|
|
@ -25,6 +25,7 @@ export default function Render(
|
|||
buttonHidden: boolean;
|
||||
sessionId: string;
|
||||
isEntity: boolean;
|
||||
isUser: boolean;
|
||||
employerId: string;
|
||||
},
|
||||
{
|
||||
|
|
@ -40,6 +41,7 @@ export default function Render(
|
|||
const {
|
||||
sessionId,
|
||||
isEntity,
|
||||
isUser,
|
||||
sessionMessageList,
|
||||
oakFullpath,
|
||||
text,
|
||||
|
|
@ -54,6 +56,10 @@ export default function Render(
|
|||
createMessage,
|
||||
} = methods;
|
||||
const [bottomHeight, setBottomHeight] = useState(0);
|
||||
const textareaRef = useRef(null);
|
||||
// const [text1, setText1] = useState("");
|
||||
// const newBottomHeight =
|
||||
// window.document.getElementById('bottom')?.offsetHeight!;
|
||||
useEffect(() => {
|
||||
if (buttonHidden) {
|
||||
const newBottomHeight =
|
||||
|
|
@ -63,14 +69,50 @@ export default function Render(
|
|||
setBottomHeight(0);
|
||||
}
|
||||
}, [buttonHidden]);
|
||||
const handleKeyDown = (event: any) => {
|
||||
// if (event.key === "Enter" && event.shiftKey) {
|
||||
// event.preventDefault(); // 阻止默认的换行行为
|
||||
// 执行你的换行逻辑
|
||||
// setContent(text + "\n");
|
||||
// if (textareaRef && textareaRef.current && textareaRef.current!.resizableTextArea) {
|
||||
// const textArea = textareaRef.current.resizableTextArea.textAreaRef; // 获取 Input.TextArea 的原生 textarea 元素
|
||||
// console.log(textArea)
|
||||
// if (textArea) {
|
||||
// console.log(textArea)
|
||||
// const selectionStart = textArea?.selectionStart;
|
||||
// const value = textArea?.value;
|
||||
|
||||
// const newValue =
|
||||
// value?.substring(0, selectionStart) +
|
||||
// "\n" +
|
||||
// value?.substring(selectionStart);
|
||||
// textArea.value = newValue;
|
||||
// textArea.selectionStart = textArea.selectionEnd = selectionStart + 1;
|
||||
|
||||
// // 触发 onChange 事件,更新 Input.TextArea 的值
|
||||
// textArea.dispatchEvent(new Event("input"));
|
||||
// }
|
||||
|
||||
// }
|
||||
// }
|
||||
if (event.key === "Enter" && !event.shiftKey) {
|
||||
event.preventDefault();
|
||||
createMessage();
|
||||
pageScroll('comment');
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className={Style.container}>
|
||||
{/* <Header
|
||||
showBack={false}
|
||||
<Header
|
||||
// showBack={false}
|
||||
sessionId={sessionId}
|
||||
userId={employerId}
|
||||
/> */}
|
||||
isEntity={isEntity}
|
||||
// userId={employerId}
|
||||
oakPath={
|
||||
'session:header1'
|
||||
}
|
||||
oakAutoUnmount={true}
|
||||
/>
|
||||
<div
|
||||
className={Style.inner}
|
||||
style={{
|
||||
|
|
@ -96,6 +138,7 @@ export default function Render(
|
|||
: ''
|
||||
}
|
||||
isEntity={isEntity}
|
||||
isUser={isUser}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
|
@ -117,7 +160,11 @@ export default function Render(
|
|||
</div>
|
||||
<div className={Style.textareaBox}>
|
||||
<Input.TextArea
|
||||
ref={textareaRef}
|
||||
className={Style.textarea}
|
||||
// autoSize={{ minRows: 2, maxRows: 15 }}
|
||||
maxLength={500}
|
||||
placeholder="Enter 发送,Shift + Enter换行"
|
||||
rows={5}
|
||||
onChange={(e) => {
|
||||
setContent(e.target.value);
|
||||
|
|
@ -125,11 +172,12 @@ export default function Render(
|
|||
onFocus={() => {
|
||||
setButtonHidden(true);
|
||||
}}
|
||||
onPressEnter={(e) => {
|
||||
e.preventDefault();
|
||||
createMessage();
|
||||
pageScroll('comment');
|
||||
}}
|
||||
// onPressEnter={(e) => {
|
||||
// e.preventDefault();
|
||||
// createMessage();
|
||||
// pageScroll('comment');
|
||||
// }}
|
||||
onKeyDown={handleKeyDown}
|
||||
value={text}
|
||||
/>
|
||||
<div className={Style.btn}>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ export interface Schema extends EntityShape {
|
|||
entityId: String<64>;
|
||||
user?: User; //发送者
|
||||
lmts?: Datetime;//最后一条消息的发送时间
|
||||
openId?: String<64>;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -21,6 +22,7 @@ const entityDesc: EntityDesc<Schema, '', Relation, {
|
|||
entityId: '关联对象id',
|
||||
user: '发送者',
|
||||
lmts: '最后一条消息的发送时间',
|
||||
openId: 'openId'
|
||||
},
|
||||
r: {
|
||||
partner: '所有者',
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ export type OpSchema = EntityShape & {
|
|||
entityId: String<64>;
|
||||
userId?: ForeignKey<"user"> | null;
|
||||
lmts?: Datetime | null;
|
||||
openId?: String<64> | null;
|
||||
};
|
||||
export type OpAttr = keyof OpSchema;
|
||||
export type Schema = EntityShape & {
|
||||
|
|
@ -25,6 +26,7 @@ export type Schema = EntityShape & {
|
|||
entityId: String<64>;
|
||||
userId?: ForeignKey<"user"> | null;
|
||||
lmts?: Datetime | null;
|
||||
openId?: String<64> | null;
|
||||
user?: User.Schema | null;
|
||||
application?: Application.Schema;
|
||||
readRemark$session?: Array<ReadRemark.Schema>;
|
||||
|
|
@ -50,6 +52,7 @@ type AttrFilter = {
|
|||
userId: Q_StringValue;
|
||||
user: User.Filter;
|
||||
lmts: Q_DateValue;
|
||||
openId: Q_StringValue;
|
||||
application: Application.Filter;
|
||||
readRemark$session: ReadRemark.Filter & SubQueryPredicateMetadata;
|
||||
sessionMessage$session: SessionMessage.Filter & SubQueryPredicateMetadata;
|
||||
|
|
@ -70,6 +73,7 @@ export type Projection = {
|
|||
userId?: number;
|
||||
user?: User.Projection;
|
||||
lmts?: number;
|
||||
openId?: number;
|
||||
application?: Application.Projection;
|
||||
readRemark$session?: ReadRemark.Selection & {
|
||||
$entity: "readRemark";
|
||||
|
|
@ -129,6 +133,8 @@ export type SortAttr = {
|
|||
user: User.SortAttr;
|
||||
} | {
|
||||
lmts: number;
|
||||
} | {
|
||||
openId: number;
|
||||
} | {
|
||||
application: Application.SortAttr;
|
||||
} | {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,12 @@ export const desc: StorageDesc<OpSchema> = {
|
|||
},
|
||||
lmts: {
|
||||
type: "datetime"
|
||||
},
|
||||
openId: {
|
||||
type: "varchar",
|
||||
params: {
|
||||
length: 64
|
||||
}
|
||||
}
|
||||
},
|
||||
actionType: "crud",
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"name":"会话","attr":{"entity":"关联对象","entityId":"关联对象id","user":"发送者","lmts":"最后一条消息的发送时间"},"r":{"partner":"所有者"}}
|
||||
{"name":"会话","attr":{"entity":"关联对象","entityId":"关联对象id","user":"发送者","lmts":"最后一条消息的发送时间","openId":"openId"},"r":{"partner":"所有者"}}
|
||||
Loading…
Reference in New Issue