Kaynağa Gözat

📦 轮播对接后台

快乐的梦鱼 14 saat önce
ebeveyn
işleme
95226598c4

+ 48 - 0
src/api/system/Banner.ts

@@ -0,0 +1,48 @@
+import { DataModel, transformArrayDataModel } from '@imengyu/js-request-transform';
+import { AppServerRequestModule } from '../RequestModules';
+
+export class BannerItem extends DataModel<BannerItem> {
+  constructor() {
+    super(BannerItem, '轮播图');
+    this.setNameMapperCase('Camel', 'Snake');
+    this._convertTable = {
+      id: { clientSide: 'number', serverSide: 'number', clientSideRequired: true },
+    };
+  }
+
+  id = 0;
+  title = '';
+  /** 图片 */
+  image = '';
+  /** 跳转路径 */
+  page = '';
+  /** 跳转外部url */
+  url = '';
+  intro = '';
+  typeText = '';
+  sceneText = '';
+  openTypeText = '';
+  statusText = '';
+}
+
+export class BannerApi extends AppServerRequestModule<DataModel> {
+
+  constructor() {
+    super();
+  }
+
+  /** 首页轮播图列表 */
+  async getBannerList(data: {
+    openType?: number,
+    model?: number,
+    keywords?: string,
+  }) {
+    return transformArrayDataModel<BannerItem>(BannerItem, (await this.post<any>('/content/banner_function/getOtherBanner', '首页轮播图列表', {
+      open_type: data.openType || 1,
+      model: data.model,
+      keywords: data.keywords,
+    })).requireData(), 'BannerItem');
+  }
+}
+
+export default new BannerApi();

+ 14 - 4
src/common/components/parts/ImageSwiper.vue

@@ -17,7 +17,7 @@
       <view 
         class="item"
         :style="{
-          backgroundImage: `url(${item})`,
+          backgroundImage: `url(${typeof item === 'string' ? item : item.image})`,
           backgroundSize: 'cover',
           height: themeContext.resolveThemeSize(height),
           width: themeContext.resolveThemeSize(width),
@@ -25,7 +25,7 @@
         }"
       >
         <image
-          :src="item"
+          :src="typeof item === 'string' ? item : item.image"
           :style="{
             borderRadius: themeContext.resolveThemeSize(radius),
             height: themeContext.resolveThemeSize(height),
@@ -42,11 +42,15 @@
 <script setup lang="ts">
 import { useSwiperImagePreview } from '@/common/composeabe/SwiperImagePreview';
 import { useTheme } from '@/components/theme/ThemeDefine';
