Ver código fonte

问题修改

吴朋磊 2 semanas atrás
pai
commit
a7b58e36ec

+ 38 - 27
common/request.js

@@ -67,35 +67,46 @@ const requestInterceptor = (config) => {
   return config;
 };
 
-// 响应拦截器
+const isLoginPage = () => {
+  const pages = getCurrentPages();
+  if (pages.length === 0) return false;
+  const currentPage = pages[pages.length - 1];
+  return currentPage.route === 'pages/login/index';
+};
+
 const responseInterceptor = (response) => {
-  // console.log("响应拦截器response",response);
-  // 对响应数据做点什么
-  switch (response.data.code) {//response.statusCode
-    case 200:
-      return response.data;
-    case 400:
-	  return response.data;	
-	case 601:
-	  return response.data;	
-	case 602:
-	    return response.data;	
-    case 401:
-	  store.dispatch('logout',true);
-	  uni.redirectTo({
-	    url: '/pages/login/index'
-	  });	
-      throw new Error(response.data.message || '未授权,请重新登录');
-    case 403:
-      throw new Error(response.data.message || '禁止访问');
-    case 404:
-      throw new Error(response.data.message || '资源未找到');
-    case 500:
-	  return response.data;	
-      // throw new Error(response.data.message || '服务器内部错误');
-    default:
-      throw new Error(`未知错误,状态码: ${response.statusCode}`);
+  if (response.data.code === 401) {
+    store.dispatch('logout', true);
+    if (!isLoginPage()) {
+      uni.redirectTo({
+        url: '/pages/login/index'
+      });
+    }
+    throw new Error(response.data.message || '未授权,请重新登录');
+  }
+
+  if (response.data.code === 500 || response.data.code === 503) {
+    uni.showToast({
+      title: response.data.message || '服务器繁忙,请稍后重试',
+      icon: 'none',
+      duration: 3000
+    });
+    throw new Error(response.data.message || '服务器内部错误');
+  }
+
+  if (response.data.code === 200 || response.data.code === 400 || response.data.code === 601 || response.data.code === 602) {
+    return response.data;
+  }
+
+  if (response.data.code === 403) {
+    throw new Error(response.data.message || '禁止访问');
   }
+
+  if (response.data.code === 404) {
+    throw new Error(response.data.message || '资源未找到');
+  }
+
+  throw new Error(`未知错误,状态码: ${response.statusCode}`);
 };
 
 const requestWithInterceptors = (options) => {

+ 4 - 2
components/common-header.vue

@@ -35,8 +35,10 @@ const handleBack = () => {
 	display: flex;
 	align-items: center;
 	justify-content: space-between;
-	height: 96rpx;
-	padding: 0 24rpx;
+	padding-top: env(safe-area-inset-top);
+	height: calc(96rpx + env(safe-area-inset-top));
+	padding-left: 24rpx;
+	padding-right: 24rpx;
 	background-color: #FFFFFF;
 	border-bottom: 2rpx solid #F3F3F3;
 

+ 1 - 0
components/notice-header.vue

@@ -162,6 +162,7 @@ const handleSearchInput = () => {
 	flex-direction: column;
 	background-color: #FFFFFF;
 	z-index: 999;
+	padding-top: env(safe-area-inset-top);
 	// border-bottom: 2rpx solid #EBEEF5;
 
 	.header_top {

+ 4 - 1
components/page-header.vue

@@ -23,7 +23,10 @@
 	left: 0;
 	right: 0;
 	background-color: #FFFFFF;
-	padding: 26rpx 24rpx;
+	padding-top: calc(26rpx + env(safe-area-inset-top));
+	padding-bottom: 26rpx;
+	padding-left: 24rpx;
+	padding-right: 24rpx;
 	border-bottom: 1rpx solid #F0F0F0;
 	z-index: 999;
 

+ 3 - 0
main.js

@@ -1,5 +1,7 @@
 import App from './App'
 import store from './store'
+import './polyfill'
+
 // #ifndef VUE3
 import Vue from 'vue'
 import './uni.promisify.adaptor'
@@ -20,6 +22,7 @@ app.$mount()
 // #ifdef VUE3
 import { createSSRApp } from 'vue'
 import CommonTabbar from './components/commonTabbar.vue'
+
 export function createApp() {
   const app = createSSRApp(App)
   app.use(store)

+ 14 - 0
package-lock.json

@@ -19,6 +19,7 @@
         "pdfjs-dist": "^3.8.162"
       },
       "devDependencies": {
+        "@dcloudio/types": "^3.4.32",
         "@dcloudio/uni-cli-i18n": "^2.0.2-4060620250520001",
         "@dcloudio/uni-cli-shared": "^3.0.0-4020320240708001"
       }
@@ -1425,6 +1426,13 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@dcloudio/types": {
+      "version": "3.4.32",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/types/-/types-3.4.32.tgz",
+      "integrity": "sha512-sjhbkjUKxoym8KLEnyeXxCsxvRlBc7Bd/kNSZZRLj+lewS384bDPtq/x5FZ4iG+NrnzDmg3+HyiwV5u5vu2reQ==",
+      "dev": true,
+      "license": "Apache-2.0"
+    },
     "node_modules/@dcloudio/uni-cli-i18n": {
       "version": "2.0.2-4060620250520001",
       "resolved": "https://registry.npmjs.org/@dcloudio/uni-cli-i18n/-/uni-cli-i18n-2.0.2-4060620250520001.tgz",
@@ -7931,6 +7939,12 @@
         "@babel/helper-validator-identifier": "^7.27.1"
       }
     },
+    "@dcloudio/types": {
+      "version": "3.4.32",
+      "resolved": "https://registry.npmmirror.com/@dcloudio/types/-/types-3.4.32.tgz",
+      "integrity": "sha512-sjhbkjUKxoym8KLEnyeXxCsxvRlBc7Bd/kNSZZRLj+lewS384bDPtq/x5FZ4iG+NrnzDmg3+HyiwV5u5vu2reQ==",
+      "dev": true
+    },
     "@dcloudio/uni-cli-i18n": {
       "version": "2.0.2-4060620250520001",
       "resolved": "https://registry.npmjs.org/@dcloudio/uni-cli-i18n/-/uni-cli-i18n-2.0.2-4060620250520001.tgz",

+ 1 - 0
package.json

@@ -20,6 +20,7 @@
     "pdfjs-dist": "^3.8.162"
   },
   "devDependencies": {
+    "@dcloudio/types": "^3.4.32",
     "@dcloudio/uni-cli-i18n": "^2.0.2-4060620250520001",
     "@dcloudio/uni-cli-shared": "^3.0.0-4020320240708001"
   }

+ 6 - 1
pages/message/index.vue

@@ -113,6 +113,8 @@
 	display: flex;
 	flex-direction: column;
 	background-color: #FFFFFF;
+	padding-bottom: env(safe-area-inset-bottom);
+	box-sizing: border-box;
 }
 
 .message_content {
@@ -120,7 +122,10 @@
 	display: flex;
 	flex-direction: column;
 	overflow: hidden;
-	padding: 140rpx 0rpx 160rpx 0rpx;
+	padding-top: calc(140rpx + env(safe-area-inset-top));
+	padding-bottom: calc(160rpx + env(safe-area-inset-bottom));
+	padding-left: 0rpx;
+	padding-right: 0rpx;
 }
 
 .message_header {

+ 3 - 1
pages/notice/mine/detail.vue

@@ -112,6 +112,8 @@ const goBack = () => {
 	display: flex;
 	flex-direction: column;
 	background-color: #FFFFFF;
+	padding-bottom: env(safe-area-inset-bottom);
+	box-sizing: border-box;
 }
 
 .detail_content {
@@ -119,7 +121,7 @@ const goBack = () => {
 	display: flex;
 	flex-direction: column;
 	overflow: hidden;
-	padding-top: 140rpx;
+	padding-top: calc(140rpx + env(safe-area-inset-top));
 }
 
 .detail_header {

+ 6 - 1
pages/notice/mine/index.vue

@@ -154,6 +154,8 @@ const handleDetail = (id) => {
 	display: flex;
 	flex-direction: column;
 	background-color: #FFFFFF;
+	padding-bottom: env(safe-area-inset-bottom);
+	box-sizing: border-box;
 }
 
 .notice_content {
@@ -161,7 +163,10 @@ const handleDetail = (id) => {
 	display: flex;
 	flex-direction: column;
 	overflow: hidden;
-	padding: 325rpx 0rpx 104px 0rpx;
+	padding-top: calc(325rpx + env(safe-area-inset-top));
+	padding-bottom: calc(208rpx + env(safe-area-inset-bottom));
+	padding-left: 0rpx;
+	padding-right: 0rpx;
 }
 
 .notice_list {

+ 6 - 3
pages/notice/overview/index.vue

@@ -202,16 +202,19 @@ const handleDetail = (id) => {
 	display: flex;
 	flex-direction: column;
 	background-color: #FFFFFF;
+	padding-bottom: env(safe-area-inset-bottom);
+	box-sizing: border-box;
 }
 
 .notice_content {
-
 	flex: 1;
 	display: flex;
 	flex-direction: column;
 	overflow: hidden;
-	padding: 325rpx 0rpx 104px 0rpx;
-
+	padding-top: calc(325rpx + env(safe-area-inset-top));
+	padding-bottom: calc(208rpx + env(safe-area-inset-bottom));
+	padding-left: 0rpx;
+	padding-right: 0rpx;
 }
 
 .notice_list {

+ 8 - 3
pages/notice/publish/index.vue

@@ -457,16 +457,21 @@ const handleSave = async () => {
 
 <style lang="scss" scoped>
 .page_publish {
-	// min-height: 100vh;
-	// background-color: #F5F5F5;
+	min-height: 100vh;
+	background-color: #FFFFFF;
 	display: flex;
 	flex-direction: column;
+	padding-bottom: env(safe-area-inset-bottom);
+	box-sizing: border-box;
 }
 
 .publish_content {
 	flex: 1;
 	box-sizing: border-box;
-	padding: 120rpx 24rpx 158rpx 24rpx;
+	padding-top: calc(120rpx + env(safe-area-inset-top));
+	padding-bottom: 158rpx;
+	padding-left: 24rpx;
+	padding-right: 24rpx;
 }
 
 .form_item {

+ 6 - 1
pages/todo/index.vue

@@ -88,6 +88,8 @@
 	display: flex;
 	flex-direction: column;
 	background-color: #FFFFFF;
+	padding-bottom: env(safe-area-inset-bottom);
+	box-sizing: border-box;
 }
 
 .todo_content {
@@ -95,7 +97,10 @@
 	display: flex;
 	flex-direction: column;
 	overflow: hidden;
-	padding: 140rpx 0rpx 160rpx 0rpx;
+	padding-top: calc(140rpx + env(safe-area-inset-top));
+	padding-bottom: calc(160rpx + env(safe-area-inset-bottom));
+	padding-left: 0rpx;
+	padding-right: 0rpx;
 }
 // 待办事项标题
 .todo_header {

+ 6 - 3
pages/workspace/index.vue

@@ -512,12 +512,15 @@ $shadow-sm: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
 .page_workspace {
 	min-height: 100vh;
 	background-color: #F8F9FD;
-	// padding-bottom: 120rpx;
-	// font-family: PingFang SC, Helvetica Neue, Arial, sans-serif;
+	padding-bottom: env(safe-area-inset-bottom);
+	box-sizing: border-box;
 }
 
 .workspace_content {
-	padding: 140rpx 24rpx 140rpx 24rpx;
+	padding-top: calc(140rpx + env(safe-area-inset-top));
+	padding-bottom: calc(140rpx + env(safe-area-inset-bottom));
+	padding-left: 24rpx;
+	padding-right: 24rpx;
 	height: 100vh;
 	box-sizing: border-box;
 	overflow: hidden;

+ 26 - 12
pages/workspace/schedule.vue

@@ -102,6 +102,15 @@
 import { ref, computed, onMounted } from 'vue';
 import workspaceApi from '@/reqApi/workspace';
 
+interface CalendarDay {
+	date: number;
+	month: number;
+	year: number;
+	dateStr: string;
+	isCurrentMonth: boolean;
+	hasSchedule: boolean;
+}
+
 const weekdays = ['日', '一', '二', '三', '四', '五', '六'];
 const today = new Date();
 const todayStr = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`;
@@ -109,16 +118,16 @@ const todayStr = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart
 const currentYear = ref(today.getFullYear());
 const currentMonth = ref(today.getMonth() + 1);
 const selectedDate = ref(todayStr);
-const calendarDays = ref([]);
-const scheduleEvents = ref({});
+const calendarDays = ref<CalendarDay[]>([]);
+const scheduleEvents = ref<{ [key: string]: Array<{ id: string; title: string }> }>({});
 const isLoading = ref(false);
 const showAddModal = ref(false);
 const scheduleContent = ref('');
-const editItem = ref(null);
+const editItem = ref<{ id: string; title: string } | null>(null);
 
-const expandedItems = ref({});
+const expandedItems = ref<{ [key: string]: boolean }>({});
 
-const toggleExpand = (id) => {
+const toggleExpand = (id: string) => {
 	expandedItems.value[id] = !expandedItems.value[id];
 };
 
@@ -200,13 +209,13 @@ const fetchScheduleList = async () => {
 	}
 };
 
-const updateScheduleEvents = (data) => {
+const updateScheduleEvents = (data: { [key: string]: any[] }) => {
 	Object.keys(scheduleEvents.value).forEach(key => {
 		delete scheduleEvents.value[key];
 	});
 	Object.keys(data).forEach(dateKey => {
 		const list = data[dateKey] || [];
-		scheduleEvents.value[dateKey] = list.map(item => ({
+		scheduleEvents.value[dateKey] = list.map((item: any) => ({
 			id: String(item.id),
 			title: item.content || ''
 		}));
@@ -234,13 +243,13 @@ const handleNextMonth = () => {
 	fetchScheduleList();
 };
 
-const handleDayClick = (day) => {
+const handleDayClick = (day: CalendarDay) => {
 	selectedDate.value = day.dateStr;
 	currentYear.value = day.year;
 	currentMonth.value = day.month;
 };
 
-const handleDateChange = (e) => {
+const handleDateChange = (e: { detail: { value: string } }) => {
 	const date = e.detail.value;
 	const [year, month, day] = date.split('-');
 	currentYear.value = parseInt(year);
@@ -261,13 +270,13 @@ const handleAddSchedule = () => {
 	showAddModal.value = true;
 };
 
-const handleEdit = (item) => {
+const handleEdit = (item: { id: string; title: string }) => {
 	editItem.value = item;
 	scheduleContent.value = item.title;
 	showAddModal.value = true;
 };
 
-const handleDelete = async (id) => {
+const handleDelete = async (id: string) => {
 	uni.showModal({
 		title: '提示',
 		content: '确定要删除这条日程吗?',
@@ -330,6 +339,8 @@ onMounted(() => {
 .page {
 	height: 100vh;
 	background-color: #F5F7FA;
+	padding-bottom: env(safe-area-inset-bottom);
+	box-sizing: border-box;
 }
 
 .nav_bar {
@@ -337,7 +348,10 @@ onMounted(() => {
 	display: flex;
 	align-items: center;
 	justify-content: space-between;
-	padding: 24rpx;
+	padding-top: calc(24rpx + env(safe-area-inset-top));
+	padding-bottom: 24rpx;
+	padding-left: 24rpx;
+	padding-right: 24rpx;
 
 	.nav_back {
 		display: flex;

+ 49 - 0
polyfill.js

@@ -0,0 +1,49 @@
+// #ifdef MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-BAIDU
+// 小程序环境 Vue Devtools 兼容处理
+(function() {
+  try {
+    // Vue 内部 getDevtoolsGlobalHook 会获取全局对象
+    // 并尝试访问 __VUE_DEVTOOLS_GLOBAL_HOOK__
+    // 在小程序中,globalThis 可能为 null 或不存在
+    
+    // 获取全局对象的安全方式
+    var getGlobal = function() {
+      if (typeof globalThis !== 'undefined' && globalThis !== null) {
+        return globalThis;
+      }
+      if (typeof global !== 'undefined' && global !== null) {
+        return global;
+      }
+      if (typeof window !== 'undefined' && window !== null) {
+        return window;
+      }
+      // 小程序环境特殊处理
+      try {
+        // eslint-disable-next-line no-new-func
+        return Function('return this')();
+      } catch (e) {
+        return null;
+      }
+    };
+    
+    var _global = getGlobal();
+    
+    if (_global) {
+      // 确保 __VUE_DEVTOOLS_GLOBAL_HOOK__ 存在
+      if (!_global.__VUE_DEVTOOLS_GLOBAL_HOOK__) {
+        _global.__VUE_DEVTOOLS_GLOBAL_HOOK__ = {
+          enabled: false,
+          addDevtools: function() {},
+          setupDevtoolsPlugin: function() {},
+          on: function() {},
+          once: function() {},
+          off: function() {},
+          emit: function() {}
+        };
+      }
+    }
+  } catch (e) {
+    console.warn('Polyfill __VUE_DEVTOOLS_GLOBAL_HOOK__ failed:', e);
+  }
+})();
+// #endif

+ 47 - 0
tsconfig.json

@@ -0,0 +1,47 @@
+{
+	"compilerOptions": {
+		"target": "ESNext",
+		"useDefineForClassFields": true,
+		"module": "ESNext",
+		"moduleResolution": "bundler",
+		"strict": true,
+		"jsx": "preserve",
+		"resolveJsonModule": true,
+		"isolatedModules": true,
+		"esModuleInterop": true,
+		"lib": ["ESNext", "DOM"],
+		"skipLibCheck": true,
+		"noEmit": true,
+		"paths": {
+			"@/*": ["./*"]
+		},
+		"types": ["@dcloudio/types"]
+	},
+	"include": [
+		"src/**/*.ts",
+		"src/**/*.d.ts",
+		"src/**/*.tsx",
+		"src/**/*.vue",
+		"pages/**/*.ts",
+		"pages/**/*.d.ts",
+		"pages/**/*.tsx",
+		"pages/**/*.vue",
+		"components/**/*.ts",
+		"components/**/*.d.ts",
+		"components/**/*.tsx",
+		"components/**/*.vue",
+		"reqApi/**/*.ts",
+		"reqApi/**/*.js",
+		"common/**/*.ts",
+		"common/**/*.js",
+		"store/**/*.ts",
+		"store/**/*.js",
+		"App.vue",
+		"main.js"
+	],
+	"exclude": [
+		"node_modules",
+		"dist",
+		"unpackage"
+	]
+}

+ 4 - 4
unpackage/dist/cache/.vite/deps/_metadata.json

@@ -1,8 +1,8 @@
 {
-  "hash": "01502c9b",
-  "configHash": "5ccaef1e",
-  "lockfileHash": "3f808f5a",
-  "browserHash": "ae45c832",
+  "hash": "66d9a829",
+  "configHash": "6d67b660",
+  "lockfileHash": "65c58edb",
+  "browserHash": "b0ea0067",
   "optimized": {},
   "chunks": {}
 }

+ 6 - 6
vite.config.js

@@ -2,18 +2,18 @@ import {
 	defineConfig
 } from 'vite'
 import uni from '@dcloudio/vite-plugin-uni'
-// import path from 'path'
+import path from 'path'
 const define = {}
 if (!["mp-weixin", "h5", "web"].includes(process.env.UNI_PLATFORM)) {
 	define['global'] = null
 	define['wx'] = 'uni'
 }
 export default defineConfig({
-	// resolve: {
-	// 	alias: {
-	// 		'l-echarts': '@/uni_modules/l-echarts/components/l-echarts/l-echarts.vue'
-	// 	}
-	// },
+	resolve: {
+		alias: {
+			'@': path.resolve(__dirname, '.')
+		}
+	},
 	plugins: [uni()],
 	define,
 	// base: process.env.NODE_ENV === 'production' ? './' : '/',