生日调整

This commit is contained in:
hebo 2025-12-24 19:45:48 +08:00
parent c79e037aab
commit 96d1d38a8b
11 changed files with 3437 additions and 5 deletions

View File

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

View File

@ -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
View 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
View 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);
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
// 导出组件和类型
export { default as ImageVideoUpload } from './ImageVideoUpload.vue'
export * from './types'
// 默认导出
export { default } from './ImageVideoUpload.vue'

View 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'
}
}
}

View File

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

File diff suppressed because it is too large Load Diff

49
src/utils/filePreview.ts Normal file
View 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
});
});
};

View File

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