[feature](webapp) add script command to accommodate different Node.js versions and change lerna + npm to pnpm workspaces (#61)

This commit is contained in:
williamhliu
2023-09-07 21:29:13 +08:00
committed by GitHub
parent 898108d7e1
commit 90f6a20516
26 changed files with 332 additions and 149 deletions

1
webapp/.gitignore vendored
View File

@@ -19,6 +19,7 @@ supersonic-webapp.tar.gz
package-lock.json
yarn.lock
pnpm-lock.yaml
# misc
.DS_Store

View File

@@ -1,6 +0,0 @@
{
"packages": [
"packages/*"
],
"version": "independent"
}

View File

@@ -1,7 +0,0 @@
{
"name": "root",
"private": true,
"devDependencies": {
"lerna": "^4.0.0"
}
}

View File

@@ -13,6 +13,8 @@
/dist
pnpm-lock.yaml
# misc
.DS_Store
.env.local

View File

@@ -1,6 +1,6 @@
{
"name": "supersonic-chat-sdk",
"version": "0.5.28",
"version": "0.0.0",
"main": "dist/index.es.js",
"module": "dist/index.es.js",
"unpkg": "dist/index.umd.js",
@@ -11,6 +11,7 @@
"axios": "^1.4.0",
"classnames": "^2.3.2",
"echarts": "^5.4.2",
"lodash": "^4.17.11",
"moment": "^2.29.4",
"react-spinners": "^0.13.8",
"tslib": "^2.5.2"
@@ -115,6 +116,7 @@
"react-refresh": "^0.11.0",
"resolve": "^1.20.0",
"resolve-url-loader": "^4.0.0",
"rimraf": "^5.0.1",
"rollup": "^3.22.1",
"rollup-plugin-exclude-dependencies-from-bundle": "^1.1.23",
"rollup-plugin-less": "^1.1.3",

View File

@@ -62,6 +62,9 @@ const ExecuteItem: React.FC<Props> = ({
</div>
<div className={`${prefixCls}-content-container ${prefixCls}-last-node`}>
<Spin spinning={entitySwitchLoading}>
{data.queryAuthorization?.message && (
<div className={`${prefixCls}-auth-tip`}>{data.queryAuthorization.message}</div>
)}
{data?.queryMode === 'WEB_PAGE' ? (
<WebPage id={queryId!} data={data} />
) : (

View File

@@ -31,7 +31,7 @@ const FilterItem: React.FC<Props> = ({ modelId, filters, filter, onFiltersChange
};
useEffect(() => {
if (typeof filter.value === 'string' && options.length === 0) {
if ((typeof filter.value === 'string' || isArray(filter.value)) && options.length === 0) {
initData();
}
}, []);

View File

@@ -228,10 +228,14 @@ const ParseTip: React.FC<Props> = ({
const entityDimensions = entityInfo?.dimensions?.filter(
item =>
!['zyqk_song_id', 'song_name', 'singer_id'].includes(item.bizName) &&
!['zyqk_song_id', 'song_name', 'singer_id', 'zyqk_cmpny_id'].includes(item.bizName) &&
!(
entityInfo?.dimensions?.some(dimension => dimension.bizName === 'singer_id') &&
item.bizName === 'singer_name'
) &&
!(
entityInfo?.dimensions?.some(dimension => dimension.bizName === 'zyqk_cmpny_id') &&
item.bizName === 'cmpny_name'
)
);

View File

@@ -113,6 +113,13 @@
padding-bottom: 10px;
}
&-auth-tip {
font-size: 13px;
color: var(--text-color-secondary);
margin-bottom: 12px;
line-height: 20px;
}
&-switch-entity-tip {
display: flex;
align-items: center;

View File

@@ -0,0 +1,98 @@
import { useEffect, useState } from 'react';
import { UpOutlined, DownOutlined } from '@ant-design/icons';
import { CLS_PREFIX } from '../../../common/constants';
import { ColumnType } from '../../../common/type';
type Props = {
columns: ColumnType[];
referenceColumn?: ColumnType;
dataSource: any[];
};
const Text: React.FC<Props> = ({ columns, referenceColumn, dataSource }) => {
const [text, setText] = useState<string>();
const [htmlCode, setHtmlCode] = useState<string>();
const [referenceExpanded, setRederenceExpanded] = useState(false);
const [referenceData, setReferenceData] = useState<any[]>([]);
const prefixCls = `${CLS_PREFIX}-text`;
const initData = () => {
let textValue = dataSource[0][columns[0].nameEn];
let htmlCodeValue: string;
const match = textValue.match(/```html([\s\S]*?)```/);
htmlCodeValue = match && match[1].trim();
if (htmlCodeValue) {
textValue = textValue.replace(/```html([\s\S]*?)```/, '');
}
let scriptCode: string;
let scriptSrc: string;
if (htmlCodeValue) {
scriptSrc = htmlCodeValue.match(/<script src="([\s\S]*?)"><\/script>/)?.[1] || '';
scriptCode =
htmlCodeValue.match(/<script type="text\/javascript">([\s\S]*?)<\/script>/)?.[1] || '';
if (scriptSrc) {
const script = document.createElement('script');
script.src = scriptSrc;
document.body.appendChild(script);
}
if (scriptCode) {
const script = document.createElement('script');
script.innerHTML = scriptCode;
setTimeout(() => {
document.body.appendChild(script);
}, 1500);
}
}
setText(textValue);
setHtmlCode(htmlCodeValue);
if (referenceColumn) {
const referenceDataValue = dataSource[0][referenceColumn.nameEn];
setReferenceData(referenceDataValue || []);
}
};
useEffect(() => {
initData();
}, []);
const onToggleMore = () => {
setRederenceExpanded(!referenceExpanded);
};
return (
<div
style={{
lineHeight: '24px',
width: 'fit-content',
maxWidth: '100%',
overflowX: 'hidden',
}}
>
{htmlCode ? <pre>{text}</pre> : text}
{referenceData.length > 0 && (
<span className={`${prefixCls}-check-more`} onClick={onToggleMore}>
{referenceExpanded ? '收起' : '查看'}
{referenceExpanded ? (
<UpOutlined className={`${prefixCls}-arrow-icon`} />
) : (
<DownOutlined className={`${prefixCls}-arrow-icon`} />
)}
</span>
)}
{referenceData.length > 0 && referenceExpanded && (
<div className={`${prefixCls}-reference-data`}>
{referenceData.map(item => (
<div className={`${prefixCls}-reference-item`} key={item.doc_title}>
<div className={`${prefixCls}-reference-item-title`}>{item.doc_title}</div>
<div className={`${prefixCls}-reference-item-value`}>{item.doc_chunk}</div>
</div>
))}
</div>
)}
{!!htmlCode && <div dangerouslySetInnerHTML={{ __html: htmlCode }} />}
</div>
);
};
export default Text;

View File

@@ -0,0 +1,38 @@
@import '../../../styles/index.less';
@text-prefix-cls: ~'@{supersonic-chat-prefix}-text';
.@{text-prefix-cls} {
&-check-more {
margin-left: 12px;
font-size: 13px;
color: var(--chat-blue);
cursor: pointer;
}
&-arrow-icon {
margin-left: 2px;
font-size: 12px;
}
&-reference-data {
display: flex;
flex-direction: column;
row-gap: 10px;
margin-top: 10px;
}
&-reference-item {
font-size: 13px;
}
&-reference-item-title {
color: var(--text-color);
font-weight: 500;
}
&-reference-item-value {
color: var(--text-color-secondary);
margin-top: 4px;
}
}

View File

@@ -7,6 +7,7 @@ import { useEffect, useState } from 'react';
import { queryData } from '../../service';
import classNames from 'classnames';
import { PREFIX_CLS } from '../../common/constants';
import Text from './Text';
type Props = {
data: MsgDataType;
@@ -17,7 +18,8 @@ type Props = {
const ChatMsg: React.FC<Props> = ({ data, chartIndex, triggerResize }) => {
const { queryColumns, queryResults, chatContext, queryMode } = data;
const [columns, setColumns] = useState<ColumnType[]>(queryColumns);
const [columns, setColumns] = useState<ColumnType[]>();
const [referenceColumn, setReferenceColumn] = useState<ColumnType>();
const [dataSource, setDataSource] = useState<any[]>(queryResults);
const [drillDownDimension, setDrillDownDimension] = useState<DrillDownDimensionType>();
@@ -25,12 +27,18 @@ const ChatMsg: React.FC<Props> = ({ data, chartIndex, triggerResize }) => {
const prefixCls = `${PREFIX_CLS}-chat-msg`;
const updateColummns = (queryColumnsValue: ColumnType[]) => {
const referenceColumn = queryColumnsValue.find(item => item.showType === 'more');
setReferenceColumn(referenceColumn);
setColumns(queryColumnsValue.filter(item => item.showType !== 'more'));
};
useEffect(() => {
setColumns(queryColumns);
updateColummns(queryColumns);
setDataSource(queryResults);
}, [queryColumns, queryResults]);
if (!queryColumns || !queryResults) {
if (!queryColumns || !queryResults || !columns) {
return null;
}
@@ -69,7 +77,7 @@ const ChatMsg: React.FC<Props> = ({ data, chartIndex, triggerResize }) => {
});
setLoading(false);
if (data.code === 200) {
setColumns(data.data?.queryColumns || []);
updateColummns(data.data?.queryColumns || []);
setDataSource(data.data?.queryResults || []);
}
};
@@ -82,51 +90,9 @@ const ChatMsg: React.FC<Props> = ({ data, chartIndex, triggerResize }) => {
});
};
const getTextContent = () => {
let text = dataSource[0][columns[0].nameEn];
let htmlCode: string;
const match = text.match(/```html([\s\S]*?)```/);
htmlCode = match && match[1].trim();
if (htmlCode) {
text = text.replace(/```html([\s\S]*?)```/, '');
}
let scriptCode: string;
let scriptSrc: string;
if (htmlCode) {
scriptSrc = htmlCode.match(/<script src="([\s\S]*?)"><\/script>/)?.[1] || '';
scriptCode =
htmlCode.match(/<script type="text\/javascript">([\s\S]*?)<\/script>/)?.[1] || '';
if (scriptSrc) {
const script = document.createElement('script');
script.src = scriptSrc;
document.body.appendChild(script);
}
if (scriptCode) {
const script = document.createElement('script');
script.innerHTML = scriptCode;
setTimeout(() => {
document.body.appendChild(script);
}, 1500);
}
}
return (
<div
style={{
lineHeight: '24px',
width: 'fit-content',
maxWidth: '100%',
overflowX: 'hidden',
}}
>
{htmlCode ? <pre>{text}</pre> : text}
{!!htmlCode && <div dangerouslySetInnerHTML={{ __html: htmlCode }} />}
</div>
);
};
const getMsgContent = () => {
if (isText) {
return getTextContent();
return <Text columns={columns} referenceColumn={referenceColumn} dataSource={dataSource} />;
}
if (isMetricCard) {
return (
@@ -168,7 +134,11 @@ const ChatMsg: React.FC<Props> = ({ data, chartIndex, triggerResize }) => {
const chartMsgClass = classNames({ [prefixCls]: !isTable });
return <div className={chartMsgClass}>{getMsgContent()}</div>;
return (
<div className={chartMsgClass}>
{dataSource?.length === 0 ? <div></div> : getMsgContent()}
</div>
);
};
export default ChatMsg;

View File

@@ -3,7 +3,7 @@
@chat-msg-prefix-cls: ~'@{supersonic-chat-prefix}-chat-msg';
.@{chat-msg-prefix-cls} {
padding: 6px 14px 12px;
padding: 6px 14px 8px;
border: 1px solid var(--border-color-base);
border-radius: 4px;
background: #f5f8fb;

View File

@@ -22,6 +22,8 @@
@import "../components/ChatMsg/FilterSection/style.less";
@import "../components/ChatMsg/Text/style.less";
@import '../components/ChatItem/style.less';
@import "../components/Tools/style.less";

View File

@@ -20,6 +20,7 @@ yarn-error.log
.idea
yarn.lock
package-lock.json
pnpm-lock.yaml
*bak
.vscode

View File

@@ -1,15 +0,0 @@
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const commitId = execSync('git rev-parse HEAD').toString().trim();
const file = path.resolve(__dirname, './public/version.js');
const data = {
commitId: commitId,
updateTime: new Date().toString(),
};
const feVersion = JSON.stringify(data, null, 4);
// 异步写入数据到文件
fs.writeFile(file, `feVersion=${feVersion}`, { encoding: 'utf8' }, (err) => {});
console.log(`成功写入版本文件,版本信息为${feVersion}`);

View File

@@ -1,19 +0,0 @@
#!/bin/bash
npm i
if [ $? -ne 0 ]; then
echo "npm i failed"
exit 1
fi
npm run build:inner
if [ $? -ne 0 ]; then
echo "build failed"
exit 1
fi
rm -rf dist.zip
zip -r dist.zip ./dist/
mkdir -p bin
mv dist.zip bin/
tar czf dist.tar.gz bin/dist.zip

View File

@@ -1,19 +0,0 @@
#!/bin/bash
npm i
if [ $? -ne 0 ]; then
echo "npm i failed"
exit 1
fi
npm run build:inner
if [ $? -ne 0 ]; then
echo "build failed"
exit 1
fi
rm -rf dist.zip
zip -r dist.zip ./dist/
mkdir -p bin
mv dist.zip bin/
tar czf dist.tar.gz bin/dist.zip

View File

@@ -11,7 +11,7 @@ const { REACT_APP_ENV, RUN_TYPE } = process.env;
export default defineConfig({
webpack5: {},
mfsu: {},
mfsu: false,
define: {
// 添加这个自定义的环境变量
// 'process.env.REACT_APP_ENV': process.env.REACT_APP_ENV, // * REACT_APP_ENV 本地开发环境dev测试服test正式服prod

View File

@@ -6,10 +6,10 @@
"scripts": {
"analyze": "cross-env ANALYZE=1 umi build",
"build": "npm run build:os",
"build:os": "node .writeVersion.js && cross-env REACT_APP_ENV=prod APP_TARGET=opensource umi build",
"build:os-local": "node .writeVersion.js && cross-env REACT_APP_ENV=prod APP_TARGET=opensource RUN_TYPE=local umi build",
"build:inner": "node .writeVersion.js && cross-env REACT_APP_ENV=prod APP_TARGET=inner umi build",
"build:test": "node .writeVersion.js && cross-env REACT_APP_ENV=test umi build",
"build:os": "cross-env REACT_APP_ENV=prod APP_TARGET=opensource umi build",
"build:os-local": "cross-env REACT_APP_ENV=prod APP_TARGET=opensource RUN_TYPE=local umi build",
"build:inner": "cross-env REACT_APP_ENV=prod APP_TARGET=inner umi build",
"build:test": "cross-env REACT_APP_ENV=test umi build",
"deploy": "npm run site && npm run gh-pages",
"dev": "npm run start:osdev",
"dev:os": "npm run start:osdev",
@@ -61,7 +61,9 @@
"@ant-design/pro-form": "^1.23.0",
"@ant-design/pro-layout": "^6.38.22",
"@ant-design/pro-table": "^2.80.6",
"@antv/dom-util": "^2.0.4",
"@antv/g6": "^4.8.14",
"@antv/g6-core": "^0.8.21",
"@antv/layout": "^0.3.20",
"@antv/xflow": "^1.0.55",
"@babel/runtime": "^7.22.5",
@@ -96,7 +98,7 @@
"react-split-pane": "^2.0.3",
"react-syntax-highlighter": "^15.4.3",
"sql-formatter": "^2.3.3",
"supersonic-chat-sdk": "^0.5.28",
"supersonic-chat-sdk": "^0.5.29",
"umi": "3.5",
"umi-request": "^1.0.8"
},
@@ -139,7 +141,7 @@
"typescript": "^4.0.3"
},
"engines": {
"node": ">=10.0.0 <17.0.0"
"node": ">=16.0.0 <20.0.0"
},
"resolutions": {
"@types/react": "17.0.0"

View File

@@ -20,7 +20,8 @@
"strict": true,
"paths": {
"@/*": ["./src/*"],
"@@/*": ["./src/.umi/*"]
"@@/*": ["./src/.umi/*"],
"react": [ "./node_modules/@types/react" ]
}
},
"include": [

View File

@@ -0,0 +1,4 @@
prefer-workspace-packages: true
packages:
- 'packages/*'
- 'apps/*'

View File

@@ -1,13 +1,45 @@
@echo off
:: 获取Node.js版本
for /f "delims=" %%i in ('node -v') do set "node_version=%%i"
:: 提取主版本号
for /f "tokens=2 delims=v." %%i in ("%node_version%") do set "major_version=%%i"
if %major_version% GEQ 17 (
set "NODE_OPTIONS=--openssl-legacy-provider"
echo Node.js版本大于等于17已设置NODE_OPTIONS为--openssl-legacy-provider
)
:: 检查pnpm是否未安装
where /q pnpm
if errorlevel 1 (
echo pnpm未安装正在进行安装...
npm install -g pnpm
if errorlevel 1 (
echo pnpm安装失败请检查npm是否已安装并且网络连接正常
) else (
echo pnpm安装成功
)
) else (
echo pnpm已安装
)
rmdir /s /q ".\packages\supersonic-fe\src\.umi"
rmdir /s /q ".\packages\supersonic-fe\src\.umi-production"
call npm i
cd ./packages/chat-sdk
call npx lerna add supersonic-chat-sdk --scope supersonic-fe
call pnpm i
call npx lerna bootstrap
call pnpm run build
call npx lerna exec --scope supersonic-chat-sdk npm run build
call pnpm link --global
call npx lerna exec --scope supersonic-fe npm start
cd ../supersonic-fe
call pnpm link ../chat-sdk
call pnpm i
call pnpm start

View File

@@ -1,11 +1,31 @@
#!/bin/bash
node_version=$(node -v)
major_version=$(echo $node_version | cut -d'.' -f1 | tr -d 'v')
if [ $major_version -ge 17 ]; then
export NODE_OPTIONS=--openssl-legacy-provider
fi
if ! command -v pnpm >/dev/null 2>&1; then
npm i -g pnpm
fi
rm -rf ./packages/supersonic-fe/src/.umi ./packages/supersonic-fe/src/.umi-production
npm i
cd ./packages/chat-sdk
npx lerna add supersonic-chat-sdk --scope supersonic-fe
pnpm i
npx lerna bootstrap
pnpm run build
npx lerna exec --scope supersonic-chat-sdk npm run build
pnpm link --global
npx lerna exec --scope supersonic-fe npm start
cd ../supersonic-fe
pnpm link ../chat-sdk
pnpm i
pnpm start

View File

@@ -1,17 +1,53 @@
setlocal
@echo off
call npm i
:: 获取Node.js版本
for /f "delims=" %%i in ('node -v') do set "node_version=%%i"
call npx lerna add supersonic-chat-sdk --scope supersonic-fe
:: 提取主版本号
for /f "tokens=2 delims=v." %%i in ("%node_version%") do set "major_version=%%i"
call npx lerna bootstrap
if %major_version% GEQ 17 (
set "NODE_OPTIONS=--openssl-legacy-provider"
echo Node.js版本大于等于17已设置NODE_OPTIONS为--openssl-legacy-provider
)
call npx lerna exec --scope supersonic-chat-sdk npm run build
:: 检查pnpm是否未安装
where /q pnpm
if errorlevel 1 (
echo pnpm未安装正在进行安装...
npm install -g pnpm
if errorlevel 1 (
echo pnpm安装失败请检查npm是否已安装并且网络连接正常
) else (
echo pnpm安装成功
)
) else (
echo pnpm已安装
)
call npx lerna exec --scope supersonic-fe npm run build:os-local
del /F /Q supersonic-webapp.tar.gz
cd packages\supersonic-fe
rmdir /S /Q .\packages\supersonic-fe\src\.umi
rmdir /S /Q .\packages\supersonic-fe\src\.umi-production
cd ./packages/chat-sdk
call pnpm i
call pnpm run build
call pnpm link --global
cd ../supersonic-fe
call pnpm link ../chat-sdk
call pnpm i
call pnpm run build:os-local
tar -zcvf supersonic-webapp.tar.gz supersonic-webapp

View File

@@ -1,21 +1,47 @@
#!/bin/bash
start=$(date +%s)
node_version=$(node -v)
major_version=$(echo $node_version | cut -d'.' -f1 | tr -d 'v')
if [ $major_version -ge 17 ]; then
export NODE_OPTIONS=--openssl-legacy-provider
fi
if ! command -v pnpm >/dev/null 2>&1; then
npm i -g pnpm
fi
rm -rf supersonic-webapp.tar.gz
rm -rf ./packages/supersonic-fe/src/.umi ./packages/supersonic-fe/src/.umi-production
npm i
cd ./packages/chat-sdk
npx lerna add supersonic-chat-sdk --scope supersonic-fe
pnpm i
npx lerna bootstrap
pnpm run build
npx lerna exec --scope supersonic-chat-sdk npm run build
pnpm link --global
npx lerna exec --scope supersonic-fe npm run build:os-local
cd ../supersonic-fe
cd ./packages/supersonic-fe
pnpm link ../chat-sdk
pnpm i
pnpm run build:os-local
tar -zcvf supersonic-webapp.tar.gz ./supersonic-webapp
mv supersonic-webapp.tar.gz ../../
cd ../../
end=$(date +%s)
take=$(( end - start ))
echo Time taken to execute commands is ${take} seconds.