fix: 修改模拟数据路径
This commit is contained in:
parent
956be17a4e
commit
55104d5aef
@ -12,6 +12,7 @@ type Config struct {
|
||||
Dubbo DubboConfig
|
||||
JWT JWTConfig
|
||||
OSS OSSConfig
|
||||
Root string
|
||||
}
|
||||
|
||||
// ServerConfig 服务器配置
|
||||
@ -62,7 +63,9 @@ func (c *OSSConfig) GetUploadDir(uploadType string) string {
|
||||
|
||||
// Load 加载配置
|
||||
func Load() *Config {
|
||||
root, _ := os.Getwd()
|
||||
return &Config{
|
||||
Root: root,
|
||||
Server: ServerConfig{
|
||||
Port: getEnv("SERVER_PORT", "8080"),
|
||||
Mode: getEnv("GIN_MODE", "debug"),
|
||||
|
||||
@ -1431,7 +1431,7 @@ func (ctrl *AssetController) ImageGeneration(c *gin.Context) {
|
||||
|
||||
// 开发模式下使用 mock 数据
|
||||
if config.Load().Server.Mode == "debug" {
|
||||
mockData, err := os.ReadFile(filepath.Join("..", "..", "mock", "minimax.json"))
|
||||
mockData, err := os.ReadFile(filepath.Join(config.Load().Root, "..", "mock", "minimax.json"))
|
||||
if err != nil {
|
||||
response.Error(c, 500, "Failed to read mock data: "+err.Error())
|
||||
return
|
||||
|
||||
@ -84,6 +84,7 @@ func ConvertAsset(pbAsset *pbAsset.Asset) AssetDTO {
|
||||
UpdatedAt: pbAsset.UpdatedAt,
|
||||
IsLiked: pbAsset.IsLiked,
|
||||
Info: pbAsset.Info,
|
||||
DisplayStatus: pbAsset.DisplayStatus,
|
||||
}
|
||||
|
||||
// 可选字段
|
||||
|
||||
@ -80,6 +80,7 @@ type AssetDTO struct {
|
||||
Owner *OwnerInfoDTO `json:"owner,omitempty"` // 持有者信息(可选,保留用于兼容性)
|
||||
IsLiked bool `json:"is_liked"` // 当前用户是否已点赞
|
||||
Info string `json:"info"` // 藏品信息
|
||||
DisplayStatus int32 `json:"display_status"` // 展示状态:0=待展示, 1=已展示
|
||||
}
|
||||
|
||||
// OwnerInfoDTO 持有者信息
|
||||
|
||||
@ -44,10 +44,11 @@ type Asset struct {
|
||||
UpdatedAt int64 `protobuf:"varint,16,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` // 更新时间(毫秒时间戳)
|
||||
MintedAt int64 `protobuf:"varint,17,opt,name=minted_at,json=mintedAt,proto3" json:"minted_at,omitempty"` // 上链成功时间(毫秒时间戳,可选)
|
||||
// 扩展字段:持有者信息(用于详情展示)
|
||||
Owner *OwnerInfo `protobuf:"bytes,18,opt,name=owner,proto3" json:"owner,omitempty"` // 持有者信息(保留用于兼容性)
|
||||
OwnerNickname string `protobuf:"bytes,19,opt,name=owner_nickname,json=ownerNickname,proto3" json:"owner_nickname,omitempty"` // 持有者昵称(在该star下的昵称)
|
||||
IsLiked bool `protobuf:"varint,20,opt,name=is_liked,json=isLiked,proto3" json:"is_liked,omitempty"` // 当前用户是否已点赞
|
||||
Info string `protobuf:"bytes,21,opt,name=info,proto3" json:"info,omitempty"` // 藏品信息
|
||||
Owner *OwnerInfo `protobuf:"bytes,18,opt,name=owner,proto3" json:"owner,omitempty"` // 持有者信息(保留用于兼容性)
|
||||
OwnerNickname string `protobuf:"bytes,19,opt,name=owner_nickname,json=ownerNickname,proto3" json:"owner_nickname,omitempty"` // 持有者昵称(在该star下的昵称)
|
||||
IsLiked bool `protobuf:"varint,20,opt,name=is_liked,json=isLiked,proto3" json:"is_liked,omitempty"` // 当前用户是否已点赞
|
||||
Info string `protobuf:"bytes,21,opt,name=info,proto3" json:"info,omitempty"` // 藏品信息
|
||||
DisplayStatus int32 `protobuf:"varint,22,opt,name=display_status,json=displayStatus,proto3" json:"display_status,omitempty"` // 展示状态:0=待展示, 1=已展示
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@ -229,6 +230,13 @@ func (x *Asset) GetInfo() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Asset) GetDisplayStatus() int32 {
|
||||
if x != nil {
|
||||
return x.DisplayStatus
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// 持有者信息
|
||||
type OwnerInfo struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
@ -2610,7 +2618,7 @@ var File_asset_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_asset_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\vasset.proto\x12\rtopfans.asset\x1a\x12proto/common.proto\x1a\x1cgoogle/api/annotations.proto\"\xec\x04\n" +
|
||||
"\vasset.proto\x12\rtopfans.asset\x1a\x12proto/common.proto\x1a\x1cgoogle/api/annotations.proto\"\x93\x05\n" +
|
||||
"\x05Asset\x12\x19\n" +
|
||||
"\basset_id\x18\x01 \x01(\x03R\aassetId\x12\x1b\n" +
|
||||
"\towner_uid\x18\x02 \x01(\x03R\bownerUid\x12\x17\n" +
|
||||
@ -2638,7 +2646,8 @@ const file_asset_proto_rawDesc = "" +
|
||||
"\x05owner\x18\x12 \x01(\v2\x18.topfans.asset.OwnerInfoR\x05owner\x12%\n" +
|
||||
"\x0eowner_nickname\x18\x13 \x01(\tR\rownerNickname\x12\x19\n" +
|
||||
"\bis_liked\x18\x14 \x01(\bR\aisLiked\x12\x12\n" +
|
||||
"\x04info\x18\x15 \x01(\tR\x04info\"X\n" +
|
||||
"\x04info\x18\x15 \x01(\tR\x04info\x12%\n" +
|
||||
"\x0edisplay_status\x18\x16 \x01(\x05R\rdisplayStatus\"X\n" +
|
||||
"\tOwnerInfo\x12\x17\n" +
|
||||
"\auser_id\x18\x01 \x01(\x03R\x06userId\x12\x1a\n" +
|
||||
"\bnickname\x18\x02 \x01(\tR\bnickname\x12\x16\n" +
|
||||
|
||||
@ -34,6 +34,7 @@ message Asset {
|
||||
string owner_nickname = 19; // 持有者昵称(在该star下的昵称)
|
||||
bool is_liked = 20; // 当前用户是否已点赞
|
||||
string info = 21; // 藏品信息
|
||||
int32 display_status = 22; // 展示状态:0=待展示, 1=已展示
|
||||
}
|
||||
|
||||
// 持有者信息
|
||||
|
||||
@ -24,6 +24,9 @@ type AssetRepository interface {
|
||||
// GetByIDAndOwner 根据ID和所有者查询资产(用于权限验证)
|
||||
GetByIDAndOwner(assetID, ownerUID, starID int64) (*models.Asset, error)
|
||||
|
||||
// GetDisplayStatusByAssetID 根据asset_id查询展示状态(从asset_registry表)
|
||||
GetDisplayStatusByAssetID(assetID int64) (int32, error)
|
||||
|
||||
// GetByOwner 查询用户的资产列表
|
||||
GetByOwner(ownerUID, starID int64, limit, offset int) ([]*models.Asset, error)
|
||||
|
||||
@ -97,6 +100,24 @@ func (r *assetRepository) GetByID(assetID int64) (*models.Asset, error) {
|
||||
return &asset, nil
|
||||
}
|
||||
|
||||
// GetDisplayStatusByAssetID 根据asset_id查询展示状态(从public.asset_registry表)
|
||||
func (r *assetRepository) GetDisplayStatusByAssetID(assetID int64) (int32, error) {
|
||||
if assetID <= 0 {
|
||||
return 0, errors.New("asset_id must be greater than 0")
|
||||
}
|
||||
|
||||
var registry models.AssetRegistry
|
||||
// 直接使用表名查询 public.asset_registry
|
||||
if err := r.db.Table("public.asset_registry").Where("asset_id = ?", assetID).First(®istry).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return 0, nil // 没找到返回0,不报错
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return registry.DisplayStatus, nil
|
||||
}
|
||||
|
||||
// GetByIDs 批量查询资产
|
||||
func (r *assetRepository) GetByIDs(assetIDs []int64) ([]*models.Asset, error) {
|
||||
if len(assetIDs) == 0 {
|
||||
|
||||
@ -2,28 +2,22 @@
|
||||
<view class="castlove-container">
|
||||
<!-- 背景图片 -->
|
||||
<image class="background-image" src="/static/background/starbook.jpg" mode="aspectFill"></image>
|
||||
|
||||
|
||||
<!-- 蒙层 -->
|
||||
<!-- <view class="background-overlay"></view> -->
|
||||
|
||||
|
||||
<!-- 左上角返回按钮 -->
|
||||
<view class="back-button" :style="{ top: backButtonTop }" @click="handleBack">
|
||||
<image class="back-icon" src="/static/icon/back.png" mode="aspectFit" />
|
||||
</view>
|
||||
|
||||
<!-- 内容区域 -->
|
||||
<scroll-view class="content-wrapper" :class="{ 'fixed-category': isFixed }" scroll-y @scrolltolower="loadMore" @scroll="handleScroll" :show-scrollbar="false" :scroll-top="scrollTop">
|
||||
<scroll-view class="content-wrapper" :class="{ 'fixed-category': isFixed }" scroll-y @scrolltolower="loadMore"
|
||||
@scroll="handleScroll" :show-scrollbar="false" :scroll-top="scrollTop">
|
||||
<!-- 区域一:顶部运营轮播图 -->
|
||||
<view class="banner-section">
|
||||
<swiper
|
||||
class="banner-swiper"
|
||||
:indicator-dots="true"
|
||||
:autoplay="true"
|
||||
:interval="3000"
|
||||
:duration="500"
|
||||
indicator-color="rgba(255, 255, 255, 0.3)"
|
||||
indicator-active-color="#FF6B9D"
|
||||
>
|
||||
<swiper class="banner-swiper" :indicator-dots="true" :autoplay="true" :interval="3000" :duration="500"
|
||||
indicator-color="rgba(255, 255, 255, 0.3)" indicator-active-color="#FF6B9D">
|
||||
<swiper-item v-for="(banner, index) in bannerList" :key="index" @click="handleBannerClick(banner)">
|
||||
<image class="banner-image" :src="banner.image_url" mode="aspectFill"></image>
|
||||
<view class="banner-overlay">
|
||||
@ -32,46 +26,33 @@
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
|
||||
|
||||
<!-- 区域二:主Tab标签区(星卡/吧唧/海报) -->
|
||||
<view class="main-tab-section">
|
||||
<view
|
||||
v-for="(tab, index) in mainTabs"
|
||||
:key="index"
|
||||
class="tab-item"
|
||||
@click="handleMainTabClick(tab)"
|
||||
>
|
||||
<view v-for="(tab, index) in mainTabs" :key="index" class="tab-item" @click="handleMainTabClick(tab)">
|
||||
<image class="tab-icon" :src="tab.icon" mode="aspectFit"></image>
|
||||
<text class="tab-name">{{ tab.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
<!-- 区域三:分类标签区 -->
|
||||
<view id="category-section" class="category-section" :class="{ fixed: isFixed }">
|
||||
<scroll-view class="category-scroll" scroll-x :show-scrollbar="false">
|
||||
<view
|
||||
v-for="(category, index) in categories"
|
||||
:key="index"
|
||||
class="category-item"
|
||||
<view v-for="(category, index) in categories" :key="index" class="category-item"
|
||||
:class="{ active: currentCategory === category.value }"
|
||||
@click="handleCategoryChange(category.value)"
|
||||
>
|
||||
@click="handleCategoryChange(category.value)">
|
||||
<text class="category-text">{{ category.label }}</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
|
||||
<!-- 占位元素,始终存在但透明度为0,避免跳动 -->
|
||||
<!-- <view class="category-placeholder" :style="{ opacity: isFixed ? 1 : 0, height: isFixed ? '32rpx' : '0' }"></view> -->
|
||||
|
||||
|
||||
<!-- 区域四:创作网格列表 -->
|
||||
<view class="creation-grid">
|
||||
<view
|
||||
v-for="(item, index) in creationList"
|
||||
:key="item.id"
|
||||
class="creation-card"
|
||||
@click="handleCardClick(item)"
|
||||
>
|
||||
<view v-for="(item, index) in creationList" :key="item.id" class="creation-card"
|
||||
@click="handleCardClick(item)">
|
||||
<image class="creation-image" :src="item.cover_image" mode="aspectFill"></image>
|
||||
<view class="creation-info">
|
||||
<view class="creation-id">
|
||||
@ -90,12 +71,12 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
<!-- 加载更多提示 -->
|
||||
<view class="loading-more" v-if="loading">
|
||||
<text class="loading-text">加载中...</text>
|
||||
</view>
|
||||
|
||||
|
||||
<view class="no-more" v-if="noMore && creationList.length > 0">
|
||||
<text class="no-more-text">没有更多了</text>
|
||||
</view>
|
||||
@ -192,7 +173,7 @@ onMounted(() => {
|
||||
console.log('[CastloveContent] 系统信息:', systemInfo);
|
||||
isAndroid.value = systemInfo.platform === 'android';
|
||||
console.log('[CastloveContent] 是否为Android:', isAndroid.value);
|
||||
|
||||
|
||||
loadBanners();
|
||||
loadCreations();
|
||||
});
|
||||
@ -211,7 +192,7 @@ const loadBanners = async () => {
|
||||
// 加载创作列表
|
||||
const loadCreations = async () => {
|
||||
if (loading.value || noMore.value) return;
|
||||
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
// TODO: 调用后台接口获取创作列表
|
||||
@ -220,16 +201,16 @@ const loadCreations = async () => {
|
||||
// page: page.value,
|
||||
// page_size: pageSize.value
|
||||
// });
|
||||
|
||||
|
||||
// 模拟数据
|
||||
const mockData = generateMockData();
|
||||
|
||||
|
||||
if (page.value === 1) {
|
||||
creationList.value = mockData;
|
||||
} else {
|
||||
creationList.value = [...creationList.value, ...mockData];
|
||||
}
|
||||
|
||||
|
||||
if (mockData.length < pageSize.value) {
|
||||
noMore.value = true;
|
||||
}
|
||||
@ -270,7 +251,7 @@ const generateMockData = () => {
|
||||
for (let i = 0; i < pageSize.value; i++) {
|
||||
// 随机选择一张素材图片
|
||||
const randomImageIndex = Math.floor(Math.random() * sucaiImages.length);
|
||||
|
||||
|
||||
data.push({
|
||||
id: `${Date.now()}_${i}`,
|
||||
cover_image: sucaiImages[randomImageIndex],
|
||||
@ -278,7 +259,7 @@ const generateMockData = () => {
|
||||
creator_name: `用户${Math.floor(Math.random() * 1000)}`,
|
||||
creator_avatar: '/static/avatar/default.png',
|
||||
like_count: Math.floor(Math.random() * 1000),
|
||||
type: currentCategory.value === 'hot' || currentCategory.value === 'latest'
|
||||
type: currentCategory.value === 'hot' || currentCategory.value === 'latest'
|
||||
? ['star_card', 'badge', 'poster'][Math.floor(Math.random() * 3)]
|
||||
: currentCategory.value
|
||||
});
|
||||
@ -313,12 +294,12 @@ const handleMainTabClick = (tab) => {
|
||||
// 分类切换
|
||||
const handleCategoryChange = (value) => {
|
||||
if (currentCategory.value === value) return;
|
||||
|
||||
|
||||
currentCategory.value = value;
|
||||
page.value = 1;
|
||||
noMore.value = false;
|
||||
creationList.value = [];
|
||||
|
||||
|
||||
// 滚动到创作网格列表的顶部(分类栏位置)
|
||||
// 轮播图360rpx + 主Tab约280rpx + 间距 ≈ 320px
|
||||
if (isFixed.value) {
|
||||
@ -328,7 +309,7 @@ const handleCategoryChange = (value) => {
|
||||
scrollTop.value = 361;
|
||||
}, 100);
|
||||
}
|
||||
|
||||
|
||||
loadCreations();
|
||||
};
|
||||
|
||||
@ -365,7 +346,17 @@ const formatCount = (count) => {
|
||||
|
||||
// 返回按钮
|
||||
const handleBack = () => {
|
||||
uni.navigateBack();
|
||||
// 获取页面栈
|
||||
const pages = getCurrentPages();
|
||||
if (pages.length > 1) {
|
||||
// 有上一页,执行返回
|
||||
uni.navigateBack();
|
||||
} else {
|
||||
// 没有上一页,跳转到square页面
|
||||
uni.reLaunch({
|
||||
url: '/pages/square/square'
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@ -839,7 +839,7 @@
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-top: 160rpx;
|
||||
padding-top: 192rpx;
|
||||
padding-left: 40rpx;
|
||||
padding-right: 40rpx;
|
||||
padding-bottom: 160rpx;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<view class="page-container">
|
||||
<Header :showBack="true" backIconColor="#e6e6e6" />
|
||||
<Header :showGuideIcon="false" :showTaskIcon="false" :showStarActivityIcon="false" :showBack="true" backIconColor="#e6e6e6" />
|
||||
<FriendsContent />
|
||||
|
||||
<!-- 蒙层 - 导航栏展开时显示 -->
|
||||
|
||||
Loading…
Reference in New Issue
Block a user