|
@@ -0,0 +1,211 @@
|
|
|
+<template>
|
|
|
+ <!-- 资讯详情页 -->
|
|
|
+ <div class="main-background">
|
|
|
+ <div class="nav-placeholder"></div>
|
|
|
+ <!-- 新闻 -->
|
|
|
+ <section class="main-section main-background main-background-type0 small-h">
|
|
|
+ <div class="content mb-2">
|
|
|
+ <!-- 路径 -->
|
|
|
+ <a-breadcrumb>
|
|
|
+ <a-breadcrumb-item><a href="" @click="navTo('/')">首页</a></a-breadcrumb-item>
|
|
|
+ <a-breadcrumb-item>{{ title }}</a-breadcrumb-item>
|
|
|
+ </a-breadcrumb>
|
|
|
+ </div>
|
|
|
+ <div class="content mb-2">
|
|
|
+ <!-- 搜素栏 -->
|
|
|
+ <div class="row mt-3">
|
|
|
+ <!-- 左栏 -->
|
|
|
+ <div class="col-sm-12 col-md-6 col-lg-6">
|
|
|
+ <!-- 分类 -->
|
|
|
+ <TagBar
|
|
|
+ :tags="tagsData || []"
|
|
|
+ :margin="[30, 70]"
|
|
|
+ v-model:selectedTag="selectedTag"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <!-- 右栏 -->
|
|
|
+ <div class="col-sm-12 col-md-6 col-lg-6 d-flex flex-row justify-content-end">
|
|
|
+ <Dropdown
|
|
|
+ v-for="(drop, k) in dropDownNames" :key="k"
|
|
|
+ :selectedValue="dropDownValues[k] || drop.defaultSelectedValue"
|
|
|
+ :options="drop.options"
|
|
|
+ @update:selectedValue="(v) => handleChangeDropDownValue(k, v)"
|
|
|
+ />
|
|
|
+ <SimpleInput v-if="showSearch" v-model="searchText" placeholder="请输入关键词" @enter="handleSearch">
|
|
|
+ <template #suffix>
|
|
|
+ <img
|
|
|
+ class="search-icon"
|
|
|
+ src="@/assets/images/news/IconSearch.png"
|
|
|
+ alt="搜索"
|
|
|
+ @click="newsLoader.loadData(undefined, true)"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ </SimpleInput>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="content news-list">
|
|
|
+ <!-- 新闻列表 -->
|
|
|
+ <SimplePageContentLoader :loader="newsLoader">
|
|
|
+ <div
|
|
|
+ v-for="(item, k) in newsLoader.list.value"
|
|
|
+ :key="item.id"
|
|
|
+ class="item user-select-none main-clickable"
|
|
|
+ :style="{ width: rowWidth }"
|
|
|
+ @click="navTo('/news/detail', { id: item.id })"
|
|
|
+ >
|
|
|
+ <img :src="item.image" alt="新闻图片" />
|
|
|
+ <TitleDescBlock
|
|
|
+ :title="item.title"
|
|
|
+ :desc="item.desc || item.title"
|
|
|
+ :date="DateUtils.formatDate(item.publish_at, DateUtils.FormatStrings.YearCommon)"
|
|
|
+ @click="handleShowDetail(item)"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </SimplePageContentLoader>
|
|
|
+ <!-- 分页 -->
|
|
|
+ <Pagination
|
|
|
+ v-model:currentPage="newsLoader.page.value"
|
|
|
+ :totalPages="newsLoader.totalPages.value"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </section>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+import { computed, onMounted, ref, watch, type PropType } from 'vue';
|
|
|
+import { useSimplePagerDataLoader } from '@/composeable/SimplePagerDataLoader';
|
|
|
+import { usePageAction } from '@/composeable/PageAction';
|
|
|
+import DateUtils from '@/common/utils/DateUtils';
|
|
|
+import TagBar from '../content/TagBar.vue';
|
|
|
+import Dropdown from '../controls/Dropdown.vue';
|
|
|
+import SimpleInput from '../controls/SimpleInput.vue';
|
|
|
+import SimplePageContentLoader from '@/components/content/SimplePageContentLoader.vue';
|
|
|
+import Pagination from '../controls/Pagination.vue';
|
|
|
+import TitleDescBlock from '../parts/TitleDescBlock.vue';
|
|
|
+
|
|
|
+const { navTo } = usePageAction();
|
|
|
+
|
|
|
+export interface DropdownCommonItem {
|
|
|
+ value: number;
|
|
|
+ title: string;
|
|
|
+}
|
|
|
+export interface DropDownNames {
|
|
|
+ options: (string|DropdownCommonItem)[],
|
|
|
+ defaultSelectedValue: number|string,
|
|
|
+}
|
|
|
+
|
|
|
+const props = defineProps({
|
|
|
+ title: {
|
|
|
+ type: String,
|
|
|
+ default: '',
|
|
|
+ },
|
|
|
+ dropDownNames: {
|
|
|
+ type: Object as PropType<DropDownNames[]>,
|
|
|
+ default: null,
|
|
|
+ },
|
|
|
+ showSearch: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true,
|
|
|
+ },
|
|
|
+ tagsData: {
|
|
|
+ type: Object as PropType<{
|
|
|
+ id: number,
|
|
|
+ name: string,
|
|
|
+ }[]>,
|
|
|
+ default: null,
|
|
|
+ },
|
|
|
+ pageSize: {
|
|
|
+ type: Number,
|
|
|
+ default: 8,
|
|
|
+ },
|
|
|
+ rowCount: {
|
|
|
+ type: Number,
|
|
|
+ default: 2,
|
|
|
+ },
|
|
|
+ rowType: {
|
|
|
+ type: Number,
|
|
|
+ default: 1,
|
|
|
+ },
|
|
|
+ defaultSelectTag: {
|
|
|
+ type: Number,
|
|
|
+ default: 1,
|
|
|
+ },
|
|
|
+ load: {
|
|
|
+ type: Function as PropType<(
|
|
|
+ page: number,
|
|
|
+ pageSize: number,
|
|
|
+ selectedTag: number,
|
|
|
+ searchText: string,
|
|
|
+ dropDownValues: number[],
|
|
|
+ ) => Promise<{
|
|
|
+ page: number,
|
|
|
+ total: number,
|
|
|
+ data: any[],
|
|
|
+ }>>,
|
|
|
+ required: true,
|
|
|
+ },
|
|
|
+})
|
|
|
+
|
|
|
+const rowWidth = computed(() => {
|
|
|
+ switch (props.rowCount) {
|
|
|
+ case 2:
|
|
|
+ return `calc(50% - 100px)`;
|
|
|
+ case 3:
|
|
|
+ return `calc(33% - 100px)`;
|
|
|
+ case 4:
|
|
|
+ return `calc(25% - 100px)`;
|
|
|
+ }
|
|
|
+});
|
|
|
+const rowMargin = computed(() => {
|
|
|
+ switch (props.rowCount) {
|
|
|
+ case 2:
|
|
|
+ return 30;
|
|
|
+ case 3:
|
|
|
+ return 30;
|
|
|
+ case 4:
|
|
|
+ return 30;
|
|
|
+ }
|
|
|
+ return '0';
|
|
|
+});
|
|
|
+const searchText = ref('');
|
|
|
+const dropDownValues = ref<any>([]);
|
|
|
+
|
|
|
+function handleSearch() {
|
|
|
+ newsLoader.loadData(undefined, true);
|
|
|
+}
|
|
|
+function handleChangeDropDownValue(index: number, value: number) {
|
|
|
+ dropDownValues.value[index] = value;
|
|
|
+ newsLoader.loadData(undefined, true);
|
|
|
+}
|
|
|
+function handleShowDetail(item: any) {
|
|
|
+ navTo('/news/detail', { id: item.id });
|
|
|
+}
|
|
|
+
|
|
|
+const newsLoader = useSimplePagerDataLoader(props.pageSize, (page, size) => props.load(
|
|
|
+ page, size,
|
|
|
+ selectedTag.value,
|
|
|
+ searchText.value,
|
|
|
+ dropDownValues.value,
|
|
|
+));
|
|
|
+
|
|
|
+//子分类
|
|
|
+const selectedTag = ref(props.defaultSelectTag);
|
|
|
+
|
|
|
+watch(selectedTag, () => {
|
|
|
+ newsLoader.loadData(undefined, true);
|
|
|
+})
|
|
|
+onMounted(() => {
|
|
|
+ newsLoader.loadData(undefined, true);
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+.search-icon {
|
|
|
+ width: 20px;
|
|
|
+ height: 20px;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+</style>
|
|
|
+
|