This commit is contained in:
熊潇 2025-01-03 05:44:12 +00:00
parent 9d8db1a559
commit 5b1b73fae5
12 changed files with 3848 additions and 447 deletions

View File

@ -24,6 +24,6 @@
<body> <body>
<div id="ai-root"></div> <div id="ai-root"></div>
</body> </body>
<script src="./src/main.ts" type="module"></script> <script src="./src/main.tsx" type="module"></script>
</html> </html>

2084
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -15,16 +15,25 @@
"license": "MIT", "license": "MIT",
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0",
"@kevisual/query": "0.0.7-alpha.3", "@kevisual/query": "0.0.7-alpha.3",
"@kevisual/system-ui": "^0.0.3",
"@mui/material": "^6.3.0",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"lodash-es": "^4.17.21" "lodash-es": "^4.17.21",
"react-dom": "^19.0.0",
"zustand": "^5.0.2"
}, },
"devDependencies": { "devDependencies": {
"@emotion/css": "^11.13.5",
"@kevisual/router": "0.0.6-alpha-4", "@kevisual/router": "0.0.6-alpha-4",
"@kevisual/store": "0.0.1-alpha.9", "@kevisual/store": "0.0.1-alpha.9",
"@kevisual/types": "^0.0.5", "@kevisual/types": "^0.0.5",
"@types/react": "^19.0.2", "@types/react": "^19.0.2",
"@types/react-dom": "^19.0.2",
"@vitejs/plugin-basic-ssl": "^1.2.0", "@vitejs/plugin-basic-ssl": "^1.2.0",
"@vitejs/plugin-react": "^4.3.4",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"react": "^19.0.0", "react": "^19.0.0",
"vite": "^6.0.6" "vite": "^6.0.6"

1921
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

10
src/ReactApp.tsx Normal file
View File

@ -0,0 +1,10 @@
import { createRoot } from 'react-dom/client';
export const App = () => {
return (
<div className='flex justify-center items-center h-screen bg-gray-200'>
<h1 className='text-4xl font-bold text-gray-800'>Hello Vite + React!</h1>
</div>
);
};
createRoot(document.getElementById('root')!).render(<App />);

44
src/app/List.tsx Normal file
View File

@ -0,0 +1,44 @@
import { useStore } from '@/store/app';
import { useEffect } from 'react';
import { css } from '@emotion/css';
const containerStyle = css`
padding: 20px;
display: flex;
`;
const itemStyle = css`
display: flex;
min-width: 240px;
flex-direction: column;
padding: 20px;
margin-bottom: 20px;
border: 1px solid #ccc;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
background-color: #fff;
`;
export const List = () => {
const store = useStore();
useEffect(() => {
store.init();
}, []);
return (
<div className={containerStyle}>
<div>
{store.list.map((item) => {
return (
<div className={itemStyle} key={item.key}>
<span>{item.key}</span>
<span>{item.description}</span>
<span>{item.status}</span>
<span>{item.type}</span>
<span>{item.version}</span>
</div>
);
})}
</div>
</div>
);
};

View File

@ -1,10 +1,15 @@
import { useContextKey } from '@kevisual/store/config'; import { useContextKey } from '@kevisual/store/config';
import { Page } from '@kevisual/store/page'; import { Page } from '@kevisual/store/page';
import { QueryRouterServer } from '@kevisual/router'; import { QueryRouterServer } from '@kevisual/router';
import { createRoot } from 'react-dom/client';
import { List } from './app/List';
export const render = ({ renderRoot }) => { export const render = ({ renderRoot }) => {
renderRoot.innerHTML = ` // renderRoot.innerHTML = `
<h1>Hello, World!</h1> // <h1>Hello, World!</h1>
`; // `;
const root = createRoot(renderRoot);
// @ts-ignore
root.render(<List />);
}; };
const page = useContextKey('page', () => { const page = useContextKey('page', () => {
@ -46,5 +51,6 @@ if (app) {
render({ render({
renderRoot, renderRoot,
}); });
}).addTo(app); })
.addTo(app);
} }

3
src/modules/message.ts Normal file
View File

@ -0,0 +1,3 @@
import { message } from '@kevisual/system-ui/dist/message';
export { message };

86
src/store/app.ts Normal file
View File

@ -0,0 +1,86 @@
import { create } from 'zustand';
import { query } from '@/modules/query';
type Store = {
list: any[];
setList: (list: any[]) => void;
data: any;
setData: (data: any) => void;
loading: boolean;
setLoading: (loading: boolean) => void;
formData: any;
setFormData: (data: any) => void;
getList: () => Promise<any>;
init: () => Promise<void>;
getData: (id: number) => Promise<any>;
updateData: (data: any, opts?: { refresh?: boolean }) => Promise<any>;
deleteData: (id: number, opts?: { refresh?: boolean }) => Promise<any>;
};
export const useStore = create<Store>((set, get) => ({
list: [],
setList: (list) => set({ list }),
data: null,
setData: (data) => set({ data }),
loading: false,
setLoading: (loading) => set({ loading }),
formData: null,
setFormData: (formData) => set({ formData }),
getList: async () => {
set({ loading: true });
const res = await query.post({ path: 'local-apps', key: 'list' });
set({ loading: false });
if (res.code === 200) {
set({ list: res.data });
}
return res;
},
init: async () => {
await get().getList();
},
getData: async (id) => {
set({ loading: true });
const res = await query.post({
path: 'local-apps',
key: 'get',
id,
});
set({ loading: false });
if (res.code === 200) {
const data = res.data;
set({ data });
}
return res;
},
updateData: async (data, opts = { refresh: true }) => {
set({ loading: true });
const res = await query.post({
path: 'local-apps',
key: 'update',
data,
});
set({ loading: false });
if (res.code === 200) {
set({ data: res.data });
}
if (opts.refresh) {
await get().getList();
}
return res;
},
deleteData: async (id, opts = { refresh: true }) => {
set({ loading: true });
const res = await query.post({
path: 'local-apps',
key: 'delete',
id,
});
set({ loading: false });
if (res.code === 200) {
set({ data: null });
}
if (opts.refresh) {
await get().getList();
}
return res;
},
}));

54
src/store/operate.ts Normal file
View File

@ -0,0 +1,54 @@
import { create } from 'zustand';
import { query } from '@/modules/query';
import { message } from '@/modules/message';
interface OperateStore {
updateStatus: () => Promise<void>;
detect: () => Promise<void>;
download: () => Promise<void>;
/**
*
*/
upload: () => Promise<void>;
unload: () => Promise<void>;
deploy: () => Promise<void>;
}
export const useOperateStore = create<OperateStore>((set) => ({
updateStatus: async () => {
const res = await query.post({
path: 'local-apps',
key: 'updateStatus',
});
},
detect: async () => {
const res = await query.post({
path: 'local-apps',
key: 'detect',
});
},
download: async () => {
const res = await query.post({
path: 'local-apps',
key: 'download',
});
},
upload: async () => {
const res = await query.post({
path: 'micro-apps',
key: 'upload',
});
},
unload: async () => {
const res = await query.post({
path: 'micro-apps',
key: 'unload',
});
},
deploy: async () => {
const res = await query.post({
path: 'micro-apps',
key: 'deploy',
});
},
}));

View File

@ -16,8 +16,8 @@
"isolatedModules": true, "isolatedModules": true,
"moduleDetection": "force", "moduleDetection": "force",
"noEmit": true, "noEmit": true,
"jsxFragmentFactory": "Fragment", // "jsxFragmentFactory": "Fragment",
"jsxFactory": "h", // "jsxFactory": "h",
"baseUrl": "./", "baseUrl": "./",
"typeRoots": [ "typeRoots": [
"node_modules/@types", "node_modules/@types",

View File

@ -1,4 +1,5 @@
import { defineConfig } from 'vite'; import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react'
// import basicSsl from '@vitejs/plugin-basic-ssl'; // import basicSsl from '@vitejs/plugin-basic-ssl';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import path from 'path'; import path from 'path';
@ -8,6 +9,7 @@ const BUILD_TIME = dayjs().format('YYYY-MM-DD HH:mm:ss');
console.log('process', isDev, process.env.WEB_DEV) console.log('process', isDev, process.env.WEB_DEV)
export default defineConfig({ export default defineConfig({
// plugins: [basicSsl()], // plugins: [basicSsl()],
plugins: [react()],
resolve: { resolve: {
alias: { alias: {
'@': path.resolve(__dirname, './src'), '@': path.resolve(__dirname, './src'),
@ -18,7 +20,7 @@ export default defineConfig({
BUILD_TIME: JSON.stringify(BUILD_TIME), BUILD_TIME: JSON.stringify(BUILD_TIME),
}, },
optimizeDeps: { optimizeDeps: {
exclude: ['react'], // 排除 react 和 react-dom 以避免打包 // exclude: ['react'], // 排除 react 和 react-dom 以避免打包
}, },
// esbuild: { // esbuild: {
// jsxFactory: 'h', // jsxFactory: 'h',