update
This commit is contained in:
1
components.d.ts
vendored
1
components.d.ts
vendored
@@ -8,6 +8,7 @@ export {}
|
|||||||
/* prettier-ignore */
|
/* prettier-ignore */
|
||||||
declare module 'vue' {
|
declare module 'vue' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
|
Corner: typeof import('./src/components/Corner.vue')['default']
|
||||||
Editor: typeof import('./src/components/Editor.vue')['default']
|
Editor: typeof import('./src/components/Editor.vue')['default']
|
||||||
Editors: typeof import('./src/components/Editors.vue')['default']
|
Editors: typeof import('./src/components/Editors.vue')['default']
|
||||||
Login: typeof import('./src/components/Login.vue')['default']
|
Login: typeof import('./src/components/Login.vue')['default']
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ watch(authed, (v) => {
|
|||||||
<template>
|
<template>
|
||||||
<n-config-provider class="myContainer" :locale="zhCN" :date-locale="dateZhCN">
|
<n-config-provider class="myContainer" :locale="zhCN" :date-locale="dateZhCN">
|
||||||
<n-modal-provider>
|
<n-modal-provider>
|
||||||
<n-message-provider>
|
<n-message-provider max="1">
|
||||||
<n-dialog-provider>
|
<n-dialog-provider>
|
||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
<Login />
|
<Login />
|
||||||
|
|||||||
@@ -73,6 +73,11 @@ export class Tutorial {
|
|||||||
return res.data
|
return res.data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async togglePublic(display: number) {
|
||||||
|
const res = await http.put(`/tutorial/public/${display}`)
|
||||||
|
return res.data
|
||||||
|
}
|
||||||
|
|
||||||
static async remove(display: number) {
|
static async remove(display: number) {
|
||||||
await http.delete(`/tutorial/${display}`)
|
await http.delete(`/tutorial/${display}`)
|
||||||
}
|
}
|
||||||
|
|||||||
80
src/components/Corner.vue
Normal file
80
src/components/Corner.vue
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<template>
|
||||||
|
<n-flex align="center" class="corner">
|
||||||
|
<template v-if="user.loaded && authed">
|
||||||
|
<n-button type="primary" secondary @click="submit">提交</n-button>
|
||||||
|
<n-dropdown :options="menu" @select="clickMenu">
|
||||||
|
<n-button>{{ user.username }}</n-button>
|
||||||
|
</n-dropdown>
|
||||||
|
</template>
|
||||||
|
<n-button
|
||||||
|
v-if="user.loaded && !authed"
|
||||||
|
@click="handleLogin"
|
||||||
|
secondary
|
||||||
|
type="primary"
|
||||||
|
>
|
||||||
|
登录
|
||||||
|
</n-button>
|
||||||
|
</n-flex>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed, h } from "vue"
|
||||||
|
import { useMessage } from "naive-ui"
|
||||||
|
import { Icon } from "@iconify/vue"
|
||||||
|
import { user, authed, roleNormal } from "../store/user"
|
||||||
|
import { loginModal } from "../store/modal"
|
||||||
|
import { Account } from "../api"
|
||||||
|
import { Role } from "../utils/type"
|
||||||
|
import { router } from "../router"
|
||||||
|
|
||||||
|
const message = useMessage()
|
||||||
|
|
||||||
|
const menu = computed(() => [
|
||||||
|
{
|
||||||
|
label: "后台",
|
||||||
|
key: "dashboard",
|
||||||
|
show: !roleNormal.value,
|
||||||
|
icon: () =>
|
||||||
|
h(Icon, {
|
||||||
|
icon: "streamline-emojis:robot-face-1",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "退出",
|
||||||
|
key: "logout",
|
||||||
|
icon: () =>
|
||||||
|
h(Icon, {
|
||||||
|
icon: "streamline-emojis:hot-beverage-2",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
function clickMenu(name: string) {
|
||||||
|
switch (name) {
|
||||||
|
case "dashboard":
|
||||||
|
router.push({ name: "tutorial" })
|
||||||
|
break
|
||||||
|
case "logout":
|
||||||
|
handleLogout()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleLogin() {
|
||||||
|
loginModal.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleLogout() {
|
||||||
|
await Account.logout()
|
||||||
|
user.username = ""
|
||||||
|
user.role = Role.Normal
|
||||||
|
}
|
||||||
|
|
||||||
|
function submit() {
|
||||||
|
message.error("未实装")
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.corner {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -67,69 +67,15 @@
|
|||||||
</n-flex>
|
</n-flex>
|
||||||
</n-tab-pane>
|
</n-tab-pane>
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
<n-flex align="center" class="suffix">
|
<Corner />
|
||||||
<template v-if="user.loaded && authed">
|
|
||||||
<n-button type="primary" secondary @click="submit">提交</n-button>
|
|
||||||
<n-dropdown :options="menu" @select="clickMenu">
|
|
||||||
<n-button>{{ user.username }}</n-button>
|
|
||||||
</n-dropdown>
|
|
||||||
</template>
|
|
||||||
<n-button
|
|
||||||
v-if="user.loaded && !authed"
|
|
||||||
@click="handleLogin"
|
|
||||||
secondary
|
|
||||||
type="primary"
|
|
||||||
>
|
|
||||||
登录
|
|
||||||
</n-button>
|
|
||||||
</n-flex>
|
|
||||||
</template>
|
</template>
|
||||||
</n-tabs>
|
</n-tabs>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Icon } from "@iconify/vue"
|
import { Icon } from "@iconify/vue"
|
||||||
import Editor from "./Editor.vue"
|
import Editor from "./Editor.vue"
|
||||||
|
import Corner from "./Corner.vue"
|
||||||
import { html, css, js, tab, size, reset } from "../store/editors"
|
import { html, css, js, tab, size, reset } from "../store/editors"
|
||||||
import { user, authed, roleNormal } from "../store/user"
|
|
||||||
import { loginModal } from "../store/modal"
|
|
||||||
import { Account } from "../api"
|
|
||||||
import { Role } from "../utils/type"
|
|
||||||
import { router } from "../router"
|
|
||||||
import { computed, h } from "vue"
|
|
||||||
import { useMessage } from "naive-ui"
|
|
||||||
|
|
||||||
const message = useMessage()
|
|
||||||
|
|
||||||
const menu = computed(() => [
|
|
||||||
{
|
|
||||||
label: "后台",
|
|
||||||
key: "dashboard",
|
|
||||||
show: !roleNormal.value,
|
|
||||||
icon: () =>
|
|
||||||
h(Icon, {
|
|
||||||
icon: "streamline-emojis:robot-face-1",
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "退出",
|
|
||||||
key: "logout",
|
|
||||||
icon: () =>
|
|
||||||
h(Icon, {
|
|
||||||
icon: "streamline-emojis:hot-beverage-2",
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
])
|
|
||||||
|
|
||||||
function clickMenu(name: string) {
|
|
||||||
switch (name) {
|
|
||||||
case "dashboard":
|
|
||||||
router.push({ name: "tutorial" })
|
|
||||||
break
|
|
||||||
case "logout":
|
|
||||||
handleLogout()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeTab(name: string) {
|
function changeTab(name: string) {
|
||||||
tab.value = name
|
tab.value = name
|
||||||
@@ -138,20 +84,6 @@ function changeTab(name: string) {
|
|||||||
function changeSize(num: number) {
|
function changeSize(num: number) {
|
||||||
size.value = num
|
size.value = num
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleLogin() {
|
|
||||||
loginModal.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleLogout() {
|
|
||||||
await Account.logout()
|
|
||||||
user.username = ""
|
|
||||||
user.role = Role.Normal
|
|
||||||
}
|
|
||||||
|
|
||||||
function submit() {
|
|
||||||
message.error("未实装")
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.pane {
|
.pane {
|
||||||
@@ -166,8 +98,4 @@ function submit() {
|
|||||||
.label {
|
.label {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.suffix {
|
|
||||||
margin-right: 20px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
<n-flex align="center">
|
<n-flex align="center">
|
||||||
<Icon icon="twemoji:open-book" :width="20"></Icon>
|
<Icon icon="twemoji:open-book" :width="20"></Icon>
|
||||||
<n-text class="preview">教程(测试版)</n-text>
|
<n-text class="preview">教程(测试版)</n-text>
|
||||||
<n-button text @click="prev" :disabled="prevDisabled">
|
<n-button text @click="prev" v-if="!hideNav" :disabled="prevDisabled">
|
||||||
<Icon :width="24" icon="pepicons-pencil:arrow-left"></Icon>
|
<Icon :width="24" icon="pepicons-pencil:arrow-left"></Icon>
|
||||||
</n-button>
|
</n-button>
|
||||||
<n-button text @click="next" :disabled="nextDisabled">
|
<n-button text @click="next" v-if="!hideNav" :disabled="nextDisabled">
|
||||||
<Icon :width="24" icon="pepicons-pencil:arrow-right"></Icon>
|
<Icon :width="24" icon="pepicons-pencil:arrow-right"></Icon>
|
||||||
</n-button>
|
</n-button>
|
||||||
</n-flex>
|
</n-flex>
|
||||||
@@ -29,10 +29,13 @@ const displays = ref<number[]>([])
|
|||||||
const content = ref("")
|
const content = ref("")
|
||||||
const $content = useTemplateRef("$content")
|
const $content = useTemplateRef("$content")
|
||||||
|
|
||||||
|
const hideNav = computed(() => displays.value.length <= 1)
|
||||||
|
|
||||||
const prevDisabled = computed(() => {
|
const prevDisabled = computed(() => {
|
||||||
const i = displays.value.indexOf(step.value)
|
const i = displays.value.indexOf(step.value)
|
||||||
return i <= 0
|
return i <= 0
|
||||||
})
|
})
|
||||||
|
|
||||||
const nextDisabled = computed(() => {
|
const nextDisabled = computed(() => {
|
||||||
const i = displays.value.indexOf(step.value)
|
const i = displays.value.indexOf(step.value)
|
||||||
return i === displays.value.length - 1
|
return i === displays.value.length - 1
|
||||||
|
|||||||
@@ -7,16 +7,20 @@
|
|||||||
:key="item.display"
|
:key="item.display"
|
||||||
@click="show(item.display)"
|
@click="show(item.display)"
|
||||||
style="cursor: pointer"
|
style="cursor: pointer"
|
||||||
|
:embedded="!item.is_public"
|
||||||
>
|
>
|
||||||
<template #header>
|
<template #header>
|
||||||
<n-flex align="center">
|
<n-flex align="center">
|
||||||
<Icon
|
<n-button text @click.stop="togglePublic(item.display)">
|
||||||
:icon="
|
<Icon
|
||||||
item.is_public
|
width="24"
|
||||||
? 'twemoji:check-mark-button'
|
:icon="
|
||||||
: 'twemoji:locked'
|
item.is_public
|
||||||
"
|
? 'twemoji:check-mark-button'
|
||||||
></Icon>
|
: 'twemoji:locked'
|
||||||
|
"
|
||||||
|
></Icon>
|
||||||
|
</n-button>
|
||||||
<span>【{{ item.display }}】{{ item.title }}</span>
|
<span>【{{ item.display }}】{{ item.title }}</span>
|
||||||
</n-flex>
|
</n-flex>
|
||||||
</template>
|
</template>
|
||||||
@@ -143,6 +147,15 @@ async function show(display: number) {
|
|||||||
content.value = await marked.parse(item.content, { async: true })
|
content.value = await marked.parse(item.content, { async: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function togglePublic(display: number) {
|
||||||
|
const data = await Tutorial.togglePublic(display)
|
||||||
|
message.success(data.message)
|
||||||
|
list.value = list.value.map((item) => {
|
||||||
|
if (item.display === display) item.is_public = !item.is_public
|
||||||
|
return item
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => tutorial.value.content,
|
() => tutorial.value.content,
|
||||||
async (v: string) => {
|
async (v: string) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user