feat:修改遗留bug

This commit is contained in:
zerosaturation 2026-06-23 19:37:18 +08:00
parent 12571eedba
commit 94457ffa8a
7 changed files with 195 additions and 12 deletions

View File

@ -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"]

View File

@ -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

View File

@ -82,6 +82,7 @@ SERVICES=(
"lasercompositor"
"statisticservice"
"notificationservice"
"moderationservice"
)
# ==================== 服务器配置 ====================

View File

@ -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:

View File

@ -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:

View File

@ -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.valuescroll-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;
}

View File

@ -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";
}
});
// ========== ==========