feat: 开发中...

This commit is contained in:
2023-04-01 19:17:20 +08:00
parent 81288078d4
commit d1054590cd
17 changed files with 293 additions and 82 deletions

View File

@@ -7,6 +7,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="叁只仓鼠的个人博客">
<title>网站标题</title>
<style id="custom-css">
</style>
</head>
<body>

View File

@@ -1,22 +1,36 @@
<script setup lang="ts">
import { onMounted } from 'vue';
import { RouterView } from 'vue-router'
import HeaderComponent from "@/components/HeaderComponent.vue"
import FooterComponent from "@/components/FooterComponent.vue"
import { load } from './api';
import { api, loadGlobalStore, siteSetting } from '@/api';
load();
loadGlobalStore();
onMounted(() => {
api.SettingController.getSettingContent(siteSetting.keys.site.css)
.then(resp => {
const vo = resp.data
if (vo.code === 200) {
const cssText = vo.data ?? ""
let cssElement = document.getElementById("custom-css")
siteSetting.css = cssText
if (cssElement != null) cssElement.innerText = cssText
}
})
})
</script>
<template>
<el-container class="blog-container">
<el-header>
<el-header class="blog-header">
<HeaderComponent />
</el-header>
<el-main>
<el-main class="blog-main">
<RouterView />
</el-main>
<el-footer>
<el-footer class="blog-footer">
<FooterComponent />
</el-footer>
</el-container>

View File

@@ -1,8 +1,14 @@
import { UserControllerApiFactory, BlogControllerApiFactory, SettingControllerApiFactory, AttachControllerApiFactory } from "@/swagger"
import { UserControllerApiFactory, BlogControllerApiFactory, SettingControllerApiFactory, AttachControllerApiFactory, Configuration } from "@/swagger"
export const apiConfig: Configuration = {
baseOptions: {
withCredentials: true
}
}
export const api = {
AttachController: AttachControllerApiFactory(),
UserController: UserControllerApiFactory(),
BlogController: BlogControllerApiFactory(),
SettingController: SettingControllerApiFactory()
AttachController: AttachControllerApiFactory(apiConfig),
UserController: UserControllerApiFactory(apiConfig),
BlogController: BlogControllerApiFactory(apiConfig),
SettingController: SettingControllerApiFactory(apiConfig)
}

View File

