快乐的梦鱼 3 周之前
父節點
當前提交
96176b57c9

+ 34 - 0
config.conf

@@ -0,0 +1,34 @@
+server
+{
+    # 匹配路径:/ 、/about/ 、/.nuxt/* 、/channel/* 、/page/*
+    # 用 ~* 实现不区分大小写匹配(可选,如需严格大小写可改为 ~)
+    location ~* ^(/|/about/|/inheritor/.*|/\.nuxt/.*|/\_nuxt/.*|/channel/.*|/page/.*|/api/ecms/.*)$ {
+        # 1. 核心:反向代理至目标服务 localhost:3106
+        proxy_pass http://localhost:3106;
+        
+        # 2. 关键:禁用反向代理缓存(多维度兜底,确保无缓存)
+        # 2.1 告诉后端服务不缓存当前请求
+        proxy_cache off;  # 直接关闭 Nginx 代理缓存(核心配置)
+        proxy_no_cache 1; # 强制不缓存响应内容
+        proxy_cache_bypass 1; # 强制绕过缓存,直接请求后端
+        
+        # 2.2 响应头:告诉客户端(浏览器)不缓存
+        add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
+        add_header Pragma "no-cache";
+        add_header Expires "0";
+        add_header Surrogate-Control "no-store";
+        
+        # 3. 可选:优化反向代理的常规配置(保证服务稳定性)
+        proxy_set_header Host $host;
+        proxy_set_header X-Real-IP $remote_addr;
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_set_header X-Forwarded-Proto $scheme;
+        proxy_connect_timeout 30s; # 连接超时时间
+        proxy_send_timeout 30s;    # 发送超时时间
+        proxy_read_timeout 30s;    # 读取超时时间
+        proxy_buffering off;       # 关闭代理缓冲(实时响应,同时避免缓存)
+    }
+    
+    access_log  /www/wwwlogs/xmswhycbhzx.cn.log;
+    error_log  /www/wwwlogs/xmswhycbhzx.cn.error.log;
+}

+ 1 - 1
server/api/ecms/article/[id].ts

@@ -32,7 +32,7 @@ export default defineEventHandler<EventHandlerRequest, Promise<IResponse<IArticl
       return createErrorResponse('分类ID不能为空');
     const article = await DB.table('pr_cms_archives')
             .where('id', id)
-            .where('deletetime', 'null')
+            .whereNull('deletetime')
             .where('status', 'normal')
             .first();
     if (!article) 

+ 1 - 1
server/api/ecms/article/byChannel.ts

@@ -13,7 +13,7 @@ export default defineEventHandler<EventHandlerRequest, Promise<IResponse<CommonP
     if (!channelId)
       return createErrorResponse('分类ID不能为空');
     const articles = await DB.table('pr_cms_archives')
-            .where('deletetime', 'null')
+            .whereNull('deletetime')
             .where('channel_id', channelId)
             .where('status', 'normal')
             .orderBy('weigh', 'desc')

+ 1 - 1
server/api/ecms/article/byChannelAndOnLevelChild.ts

@@ -21,7 +21,7 @@ export default defineEventHandler<EventHandlerRequest, Promise<IResponse<CommonP
 
     const articles = await DB.table('pr_cms_archives')
             .whereIn('channel_id', [...childChannels.map(item => item.id), channelId])
-            .where('deletetime', 'null')
+            .whereNull('deletetime')
             .where('status', 'normal')
             .orderBy('weigh', 'desc')
             .orderBy('publishtime', 'desc')

+ 1 - 1
server/api/ecms/article/byChannelName.ts

@@ -29,7 +29,7 @@ export default defineEventHandler<EventHandlerRequest, Promise<IResponse<ICommon
     const articles = await DB.table('pr_cms_archives')
             .where('channel_id', channelId)
             .where('status', 'normal')
-            .where('deletetime', 'null')
+            .whereNull('deletetime')
             .orderBy('weigh', 'desc')
             .orderBy('publishtime', 'desc')
             .orderBy('createtime', 'desc')

+ 1 - 1
server/api/ecms/article/recommend.ts

@@ -13,7 +13,7 @@ export default defineEventHandler<EventHandlerRequest, Promise<IResponse<IArticl
     // 先按weigh降序排序,再按publishtime降序排序
     const articles = await DB.table('pr_cms_archives')
         .where('status', 'normal')
-        .where('deletetime', 'null')
+        .whereNull('deletetime')
         .where('flag', 'like', '%recommend%')
         .orderBy('weigh','desc')
         .orderBy('publishtime','desc')

+ 1 - 1
server/api/ecms/article/search.ts

