| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394 |
- <template>
- <FlexCol :padding="30" gap="gap.lg">
- <!-- 卡片背景 -->
- <BackgroundBox
- color1="#eecaa0"
- color2="white"
- color2Position="45%"
- color3="white"
- radius="radius.lg"
- direction="column"
- :padding="[35,30]"
- gap="gap.lg"
- >
- <!-- 标题 -->
- <FlexRow justify="space-between" width="100%">
- <FlexCol gap="gap.md">
- <Text :text="villageInfoLoader.content.value?.title" fontConfig="primaryTitle" />
- <Text :text="villageInfoLoader.content.value?.address" fontConfig="contentText" />
- </FlexCol>
- <FlexCol gap="gap.md">
- <Button icon="https://xy.wenlvti.net/app_static/images/village/IconUser.png" radius="radius.lgr" :padding="[10, 30]" backgroundColor="white">申请管理者</Button>
- <Text :text="`${villageInfoLoader.content.value?.applyCount} 个乡源果可申请`" fontConfig="secondText" />
- </FlexCol>
- </FlexRow>
-
- <!-- 图片 -->
- <FlexRow v-if="villageInfoLoader.content.value" justify="space-between">
- <Image
- v-for="index of 3"
- :key="index"
- :src="villageInfoLoader.content.value.images[index - 1]"
- radius="radius.md"
- :width="200"
- :height="140"
- mode="aspectFill"
- defaultImage=""
- touchable
- >
- <template #empty>
- <Touchable
- direction="column"
- position="absolute"
- inset="0"
- center
- backgroundColor="background.primary"
- >
- <Icon name="add" size="fontSize.md" />
- <Text text="上传封面" fontConfig="secondText" />
- </Touchable>
- </template>
- <FlexCol
- v-if="index === 3 && villageInfoLoader.content.value.images.length > 3"
- position="absolute" inset="0"
- center
- backgroundColor="mask.default"
- >
- <Text :text="`+${villageInfoLoader.content.value.images.length - 3}`" fontSize="fontSize.lg" color="white" />
- </FlexCol>
- </Image>
- </FlexRow>
- <!-- 地址 -->
- <FlexRow align="center" gap="gap.sm">
- <Icon name="https://xy.wenlvti.net/app_static/images/village/IconMap.png" size="fontSize.md" />
- <Text :text="villageInfoLoader.content.value?.address" fontConfig="contentText" />
- </FlexRow>
- <VillageMiniMap
- v-if="villageInfoLoader.content.value"
- :lonlat="{
- longitude: villageInfoLoader.content.value.longitude,
- latitude: villageInfoLoader.content.value.latitude
- }"
- />
- <FlexRow center gap="gap.lg">
- <Button
- icon="https://xy.wenlvti.net/app_static/images/village/IconJoin.png"
- radius="radius.lgr"
- size="large"
- :innerStyle="{ flexBasis: '25%' }"
- @click="isFollowed ? onUnFollow() : onFollow()"
- >
- {{ isFollowed ? '已关注' : '关注' }}
- </Button>
- <Button
- icon="https://xy.wenlvti.net/app_static/images/village/IconFollow.png"
- size="large"
- radius="radius.lgr"
- :innerStyle="{ flexBasis: '25%' }"
- >
- 加入
- </Button>
- </FlexRow>
- <FlexRow justify="space-between" align="center">
- <FlexRow center gap="gap.lg" flexBasis="50%">
- <Text text="村社排名" fontConfig="contentText" />
- <Text text="No." fontConfig="lightTitle" />
- <Text :text="villageInfoLoader.content.value?.rankText" fontConfig="primaryTitle" />
- </FlexRow>
- <FlexRow center gap="gap.lg" flexBasis="50%">
- <Text text="村社等级" fontConfig="contentText" />
- <Text :text="villageInfoLoader.content.value?.levelText" fontConfig="primaryTitle" />
- </FlexRow>
- </FlexRow>
- <FlexRow backgroundColor="background.tertiary" radius="radius.md" :padding="[30, 20]">
- <FlexCol center gap="gap.sm" flexBasis="25%">
- <Text text="乡源光" fontConfig="secondText" />
- <Text :text="villageInfoLoader.content.value?.light" fontConfig="importantTitle" />
- </FlexCol>
- <Divider type="vertical" />
- <FlexCol center gap="gap.sm" flexBasis="25%">
- <Text text="乡源人数" fontConfig="contentText" />
- <Text :text="villageInfoLoader.content.value?.memberCount" fontConfig="importantTitle" />
- </FlexCol>
- <Divider type="vertical" />
- <FlexCol center gap="gap.sm" flexBasis="25%">
- <Text text="关注人数" fontConfig="contentText" />
- <Text :text="villageInfoLoader.content.value?.followerCount" fontConfig="importantTitle" />
- </FlexCol>
- <Divider type="vertical" />
- <Button :padding="0" type="text" size="small" textColor="text.title" text="新手上路" rightIcon="arrow-right" />
- </FlexRow>
- </BackgroundBox>
- <!-- 排行榜 -->
- <HomeTitle title="排行榜" showMore @moreClicked="navTo('/pages/home/village/rank/volunteer', {
- villageId: villageStore.currentVillage?.id ?? undefined,
- })" />
- <RoundTags v-model:active="rankActiveTag" :tags="['乡源果', '志愿者', '乡源光']" />
- <VillageUserRankList :list="villageUserRankListLoader.content.value ?? []" />
- <!-- 魅力乡源 -->
- <HomeTitle title="魅力乡源" showMore>
- <template #right>
- <BackgroundImageButton
- backgroundImage="https://xy.wenlvti.net/app_static/images/village/TagActive.png"
- :backgroundCutBorder="[10, 10, 10, 10]"
- :backgroundCutBorderSize="[10, 10, 10, 10]"
- :padding="[15, 20]"
- :innerStyle="{ marginRight: '20rpx' }"
- >
- <Text text="120乡源果兑换" fontConfig="contentText" color="white" />
- </BackgroundImageButton>
- </template>
- </HomeTitle>
- <ProvideVar :vars="{
- GridItemIconSize: 90,
- GridItemBackgroundColor: 'transparent',
- GridItemPaddingHorizontal: 0,
- GridItemPaddingVertical: 8,
- }">
- <Grid :borderGrid="false" :mainAxisCount="4">
- <GridItem title="村庄概况" icon="https://xy.wenlvti.net/app_static/images/village/IconLargeIntrod.png" touchable @click="handleGoCollect('overview')" />
- <GridItem title="自然风光" icon="https://xy.wenlvti.net/app_static/images/village/IconLargeEnvirounment.png" touchable @click="handleGoCollect('environment')" />
- <GridItem title="历史沿革" icon="https://xy.wenlvti.net/app_static/images/village/IconLargeHistory.png" touchable @click="handleGoCollect('history')" />
- <GridItem title="特色产业" icon="https://xy.wenlvti.net/app_static/images/village/IconLargeIndustry.png" touchable @click="handleGoCollect('product')" />
- <GridItem title="文艺活动" icon="https://xy.wenlvti.net/app_static/images/village/IconLargeActivity.png" touchable @click="handleGoCollect('trip')" />
- <GridItem title="非遗展示" icon="https://xy.wenlvti.net/app_static/images/village/IconLargeShow.png" touchable @click="handleGoCollect('ich')" />
- <GridItem title="民俗风采" icon="https://xy.wenlvti.net/app_static/images/village/IconLargeFolkloreVibe.png" touchable @click="handleGoCollect('custom')" />
- <GridItem title="文化志愿者" icon="https://xy.wenlvti.net/app_static/images/village/IconLargeVolunteer.png" touchable @click="toast('TODO')" />
- </Grid>
- </ProvideVar>
- <!-- 活力乡源 -->
- <HomeTitle title="活力乡源" />
- <ProvideVar :vars="{
- GridItemIconSize: 90,
- GridItemBackgroundColor: 'transparent',
- GridItemPaddingHorizontal: 0,
- GridItemPaddingVertical: 8,
- }">
- <Grid :borderGrid="false" :mainAxisCount="4">
- <GridItem title="乡源荣光" icon="https://xy.wenlvti.net/app_static/images/village/IconLargeHornor.png" touchable />
- <GridItem title="乡源好物" icon="https://xy.wenlvti.net/app_static/images/village/IconLargeGoods.png" touchable />
- <GridItem title="乡源树" icon="https://xy.wenlvti.net/app_static/images/village/IconLargeTree.png" touchable />
- <GridItem title="共编村史" icon="https://xy.wenlvti.net/app_static/images/village/IconLargeIndustry.png" touchable />
- <GridItem title="互动游戏" icon="https://xy.wenlvti.net/app_static/images/village/IconLargeGame.png" touchable />
- </Grid>
- </ProvideVar>
- <!-- 文脉乡源 -->
- <HomeTitle title="文脉乡源">
- <template #right>
- <BackgroundImageButton
- backgroundImage="https://xy.wenlvti.net/app_static/images/village/TagActive.png"
- :backgroundCutBorder="[10, 10, 10, 10]"
- :backgroundCutBorderSize="[10, 10, 10, 10]"
- :padding="[15, 20]"
- :innerStyle="{ marginRight: '20rpx' }"
- @click="handleGoPublish()"
- >
- <Text text="去发布" fontConfig="contentText" color="white" />
- </BackgroundImageButton>
- </template>
- </HomeTitle>
- <RoundTags v-model:active="listActiveTag" :tags="['广场', '老味道', '老手艺', '老物件', '老故事']" />
- <SimplePageListLoader :loader="recommendLoader">
- <MasonryGrid>
- <MasonryGridItem
- v-for="(item, i) in recommendLoader.list.value"
- :key="i"
- :width="340"
- >
- <IndexCommonImageItem
- :image="item.image"
- :title="item.title"
- :desc="item.content ?? ''"
- :userName="item.nickName ?? ''"
- :likes="item.likeCount"
- :isLike="false"
- @click="handleGoPost(item.id)"
- />
- </MasonryGridItem>
- </MasonryGrid>
- </SimplePageListLoader>
- </FlexCol>
- </template>
- <script setup lang="ts">
- import { computed, ref, watch } from 'vue';
- import { useSimplePageListLoader } from '@/components/composeabe/loader/SimplePageListLoader';
- import { useAuthStore } from '@/store/auth';
- import { useSimpleDataLoader } from '@/components/composeabe/loader/SimpleDataLoader';
- import { useVillageStore } from '@/store/village';
- import { confirm, toast } from '@/components/utils/DialogAction';
- import { ArrayUtils } from '@imengyu/imengyu-utils';
- import { navTo } from '@/components/utils/PageAction';
- import HomeTitle from '@/common/components/parts/HomeTitle.vue';
- import Button from '@/components/basic/Button.vue';
- import Icon from '@/components/basic/Icon.vue';
- import Image from '@/components/basic/Image.vue';
- import Text from '@/components/basic/Text.vue';
- import BackgroundBox from '@/components/display/block/BackgroundBox.vue';
- import Touchable from '@/components/feedback/Touchable.vue';
- import FlexCol from '@/components/layout/FlexCol.vue';
- import FlexRow from '@/components/layout/FlexRow.vue';
- import VillageMiniMap from '../../components/VillageMiniMap.vue';
- import Divider from '@/components/display/Divider.vue';
- import RoundTags from '@/common/components/parts/RoundTags.vue';
- import VillageUserRankList from '../../components/VillageUserRankList.vue';
- import BackgroundImageButton from '@/components/basic/BackgroundImageButton.vue';
- import ProvideVar from '@/components/theme/ProvideVar.vue';
- import Grid from '@/components/layout/grid/Grid.vue';
- import GridItem from '@/components/layout/grid/GridItem.vue';
- import MasonryGrid from '@/components/layout/masonry/MasonryGrid.vue';
- import MasonryGridItem from '@/components/layout/masonry/MasonryGridItem.vue';
- import IndexCommonImageItem from '@/common/components/parts/IndexCommonImageItem.vue';
- import FollowVillageApi from '@/api/light/FollowVillageApi';
- import LightVillageApi from '@/api/light/LightVillageApi';
- import SimplePageListLoader from '@/components/loader/SimplePageListLoader.vue';
- import { useReqireLogin } from '@/common/composeabe/RequireLogin';
- const authStore = useAuthStore();
- const { requireLogin } = useReqireLogin();
- const villageStore = useVillageStore();
- const villageInfoLoader = useSimpleDataLoader(async () => {
- const village = villageStore.currentVillage;
- return {
- title: village?.name || '',
- desc: village?.desc || '',
- address: village?.address,
- applyCount: village?.applyCount || 0,
- levelText: village?.levelText as string || '',
- rankText: village?.rankText as string || '',
- light: village?.light as number || 0,
- memberCount: village?.memberCount as number || 0,
- followerCount: village?.followerCount as number || 0,
- images: village?.images || [],
- longitude: village?.longitude as number || 0,
- latitude: village?.latitude as number || 0,
- };
- });
- watch(() => villageStore.currentVillage, () => {
- villageInfoLoader.reload();
- recommendLoader.reload();
- villageUserRankListLoader.reload();
- }, { immediate: true });
- const rankActiveTag = ref('乡源果');
- const listActiveTag = ref('广场');
- const villageUserRankListLoader = useSimpleDataLoader(async () => {
- const res = (await LightVillageApi.getVolunteerRankList({
- num: 3,
- village_id: villageStore.currentVillage?.id ?? undefined,
- }))
- .map((item, i) => ({
- id: item.id,
- image: item.image ?? '',
- title: item.name,
- rank: i + 1,
- score: item.points,
- }));
- if (res.length >= 3) {
- //移动第一名到中间
- const first = res[0];
- ArrayUtils.removeAt(res, 0);
- ArrayUtils.insert(res, 1, first);
- }
- return res
- });
- watch(rankActiveTag, () => {
- villageUserRankListLoader.reload();
- });
- const isFollowed = computed(() => {
- return villageStore.myFollowVillages.some(p => p.id === villageStore.currentVillage?.id);
- });
- const isJoined = computed(() => {
- return false;
- });
- async function onFollow() {
- if (!villageStore.currentVillage)
- return;
- requireLogin(async () => {
- try {
- await FollowVillageApi.followVillage(villageStore.currentVillage!.id);
- villageStore.myFollowVillages.push(villageStore.currentVillage!);
- toast('关注成功');
- } catch {
- toast('关注失败');
- }
- }, '登录后才能关注村庄哦');
- }
- function onUnFollow() {
- if (!villageStore.currentVillage) return;
- confirm({
- title: '取消关注',
- content: '确定取消关注该村庄吗?',
- confirmText: '取消关注',
- cancelText: '取消',
- }).then(async (res) => {
- if (res) {
- try {
- await FollowVillageApi.unfollowVillage(villageStore.currentVillage!.id);
- villageStore.myFollowVillages = villageStore.myFollowVillages.filter(p => p.id !== villageStore.currentVillage!.id);
- toast('取消关注成功');
- } catch {
- toast('取消关注失败');
- }
- }
- });
- }
- const recommendLoader = useSimplePageListLoader(20, async (page, pageSize) => {
- return await LightVillageApi.getMessages(page, pageSize, {
- villageId: villageStore.currentVillage?.id ?? undefined,
- keywords: listActiveTag.value,
- });
- });
- watch(listActiveTag, () => {
- recommendLoader.reload();
- });
- function handleGoCollect(taskName: string) {
- navTo('/pages/dig/forms/task', {
- villageId: villageStore.currentVillage?.id ?? undefined,
- taskName: taskName,
- taskPid: -1,
- });
- }
- function handleGoPublish() {
- if (!authStore.isLogged) {
- confirm({
- title: '提示',
- content: '登录后就可以发布村落贴图了',
- confirmText: '去登录',
- }).then((res) => {
- if (res) {
- navTo('/pages/user/login');
- }
- });
- return;
- }
- navTo('/pages/chat/dependent/post/publish', {
- tag: listActiveTag.value,
- villageId: villageStore.currentVillage?.id ?? undefined,
- });
- }
- function handleGoPost(id: number) {
- navTo('/pages/home/post/detail', {
- id: id,
- });
- }
- </script>
|