@@ -1,25 +1,38 @@
import { reactive, ref } from "vue"
import type { UserInfoResponseVO } from "@/swagger"
export const globalStore = {
currentUserInfo: ref<UserInfoResponseVO>({})
}
export const globalStore = reactive<{
currentUserInfo?: UserInfoResponseVO
}>({})
export const siteSetting = {
title: ref<string>("网站标题"),
footer: ref<string>(""),
customNavigationMenu: ref<Array<{
export const siteSetting = reactive({
keys: {
site: {
title: "site.title",
navigation: "site.navigation",
css: "site.css",
footer: "site.footer"
}
},
title: "网站标题",
footer: "",
css: "",
navigation: ref<Array<{
url: string,
text: string
}>>()
}>>(),
})
export function loadGlobalStore() {
globalStore.currentUserInfo = JSON.parse(window.localStorage.getItem("currentUserInfo") || "{}")
console.log("local storage user info: ", globalStore.currentUserInfo)
}
export function load() {
globalStore.currentUserInfo.value = JSON.parse(window.localStorage.getItem("currentUserInfo") || "{}")
console.log("local storage user info: ", globalStore.currentUserInfo.value)
}
export function save() {
window.localStorage.setItem("currentUserInfo", JSON.stringify(globalStore.currentUserInfo.value))
console.log(window.localStorage)
export function saveGlobalStore() {
if (globalStore.currentUserInfo?.id) {
window.localStorage.setItem("currentUserInfo", JSON.stringify(globalStore.currentUserInfo))
} else {
window.localStorage.removeItem("currentUserInfo")
}
}

View File

@@ -1,6 +1,19 @@
<script setup lang="ts">
import { siteSetting } from '@/api';
import { onMounted } from 'vue';
import { api, siteSetting } from '@/api';
onMounted(() => {
// 获取站点页脚
api.SettingController.getSettingContent(siteSetting.keys.site.footer)
.then(response => {
let vo = response.data;
if (vo.code === 200) {
let title = vo.data ?? ""
siteSetting.footer = title
}
})
})
</script>
<template>
@@ -13,7 +26,11 @@ import { siteSetting } from '@/api';
|
<a href="https://editor.swagger.io/">Editor</a>
</p>
<p>{{ siteSetting.footer.value }}</p>
<p>{{ siteSetting.footer }}</p>
</template>
<style scoped></style>
<style scoped>
p {
text-align: center;
}
</style>

View File

@@ -6,6 +6,7 @@ import { RouterLink } from 'vue-router'
import { UserInfoResponseVORoleEnum } from "@/swagger";
import { api, globalStore, siteSetting } from "@/api"
import { updateCurrentUserInfo } from '@/utils';
import router from '@/router';
const currentUserInfo = globalStore.currentUserInfo
const navigationMenu = siteSetting.customNavigationMenu
@@ -14,53 +15,48 @@ const menuIndex = ref<string>(document.location.pathname)
onMounted(() => {
// 获取站点标题
api.SettingController.getSettingContent("site.title")
api.SettingController.getSettingContent(siteSetting.keys.site.title)
.then(response => {
let vo = response.data;
if (vo.code === 200) {
let title = vo.data ?? "网站标题"
siteSetting.title.value = title
siteSetting.title = title
document.title = title
}
})
// 获取站点页脚
api.SettingController.getSettingContent("site.footer")
.then(response => {
let vo = response.data;
if (vo.code === 200) {
let title = vo.data ?? ""
siteSetting.footer.value = title
}
})
if (!currentUserInfo.value.id) {
if (currentUserInfo?.id) {
// 获取当前登录的用户信息
updateCurrentUserInfo();
}
})
function onSelectMenu(index: string) {
router.push(index)
}
</script>
<template>
<el-menu :default-active="menuIndex" mode="horizontal" :ellipsis="false">
<el-menu :default-active="menuIndex" mode="horizontal" :ellipsis="false" @select="onSelectMenu">
<el-menu-item index="/">
<router-link to="/">{{ siteSetting.title.value }}</router-link>
{{ siteSetting.title }}
</el-menu-item>
<el-menu-item index="/tags">
<router-link to="/tags">标签</router-link>
标签
</el-menu-item>
<el-menu-item v-for="customMenu in navigationMenu">
<router-link :to="customMenu.url">{{ customMenu.text }}</router-link>
<el-menu-item v-for="customMenu in navigationMenu" :index="customMenu.text">
{{ customMenu.text }}
</el-menu-item>
<div class="flex-grow" />
<el-menu-item index="/login" v-if="!currentUserInfo.id">
<router-link to="/login">登录</router-link>
<el-menu-item index="/login" v-if="!currentUserInfo?.id">
登录
</el-menu-item>
<el-menu-item index="/register" v-if="!currentUserInfo.id">
<router-link to="/register">注册</router-link>
<el-menu-item index="/register" v-if="!currentUserInfo?.id">
注册
</el-menu-item>
<el-menu-item index="/manage" v-if="currentUserInfo?.role === UserInfoResponseVORoleEnum.ADMIN">
<router-link to="/manage">管理面板</router-link>
管理面板
</el-menu-item>
</el-menu>
</template>

View File

@@ -2,14 +2,27 @@
<script setup lang="ts">
import { api, siteSetting } from '@/api';
function changeSetting(id: string, content: string) {
api.SettingController.updateSetting(content, id, { withCredentials: true })
api.SettingController.updateSetting({ content }, id)
}
function changeCustomCSS(cssText: string) {
let cssElement = document.getElementById("custom-css")
siteSetting.css = cssText
if (cssElement != null) cssElement.innerText = cssText
api.SettingController.updateSetting({ "content": cssText }, siteSetting.keys.site.css)
}
</script>
<template>
<el-input v-model="siteSetting.title.value" placeholder="网站标题"
@change="changeSetting('site.title', siteSetting.title.value)" />
<el-input v-model="siteSetting.footer.value" placeholder="页脚文本"
@change="changeSetting('site.footer', siteSetting.footer.value)" />
<el-input v-model="siteSetting.title" placeholder="网站标题"
@change="changeSetting(siteSetting.keys.site.title, siteSetting.title)" show-word-limit maxlength="10" />
<el-input v-model="siteSetting.footer" placeholder="页脚文本支持HTML"
@change="changeSetting(siteSetting.keys.site.footer, siteSetting.footer)" show-word-limit maxlength="1024" />
<el-input v-model="siteSetting.css" placeholder="自定义CSS" @change="changeCustomCSS(siteSetting.css)" type="textarea"
autosize />
</template>
<style scoped></style>
<style scoped>
.el-input {
margin-bottom: 5px;
}
</style>

View File

@@ -20,6 +20,7 @@ import { ResponseVOPageableVOSettingInfoResponseVO } from '../models';
import { ResponseVOSettingInfoResponseVO } from '../models';
import { ResponseVOString } from '../models';
import { ResponseVOVoid } from '../models';
import { SettingUpdateRequireVO } from '../models';
/**
* SettingControllerApi - axios parameter creator
* @export
@@ -201,12 +202,12 @@ export const SettingControllerApiAxiosParamCreator = function (configuration?: C
/**
*
* @summary 更改网站设置
* @param {string} body
* @param {SettingUpdateRequireVO} body
* @param {string} id 设置ID
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
updateSetting: async (body: string, id: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
updateSetting: async (body: SettingUpdateRequireVO, id: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'body' is not null or undefined
if (body === null || body === undefined) {
throw new RequiredError('body','Required parameter body was null or undefined when calling updateSetting.');
@@ -227,7 +228,50 @@ export const SettingControllerApiAxiosParamCreator = function (configuration?: C
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
localVarHeaderParameter['Content-Type'] = 'text/plain';
localVarHeaderParameter['Content-Type'] = 'application/json';
const query = new URLSearchParams(localVarUrlObj.search);
for (const key in localVarQueryParameter) {
query.set(key, localVarQueryParameter[key]);
}
for (const key in options.params) {
query.set(key, options.params[key]);
}
localVarUrlObj.search = (new URLSearchParams(query)).toString();
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
const needsSerialization = (typeof body !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
localVarRequestOptions.data = needsSerialization ? JSON.stringify(body !== undefined ? body : {}) : (body || "");
return {
url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
options: localVarRequestOptions,
};
},
/**
*
* @summary 批量更改网站设置
* @param {{ [key: string]: string; }} body
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
updateSettings: async (body: { [key: string]: string; }, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'body' is not null or undefined
if (body === null || body === undefined) {
throw new RequiredError('body','Required parameter body was null or undefined when calling updateSettings.');
}
const localVarPath = `/api/v1/settings/`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, 'https://example.com');
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}
const localVarRequestOptions :AxiosRequestConfig = { method: 'PUT', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;
localVarHeaderParameter['Content-Type'] = 'application/json';
const query = new URLSearchParams(localVarUrlObj.search);
for (const key in localVarQueryParameter) {
@@ -316,18 +360,32 @@ export const SettingControllerApiFp = function(configuration?: Configuration) {
/**
*
* @summary 更改网站设置
* @param {string} body
* @param {SettingUpdateRequireVO} body
* @param {string} id 设置ID
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async updateSetting(body: string, id: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<ResponseVOVoid>>> {
async updateSetting(body: SettingUpdateRequireVO, id: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<ResponseVOVoid>>> {
const localVarAxiosArgs = await SettingControllerApiAxiosParamCreator(configuration).updateSetting(body, id, options);
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
return axios.request(axiosRequestArgs);
};
},
/**
*
* @summary 批量更改网站设置
* @param {{ [key: string]: string; }} body
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async updateSettings(body: { [key: string]: string; }, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<ResponseVOVoid>>> {
const localVarAxiosArgs = await SettingControllerApiAxiosParamCreator(configuration).updateSettings(body, options);
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
return axios.request(axiosRequestArgs);
};
},
}
};
@@ -381,14 +439,24 @@ export const SettingControllerApiFactory = function (configuration?: Configurati
/**
*
* @summary 更改网站设置
* @param {string} body
* @param {SettingUpdateRequireVO} body
* @param {string} id 设置ID
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async updateSetting(body: string, id: string, options?: AxiosRequestConfig): Promise<AxiosResponse<ResponseVOVoid>> {
async updateSetting(body: SettingUpdateRequireVO, id: string, options?: AxiosRequestConfig): Promise<AxiosResponse<ResponseVOVoid>> {
return SettingControllerApiFp(configuration).updateSetting(body, id, options).then((request) => request(axios, basePath));
},
/**
*
* @summary 批量更改网站设置
* @param {{ [key: string]: string; }} body
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async updateSettings(body: { [key: string]: string; }, options?: AxiosRequestConfig): Promise<AxiosResponse<ResponseVOVoid>> {
return SettingControllerApiFp(configuration).updateSettings(body, options).then((request) => request(axios, basePath));
},
};
};
@@ -447,13 +515,24 @@ export class SettingControllerApi extends BaseAPI {
/**
*
* @summary 更改网站设置
* @param {string} body
* @param {SettingUpdateRequireVO} body
* @param {string} id 设置ID
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof SettingControllerApi
*/
public async updateSetting(body: string, id: string, options?: AxiosRequestConfig) : Promise<AxiosResponse<ResponseVOVoid>> {
public async updateSetting(body: SettingUpdateRequireVO, id: string, options?: AxiosRequestConfig) : Promise<AxiosResponse<ResponseVOVoid>> {
return SettingControllerApiFp(this.configuration).updateSetting(body, id, options).then((request) => request(this.axios, this.basePath));
}
/**
*
* @summary 批量更改网站设置
* @param {{ [key: string]: string; }} body
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof SettingControllerApi
*/
public async updateSettings(body: { [key: string]: string; }, options?: AxiosRequestConfig) : Promise<AxiosResponse<ResponseVOVoid>> {
return SettingControllerApiFp(this.configuration).updateSettings(body, options).then((request) => request(this.axios, this.basePath));
}
}

View File

@@ -21,6 +21,7 @@ export * from './response-vostring';
export * from './response-vouser-info-response-vo';
export * from './response-vovoid';
export * from './setting-info-response-vo';
export * from './setting-update-require-vo';
export * from './user-create-require-vo';
export * from './user-entity';
export * from './user-info-response-vo';

View File

@@ -0,0 +1,26 @@
/* tslint:disable */
/* eslint-disable */
/**
* OpenAPI definition
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
*
* OpenAPI spec version: v0
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/**
* 设置内容
* @export
* @interface SettingUpdateRequireVO
*/
export interface SettingUpdateRequireVO {
/**
*
* @type {string}
* @memberof SettingUpdateRequireVO
*/
content?: string;
}

View File

@@ -1,16 +1,16 @@
import { api, globalStore, save } from "@/api";
import { api, globalStore, saveGlobalStore } from "@/api";
export function updateCurrentUserInfo() {
api.UserController.getCurrentUserInfo({ withCredentials: true })
api.UserController.getCurrentUserInfo()
.then(resp => {
let vo = resp.data
if (vo.code === 200) {
globalStore.currentUserInfo.value = vo.data || {}
globalStore.currentUserInfo = vo.data
console.log("current user info: ", vo.data)
} else {
console.error("ckeck current user info failed!")
globalStore.currentUserInfo = undefined
console.warn("ckeck current user info failed!")
}
save()
saveGlobalStore()
})
}

View File

@@ -9,7 +9,7 @@ const form = reactive({
})
const onSubmit = () => {
api.UserController.loginUser(form, { withCredentials: true })
api.UserController.loginUser(form)
.then(resp => {
let vo = resp.data;
if (vo.code === 200) {
@@ -31,7 +31,7 @@ const onSubmit = () => {
<el-input v-model="form.email" />
</el-form-item>
<el-form-item label="密码">
<el-input v-model="form.password" type="password" />
<el-input v-model="form.password" type="password" show-password />
</el-form-item>
<el-form-item>
<el-button class="login-button" type="primary" @click="onSubmit">登录</el-button>

View File

@@ -1,9 +1,16 @@
<script setup lang="ts">
import { ref } from 'vue';
import { onMounted, ref } from 'vue';
import SiteManageComponent from '@/components/manage/SiteManageComponent.vue';
import { globalStore } from '@/api';
const activeName = ref<string>('site')
onMounted(() => {
if (!globalStore.currentUserInfo?.id) {
location.pathname = "/"
console.log("not login!")
}
})
</script>
<template>