feat: update addition feature storage and frontend features

This commit is contained in:
Zhang Minghan 2024-03-09 18:48:09 +08:00
parent 9f41572b40
commit 6bf12df847
14 changed files with 33 additions and 15 deletions

View File

@ -15,6 +15,7 @@ screenshot
config.yaml config.yaml
config.dev.yaml config.dev.yaml
# current in ~/storage
addition/generation/data/* addition/generation/data/*
!addition/generation/data/.gitkeep !addition/generation/data/.gitkeep

View File

@ -145,6 +145,7 @@ _🚀 **Next Generation AI One-Stop Solution**_
-p 8000:8094 \ -p 8000:8094 \
-v ~/config:/config \ -v ~/config:/config \
-v ~/logs:/logs \ -v ~/logs:/logs \
-v ~/storage:/storage \
-e MYSQL_HOST=localhost \ -e MYSQL_HOST=localhost \
-e MYSQL_PORT=3306 \ -e MYSQL_PORT=3306 \
-e MYSQL_DATABASE=chatnio \ -e MYSQL_DATABASE=chatnio \
@ -160,7 +161,7 @@ _🚀 **Next Generation AI One-Stop Solution**_
> - *-p 8000:8094* 指映射宿主机端口为 8000, 可自行修改冒号前的端口号 > - *-p 8000:8094* 指映射宿主机端口为 8000, 可自行修改冒号前的端口号
> - SECRET: JWT 密钥, 自行生成随机字符串修改 > - SECRET: JWT 密钥, 自行生成随机字符串修改
> - SERVE_STATIC: 是否启用静态文件服务 (正常情况下不需要更改此项, 详见下方常见问题解答) > - SERVE_STATIC: 是否启用静态文件服务 (正常情况下不需要更改此项, 详见下方常见问题解答)
> - *-v ~/config:/config* *-v ~/logs:/logs* 指挂载配置文件和日志文件的宿主机目录, 可自行修改 > - *-v ~/config:/config* 挂载配置文件, *-v ~/logs:/logs* 挂载日志文件的宿主机目录, *-v ~/storage:/storage* 挂载附加功能的生成文件
> - 需配置 MySQL 和 Redis 服务, 请自行参考上方信息修改环境变量 > - 需配置 MySQL 和 Redis 服务, 请自行参考上方信息修改环境变量
版本更新 _开启 Watchtower 后无需手动更新, 执行后按照上述步骤重新运行即可_ 版本更新 _开启 Watchtower 后无需手动更新, 执行后按照上述步骤重新运行即可_

View File

@ -25,13 +25,13 @@ type WebsocketArticleResponse struct {
func ProjectTarDownloadAPI(c *gin.Context) { func ProjectTarDownloadAPI(c *gin.Context) {
hash := strings.TrimSpace(c.Query("hash")) hash := strings.TrimSpace(c.Query("hash"))
c.Writer.Header().Add("Content-Disposition", "attachment; filename=article.tar.gz") c.Writer.Header().Add("Content-Disposition", "attachment; filename=article.tar.gz")
c.File(fmt.Sprintf("addition/article/data/out/%s.tar.gz", hash)) c.File(fmt.Sprintf("storage/article/%s.tar.gz", hash))
} }
func ProjectZipDownloadAPI(c *gin.Context) { func ProjectZipDownloadAPI(c *gin.Context) {
hash := strings.TrimSpace(c.Query("hash")) hash := strings.TrimSpace(c.Query("hash"))
c.Writer.Header().Add("Content-Disposition", "attachment; filename=article.zip") c.Writer.Header().Add("Content-Disposition", "attachment; filename=article.zip")
c.File(fmt.Sprintf("addition/article/data/out/%s.zip", hash)) c.File(fmt.Sprintf("storage/article/%s.zip", hash))
} }
func GenerateAPI(c *gin.Context) { func GenerateAPI(c *gin.Context) {

View File

@ -75,8 +75,8 @@ func CreateWorker(c *gin.Context, user *auth.User, model string, prompt string,
hook(StreamProgressResponse{Current: current, Total: total, Quota: 0}) hook(StreamProgressResponse{Current: current, Total: total, Quota: 0})
path := fmt.Sprintf("addition/article/data/%s", hash) path := fmt.Sprintf("storage/article/data/%s", hash)
if _, _, err := utils.GenerateCompressTask(hash, "addition/article/data/out", path, path); err != nil { if _, _, err := utils.GenerateCompressTask(hash, "storage/article", path, path); err != nil {
globals.Debug(fmt.Sprintf("[article] error during generate compress task: %s", err.Error())) globals.Debug(fmt.Sprintf("[article] error during generate compress task: %s", err.Error()))
return "" return ""
} }

View File

@ -30,7 +30,7 @@ func GenerateDocxFile(target, title, content string) error {
} }
func CreateArticleFile(hash, title, content string) string { func CreateArticleFile(hash, title, content string) string {
target := fmt.Sprintf("addition/article/data/%s/%s.docx", hash, title) target := fmt.Sprintf("storage/article/data/%s/%s.docx", hash, title)
utils.FileDirSafe(target) utils.FileDirSafe(target)
if err := GenerateDocxFile(target, title, content); err != nil { if err := GenerateDocxFile(target, title, content); err != nil {
globals.Debug(fmt.Sprintf("[article] error during generate article %s: %s", title, err.Error())) globals.Debug(fmt.Sprintf("[article] error during generate article %s: %s", title, err.Error()))

View File

@ -18,13 +18,13 @@ type WebsocketGenerationForm struct {
func ProjectTarDownloadAPI(c *gin.Context) { func ProjectTarDownloadAPI(c *gin.Context) {
hash := strings.TrimSpace(c.Query("hash")) hash := strings.TrimSpace(c.Query("hash"))
c.Writer.Header().Add("Content-Disposition", "attachment; filename=code.tar.gz") c.Writer.Header().Add("Content-Disposition", "attachment; filename=code.tar.gz")
c.File(fmt.Sprintf("addition/generation/data/out/%s.tar.gz", hash)) c.File(fmt.Sprintf("storage/generation/%s.tar.gz", hash))
} }
func ProjectZipDownloadAPI(c *gin.Context) { func ProjectZipDownloadAPI(c *gin.Context) {
hash := strings.TrimSpace(c.Query("hash")) hash := strings.TrimSpace(c.Query("hash"))
c.Writer.Header().Add("Content-Disposition", "attachment; filename=code.zip") c.Writer.Header().Add("Content-Disposition", "attachment; filename=code.zip")
c.File(fmt.Sprintf("addition/generation/data/out/%s.zip", hash)) c.File(fmt.Sprintf("storage/generation/%s.zip", hash))
} }
func GenerateAPI(c *gin.Context) { func GenerateAPI(c *gin.Context) {

View File

@ -7,7 +7,7 @@ import (
) )
func GetFolder(hash string) string { func GetFolder(hash string) string {
return fmt.Sprintf("addition/generation/data/%s", hash) return fmt.Sprintf("storage/generation/data/%s", hash)
} }
func GetFolderByHash(model string, prompt string) (string, string) { func GetFolderByHash(model string, prompt string) (string, string) {

View File

@ -15,7 +15,7 @@ func CreateGenerationWithCache(group, model, prompt string, hook func(buffer *ut
} }
} }
if _, _, err := utils.GenerateCompressTask(hash, "addition/generation/data/out", path, path); err != nil { if _, _, err := utils.GenerateCompressTask(hash, "storage/generation", path, path); err != nil {
return "", fmt.Errorf("error during generate compress task: %s", err.Error()) return "", fmt.Errorf("error during generate compress task: %s", err.Error())
} }

View File

@ -246,7 +246,10 @@ function MarkdownContent({
<DialogClose asChild> <DialogClose asChild>
<Button variant={`outline`}>{t("cancel")}</Button> <Button variant={`outline`}>{t("cancel")}</Button>
</DialogClose> </DialogClose>
<DialogClose onClick={async () => await sendAction(message)} asChild> <DialogClose
onClick={async () => await sendAction(message)}
asChild
>
<Button variant={`default`}>{t("confirm")}</Button> <Button variant={`default`}>{t("confirm")}</Button>
</DialogClose> </DialogClose>
</DialogFooter> </DialogFooter>

View File

@ -1,7 +1,7 @@
import "@/assets/pages/article.less"; import "@/assets/pages/article.less";
import { Button } from "@/components/ui/button.tsx"; import { Button } from "@/components/ui/button.tsx";
import router from "@/router.tsx"; import router from "@/router.tsx";
import { Check, ChevronLeft, Files, Globe, Loader2 } from "lucide-react"; import { Check, ChevronLeft, Cloud, Files, Globe, Loader2 } from "lucide-react";
import { Textarea } from "@/components/ui/textarea.tsx"; import { Textarea } from "@/components/ui/textarea.tsx";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
@ -31,7 +31,7 @@ type ProgressProps = {
total: number; total: number;
}; };
function GenerateProgress({ current, total }: ProgressProps) { function GenerateProgress({ current, total, quota }: ProgressProps & { quota: number }) {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
@ -56,6 +56,12 @@ function GenerateProgress({ current, total }: ProgressProps) {
)} )}
</p> </p>
<Progress value={(100 * current) / total} /> <Progress value={(100 * current) / total} />
<div
className={`article-quota flex flex-row mt-4 border border-input rounded-md py-1 px-3 select-none w-max items-center mx-auto`}
>
<Cloud className={`h-4 w-4 mr-2`} />
<p>{quota.toFixed(2)}</p>
</div>
</div> </div>
); );
} }
@ -72,6 +78,7 @@ function ArticleContent() {
const [progress, setProgress] = useState(false); const [progress, setProgress] = useState(false);
const [state, setState] = useState<ProgressProps>({ current: 0, total: 0 }); const [state, setState] = useState<ProgressProps>({ current: 0, total: 0 });
const [quota, setQuota] = useState<number>(0);
const [hash, setHash] = useState(""); const [hash, setHash] = useState("");
function clear() { function clear() {
@ -79,6 +86,7 @@ function ArticleContent() {
setTitle(""); setTitle("");
setHash(""); setHash("");
setProgress(false); setProgress(false);
setQuota(0);
setState({ current: 0, total: 0 }); setState({ current: 0, total: 0 });
} }
@ -100,6 +108,8 @@ function ArticleContent() {
connection.onmessage = (e) => { connection.onmessage = (e) => {
const data = JSON.parse(e.data); const data = JSON.parse(e.data);
data.data && data.data.quota && setQuota(quota + data.data.quota);
if (!data.hash) setState(data.data as ProgressProps); if (!data.hash) setState(data.data as ProgressProps);
else { else {
toast({ toast({
@ -123,7 +133,7 @@ function ArticleContent() {
return progress ? ( return progress ? (
<> <>
<GenerateProgress {...state} /> <GenerateProgress {...state} quota={quota} />
{hash && ( {hash && (
<div className={`article-action flex flex-row items-center my-4 gap-4`}> <div className={`article-action flex flex-row items-center my-4 gap-4`}>
<Button <Button

View File

@ -101,7 +101,7 @@ function Wrapper({ onSend }: WrapperProps) {
{quota > 0 && ( {quota > 0 && (
<div className={`quota-box`}> <div className={`quota-box`}>
<Cloud className={`h-4 w-4 mr-2`} /> <Cloud className={`h-4 w-4 mr-2`} />
{quota} {quota.toFixed(2)}
</div> </div>
)} )}
<pre className={`message-box`}> <pre className={`message-box`}>

View File

@ -56,6 +56,7 @@ services:
volumes: volumes:
- ./config:/config - ./config:/config
- ./logs:/logs - ./logs:/logs
- ./storage:/storage
networks: networks:
- chatnio-network - chatnio-network

View File

@ -56,6 +56,7 @@ services:
volumes: volumes:
- ./config:/config - ./config:/config
- ./logs:/logs - ./logs:/logs
- ./storage:/storage
networks: networks:
- chatnio-network - chatnio-network

View File

@ -56,6 +56,7 @@ services:
volumes: volumes:
- ./config:/config - ./config:/config
- ./logs:/logs - ./logs:/logs
- ./storage:/storage
networks: networks:
- chatnio-network - chatnio-network