mirror of
https://github.com/Megghy/vtsuru.live.git
synced 2025-12-06 18:36:55 +08:00
add questionbox share card
This commit is contained in:
@@ -19,7 +19,9 @@
|
|||||||
"echarts": "^5.4.3",
|
"echarts": "^5.4.3",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"grapheme-splitter": "^1.0.4",
|
"grapheme-splitter": "^1.0.4",
|
||||||
|
"html2canvas": "^1.4.1",
|
||||||
"linqts": "^1.15.0",
|
"linqts": "^1.15.0",
|
||||||
|
"qrcode.vue": "^3.4.1",
|
||||||
"universal-cookie": "^4.0.4",
|
"universal-cookie": "^4.0.4",
|
||||||
"vite": "^4.3.9",
|
"vite": "^4.3.9",
|
||||||
"vite-svg-loader": "^4.0.0",
|
"vite-svg-loader": "^4.0.0",
|
||||||
|
|||||||
17
src/Utils.ts
17
src/Utils.ts
@@ -1,6 +1,8 @@
|
|||||||
import { useOsTheme } from "naive-ui"
|
import { createDiscreteApi, useOsTheme } from 'naive-ui'
|
||||||
import { ThemeType } from "./api/api-models"
|
import { ThemeType } from './api/api-models'
|
||||||
import { useStorage } from "@vueuse/core"
|
import { useStorage } from '@vueuse/core'
|
||||||
|
|
||||||
|
const { message } = createDiscreteApi(['message'])
|
||||||
|
|
||||||
const osThemeRef = useOsTheme() //获取当前系统主题
|
const osThemeRef = useOsTheme() //获取当前系统主题
|
||||||
export function NavigateToNewTab(url: string) {
|
export function NavigateToNewTab(url: string) {
|
||||||
@@ -8,7 +10,14 @@ export function NavigateToNewTab(url: string) {
|
|||||||
}
|
}
|
||||||
const themeType = useStorage('Settings.Theme', ThemeType.Auto)
|
const themeType = useStorage('Settings.Theme', ThemeType.Auto)
|
||||||
export function isDarkMode(): boolean {
|
export function isDarkMode(): boolean {
|
||||||
|
|
||||||
if (themeType.value == ThemeType.Auto) return osThemeRef.value === 'dark'
|
if (themeType.value == ThemeType.Auto) return osThemeRef.value === 'dark'
|
||||||
else return themeType.value == ThemeType.Dark
|
else return themeType.value == ThemeType.Dark
|
||||||
}
|
}
|
||||||
|
export function copyToClipboard(text: string) {
|
||||||
|
if (navigator.clipboard) {
|
||||||
|
navigator.clipboard.writeText(text)
|
||||||
|
message.success('已复制到剪切板')
|
||||||
|
} else {
|
||||||
|
message.warning('当前环境不支持自动复制, 请手动选择并复制')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,12 +33,13 @@ import { NButton, NCard, NDivider, NLayoutContent, NSpace, NText, NTimeline, NTi
|
|||||||
</NSpace>
|
</NSpace>
|
||||||
<NDivider title-placement="left"> 更新日志 </NDivider>
|
<NDivider title-placement="left"> 更新日志 </NDivider>
|
||||||
<NTimeline>
|
<NTimeline>
|
||||||
|
<NTimelineItem type="success" title="功能添加" content="提问箱分享卡片" time="2023-10-25" />
|
||||||
<NTimelineItem type="success" title="功能添加" content="舰长及SC记录" time="2023-10-24" line-type="dashed" />
|
<NTimelineItem type="success" title="功能添加" content="舰长及SC记录" time="2023-10-24" line-type="dashed" />
|
||||||
<NTimelineItem type="info" content="开始运行" time="2023-10-23" />
|
<NTimelineItem type="info" content="开始运行" time="2023-10-23" />
|
||||||
</NTimeline>
|
</NTimeline>
|
||||||
</template>
|
</template>
|
||||||
</NCard>
|
</NCard>
|
||||||
<NButton @click="$router.push({ name: 'manage-index' })"> 回到主页 </NButton>
|
<NButton @click="$router.push({ name: 'manage-index' })"> 回到控制台 </NButton>
|
||||||
</NSpace>
|
</NSpace>
|
||||||
</NLayoutContent>
|
</NLayoutContent>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -55,13 +55,13 @@ const iconColor = 'white'
|
|||||||
<vtb />
|
<vtb />
|
||||||
<NSpace vertical justify="center">
|
<NSpace vertical justify="center">
|
||||||
<NGradientText
|
<NGradientText
|
||||||
size="3.6rem"
|
size="3rem"
|
||||||
:gradient="{
|
:gradient="{
|
||||||
deg: 180,
|
deg: 180,
|
||||||
from: '#e5e5e5',
|
from: '#e5e5e5',
|
||||||
to: '#c2ebeb',
|
to: '#c2ebeb',
|
||||||
}"
|
}"
|
||||||
style="font-family: Microsoft YaHei, Times New Roman, Times, serif; font-weight: 700"
|
style="font-weight: 700"
|
||||||
>
|
>
|
||||||
VTSURU.LIVE
|
VTSURU.LIVE
|
||||||
</NGradientText>
|
</NGradientText>
|
||||||
@@ -69,6 +69,7 @@ const iconColor = 'white'
|
|||||||
<span></span>
|
<span></span>
|
||||||
<NSpace justify="center">
|
<NSpace justify="center">
|
||||||
<NButton type="primary" size="large" @click="$router.push({ name: 'manage-index' })"> 开始使用 </NButton>
|
<NButton type="primary" size="large" @click="$router.push({ name: 'manage-index' })"> 开始使用 </NButton>
|
||||||
|
<NButton type="info" size="large" @click="$router.push({ name: 'about' })"> 关于 </NButton>
|
||||||
</NSpace>
|
</NSpace>
|
||||||
</NSpace>
|
</NSpace>
|
||||||
</NSpace>
|
</NSpace>
|
||||||
|
|||||||
@@ -3,10 +3,39 @@ import { QAInfo } from '@/api/api-models'
|
|||||||
import { QueryGetAPI, QueryPostAPI } from '@/api/query'
|
import { QueryGetAPI, QueryPostAPI } from '@/api/query'
|
||||||
import { ACCOUNT_API_URL, QUESTION_API_URL } from '@/data/constants'
|
import { ACCOUNT_API_URL, QUESTION_API_URL } from '@/data/constants'
|
||||||
import { Heart, HeartOutline } from '@vicons/ionicons5'
|
import { Heart, HeartOutline } from '@vicons/ionicons5'
|
||||||
import { NButton, NCard, NDivider, NIcon, NImage, NInput, NList, NListItem, NModal, NSpace, NSpin, NSwitch, NTabPane, NTabs, NTag, NText, NTime, NTooltip, useMessage } from 'naive-ui'
|
import {
|
||||||
|
NButton,
|
||||||
|
NCard,
|
||||||
|
NDivider,
|
||||||
|
NGradientText,
|
||||||
|
NIcon,
|
||||||
|
NImage,
|
||||||
|
NInput,
|
||||||
|
NInputGroup,
|
||||||
|
NList,
|
||||||
|
NListItem,
|
||||||
|
NModal,
|
||||||
|
NSpace,
|
||||||
|
NSpin,
|
||||||
|
NSwitch,
|
||||||
|
NTabPane,
|
||||||
|
NTabs,
|
||||||
|
NTag,
|
||||||
|
NText,
|
||||||
|
NTime,
|
||||||
|
NTooltip,
|
||||||
|
useMessage,
|
||||||
|
} from 'naive-ui'
|
||||||
import { computed, onMounted, ref } from 'vue'
|
import { computed, onMounted, ref } from 'vue'
|
||||||
import { List } from 'linqts'
|
import { List } from 'linqts'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
|
import html2canvas from 'html2canvas'
|
||||||
|
import QrcodeVue from 'qrcode.vue'
|
||||||
|
import { useAccount } from '@/api/account'
|
||||||
|
import { saveAs } from 'file-saver'
|
||||||
|
import { copyToClipboard } from '@/Utils'
|
||||||
|
|
||||||
|
const accountInfo = useAccount()
|
||||||
|
|
||||||
const recieveQuestions = ref<QAInfo[]>([])
|
const recieveQuestions = ref<QAInfo[]>([])
|
||||||
const recieveQuestionsFiltered = computed(() => {
|
const recieveQuestionsFiltered = computed(() => {
|
||||||
@@ -21,9 +50,13 @@ const onlyFavorite = ref(false)
|
|||||||
const isLoading = ref(true)
|
const isLoading = ref(true)
|
||||||
|
|
||||||
const replyModalVisiable = ref(false)
|
const replyModalVisiable = ref(false)
|
||||||
|
const shareModalVisiable = ref(false)
|
||||||
const currentQuestion = ref<QAInfo>()
|
const currentQuestion = ref<QAInfo>()
|
||||||
const replyMessage = ref()
|
const replyMessage = ref()
|
||||||
|
|
||||||
|
const shareCardRef = ref()
|
||||||
|
const shareUrl = computed(() => 'https://vtsuru.live/user/' + accountInfo.value?.name + '/question-box')
|
||||||
|
|
||||||
async function GetRecieveQAInfo() {
|
async function GetRecieveQAInfo() {
|
||||||
isLoading.value = true
|
isLoading.value = true
|
||||||
await QueryGetAPI<QAInfo[]>(QUESTION_API_URL + 'get-recieve')
|
await QueryGetAPI<QAInfo[]>(QUESTION_API_URL + 'get-recieve')
|
||||||
@@ -175,6 +208,27 @@ function refresh() {
|
|||||||
isRevieveGetted = false
|
isRevieveGetted = false
|
||||||
onTabChange(selectedTabItem.value)
|
onTabChange(selectedTabItem.value)
|
||||||
}
|
}
|
||||||
|
function saveShareImage() {
|
||||||
|
html2canvas(shareCardRef.value, {
|
||||||
|
width: shareCardRef.value.clientWidth, //dom 原始宽度
|
||||||
|
height: shareCardRef.value.clientHeight,
|
||||||
|
backgroundColor:null,
|
||||||
|
scrollY: 0, // html2canvas默认绘制视图内的页面,需要把scrollY,scrollX设置为0
|
||||||
|
scrollX: 0,
|
||||||
|
useCORS: true, //支持跨域,但好像没什么用
|
||||||
|
allowTaint: true, //允许跨域(默认false)
|
||||||
|
scale: 1,
|
||||||
|
}).then((canvas) => {
|
||||||
|
// 生成的ba64图片
|
||||||
|
canvas.toBlob(
|
||||||
|
(data) => {
|
||||||
|
saveAs(data, `vtsuru-提问箱-${accountInfo.value?.name}.png`)
|
||||||
|
},
|
||||||
|
'image/png',
|
||||||
|
1
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
GetRecieveQAInfo()
|
GetRecieveQAInfo()
|
||||||
@@ -182,9 +236,12 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<NButton type="primary" @click="refresh"> 刷新 </NButton>
|
<NSpace>
|
||||||
|
<NButton type="primary" @click="refresh"> 刷新 </NButton>
|
||||||
|
<NButton type="primary" @click="shareModalVisiable = true" secondary> 分享 </NButton>
|
||||||
|
</NSpace>
|
||||||
<NDivider style="margin: 10px 0 10px 0" />
|
<NDivider style="margin: 10px 0 10px 0" />
|
||||||
<NSpin v-if="isLoading" show/>
|
<NSpin v-if="isLoading" show />
|
||||||
<NTabs v-else animated @update:value="onTabChange" v-model:value="selectedTabItem">
|
<NTabs v-else animated @update:value="onTabChange" v-model:value="selectedTabItem">
|
||||||
<NTabPane tab="我收到的" name="0">
|
<NTabPane tab="我收到的" name="0">
|
||||||
只显示收藏 <NSwitch v-model:value="onlyFavorite" />
|
只显示收藏 <NSwitch v-model:value="onlyFavorite" />
|
||||||
@@ -290,10 +347,96 @@ onMounted(() => {
|
|||||||
<NDivider style="margin: 10px 0 10px 0" />
|
<NDivider style="margin: 10px 0 10px 0" />
|
||||||
<NButton :loading="isRepling" @click="reply" type="primary"> 发送 </NButton>
|
<NButton :loading="isRepling" @click="reply" type="primary"> 发送 </NButton>
|
||||||
</NModal>
|
</NModal>
|
||||||
|
<NModal v-model:show="shareModalVisiable" preset="card" title="分享" style="width: 600px">
|
||||||
|
<div ref="shareCardRef" class="share-card container">
|
||||||
|
<NText class="share-card title"> 向我提问 </NText>
|
||||||
|
<NText class="share-card type"> 提 问 箱 </NText>
|
||||||
|
<NText class="share-card name">
|
||||||
|
{{ accountInfo?.name }}
|
||||||
|
</NText>
|
||||||
|
<NDivider class="share-card divider-1" />
|
||||||
|
<NText class="share-card site"> VTSURU.LIVE </NText>
|
||||||
|
<QrcodeVue class="share-card qrcode" :value="shareUrl" level="Q" :size="100" background="#00000000" foreground="#ffffff" :margin="1" />
|
||||||
|
</div>
|
||||||
|
<NDivider style="margin: 10px" />
|
||||||
|
<NInputGroup>
|
||||||
|
<NInput :value="shareUrl" />
|
||||||
|
<NButton secondary @click="copyToClipboard(shareUrl)"> 复制 </NButton>
|
||||||
|
</NInputGroup>
|
||||||
|
<br /><br />
|
||||||
|
<NSpace justify="center">
|
||||||
|
<NButton type="primary" @click="saveShareImage"> 保存卡片 </NButton>
|
||||||
|
</NSpace>
|
||||||
|
</NModal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.n-list {
|
.n-list {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.share-card.container {
|
||||||
|
position: relative;
|
||||||
|
height: 200px;
|
||||||
|
width: 550px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: linear-gradient(to right, #66bea3, #9179be);
|
||||||
|
}
|
||||||
|
.share-card.qrcode {
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
top: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: linear-gradient(to right, #3d554e, #503e74);
|
||||||
|
}
|
||||||
|
.share-card.title {
|
||||||
|
position: absolute;
|
||||||
|
font-size: 80px;
|
||||||
|
bottom: -17px;
|
||||||
|
left: 5px;
|
||||||
|
color: #e6e6e662;
|
||||||
|
font-weight: 550;
|
||||||
|
}
|
||||||
|
/* .share-card.type {
|
||||||
|
position: absolute;
|
||||||
|
font-size: 20px;
|
||||||
|
transform:rotate(90deg);
|
||||||
|
left: 300px;
|
||||||
|
bottom: 20px;
|
||||||
|
color: #e6e6e6b6;
|
||||||
|
} */
|
||||||
|
.share-card.type {
|
||||||
|
position: absolute;
|
||||||
|
font-size: 20px;
|
||||||
|
left: 332px;
|
||||||
|
bottom: 55px;
|
||||||
|
font-weight: 550;
|
||||||
|
color: #e6e6e662;
|
||||||
|
}
|
||||||
|
.share-card.name {
|
||||||
|
position: absolute;
|
||||||
|
font-size: 30px;
|
||||||
|
left: 10px;
|
||||||
|
bottom: 95px;
|
||||||
|
max-width: 300px;
|
||||||
|
word-wrap: break-word;
|
||||||
|
line-height: 1.3;
|
||||||
|
color: #e6e6e6;
|
||||||
|
font-weight: 550;
|
||||||
|
}
|
||||||
|
.share-card.site {
|
||||||
|
position: absolute;
|
||||||
|
font-size: 12px;
|
||||||
|
right: 20px;
|
||||||
|
top: 110px;
|
||||||
|
color: #e6e6e6a4;
|
||||||
|
font-weight: 550;
|
||||||
|
}
|
||||||
|
.share-card.divider-1 {
|
||||||
|
position: absolute;
|
||||||
|
width: 400px;
|
||||||
|
left: 5px;
|
||||||
|
bottom: 66px;
|
||||||
|
background-color: #c0c0c057;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user