Merge branch 'abp-dev' of https://gitee.com/ccnetcore/Yi into abp-dev
This commit is contained in:
@@ -15,3 +15,10 @@ export function getWeek() {
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
// 获取全部数据
|
||||
export function getAccessList() {
|
||||
return request({
|
||||
url: "/access-log",
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
96
Yi.Bbs.Vue3/src/assets/atom-one-dark.css
Normal file
96
Yi.Bbs.Vue3/src/assets/atom-one-dark.css
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
|
||||
Atom One Dark by Daniel Gamage
|
||||
Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax
|
||||
|
||||
base: #282c34
|
||||
mono-1: #abb2bf
|
||||
mono-2: #818896
|
||||
mono-3: #5c6370
|
||||
hue-1: #56b6c2
|
||||
hue-2: #61aeee
|
||||
hue-3: #c678dd
|
||||
hue-4: #98c379
|
||||
hue-5: #e06c75
|
||||
hue-5-2: #be5046
|
||||
hue-6: #d19a66
|
||||
hue-6-2: #e6c07b
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
color: #abb2bf;
|
||||
background: #282c34;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #5c6370;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-doctag,
|
||||
.hljs-keyword,
|
||||
.hljs-formula {
|
||||
color: #c678dd;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name,
|
||||
.hljs-selector-tag,
|
||||
.hljs-deletion,
|
||||
.hljs-subst {
|
||||
color: #e06c75;
|
||||
}
|
||||
|
||||
.hljs-literal {
|
||||
color: #56b6c2;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-regexp,
|
||||
.hljs-addition,
|
||||
.hljs-attribute,
|
||||
.hljs-meta-string {
|
||||
color: #98c379;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-class .hljs-title {
|
||||
color: #e6c07b;
|
||||
}
|
||||
|
||||
.hljs-attr,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-type,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-number {
|
||||
color: #d19a66;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-link,
|
||||
.hljs-meta,
|
||||
.hljs-selector-id,
|
||||
.hljs-title {
|
||||
color: #61aeee;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
@@ -1,3 +1,71 @@
|
||||
<style scoped lang="scss">
|
||||
/*::v-dedp .markdown-body pre{
|
||||
padding: 0 !important;
|
||||
}*/
|
||||
::v-deep .pre-out
|
||||
{
|
||||
padding: 0;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
::v-deep .pre {
|
||||
padding: 0;
|
||||
margin-bottom: 0;
|
||||
overflow-x: hidden;
|
||||
.header {
|
||||
background-color: #409eff;
|
||||
color: white;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding-top: 10px;
|
||||
|
||||
|
||||
.language {}
|
||||
.copy:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
.copy {
|
||||
margin: 0px 10px;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.code-con {
|
||||
display: flex;
|
||||
|
||||
.nav {
|
||||
display: block;
|
||||
background-color: #282C34;
|
||||
|
||||
}
|
||||
|
||||
.code {
|
||||
display: block;
|
||||
padding: 10px 10px;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
border-radius: 4px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
::v-deep .nav-ul {
|
||||
border-right: 1px solid #FFFFFF;
|
||||
margin-top: 12px;
|
||||
padding-left: 10px;
|
||||
padding-right: 2px;
|
||||
|
||||
.nav-li {
|
||||
margin: 5.3px 0;
|
||||
text-align: right;
|
||||
margin-right: 3px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div>
|
||||
<div class="markdown-body" v-html="outputHtml"></div>
|
||||
@@ -9,24 +77,87 @@ import { marked } from 'marked';
|
||||
|
||||
import hljs from "highlight.js";
|
||||
//可以设置加载样式切换主题
|
||||
import 'highlight.js/styles/atom-one-dark.css'
|
||||
import '@/assets/atom-one-dark.css'
|
||||
import '@/assets/github-markdown.css'
|
||||
import { ref,watch } from 'vue';
|
||||
import {nextTick , ref, watch } from 'vue';
|
||||
const BREAK_LINE_REGEXP = /\r\n|\r|\n/g;
|
||||
|
||||
|
||||
|
||||
const outputHtml=ref("")
|
||||
const outputHtml = ref("")
|
||||
const props = defineProps(['code'])
|
||||
watch(props,(n,o)=>{
|
||||
let codeCopyDic=[];
|
||||
const addCopyEvent=()=>{
|
||||
const copySpans = document.querySelectorAll('.copy');
|
||||
console.log(copySpans,"copySpans");
|
||||
// 为每个 copy span 元素添加点击事件
|
||||
copySpans.forEach(span => {
|
||||
|
||||
span.addEventListener('click', async function() {
|
||||
await navigator.clipboard.writeText(codeCopyDic.filter(x=>x.id==span.id)[0].code );
|
||||
ElMessage({
|
||||
message: "代码块复制成功",
|
||||
type: "success",
|
||||
duration: 2000,
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//code部分处理、高亮
|
||||
const codeHandler = (code, language) => {
|
||||
const codeIndex = parseInt(Date.now() + "") + Math.floor(Math.random() * 10000000);
|
||||
// 格式化第一行是右侧language和 “复制” 按钮;
|
||||
if (code) {
|
||||
const navCode = navHandler(code)
|
||||
try {
|
||||
// 使用 highlight.js 对代码进行高亮显示
|
||||
const preCode = hljs.highlightAuto(code).value;
|
||||
// 将代码包裹在 textarea 中,由于防止textarea渲染出现问题,这里将 "<" 用 "<" 代替,不影响复制功能
|
||||
let html = `<pre class='hljs pre'><div class="header"><span class="language">${language}</span><span class="copy" id="${codeIndex}">复制代码</span></div><div class="code-con"><div class="nav">${navCode}</div><code class="code">${preCode}</code></div></pre>`;
|
||||
codeCopyDic.push({id: codeIndex,code:code});
|
||||
console.log(codeCopyDic.length);
|
||||
return html;
|
||||
//<textarea style="position: absolute;top: -9999px;left: -9999px;z-index: -9999;" id="copy${codeIndex}">${code.replace(/<\/textarea>/g, "</textarea>")}</textarea>
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//左侧导航栏处理
|
||||
const navHandler = (code) => {
|
||||
//获取行数
|
||||
var linesCount = getLinesCount(code);
|
||||
|
||||
var currentLine = 1;
|
||||
var liHtml = ``;
|
||||
while (linesCount + 1 >= currentLine) {
|
||||
liHtml += `<li class="nav-li">${currentLine}</li>`
|
||||
currentLine++
|
||||
}
|
||||
|
||||
let html = `<ul class="nav-ul">${liHtml}</ul>`
|
||||
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
const getLinesCount = (text) => {
|
||||
return (text.trim().match(BREAK_LINE_REGEXP) || []).length;
|
||||
}
|
||||
|
||||
watch(props, (n, o) => {
|
||||
codeCopyDic=[];
|
||||
marked.setOptions({
|
||||
renderer: new marked.Renderer(),
|
||||
highlight: function(code) {
|
||||
return hljs.highlightAuto(code).value;
|
||||
},
|
||||
highlight: function (code, language) {
|
||||
return codeHandler(code, language);
|
||||
// return hljs.highlightAuto(code).value;
|
||||
},
|
||||
pedantic: false,
|
||||
gfm: true,//允许 Git Hub标准的markdown
|
||||
tables: true,//支持表格
|
||||
|
||||
|
||||
breaks: true,
|
||||
sanitize: false,
|
||||
smartLists: true,
|
||||
@@ -36,8 +167,11 @@ watch(props,(n,o)=>{
|
||||
}
|
||||
);
|
||||
//需要注意代码块样式
|
||||
outputHtml.value = marked(n.code).replace(/<pre>/g, "<pre class='hljs'>")
|
||||
},{immediate:true,deep:true})
|
||||
|
||||
const soureHtml = marked(n.code);
|
||||
outputHtml.value= soureHtml.replace(/<pre>/g, '<pre class="pre-out">');
|
||||
nextTick(()=>{
|
||||
addCopyEvent();
|
||||
})
|
||||
}, { immediate: true, deep: true })
|
||||
</script>
|
||||
|
||||
|
||||
@@ -2,7 +2,12 @@
|
||||
import { ref } from "vue";
|
||||
|
||||
const props = defineProps(["items", "header", "text", "hideDivider", "height"]);
|
||||
const emit = defineEmits(['onClickText'])
|
||||
const height = ref(props.height + "px");
|
||||
|
||||
const onClickText=()=>{
|
||||
emit('onClickText')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -10,7 +15,7 @@ const height = ref(props.height + "px");
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>{{ props.header }}</span>
|
||||
<el-link :underline="false" type="primary">{{ props.text }}</el-link>
|
||||
<el-link :underline="false" type="primary" @click="onClickText">{{ props.text }}</el-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -6,22 +6,11 @@
|
||||
<ScrollbarInfo />
|
||||
</div>
|
||||
<el-row class="left-div">
|
||||
<el-col
|
||||
:span="8"
|
||||
v-for="i in plateList"
|
||||
:key="i.id"
|
||||
class="plate"
|
||||
:style="{
|
||||
'padding-left': i % 3 == 1 ? 0 : 0.2 + 'rem',
|
||||
'padding-right': i % 3 == 0 ? 0 : 0.2 + 'rem',
|
||||
}"
|
||||
>
|
||||
<PlateCard
|
||||
:name="i.name"
|
||||
:introduction="i.introduction"
|
||||
:id="i.id"
|
||||
:isPublish="i.isDisableCreateDiscuss"
|
||||
/>
|
||||
<el-col :span="8" v-for="i in plateList" :key="i.id" class="plate" :style="{
|
||||
'padding-left': i % 3 == 1 ? 0 : 0.2 + 'rem',
|
||||
'padding-right': i % 3 == 0 ? 0 : 0.2 + 'rem',
|
||||
}">
|
||||
<PlateCard :name="i.name" :introduction="i.introduction" :id="i.id" :isPublish="i.isDisableCreateDiscuss" />
|
||||
</el-col>
|
||||
<template v-if="isDiscussFinished">
|
||||
<el-col :span="24" v-for="i in discussList" :key="i.id">
|
||||
@@ -49,11 +38,7 @@
|
||||
<div class="carousel-font" :style="{ color: item.color }">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
<el-image
|
||||
style="width: 100%; height: 100%"
|
||||
:src="item.logo"
|
||||
fit="cover"
|
||||
/>
|
||||
<el-image style="width: 100%; height: 100%" :src="item.logo" fit="cover" />
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</el-col>
|
||||
@@ -101,20 +86,22 @@
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<InfoCard header="访问统计" class="VisitsLineChart" text="详情">
|
||||
<InfoCard header="访问统计" class="VisitsLineChart" text="(New)全站历史统计" @onClickText="onClickAccessLog">
|
||||
<template #content>
|
||||
<VisitsLineChart :option="statisOptions" class="statisChart" />
|
||||
</template>
|
||||
</InfoCard>
|
||||
|
||||
<el-dialog v-model="accessLogDialogVisible" title="全站历史统计" width="1200px" center>
|
||||
<AccessLogChart :option="accessLogOptins" class="accessLogChart" />
|
||||
</el-dialog>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<InfoCard header="简介" text="详情">
|
||||
<InfoCard header="简介" text="">
|
||||
<template #content>
|
||||
<div class="introduce">
|
||||
没有什么能够阻挡,人类对代码<span style="color: #1890ff"
|
||||
>优雅</span
|
||||
>的追求
|
||||
没有什么能够阻挡,人类对代码<span style="color: #1890ff">优雅</span>的追求
|
||||
</div>
|
||||
</template>
|
||||
</InfoCard>
|
||||
@@ -122,12 +109,7 @@
|
||||
|
||||
<el-col :span="24">
|
||||
<template v-if="isPointFinished">
|
||||
<InfoCard
|
||||
:items="pointList"
|
||||
header="财富排行榜"
|
||||
text="关于钱钱"
|
||||
height="400"
|
||||
>
|
||||
<InfoCard :items="pointList" header="财富排行榜" text="关于钱钱" height="400">
|
||||
<template #item="temp">
|
||||
<PointsRanking :pointsData="temp" />
|
||||
</template>
|
||||
@@ -135,19 +117,16 @@
|
||||
</template>
|
||||
<template v-else>
|
||||
<InfoCard header="本月排行" text="更多">
|
||||
<template #content> <Skeleton /></template>
|
||||
<template #content>
|
||||
<Skeleton />
|
||||
</template>
|
||||
</InfoCard>
|
||||
</template>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<template v-if="isFriendFinished">
|
||||
<InfoCard
|
||||
:items="friendList"
|
||||
header="推荐好友"
|
||||
text="更多"
|
||||
height="400"
|
||||
>
|
||||
<InfoCard :items="friendList" header="推荐好友" text="更多" height="400">
|
||||
<template #item="temp">
|
||||
<RecommendFriend :friendData="temp" />
|
||||
</template>
|
||||
@@ -155,18 +134,15 @@
|
||||
</template>
|
||||
<template v-else>
|
||||
<InfoCard header="推荐好友" text="更多">
|
||||
<template #content> <Skeleton /></template>
|
||||
<template #content>
|
||||
<Skeleton />
|
||||
</template>
|
||||
</InfoCard>
|
||||
</template>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<template v-if="isThemeFinished">
|
||||
<InfoCard
|
||||
:items="themeList"
|
||||
header="推荐主题"
|
||||
text="更多"
|
||||
height="400"
|
||||
>
|
||||
<InfoCard :items="themeList" header="推荐主题" text="更多" height="400">
|
||||
<template #item="temp">
|
||||
<ThemeData :themeData="temp" />
|
||||
</template>
|
||||
@@ -174,7 +150,9 @@
|
||||
</template>
|
||||
<template v-else>
|
||||
<InfoCard header="推荐主题" text="更多">
|
||||
<template #content> <Skeleton /></template>
|
||||
<template #content>
|
||||
<Skeleton />
|
||||
</template>
|
||||
</InfoCard>
|
||||
</template>
|
||||
</el-col>
|
||||
@@ -197,7 +175,8 @@ import PlateCard from "@/components/PlateCard.vue";
|
||||
import ScrollbarInfo from "@/components/ScrollbarInfo.vue";
|
||||
import BottomInfo from "@/components/BottomInfo.vue";
|
||||
import VisitsLineChart from "./components/VisitsLineChart/index.vue";
|
||||
import { access } from "@/apis/accessApi.js";
|
||||
import AccessLogChart from "./components/AccessLogChart/Index.vue"
|
||||
import { access, getAccessList } from "@/apis/accessApi.js";
|
||||
import { getList } from "@/apis/plateApi.js";
|
||||
import { getList as bannerGetList } from "@/apis/bannerApi.js";
|
||||
import { getHomeDiscuss } from "@/apis/discussApi.js";
|
||||
@@ -215,10 +194,10 @@ import ThemeData from "./components/RecommendTheme/index.vue";
|
||||
import Skeleton from "@/components/Skeleton/index.vue";
|
||||
import useSocketStore from "@/stores/socket";
|
||||
|
||||
|
||||
const accessLogDialogVisible = ref(false)
|
||||
const router = useRouter();
|
||||
|
||||
|
||||
const accessAllList = ref([]);
|
||||
|
||||
const plateList = ref([]);
|
||||
const discussList = ref([]);
|
||||
@@ -294,6 +273,25 @@ const statisOptions = computed(() => {
|
||||
},
|
||||
};
|
||||
});
|
||||
//历史全部访问统计
|
||||
const accessLogOptins = computed(() => {
|
||||
return {
|
||||
xAxis: {
|
||||
data: accessAllList.value?.map((item,index)=>{
|
||||
return item.creationTime.slice(0, 10);
|
||||
|
||||
})
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: accessAllList.value?.map((item,index)=>{
|
||||
return item.number;
|
||||
})
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const handleToSign = () => {
|
||||
router.push("/activity/sign");
|
||||
@@ -309,12 +307,19 @@ watch(
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
const onClickAccessLog = async () => {
|
||||
accessLogDialogVisible.value = true;
|
||||
const {data} = await getAccessList();
|
||||
|
||||
accessAllList.value = data;
|
||||
}
|
||||
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.home-box {
|
||||
width: 1300px;
|
||||
height: 100%;
|
||||
|
||||
.introduce {
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
font-size: small;
|
||||
@@ -350,6 +355,7 @@ watch(
|
||||
display: block;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.analyse {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -357,6 +363,7 @@ watch(
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.item {
|
||||
width: 30%;
|
||||
height: 100%;
|
||||
@@ -368,6 +375,7 @@ watch(
|
||||
border: 1px solid #409eff;
|
||||
border-radius: 5px;
|
||||
color: #409eff;
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -385,6 +393,7 @@ watch(
|
||||
.name {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.count {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
@@ -407,11 +416,13 @@ watch(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.signIn {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
color: #8a919f;
|
||||
|
||||
&-btn {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
@@ -426,7 +437,7 @@ watch(
|
||||
}
|
||||
}
|
||||
|
||||
.VisitsLineChart >>> .el-card__body {
|
||||
.VisitsLineChart>>>.el-card__body {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
@@ -434,5 +445,10 @@ watch(
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.accessLogChart {
|
||||
width: 1100px;
|
||||
height: 500px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<template>
|
||||
<div class="v-chart" ref="statis"></div>
|
||||
</template>
|
||||
|
||||
<script setup name="AccessLogChart">
|
||||
import { ref, defineEmits, defineProps, defineExpose } from "vue";
|
||||
import useEcharts from "@/hooks/useEcharts";
|
||||
import { accessLogEchartsConfig } from "../../hooks/accessLogEchartsConfig";
|
||||
const props = defineProps({
|
||||
option: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
const emits = defineEmits([
|
||||
"chart-click", // 点击chart
|
||||
]);
|
||||
|
||||
let statis = ref(null);
|
||||
const { resize } = useEcharts(statis, emits, props, accessLogEchartsConfig);
|
||||
defineExpose({
|
||||
resize,
|
||||
});
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.v-chart {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
18
Yi.Bbs.Vue3/src/views/home/hooks/accessLogEchartsConfig.js
Normal file
18
Yi.Bbs.Vue3/src/views/home/hooks/accessLogEchartsConfig.js
Normal file
@@ -0,0 +1,18 @@
|
||||
export const accessLogEchartsConfig = {
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: []
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: [],
|
||||
type: 'line',
|
||||
areaStyle: {}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
@@ -79,8 +79,22 @@ const startCallback = () => {
|
||||
// 假设后端返回的中奖索引是0
|
||||
// 调用stop停止旋转并传递中奖索引
|
||||
}, 3000)
|
||||
|
||||
try
|
||||
{
|
||||
const ddd=(await luckyWheel()).data;
|
||||
console.log(ddd,"dd");
|
||||
index= (await luckyWheel()).data;
|
||||
myLucky.value.stop(index)
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
finally{
|
||||
|
||||
myLucky.value.stop(index)
|
||||
}
|
||||
|
||||
|
||||
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user