Initial project

This commit is contained in:
Timi
2025-07-16 16:35:28 +08:00
parent 1e8213575b
commit 1c1f2f6594
36 changed files with 11610 additions and 129 deletions

View File

@ -0,0 +1,168 @@
<template>
<div v-if="article" class="article-software">
<p class="time" v-text="articleTime" @click="isCreatedAt = !isCreatedAt"></p>
<div class="header">
<img class="logo" :src="coverUrl" alt="程序封面" />
<div v-if="article.extendData" class="info">
<div>
<span>官网</span>
<a :href="article.extendData.url" v-text="article.extendData.url"></a>
</div>
<div>
<span>版本</span>
<span class="selectable" v-text="article.extendData.version"></span>
</div>
<div>
<span>文件格式</span>
<span class="selectable" v-text="article.extendData.format"></span>
</div>
<div class="runtimes">
<span>运行环境</span>
<span
class="runtime"
v-for="item in article.extendData.runtime"
v-text="`${item} `"
:key="item"
></span>
</div>
<div>
<span>大小</span>
<span v-text="IOSize.format(article.extendData.size)"></span>
</div>
<div class="downloads">
<span>下载</span>
<a
class="download"
v-for="item in article.extendData.downloads"
:href="Toolkit.toResURL(item.value)"
:key="item.value"
v-text="item.type"
target="_blank"
></a>
</div>
<div>
<span>解压密码</span>
<span class="selectable" v-text="article.extendData.password"></span>
</div>
</div>
</div>
<markdown-view class="content" :content="article.data" />
</div>
<comment
v-if="SettingMapper.is(SettingKey.ENABLE_COMMENT) && article && article.showComment"
:bizType="CommentBizType.ARTICLE"
:bizId="article.id!"
:titleStickyOffset="80"
:canComment="article.canComment"
/>
</template>
<script lang="ts" setup>
import { ArticleAttachType, ArticleSoftwareExtendData, ArticleView } from "@/types/Article.ts";
import { CommentBizType, CommonAPI, IOSize, MarkdownView, SettingKey, SettingMapper, Time, Toolkit } from "timi-web";
import { Comment } from "timi-tdesign-pc";
const props = defineProps<{
article?: ArticleView<ArticleSoftwareExtendData>,
}>();
const { article } = toRefs(props);
const isCreatedAt = ref<boolean>(false);
const articleTime = computed(() => {
if (article.value) {
if (isCreatedAt.value || !article.value.updatedAt) {
return "发布于 " + Time.toPassedDateTime(article.value.createdAt);
} else {
return "编辑于 " + Time.toPassedDateTime(article.value.updatedAt);
}
}
});
const coverUrl = computed(() => {
if (article.value && article.value.attachmentList) {
for (let i = 0; i < article.value.attachmentList.length; i++) {
const item = article.value.attachmentList[i];
const attachType = (<any>ArticleAttachType)[item.attachType!];
if (attachType === ArticleAttachType.COVER) {
return CommonAPI.getAttachmentReadAPI(item.mongoId);
}
}
}
return undefined;
})
</script>
<style lang="less" scoped>
.article-software {
.time {
text-align: center;
}
.header {
display: flex;
padding: 1rem;
margin-bottom: 2rem;
.logo {
width: 140px;
height: 140px;
transition: 520ms var(--tui-bezier);
}
.info {
font-size: 13px;
border-left: 2px solid var(--tui-light-gray);
margin-left: 1rem;
padding-left: 1rem;
> div {
margin-bottom: 4px;
> span:first-child {
color: #666;
padding: 2px 0;
}
}
.downloads {
.download {
border: 1px solid #FF7A9B;
padding: 1px 4px;
background: transparent;
margin-right: 6px;
&:hover {
color: #FFF;
background: #FF7A9B;
}
&:active {
background: #FFAAC0;
}
}
}
}
}
.content {
width: calc(100% - 2rem);
padding: 1rem;
}
}
@media screen and (max-width: 650px) {
.article-software {
.header {
.logo {
width: 70px;
height: 70px;
}
}
}
}
</style>