This commit is contained in:
Wang Kejun 2023-10-12 18:45:18 +08:00
parent 9a4c27233a
commit 95d1d789ba
69 changed files with 687 additions and 654 deletions

View File

@ -18,6 +18,7 @@ export declare function signatureJsSDK<ED extends EntityDict, Cxt extends Backen
appId: string;
}>;
export declare function uploadWechatMedia<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
appType: AppType;
applicationId: string;
file: File;
type: MediaType;

View File

@ -60,10 +60,11 @@ export async function signatureJsSDK({ url, env }, context) {
}
export async function uploadWechatMedia(params, // FormData表单提交 isPermanent 变成 'true' | 'false'
context) {
const { applicationId, file, type: mediaType, isPermanent, description, } = params;
const { applicationId, file, type: mediaType, isPermanent, description, appType, } = params;
const filename = file.originalFilename;
const filetype = file.mimetype;
const file2 = fs.createReadStream(file.filepath);
assert(appType === 'wechatPublic' || appType === 'wechatMp');
const [application] = await context.select('application', {
data: cloneDeep(applicationProjection),
filter: {
@ -73,11 +74,22 @@ context) {
dontCollect: true,
});
const { type, config } = application;
assert(type === 'wechatPublic' && config.type === 'wechatPublic');
const config2 = config;
const { appId, appSecret } = config2;
const wechatInstance = WechatSDK.getInstance(appId, 'wechatPublic', appSecret);
let wechatInstance;
if (appType === 'wechatPublic') {
assert(type === 'wechatPublic' && config.type === 'wechatPublic');
const config2 = config;
const { appId, appSecret } = config2;
wechatInstance = WechatSDK.getInstance(appId, 'wechatPublic', appSecret);
}
else {
assert(type === 'wechatMp' && config.type === 'wechatMp');
const config2 = config;
const { appId, appSecret } = config2;
wechatInstance = WechatSDK.getInstance(appId, 'wechatPublic', appSecret);
}
if (isPermanent === 'true') {
// 只有公众号才能上传永久素材
assert(appType === 'wechatPublic');
const result = (await wechatInstance.createMaterial({
type: mediaType,
media: file2,

View File

@ -1,49 +1,5 @@
import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
import assert from "assert";
// export async function transformData<
// ED extends EntityDict,
// Cxt extends BackendRuntimeContext<ED>
// >(
// params: {
// data: WechatPublicEventData | WechatMpEventData;
// type: AppType,
// entity: string,
// entityId: string,
// },
// context: Cxt
// ) {
// const { data, type, entity, entityId } = params;
// const {
// ToUserName,
// FromUserName,
// CreateTime,
// MsgType,
// // Event,
// Content,
// // EventKey,
// } = data;
// if (entity !== 'web') {
// const sessionMessageData = {
// createTime: CreateTime,
// type: MsgType,
// text: Content,
// // news: ,
// aaoe: false,
// isRead: false,
// }
// return sessionMessageData
// } else {
// const sessionMessageData = {
// createTime: CreateTime,
// type: MsgType,
// text: Content,
// // news: ,
// aaoe: false,
// isRead: false,
// }
// return sessionMessageData
// }
// }
import { assert } from 'oak-domain/lib/utils/assert';
export async function createSession(params, context) {
const { data, type, entity, entityId } = params;
const userId = context.getCurrentUserId(true);
@ -52,17 +8,25 @@ export async function createSession(params, context) {
switch (type) {
case 'web': {
const systemId = context.getSystemId();
const [application] = await context.select('application', {
data: {
id: 1,
systemId: 1,
type: 1,
},
filter: {
systemId,
type: 'web'
}
}, {});
let entity2 = entity;
let entityId2 = entityId;
if (!entity) {
// 默认
const [application] = await context.select('application', {
data: {
id: 1,
systemId: 1,
type: 1,
},
filter: {
systemId,
type: 'web',
},
}, {});
entity2 = 'application';
entityId2 = application?.id;
}
assert(entity2 && entityId2);
const result = await context.select('session', {
data: {
id: 1,
@ -72,10 +36,10 @@ export async function createSession(params, context) {
lmts: 1,
},
filter: {
entity: entity || 'application',
entityId: entityId || application?.id,
entity: entity2,
entityId: entityId2,
userId,
}
},
}, {});
session = result[0];
break;
@ -83,7 +47,7 @@ export async function createSession(params, context) {
case 'wechatMp':
case 'wechatPublic': {
assert(data);
assert(entity === 'application');
assert(entity === 'application' && entityId);
const { ToUserName, FromUserName, CreateTime, MsgType,
// Event,
Content,
@ -123,38 +87,39 @@ export async function createSession(params, context) {
id: await generateNewIdAsync(),
applicationId: wechatUser?.applicationId,
wechatUserId: wechatUser?.id,
createTime: CreateTime,
createTime: Number(CreateTime) * 1000,
type: MsgType,
text: Content,
// news: ,
aaoe: false,
},
}
},
];
break;
}
default: {
assert(false, '');
assert(false, `传入不支持的type: ${type}`);
}
}
const sessionId = await generateNewIdAsync();
if (session) {
if (!data) {
if (!sessionMessage$session) {
return session.id;
}
await context.operate('session', {
id: await generateNewIdAsync(),
action: 'update',
data: Object.assign({}, sessionMessage$session && { sessionMessage$session }),
data: {
sessionMessage$session,
},
filter: {
id: session.id,
}
},
}, {
dontCollect: true,
});
return session.id;
}
else {
const sessionId = await generateNewIdAsync();
await context.operate('session', {
id: await generateNewIdAsync(),
action: 'create',

View File

@ -1009,15 +1009,12 @@ export async function syncUserInfoWechatMp({ nickname, avatarUrl, encryptedData,
}, {
dontCollect: true,
});
// console.log(avatarUrl);
const { type, config: config2 } = application;
assert(type === 'wechatMp' || config2.type === 'wechatMp');
// const config2 = config as WechatMpConfig;
const { appId, appSecret } = config2;
const wechatInstance = WechatSDK.getInstance(appId, 'wechatMp', appSecret);
const result = wechatInstance.decryptData(sessionKey, encryptedData, iv, signature);
// 实测发现解密出来的和userInfo完全一致……
console.log(result);
await setUserInfoFromWechat(user, { nickname, avatar: avatarUrl }, context);
}
export async function sendCaptcha({ mobile, env, type: type2 }, context) {

View File

@ -167,7 +167,6 @@ export async function createWechatQrCode(options, context) {
const application = applications.find((ele) => ele.id === data.applicationId);
assert(application);
const { type: applicationType, config } = application;
// console.log(process.env.OAK_PLATFORM, process.env.NODE_ENV);
switch (type) {
case 'wechatMpWxaCode': {
assert(applicationType === 'wechatMp' && config.type === 'wechatMp');

View File

@ -8,7 +8,6 @@ export default function Render(props) {
const [syncDisable, setSyncDisable] = useState(false);
const [open, setOpen] = useState(false);
const { pageSize, total, currentPage } = oakPagination || {};
console.log(messageTypes, wechatPublicTemplates);
return (_jsxs("div", { className: Styles.container, children: [_jsxs(Space, { children: [_jsx(Button, { type: "default", disabled: !(messageTypes.length > 0 && wechatPublicTemplates.length > 0), onClick: () => {
addItem({
templateId: wechatPublicTemplates[0].id,

View File

@ -13,7 +13,6 @@ export default function render(props) {
const defaultUrl = 'http://qiniu.gecomebox.com/static/defaultAvatar.png';
const features = useFeatures();
const width = useWidth();
console.log(session);
return (_jsxs("div", { className: classNames(Style.header, {
[Style.header_mobile]: width === 'xs'
}), children: [showBack && (_jsx(Button, { type: "text", onClick: () => {

View File

@ -16,9 +16,7 @@ export default function Render(props) {
}, oakId: session.id, oakPath: oakFullpath
? `${oakFullpath}.${session.id}`
: '' }, session.id));
}) })] }), selectedSessionId && (_jsx(MessageList, { sessionId: selectedSessionId,
// isCombine={true}
isEntity: entityFilter ? true : false, isUser: entityFilter ? false : true, oakAutoUnmount: true, entityDisplay: entityDisplay, entityProjection: entityProjection, oakPath: oakFullpath
}) })] }), selectedSessionId && (_jsx(MessageList, { sessionId: selectedSessionId, isEntity: entityFilter ? true : false, oakAutoUnmount: true, entityDisplay: entityDisplay, entityProjection: entityProjection, oakPath: oakFullpath
? `$$sessionMessage/list`
: undefined }))] }) }));
}

View File

@ -0,0 +1,7 @@
/// <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;
entity: string;
entityId: string;
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
export default _default;

View File

@ -0,0 +1,28 @@
import { assert } from 'oak-domain/lib/utils/assert';
export default OakComponent({
isList: false,
lifetimes: {
async ready() {
const { sessionId, entity, entityId } = this.props;
if (!sessionId) {
assert(entity && entityId);
const { result: newSessionId } = await this.features.cache.exec('createSession', { type: 'web', entity, entityId });
this.setState({
newSessionId,
});
}
else {
this.setState({
newSessionId: sessionId,
});
}
},
detached() {
},
},
properties: {
sessionId: '',
entity: '',
entityId: ''
}
});

View File

@ -0,0 +1,4 @@
{
"navigationBarTitleText": "会话",
"usingComponents": {}
}

View File

@ -0,0 +1,5 @@
import { WebComponentProps } from 'oak-frontend-base';
import { EntityDict } from '../../../oak-app-domain';
export default function Render(props: WebComponentProps<EntityDict, 'session', false, {
newSessionId: string;
}, {}>): import("react/jsx-runtime").JSX.Element | null;

View File

@ -0,0 +1,7 @@
import { jsx as _jsx } from "react/jsx-runtime";
import SessionMessageList from '../../sessionMessage/list';
export default function Render(props) {
const { data } = props;
const { oakFullpath, newSessionId } = data;
return newSessionId ? (_jsx(SessionMessageList, { oakAutoUnmount: true, oakPath: oakFullpath ? `$$sessionMessage/list` : undefined, sessionId: newSessionId, isEntity: false })) : null;
}

View File

@ -1,7 +1,5 @@
/// <reference types="react" />
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;

View File

@ -8,7 +8,6 @@ export default OakComponent({
createTime: 1,
userId: 1,
wechatUserId: 1,
// isRead: 1,
$$createAt$$: 1,
sessionId: 1,
session: {
@ -86,7 +85,6 @@ export default OakComponent({
userId: session?.userId,
userMobile: session?.user?.mobile$user &&
session?.user?.mobile$user[0]?.mobile,
// companyName: conversation?.company?.name,
userAvatar: this.features.extraFile.getUrl(session?.user?.extraFile$entity &&
session?.user?.extraFile$entity[0]),
};
@ -99,9 +97,7 @@ export default OakComponent({
return newSessionMessage;
},
properties: {
key: '',
isEntity: false,
isUser: false,
},
methods: {
getAvatarUrl(aaoe) {
@ -113,23 +109,6 @@ export default OakComponent({
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
// }
// }
},
},
});

View File

@ -5,13 +5,15 @@ 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, isUser, aaoe, sessionId, } = data;
const { $$createAt$$, text, type, picUrl, isEntity, aaoe, sessionId, } = data;
const { t, getAvatarUrl } = methods;
return (_jsx(ICell, { time: $$createAt$$, children: _jsxs("div", { className: classNames(Style.myMessage, {
[Style.notMyMessage]: (isEntity && !aaoe) || (isUser && aaoe),
[Style.notMyMessage]: !((isEntity && aaoe) ||
(!isEntity && !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) || (isUser && aaoe),
[Style.messageType_text_no]: !((isEntity && aaoe) ||
(!isEntity && !aaoe)),
}), children: [type === 'text' && _jsx(IText, { value: text }), type === 'image' && _jsx(IImage, { url: picUrl })] })] }) }));
}
function ICell(props) {

View File

@ -3,7 +3,6 @@ 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;

View File

@ -96,11 +96,7 @@ export 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: sessionMessageList?.filter((ele) => ele.$$createAt$$ !== 1),
num: sessionMessageList?.length,
@ -110,7 +106,6 @@ export default OakComponent({
properties: {
sessionId: '',
isEntity: false,
isUser: false,
dialog: false,
entity: '',
entityId: '',
@ -178,7 +173,6 @@ export default OakComponent({
},
setContent(text) {
const { sessionMessageId } = this.state;
console.log(sessionMessageId);
this.setState({
text,
});
@ -329,10 +323,6 @@ export default OakComponent({
id: generateNewId(),
};
try {
// await this.features.extraFile.upload(
// extraFile,
// originFileObj
// );
const userId = this.features.token.getUserId();
this.addItem({
id: generateNewId(),

View File

@ -7,12 +7,10 @@ import Header from '../../../components/session/forMessage';
import Style from './web.module.less';
export default function Render(props) {
const { data, methods } = props;
const { sessionId, isEntity, isUser, sessionMessageList, oakFullpath, text, buttonHidden, sessionMessageType, sessionMessageId, entityDisplay, entityProjection, isWeChat, } = data;
const { sessionId, isEntity, sessionMessageList, oakFullpath, text, buttonHidden, sessionMessageType, sessionMessageId, entityDisplay, entityProjection, isWeChat, } = data;
const { setButtonHidden, customUpload, setContent, pageScroll, createMessage, } = methods;
const [bottomHeight, setBottomHeight] = useState(0);
const textareaRef = useRef(null);
// const newBottomHeight =
// window.document.getElementById('bottom')?.offsetHeight!;
useEffect(() => {
if (buttonHidden) {
const newBottomHeight = window.document.getElementById('bottom')?.offsetHeight;
@ -23,42 +21,13 @@ export default function Render(props) {
}
}, [buttonHidden]);
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');
}
};
console.log(isWeChat);
return (_jsxs("div", { className: Style.container, children: [_jsx(Header
// showBack={false}
, {
// showBack={false}
sessionId: sessionId, isEntity: isEntity,
// userId={employerId}
oakPath: 'session:header1', oakAutoUnmount: true, entityDisplay: entityDisplay, entityProjection: entityProjection }), _jsx("div", { className: Style.inner, style: {
return (_jsxs("div", { className: Style.container, children: [_jsx(Header, { sessionId: sessionId, isEntity: isEntity, oakPath: 'session:header1', oakAutoUnmount: true, entityDisplay: entityDisplay, entityProjection: entityProjection }), _jsx("div", { className: Style.inner, style: {
marginBottom: bottomHeight ? `${bottomHeight}px` : '168px',
}, id: "comment", onClick: () => setButtonHidden(true), children: sessionMessageList
?.sort((a, b) => a.$$createAt$$ -
@ -66,14 +35,12 @@ export default function Render(props) {
.map((sessionMessage, index) => {
return (_jsx(MessageCell, { oakId: sessionMessage.id, oakPath: oakFullpath
? `${oakFullpath}.${sessionMessage.id}`
: '', isEntity: isEntity, isUser: isUser }, sessionMessage.id));
: '', isEntity: isEntity }, sessionMessage.id));
}) }), _jsxs("div", { className: Style.bottom, id: "bottom", children: [_jsx("div", { className: Style.toolbar, children: isWeChat ? (
//微信资源库
_jsx(PictureOutlined, { className: Style.icon })) : (_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, { ref: textareaRef, className: Style.textarea,
// autoSize={{ minRows: 2, maxRows: 15 }}
maxLength: 500, placeholder: "Enter \u53D1\u9001\uFF0CShift + Enter\u6362\u884C", rows: 5, onChange: (e) => {
}, children: _jsx(PictureOutlined, { className: Style.icon }) })) }), _jsxs("div", { className: Style.textareaBox, children: [_jsx(Input.TextArea, { ref: textareaRef, className: Style.textarea, maxLength: 500, placeholder: "Enter \u53D1\u9001\uFF0CShift + Enter\u6362\u884C", rows: 5, onChange: (e) => {
setContent(e.target.value);
}, onFocus: () => {
setButtonHidden(true);
@ -83,7 +50,7 @@ export default function Render(props) {
// createMessage();
// pageScroll('comment');
// }}
onKeyDown: handleKeyDown, value: text }), _jsx("div", { className: Style.btn, children: _jsx(Button, { type: "primary", disabled: text ? false : true, onClick: () => {
onKeyDown: handleKeyDown, value: text }), _jsx("div", { className: Style.btn, children: _jsx(Button, { type: "primary", disabled: !text, onClick: () => {
createMessage();
pageScroll('comment');
}, children: "\u53D1\u9001" }) })] })] })] }));

View File

@ -33,7 +33,6 @@ export default OakComponent({
}
],
formData({ data: rows }) {
console.log(rows);
const userWechatPublicTags = rows?.map((ele) => {
return {
id: ele?.id,

View File

@ -10,46 +10,60 @@ export default OakComponent({
const { type, applicationId } = this.props;
let result;
if (type === 'news') {
result = await this.features.wechatMenu.batchGetArticle({ applicationId: applicationId, offset: 0, count: 10, noContent: 0 });
const news = JSON.parse(result);
if (news && news.item.length > 0) {
const modifiedResult = await Promise.all(news.item.map(async (ele) => {
result = await this.features.wechatMenu.batchGetArticle({
applicationId: applicationId,
offset: 0,
count: 10,
noContent: 0,
});
if (result && result.item.length > 0) {
const modifiedResult = await Promise.all(result.item.map(async (ele) => {
const news_item = await Promise.all(ele.content.news_item.map(async (ele2) => {
const coverUrl = await this.getMaterialImg(ele2.thumb_media_id);
return {
...ele2,
coverUrl
coverUrl,
};
}));
return {
...ele,
content: {
...ele.content,
news_item
}
news_item,
},
};
}));
this.setState({
materials: modifiedResult,
total: news.total_count,
total: result.total_count,
});
}
}
else {
result = await this.features.wechatMenu.batchGetMaterialList({ applicationId: applicationId, type: type, offset: 0, count: 10 });
result = await this.features.wechatMenu.batchGetMaterialList({
applicationId: applicationId,
type: type,
offset: 0,
count: 10,
});
this.setState({
materials: result.item,
total: result.total_count,
});
}
}
},
},
methods: {
async getMaterialList(page) {
const { applicationId } = this.props;
const { type } = this.props;
const offset = (page - 1) * 10;
const result = await this.features.wechatMenu.batchGetMaterialList({ applicationId: applicationId, type: type, offset, count: 10 });
const result = await this.features.wechatMenu.batchGetMaterialList({
applicationId: applicationId,
type: type,
offset,
count: 10,
});
this.setState({
materials: result.item,
total: result.total_count,
@ -58,21 +72,26 @@ export default OakComponent({
async getArticleList(page) {
const { applicationId } = this.props;
const offset = (page - 1) * 10;
const result = await this.features.wechatMenu.batchGetArticle({ applicationId: applicationId, offset, count: 10, noContent: 0 });
const result = await this.features.wechatMenu.batchGetArticle({
applicationId: applicationId,
offset,
count: 10,
noContent: 0,
});
const modifiedResult = await Promise.all(result.item.map(async (ele) => {
const news_item = await Promise.all(ele.content.news_item.map(async (ele2) => {
const coverUrl = await this.getMaterialImg(ele2.thumb_media_id);
return {
...ele2,
coverUrl
coverUrl,
};
}));
return {
...ele,
content: {
...ele.content,
news_item
}
news_item,
},
};
}));
this.setState({
@ -83,7 +102,14 @@ export default OakComponent({
async upload(media, description) {
const { applicationId } = this.props;
const { type } = this.props;
const result = await this.features.wechatMenu.createMaterial({ appType: 'wechatPublic', applicationId: applicationId, type: type, file: media, description, isPermanent: true });
const result = await this.features.wechatMenu.createMaterial({
appType: 'wechatPublic',
applicationId: applicationId,
type: type,
file: media,
description,
isPermanent: true,
});
if (result && result.mediaId) {
this.setMessage({
type: 'success',
@ -113,6 +139,6 @@ export default OakComponent({
},
getImg(url) {
return this.features.locales.makeBridgeUrl(url);
}
}
},
},
});

View File

@ -245,6 +245,9 @@ export default OakComponent({
async deleteConditionalMenu() {
const { deleteMenu } = this.props;
deleteMenu();
}
},
getImg(url) {
return this.features.locales.makeBridgeUrl(url);
},
},
});

View File

@ -38,4 +38,5 @@ export default function Render(props: WebComponentProps<EntityDict, keyof Entity
createMenu: (errorInfo: string, errorUrlInfo: string) => void;
deleteConditionalMenu: () => void;
confirmUrl: (url: string) => string;
getImg: (url: string) => string;
}>): import("react/jsx-runtime").JSX.Element;

View File

@ -14,7 +14,7 @@ import TextClick from '../textClick';
export default function Render(props) {
const { data, methods } = props;
const { config, menuIndex, selectedBtn, selectedSubBtn, currentIndex, changeIsPreview, getOpen, menuType, applicationId, menuId, actions, wechatId, iState, } = data;
const { setConfig, confirmName, confirmSubName, editMenuName, deleteMenuContent, getMaterialImgAndVoice, getMaterialVideo, decideMenuContentLabel, getArticle, createMenu, deleteConditionalMenu, confirmUrl, } = methods;
const { setConfig, confirmName, confirmSubName, editMenuName, deleteMenuContent, getMaterialImgAndVoice, getMaterialVideo, decideMenuContentLabel, getArticle, createMenu, deleteConditionalMenu, confirmUrl, getImg, } = methods;
const [msgType, setMsgType] = useState('sendMsg');
const [errorInfo, setErrorInfo] = useState('');
const [errorUrlInfo, setErrorUrlInfo] = useState('');
@ -58,7 +58,9 @@ export default function Render(props) {
if (selectedBtn > 0) {
setConfig(selectedBtn - 1, {
type: 'click',
key: menuType === 'conditional' ? `${wechatId}$${await generateNewIdAsync()}` : await generateNewIdAsync(),
key: menuType === 'conditional'
? `${wechatId}$${await generateNewIdAsync()}`
: await generateNewIdAsync(),
subType: 'text',
content: menuContent,
});
@ -66,7 +68,9 @@ export default function Render(props) {
else {
setConfig(selectedSubBtn - 1, {
type: 'click',
key: menuType === 'conditional' ? `${wechatId}$${await generateNewIdAsync()}` : await generateNewIdAsync(),
key: menuType === 'conditional'
? `${wechatId}$${await generateNewIdAsync()}`
: await generateNewIdAsync(),
subType: 'text',
content: menuContent,
}, currentIndex);
@ -257,7 +261,7 @@ export default function Render(props) {
setOpen(true);
getOpen(true);
setType('video');
}, children: "\u89C6\u9891" })] })) : type === 'image' ? (_jsxs("div", { className: Style.coverImage, children: [_jsx("img", { className: Style.img, src: decidedMenuContent.url }), _jsxs("div", { className: Style.buttonGroup, children: [_jsx("div", { className: Style.buttonItem, onClick: () => {
}, children: "\u89C6\u9891" })] })) : type === 'image' ? (_jsxs("div", { className: Style.coverImage, children: [_jsx("img", { className: Style.img, src: getImg(decidedMenuContent.url) }), _jsxs("div", { className: Style.buttonGroup, children: [_jsx("div", { className: Style.buttonItem, onClick: () => {
const modal = confirm({
title: '确定删除该图片吗?',
content: '删除后不可恢复',

View File

@ -9,7 +9,6 @@ export class Template extends Feature {
const result = await this.cache.exec('syncMessageTemplate', {
applicationId
});
console.log(result);
this.publish();
}
}

View File

@ -18,6 +18,7 @@ export declare function signatureJsSDK<ED extends EntityDict, Cxt extends Backen
appId: string;
}>;
export declare function uploadWechatMedia<ED extends EntityDict, Cxt extends BackendRuntimeContext<ED>>(params: {
appType: AppType;
applicationId: string;
file: File;
type: MediaType;

View File

@ -66,10 +66,11 @@ async function signatureJsSDK({ url, env }, context) {
exports.signatureJsSDK = signatureJsSDK;
async function uploadWechatMedia(params, // FormData表单提交 isPermanent 变成 'true' | 'false'
context) {
const { applicationId, file, type: mediaType, isPermanent, description, } = params;
const { applicationId, file, type: mediaType, isPermanent, description, appType, } = params;
const filename = file.originalFilename;
const filetype = file.mimetype;
const file2 = fs_1.default.createReadStream(file.filepath);
(0, assert_1.assert)(appType === 'wechatPublic' || appType === 'wechatMp');
const [application] = await context.select('application', {
data: (0, lodash_1.cloneDeep)(Projection_1.applicationProjection),
filter: {
@ -79,11 +80,22 @@ context) {
dontCollect: true,
});
const { type, config } = application;
(0, assert_1.assert)(type === 'wechatPublic' && config.type === 'wechatPublic');
const config2 = config;
const { appId, appSecret } = config2;
const wechatInstance = oak_external_sdk_1.WechatSDK.getInstance(appId, 'wechatPublic', appSecret);
let wechatInstance;
if (appType === 'wechatPublic') {
(0, assert_1.assert)(type === 'wechatPublic' && config.type === 'wechatPublic');
const config2 = config;
const { appId, appSecret } = config2;
wechatInstance = oak_external_sdk_1.WechatSDK.getInstance(appId, 'wechatPublic', appSecret);
}
else {
(0, assert_1.assert)(type === 'wechatMp' && config.type === 'wechatMp');
const config2 = config;
const { appId, appSecret } = config2;
wechatInstance = oak_external_sdk_1.WechatSDK.getInstance(appId, 'wechatPublic', appSecret);
}
if (isPermanent === 'true') {
// 只有公众号才能上传永久素材
(0, assert_1.assert)(appType === 'wechatPublic');
const result = (await wechatInstance.createMaterial({
type: mediaType,
media: file2,

View File

@ -1,53 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createSession = void 0;
const tslib_1 = require("tslib");
const uuid_1 = require("oak-domain/lib/utils/uuid");
const assert_1 = tslib_1.__importDefault(require("assert"));
// export async function transformData<
// ED extends EntityDict,
// Cxt extends BackendRuntimeContext<ED>
// >(
// params: {
// data: WechatPublicEventData | WechatMpEventData;
// type: AppType,
// entity: string,
// entityId: string,
// },
// context: Cxt
// ) {
// const { data, type, entity, entityId } = params;
// const {
// ToUserName,
// FromUserName,
// CreateTime,
// MsgType,
// // Event,
// Content,
// // EventKey,
// } = data;
// if (entity !== 'web') {
// const sessionMessageData = {
// createTime: CreateTime,
// type: MsgType,
// text: Content,
// // news: ,
// aaoe: false,
// isRead: false,
// }
// return sessionMessageData
// } else {
// const sessionMessageData = {
// createTime: CreateTime,
// type: MsgType,
// text: Content,
// // news: ,
// aaoe: false,
// isRead: false,
// }
// return sessionMessageData
// }
// }
const assert_1 = require("oak-domain/lib/utils/assert");
async function createSession(params, context) {
const { data, type, entity, entityId } = params;
const userId = context.getCurrentUserId(true);
@ -56,17 +11,25 @@ async function createSession(params, context) {
switch (type) {
case 'web': {
const systemId = context.getSystemId();
const [application] = await context.select('application', {
data: {
id: 1,
systemId: 1,
type: 1,
},
filter: {
systemId,
type: 'web'
}
}, {});
let entity2 = entity;
let entityId2 = entityId;
if (!entity) {
// 默认
const [application] = await context.select('application', {
data: {
id: 1,
systemId: 1,
type: 1,
},
filter: {
systemId,
type: 'web',
},
}, {});
entity2 = 'application';
entityId2 = application?.id;
}
(0, assert_1.assert)(entity2 && entityId2);
const result = await context.select('session', {
data: {
id: 1,
@ -76,18 +39,18 @@ async function createSession(params, context) {
lmts: 1,
},
filter: {
entity: entity || 'application',
entityId: entityId || application?.id,
entity: entity2,
entityId: entityId2,
userId,
}
},
}, {});
session = result[0];
break;
}
case 'wechatMp':
case 'wechatPublic': {
(0, assert_1.default)(data);
(0, assert_1.default)(entity === 'application');
(0, assert_1.assert)(data);
(0, assert_1.assert)(entity === 'application' && entityId);
const { ToUserName, FromUserName, CreateTime, MsgType,
// Event,
Content,
@ -127,38 +90,39 @@ async function createSession(params, context) {
id: await (0, uuid_1.generateNewIdAsync)(),
applicationId: wechatUser?.applicationId,
wechatUserId: wechatUser?.id,
createTime: CreateTime,
createTime: Number(CreateTime) * 1000,
type: MsgType,
text: Content,
// news: ,
aaoe: false,
},
}
},
];
break;
}
default: {
(0, assert_1.default)(false, '');
(0, assert_1.assert)(false, `传入不支持的type: ${type}`);
}
}
const sessionId = await (0, uuid_1.generateNewIdAsync)();
if (session) {
if (!data) {
if (!sessionMessage$session) {
return session.id;
}
await context.operate('session', {
id: await (0, uuid_1.generateNewIdAsync)(),
action: 'update',
data: Object.assign({}, sessionMessage$session && { sessionMessage$session }),
data: {
sessionMessage$session,
},
filter: {
id: session.id,
}
},
}, {
dontCollect: true,
});
return session.id;
}
else {
const sessionId = await (0, uuid_1.generateNewIdAsync)();
await context.operate('session', {
id: await (0, uuid_1.generateNewIdAsync)(),
action: 'create',

View File

@ -1017,15 +1017,12 @@ async function syncUserInfoWechatMp({ nickname, avatarUrl, encryptedData, iv, si
}, {
dontCollect: true,
});
// console.log(avatarUrl);
const { type, config: config2 } = application;
(0, assert_1.assert)(type === 'wechatMp' || config2.type === 'wechatMp');
// const config2 = config as WechatMpConfig;
const { appId, appSecret } = config2;
const wechatInstance = oak_external_sdk_1.WechatSDK.getInstance(appId, 'wechatMp', appSecret);
const result = wechatInstance.decryptData(sessionKey, encryptedData, iv, signature);
// 实测发现解密出来的和userInfo完全一致……
console.log(result);
await setUserInfoFromWechat(user, { nickname, avatar: avatarUrl }, context);
}
exports.syncUserInfoWechatMp = syncUserInfoWechatMp;

View File

@ -170,7 +170,6 @@ async function createWechatQrCode(options, context) {
const application = applications.find((ele) => ele.id === data.applicationId);
(0, assert_1.assert)(application);
const { type: applicationType, config } = application;
// console.log(process.env.OAK_PLATFORM, process.env.NODE_ENV);
switch (type) {
case 'wechatMpWxaCode': {
(0, assert_1.assert)(applicationType === 'wechatMp' && config.type === 'wechatMp');

View File

@ -11,7 +11,6 @@ function Render(props) {
const [syncDisable, setSyncDisable] = (0, react_1.useState)(false);
const [open, setOpen] = (0, react_1.useState)(false);
const { pageSize, total, currentPage } = oakPagination || {};
console.log(messageTypes, wechatPublicTemplates);
return ((0, jsx_runtime_1.jsxs)("div", { className: web_module_less_1.default.container, children: [(0, jsx_runtime_1.jsxs)(antd_1.Space, { children: [(0, jsx_runtime_1.jsx)(antd_1.Button, { type: "default", disabled: !(messageTypes.length > 0 && wechatPublicTemplates.length > 0), onClick: () => {
addItem({
templateId: wechatPublicTemplates[0].id,

View File

@ -16,7 +16,6 @@ function render(props) {
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: () => {

View File

@ -19,9 +19,7 @@ function Render(props) {
}, 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 ? true : false, isUser: entityFilter ? false : true, oakAutoUnmount: true, entityDisplay: entityDisplay, entityProjection: entityProjection, oakPath: oakFullpath
}) })] }), selectedSessionId && ((0, jsx_runtime_1.jsx)(list_1.default, { sessionId: selectedSessionId, isEntity: entityFilter ? true : false, oakAutoUnmount: true, entityDisplay: entityDisplay, entityProjection: entityProjection, oakPath: oakFullpath
? `$$sessionMessage/list`
: undefined }))] }) }));
}

View File

@ -0,0 +1,7 @@
/// <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;
entity: string;
entityId: string;
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
export default _default;

View File

@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const assert_1 = require("oak-domain/lib/utils/assert");
exports.default = OakComponent({
isList: false,
lifetimes: {
async ready() {
const { sessionId, entity, entityId } = this.props;
if (!sessionId) {
(0, assert_1.assert)(entity && entityId);
const { result: newSessionId } = await this.features.cache.exec('createSession', { type: 'web', entity, entityId });
this.setState({
newSessionId,
});
}
else {
this.setState({
newSessionId: sessionId,
});
}
},
detached() {
},
},
properties: {
sessionId: '',
entity: '',
entityId: ''
}
});

View File

@ -0,0 +1,4 @@
{
"navigationBarTitleText": "会话",
"usingComponents": {}
}

View File

@ -0,0 +1,5 @@
import { WebComponentProps } from 'oak-frontend-base';
import { EntityDict } from '../../../oak-app-domain';
export default function Render(props: WebComponentProps<EntityDict, 'session', false, {
newSessionId: string;
}, {}>): import("react/jsx-runtime").JSX.Element | null;

View File

@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const list_1 = tslib_1.__importDefault(require("../../sessionMessage/list"));
function Render(props) {
const { data } = props;
const { oakFullpath, newSessionId } = data;
return newSessionId ? ((0, jsx_runtime_1.jsx)(list_1.default, { oakAutoUnmount: true, oakPath: oakFullpath ? `$$sessionMessage/list` : undefined, sessionId: newSessionId, isEntity: false })) : null;
}
exports.default = Render;

View File

@ -1,7 +1,5 @@
/// <reference types="react" />
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;

View File

@ -10,7 +10,6 @@ exports.default = OakComponent({
createTime: 1,
userId: 1,
wechatUserId: 1,
// isRead: 1,
$$createAt$$: 1,
sessionId: 1,
session: {
@ -88,7 +87,6 @@ exports.default = OakComponent({
userId: session?.userId,
userMobile: session?.user?.mobile$user &&
session?.user?.mobile$user[0]?.mobile,
// companyName: conversation?.company?.name,
userAvatar: this.features.extraFile.getUrl(session?.user?.extraFile$entity &&
session?.user?.extraFile$entity[0]),
};
@ -101,9 +99,7 @@ exports.default = OakComponent({
return newSessionMessage;
},
properties: {
key: '',
isEntity: false,
isUser: false,
},
methods: {
getAvatarUrl(aaoe) {
@ -115,23 +111,6 @@ exports.default = OakComponent({
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
// }
// }
},
},
});

View File

@ -8,13 +8,15 @@ 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, isUser, aaoe, sessionId, } = data;
const { $$createAt$$, text, type, picUrl, isEntity, 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) || (isUser && aaoe),
[web_module_less_1.default.notMyMessage]: !((isEntity && aaoe) ||
(!isEntity && !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) || (isUser && aaoe),
[web_module_less_1.default.messageType_text_no]: !((isEntity && aaoe) ||
(!isEntity && !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;

View File

@ -3,7 +3,6 @@ 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;

View File

@ -98,11 +98,7 @@ 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: sessionMessageList?.filter((ele) => ele.$$createAt$$ !== 1),
num: sessionMessageList?.length,
@ -112,7 +108,6 @@ exports.default = OakComponent({
properties: {
sessionId: '',
isEntity: false,
isUser: false,
dialog: false,
entity: '',
entityId: '',
@ -180,7 +175,6 @@ exports.default = OakComponent({
},
setContent(text) {
const { sessionMessageId } = this.state;
console.log(sessionMessageId);
this.setState({
text,
});
@ -331,10 +325,6 @@ exports.default = OakComponent({
id: (0, uuid_1.generateNewId)(),
};
try {
// await this.features.extraFile.upload(
// extraFile,
// originFileObj
// );
const userId = this.features.token.getUserId();
this.addItem({
id: (0, uuid_1.generateNewId)(),

View File

@ -10,12 +10,10 @@ const forMessage_1 = tslib_1.__importDefault(require("../../../components/sessio
const web_module_less_1 = tslib_1.__importDefault(require("./web.module.less"));
function Render(props) {
const { data, methods } = props;
const { sessionId, isEntity, isUser, sessionMessageList, oakFullpath, text, buttonHidden, sessionMessageType, sessionMessageId, entityDisplay, entityProjection, isWeChat, } = data;
const { sessionId, isEntity, sessionMessageList, oakFullpath, text, buttonHidden, sessionMessageType, sessionMessageId, entityDisplay, entityProjection, isWeChat, } = data;
const { setButtonHidden, customUpload, setContent, pageScroll, createMessage, } = methods;
const [bottomHeight, setBottomHeight] = (0, react_1.useState)(0);
const textareaRef = (0, react_1.useRef)(null);
// const newBottomHeight =
// window.document.getElementById('bottom')?.offsetHeight!;
(0, react_1.useEffect)(() => {
if (buttonHidden) {
const newBottomHeight = window.document.getElementById('bottom')?.offsetHeight;
@ -26,42 +24,13 @@ function Render(props) {
}
}, [buttonHidden]);
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');
}
};
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}
, {
// showBack={false}
sessionId: sessionId, isEntity: isEntity,
// userId={employerId}
oakPath: 'session:header1', oakAutoUnmount: true, entityDisplay: entityDisplay, entityProjection: entityProjection }), (0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.inner, style: {
return ((0, jsx_runtime_1.jsxs)("div", { className: web_module_less_1.default.container, children: [(0, jsx_runtime_1.jsx)(forMessage_1.default, { sessionId: sessionId, isEntity: isEntity, oakPath: 'session:header1', oakAutoUnmount: true, entityDisplay: entityDisplay, entityProjection: entityProjection }), (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$$ -
@ -69,14 +38,12 @@ 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, isUser: isUser }, sessionMessage.id));
: '', isEntity: isEntity }, 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: 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,
// autoSize={{ minRows: 2, maxRows: 15 }}
maxLength: 500, placeholder: "Enter \u53D1\u9001\uFF0CShift + Enter\u6362\u884C", 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, maxLength: 500, placeholder: "Enter \u53D1\u9001\uFF0CShift + Enter\u6362\u884C", rows: 5, onChange: (e) => {
setContent(e.target.value);
}, onFocus: () => {
setButtonHidden(true);
@ -86,7 +53,7 @@ function Render(props) {
// 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: () => {
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, onClick: () => {
createMessage();
pageScroll('comment');
}, children: "\u53D1\u9001" }) })] })] })] }));

View File

@ -35,7 +35,6 @@ exports.default = OakComponent({
}
],
formData({ data: rows }) {
console.log(rows);
const userWechatPublicTags = rows?.map((ele) => {
return {
id: ele?.id,

View File

@ -12,46 +12,60 @@ exports.default = OakComponent({
const { type, applicationId } = this.props;
let result;
if (type === 'news') {
result = await this.features.wechatMenu.batchGetArticle({ applicationId: applicationId, offset: 0, count: 10, noContent: 0 });
const news = JSON.parse(result);
if (news && news.item.length > 0) {
const modifiedResult = await Promise.all(news.item.map(async (ele) => {
result = await this.features.wechatMenu.batchGetArticle({
applicationId: applicationId,
offset: 0,
count: 10,
noContent: 0,
});
if (result && result.item.length > 0) {
const modifiedResult = await Promise.all(result.item.map(async (ele) => {
const news_item = await Promise.all(ele.content.news_item.map(async (ele2) => {
const coverUrl = await this.getMaterialImg(ele2.thumb_media_id);
return {
...ele2,
coverUrl
coverUrl,
};
}));
return {
...ele,
content: {
...ele.content,
news_item
}
news_item,
},
};
}));
this.setState({
materials: modifiedResult,
total: news.total_count,
total: result.total_count,
});
}
}
else {
result = await this.features.wechatMenu.batchGetMaterialList({ applicationId: applicationId, type: type, offset: 0, count: 10 });
result = await this.features.wechatMenu.batchGetMaterialList({
applicationId: applicationId,
type: type,
offset: 0,
count: 10,
});
this.setState({
materials: result.item,
total: result.total_count,
});
}
}
},
},
methods: {
async getMaterialList(page) {
const { applicationId } = this.props;
const { type } = this.props;
const offset = (page - 1) * 10;
const result = await this.features.wechatMenu.batchGetMaterialList({ applicationId: applicationId, type: type, offset, count: 10 });
const result = await this.features.wechatMenu.batchGetMaterialList({
applicationId: applicationId,
type: type,
offset,
count: 10,
});
this.setState({
materials: result.item,
total: result.total_count,
@ -60,21 +74,26 @@ exports.default = OakComponent({
async getArticleList(page) {
const { applicationId } = this.props;
const offset = (page - 1) * 10;
const result = await this.features.wechatMenu.batchGetArticle({ applicationId: applicationId, offset, count: 10, noContent: 0 });
const result = await this.features.wechatMenu.batchGetArticle({
applicationId: applicationId,
offset,
count: 10,
noContent: 0,
});
const modifiedResult = await Promise.all(result.item.map(async (ele) => {
const news_item = await Promise.all(ele.content.news_item.map(async (ele2) => {
const coverUrl = await this.getMaterialImg(ele2.thumb_media_id);
return {
...ele2,
coverUrl
coverUrl,
};
}));
return {
...ele,
content: {
...ele.content,
news_item
}
news_item,
},
};
}));
this.setState({
@ -85,7 +104,14 @@ exports.default = OakComponent({
async upload(media, description) {
const { applicationId } = this.props;
const { type } = this.props;
const result = await this.features.wechatMenu.createMaterial({ appType: 'wechatPublic', applicationId: applicationId, type: type, file: media, description, isPermanent: true });
const result = await this.features.wechatMenu.createMaterial({
appType: 'wechatPublic',
applicationId: applicationId,
type: type,
file: media,
description,
isPermanent: true,
});
if (result && result.mediaId) {
this.setMessage({
type: 'success',
@ -115,6 +141,6 @@ exports.default = OakComponent({
},
getImg(url) {
return this.features.locales.makeBridgeUrl(url);
}
}
},
},
});

View File

@ -247,6 +247,9 @@ exports.default = OakComponent({
async deleteConditionalMenu() {
const { deleteMenu } = this.props;
deleteMenu();
}
},
getImg(url) {
return this.features.locales.makeBridgeUrl(url);
},
},
});

View File

@ -38,4 +38,5 @@ export default function Render(props: WebComponentProps<EntityDict, keyof Entity
createMenu: (errorInfo: string, errorUrlInfo: string) => void;
deleteConditionalMenu: () => void;
confirmUrl: (url: string) => string;
getImg: (url: string) => string;
}>): import("react/jsx-runtime").JSX.Element;

View File

@ -17,7 +17,7 @@ const textClick_1 = tslib_1.__importDefault(require("../textClick"));
function Render(props) {
const { data, methods } = props;
const { config, menuIndex, selectedBtn, selectedSubBtn, currentIndex, changeIsPreview, getOpen, menuType, applicationId, menuId, actions, wechatId, iState, } = data;
const { setConfig, confirmName, confirmSubName, editMenuName, deleteMenuContent, getMaterialImgAndVoice, getMaterialVideo, decideMenuContentLabel, getArticle, createMenu, deleteConditionalMenu, confirmUrl, } = methods;
const { setConfig, confirmName, confirmSubName, editMenuName, deleteMenuContent, getMaterialImgAndVoice, getMaterialVideo, decideMenuContentLabel, getArticle, createMenu, deleteConditionalMenu, confirmUrl, getImg, } = methods;
const [msgType, setMsgType] = (0, react_1.useState)('sendMsg');
const [errorInfo, setErrorInfo] = (0, react_1.useState)('');
const [errorUrlInfo, setErrorUrlInfo] = (0, react_1.useState)('');
@ -61,7 +61,9 @@ function Render(props) {
if (selectedBtn > 0) {
setConfig(selectedBtn - 1, {
type: 'click',
key: menuType === 'conditional' ? `${wechatId}$${await (0, uuid_1.generateNewIdAsync)()}` : await (0, uuid_1.generateNewIdAsync)(),
key: menuType === 'conditional'
? `${wechatId}$${await (0, uuid_1.generateNewIdAsync)()}`
: await (0, uuid_1.generateNewIdAsync)(),
subType: 'text',
content: menuContent,
});
@ -69,7 +71,9 @@ function Render(props) {
else {
setConfig(selectedSubBtn - 1, {
type: 'click',
key: menuType === 'conditional' ? `${wechatId}$${await (0, uuid_1.generateNewIdAsync)()}` : await (0, uuid_1.generateNewIdAsync)(),
key: menuType === 'conditional'
? `${wechatId}$${await (0, uuid_1.generateNewIdAsync)()}`
: await (0, uuid_1.generateNewIdAsync)(),
subType: 'text',
content: menuContent,
}, currentIndex);
@ -260,7 +264,7 @@ function Render(props) {
setOpen(true);
getOpen(true);
setType('video');
}, children: "\u89C6\u9891" })] })) : type === 'image' ? ((0, jsx_runtime_1.jsxs)("div", { className: web_module_less_1.default.coverImage, children: [(0, jsx_runtime_1.jsx)("img", { className: web_module_less_1.default.img, src: decidedMenuContent.url }), (0, jsx_runtime_1.jsxs)("div", { className: web_module_less_1.default.buttonGroup, children: [(0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.buttonItem, onClick: () => {
}, children: "\u89C6\u9891" })] })) : type === 'image' ? ((0, jsx_runtime_1.jsxs)("div", { className: web_module_less_1.default.coverImage, children: [(0, jsx_runtime_1.jsx)("img", { className: web_module_less_1.default.img, src: getImg(decidedMenuContent.url) }), (0, jsx_runtime_1.jsxs)("div", { className: web_module_less_1.default.buttonGroup, children: [(0, jsx_runtime_1.jsx)("div", { className: web_module_less_1.default.buttonItem, onClick: () => {
const modal = confirm({
title: '确定删除该图片吗?',
content: '删除后不可恢复',

View File

@ -12,7 +12,6 @@ class Template extends oak_frontend_base_1.Feature {
const result = await this.cache.exec('syncMessageTemplate', {
applicationId
});
console.log(result);
this.publish();
}
}

View File

@ -1,6 +1,6 @@
import { assert } from 'oak-domain/lib/utils/assert';
import { EntityDict } from "../oak-app-domain";
import { AppType, WechatPublicConfig } from "../oak-app-domain/Application/Schema";
import { AppType, WechatPublicConfig, WechatMpConfig } from "../oak-app-domain/Application/Schema";
import { BackendRuntimeContext } from "../context/BackendRuntimeContext";
import { applicationProjection } from '../types/Projection';
import { MediaType } from '../types/WeChat';
@ -9,6 +9,7 @@ import {
} from 'oak-domain/lib/types/Environment';
import {
WechatPublicInstance,
WechatMpInstance,
WechatSDK,
} from 'oak-external-sdk';
import fs from 'fs';
@ -114,6 +115,7 @@ export async function uploadWechatMedia<
Cxt extends BackendRuntimeContext<ED>
>(
params: {
appType: AppType;
applicationId: string;
file: File;
type: MediaType;
@ -128,10 +130,12 @@ export async function uploadWechatMedia<
type: mediaType,
isPermanent,
description,
appType,
} = params;
const filename = file.originalFilename!;
const filetype = file.mimetype!;
const file2 = fs.createReadStream(file.filepath);
assert(appType === 'wechatPublic' || appType === 'wechatMp');
const [application] = await context.select(
'application',
@ -145,19 +149,33 @@ export async function uploadWechatMedia<
dontCollect: true,
}
);
const { type, config } = application!;
assert(type === 'wechatPublic' && config!.type === 'wechatPublic');
const config2 = config as WechatPublicConfig;
const { appId, appSecret } = config2;
const wechatInstance = WechatSDK.getInstance(
appId,
'wechatPublic',
appSecret
) as WechatPublicInstance;
let wechatInstance: WechatPublicInstance | WechatMpInstance;
if (appType === 'wechatPublic') {
assert(type === 'wechatPublic' && config!.type === 'wechatPublic');
const config2 = config as WechatPublicConfig;
const { appId, appSecret } = config2;
wechatInstance = WechatSDK.getInstance(
appId,
'wechatPublic',
appSecret
) as WechatPublicInstance;
} else {
assert(type === 'wechatMp' && config!.type === 'wechatMp');
const config2 = config as WechatMpConfig;
const { appId, appSecret } = config2;
wechatInstance = WechatSDK.getInstance(
appId,
'wechatPublic',
appSecret
) as WechatMpInstance;
}
if (isPermanent === 'true') {
const result = (await wechatInstance.createMaterial({
// 只有公众号才能上传永久素材
assert(appType === 'wechatPublic');
const result = (await (wechatInstance as WechatPublicInstance).createMaterial({
type: mediaType,
media: file2,
filename,

View File

@ -4,52 +4,8 @@ import { BackendRuntimeContext } from "../context/BackendRuntimeContext";
import { OakUserException } from 'oak-domain/lib/types';
import { WechatPublicEventData, WechatMpEventData } from 'oak-external-sdk';
import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
import assert from "assert";
// export async function transformData<
// ED extends EntityDict,
// Cxt extends BackendRuntimeContext<ED>
// >(
// params: {
// data: WechatPublicEventData | WechatMpEventData;
// type: AppType,
// entity: string,
// entityId: string,
// },
// context: Cxt
// ) {
// const { data, type, entity, entityId } = params;
// const {
// ToUserName,
// FromUserName,
// CreateTime,
// MsgType,
// // Event,
// Content,
// // EventKey,
// } = data;
// if (entity !== 'web') {
// const sessionMessageData = {
// createTime: CreateTime,
// type: MsgType,
// text: Content,
// // news: ,
// aaoe: false,
// isRead: false,
// }
// return sessionMessageData
// } else {
// const sessionMessageData = {
// createTime: CreateTime,
// type: MsgType,
// text: Content,
// // news: ,
// aaoe: false,
// isRead: false,
// }
// return sessionMessageData
// }
import { assert } from 'oak-domain/lib/utils/assert';
// }
export async function createSession<
ED extends EntityDict,
Cxt extends BackendRuntimeContext<ED>
@ -72,38 +28,54 @@ export async function createSession<
case 'web': {
const systemId = context.getSystemId();
const [application] = await context.select('application', {
data: {
id: 1,
systemId: 1,
type: 1,
let entity2 = entity;
let entityId2 = entityId;
if (!entity) {
// 默认
const [application] = await context.select(
'application',
{
data: {
id: 1,
systemId: 1,
type: 1,
},
filter: {
systemId,
type: 'web',
},
},
{}
);
entity2 = 'application';
entityId2 = application?.id;
}
assert(entity2 && entityId2);
const result = await context.select(
'session',
{
data: {
id: 1,
entity: 1,
entityId: 1,
userId: 1,
lmts: 1,
},
filter: {
entity: entity2!,
entityId: entityId2!,
userId,
},
},
filter: {
systemId,
type: 'web'
}
}, {});
const result = await context.select('session', {
data: {
id: 1,
entity: 1,
entityId: 1,
userId: 1,
lmts: 1,
},
filter: {
entity: entity || 'application',
entityId: entityId || application?.id,
userId,
}
}, {});
{}
);
session = result[0]
break;
}
case 'wechatMp':
case 'wechatPublic': {
assert(data);
assert(entity === 'application');
assert(entity === 'application' && entityId);
const {
ToUserName,
FromUserName,
@ -147,56 +119,64 @@ export async function createSession<
id: await generateNewIdAsync(),
applicationId: wechatUser?.applicationId,
wechatUserId: wechatUser?.id,
createTime: CreateTime,
createTime: Number(CreateTime) * 1000,
type: MsgType,
text: Content,
// news: ,
aaoe: false,
},
}
]
},
];
break;
}
default: {
assert(false, '')
assert(false, `传入不支持的type: ${type}`)
}
}
const sessionId = await generateNewIdAsync();
if (session) {
if (!data) {
return session.id
if (!sessionMessage$session) {
return session.id;
}
await context.operate('session', {
id: await generateNewIdAsync(),
action: 'update',
data: Object.assign({
}, sessionMessage$session && { sessionMessage$session }),
filter: {
id: session.id,
await context.operate(
'session',
{
id: await generateNewIdAsync(),
action: 'update',
data: {
sessionMessage$session,
},
filter: {
id: session.id,
},
},
{
dontCollect: true,
}
}, {
dontCollect: true,
});
return session.id
}
else {
await context.operate('session', {
id: await generateNewIdAsync(),
action: 'create',
data: Object.assign({
id: sessionId,
entity,
entityId,
userId,
lmts: Date.now(),
openId: data?.FromUserName,
}, sessionMessage$session && { sessionMessage$session }),
}, {
dontCollect: true,
});
return sessionId
);
return session.id;
} else {
const sessionId = await generateNewIdAsync();
await context.operate(
'session',
{
id: await generateNewIdAsync(),
action: 'create',
data: Object.assign(
{
id: sessionId,
entity,
entityId,
userId,
lmts: Date.now(),
openId: data?.FromUserName,
},
sessionMessage$session && { sessionMessage$session }
),
},
{
dontCollect: true,
}
);
return sessionId;
}
}

View File

@ -1459,13 +1459,11 @@ export async function syncUserInfoWechatMp<
}
);
// console.log(avatarUrl);
const { type, config: config2 } = application as Partial<
EntityDict['application']['Schema']
>;
assert(type === 'wechatMp' || config2!.type === 'wechatMp');
// const config2 = config as WechatMpConfig;
const { appId, appSecret } = config2 as WechatMpConfig;
const wechatInstance = WechatSDK.getInstance(appId, 'wechatMp', appSecret);
const result = wechatInstance.decryptData(
@ -1475,7 +1473,6 @@ export async function syncUserInfoWechatMp<
signature
);
// 实测发现解密出来的和userInfo完全一致……
console.log(result);
await setUserInfoFromWechat<ED, Cxt>(
user!,
{ nickname, avatar: avatarUrl },

View File

@ -223,7 +223,6 @@ export async function createWechatQrCode<ED extends EntityDict, T extends keyof
const { type: applicationType, config } = application;
// console.log(process.env.OAK_PLATFORM, process.env.NODE_ENV);
switch (type) {
case 'wechatMpWxaCode': {
assert(

View File

@ -34,7 +34,6 @@ export default function Render(props: WebComponentProps<
const [open, setOpen] = useState(false);
const { pageSize, total, currentPage } = oakPagination || {};
console.log(messageTypes, wechatPublicTemplates);
return (
<div className={Styles.container}>
<Space>

View File

@ -31,7 +31,6 @@ export default function render(props: WebComponentProps<
const defaultUrl = 'http://qiniu.gecomebox.com/static/defaultAvatar.png'
const features = useFeatures();
const width = useWidth();
console.log(session)
return (
<div className={classNames(Style.header, {

View File

@ -78,9 +78,7 @@ export default function Render(
{selectedSessionId && (
<MessageList
sessionId={selectedSessionId}
// isCombine={true}
isEntity={entityFilter ? true : false}
isUser={entityFilter ? false : true}
oakAutoUnmount={true}
entityDisplay={entityDisplay}
entityProjection={entityProjection}

View File

@ -0,0 +1,4 @@
{
"navigationBarTitleText": "会话",
"usingComponents": {}
}

View File

@ -0,0 +1,32 @@
import { assert } from 'oak-domain/lib/utils/assert'
export default OakComponent({
isList: false,
lifetimes: {
async ready() {
const { sessionId, entity, entityId } = this.props;
if (!sessionId) {
assert(entity && entityId);
const { result: newSessionId } = await this.features.cache.exec(
'createSession',
{ type: 'web', entity, entityId }
);
this.setState({
newSessionId,
});
} else {
this.setState({
newSessionId: sessionId,
});
}
},
detached() {
},
},
properties: {
sessionId: '' as string,
entity: '' as string,
entityId: '' as string
}
});

View File

@ -0,0 +1,27 @@
import React from 'react';
import SessionMessageList from '../../sessionMessage/list'
import { WebComponentProps } from 'oak-frontend-base';
import { EntityDict } from '../../../oak-app-domain';
export default function Render(
props: WebComponentProps<
EntityDict,
'session',
false,
{
newSessionId: string;
},
{}
>
) {
const { data } = props;
const { oakFullpath, newSessionId } = data;
return newSessionId ? (
<SessionMessageList
oakAutoUnmount={true}
oakPath={oakFullpath ? `$$sessionMessage/list` : undefined}
sessionId={newSessionId}
isEntity={false}
/>
) : null;
}

View File

@ -10,7 +10,6 @@ export default OakComponent({
createTime: 1,
userId: 1,
wechatUserId: 1,
// isRead: 1,
$$createAt$$: 1,
sessionId: 1,
session: {
@ -89,7 +88,6 @@ export default OakComponent({
userMobile:
session?.user?.mobile$user &&
session?.user?.mobile$user[0]?.mobile,
// companyName: conversation?.company?.name,
userAvatar: this.features.extraFile.getUrl(
session?.user?.extraFile$entity &&
session?.user?.extraFile$entity[0]
@ -109,9 +107,7 @@ export default OakComponent({
return newSessionMessage;
},
properties: {
key: '' as string,
isEntity: false,
isUser: false,
},
methods: {
getAvatarUrl(aaoe: boolean) {
@ -124,23 +120,6 @@ export default OakComponent({
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
// }
// }
},
},
});

View File

@ -34,7 +34,6 @@ export default function render(
type,
picUrl,
isEntity,
isUser,
aaoe,
sessionId,
} = data;
@ -43,7 +42,10 @@ export default function render(
<ICell time={$$createAt$$}>
<div
className={classNames(Style.myMessage, {
[Style.notMyMessage]: (isEntity && !aaoe) || (isUser && aaoe),
[Style.notMyMessage]: !(
(isEntity && aaoe) ||
(!isEntity && !aaoe)
),
})}
>
<Image
@ -54,10 +56,12 @@ export default function render(
<div
className={classNames({
[Style.messageType_text]: type === 'text',
[Style.messageType_text_no]: (isEntity && !aaoe) || (isUser && aaoe),
[Style.messageType_text_no]: !(
(isEntity && aaoe) ||
(!isEntity && !aaoe)
),
})}
>
{type === 'text' && <IText value={text} />}
{type === 'image' && <IImage url={picUrl} />}
</div>

View File

@ -3,6 +3,7 @@ import { generateNewId } from 'oak-domain/lib/utils/uuid';
import { DATA_SUBSCRIBER_KEYS } from '../../../config/constants';
import { getConfig } from '../../../utils/getContextConfig';
import { QiniuCosConfig } from '../../../types/Config';
export default OakComponent({
entity: 'sessionMessage',
projection: {
@ -107,11 +108,7 @@ export default OakComponent({
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: sessionMessageList?.filter(
(ele) => ele.$$createAt$$ !== 1
@ -123,7 +120,6 @@ export default OakComponent({
properties: {
sessionId: '' as string,
isEntity: false as boolean,
isUser: false as boolean,
dialog: false as boolean,
entity: '',
entityId: '',
@ -191,7 +187,6 @@ export default OakComponent({
},
setContent(text: string) {
const { sessionMessageId } = this.state;
console.log(sessionMessageId);
this.setState({
text,
});
@ -362,10 +357,6 @@ export default OakComponent({
} as EntityDict['extraFile']['CreateSingle']['data'];
try {
// await this.features.extraFile.upload(
// extraFile,
// originFileObj
// );
const userId = this.features.token.getUserId();
this.addItem({
id: generateNewId(),

View File

@ -47,7 +47,6 @@ export default function Render(
const {
sessionId,
isEntity,
isUser,
sessionMessageList,
oakFullpath,
text,
@ -67,8 +66,7 @@ export default function Render(
} = methods;
const [bottomHeight, setBottomHeight] = useState(0);
const textareaRef = useRef(null);
// const newBottomHeight =
// window.document.getElementById('bottom')?.offsetHeight!;
useEffect(() => {
if (buttonHidden) {
const newBottomHeight =
@ -79,45 +77,17 @@ export default function Render(
}
}, [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');
}
};
console.log(isWeChat)
return (
<div className={Style.container}>
<Header
// showBack={false}
sessionId={sessionId}
isEntity={isEntity}
// userId={employerId}
oakPath={
'session:header1'
}
@ -150,7 +120,6 @@ export default function Render(
: ''
}
isEntity={isEntity}
isUser={isUser}
/>
);
})}
@ -204,7 +173,6 @@ export default function Render(
<Input.TextArea
ref={textareaRef}
className={Style.textarea}
// autoSize={{ minRows: 2, maxRows: 15 }}
maxLength={500}
placeholder="Enter 发送Shift + Enter换行"
rows={5}
@ -225,7 +193,7 @@ export default function Render(
<div className={Style.btn}>
<Button
type="primary"
disabled={text ? false : true}
disabled={!text}
onClick={() => {
createMessage();
pageScroll('comment');

View File

@ -34,7 +34,6 @@ export default OakComponent({
}
],
formData({ data: rows }) {
console.log(rows);
const userWechatPublicTags = rows?.map((ele) => {
return {
id: ele?.id,

View File

@ -1,4 +1,4 @@
import { MenuType, MediaVideoDescription } from '../../types/WeChat'
import { MenuType, MediaVideoDescription } from '../../types/WeChat';
export default OakComponent({
isList: false,
@ -12,46 +12,66 @@ export default OakComponent({
const { type, applicationId } = this.props;
let result;
if (type === 'news') {
result = await this.features.wechatMenu.batchGetArticle({ applicationId: applicationId!, offset: 0, count: 10, noContent: 0 });
const news = JSON.parse(result);
if (news && news.item.length > 0) {
const modifiedResult = await Promise.all(news.item.map(async (ele: any) => {
const news_item = await Promise.all(ele.content.news_item.map(async (ele2: any) => {
const coverUrl = await this.getMaterialImg(ele2.thumb_media_id);
return {
...ele2,
coverUrl
};
}));
result = await this.features.wechatMenu.batchGetArticle({
applicationId: applicationId!,
offset: 0,
count: 10,
noContent: 0,
});
if (result && result.item.length > 0) {
const modifiedResult = await Promise.all(
result.item.map(async (ele: any) => {
const news_item = await Promise.all(
ele.content.news_item.map(async (ele2: any) => {
const coverUrl = await this.getMaterialImg(
ele2.thumb_media_id
);
return {
...ele2,
coverUrl,
};
})
);
return {
...ele,
content: {
...ele.content,
news_item
}
};
}));
return {
...ele,
content: {
...ele.content,
news_item,
},
};
})
);
this.setState({
materials: modifiedResult,
total: news.total_count,
total: result.total_count,
});
}
} else {
result = await this.features.wechatMenu.batchGetMaterialList({ applicationId: applicationId!, type: type!, offset: 0, count: 10 });
result = await this.features.wechatMenu.batchGetMaterialList({
applicationId: applicationId!,
type: type!,
offset: 0,
count: 10,
});
this.setState({
materials: result.item,
total: result.total_count,
});
}
}
},
},
methods: {
async getMaterialList(page: number) {
const { applicationId } = this.props;
const { type } = this.props;
const offset = (page - 1) * 10;
const result = await this.features.wechatMenu.batchGetMaterialList({ applicationId: applicationId!, type: type!, offset, count: 10 });
const result = await this.features.wechatMenu.batchGetMaterialList({
applicationId: applicationId!,
type: type!,
offset,
count: 10,
});
this.setState({
materials: result.item,
total: result.total_count,
@ -60,24 +80,35 @@ export default OakComponent({
async getArticleList(page: number) {
const { applicationId } = this.props;
const offset = (page - 1) * 10;
const result = await this.features.wechatMenu.batchGetArticle({ applicationId: applicationId!, offset, count: 10, noContent: 0 });
const modifiedResult = await Promise.all(result.item.map(async (ele: any) => {
const news_item = await Promise.all(ele.content.news_item.map(async (ele2: any) => {
const coverUrl = await this.getMaterialImg(ele2.thumb_media_id);
return {
...ele2,
coverUrl
};
}));
const result = await this.features.wechatMenu.batchGetArticle({
applicationId: applicationId!,
offset,
count: 10,
noContent: 0,
});
const modifiedResult = await Promise.all(
result.item.map(async (ele: any) => {
const news_item = await Promise.all(
ele.content.news_item.map(async (ele2: any) => {
const coverUrl = await this.getMaterialImg(
ele2.thumb_media_id
);
return {
...ele2,
coverUrl,
};
})
);
return {
...ele,
content: {
...ele.content,
news_item
}
};
}));
return {
...ele,
content: {
...ele.content,
news_item,
},
};
})
);
this.setState({
materials: modifiedResult,
total: result.total_count,
@ -86,7 +117,14 @@ export default OakComponent({
async upload(media: File, description?: MediaVideoDescription) {
const { applicationId } = this.props;
const { type } = this.props;
const result = await this.features.wechatMenu.createMaterial({appType: 'wechatPublic', applicationId: applicationId!, type: type as 'image' | 'voice' | 'video', file: media, description, isPermanent: true });
const result = await this.features.wechatMenu.createMaterial({
appType: 'wechatPublic',
applicationId: applicationId!,
type: type as 'image' | 'voice' | 'video',
file: media,
description,
isPermanent: true,
});
if (result && result.mediaId) {
this.setMessage({
type: 'success',
@ -99,13 +137,19 @@ export default OakComponent({
}
},
async getMaterialImg(mediaId: string) {
const { applicationId } = this.props
const { applicationId } = this.props;
const imgFile = await this.features.wechatMenu.getMaterial({
applicationId: applicationId!,
type: 'image',
mediaId,
});
return new Promise<string | ArrayBuffer | PromiseLike<string | ArrayBuffer | null> | null | undefined>((resolve) => {
return new Promise<
| string
| ArrayBuffer
| PromiseLike<string | ArrayBuffer | null>
| null
| undefined
>((resolve) => {
const reader = new FileReader();
reader.readAsDataURL(imgFile);
reader.onload = function (e) {
@ -115,6 +159,6 @@ export default OakComponent({
},
getImg(url: string) {
return this.features.locales.makeBridgeUrl(url);
}
}
});
},
},
});

View File

@ -6,8 +6,7 @@ export default OakComponent({
config: null as any,
menuIndex: 0,
changeConfig: (config: any) => undefined as void,
publish: (iState: 'wait' | 'fail') =>
undefined as void,
publish: (iState: 'wait' | 'fail') => undefined as void,
getErrorIndex: (errorIndex: number[]) => undefined as void,
createMenu: () => undefined as void,
selectedBtn: 0,
@ -266,6 +265,9 @@ export default OakComponent({
async deleteConditionalMenu() {
const { deleteMenu } = this.props;
deleteMenu!();
}
},
getImg(url: string) {
return this.features.locales.makeBridgeUrl(url);
},
},
});

View File

@ -77,6 +77,7 @@ export default function Render(
createMenu: (errorInfo: string, errorUrlInfo: string) => void;
deleteConditionalMenu: () => void;
confirmUrl: (url: string) => string;
getImg: (url: string) => string;
}
>
) {
@ -109,6 +110,7 @@ export default function Render(
createMenu,
deleteConditionalMenu,
confirmUrl,
getImg,
} = methods;
const [msgType, setMsgType] = useState('sendMsg');
const [errorInfo, setErrorInfo] = useState('');
@ -158,7 +160,10 @@ export default function Render(
if (selectedBtn > 0) {
setConfig(selectedBtn - 1, {
type: 'click',
key: menuType === 'conditional' ? `${wechatId}$${await generateNewIdAsync()}` : await generateNewIdAsync(),
key:
menuType === 'conditional'
? `${wechatId}$${await generateNewIdAsync()}`
: await generateNewIdAsync(),
subType: 'text',
content: menuContent,
});
@ -167,7 +172,10 @@ export default function Render(
selectedSubBtn - 1,
{
type: 'click',
key: menuType === 'conditional' ? `${wechatId}$${await generateNewIdAsync()}` : await generateNewIdAsync(),
key:
menuType === 'conditional'
? `${wechatId}$${await generateNewIdAsync()}`
: await generateNewIdAsync(),
subType: 'text',
content: menuContent,
},
@ -316,11 +324,14 @@ export default function Render(
}
}, [url]);
return (
<div className={Style.container} style={iState === 'fail' ? { border: '1px solid #FF5557' } : {}}>
<div
className={Style.container}
style={iState === 'fail' ? { border: '1px solid #FF5557' } : {}}
>
{config &&
config.button &&
config.button.length > 0 &&
(selectedBtn !== 0 || selectedSubBtn !== 0) ? (
config.button &&
config.button.length > 0 &&
(selectedBtn !== 0 || selectedSubBtn !== 0) ? (
<div className={Style.upsertMenu}>
<div className={Style.content}>
<div className={Style.title}>
@ -332,9 +343,11 @@ export default function Render(
colon={false}
help={
<div>
<div>{`仅支持中英文和数字,字数不超过${selectedSubBtn !== 0 ? 8 : 4
}${selectedSubBtn !== 0 ? 16 : 8
}`}</div>
<div>{`仅支持中英文和数字,字数不超过${
selectedSubBtn !== 0 ? 8 : 4
}${
selectedSubBtn !== 0 ? 16 : 8
}`}</div>
{errorInfo && (
<div style={{ color: '#fa5151' }}>
{errorInfo}
@ -384,7 +397,7 @@ export default function Render(
{(config.button[currentIndex]?.sub_button?.length ===
0 &&
selectedSubBtn === 0) ||
selectedSubBtn > 0 ? (
selectedSubBtn > 0 ? (
<>
<Form.Item
colon={false}
@ -418,17 +431,17 @@ export default function Render(
{decideMenuContentLabel(
decidedMenuContent,
type as
| 'video'
| 'image'
| 'text'
| 'news'
| 'voice'
| 'video'
| 'image'
| 'text'
| 'news'
| 'voice'
)}
</div>
}
>
{!decidedMenuContent &&
type !== 'text' ? (
type !== 'text' ? (
<div
className={
Style.menuContent
@ -492,9 +505,9 @@ export default function Render(
>
<img
className={Style.img}
src={
src={getImg(
decidedMenuContent.url
}
)}
/>
<div
className={
@ -527,12 +540,12 @@ export default function Render(
) {
deleteMenuContent(
selectedBtn -
1
1
);
} else {
deleteMenuContent(
selectedSubBtn -
1,
1,
currentIndex
);
}
@ -605,12 +618,12 @@ export default function Render(
) {
deleteMenuContent(
selectedBtn -
1
1
);
} else {
deleteMenuContent(
selectedSubBtn -
1,
1,
currentIndex
);
}
@ -683,12 +696,12 @@ export default function Render(
) {
deleteMenuContent(
selectedBtn -
1
1
);
} else {
deleteMenuContent(
selectedSubBtn -
1,
1,
currentIndex
);
}
@ -755,12 +768,12 @@ export default function Render(
) {
deleteMenuContent(
selectedBtn -
1
1
);
} else {
deleteMenuContent(
selectedSubBtn -
1,
1,
currentIndex
);
}
@ -835,12 +848,12 @@ export default function Render(
) {
deleteMenuContent(
selectedBtn -
1
1
);
} else {
deleteMenuContent(
selectedSubBtn -
1,
1,
currentIndex
);
}
@ -882,7 +895,7 @@ export default function Render(
) {
setConfig(
selectedBtn -
1,
1,
{
type: 'media_id',
media_id:
@ -898,7 +911,7 @@ export default function Render(
) {
setConfig(
selectedBtn -
1,
1,
{
type: 'media_id',
media_id:
@ -914,7 +927,7 @@ export default function Render(
) {
setConfig(
selectedBtn -
1,
1,
{
type: 'media_id',
media_id:
@ -927,7 +940,7 @@ export default function Render(
} else {
setConfig(
selectedBtn -
1,
1,
{
type: 'article_id',
article_id:
@ -946,7 +959,7 @@ export default function Render(
) {
setConfig(
selectedSubBtn -
1,
1,
{
type: 'media_id',
media_id:
@ -963,7 +976,7 @@ export default function Render(
) {
setConfig(
selectedSubBtn -
1,
1,
{
type: 'media_id',
media_id:
@ -980,7 +993,7 @@ export default function Render(
) {
setConfig(
selectedSubBtn -
1,
1,
{
type: 'media_id',
media_id:
@ -994,7 +1007,7 @@ export default function Render(
} else {
setConfig(
selectedSubBtn -
1,
1,
{
type: 'article_id',
article_id:
@ -1034,10 +1047,10 @@ export default function Render(
oakAutoUnmount={true}
type={
type as
| 'news'
| 'image'
| 'video'
| 'voice'
| 'news'
| 'image'
| 'video'
| 'voice'
}
getMenuContent={getMenuContent}
applicationId={applicationId}

View File

@ -25,7 +25,6 @@ export class Template<
const result = await this.cache.exec('syncMessageTemplate', {
applicationId
});
console.log(result);
this.publish();
}
}