mirror of
https://github.com/coaidev/coai.git
synced 2025-05-28 17:30:15 +09:00
feat: support custom footer and hide when logged in
This commit is contained in:
parent
780a55a109
commit
3a6eed9ec4
@ -18,6 +18,8 @@ export type SiteInfo = {
|
||||
buy_link: string;
|
||||
mail: boolean;
|
||||
contact: string;
|
||||
footer: string;
|
||||
auth_footer: boolean;
|
||||
article: string[];
|
||||
generation: string[];
|
||||
};
|
||||
@ -36,6 +38,8 @@ export async function getSiteInfo(): Promise<SiteInfo> {
|
||||
announcement: "",
|
||||
buy_link: "",
|
||||
contact: "",
|
||||
footer: "",
|
||||
auth_footer: false,
|
||||
mail: false,
|
||||
article: [],
|
||||
generation: [],
|
||||
|
@ -35,6 +35,8 @@ export type SiteState = {
|
||||
buy_link: string;
|
||||
announcement: string;
|
||||
contact: string;
|
||||
footer: string;
|
||||
auth_footer: boolean;
|
||||
};
|
||||
|
||||
export type CommonState = {
|
||||
@ -119,6 +121,8 @@ export const initialSystemState: SystemProps = {
|
||||
buy_link: "",
|
||||
announcement: "",
|
||||
contact: "",
|
||||
footer: "",
|
||||
auth_footer: false,
|
||||
},
|
||||
mail: {
|
||||
host: "",
|
||||
|
@ -11,25 +11,36 @@ import {
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog.tsx";
|
||||
import { getLanguage } from "@/i18n.ts";
|
||||
import { selectAuthenticated } from "@/store/auth.ts";
|
||||
import { appLogo } from "@/conf/env.ts";
|
||||
import {
|
||||
infoArticleSelector,
|
||||
infoAuthFooterSelector,
|
||||
infoContactSelector,
|
||||
infoFooterSelector,
|
||||
infoGenerationSelector,
|
||||
} from "@/store/info.ts";
|
||||
import Markdown from "@/components/Markdown.tsx";
|
||||
import { hitGroup } from "@/utils/groups.ts";
|
||||
|
||||
function Footer() {
|
||||
const auth = useSelector(selectAuthenticated);
|
||||
const footer = useSelector(infoFooterSelector);
|
||||
const auth_footer = useSelector(infoAuthFooterSelector);
|
||||
|
||||
if (auth && auth_footer) {
|
||||
// hide footer
|
||||
return null;
|
||||
}
|
||||
|
||||
return footer.length > 0 && <Markdown acceptHtml={true}>{footer}</Markdown>;
|
||||
}
|
||||
|
||||
function ChatSpace() {
|
||||
const [open, setOpen] = useState(false);
|
||||
const { t } = useTranslation();
|
||||
const contact = useSelector(infoContactSelector);
|
||||
|
||||
const cn = getLanguage() === "cn";
|
||||
const auth = useSelector(selectAuthenticated);
|
||||
|
||||
const generationGroup = useSelector(infoGenerationSelector);
|
||||
const generation = hitGroup(generationGroup);
|
||||
|
||||
@ -84,18 +95,7 @@ function ChatSpace() {
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
<div className={`space-footer`}>
|
||||
{cn && !auth && (
|
||||
<p>
|
||||
请您遵守
|
||||
<a
|
||||
href={`http://www.cac.gov.cn/2023-07/13/c_1690898327029107.htm`}
|
||||
target={`_blank`}
|
||||
>
|
||||
《生成式人工智能服务管理暂行办法》
|
||||
</a>
|
||||
法规使用
|
||||
</p>
|
||||
)}
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -3,6 +3,8 @@ import { EventCommitter } from "@/events/struct.ts";
|
||||
export type InfoForm = {
|
||||
mail: boolean;
|
||||
contact: string;
|
||||
footer: string;
|
||||
auth_footer: boolean;
|
||||
article: string[];
|
||||
generation: string[];
|
||||
};
|
||||
|
@ -664,6 +664,9 @@
|
||||
"announcementPlaceholder": "请输入站点公告 (支持 Markdown / HTML 格式)",
|
||||
"contact": "联系信息",
|
||||
"contactPlaceholder": "请输入联系信息 (支持 Markdown / HTML 格式)",
|
||||
"footer": "页脚信息",
|
||||
"footerPlaceholder": "请输入页脚信息 (支持 Markdown / HTML 格式)",
|
||||
"authFooter": "登录后隐藏页脚",
|
||||
"article": "批量文章生成功能分组",
|
||||
"articleTip": "批量文章生成功能分组,勾选后当前用户组可使用批量文章生成功能",
|
||||
"generate": "AI 项目生成器分组",
|
||||
|
@ -522,6 +522,30 @@ function Site({ data, dispatch, onChange }: CompProps<SiteState>) {
|
||||
placeholder={t("admin.system.contactPlaceholder")}
|
||||
/>
|
||||
</ParagraphItem>
|
||||
<ParagraphSpace />
|
||||
<ParagraphItem rowLayout={true}>
|
||||
<Label>{t("admin.system.footer")}</Label>
|
||||
<Textarea
|
||||
value={data.footer}
|
||||
rows={6}
|
||||
onChange={(e) =>
|
||||
dispatch({
|
||||
type: "update:site.footer",
|
||||
value: e.target.value,
|
||||
})
|
||||
}
|
||||
placeholder={t("admin.system.footerPlaceholder")}
|
||||
/>
|
||||
</ParagraphItem>
|
||||
<ParagraphItem>
|
||||
<Label>{t("admin.system.authFooter")}</Label>
|
||||
<Switch
|
||||
checked={data.auth_footer}
|
||||
onCheckedChange={(value) => {
|
||||
dispatch({ type: "update:site.auth_footer", value });
|
||||
}}
|
||||
/>
|
||||
</ParagraphItem>
|
||||
<ParagraphFooter>
|
||||
<div className={`grow`} />
|
||||
<Button
|
||||
|
@ -17,6 +17,8 @@ export const infoSlice = createSlice({
|
||||
contact: getMemory("contact"),
|
||||
article: getArrayMemory("article"),
|
||||
generation: getArrayMemory("generation"),
|
||||
footer: getMemory("footer"),
|
||||
auth_footer: getBooleanMemory("auth_footer", false),
|
||||
} as InfoForm,
|
||||
reducers: {
|
||||
setForm: (state, action) => {
|
||||
@ -25,11 +27,15 @@ export const infoSlice = createSlice({
|
||||
state.contact = form.contact ?? "";
|
||||
state.article = form.article ?? [];
|
||||
state.generation = form.generation ?? [];
|
||||
state.footer = form.footer ?? "";
|
||||
state.auth_footer = form.auth_footer ?? false;
|
||||
|
||||
setBooleanMemory("mail", state.mail);
|
||||
setMemory("contact", state.contact);
|
||||
setArrayMemory("article", state.article);
|
||||
setArrayMemory("generation", state.generation);
|
||||
setMemory("footer", state.footer);
|
||||
setBooleanMemory("auth_footer", state.auth_footer);
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -46,3 +52,7 @@ export const infoArticleSelector = (state: RootState): string[] =>
|
||||
state.info.article;
|
||||
export const infoGenerationSelector = (state: RootState): string[] =>
|
||||
state.info.generation;
|
||||
export const infoFooterSelector = (state: RootState): string =>
|
||||
state.info.footer;
|
||||
export const infoAuthFooterSelector = (state: RootState): boolean =>
|
||||
state.info.auth_footer;
|
||||
|
@ -16,6 +16,8 @@ type ApiInfo struct {
|
||||
Announcement string `json:"announcement"`
|
||||
BuyLink string `json:"buy_link"`
|
||||
Contact string `json:"contact"`
|
||||
Footer string `json:"footer"`
|
||||
AuthFooter bool `json:"auth_footer"`
|
||||
Mail bool `json:"mail"`
|
||||
Article []string `json:"article"`
|
||||
Generation []string `json:"generation"`
|
||||
@ -34,6 +36,8 @@ type siteState struct {
|
||||
BuyLink string `json:"buy_link" mapstructure:"buylink"`
|
||||
Announcement string `json:"announcement" mapstructure:"announcement"`
|
||||
Contact string `json:"contact" mapstructure:"contact"`
|
||||
Footer string `json:"footer" mapstructure:"footer"`
|
||||
AuthFooter bool `json:"auth_footer" mapstructure:"authfooter"`
|
||||
}
|
||||
|
||||
type whiteList struct {
|
||||
@ -108,6 +112,8 @@ func (c *SystemConfig) AsInfo() ApiInfo {
|
||||
Docs: c.General.Docs,
|
||||
Announcement: c.Site.Announcement,
|
||||
Contact: c.Site.Contact,
|
||||
Footer: c.Site.Footer,
|
||||
AuthFooter: c.Site.AuthFooter,
|
||||
BuyLink: c.Site.BuyLink,
|
||||
Mail: c.IsMailValid(),
|
||||
Article: c.Common.Article,
|
||||
|
@ -42,7 +42,6 @@ func PreflightCache(cache *redis.Client, hash string, buffer *utils.Buffer, hook
|
||||
|
||||
buf, err := utils.UnmarshalString[utils.Buffer](raw)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return idx, false, nil
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user