app
This commit is contained in:
@@ -60,7 +60,7 @@
|
|||||||
"ExpireMinutes": 60
|
"ExpireMinutes": 60
|
||||||
},
|
},
|
||||||
"Cors": {
|
"Cors": {
|
||||||
"Origins": []
|
"Origins": ["capacitor://localhost", "http://localhost"]
|
||||||
},
|
},
|
||||||
"OfficialDocuments": {
|
"OfficialDocuments": {
|
||||||
"InstitutionName": "明序大学",
|
"InstitutionName": "明序大学",
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
# Capacitor
|
||||||
|
/android
|
||||||
|
/ios
|
||||||
|
.env.capacitor
|
||||||
|
|
||||||
# Logs
|
# Logs
|
||||||
logs
|
logs
|
||||||
*.log
|
*.log
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import type { CapacitorConfig } from '@capacitor/cli'
|
||||||
|
|
||||||
|
const config: CapacitorConfig = {
|
||||||
|
appId: 'edu.mingxu.jiaowu',
|
||||||
|
appName: '明序教务',
|
||||||
|
webDir: 'dist',
|
||||||
|
bundledWebRuntime: false,
|
||||||
|
android: {
|
||||||
|
allowMixedContent: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export default config
|
||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover, maximum-scale=1.0, user-scalable=no" />
|
||||||
<meta name="theme-color" content="#152550" />
|
<meta name="theme-color" content="#152550" />
|
||||||
<meta name="description" content="明序大学教务管理系统" />
|
<meta name="description" content="明序大学教务管理系统" />
|
||||||
<title>明序教务管理系统</title>
|
<title>明序教务管理系统</title>
|
||||||
|
|||||||
Generated
+1021
-3
File diff suppressed because it is too large
Load Diff
+11
-1
@@ -6,9 +6,18 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vue-tsc -b && vite build",
|
"build": "vue-tsc -b && vite build",
|
||||||
"preview": "vite preview"
|
"build:capacitor": "vue-tsc -b && vite build --mode capacitor",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"cap:sync": "npx cap sync",
|
||||||
|
"cap:open:android": "npx cap open android",
|
||||||
|
"cap:open:ios": "npx cap open ios",
|
||||||
|
"cap:run:android": "npx cap run android",
|
||||||
|
"cap:run:ios": "npx cap run ios"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@capacitor/android": "^8.4.2",
|
||||||
|
"@capacitor/core": "^8.4.2",
|
||||||
|
"@capacitor/ios": "^8.4.2",
|
||||||
"@ckeditor/ckeditor5-vue": "^8.2.0",
|
"@ckeditor/ckeditor5-vue": "^8.2.0",
|
||||||
"@element-plus/icons-vue": "^2.3.2",
|
"@element-plus/icons-vue": "^2.3.2",
|
||||||
"axios": "^1.18.1",
|
"axios": "^1.18.1",
|
||||||
@@ -24,6 +33,7 @@
|
|||||||
"vue-router": "^4.6.4"
|
"vue-router": "^4.6.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@capacitor/cli": "^8.4.2",
|
||||||
"@types/node": "^24.13.2",
|
"@types/node": "^24.13.2",
|
||||||
"@types/qrcode": "1.5.6",
|
"@types/qrcode": "1.5.6",
|
||||||
"@vitejs/plugin-vue": "^6.0.7",
|
"@vitejs/plugin-vue": "^6.0.7",
|
||||||
|
|||||||
+2
-1
@@ -1,4 +1,5 @@
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
import { goLogin } from '../utils/navigate'
|
||||||
|
|
||||||
const http = axios.create({
|
const http = axios.create({
|
||||||
baseURL: import.meta.env.VITE_API_BASE_URL ?? '/api',
|
baseURL: import.meta.env.VITE_API_BASE_URL ?? '/api',
|
||||||
@@ -17,7 +18,7 @@ http.interceptors.response.use(
|
|||||||
if (error.response?.status === 401 && !error.config?.url?.endsWith('/auth/login')) {
|
if (error.response?.status === 401 && !error.config?.url?.endsWith('/auth/login')) {
|
||||||
localStorage.removeItem('jiaowu_token')
|
localStorage.removeItem('jiaowu_token')
|
||||||
localStorage.removeItem('jiaowu_user')
|
localStorage.removeItem('jiaowu_user')
|
||||||
window.location.assign(`/login?redirect=${encodeURIComponent(location.pathname)}`)
|
goLogin(location.pathname + location.search + location.hash)
|
||||||
}
|
}
|
||||||
return Promise.reject(error)
|
return Promise.reject(error)
|
||||||
},
|
},
|
||||||
|
|||||||
+6
-4
@@ -3,8 +3,10 @@ import { createPinia } from 'pinia'
|
|||||||
import './style.css'
|
import './style.css'
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import router from './router'
|
import router from './router'
|
||||||
|
import { setRouter } from './utils/navigate'
|
||||||
|
|
||||||
createApp(App)
|
const app = createApp(App)
|
||||||
.use(createPinia())
|
app.use(createPinia())
|
||||||
.use(router)
|
app.use(router)
|
||||||
.mount('#app')
|
setRouter(router)
|
||||||
|
app.mount('#app')
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'
|
||||||
import { useAuthStore } from '../stores/auth'
|
import { useAuthStore } from '../stores/auth'
|
||||||
import AdminLayout from '../layouts/AdminLayout.vue'
|
import AdminLayout from '../layouts/AdminLayout.vue'
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(),
|
history: import.meta.env.VITE_ROUTER_MODE === 'hash'
|
||||||
|
? createWebHashHistory()
|
||||||
|
: createWebHistory(),
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: '/login',
|
path: '/login',
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import type { Router } from 'vue-router'
|
||||||
|
|
||||||
|
let router: Router | null = null
|
||||||
|
|
||||||
|
export function setRouter(r: Router): void {
|
||||||
|
router = r
|
||||||
|
}
|
||||||
|
|
||||||
|
export function goLogin(redirect: string): void {
|
||||||
|
if (router) {
|
||||||
|
router.push({ name: 'login', query: { redirect } })
|
||||||
|
} else {
|
||||||
|
window.location.assign(
|
||||||
|
`/?redirect=${encodeURIComponent(redirect)}#/login`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -314,8 +314,9 @@ async function showQrCode() {
|
|||||||
ElMessage.warning('未取得签到码,请刷新考勤表后重试。')
|
ElMessage.warning('未取得签到码,请刷新考勤表后重试。')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
const publicBase = import.meta.env.VITE_PUBLIC_BASE_URL ?? window.location.origin
|
||||||
qrCheckInUrl.value =
|
qrCheckInUrl.value =
|
||||||
`${window.location.origin}/my-attendance?token=${encodeURIComponent(sheet.checkInToken)}`
|
`${publicBase}/my-attendance?token=${encodeURIComponent(sheet.checkInToken)}`
|
||||||
try {
|
try {
|
||||||
qrDataUrl.value = await QRCode.toDataURL(qrCheckInUrl.value, {
|
qrDataUrl.value = await QRCode.toDataURL(qrCheckInUrl.value, {
|
||||||
width: 360,
|
width: 360,
|
||||||
|
|||||||
@@ -610,9 +610,10 @@ function openCalendarClient() {
|
|||||||
function normalizeCalendarSubscription(value: any) {
|
function normalizeCalendarSubscription(value: any) {
|
||||||
if (!value?.feedPath) return value
|
if (!value?.feedPath) return value
|
||||||
const configuredBase = String(http.defaults.baseURL ?? '/api')
|
const configuredBase = String(http.defaults.baseURL ?? '/api')
|
||||||
|
const publicBase = import.meta.env.VITE_PUBLIC_BASE_URL ?? window.location.origin
|
||||||
const apiBase = new URL(
|
const apiBase = new URL(
|
||||||
configuredBase.endsWith('/') ? configuredBase : `${configuredBase}/`,
|
configuredBase.endsWith('/') ? configuredBase : `${configuredBase}/`,
|
||||||
window.location.origin,
|
publicBase,
|
||||||
)
|
)
|
||||||
const feedUrl = new URL(value.feedPath, apiBase).toString()
|
const feedUrl = new URL(value.feedPath, apiBase).toString()
|
||||||
return {
|
return {
|
||||||
|
|||||||
+34
-28
@@ -1,37 +1,43 @@
|
|||||||
import { defineConfig } from 'vite'
|
import { defineConfig, loadEnv } from 'vite'
|
||||||
import vue from '@vitejs/plugin-vue'
|
import vue from '@vitejs/plugin-vue'
|
||||||
import AutoImport from 'unplugin-auto-import/vite'
|
import AutoImport from 'unplugin-auto-import/vite'
|
||||||
import Components from 'unplugin-vue-components/vite'
|
import Components from 'unplugin-vue-components/vite'
|
||||||
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
|
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
|
||||||
|
|
||||||
// https://vite.dev/config/
|
// https://vite.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig(({ mode }) => {
|
||||||
plugins: [
|
const env = loadEnv(mode, process.cwd(), '')
|
||||||
vue(),
|
const isCapacitor = env.VITE_ROUTER_MODE === 'hash'
|
||||||
AutoImport({
|
|
||||||
resolvers: [ElementPlusResolver()],
|
return {
|
||||||
dts: 'src/auto-imports.d.ts',
|
plugins: [
|
||||||
}),
|
vue(),
|
||||||
Components({
|
AutoImport({
|
||||||
resolvers: [ElementPlusResolver({ importStyle: 'css', directives: true })],
|
resolvers: [ElementPlusResolver()],
|
||||||
dts: 'src/components.d.ts',
|
dts: 'src/auto-imports.d.ts',
|
||||||
}),
|
}),
|
||||||
],
|
Components({
|
||||||
build: {
|
resolvers: [ElementPlusResolver({ importStyle: 'css', directives: true })],
|
||||||
outDir: '../src/Jiaowu.Api/wwwroot',
|
dts: 'src/components.d.ts',
|
||||||
emptyOutDir: true,
|
}),
|
||||||
},
|
],
|
||||||
server: {
|
base: isCapacitor ? './' : '/',
|
||||||
port: 5173,
|
build: {
|
||||||
proxy: {
|
outDir: isCapacitor ? 'dist' : '../src/Jiaowu.Api/wwwroot',
|
||||||
'/api': {
|
emptyOutDir: true,
|
||||||
target: 'http://localhost:5255',
|
},
|
||||||
changeOrigin: true,
|
server: {
|
||||||
},
|
port: 5173,
|
||||||
'/health': {
|
proxy: {
|
||||||
target: 'http://localhost:5255',
|
'/api': {
|
||||||
changeOrigin: true,
|
target: 'http://localhost:5255',
|
||||||
|
changeOrigin: true,
|
||||||
|
},
|
||||||
|
'/health': {
|
||||||
|
target: 'http://localhost:5255',
|
||||||
|
changeOrigin: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user