| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- <template>
- <!--通用内容首页小分块组件-->
- <FlexCol width="100%">
- <!-- 分类 -->
- <FlexCol
- v-for="(category,i) in categoryDatas" :key="i"
- :innerStyle="category.style"
- >
- <HomeTitle
- v-if="category.showTitle"
- :title="category.title"
- :showMore="category.showMore !== false"
- :showIcon="category.showIcon !== false"
- :showTopMargin="category.showTopMargin !== false"
- :icon="category.icon"
- :size="category.size || 'medium'"
- :subTitle="category.subTitle"
- :center="category.center"
- :moreText="category.moreText || '更多'"
- @moreClicked="category.morePage"
- >
- <template v-if="category.titleRightButtons" #right>
- <FlexRow align="center" gap="gap.md">
- <FrameButton
- v-for="item in category.titleRightButtons"
- :key="item.text"
- :text="item.text"
- :size="item.size"
- :primary="item.primary || false"
- @click="() => scriptEngine.execute(item.handler, getNodeContext(), { params: { item } })"
- />
- <Width :size="15" />
- </FlexRow>
- </template>
- </HomeTitle>
- <!--预制块-->
- <template v-if="category.type === 'RichBlock'">
- <RichBlock
- v-bind="category.blockProps"
- :scriptEngine="scriptEngine"
- :getNodeContext="getNodeContext"
- />
- </template>
- <!--通用列表-->
- <SimplePageContentLoader v-else-if="category.data" :loader="category.data" >
- <FlexCol>
- <template v-if="category.type === 'simple-article'">
- <FlexCol :margin="[10, 0]">
- <Box2LineImageRightShadow
- v-for="(item, i) in category.data.content.value"
- :key="i"
- :title="item.title"
- :titleBox="item.titleBox"
- :desc="item.desc"
- :tags="(item.bottomTags as string[])"
- :props="item.props"
- @click="category.detailsPage(item)"
- />
- </FlexCol>
- </template>
- <template v-else-if="category.type === 'large-image'">
- <FlexCol>
- <Box2LineLargeImageUserShadow
- v-for="(item, i) in category.data.content.value"
- titleColor="title-text"
- fixSize
- title1
- :key="i"
- :title="item.title"
- :titleBox="Boolean(item.titleBox)"
- :desc="item.desc"
- :image="item.image"
- :tags="(item.bottomTags as string[])"
- :props="item.props"
- @click="category.detailsPage(item)"
- />
- </FlexCol>
- </template>
- <template v-else-if="category.type === 'large-image2'">
- <scroll-view scroll-x>
- <FlexRow>
- <Box2LineLargeImageUserShadow
- v-for="(item, i) in category.data.content.value"
- :width="400"
- titleColor="title-text"
- fixSize
- title1
- :key="i"
- :title="item.title"
- :titleBox="Boolean(item.titleBox)"
- :desc="item.desc"
- :image="item.image"
- :tags="(item.bottomTags as string[])"
- :props="item.props"
- @click="category.detailsPage(item)"
- />
- </FlexRow>
- </scroll-view>
- </template>
- <template v-else-if="category.type === 'horizontal-large'">
- <scroll-view scroll-x>
- <FlexRow :padding="[20,0]" overflow="visible" align="stretch">
- <Box2LineLargeImageUserShadow
- v-for="(item, i) in category.data.content.value"
- :width="400"
- titleColor="title-text"
- title1
- fixSize
- :key="i"
- :title="item.title"
- :titleBox="Boolean(item.titleBox)"
- :desc="item.desc"
- :image="item.thumbnail || item.image"
- :tags="(item.bottomTags as string[])"
- :props="item.props"
- @click="category.detailsPage(item)"
- />
- </FlexRow>
- </scroll-view>
- </template>
- <template v-else-if="category.type === 'large-grid2'">
- <FlexRow wrap align="stretch" justify="space-between" overflow="visible">
- <Box2LineLargeImageUserShadow
- v-for="(item, i) in category.data.content.value"
- titleColor="title-text"
- width="calc(50% - 10rpx)"
- fixSize
- :key="i"
- :title="item.title"
- :titleBox="Boolean(item.titleBox)"
- :desc="item.desc"
- :image="item.image"
- :tags="(item.bottomTags as string[])"
- :props="item.props"
- @click="category.detailsPage(item)"
- />
- </FlexRow>
- </template>
- <template v-else-if="category.type === 'small-grid2'">
- <FlexRow wrap justify="space-between" align="stretch">
- <IndexRoundSimpleItem
- v-for="(tab, k) in category.data.content.value"
- :key="k"
- :item="{
- title: tab.title,
- image: tab.thumbnail || tab.image,
- }"
- :half="true"
- :props="tab.props"
- @click="category.detailsPage(tab)"
- />
- </FlexRow>
- </template>
- <template v-else-if="category.type === 'small-grid'">
- <FlexCol :gap="10" align="center">
- <IndexRoundSimpleItem
- v-for="(tab, k) in category.data.content.value"
- :key="k"
- :item="{
- title: tab.title,
- image: tab.thumbnail || tab.image,
- }"
- :half="false"
- :props="tab.props"
- :imageHeight="400"
- @click="category.detailsPage(tab)"
- />
- </FlexCol>
- </template>
- <template v-else-if="category.type === 'simple-text'">
- <FlexCol>
- <Box2LineImageRightShadow
- v-for="(item, i) in category.data.content.value"
- titleColor="title-text"
- :border="false"
- fixSize
- :key="i"
- :title="item.title"
- :titleBox="Boolean(item.titleBox)"
- :desc="item.desc"
- :showImage="false"
- :props="item.props"
- :tags="(item.bottomTags as string[])"
- />
- </FlexCol>
- </template>
- <template v-else-if="category.type === 'article'">
- <Box2LineImageRightShadow
- v-for="(item, i) in category.data.content.value"
- titleColor="title-text"
- fixSize
- wideImage
- :key="i"
- :title="item.title"
- :titleBox="Boolean(item.titleBox)"
- :desc="item.desc"
- :image="item.image"
- :tags="(item.bottomTags as string[])"
- :props="item.props"
- @click="category.detailsPage(item)"
- />
- </template>
- <template v-else-if="category.type === 'box-grid'">
- <FlexRow wrap justify="space-between" align="stretch">
- <IndexRoundBoxSimpleItem
- v-for="(tab, k) in category.data.content.value"
- :key="k"
- :item="tab"
- :iconSize="tab.iconSize"
- :props="tab.props"
- @click="category.detailsPage(tab)"
- />
- </FlexRow>
- </template>
- <template v-else>
- <Box2LineImageRightShadow
- v-for="(item, i) in category.data.content.value"
- titleColor="title-text"
- fixSize
- :key="i"
- :title="item.title"
- :titleBox="Boolean(item.titleBox)"
- :desc="item.desc"
- :image="item.image"
- :tags="(item.bottomTags as string[])"
- :props="item.props"
- @click="category.detailsPage(item)"
- />
- </template>
- </FlexCol>
- </SimplePageContentLoader>
- <text v-else>No Data</text>
- </FlexCol>
- </FlexCol>
- </template>
- <script setup lang="ts">;
- import { computed, onMounted, watch, type PropType } from 'vue';
- import { GetContentListItem } from '@/api/CommonContent';
- import { useSimpleDataLoader } from '@/components/composeabe/loader/SimpleDataLoader';
- import { doLoadDynamicListData } from '../data/DynamicData';
- import type { ContentBlockDefine } from './ContentBlocks';
- import type { MiniScript } from '@/components/dynamic/minisc/MiniScript';
- import FlexCol from '@/components/layout/FlexCol.vue';
- import FlexRow from '@/components/layout/FlexRow.vue';
- import FrameButton from '@/common/components/FrameButton.vue';
- import HomeTitle from '@/common/components/parts/HomeTitle.vue';
- import SimplePageContentLoader from '@/components/loader/SimplePageContentLoader.vue';
- import RichBlock from '../blocks/RichBlock.vue';
- import Box2LineLargeImageUserShadow from '@/common/components/parts/Box2LineLargeImageUserShadow.vue';
- import Box2LineImageRightShadow from '@/common/components/parts/Box2LineImageRightShadow.vue';
- import IndexRoundSimpleItem from '@/common/components/parts/IndexRoundSimpleItem.vue';
- import Width from '@/components/layout/space/Width.vue';
- import IndexRoundBoxSimpleItem from '@/common/components/parts/IndexRoundBoxSimpleItem.vue';
- const props = defineProps({
- /**
- * 分类定义
- */
- categoryDefine: {
- type: Array as PropType<ContentBlockDefine[]>,
- default: () => [],
- },
- /**
- * 父级数据
- */
- parentData: {
- type: Object as PropType<any>,
- default: () => {},
- },
- scriptEngine: {
- type: Object as PropType<MiniScript>,
- default: () => {},
- },
- getNodeContext: {
- type: Function as PropType<() => Record<string, any>>,
- default: () => {},
- },
- });
- const categoryDatas = computed(() => props.categoryDefine.map(item => {
- if (!item.content)
- return {
- ...item,
- detailsPage: () => {},
- morePage: () => {
- if (item.onMoreClicked)
- props.scriptEngine.execute(item.onMoreClicked, props.getNodeContext(), {});
- },
- data: null,
- };
- return {
- ...item,
- detailsPage: (dataItem: GetContentListItem) => {
- if (item.onItemDetailClicked)
- props.scriptEngine.execute(item.onItemDetailClicked, props.getNodeContext(), { dataItem });
- },
- morePage: () => {
- if (item.onMoreClicked)
- props.scriptEngine.execute(item.onMoreClicked, props.getNodeContext(), {});
- },
- data: useSimpleDataLoader(async () => {
- let res : any[] = [];
- if (!item.content)
- return res;
- res = (await doLoadDynamicListData(
- item.content, 1, item.count || 4, '',
- props.scriptEngine,
- props.getNodeContext,
- )).list;
- if (item.onContentSolve)
- res = props.scriptEngine.execute(item.onContentSolve || '', props.getNodeContext(), { res }) as any;
- return res;
- }, false)
- }
- }));
- function loadCategoryDatas() {
- categoryDatas.value.forEach(item => {
- if (item.data)
- item.data.load(true);
- })
- }
- watch(categoryDatas, loadCategoryDatas);
- onMounted( loadCategoryDatas);
- </script>
|