temp
This commit is contained in:
parent
51733f3f2e
commit
2bc8822f60
@ -25,7 +25,7 @@ export default defineConfig({
|
|||||||
// ...
|
// ...
|
||||||
site: 'https://www.kevisual.cn/',
|
site: 'https://www.kevisual.cn/',
|
||||||
// base: isDev ? undefined : pkgs.basename,
|
// base: isDev ? undefined : pkgs.basename,
|
||||||
base: './',
|
base: isDev ? undefined : './',
|
||||||
integrations: [
|
integrations: [
|
||||||
mdx(),
|
mdx(),
|
||||||
react(), //
|
react(), //
|
||||||
|
@ -1,54 +1,21 @@
|
|||||||
import { Mail, Phone, MapPin, Book, Globe, Brain, Save } from 'lucide-react';
|
import { Mail, Phone, MapPin, Book, Globe, Brain, Save } from 'lucide-react';
|
||||||
import { chain, TextEditor } from './components/TextEditor';
|
import { ToastContainer } from 'react-toastify';
|
||||||
import { toast, ToastContainer } from 'react-toastify';
|
|
||||||
import { Provider } from './Provider';
|
import { Provider } from './Provider';
|
||||||
// @ts-ignore
|
|
||||||
import Logo from './assets/logo-1.png';
|
import Logo from './assets/logo-1.png';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { CodeDescModal } from './modules/CodeDescModal';
|
import { toastWeChat } from './modules/RedirectSuccess.tsx';
|
||||||
import { query } from './modules/query.ts';
|
|
||||||
import { toastSuccess, toastWeChat } from './modules/RedirectSuccess.tsx';
|
|
||||||
import { WeChat } from './components/Icon.tsx';
|
import { WeChat } from './components/Icon.tsx';
|
||||||
const getOrigin = () => {
|
import { getOrigin } from './modules/get-origin.ts';
|
||||||
let origin = window.location.origin;
|
|
||||||
if (origin.includes('www.kevisual.cn')) {
|
export const openEditor = () => {
|
||||||
origin = origin.replace('www.kevisual.cn', 'kevisual.cn');
|
window.open('./editor');
|
||||||
}
|
|
||||||
return origin;
|
|
||||||
};
|
};
|
||||||
export const Main = () => {
|
export const Main = () => {
|
||||||
const [showPreview, setShowPreview] = useState(false);
|
|
||||||
const [html, setHtml] = useState<string>('');
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
const [resultUrl, setResultUrl] = useState<string>('');
|
|
||||||
const [url] = useState<string>('https://kevisual.cn');
|
const [url] = useState<string>('https://kevisual.cn');
|
||||||
const onSubmit = async (values: { title: string; description: string }) => {
|
|
||||||
setResultUrl('');
|
|
||||||
const uploadData = {
|
|
||||||
title: values?.title,
|
|
||||||
description: values?.description,
|
|
||||||
content: chain.getContent(),
|
|
||||||
};
|
|
||||||
const res = await query.post({
|
|
||||||
path: 'app',
|
|
||||||
key: 'public-upload-html',
|
|
||||||
data: uploadData,
|
|
||||||
});
|
|
||||||
if (res.code === 200) {
|
|
||||||
const url = res.data?.url;
|
|
||||||
if (url) {
|
|
||||||
let origin = getOrigin();
|
|
||||||
const newUrl = new URL(url, origin);
|
|
||||||
// toast.success('创建成功, 访问地址' + newUrl.toString(), { autoClose: 3000 });
|
|
||||||
toastSuccess(newUrl.toString());
|
|
||||||
setResultUrl(newUrl.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return (
|
return (
|
||||||
<div className='min-h-screen bg-gray-50'>
|
<div className='min-h-screen bg-gray-50'>
|
||||||
{/* Hero Section */}
|
{/* Hero Section */}
|
||||||
<header className=''>
|
<div className=''>
|
||||||
<nav className='px-4 mx-auto h-16 flex justify-between items-center bg-white border-b border-b-gray-200 w-full'>
|
<nav className='px-4 mx-auto h-16 flex justify-between items-center bg-white border-b border-b-gray-200 w-full'>
|
||||||
<div
|
<div
|
||||||
className='flex items-center space-x-4 cursor-pointer'
|
className='flex items-center space-x-4 cursor-pointer'
|
||||||
@ -56,8 +23,6 @@ export const Main = () => {
|
|||||||
window.open(url, '_blank');
|
window.open(url, '_blank');
|
||||||
}}>
|
}}>
|
||||||
<img src={Logo.src} alt='可视化助手 Logo' className='h-10 w-30 ' />
|
<img src={Logo.src} alt='可视化助手 Logo' className='h-10 w-30 ' />
|
||||||
|
|
||||||
<span className='text-xl font-semibold text-gray-400 cursor-default'>Kevisual 设计助手</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div className='hidden md:flex space-x-6'>
|
<div className='hidden md:flex space-x-6'>
|
||||||
<a
|
<a
|
||||||
@ -77,66 +42,49 @@ export const Main = () => {
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</div>
|
||||||
<main
|
|
||||||
className='flex flex-col overflow-hidden'
|
|
||||||
style={{
|
|
||||||
height: 'calc(100vh - 64px)',
|
|
||||||
}}>
|
|
||||||
<nav className='h-12 bg-white flex'>
|
|
||||||
<button
|
|
||||||
className='flex items-center px-4 h-full bg-white border-b border-b-gray-200 hover:bg-gray-50 cursor-pointer'
|
|
||||||
onClick={() => {
|
|
||||||
const content = chain.getContent();
|
|
||||||
if (!content) {
|
|
||||||
toast.error('内容不能为空', { position: 'top-center', autoClose: 1000 });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setOpen(true);
|
|
||||||
}}>
|
|
||||||
<span className='text-gray-700'>创建</span>
|
|
||||||
<Save className='ml-2 w-4 h-4 text-gray-500' />
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
<article className='container mx-auto px-6 py-10 bg-gray-50'>
|
||||||
className='flex items-center px-4 h-full bg-white border-b border-b-gray-200 hover:bg-gray-50 cursor-pointer'
|
<div className='mx-auto bg-white p-8 py-10 rounded-lg shadow-lg'>
|
||||||
style={{
|
<h2 className='text-3xl font-bold mb-8 text-center'>网页部署平台</h2>
|
||||||
backgroundColor: showPreview ? '#f0f0f0' : 'white',
|
<p className='text-gray-700 mb-6'>
|
||||||
}}
|
Kevisual设计助手提供强大的网页部署平台,让您轻松管理自己的博客和自定义网页。无论是个人博客、AI生成的网页,还是专业项目,都能通过我们的平台进行高效管理。
|
||||||
onClick={() => {
|
</p>
|
||||||
setShowPreview(!showPreview);
|
<div className='grid md:grid-cols-2 gap-8 mt-10'>
|
||||||
}}>
|
<div>
|
||||||
<span className='text-gray-700'>预览</span>
|
<h3 className='text-xl font-semibold mb-4'>功能亮点</h3>
|
||||||
<Globe className='ml-2 w-4 h-4 text-gray-500' />
|
<ul className='list-disc pl-5 space-y-2 text-gray-600'>
|
||||||
</button>
|
<li>类似图床的文件管理系统,高效整理各类资源</li>
|
||||||
</nav>
|
<li>一键创建、删除和管理多个站点</li>
|
||||||
<div className='p-2 rounded shadow flex' style={{ height: 'calc(100% - 48px - 48px)' }}>
|
<li>支持自定义域名,打造专属网络形象</li>
|
||||||
<div className='h-full overflow-auto flex-1'>
|
<li>权限控制系统,可设置为仅自己可访问或公开共享</li>
|
||||||
<TextEditor content={''} chain={chain} onChange={setHtml} />
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 className='text-xl font-semibold mb-4'>使用场景</h3>
|
||||||
|
<ul className='list-disc pl-5 space-y-2 text-gray-600'>
|
||||||
|
<li>个人博客与作品集展示</li>
|
||||||
|
<li className='text-blue-600 hover:underline cursor-pointer' onClick={openEditor}>
|
||||||
|
临时网页快速部署
|
||||||
|
</li>
|
||||||
|
<li>AI生成内容的发布与管理</li>
|
||||||
|
<li>小型项目的在线展示</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='mt-8 text-center'>
|
||||||
|
<a href='./docs/features' className='inline-flex items-center text-blue-600 hover:underline font-medium cursor-not-allowed'>
|
||||||
|
了解更多功能
|
||||||
|
<svg className='w-4 h-4 ml-1' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
|
||||||
|
<path strokeLinecap='round' strokeLinejoin='round' strokeWidth='2' d='M9 5l7 7-7 7'></path>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{showPreview && (
|
|
||||||
<div className='w-1/2 shrink-1 border-l border-gray-200 h-full overflow-auto'>
|
|
||||||
<iframe className='w-full h-full border-0' srcDoc={html} title='预览' sandbox='allow-scripts allow-same-origin allow-popups' />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
<footer className='h-12'>
|
</article>
|
||||||
{!resultUrl && <div className='flex items-center h-full text-gray-500 px-2 italic'>粘贴您的 HTML 内容到编辑器中,点击“创建”按钮生成链接。</div>}
|
|
||||||
{resultUrl && (
|
|
||||||
<div className='flex items-center gap-2 px-4 h-full bg-white border-t border-t-gray-200'>
|
|
||||||
<span className='text-gray-700'>生成的链接:</span>
|
|
||||||
<a href={resultUrl} target='_blank' rel='noopener noreferrer' className='text-blue-600 hover:underline'>
|
|
||||||
{resultUrl}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</footer>
|
|
||||||
<CodeDescModal open={open} onClose={() => setOpen(false)} onSubmit={onSubmit} />
|
|
||||||
</main>
|
|
||||||
|
|
||||||
{/* Features Section */}
|
{/* Features Section */}
|
||||||
<section id='features' className='py-20 bg-white'>
|
<section id='features' className='container mx-auto px-6 py-10 bg-gray-50'>
|
||||||
<div className='container mx-auto px-6'>
|
<div className='mx-auto bg-white p-8 py-10 rounded-lg shadow-lg'>
|
||||||
<h2 className='text-3xl font-bold text-center mb-16'>核心功能</h2>
|
<h2 className='text-3xl font-bold text-center mb-16'>核心功能</h2>
|
||||||
|
|
||||||
<div className='grid md:grid-cols-3 gap-12'>
|
<div className='grid md:grid-cols-3 gap-12'>
|
||||||
@ -162,8 +110,8 @@ export const Main = () => {
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Contact Section */}
|
{/* Contact Section */}
|
||||||
<section id='contact' className='py-20 bg-white'>
|
<section id='contact' className='container mx-auto px-6 py-10 bg-gray-50'>
|
||||||
<div className='container mx-auto px-6'>
|
<div className='mx-auto bg-white p-8 py-10 rounded-lg shadow-lg'>
|
||||||
<h2 className='text-3xl font-bold text-center mb-16'>联系我们</h2>
|
<h2 className='text-3xl font-bold text-center mb-16'>联系我们</h2>
|
||||||
<div className='max-w-2xl mx-auto w-[300px]'>
|
<div className='max-w-2xl mx-auto w-[300px]'>
|
||||||
<div className='space-y-6'>
|
<div className='space-y-6'>
|
||||||
|
107
official/src/apps/index/Editor.tsx
Normal file
107
official/src/apps/index/Editor.tsx
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
import { Mail, Phone, MapPin, Book, Globe, Brain, Save } from 'lucide-react';
|
||||||
|
import { chain, TextEditor } from './components/TextEditor';
|
||||||
|
import { toast, ToastContainer } from 'react-toastify';
|
||||||
|
import { Provider } from './Provider';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { CodeDescModal } from './modules/CodeDescModal';
|
||||||
|
import { query } from './modules/query.ts';
|
||||||
|
import { toastSuccess, toastWeChat } from './modules/RedirectSuccess.tsx';
|
||||||
|
import { getOrigin } from './modules/get-origin.ts';
|
||||||
|
|
||||||
|
export const Editor = () => {
|
||||||
|
const [showPreview, setShowPreview] = useState(false);
|
||||||
|
const [html, setHtml] = useState<string>('');
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const [resultUrl, setResultUrl] = useState<string>('');
|
||||||
|
const [url] = useState<string>('https://kevisual.cn');
|
||||||
|
const onSubmit = async (values: { title: string; description: string }) => {
|
||||||
|
setResultUrl('');
|
||||||
|
const uploadData = {
|
||||||
|
title: values?.title,
|
||||||
|
description: values?.description,
|
||||||
|
content: chain.getContent(),
|
||||||
|
};
|
||||||
|
const res = await query.post({
|
||||||
|
path: 'app',
|
||||||
|
key: 'public-upload-html',
|
||||||
|
data: uploadData,
|
||||||
|
});
|
||||||
|
if (res.code === 200) {
|
||||||
|
const url = res.data?.url;
|
||||||
|
if (url) {
|
||||||
|
let origin = getOrigin();
|
||||||
|
const newUrl = new URL(url, origin);
|
||||||
|
// toast.success('创建成功, 访问地址' + newUrl.toString(), { autoClose: 3000 });
|
||||||
|
toastSuccess(newUrl.toString());
|
||||||
|
setResultUrl(newUrl.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<main
|
||||||
|
className='flex flex-col overflow-hidden'
|
||||||
|
style={{
|
||||||
|
height: 'calc(100vh - 64px)',
|
||||||
|
}}>
|
||||||
|
<nav className='h-12 bg-white flex'>
|
||||||
|
<button
|
||||||
|
className='flex items-center px-4 h-full bg-white border-b border-b-gray-200 hover:bg-gray-50 cursor-pointer'
|
||||||
|
onClick={() => {
|
||||||
|
const content = chain.getContent();
|
||||||
|
if (!content) {
|
||||||
|
toast.error('内容不能为空', { position: 'top-center', autoClose: 1000 });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setOpen(true);
|
||||||
|
}}>
|
||||||
|
<span className='text-gray-700'>创建</span>
|
||||||
|
<Save className='ml-2 w-4 h-4 text-gray-500' />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className='flex items-center px-4 h-full bg-white border-b border-b-gray-200 hover:bg-gray-50 cursor-pointer'
|
||||||
|
style={{
|
||||||
|
backgroundColor: showPreview ? '#f0f0f0' : 'white',
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
setShowPreview(!showPreview);
|
||||||
|
}}>
|
||||||
|
<span className='text-gray-700'>预览</span>
|
||||||
|
<Globe className='ml-2 w-4 h-4 text-gray-500' />
|
||||||
|
</button>
|
||||||
|
</nav>
|
||||||
|
<div className='p-2 rounded shadow flex' style={{ height: 'calc(100% - 48px - 48px)' }}>
|
||||||
|
<div className='h-full overflow-auto flex-1'>
|
||||||
|
<TextEditor content={''} chain={chain} onChange={setHtml} />
|
||||||
|
</div>
|
||||||
|
{showPreview && (
|
||||||
|
<div className='w-1/2 shrink-1 border-l border-gray-200 h-full overflow-auto'>
|
||||||
|
<iframe className='w-full h-full border-0' srcDoc={html} title='预览' sandbox='allow-scripts allow-same-origin allow-popups' />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<footer className='h-12'>
|
||||||
|
{!resultUrl && <div className='flex items-center h-full text-gray-500 px-2 italic'>粘贴您的 HTML 内容到编辑器中,点击“创建”按钮生成链接。</div>}
|
||||||
|
{resultUrl && (
|
||||||
|
<div className='flex items-center gap-2 px-4 h-full bg-white border-t border-t-gray-200'>
|
||||||
|
<span className='text-gray-700'>生成的链接:</span>
|
||||||
|
<a href={resultUrl} target='_blank' rel='noopener noreferrer' className='text-blue-600 hover:underline'>
|
||||||
|
{resultUrl}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</footer>
|
||||||
|
<CodeDescModal open={open} onClose={() => setOpen(false)} onSubmit={onSubmit} />
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export const App = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Provider>
|
||||||
|
<ToastContainer autoClose={2000}></ToastContainer>
|
||||||
|
<Editor />
|
||||||
|
</Provider>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
7
official/src/apps/index/modules/get-origin.ts
Normal file
7
official/src/apps/index/modules/get-origin.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export const getOrigin = () => {
|
||||||
|
let origin = window.location.origin;
|
||||||
|
if (origin.includes('www.kevisual.cn')) {
|
||||||
|
origin = origin.replace('www.kevisual.cn', 'kevisual.cn');
|
||||||
|
}
|
||||||
|
return origin;
|
||||||
|
};
|
21
official/src/pages/editor.astro
Normal file
21
official/src/pages/editor.astro
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
import '../apps/index/index.css';
|
||||||
|
import { App } from '../apps/index/Editor.tsx';
|
||||||
|
---
|
||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
<html lang='zh-CN'>
|
||||||
|
<head>
|
||||||
|
<meta charset='UTF-8' />
|
||||||
|
<link rel='icon' type='image/svg+xml' href='https://kevisual.cn/root/center/panda.jpg' />
|
||||||
|
<meta name='viewport' content='width=device-width, initial-scale=1.0' />
|
||||||
|
<meta name='description' content='Kevisual 是一个专注于可视化设计, AI使用助手的工作室' />
|
||||||
|
<meta name='generator' content={Astro.generator} />
|
||||||
|
<meta name="baidu-site-verification" content="codeva-qAEXUzv0tn" />
|
||||||
|
<title>逸文设计工作室</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<App client:only />
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
x
Reference in New Issue
Block a user