生日调整
This commit is contained in:
parent
c79e037aab
commit
96d1d38a8b
37
index.html
37
index.html
@ -2,13 +2,46 @@
|
|||||||
<html lang="zh">
|
<html lang="zh">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8"/>
|
<meta charset="UTF-8"/>
|
||||||
|
<!-- 版本号:每次发布时自动更新 -->
|
||||||
|
<meta name="version" content="20251209-154559">
|
||||||
|
<!-- HTML文件不缓存,但允许静态资源缓存 -->
|
||||||
|
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
||||||
|
<meta http-equiv="Pragma" content="no-cache">
|
||||||
|
<meta http-equiv="Expires" content="0">
|
||||||
<script>
|
<script>
|
||||||
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
||||||
CSS.supports('top: constant(a)'))
|
CSS.supports('top: constant(a)'))
|
||||||
document.write(
|
document.write(
|
||||||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||||
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
(coverSupport ? ', viewport-fit=cover' : '') + '" />');
|
||||||
log=false
|
var log = false;
|
||||||
|
|
||||||
|
// 版本检查:如果检测到新版本,清除缓存并刷新
|
||||||
|
(function() {
|
||||||
|
try {
|
||||||
|
const currentVersion = document.querySelector('meta[name="version"]')?.getAttribute('content');
|
||||||
|
const storedVersion = localStorage.getItem('app_version');
|
||||||
|
|
||||||
|
if (storedVersion && storedVersion !== currentVersion && currentVersion) {
|
||||||
|
// 检测到新版本,清除所有缓存
|
||||||
|
if ('caches' in window) {
|
||||||
|
caches.keys().then(names => {
|
||||||
|
names.forEach(name => caches.delete(name));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 更新版本号
|
||||||
|
localStorage.setItem('app_version', currentVersion);
|
||||||
|
// 强制刷新页面
|
||||||
|
window.location.reload(true);
|
||||||
|
} else if (currentVersion) {
|
||||||
|
// 首次访问或版本相同,保存版本号
|
||||||
|
localStorage.setItem('app_version', currentVersion);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// 版本检查失败不影响页面加载
|
||||||
|
console.warn('Version check failed:', e);
|
||||||
|
}
|
||||||
|
})();
|
||||||
</script>
|
</script>
|
||||||
<title></title>
|
<title></title>
|
||||||
<!--preload-links-->
|
<!--preload-links-->
|
||||||
|
|||||||
@ -22,8 +22,8 @@
|
|||||||
"build:app-android": "uni build -p app-android",
|
"build:app-android": "uni build -p app-android",
|
||||||
"build:app-ios": "uni build -p app-ios",
|
"build:app-ios": "uni build -p app-ios",
|
||||||
"build:custom": "uni build -p",
|
"build:custom": "uni build -p",
|
||||||
"build:h5": "uni build",
|
"build:h5": "node scripts/update-version.js && uni build",
|
||||||
"build:h5:ssr": "uni build --ssr",
|
"build:h5:ssr": "node scripts/update-version.js && uni build --ssr",
|
||||||
"build:mp-alipay": "uni build -p mp-alipay",
|
"build:mp-alipay": "uni build -p mp-alipay",
|
||||||
"build:mp-baidu": "uni build -p mp-baidu",
|
"build:mp-baidu": "uni build -p mp-baidu",
|
||||||
"build:mp-kuaishou": "uni build -p mp-kuaishou",
|
"build:mp-kuaishou": "uni build -p mp-kuaishou",
|
||||||
|
|||||||
47
scripts/update-version.js
Normal file
47
scripts/update-version.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
// 生成版本号(格式:YYYYMMDD-HHmmss)
|
||||||
|
function generateVersion() {
|
||||||
|
const now = new Date();
|
||||||
|
const year = now.getFullYear();
|
||||||
|
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||||||
|
const day = String(now.getDate()).padStart(2, '0');
|
||||||
|
const hours = String(now.getHours()).padStart(2, '0');
|
||||||
|
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||||||
|
const seconds = String(now.getSeconds()).padStart(2, '0');
|
||||||
|
return `${year}${month}${day}-${hours}${minutes}${seconds}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新 index.html 中的版本号
|
||||||
|
function updateVersion() {
|
||||||
|
const htmlPath = path.join(__dirname, '../index.html');
|
||||||
|
|
||||||
|
if (!fs.existsSync(htmlPath)) {
|
||||||
|
console.error('❌ index.html 文件不存在:', htmlPath);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let html = fs.readFileSync(htmlPath, 'utf8');
|
||||||
|
const version = generateVersion();
|
||||||
|
|
||||||
|
// 替换版本号
|
||||||
|
if (html.includes('<meta name="version"')) {
|
||||||
|
html = html.replace(
|
||||||
|
/<meta name="version" content="[^"]*">/,
|
||||||
|
`<meta name="version" content="${version}">`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// 如果不存在版本号 meta 标签,在 charset 后面添加
|
||||||
|
html = html.replace(
|
||||||
|
/<meta charset="UTF-8"\/>/,
|
||||||
|
`<meta charset="UTF-8"/>\n <!-- 版本号:每次发布时自动更新 -->\n <meta name="version" content="${version}">`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFileSync(htmlPath, html, 'utf8');
|
||||||
|
console.log(`✅ 版本号已更新为: ${version}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateVersion();
|
||||||
|
|
||||||
76
src/api/base/wjApi.ts
Normal file
76
src/api/base/wjApi.ts
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
import { get, post } from "@/utils/request";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 问卷相关API
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID获取问卷详情(包含验证权限)
|
||||||
|
*/
|
||||||
|
export const questionnaireFindByIdApi = async (params: { id: string }) => {
|
||||||
|
return await get(`/api/questionnaire/findById?id=${params.id}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证问卷填写权限
|
||||||
|
*/
|
||||||
|
export const questionnaireCheckPermissionApi = async (params: { questionnaireId: string }) => {
|
||||||
|
return await post("/api/questionnaire/checkPermission", params);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取问卷列表(分页)
|
||||||
|
*/
|
||||||
|
export const questionnaireFindPageApi = async (params: any) => {
|
||||||
|
return await get("/api/questionnaire/findPage", params);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取问卷题目列表
|
||||||
|
*/
|
||||||
|
export const questionnaireQuestionFindPageApi = async (params: any) => {
|
||||||
|
return await get("/api/questionnaireQuestion/findPage", params);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存问卷答案
|
||||||
|
*/
|
||||||
|
export const questionnaireAnswerSaveApi = async (params: any) => {
|
||||||
|
return await post("/api/questionnaireAnswer/save", params);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询用户是否已填写问卷
|
||||||
|
*/
|
||||||
|
export const questionnaireAnswerFindByUserApi = async (params: { questionnaireId: string }) => {
|
||||||
|
return await get("/api/questionnaireAnswer/findByUser", params);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取问卷填写人列表(分页)
|
||||||
|
*/
|
||||||
|
export const questionnaireAnswerFindPageApi = async (params: any) => {
|
||||||
|
return await get("/api/questionnaireAnswer/findPage", params);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据问卷ID获取填写人列表(按问卷ID和提交用户ID分组)
|
||||||
|
*/
|
||||||
|
export const questionnaireAnswerFindUserListApi = async (params: { questionnaireId: string }) => {
|
||||||
|
return await get("/api/questionnaireAnswer/findUserListByQuestionnaireId", params);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据问卷ID和用户ID获取问卷填写详情
|
||||||
|
*/
|
||||||
|
export const questionnaireAnswerFindDetailApi = async (params: { questionnaireId: string, userId?: string, answerId?: string }) => {
|
||||||
|
return await get("/api/questionnaireAnswer/findDetail", params);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用AI分析问卷内容
|
||||||
|
*/
|
||||||
|
export const questionnaireAnalyzeWithAIApi = async (params: any) => {
|
||||||
|
return await post("/api/questionnaireAnswer/analyzeWithAI", params);
|
||||||
|
};
|
||||||
|
|
||||||
1285
src/components/ImageVideoUpload/ImageVideoUpload.vue
Normal file
1285
src/components/ImageVideoUpload/ImageVideoUpload.vue
Normal file
File diff suppressed because it is too large
Load Diff
7
src/components/ImageVideoUpload/index.ts
Normal file
7
src/components/ImageVideoUpload/index.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// 导出组件和类型
|
||||||
|
export { default as ImageVideoUpload } from './ImageVideoUpload.vue'
|
||||||
|
export * from './types'
|
||||||
|
|
||||||
|
// 默认导出
|
||||||
|
export { default } from './ImageVideoUpload.vue'
|
||||||
|
|
||||||
156
src/components/ImageVideoUpload/types.ts
Normal file
156
src/components/ImageVideoUpload/types.ts
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
// 图片项接口
|
||||||
|
export interface ImageItem {
|
||||||
|
tempPath?: string // 临时路径(用于预览)
|
||||||
|
url?: string // 服务器路径(上传成功后)
|
||||||
|
name?: string // 文件名(临时文件名或服务器文件名)
|
||||||
|
originalName?: string // 原始文件名(用户选择的真实文件名)
|
||||||
|
originalPath?: string // 原始路径(用于调试)
|
||||||
|
isCompressed?: boolean // 是否已压缩
|
||||||
|
}
|
||||||
|
|
||||||
|
// 视频项接口
|
||||||
|
export interface VideoItem {
|
||||||
|
tempPath?: string // 临时路径(用于预览)
|
||||||
|
url?: string // 服务器路径(上传成功后)
|
||||||
|
name?: string // 文件名(临时文件名或服务器文件名)
|
||||||
|
originalName?: string // 原始文件名(用户选择的真实文件名)
|
||||||
|
duration?: number // 视频时长(秒)
|
||||||
|
size?: number // 文件大小(字节)
|
||||||
|
thumbnail?: string // 缩略图路径
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文件项接口
|
||||||
|
export interface FileItem {
|
||||||
|
tempPath?: string // 临时路径(用于预览)
|
||||||
|
url?: string // 服务器路径(上传成功后)
|
||||||
|
name?: string // 文件名(临时文件名或服务器文件名)
|
||||||
|
originalName?: string // 原始文件名(用户选择的真实文件名)
|
||||||
|
type?: string // 文件类型(image/video/audio/document等)
|
||||||
|
size?: number // 文件大小(字节)
|
||||||
|
extension?: string // 文件扩展名
|
||||||
|
mimeType?: string // MIME类型
|
||||||
|
}
|
||||||
|
|
||||||
|
// 压缩配置接口
|
||||||
|
export interface CompressConfig {
|
||||||
|
image: {
|
||||||
|
quality: number // 压缩质量 (1-100)
|
||||||
|
maxWidth: number // 最大宽度
|
||||||
|
maxHeight: number // 最大高度
|
||||||
|
maxSize: number // 最大文件大小(字节)
|
||||||
|
minQuality: number // 最低压缩质量
|
||||||
|
}
|
||||||
|
video: {
|
||||||
|
maxDuration: number // 最大时长(秒)
|
||||||
|
maxSize: number // 最大文件大小(字节)
|
||||||
|
quality: string // 视频质量
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 组件Props接口
|
||||||
|
export interface ImageVideoUploadProps {
|
||||||
|
// 图片相关
|
||||||
|
enableImage?: boolean
|
||||||
|
maxImageCount?: number
|
||||||
|
imageList?: ImageItem[]
|
||||||
|
|
||||||
|
// 视频相关
|
||||||
|
enableVideo?: boolean
|
||||||
|
maxVideoCount?: number
|
||||||
|
videoList?: VideoItem[]
|
||||||
|
|
||||||
|
// 文件相关
|
||||||
|
enableFile?: boolean
|
||||||
|
maxFileCount?: number
|
||||||
|
fileList?: FileItem[]
|
||||||
|
allowedFileTypes?: string[] // 允许的文件类型,如 ['pdf', 'doc', 'docx', 'mp3', 'wav']
|
||||||
|
|
||||||
|
// 压缩配置
|
||||||
|
compressConfig?: CompressConfig
|
||||||
|
|
||||||
|
// 上传配置
|
||||||
|
autoUpload?: boolean
|
||||||
|
uploadApi?: (file: any) => Promise<any>
|
||||||
|
}
|
||||||
|
|
||||||
|
// 组件Emits接口
|
||||||
|
export interface ImageVideoUploadEmits {
|
||||||
|
'update:imageList': [images: ImageItem[]]
|
||||||
|
'update:videoList': [videos: VideoItem[]]
|
||||||
|
'update:fileList': [files: FileItem[]]
|
||||||
|
'image-upload-success': [image: ImageItem, index: number]
|
||||||
|
'image-upload-error': [error: any, index: number]
|
||||||
|
'video-upload-success': [video: VideoItem, index: number]
|
||||||
|
'video-upload-error': [error: any, index: number]
|
||||||
|
'file-upload-success': [file: FileItem, index: number]
|
||||||
|
'file-upload-error': [error: any, index: number]
|
||||||
|
'upload-progress': [type: 'image' | 'video' | 'file', current: number, total: number]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 默认压缩配置
|
||||||
|
export const DEFAULT_COMPRESS_CONFIG: CompressConfig = {
|
||||||
|
image: {
|
||||||
|
quality: 60,
|
||||||
|
maxWidth: 1280,
|
||||||
|
maxHeight: 720,
|
||||||
|
maxSize: 200 * 1024, // 200KB
|
||||||
|
minQuality: 20
|
||||||
|
},
|
||||||
|
video: {
|
||||||
|
maxDuration: 60,
|
||||||
|
maxSize: 10 * 1024 * 1024, // 10MB
|
||||||
|
quality: 'medium'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 预设压缩配置
|
||||||
|
export const COMPRESS_PRESETS = {
|
||||||
|
// 高质量配置
|
||||||
|
high: {
|
||||||
|
image: {
|
||||||
|
quality: 80,
|
||||||
|
maxWidth: 1920,
|
||||||
|
maxHeight: 1080,
|
||||||
|
maxSize: 500 * 1024, // 500KB
|
||||||
|
minQuality: 40
|
||||||
|
},
|
||||||
|
video: {
|
||||||
|
maxDuration: 60,
|
||||||
|
maxSize: 20 * 1024 * 1024, // 20MB
|
||||||
|
quality: 'high'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 平衡配置
|
||||||
|
medium: {
|
||||||
|
image: {
|
||||||
|
quality: 60,
|
||||||
|
maxWidth: 1280,
|
||||||
|
maxHeight: 720,
|
||||||
|
maxSize: 200 * 1024, // 200KB
|
||||||
|
minQuality: 20
|
||||||
|
},
|
||||||
|
video: {
|
||||||
|
maxDuration: 60,
|
||||||
|
maxSize: 10 * 1024 * 1024, // 10MB
|
||||||
|
quality: 'medium'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 高压缩配置
|
||||||
|
low: {
|
||||||
|
image: {
|
||||||
|
quality: 40,
|
||||||
|
maxWidth: 960,
|
||||||
|
maxHeight: 540,
|
||||||
|
maxSize: 100 * 1024, // 100KB
|
||||||
|
minQuality: 15
|
||||||
|
},
|
||||||
|
video: {
|
||||||
|
maxDuration: 30,
|
||||||
|
maxSize: 5 * 1024 * 1024, // 5MB
|
||||||
|
quality: 'low'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -150,7 +150,13 @@
|
|||||||
"enablePullDownRefresh": false
|
"enablePullDownRefresh": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/base/wj/indexwb",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "家长问卷",
|
||||||
|
"enablePullDownRefresh": false
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/base/xk/index",
|
"path": "pages/base/xk/index",
|
||||||
"style": {
|
"style": {
|
||||||
|
|||||||
1761
src/pages/base/wj/indexwb.vue
Normal file
1761
src/pages/base/wj/indexwb.vue
Normal file
File diff suppressed because it is too large
Load Diff
49
src/utils/filePreview.ts
Normal file
49
src/utils/filePreview.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// 文件预览工具函数
|
||||||
|
export const previewFile = (fileUrl: string, fileName: string, fileType: string) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const type = fileType.toLowerCase();
|
||||||
|
|
||||||
|
// 检查是否是压缩包文件,如果是则直接下载
|
||||||
|
if (['zip', 'rar', '7z', 'tar', 'gz'].includes(type)) {
|
||||||
|
uni.showToast({ title: '压缩包文件不支持预览,将为您下载', icon: 'none' });
|
||||||
|
downloadFile(fileUrl, fileName).then(resolve).catch(resolve);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 kkview 预览
|
||||||
|
const previewUrl = fileUrl;
|
||||||
|
const needLandscape = ['ppt', 'pptx'].includes(type);
|
||||||
|
|
||||||
|
// 打开预览页面
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/base/view/index?url=${encodeURIComponent(previewUrl)}&name=${encodeURIComponent(fileName)}&landscape=${needLandscape}`,
|
||||||
|
success: resolve,
|
||||||
|
fail: reject
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 下载文件
|
||||||
|
const downloadFile = (fileUrl: string, fileName: string) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
uni.downloadFile({
|
||||||
|
url: fileUrl,
|
||||||
|
success: (res) => {
|
||||||
|
if (res.statusCode === 200) {
|
||||||
|
uni.saveFile({
|
||||||
|
tempFilePath: res.tempFilePath,
|
||||||
|
success: (saveRes) => {
|
||||||
|
uni.showToast({ title: '文件已保存', icon: 'success' });
|
||||||
|
resolve(saveRes);
|
||||||
|
},
|
||||||
|
fail: reject
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
reject(new Error('下载失败'));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: reject
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
@ -17,6 +17,18 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
port: 5139,
|
port: 5139,
|
||||||
},
|
},
|
||||||
|
build: {
|
||||||
|
// 确保文件名包含 hash,便于缓存失效控制
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
entryFileNames: `assets/[name]-[hash].js`,
|
||||||
|
chunkFileNames: `assets/[name]-[hash].js`,
|
||||||
|
assetFileNames: `assets/[name]-[hash].[ext]`,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 生成 manifest 方便版本追踪
|
||||||
|
manifest: true,
|
||||||
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
//c 为class 例如 class="wi-10"
|
//c 为class 例如 class="wi-10"
|
||||||
//w 为样式style 例如 width:10rpx
|
//w 为样式style 例如 width:10rpx
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user