发微信客服消息

This commit is contained in:
wangwenchen 2023-10-11 16:57:02 +08:00
parent e8c8f1ebd6
commit 013dd3a586
11 changed files with 212 additions and 107 deletions

View File

@ -43,28 +43,13 @@ exports.default = OakComponent({
// },
// },
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;
// },
formData({ data, features }) {
const { sessionId } = this.props;
if (sessionId) {
this.getSession(sessionId);
}
return {};
},
// filters: [
// {
// filter() {
@ -80,9 +65,9 @@ exports.default = OakComponent({
lifetimes: {
ready() {
const { sessionId } = this.props;
if (sessionId) {
this.getSession(sessionId);
}
// if (sessionId) {
// this.getSession(sessionId)
// }
},
},
listeners: {

View File

@ -6,6 +6,7 @@ export default function render(props: WebComponentProps<EntityDict, 'session', f
name: string;
showBack: boolean;
sessionId: string;
session: EntityDict['session']['Schema'];
}, {
getName: () => string;
}>): import("react/jsx-runtime").JSX.Element;

View File

@ -11,15 +11,16 @@ 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 { nickname, avatarUrl, name, showBack, sessionId, session } = 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)();
console.log(session);
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() }) })] }));
}, 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: session && ((0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.name, children: getName() })) })] }));
}
exports.default = render;

View File

