Merge branch 'abp-dev' of https://gitee.com/ccnetcore/Yi into abp-dev

This commit is contained in:
橙子
2024-03-03 15:58:23 +08:00
17 changed files with 518 additions and 72 deletions

View File

@@ -15,3 +15,10 @@ export function getWeek() {
method: "get",
});
}
// 获取全部数据
export function getAccessList() {
return request({
url: "/access-log",
method: "get",
});
}

View 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;
}

View File

@@ -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渲染出现问题这里将 "<" 用 "&lt;" 代替,不影响复制功能
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, "&lt;/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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -0,0 +1,18 @@
export const accessLogEchartsConfig = {
xAxis: {
type: 'category',
boundaryGap: false,
data: []
},
yAxis: {
type: 'value'
},
series: [
{
data: [],
type: 'line',
areaStyle: {}
}
]
};

View File

@@ -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)
}
})