UNPKG

fastlion-amis

Version:

一种MIS页面生成工具

344 lines (343 loc) 25.6 kB
"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