@@ -14,7 +14,7 @@ export default defineEventHandler<EventHandlerRequest, Promise<IResponse<ICommon
     // 2. 从pr_cms_archives表中通过channel_id查询文章
     const articles = await DB.table('pr_cms_archives')
             .where('status', 'normal')
-            .where('deletetime', 'null')
+            .whereNull('deletetime')
             .where('title', 'like', `%${search}%`)
             .orderBy('weigh', 'desc')
             .orderBy('publishtime', 'desc')

+ 1 - 1
server/db/QueryGenerator.ts

@@ -30,7 +30,7 @@ export type QueryCondition = 'and'|'or';
 
 export type QuerySubWhereCallback = (query : QueryGenerator) => void;
 
-type QueryAcceptValue = string|number|boolean|Date;
+type QueryAcceptValue = string|number|boolean|Date|null;
 
 interface QueryWhere {
   condition : QueryCondition;

+ 2 - 2
src/api/RequestModules.ts

@@ -19,8 +19,8 @@ import type { DataModel, NewDataModel } from "@imengyu/js-request-transform";
 import { StringUtils } from "@imengyu/imengyu-utils";
 
 const ApiCofig = {
-  serverDev: 'https://mn.wenlvti.net/api',
-  serverProd: 'https://mn.wenlvti.net/api',
+  serverDev: '/api',
+  serverProd: '/api',
   mainBodyId: 1,
 }
 

+ 1 - 0
src/components/content/CommonListPage.vue

@@ -25,6 +25,7 @@
           text: item.name,
           link: `${item.url}?parent_channel_id=${channelId}`,
         }))"
+        :showBackUpLevel="true"
         :backUpLevelLink="`/channel/${channelData.content.value?.parent_id}`"
       />
     </template>

+ 9 - 0
src/composeable/InternalData.ts

@@ -1,5 +1,14 @@
 import type { IChannel } from "~~/server/api/ecms/channel/[id]";
 
+export function getNeedJumpToInternalPage(data: IChannel[]) {
+  const intangiblePage = data.find(item => item.name === '非遗项目');
+  if (intangiblePage)
+    return '/inheritor/intangible';
+  const inheritorPage = data.find(item => item.name === '非遗传承人');
+  if (inheritorPage) 
+    return '/inheritor/inheritor';
+  return undefined;
+}
 //处理系统内部使用的分类数据
 export function solveChannelData(data: IChannel[]) : (IChannel & {
   url: string;

+ 12 - 1
src/pages/channel/[id].vue

@@ -70,7 +70,7 @@ import { useSSrSimpleDataLoader } from '@/composeable/SimpleDataLoader';
 import { DateUtils } from '@imengyu/imengyu-utils';
 import type { IChannel } from '~~/server/api/ecms/channel/[id]';
 import SimplePagination from '~/components/content/SimplePagination.vue';
-import { solveChannelData } from '~/composeable/InternalData';
+import { getNeedJumpToInternalPage, solveChannelData } from '~/composeable/InternalData';
 
 const carouselConfig : (typeof Carousel['props']) = {
   itemsToShow: 1,
@@ -79,6 +79,8 @@ const carouselConfig : (typeof Carousel['props']) = {
 }
 
 const route = useRoute();
+const router = useRouter();
+
 const channelId = parseInt(route.params.id as string);
 
 const channelData = await useSSrSimpleDataLoader('channel' + channelId, async () => {
@@ -89,6 +91,15 @@ const channelData = await useSSrSimpleDataLoader('channel' + channelId, async ()
     childs: IChannel[];
     parents: IChannel[];
   };
+  const internalPage = getNeedJumpToInternalPage(data.childs);
+  if (internalPage) {
+    if (import.meta.client) {
+      setTimeout(() => {
+        router.push(internalPage + '?parent_channel_id=' + channelId);
+      }, 200);
+    }
+    return;
+  }
   return {
     ...data,
     childs: solveChannelData(data.childs),

+ 1 - 1
src/pages/index.vue

@@ -31,7 +31,7 @@
             <div class="section-title">
               <div class="d-flex flex-row align-items-center">
                 <h2 id="notices-button" @click="currentTab = 'notices'" :class="{'active': currentTab === 'notices'}" class="button icon">通知公告</h2>
-                <h2 id="hot-news-button" @click="currentTab = 'hot'" :class="{'active': currentTab === 'hot'}" class="button icon">热点新闻</h2>
+                <!-- <h2 id="hot-news-button" @click="currentTab = 'hot'" :class="{'active': currentTab === 'hot'}" class="button icon">热点新闻</h2> -->
               </div>
               <router-link :to="currentTab === 'notices' ? 
                 `/channel/${notices.content.value?.channel_id}` :