@ -108,7 +108,7 @@ exports.default = OakComponent({
// return;
// }
const { sessionId } = this.props;
// 父层传入conversationId 默认聊天
// 父层传入sessionId 默认聊天
if (sessionId) {
this.setSelectedSessionId(sessionId);
}
@ -122,7 +122,7 @@ exports.default = OakComponent({
filter: entityFilter ? { ...entityFilter } : { userId },
id: `${constants_1.DATA_SUBSCRIBER_KEYS.sessionList}`,
}
], () => { console.log(123); });
]);
},
detached() {
this.unSubData([
@ -244,7 +244,7 @@ exports.default = OakComponent({
// mobile独有
navigateToMessage(sessionId) {
this.navigateTo({
url: '/sessionMessage/list',
url: '/session/sessionMessage',
sessionId,
}, undefined, true);
},

View File

@ -0,0 +1,10 @@
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'][];
selectedSessionId: string;
entityFilter: object;
}, {
setSelectedSessionId: (sessionId: string) => void;
navigateToMessage: (sessionId: string) => void;
}>): import("react/jsx-runtime").JSX.Element;

View File

@ -1,69 +1,20 @@
"use strict";
// import React from 'react';
// import Style from './mobile.module.less';
// import ConversationHeader from '@project/components/conversation/header';
// import ConversationCell from '@project/components/conversation/cell';
// import ConversationMessageNumber from '@project/components/conversation/messageNumber';
// import { WebComponentProps } from 'oak-frontend-base';
// import { EntityDict } from '@oak-app-domain';
// export default function Render(
// props: WebComponentProps<
// EntityDict,
// 'conversation',
// false,
// {
// conversations: EntityDict['conversation']['Schema'][];
// selectedConversationId: string;
// unReadConversation: number;
// userType: string;
// },
// {
// clearUnRead: () => void;
// setSelectedConversationId: (conversationId: string) => void;
// navigateToConversationMessage: (conversationId: string) => void;
// }
// >
// ) {
// const { data, methods } = props;
// const {
// conversations,
// selectedConversationId,
// oakFullpath,
// unReadConversation,
// userType,
// } = data;
// const {
// clearUnRead,
// setSelectedConversationId,
// navigateToConversationMessage,
// } = methods;
// return (
// <div className={Style.container}>
// <div className={Style.conversationContainer}>
// <ConversationHeader />
// <ConversationMessageNumber
// number={unReadConversation}
// clear={clearUnRead}
// />
// {conversations?.map((conversation: any, index: number) => {
// return (
// <ConversationCell
// userType={userType}
// selectedId={selectedConversationId}
// onSelect={(id: string) => {
// navigateToConversationMessage(conversation.id);
// }}
// oakId={conversation.id}
// key={conversation.id}
// oakPath={
// oakFullpath
// ? `${oakFullpath}.${conversation.id}`
// : ''
// }
// />
// );
// })}
// </div>
// </div>
// );
// }
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const mobile_module_less_1 = tslib_1.__importDefault(require("./mobile.module.less"));
const header_1 = tslib_1.__importDefault(require("../../../components/session/header"));
const cell_1 = tslib_1.__importDefault(require("../../../components/session/cell"));
function Render(props) {
const { data, methods } = props;
const { sessions, selectedSessionId, oakFullpath, entityFilter, } = data;
const { setSelectedSessionId, navigateToMessage, } = methods;
return ((0, jsx_runtime_1.jsx)("div", { className: mobile_module_less_1.default.container, children: (0, jsx_runtime_1.jsxs)("div", { className: mobile_module_less_1.default.conversationContainer, children: [(0, jsx_runtime_1.jsx)(header_1.default, {}), sessions?.map((session, index) => {
return ((0, jsx_runtime_1.jsx)(cell_1.default, { entityFilter: entityFilter, selectedId: selectedSessionId, name: session?.name, onSelect: (id) => {
navigateToMessage(id);
}, oakId: session.id, oakPath: oakFullpath
? `${oakFullpath}.${session.id}`
: '' }, session.id));
})] }) }));
}
exports.default = Render;

View File

@ -9,5 +9,5 @@ export default function Render(props: WebComponentProps<EntityDict, 'session', f
entityDisplay: (data: any) => any[];
entityProjection: object;
}, {
setSelectedSessionId: (conversationId: string) => void;
setSelectedSessionId: (sessionId: string) => void;
}>): import("react/jsx-runtime").JSX.Element;

View File

@ -98,7 +98,11 @@ exports.default = OakComponent({
},
formData({ data: sessionMessageList = [], features }) {
const sessionMessageType = sessionMessageList?.find((ele) => ele.$$createAt$$ === 1)?.type;
// const url = sessionMessageList?.find(
// (ele) => ele.$$createAt$$ === 1
// )?.extraFile$entity?.filter((ele) => ['image'].includes(ele.tag1!))?.map((ele) => features.extraFile.getUrl(ele));
this.getUserLastMessage();
// console.log(url);
return {
sessionMessageList,
num: sessionMessageList?.length,
@ -172,7 +176,6 @@ exports.default = OakComponent({
count: 1,
});
const isWeChat = !!lastMessage?.wechatUserId;
console.log(lastMessage);
this.setState({ isWeChat });
},
setContent(text) {

View File

@ -14,7 +14,6 @@ function Render(props) {
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)(() => {
@ -55,6 +54,7 @@ function Render(props) {
pageScroll('comment');
}
};
console.log(isWeChat);
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}
, {
@ -70,9 +70,11 @@ function Render(props) {
return ((0, jsx_runtime_1.jsx)(cell_1.default, { oakId: sessionMessage.id, oakPath: oakFullpath
? `${oakFullpath}.${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 }) => {
}) }), (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: isWeChat ? (
//微信资源库
(0, jsx_runtime_1.jsx)(icons_1.PictureOutlined, { className: web_module_less_1.default.icon })) : ((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, { ref: textareaRef, className: web_module_less_1.default.textarea,
}, 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);

View File

@ -1,6 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const uuid_1 = require("oak-domain/lib/utils/uuid");
const assert_1 = require("oak-domain/lib/utils/assert");
const oak_external_sdk_1 = require("oak-external-sdk");
const triggers = [
{
name: '当sessionMessage创建时时使其相关session更新lmts',
@ -9,8 +11,9 @@ const triggers = [
when: 'after',
fn: async (event, context) => {
const { operation: { data }, } = event;
const { sessionId } = data;
const { sessionId, type, text, } = data;
const closeRootMode = context.openRootMode();
const messageType = type;
try {
await context.operate('session', {
id: await (0, uuid_1.generateNewIdAsync)(),
@ -22,6 +25,94 @@ const triggers = [
id: sessionId,
},
}, {});
const [sessionMessage] = await context.select('sessionMessage', {
data: {
id: 1,
sessionId: 1,
text: 1,
type: 1,
userId: 1,
wechatUserId: 1,
wechatUser: {
id: 1,
openId: 1,
},
applicationId: 1,
createTime: 1,
$$createAt$$: 1,
aaoe: 1,
},
filter: {
id: sessionId,
aaoe: false,
createTime: {
$gt: Date.now() - (48 * 60 * 60 * 1000 - 5 * 60 * 1000)
}
},
sorter: [
{
$attr: {
$$createAt$$: 1,
},
$direction: 'desc',
},
],
count: 1,
}, {});
if (sessionMessage && sessionMessage.wechatUserId) {
const [session] = await context.select('session', {
data: {
id: 1,
entity: 1,
entityId: 1,
userId: 1,
openId: 1,
},
filter: {
id: sessionId,
},
}, {});
const [application] = await context.select('application', {
data: {
id: 1,
type: 1,
config: 1,
systemId: 1,
},
filter: {
id: session.entityId,
},
}, {});
const { type, config, systemId } = application;
(0, assert_1.assert)(type === 'wechatPublic');
const { appId, appSecret } = config;
const wechatInstance = oak_external_sdk_1.WechatSDK.getInstance(appId, 'wechatPublic', appSecret);
function sendMessage() {
switch (messageType) {
case 'text': {
wechatInstance.sendServeMessage({
openId: sessionMessage.wechatUser?.openId,
type: messageType,
content: text,
});
break;
}
default: {
(0, assert_1.assert)(false, '你所发送的消息类型不支持');
}
//todo
// case 'image' :{
// wechatInstance.sendServeMessage({
// openId: sessionMessage.wechatUser?.openId!,
// type: messageType,
// mediaId: '',
// });
// break;
// }
}
}
sendMessage();
}
}
catch (err) {
closeRootMode();

View File

@ -4,6 +4,13 @@ import { RuntimeCxt } from '../types/RuntimeCxt';
import { EntityDict } from '../oak-app-domain/EntityDict';
import { BackendRuntimeContext } from '../context/BackendRuntimeContext';
import { CreateOperationData as CreateSessionMessageData } from '../oak-app-domain/SessionMessage/Schema';
import { assert } from 'oak-domain/lib/utils/assert';
import { WechatMpConfig, WechatPublicConfig } from '../entities/Application';
import {
WechatSDK,
WechatMpInstance,
WechatPublicInstance,
} from 'oak-external-sdk';
const triggers: Trigger<EntityDict, 'sessionMessage', BackendRuntimeContext<EntityDict>>[] = [
{
name: '当sessionMessage创建时时使其相关session更新lmts',
@ -14,8 +21,9 @@ const triggers: Trigger<EntityDict, 'sessionMessage', BackendRuntimeContext<Enti
const {
operation: { data },
} = event;
const { sessionId } = data as CreateSessionMessageData;
const { sessionId, type, text, } = data as CreateSessionMessageData;
const closeRootMode = context.openRootMode();
const messageType = type;
try {
await context.operate(
@ -42,6 +50,10 @@ const triggers: Trigger<EntityDict, 'sessionMessage', BackendRuntimeContext<Enti
type: 1,
userId: 1,
wechatUserId: 1,
wechatUser: {
id: 1,
openId: 1,
},
applicationId: 1,
createTime: 1,
$$createAt$$: 1,
@ -83,10 +95,59 @@ const triggers: Trigger<EntityDict, 'sessionMessage', BackendRuntimeContext<Enti
},
{}
);
const [application] = await context.select(
'application',
{
data: {
id: 1,
type: 1,
config: 1,
systemId: 1,
},
filter: {
id: session.entityId,
},
},
{}
);
const { type, config, systemId } = application!;
assert(type === 'wechatPublic');
const { appId, appSecret } = config as WechatPublicConfig;
const wechatInstance = WechatSDK.getInstance(
appId,
'wechatPublic',
appSecret
) as WechatPublicInstance;
function sendMessage() {
switch (messageType) {
case 'text': {
wechatInstance.sendServeMessage({
openId: sessionMessage.wechatUser?.openId!,
type: messageType,
content: text!,
});
break;
}
default: {
assert(false, '你所发送的消息类型不支持')
}
//todo
// case 'image' :{
// wechatInstance.sendServeMessage({
// openId: sessionMessage.wechatUser?.openId!,
// type: messageType,
// mediaId: '',
// });
// break;
// }
}
}
sendMessage();
}
} catch (err) {
closeRootMode();
throw err;