feat:修改遗留bug
This commit is contained in:
parent
12571eedba
commit
94457ffa8a
@ -60,7 +60,10 @@ RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags="-s -w" \
|
||||
echo "Built statisticservice" && \
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags="-s -w" \
|
||||
-o /tmp/notificationservice services/notificationService/main.go && \
|
||||
echo "Built notificationservice"
|
||||
echo "Built notificationservice" && \
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags="-s -w" \
|
||||
-o /tmp/moderationservice services/moderationService/main.go && \
|
||||
echo "Built moderationservice"
|
||||
|
||||
# ---- Runtime Stage: Gateway ----
|
||||
FROM --platform=linux/amd64 alpine:3.19 AS gateway
|
||||
@ -243,3 +246,18 @@ HEALTHCHECK --interval=10s --timeout=5s --start-period=15s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:21010/healthz || exit 1
|
||||
|
||||
ENTRYPOINT ["/app/notificationservice"]
|
||||
|
||||
# ---- Runtime Stage: ModerationService (举报 / 反馈 / 自动隐藏) ----
|
||||
FROM --platform=linux/amd64 alpine:3.19 AS moderationservice
|
||||
|
||||
RUN apk add --no-cache ca-certificates tzdata
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=builder /tmp/moderationservice /app/moderationservice
|
||||
|
||||
EXPOSE 20011
|
||||
|
||||
HEALTHCHECK --interval=10s --timeout=5s --start-period=15s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost:20011 || exit 1
|
||||
|
||||
ENTRYPOINT ["/app/moderationservice"]
|
||||
|
||||
@ -79,6 +79,7 @@ while [[ $# -gt 0 ]]; do
|
||||
echo " gateway, userService, socialService, assetService,"
|
||||
echo " galleryService, activityService, taskService, starbookService, aiChatService,"
|
||||
echo " laserCompositor, statisticService"
|
||||
echo " notificationService, moderationService"
|
||||
echo ""
|
||||
echo "示例:"
|
||||
echo " $0 # 构建所有服务"
|
||||
@ -102,6 +103,7 @@ while [[ $# -gt 0 ]]; do
|
||||
ai|aiChatService|aichatservice) SERVICES+=("aiChatService") ;;
|
||||
statistic|statisticService|statisticservice) SERVICES+=("statisticservice") ;;
|
||||
notification|notificationService|notificationservice) SERVICES+=("notificationservice") ;;
|
||||
moderation|moderationService|moderationservice) SERVICES+=("moderationservice") ;;
|
||||
all)
|
||||
# all 关键字,构建所有服务
|
||||
SERVICES=()
|
||||
@ -120,7 +122,7 @@ done
|
||||
|
||||
# ==================== 服务列表 ====================
|
||||
# 所有可用服务及其配置(使用小写 target 名)
|
||||
ALL_SERVICES_NAME=("gateway" "userservice" "socialservice" "assetservice" "galleryservice" "activityservice" "taskservice" "starbookservice" "aichatservice" "lasercompositor" "statisticservice" "notificationservice")
|
||||
ALL_SERVICES_NAME=("gateway" "userservice" "socialservice" "assetservice" "galleryservice" "activityservice" "taskservice" "starbookservice" "aichatservice" "lasercompositor" "statisticservice" "notificationservice" "moderationservice")
|
||||
|
||||
# 确定要构建的服务
|
||||
if [ ${#SERVICES[@]} -eq 0 ]; then
|
||||
@ -213,6 +215,7 @@ main() {
|
||||
lasercompositor) docker_target="lasercompositor" ;;
|
||||
statisticservice) docker_target="statisticservice" ;;
|
||||
notificationservice) docker_target="notificationservice" ;;
|
||||
moderationservice) docker_target="moderationservice" ;;
|
||||
# 兼容旧的大写服务名
|
||||
userService) docker_target="userservice" ;;
|
||||
socialService) docker_target="socialservice" ;;
|
||||
@ -224,6 +227,7 @@ main() {
|
||||
statisticService) docker_target="statisticservice" ;;
|
||||
statisticservice) docker_target="statisticservice" ;;
|
||||
notificationService) docker_target="notificationservice" ;;
|
||||
moderationService) docker_target="moderationservice" ;;
|
||||
*) docker_target="$service" ;;
|
||||
esac
|
||||
|
||||
|
||||
@ -82,6 +82,7 @@ SERVICES=(
|
||||
"lasercompositor"
|
||||
"statisticservice"
|
||||
"notificationservice"
|
||||
"moderationservice"
|
||||
)
|
||||
|
||||
# ==================== 服务器配置 ====================
|
||||
|
||||
@ -410,6 +410,48 @@ services:
|
||||
reservations:
|
||||
memory: 256M
|
||||
|
||||
# 内容审核服务(举报 / 反馈 / 自动隐藏)
|
||||
# 依赖 user / asset / notification Dubbo 服务,以及 Postgres + Redis
|
||||
moderationservice:
|
||||
image: topfans/moderationservice:latest
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile.services
|
||||
target: moderationservice
|
||||
container_name: topfans-moderationservice
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
<<: *common-env
|
||||
PORT: 20011
|
||||
REDIS_HOST: host.docker.internal
|
||||
REDIS_PORT: 6379
|
||||
REDIS_DB: 0
|
||||
DUBBO_USER_SERVICE_URL: tri://userservice:20000
|
||||
DUBBO_ASSET_SERVICE_URL: tri://assetservice:20003
|
||||
DUBBO_NOTIFICATION_SERVICE_URL: tri://notificationservice:20010
|
||||
depends_on:
|
||||
userservice:
|
||||
condition: service_healthy
|
||||
assetservice:
|
||||
condition: service_healthy
|
||||
notificationservice:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- topfans-net
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
expose:
|
||||
- "20011"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "nc -z localhost 20011 || exit 1"]
|
||||
<<: *healthcheck
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 512M
|
||||
reservations:
|
||||
memory: 256M
|
||||
|
||||
# ==================== API Gateway ====================
|
||||
gateway:
|
||||
image: topfans/gateway:latest
|
||||
@ -435,6 +477,7 @@ services:
|
||||
DUBBO_AI_CHAT_SERVICE_URL: tri://aichatservice:20008
|
||||
DUBBO_STATISTIC_SERVICE_URL: tri://statisticservice:20009
|
||||
DUBBO_NOTIFICATION_SERVICE_URL: tri://notificationservice:20010
|
||||
DUBBO_MODERATION_SERVICE_URL: tri://moderationservice:20011
|
||||
# 镭射卡 AI 生成(MiniMax 文生图)
|
||||
MINIMAX_API_KEY: ${MINIMAX_API_KEY:-}
|
||||
MINIMAX_API_URL: ${MINIMAX_API_URL:-https://api.minimaxi.com/v1/image_generation}
|
||||
@ -472,6 +515,8 @@ services:
|
||||
condition: service_healthy
|
||||
notificationservice:
|
||||
condition: service_healthy
|
||||
moderationservice:
|
||||
condition: service_healthy
|
||||
lasercompositor:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
|
||||
@ -552,6 +552,51 @@ services:
|
||||
memory: 128M
|
||||
cpus: '0.25'
|
||||
|
||||
# 内容审核服务(举报 / 反馈 / 自动隐藏)
|
||||
# 依赖 user / asset / notification Dubbo 服务,以及 Postgres + Redis
|
||||
moderationservice:
|
||||
image: topfans/moderationservice:latest
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile.services
|
||||
target: moderationservice
|
||||
container_name: topfans-moderationservice
|
||||
restart: always
|
||||
env_file:
|
||||
- .env.prod
|
||||
environment:
|
||||
<<: *common-env
|
||||
PORT: 20011
|
||||
DUBBO_USER_SERVICE_URL: tri://userservice:20000
|
||||
DUBBO_ASSET_SERVICE_URL: tri://assetservice:20003
|
||||
DUBBO_NOTIFICATION_SERVICE_URL: tri://notificationservice:20010
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
userservice:
|
||||
condition: service_started
|
||||
assetservice:
|
||||
condition: service_started
|
||||
notificationservice:
|
||||
condition: service_started
|
||||
networks:
|
||||
- topfans-net
|
||||
expose:
|
||||
- "20011"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:20011 || exit 1"]
|
||||
<<: *healthcheck
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 300M
|
||||
cpus: '0.5'
|
||||
reservations:
|
||||
memory: 128M
|
||||
cpus: '0.25'
|
||||
|
||||
# ==================== API Gateway ====================
|
||||
gateway:
|
||||
image: topfans/gateway:latest
|
||||
@ -576,6 +621,7 @@ services:
|
||||
DUBBO_AI_CHAT_SERVICE_URL: tri://aichatservice:20008
|
||||
DUBBO_STATISTIC_SERVICE_URL: tri://statisticservice:20009
|
||||
DUBBO_NOTIFICATION_SERVICE_URL: tri://notificationservice:20010
|
||||
DUBBO_MODERATION_SERVICE_URL: tri://moderationservice:20011
|
||||
LASER_COMPOSITOR_URL: http://lasercompositor:7002
|
||||
# 抠图(人像扣底)、OSS、Dify、JWT、Redis 全部走 env_file: .env.prod
|
||||
REDIS_HOST: topfans-redis
|
||||
@ -602,6 +648,8 @@ services:
|
||||
condition: service_started
|
||||
notificationservice:
|
||||
condition: service_started
|
||||
moderationservice:
|
||||
condition: service_started
|
||||
lasercompositor:
|
||||
condition: service_started
|
||||
redis:
|
||||
|
||||
@ -33,6 +33,11 @@
|
||||
:lower-threshold="80"
|
||||
:scroll-into-view="scrollIntoView"
|
||||
:scroll-with-animation="false"
|
||||
:refresher-enabled="true"
|
||||
:refresher-triggered="refreshing"
|
||||
refresher-default-style="white"
|
||||
refresher-background="transparent"
|
||||
@refresherrefresh="handleRefresh"
|
||||
@scrolltolower="handleScrollToLower"
|
||||
>
|
||||
<!-- 顶部哨兵:切换 tab 时通过 scroll-into-view 把列表强制滚回顶部 -->
|
||||
@ -174,6 +179,8 @@ const items = ref([]);
|
||||
const loading = ref(false);
|
||||
const likingMap = ref({});
|
||||
const activeTabKey = ref("");
|
||||
// 下拉刷新状态:与 scroll-view 的 :refresher-triggered 双向绑定
|
||||
const refreshing = ref(false);
|
||||
|
||||
// ===== 分页状态 =====
|
||||
// currentPage : 已加载到的页码(从 1 开始)
|
||||
@ -330,17 +337,18 @@ const resetAndLoad = () => {
|
||||
// 2) 立刻 set items.value → 列表瞬时出现,骨架屏立即下线
|
||||
// 3) 后台并行跑 getAssetCoverRealUrl 拿到精确的预签名 URL,逐个 patch 回 items.value[i].cover_url
|
||||
// (Vue 3 ref 数组里的对象是 reactive 代理,单个属性变更会触发该卡片重渲染)
|
||||
const loadData = async ({ append = false } = {}) => {
|
||||
const loadData = async ({ append = false, silent = false } = {}) => {
|
||||
const tab = activeTab.value;
|
||||
if (!tab || typeof tab.fetch !== "function") {
|
||||
console.warn("[HotCategoryBlock] 当前 tab 未配置 fetch:", tab);
|
||||
if (!append) items.value = [];
|
||||
return;
|
||||
if (!append && !silent) items.value = [];
|
||||
return false;
|
||||
}
|
||||
// 首页用 loading 整屏骨架;分页用 loadingMore 底部小指示器
|
||||
// silent=true 时跳过骨架屏、保留旧 items(用于下拉刷新,避免列表闪烁/抖动)
|
||||
if (append) {
|
||||
loadingMore.value = true;
|
||||
} else {
|
||||
} else if (!silent) {
|
||||
loading.value = true;
|
||||
}
|
||||
try {
|
||||
@ -401,13 +409,17 @@ const loadData = async ({ append = false } = {}) => {
|
||||
} else {
|
||||
hasMore.value = rawItems.length >= PAGE_SIZE;
|
||||
}
|
||||
return true;
|
||||
} else if (!append) {
|
||||
items.value = [];
|
||||
if (!silent) items.value = [];
|
||||
hasMore.value = false;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
} catch (e) {
|
||||
console.error("[HotCategoryBlock] 加载数据失败", e?.message ?? e);
|
||||
if (!append) items.value = [];
|
||||
if (!append && !silent) items.value = [];
|
||||
return false;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
loadingMore.value = false;
|
||||
@ -424,6 +436,47 @@ const handleScrollToLower = () => {
|
||||
loadData({ append: true });
|
||||
};
|
||||
|
||||
// 处理下拉刷新
|
||||
// 设计原则(避免抖动):
|
||||
// - 不清空 items.value:保留旧列表让用户视觉连续,避免内容高度突变
|
||||
// - 不重置 scrollIntoView:用户下拉时已经在顶部,强制滚动会和手势冲突
|
||||
// - silent=true 跳过骨架屏:loadData 内部不会触发 loading 状态切换
|
||||
// - 新数据回来后整体替换 items.value,scroll-view 平滑过渡到新列表
|
||||
const handleRefresh = async () => {
|
||||
if (refreshing.value || loading.value) return;
|
||||
refreshing.value = true;
|
||||
try {
|
||||
currentPage.value = 1;
|
||||
hasMore.value = true;
|
||||
loadingMore.value = false;
|
||||
const success = await loadData({ append: false, silent: true });
|
||||
if (success) {
|
||||
uni.showToast({
|
||||
title: "刷新成功",
|
||||
icon: "success",
|
||||
duration: 1200,
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: "刷新失败",
|
||||
icon: "none",
|
||||
duration: 1500,
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("[HotCategoryBlock] 刷新失败", e?.message ?? e);
|
||||
uni.showToast({
|
||||
title: "刷新失败",
|
||||
icon: "none",
|
||||
duration: 1500,
|
||||
});
|
||||
} finally {
|
||||
setTimeout(() => {
|
||||
refreshing.value = false;
|
||||
}, 500);
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
uni.$on("assetLiked", onAssetLiked);
|
||||
loadData();
|
||||
@ -458,7 +511,7 @@ onUnmounted(() => {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
margin-top: 32rpx;
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
.ranking-tabs {
|
||||
@ -627,7 +680,7 @@ onUnmounted(() => {
|
||||
border-bottom-right-radius: 12px;
|
||||
border-bottom-left-radius: 12px;
|
||||
// opacity: 0.8;
|
||||
padding: 40rpx 20rpx 32rpx;
|
||||
padding: 24rpx 20rpx 32rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
@ -94,7 +94,7 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, watch, onMounted, onUnmounted } from "vue";
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||
import { onLoad, onShow, onHide } from "@dcloudio/uni-app";
|
||||
import { useStore } from "vuex";
|
||||
import Header from "../components/Header.vue";
|
||||
import BottomNav from "../components/BottomNav.vue";
|
||||
@ -265,8 +265,22 @@ onMounted(() => {
|
||||
loadBanners();
|
||||
});
|
||||
|
||||
// 离开页面时记住当前 tab,返回时恢复;首次进入默认 xinghe
|
||||
const lastActiveTab = ref(null);
|
||||
|
||||
onHide(() => {
|
||||
lastActiveTab.value = activeContentTab.value;
|
||||
});
|
||||
|
||||
onShow(() => {
|
||||
activeContentTab.value = "xinghe";
|
||||
// 有记录说明是从其他页面返回,恢复之前停留的 tab
|
||||
// 没有记录说明是首次进入(或从后台切回),保持 xinghe
|
||||
if (lastActiveTab.value) {
|
||||
activeContentTab.value = lastActiveTab.value;
|
||||
lastActiveTab.value = null;
|
||||
} else {
|
||||
activeContentTab.value = "xinghe";
|
||||
}
|
||||
});
|
||||
|
||||
// ========== 后台切回自动刷新 ==========
|
||||
|
||||
Loading…
Reference in New Issue
Block a user