|
@@ -0,0 +1,267 @@
|
|
|
+import { useArticle } from "@/modules";
|
|
|
+import { css } from "@linaria/core";
|
|
|
+import loading from "@/components/Provider/Loading";
|
|
|
+import { defineComponent, onMounted, reactive, watch } from "vue";
|
|
|
+import Image from "@/components/Image";
|
|
|
+import { any, object } from "vue-types";
|
|
|
+import List from "./List";
|
|
|
+import { useRoute, useRouter } from "vue-router";
|
|
|
+import dayjs from "dayjs";
|
|
|
+const teacherList = [
|
|
|
+ "6464ae7a8dcb7ddb98b57a28",
|
|
|
+ "6464b7ca8dcb7ddb98b57a63",
|
|
|
+ "6464b7d18dcb7ddb98b57a64",
|
|
|
+ "6464b7d78dcb7ddb98b57a65",
|
|
|
+ "6464b7dd8dcb7ddb98b57a66",
|
|
|
+ "6464b7e38dcb7ddb98b57a67",
|
|
|
+ "6464b7e98dcb7ddb98b57a68",
|
|
|
+ "6464b7f08dcb7ddb98b57a69",
|
|
|
+ "6464b7f68dcb7ddb98b57a6a",
|
|
|
+];
|
|
|
+export default defineComponent({
|
|
|
+ props: {
|
|
|
+ data: object<CategoryItem>(),
|
|
|
+ },
|
|
|
+ setup(props, { emit }) {
|
|
|
+ const data: any = props.data || {};
|
|
|
+ const artStore = useArticle();
|
|
|
+ artStore.listController.state.list = [];
|
|
|
+ const route = useRoute();
|
|
|
+ onMounted(() => {
|
|
|
+ initDetail();
|
|
|
+ });
|
|
|
+ watch(
|
|
|
+ () => route.query.page,
|
|
|
+ () => {
|
|
|
+ initDetail();
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ const initDetail = async () => {
|
|
|
+ loading.show("");
|
|
|
+ let page: any = 1;
|
|
|
+ if (route.query.page) {
|
|
|
+ page = route.query.page as string;
|
|
|
+ }
|
|
|
+ artStore.listController.state.query = JSON.stringify({
|
|
|
+ cid: data._id,
|
|
|
+ });
|
|
|
+ await artStore.listController.loadPage(page * 1);
|
|
|
+ loading.hidden();
|
|
|
+ };
|
|
|
+ const itemRender = (item: any, index: number) => {
|
|
|
+ if (teacherList.includes(data._id)) {
|
|
|
+ return <TeacherItem item={item} key={item._id} />;
|
|
|
+ }
|
|
|
+ return <ArticleItem item={item} key={item._id} />;
|
|
|
+ };
|
|
|
+ return () => {
|
|
|
+ return (
|
|
|
+ <div class={page}>
|
|
|
+ <div class={"list_content"}>
|
|
|
+ <List
|
|
|
+ dataSource={artStore.listController.state.list}
|
|
|
+ actions={artStore.listController}
|
|
|
+ >
|
|
|
+ {{
|
|
|
+ item: (item: any, index: number) => {
|
|
|
+ return itemRender(item, index);
|
|
|
+ },
|
|
|
+ }}
|
|
|
+ </List>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ };
|
|
|
+ },
|
|
|
+});
|
|
|
+const TeacherItem = defineComponent({
|
|
|
+ props: {
|
|
|
+ item: any(),
|
|
|
+ },
|
|
|
+ setup(props, ctx) {
|
|
|
+ const { item } = props;
|
|
|
+ const router = useRouter();
|
|
|
+ const route = useRoute();
|
|
|
+ return () => (
|
|
|
+ <div class={TeacherItemStyle}>
|
|
|
+ <div
|
|
|
+ class={"item"}
|
|
|
+ onClick={() => {
|
|
|
+ const id = route.params.id;
|
|
|
+ const aid = item._id;
|
|
|
+ router.push({ name: "article", params: { id }, query: { aid } });
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Image src={item.cover} />
|
|
|
+ <div class={"item_footer"}>
|
|
|
+ <div class={"name"}>{item.title}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ },
|
|
|
+});
|
|
|
+const ArticleItem = defineComponent({
|
|
|
+ props: {
|
|
|
+ item: object<ArticleItem>(),
|
|
|
+ },
|
|
|
+ setup(props) {
|
|
|
+ const { item } = props;
|
|
|
+ const router = useRouter();
|
|
|
+ const route = useRoute();
|
|
|
+ const renderTitle = (title?: string) => {
|
|
|
+ if (title && title.length > 30) {
|
|
|
+ return title.substring(0, 30) + "...";
|
|
|
+ }
|
|
|
+ return title;
|
|
|
+ };
|
|
|
+ const renderSummary = (summary?: string) => {
|
|
|
+ if (summary && summary.length > 60) {
|
|
|
+ return summary.substring(0, 60) + "...";
|
|
|
+ }
|
|
|
+ return summary;
|
|
|
+ };
|
|
|
+ return () => (
|
|
|
+ <div class={ListItemStyle}>
|
|
|
+ <div
|
|
|
+ class={"item"}
|
|
|
+ onClick={() => {
|
|
|
+ const id = route.params.id;
|
|
|
+ const aid = item?._id;
|
|
|
+ router.push({ name: "article", params: { id }, query: { aid } });
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <div class={"list_img"}>
|
|
|
+ <Image src={item?.cover} />
|
|
|
+ </div>
|
|
|
+ <div class={"info_box"}>
|
|
|
+ <div class={"item_tit"}>{renderTitle(item?.title)}</div>
|
|
|
+ <div class={"item_desc"}>{renderSummary(item?.summary)}</div>
|
|
|
+ <div class={"item_date"}>
|
|
|
+ {dayjs(item?.createTime).format("YYYY.MM.DD")}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ },
|
|
|
+});
|
|
|
+const page = css``;
|
|
|
+const TeacherItemStyle = css`
|
|
|
+ width: 100%;
|
|
|
+ height: 380px;
|
|
|
+ overflow: hidden;
|
|
|
+ .item {
|
|
|
+ display: block;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+ cursor: pointer;
|
|
|
+ img {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ object-fit: cover;
|
|
|
+ }
|
|
|
+ &:hover {
|
|
|
+ .item_footer {
|
|
|
+ transform: translateY(0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .item_footer {
|
|
|
+ position: absolute;
|
|
|
+ display: inline-flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: flex-end;
|
|
|
+ bottom: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 140px;
|
|
|
+ padding: 0 24px 20px;
|
|
|
+ transform: translateY(100%);
|
|
|
+ background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, #000000 100%);
|
|
|
+ transition: all 0.3s ease-in-out;
|
|
|
+ }
|
|
|
+ .name {
|
|
|
+ color: #fff;
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+ }
|
|
|
+`;
|
|
|
+const ListItemStyle = css`
|
|
|
+ width: 100%;
|
|
|
+ background-color: #fff;
|
|
|
+ overflow: hidden;
|
|
|
+ position: relative;
|
|
|
+ .item {
|
|
|
+ position: relative;
|
|
|
+ display: block;
|
|
|
+ border-bottom: 2px solid rgba(159, 159, 159, 0.5);
|
|
|
+ cursor: pointer;
|
|
|
+ &::before {
|
|
|
+ content: "";
|
|
|
+ position: absolute;
|
|
|
+ bottom: 0;
|
|
|
+ right: 0;
|
|
|
+ border-width: 6px;
|
|
|
+ border-color: transparent rgba(159, 159, 159, 0.5)
|
|
|
+ rgba(159, 159, 159, 0.5) transparent;
|
|
|
+ }
|
|
|
+ &::after {
|
|
|
+ content: "";
|
|
|
+ position: absolute;
|
|
|
+ bottom: -2px;
|
|
|
+ right: 0;
|
|
|
+ width: 0;
|
|
|
+ height: 2px;
|
|
|
+ background-color: var(--vt-c-primary);
|
|
|
+ transition: width 0.3s ease-in-out;
|
|
|
+ }
|
|
|
+ &:hover {
|
|
|
+ &::before {
|
|
|
+ border-color: transparent var(--vt-c-primary) var(--vt-c-primary)
|
|
|
+ transparent;
|
|
|
+ }
|
|
|
+ &::after {
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+ img {
|
|
|
+ transform: scale(1.2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .list_img {
|
|
|
+ width: 100%;
|
|
|
+ height: 280px;
|
|
|
+ overflow: hidden;
|
|
|
+ }
|
|
|
+ img {
|
|
|
+ width: 100%;
|
|
|
+ height: 280px;
|
|
|
+ object-fit: cover;
|
|
|
+ transition: all 0.3s ease-in-out;
|
|
|
+ }
|
|
|
+ .info_box {
|
|
|
+ padding: 16px 12px;
|
|
|
+ }
|
|
|
+ .item_tit {
|
|
|
+ font-size: 16px;
|
|
|
+ line-height: 24px;
|
|
|
+ color: #333333;
|
|
|
+ }
|
|
|
+ .item_desc {
|
|
|
+ margin-top: 16px;
|
|
|
+ font-size: 12px;
|
|
|
+ line-height: 20px;
|
|
|
+ font-weight: 400;
|
|
|
+ color: #666666;
|
|
|
+ }
|
|
|
+ .item_date {
|
|
|
+ font-size: 12px;
|
|
|
+ margin-top: 18px;
|
|
|
+ font-weight: 300;
|
|
|
+ color: #999999;
|
|
|
+ }
|
|
|
+`;
|