+import { navTo } from '@/components/utils/PageAction';
 import type { PropType } from 'vue';
 
 const props = defineProps({
   images: {
-    type: Array as PropType<string[]>,
+    type: Array as PropType<(string|{
+      image: string,
+      url: string,
+    })[]>,
     default: () => [],
   },
   height: {
@@ -67,7 +71,13 @@ const props = defineProps({
   },
 })
 
-const { onPreviewImage } = useSwiperImagePreview(() => props.images || [])
+function onPreviewImage(index: number) {
+  if (typeof props.images[index] === 'object' && props.images[index].url)
+    return navTo(props.images[index].url);
+  rawPreviewImage(index);
+}
+
+const { onPreviewImage: rawPreviewImage } = useSwiperImagePreview(() => props.images.map(p => typeof p === 'string' ? p : p.image));
 const themeContext = useTheme();
 
 </script>

+ 10 - 1
src/pages/home/dig.vue

@@ -2,7 +2,7 @@
   <FlexCol padding="padding.md">
     <HomeLargeTitle title="挖掘" />
     <ImageSwiper
-      :images="appConfiguration?.banners.dig.images"
+      :images="bannerLoader.content.value || []"
       :height="appConfiguration?.banners.dig.height"
       width="100%"
       radius="radius.md"
@@ -124,6 +124,7 @@ import { useStorageVar } from '@/components/composeabe/StorageVar';
 import { injectAppConfiguration } from '@/api/system/useAppConfiguration';
 import { confirm } from '@/components/dialog/CommonRoot';
 import VillageApi, { VillageListItem } from '@/api/inhert/VillageApi';
+import BannerApi from '@/api/system/Banner';
 import RequireLogin from '@/common/components/RequireLogin.vue';
 import SimplePageContentLoader from '@/components/loader/SimplePageContentLoader.vue';
 import Button from '@/components/basic/Button.vue';
@@ -151,6 +152,14 @@ const collectStore = useCollectStore();
 const appConfiguration = injectAppConfiguration();
 const { value: currentCity } = useStorageVar('currentCityName', '');
 
+const bannerLoader = useSimpleDataLoader(async () => {
+  return (await BannerApi.getBannerList({
+    keywords: '亮乡源大众版挖掘',
+  })).map(p => ({
+    image: p.image,
+    url: p.url,
+  }));
+});
 const notVolunteerError = ref(false);
 const villageListLoader = useSimpleDataLoader(async () => await VillageApi.getClaimedVallageList(), true);
 const volunteerInfoLoader = useSimpleDataLoader(async () => {

+ 12 - 3
src/pages/home/discover/index.vue

@@ -4,7 +4,7 @@
     <ImageSwiper
       width="100%"
       :height="appConfiguration?.banners.discover.height"
-      :images="appConfiguration?.banners.discover.images"
+      :images="bannerLoader.content.value || []"
       radius="radius.md"
       :innerStyle="{
         border: '1px solid #fff',
@@ -106,7 +106,8 @@ import { useSimplePageListLoader } from '@/components/composeabe/loader/SimplePa
 import { useSimpleDataLoader } from '@/components/composeabe/loader/SimpleDataLoader';
 import { useVillageStore } from '@/store/village';
 import { injectAppConfiguration } from '@/api/system/useAppConfiguration';
-import Loadmore from '@/components/display/loading/Loadmore.vue';
+import { waitTimeOut } from '@imengyu/imengyu-utils';
+import BannerApi from '@/api/system/Banner';
 import FlexCol from '@/components/layout/FlexCol.vue';
 import Height from '@/components/layout/space/Height.vue';
 import HomeLargeTitle from '@/common/components/parts/HomeLargeTitle.vue';
@@ -122,7 +123,6 @@ import Avatar from '@/components/display/Avatar.vue';
 import Touchable from '@/components/feedback/Touchable.vue';
 import Text from '@/components/basic/Text.vue';
 import Image from '@/components/basic/Image.vue';
-import { waitTimeOut } from '@imengyu/imengyu-utils';
 import FlexRow from '@/components/layout/FlexRow.vue';
 import BoxMid from '@/common/components/box/BoxMid.vue';
 import RankVolunteerItem from '../village/rank/components/RankVolunteerItem.vue';
@@ -133,6 +133,15 @@ const emit = defineEmits([ 'goVillage' ]);
 
 const villageStore = useVillageStore();
 const appConfiguration = injectAppConfiguration();
+
+const bannerLoader = useSimpleDataLoader(async () => {
+  return (await BannerApi.getBannerList({
+    keywords: '亮乡源大众版发现',
+  })).map(p => ({
+    image: p.image,
+    url: p.url,
+  }));
+});
 const discoverLoader = useSimplePageListLoader(15, async (page, pageSize) => {
   return await VillageInfoApi.getListForDiscover(page, pageSize);
 });

+ 11 - 1
src/pages/home/index.vue

@@ -45,7 +45,7 @@
           <!-- <Button icon="ai-thinking" @click="handleGoAI" text="问AI" /> -->
         </FlexRow>
         <ImageSwiper 
-          :images="appConfiguration?.banners.home.images"
+          :images="bannerLoader.content.value || []"
           :height="appConfiguration?.banners.home.height"
           :width="700"
           radius="radius.md"
@@ -261,6 +261,7 @@ import PostIndex from './village/dialogs/PostIndex.vue';
 import FrameButton from '@/common/components/FrameButton.vue';
 import type { RegionItem } from '@/api/map/RegionApi';
 import BubbleTip from '@/components/feedback/BubbleTip.vue';
+import BannerApi from '@/api/system/Banner';
 
 const emit = defineEmits(['goVillage','goDig']);
 const authStore = useAuthStore();
@@ -289,6 +290,15 @@ const currentLocation = useGetCurrentLocation({
 
 const { currentNoticeContent } = useGetNotice();
 
+const bannerLoader = useSimpleDataLoader(async () => {
+  return (await BannerApi.getBannerList({
+    keywords: '亮乡源大众版首页头部',
+  })).map(p => ({
+    image: p.image,
+    url: p.url,
+  }));
+});
+
 const villageRankListLoader = useSimpleDataLoader(async () => {
   const res = await LightVillageApi.getVillageRankList({ num: 3 });
   return res.map((item, i) => ({