fastlion-amis
Version:
一种MIS页面生成工具
344 lines (343 loc) • 25.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var react_1 = tslib_1.__importStar(require("react"));
var antd_1 = require("antd");
var utils_1 = require("../../../renderers/Lion/utils/utils");
var components_1 = require("../../../components");
var DragModal_1 = (0, tslib_1.__importDefault)(require("../../../components/DragModal"));
var icons_1 = require("../../../components/icons");
var icons_2 = require("@ant-design/icons");
var icons_3 = require("@ant-design/icons");
require("./index.scss");
var helper_1 = require("../../../utils/helper");
var Ai = function (props) {
var _a, _b, _c;
var _d = (0, react_1.useState)([{ id: 'robot_00', isUser: false, title: '你好,我是你的AI助理' }]), chatDatas = _d[0], setChatDatas = _d[1];
var _e = (0, react_1.useState)(), inputValue = _e[0], setInputValue = _e[1];
// 选择模型的功能暂时隐藏
var _f = (0, react_1.useState)(false), isChatMode = _f[0], setIsChatMode = _f[1];
var _g = (0, react_1.useState)(false), fetchLoading = _g[0], setFetchLoading = _g[1];
/** 聊天模式的关联上下文的id */
var _h = (0, react_1.useState)(), chatConversationId = _h[0], setChatConversationId = _h[1];
var _j = (0, react_1.useState)(false), commentLoading = _j[0], setCommentLoading = _j[1];
var _k = (0, react_1.useState)({}), recommends = _k[0], setRecommends = _k[1];
var serverApiObj = (0, react_1.useRef)();
var _l = (0, react_1.useState)(), aiChatID = _l[0], setChatID = _l[1];
var showChatID = (0, react_1.useState)(!['sas.sanfu.com', 'sas.clothes.sanfu.com'].includes(location.host))[0];
var userName = (_c = (_b = JSON.parse((_a = sessionStorage.getItem('userInfo')) !== null && _a !== void 0 ? _a : '{}')) === null || _b === void 0 ? void 0 : _b.user_name) !== null && _c !== void 0 ? _c : 'USER';
(0, react_1.useEffect)(function () {
setIsChatMode(props.isChatMode);
}, [props.isChatMode]);
(0, react_1.useEffect)(function () {
initAi();
}, []);
/** 初始化AI工具,获取接口 */
var initAi = function () { return (0, tslib_1.__awaiter)(void 0, void 0, void 0, function () {
var res;
return (0, tslib_1.__generator)(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, props.env.fetcher("/api/v1/ai/init?page_id=" + props.pageId)];
case 1:
res = _a.sent();
if (res.ok && res.data != null) {
serverApiObj.current = res.data;
props.onTitleChange(res.data.title);
setChatDatas(function (datas) { return datas.map(function (data) {
if (data.id == 'robot_00') {
return (0, tslib_1.__assign)((0, tslib_1.__assign)({}, data), {
// title: res.data.desc,
title: '', description: {
type: 'lion-tpl',
tpl: "<div class=\"description-box\"><div class=\"title\">" + res.data.desc + "</div>" + res.data.subDesc + "</div>"
} });
}
return data;
}); });
handleGetRecommends();
}
else {
setChatDatas(function (datas) { return datas.map(function (data) {
if (data.id == 'robot_00') {
return (0, tslib_1.__assign)((0, tslib_1.__assign)({}, data), { title: '', description: {
type: 'lion-tpl',
tpl: "<div class=\"description-box\" style=\"white-space: normal\"><div class=\"title\">" + data.title + "</div>" + res.msg + "</div>"
} });
}
return data;
}); });
}
return [2 /*return*/];
}
});
}); };
var scrollToBottom = function () {
var element = document.getElementById('sf-chat-list');
if (element) {
element.scrollTop = element.scrollHeight;
}
};
var generateSearchParam = (0, react_1.useCallback)(function () {
var _a;
var _b = ((_a = props.paramData) !== null && _a !== void 0 ? _a : '').split('?'), url = _b[0], _c = _b[1], param = _c === void 0 ? '' : _c;
return "?" + param + (aiChatID ? "&AI_CHAT_ID=" + aiChatID : '');
}, [props.paramData, aiChatID]);
/** 获取推荐条目 */
var handleGetRecommends = function (config) {
if (config === void 0) { config = {}; }
return (0, tslib_1.__awaiter)(void 0, void 0, void 0, function () {
var _a, chatId, _b, question, apiConfig, res_1;
var _c;
return (0, tslib_1.__generator)(this, function (_d) {
switch (_d.label) {
case 0:
_a = config.chatId, chatId = _a === void 0 ? 'robot_00' : _a, _b = config.question, question = _b === void 0 ? '' : _b;
apiConfig = (_c = serverApiObj.current) === null || _c === void 0 ? void 0 : _c['recommendUrlApi'];
_d.label = 1;
case 1:
_d.trys.push([1, , 3, 4]);
return [4 /*yield*/, props.env.fetcher((0, tslib_1.__assign)({}, apiConfig), { question: question })];
case 2:
res_1 = _d.sent();
if (res_1.ok && res_1.data != null) {
setRecommends(function (obj) {
var _a;
return ((0, tslib_1.__assign)((0, tslib_1.__assign)({}, obj), (_a = {}, _a[chatId] = res_1.data, _a)));
});
}
return [3 /*break*/, 4];
case 3: return [7 /*endfinally*/];
case 4: return [2 /*return*/];
}
});
});
};
var handleSend = function (e, value) { return (0, tslib_1.__awaiter)(void 0, void 0, void 0, function () {
var userId, robotId_1, userData_1, robotData_1, apiConfig, url, params, fetchUrl, res_2, _a, aiPagePanel_1, sasAiChat, conversationId_1, _b, aiPagePanel_2, sasAiChat_1, err_1;
return (0, tslib_1.__generator)(this, function (_c) {
switch (_c.label) {
case 0:
if (fetchLoading) {
e.preventDefault();
return [2 /*return*/];
}
;
if (!(value && (value === null || value === void 0 ? void 0 : value.trim().length) > 0)) return [3 /*break*/, 5];
userId = 'user_' + (0, utils_1.createRandomValue)();
robotId_1 = 'robot_' + (0, utils_1.createRandomValue)();
userData_1 = { id: userId, isUser: true, title: value };
robotData_1 = { id: robotId_1, isUser: false, title: '' };
setChatDatas(function (datas) { return datas.concat([userData_1, robotData_1]); });
setTimeout(function () {
requestAnimationFrame(function () {
setInputValue('');
scrollToBottom();
});
}, 100);
if (!serverApiObj.current) return [3 /*break*/, 5];
apiConfig = serverApiObj.current[isChatMode ? 'chatApi' : 'questionApi'];
url = apiConfig.url;
params = (0, tslib_1.__assign)({ question: value }, (isChatMode ? { conversationId: chatConversationId } : {}));
fetchUrl = "" + url + (!isChatMode ? generateSearchParam() : '');
_c.label = 1;
case 1:
_c.trys.push([1, 3, 4, 5]);
setFetchLoading(true);
return [4 /*yield*/, props.env.fetcher((0, tslib_1.__assign)((0, tslib_1.__assign)({}, apiConfig), { url: fetchUrl }), params)];
case 2:
res_2 = _c.sent();
if (res_2.ok && res_2.data != null) {
/** 如果是聊天模式,则直接显示answer */
if (isChatMode) {
_a = res_2.data, aiPagePanel_1 = _a.aiPagePanel, sasAiChat = _a.sasAiChat;
conversationId_1 = sasAiChat.conversationId;
setChatConversationId(conversationId_1);
setChatDatas(function (datas) { return datas.map(function (data) { return data.id == robotId_1 ? (0, tslib_1.__assign)((0, tslib_1.__assign)({}, data), { description: aiPagePanel_1 === null || aiPagePanel_1 === void 0 ? void 0 : aiPagePanel_1.body, id: conversationId_1 }) : data; }); });
}
else {
_b = res_2.data, aiPagePanel_2 = _b.aiPagePanel, sasAiChat_1 = _b.sasAiChat;
setChatDatas(function (datas) { return datas.map(function (data) { var _a; return data.id == robotId_1 ? (0, tslib_1.__assign)((0, tslib_1.__assign)({}, data), { description: aiPagePanel_2 === null || aiPagePanel_2 === void 0 ? void 0 : aiPagePanel_2.body, id: (_a = sasAiChat_1 === null || sasAiChat_1 === void 0 ? void 0 : sasAiChat_1.chatId) !== null && _a !== void 0 ? _a : data.id, question: value }) : data; }); });
handleGetRecommends((0, tslib_1.__assign)((0, tslib_1.__assign)({}, sasAiChat_1), { question: value }));
setChatID(undefined);
}
}
else {
setChatDatas(function (datas) { return datas.map(function (data) { return data.id == robotId_1 ? (0, tslib_1.__assign)((0, tslib_1.__assign)({}, data), { description: {
type: 'lion-tpl',
tpl: res_2.msg
} }) : data; }); });
}
return [3 /*break*/, 5];
case 3:
err_1 = _c.sent();
console.log('debug-networkerr', err_1);
return [3 /*break*/, 5];
case 4:
setFetchLoading(false);
return [7 /*endfinally*/];
case 5: return [2 /*return*/];
}
});
}); };
var genSendIconClassName = (0, react_1.useCallback)(function () {
return "icon-send " + ((inputValue === null || inputValue === void 0 ? void 0 : inputValue.length) && !fetchLoading ? '' : 'disabled');
}, [inputValue, fetchLoading]);
/** 评论AI的答复 */
var handleCommentItem = function (config) { return (0, tslib_1.__awaiter)(void 0, void 0, void 0, function () {
var chatId, commentType, params, res;
var _a;
return (0, tslib_1.__generator)(this, function (_b) {
switch (_b.label) {
case 0:
/** commentType: 0 点赞 1 点踩 */
if (commentLoading)
return [2 /*return*/];
chatId = config.chatId, commentType = config.commentType, params = (0, tslib_1.__rest)(config, ["chatId", "commentType"]);
_b.label = 1;
case 1:
_b.trys.push([1, , 3, 4]);
setCommentLoading(true);
return [4 /*yield*/, props.env.fetcher((_a = serverApiObj.current) === null || _a === void 0 ? void 0 : _a['commentApi'], (0, tslib_1.__assign)((0, tslib_1.__assign)({}, params), { pageId: props.pageId }))];
case 2:
res = _b.sent();
if (res.ok) {
setChatDatas(function (datas) { return datas.map(function (data) { return data.id === chatId ? (0, tslib_1.__assign)((0, tslib_1.__assign)({}, data), { commentType: "" + commentType }) : data; }); });
}
return [3 /*break*/, 4];
case 3:
setCommentLoading(false);
return [7 /*endfinally*/];
case 4: return [2 /*return*/];
}
});
}); };
/** 支持 shift + enter 插入换行 */
var handleBreakLine = function (e) {
if (!e.shiftKey && e.keyCode === 13) {
e.preventDefault();
handleSend(e, inputValue);
}
};
var commentTypeTextMap = {
0: '赞',
1: '踩'
};
var listRender = (0, react_1.useMemo)(function () {
return (react_1.default.createElement(antd_1.List, { className: 'chat-list', id: 'sf-chat-list', rowKey: 'id', dataSource: chatDatas, split: false, renderItem: function (data) {
var id = data.id, isUser = data.isUser, title = data.title, description = data.description, _a = data.question, question = _a === void 0 ? '' : _a, commentType = data.commentType;
return (react_1.default.createElement(antd_1.List.Item, { className: isUser ? 'item-user' : 'item-ai' },
react_1.default.createElement(antd_1.List.Item.Meta, { className: isUser ? 'meta-user' : 'meta-ai', style: { flexDirection: isUser ? 'row-reverse' : 'row' }, avatar: react_1.default.createElement(antd_1.Avatar, { shape: "square", size: 32, src: isUser ? undefined : './public/images/zhilong.png', icon: react_1.default.createElement("span", null, isUser ? userName.substring(0, 1) : 'AI') }), title: (title === null || title === void 0 ? void 0 : title.length) ? react_1.default.createElement("div", { className: 'description-box', id: id }, title) : null,
// title={false}
description: react_1.default.createElement("div", null,
!isUser ? description ? (react_1.default.createElement("div", null,
props.render((0, utils_1.createRandomValue)(), description, { aiQuery: props.data, onAiFinished: function () { scrollToBottom(); } }),
id.startsWith('robot_00') ? (react_1.default.createElement("div", { className: 'recommend-box-init' }, recommendRender(id))) : null)) : react_1.default.createElement("div", { className: 'description-box' },
react_1.default.createElement(antd_1.Spin, null)) : null,
react_1.default.createElement("div", { className: 'bottom-operate-box' }, !isUser && id && id !== 'robot_00' && description && !isChatMode && (react_1.default.createElement("div", { className: "ai-btn-groups " + (commentType ? 'checked' : '') },
commentType ? (react_1.default.createElement(react_1.default.Fragment, null,
react_1.default.createElement("div", { className: 'comment-btn' },
react_1.default.createElement(icons_3.LikeFilled, { style: { color: commentType === '0' ? '#fda71e' : '#999' }, rotate: commentType === '1' ? 180 : 0 }),
react_1.default.createElement("span", { className: 'text' }, commentTypeTextMap[commentType])))) : (react_1.default.createElement(react_1.default.Fragment, null,
react_1.default.createElement("div", { className: 'comment-btn like', onClick: function () { return handleCommentItem({ question: question, commentType: 0, chatId: id }); } },
react_1.default.createElement(icons_3.LikeOutlined, null),
" ",
react_1.default.createElement("span", { className: 'text' }, commentTypeTextMap[0])),
react_1.default.createElement("div", { className: 'comment-btn dislike', onClick: function () { return handleCommentItem({ question: question, commentType: 1, chatId: id }); } },
react_1.default.createElement(icons_3.LikeOutlined, { rotate: 180 }),
" ",
react_1.default.createElement("span", { className: 'text' }, commentTypeTextMap[1])))),
showChatID ? (react_1.default.createElement("div", { className: 'comment-btn', onClick: function () { return handleSetAIChatId(id); } },
react_1.default.createElement(icons_3.FormOutlined, null),
react_1.default.createElement("span", { className: 'text' }, "\u5F15\u7528"))) : null)))) }),
!isUser && !id.startsWith('robot_00') && (react_1.default.createElement(react_1.default.Fragment, null, recommendRender(id)))));
} }));
}, [chatDatas, commentLoading, recommends]);
var handleSendRecommend = function (e, question, id) {
setRecommends(function (obj) {
var _a;
return ((0, tslib_1.__assign)((0, tslib_1.__assign)({}, obj), (_a = {}, _a[id] = undefined, _a)));
});
handleSend(e, question);
};
var recommendRender = function (id) {
var _a;
if (id === void 0) { id = 'robot_00'; }
var render = (_a = recommends[id]) === null || _a === void 0 ? void 0 : _a.map(function (item) {
var _a = item.question, question = _a === void 0 ? '' : _a;
return (react_1.default.createElement("div", { className: "recommend-item", onClick: function (e) { return handleSendRecommend(e, question, id); } },
react_1.default.createElement("div", null, question),
react_1.default.createElement("div", { className: 'icon-box' },
react_1.default.createElement(icons_2.RightOutlined, { style: { color: 'rgba(0,0,0, 0.6', fontSize: '12px' } }))));
});
return (render === null || render === void 0 ? void 0 : render.length) ? (react_1.default.createElement("div", { className: 'recommend-box' }, render)) : null;
};
// 调试代码,引用某chatId
var handleSetAIChatId = function (id) {
setChatID(id);
};
return (react_1.default.createElement("div", { className: 'ai-tool-container' },
listRender,
react_1.default.createElement("div", { className: 'chat-footer' }, (0, helper_1.isMobile)() ? (react_1.default.createElement("div", { className: "footer-box" },
react_1.default.createElement("div", { className: "icon-prefix-box" },
react_1.default.createElement(icons_1.Icon, { icon: "#icon-toolailoong", className: "icon-send-prefix", symbol: true })),
react_1.default.createElement(antd_1.Input.TextArea, { bordered: false, className: 'word-inp', autoSize: { minRows: 1, maxRows: 3 }, placeholder: 'Enter\u53D1\u9001', value: inputValue, onFocus: scrollToBottom,
// allowClear
// onPressEnter={(e) => { handleSend(e, inputValue) }}
onChange: function (e) { return setInputValue(e.target.value); } }),
react_1.default.createElement(antd_1.Button, { type: 'link', className: genSendIconClassName(), onClick: function (e) { handleSend(e, inputValue); } },
react_1.default.createElement(icons_3.SendOutlined, null)))) : (react_1.default.createElement("div", { className: "footer-box" },
react_1.default.createElement(antd_1.Input.TextArea, { className: 'word-inp', autoSize: { minRows: 3, maxRows: 4 }, bordered: false,
// style={{ height: 32, border: 'none', }}
placeholder: '\u6309Enter\u53D1\u9001\u3001Shift + Enter\u6362\u884C', value: inputValue, onKeyDown: handleBreakLine, onChange: function (e) { return setInputValue(e.target.value); }, allowClear: true }),
react_1.default.createElement("div", { className: "bottom-box" },
react_1.default.createElement("div", null, aiChatID ? (react_1.default.createElement(react_1.default.Fragment, null,
"\u5F53\u524D\u5F15\u7528\uFF1A ",
aiChatID)) : null),
react_1.default.createElement(antd_1.Button, { type: 'link', className: genSendIconClassName(), onClick: function (e) { handleSend(e, inputValue); } },
react_1.default.createElement(icons_3.SendOutlined, null))))))));
};
exports.default = (function (props) {
var _a, _b;
var action = props.action, onClose = props.onClose;
var _c = (0, react_1.useState)(false), open = _c[0], setOpen = _c[1];
var _d = (0, react_1.useState)(true), hide = _d[0], setHide = _d[1];
var _e = (0, react_1.useState)(false), showFixModal = _e[0], setShowFixModal = _e[1];
var _f = (0, react_1.useState)('智龙助理'), title = _f[0], setTitle = _f[1];
var _g = (0, react_1.useState)(false), isChatMode = _g[0], setIsChatMode = _g[1];
var updateTitle = function (titleText) {
var newTitle = (react_1.default.createElement(react_1.default.Fragment, null,
react_1.default.createElement("div", { className: 'table-icon-box' },
react_1.default.createElement(icons_1.Icon, { icon: "#icon-toolailoong", className: "icon", symbol: true })),
react_1.default.createElement("span", { className: 'title-text' }, titleText)));
setTitle(newTitle);
};
return (react_1.default.createElement(react_1.default.Fragment, null, !(0, helper_1.isMobile)() ? (react_1.default.createElement(react_1.default.Fragment, null,
react_1.default.createElement(components_1.Button, { onClick: function () {
open && setShowFixModal(open);
setOpen(true);
hide && setHide(false);
requestAnimationFrame(function () {
setShowFixModal(false);
});
} },
react_1.default.createElement(icons_1.Icon, { icon: "#icon-toolailoong", className: "icon", symbol: true }), action === null || action === void 0 ? void 0 :
action.label),
open && react_1.default.createElement(DragModal_1.default, { className: 'ai-tool-drawer', width: 500, minWidth: 400, minHeight: 500, setFixRight: false, dialogVisible: open, mask: false, showMinTitle: true, title: title, resizeable: true, centered: true, canClickBelowDom: true, setMaxSize: true, forceCalcOnResize: true, pinRight: true, hide: hide, onHide: function () { setHide((true)); }, onShow: function () { setHide(false); setOpen(true); }, onCancel: function () { setHide(false); setOpen(false); }, bodyStyle: { padding: 0, height: 'calc(100vh - 200px)' }, maskClosable: false, footer: null, keyboard: false, fullHeightOnInit: true,
// cacheConfigKey="MODAL_AI_TOOL_CONFIG"
miniTitleWrapperClassName: "aitool-dialog-wrapper", getContainer: ((_a = props.env.container) !== null && _a !== void 0 ? _a : props.env.getModalContainer), forceShowFixModal: showFixModal, hiddenBtn: react_1.default.createElement(icons_1.Icon, { icon: "#icon-toolailoong", className: "ai-hidden-btn", symbol: true }) },
react_1.default.createElement(Ai, (0, tslib_1.__assign)({}, props, { onTitleChange: updateTitle }))))) : (react_1.default.createElement(react_1.default.Fragment, null,
open ? (react_1.default.createElement(antd_1.Drawer, { placement: 'top', mask: true, width: '100vw', height: '100vh', getContainer: ((_b = props.env.container) !== null && _b !== void 0 ? _b : props.env.getModalContainer), open: open, className: "ai-tool-drawer", title: title,
// extra={
// <div className='chat-mode-box'>
// <Switch className='chat-mode-switch' checked={isChatMode} onChange={setIsChatMode} checkedChildren="聊天" unCheckedChildren="查询" />
// </div>
// }
onClose: function () { setOpen(false); onClose === null || onClose === void 0 ? void 0 : onClose(); } },
react_1.default.createElement("div", { className: "ai-tool-mobile-wrapper" },
react_1.default.createElement(Ai, (0, tslib_1.__assign)({}, props, { onTitleChange: updateTitle, isChatMode: isChatMode }))))) : null,
react_1.default.createElement("div", { className: 'toolbar-item', onClick: function () { return setOpen(true); } },
react_1.default.createElement("div", { className: 'toolbar-item-icon' },
react_1.default.createElement(icons_1.Icon, { icon: action === null || action === void 0 ? void 0 : action.icon })),
react_1.default.createElement("div", { className: 'toolbar-item-name' }, action === null || action === void 0 ? void 0 : action.label))))));
});
//# sourceMappingURL=./renderers/Table/AiTool/index.js.map