| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915 |
- // 移动端统一请求工具 - 与mobile工程保持一致
- import {
- generateAesKey,
- encryptBase64,
- decryptBase64,
- encryptWithAes,
- decryptWithAes,
- encrypt,
- decrypt,
- } from './crypto.js';
- import { ENCRYPT_CONFIG, REQUEST_CONFIG } from './config.js';
- import { sessionCache, userStorage } from './storage.js';
- /**
- * 获取token
- */
- function getToken() {
- try {
- const token = uni.getStorageSync('access_token');
- console.log(
- '🔍 获取Token:',
- token ? `Bearer ${token.substring(0, 20)}...` : '❌ Token为空',
- );
- return token ? `Bearer ${token}` : '';
- } catch (e) {
- console.error('❌ 获取Token失败:', e);
- return '';
- }
- }
- /**
- * 处理401未授权响应
- */
- function handleUnauthorized(message = '登录已失效,请重新登录') {
- console.log('🔒 处理401未授权响应:', message);
- // 获取当前页面路径
- const pages = getCurrentPages();
- const currentPage = pages[pages.length - 1];
- const currentPath = '/' + currentPage.route;
- // 如果是新生报名页面,不跳转到登录页,只是静默处理
- if (currentPath === '/pages/enrollment/index') {
- console.log('📋 新生报名页面401错误,使用兜底数据,不跳转登录页');
- return;
- }
- // 清除登录信息
- try {
- uni.removeStorageSync('access_token');
- uni.removeStorageSync('userInfo');
- uni.removeStorageSync('isLoggedIn');
- console.log('📤 已清除本地登录信息');
- } catch (e) {
- console.error('❌ 清除登录信息失败:', e);
- }
- // 显示提示信息
- uni.showToast({
- title: message,
- icon: 'none',
- duration: 2000,
- });
- // 延迟跳转,确保Toast显示
- setTimeout(() => {
- // 如果当前不是登录页,则跳转到登录页
- if (currentPath !== '/pages/login/index') {
- console.log('🔄 从', currentPath, '跳转到登录页');
- uni.reLaunch({
- url: '/pages/login/index',
- fail: (error) => {
- console.error('❌ 跳转登录页失败:', error);
- // 如果reLaunch失败,尝试其他方式
- uni.redirectTo({
- url: '/pages/login/index',
- });
- },
- });
- }
- }, 500);
- }
- /**
- * 统一请求方法
- */
- export const request = (options) => {
- return new Promise((resolve, reject) => {
- // 获取token
- const token = getToken();
- // 处理GET请求的params参数
- let url = REQUEST_CONFIG.baseURL + options.url;
- if (options.params && Object.keys(options.params).length > 0) {
- // 将params对象转换为查询字符串
- const queryString = Object.keys(options.params)
- .filter((key) => options.params[key] !== undefined && options.params[key] !== null)
- .map(
- (key) =>
- `${encodeURIComponent(key)}=${encodeURIComponent(options.params[key])}`,
- )
- .join('&');
- if (queryString) {
- url += (url.indexOf('?') > -1 ? '&' : '?') + queryString;
- }
- console.log('🔍 处理GET请求params:', {
- 原始params: options.params,
- 查询字符串: queryString,
- 最终URL: url,
- });
- }
- // 处理请求配置
- const config = {
- url: url,
- method: options.method || 'GET',
- data: options.data || {},
- timeout: options.timeout || REQUEST_CONFIG.timeout,
- responseType: options.responseType || 'text', // 支持responseType参数
- header: {
- // 吴自龙 注释 get方法,后台不接受json 20250811
- // 'Content-Type': 'application/json',
- authorization: token,
- clientid: options.clientId || REQUEST_CONFIG.clientId,
- // 注意:在H5环境中,浏览器会自动设置referer,手动设置会报错
- // referer: options.referer || REQUEST_CONFIG.referer,
- ...options.header,
- },
- };
- // 检查特殊header配置
- const isToken = options.header?.isToken === false;
- const isRepeatSubmit = options.header?.repeatSubmit === false;
- const isEncrypt = options.header?.isEncrypt === 'true';
- // 如果不需要token,移除authorization
- if (isToken) {
- delete config.header.authorization;
- }
- // 防重复提交检查
- if (!isRepeatSubmit && (config.method === 'POST' || config.method === 'PUT')) {
- const requestObj = {
- url: config.url,
- data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
- time: new Date().getTime(),
- };
- const sessionObj = sessionCache.get('sessionObj');
- if (sessionObj) {
- const s_url = sessionObj.url;
- const s_data = sessionObj.data;
- const s_time = sessionObj.time;
- const interval = REQUEST_CONFIG.repeatSubmitInterval;
- if (
- s_data === requestObj.data &&
- requestObj.time - s_time < interval &&
- s_url === requestObj.url
- ) {
- const message = '数据正在处理,请勿重复提交';
- console.warn(`[${s_url}]: ` + message);
- uni.showToast({
- title: message,
- icon: 'none',
- });
- return reject(new Error(message));
- }
- }
- sessionCache.set('sessionObj', requestObj);
- }
- // 加密处理
- if (
- REQUEST_CONFIG.encryptEnabled &&
- isEncrypt &&
- (config.method === 'POST' || config.method === 'PUT')
- ) {
- try {
- console.log('🔐 开始请求加密处理...');
- // 生成AES密钥
- const aesKey = generateAesKey();
- // 使用RSA加密AES密钥
- const encryptedKey = encrypt(encryptBase64(aesKey));
- if (!encryptedKey) {
- throw new Error('RSA加密AES密钥失败');
- }
- // 设置加密头
- config.header[ENCRYPT_CONFIG.ENCRYPT_HEADER] = encryptedKey;
- // 加密请求数据
- const dataToEncrypt =
- typeof config.data === 'object' ? JSON.stringify(config.data) : config.data;
- config.data = encryptWithAes(dataToEncrypt, aesKey);
- console.log('✅ 请求数据加密完成');
- } catch (error) {
- console.error('❌ 请求加密失败:', error);
- uni.showToast({
- title: '请求加密失败',
- icon: 'none',
- });
- return reject(error);
- }
- }
- // FormData处理
- if (config.data instanceof globalThis.FormData) {
- delete config.header['Content-Type'];
- }
- console.log('📤 发送请求:', {
- url: config.url,
- method: config.method,
- hasToken: !!token,
- isEncrypt: isEncrypt,
- });
- // 发送请求
- uni.request({
- ...config,
- success: (res) => {
- console.log('📥 收到响应:', {
- statusCode: res.statusCode,
- url: config.url,
- hasEncryptHeader: !!res.header[ENCRYPT_CONFIG.ENCRYPT_HEADER],
- });
- // 解密处理 - 只对JSON响应进行解密
- if (
- REQUEST_CONFIG.encryptEnabled &&
- res.header[ENCRYPT_CONFIG.ENCRYPT_HEADER] &&
- config.responseType === 'text'
- ) {
- try {
- console.log('🔓 开始响应解密处理...');
- // 获取加密的AES密钥
- const keyStr = res.header[ENCRYPT_CONFIG.ENCRYPT_HEADER];
- // RSA解密获取AES密钥
- const base64Str = decrypt(keyStr);
- if (!base64Str) {
- throw new Error('RSA解密AES密钥失败');
- }
- // Base64解码获取AES密钥
- const aesKey = decryptBase64(base64Str);
- // AES解密响应数据
- const decryptedData = decryptWithAes(res.data, aesKey);
- // 解析JSON
- res.data = JSON.parse(decryptedData);
- console.log('✅ 响应数据解密完成');
- } catch (error) {
- console.error('❌ 响应解密失败:', error);
- uni.showToast({
- title: '响应解密失败',
- icon: 'none',
- });
- return reject(error);
- }
- }
- // 处理响应
- if (res.statusCode === 200) {
- // 对于arraybuffer类型的响应,直接返回数据
- if (config.responseType === 'arraybuffer') {
- resolve(res.data);
- return;
- }
- // 检查业务状态码
- if (res.data && res.data.code !== undefined) {
- if (res.data.code === 200) {
- resolve(res.data);
- } else if (res.data.code === 401) {
- // 401未授权,跳转到登录页
- console.log('🔒 Token失效,自动跳转到登录页');
- handleUnauthorized(res.data.msg || '登录已失效,请重新登录');
- reject(res.data);
- } else {
- // 其他业务错误
- const errorMsg = res.data.msg || '请求失败';
- if (res.data.code !== 404) {
- // 404错误静默处理
- uni.showToast({
- title: errorMsg,
- icon: 'none',
- });
- }
- reject(res.data);
- }
- } else {
- resolve(res.data);
- }
- } else if (res.statusCode === 401) {
- // HTTP 401未授权
- console.log('🔒 HTTP 401未授权,自动跳转到登录页');
- handleUnauthorized('登录已失效,请重新登录');
- reject(res);
- } else if (res.statusCode === 404) {
- // 404错误静默处理
- console.log('404错误被静默处理,不显示用户提示');
- reject(res);
- } else {
- // 其他HTTP状态码错误
- const errorMsg = `请求失败: ${res.statusCode}`;
- uni.showToast({
- title: errorMsg,
- icon: 'none',
- });
- reject(res);
- }
- },
- fail: (error) => {
- console.error('❌ 网络请求失败:', error);
- let message = '网络请求失败';
- if (error.errMsg) {
- if (error.errMsg.includes('timeout')) {
- message = '请求超时,请检查网络连接';
- } else if (error.errMsg.includes('fail')) {
- message = '网络连接失败,请检查网络';
- }
- }
- uni.showToast({
- title: message,
- icon: 'none',
- });
- reject(error);
- },
- });
- });
- };
- // API方法封装
- export const api = {
- // 用户登录 - 使用统一的request方法和加密拦截器
- login: (data) => {
- console.log('🔐 开始登录流程...');
- return request({
- url: '/auth/login',
- method: 'POST',
- data: {
- username: data.username,
- password: data.password,
- tenantId: data.tenantId || '000000',
- clientId: data.clientId || REQUEST_CONFIG.clientId,
- grantType: data.grantType || 'password',
- },
- header: {
- isToken: false, // 登录接口不需要token
- isEncrypt: 'true', // 启用加密
- },
- });
- },
- // 获取用户信息
- getUserInfo: () => {
- const token = getToken();
- console.log(
- '🎫 获取用户信息,当前token:',
- token ? token.substring(0, 20) + '...' : '无token',
- );
- return request({
- url: '/system/user/getInfo',
- method: 'GET',
- });
- },
- // 获取租户列表
- getTenantList: (isToken = false) =>
- request({
- url: '/auth/tenant/list',
- method: 'GET',
- header: {
- isToken: isToken,
- },
- }),
- // 注销登录
- logout: () =>
- request({
- url: '/auth/logout',
- method: 'POST',
- }),
- // 修改密码
- resetPassword: (data) =>
- request({
- url: '/system/user/profile/updatePwd',
- method: 'PUT',
- header: {
- isEncrypt: 'true', // 修复:使用字符串 'true' 而不是布尔值 true
- repeatSubmit: false,
- },
- data: {
- oldPassword: data.oldPassword,
- newPassword: data.newPassword,
- },
- }),
- // 更新用户头像
- // updateUserAvatar: (data) =>
- // request({
- // url: '/system/user/profile/updateAvatar',
- // method: 'PUT',
- // data: {
- // avatar: data.avatar,
- // },
- // }),
- };
- // 便捷请求方法封装
- export const get = (url, data, header) => {
- return request({
- url,
- method: 'GET',
- data,
- header,
- });
- };
- export const post = (url, data, header) => {
- return request({
- url,
- method: 'POST',
- data,
- header,
- });
- };
- export const put = (url, data, header) => {
- return request({
- url,
- method: 'PUT',
- data,
- header,
- });
- };
- export const del = (url, data, header) => {
- return request({
- url,
- method: 'DELETE',
- data,
- header,
- });
- };
- // 文件上传方法
- export const uploadFile = (url, filePath, formData) => {
- return new Promise((resolve, reject) => {
- const token = getToken();
- const clientid = uni.getStorageSync('clientid') || REQUEST_CONFIG.clientId;
- // 构建完整URL - 使用统一配置的服务器地址
- let fullUrl;
- if (REQUEST_CONFIG.baseURL.startsWith('/')) {
- // 开发环境,baseURL是'/api',需要使用完整的服务器URL
- fullUrl = `${REQUEST_CONFIG.devServerUrl}${REQUEST_CONFIG.baseURL}${url}`;
- } else {
- // 生产环境,直接拼接
- fullUrl = REQUEST_CONFIG.baseURL + url;
- }
- console.log('🚀 上传文件URL:', fullUrl);
- console.log('🗂️ 文件路径:', filePath);
- console.log('📊 表单数据:', formData);
- const headers = {
- // 移除Content-Type设置,让uni.uploadFile自动处理
- authorization: token,
- clientid: clientid,
- };
- uni.uploadFile({
- url: fullUrl,
- filePath,
- name: 'file',
- formData,
- header: headers,
- success: (res) => {
- console.log('✅ 上传成功响应:', res);
- try {
- const data = JSON.parse(res.data);
- resolve(data);
- } catch (error) {
- console.error('❌ 解析响应数据失败:', error);
- reject(new Error('解析响应数据失败'));
- }
- },
- fail: (err) => {
- console.error('❌ 上传失败:', err);
- reject(new Error(err.errMsg || '上传失败'));
- },
- });
- });
- };
- // 文件下载方法(支持多平台)
- export const downloadFile = (url, fileName = null) => {
- return new Promise((resolve, reject) => {
- const token = getToken();
- const clientid = uni.getStorageSync('clientid') || REQUEST_CONFIG.clientId;
- console.log('REQUEST_CONFIG.baseURL:', REQUEST_CONFIG.baseURL);
- // 构建完整URL - 使用统一配置的服务器地址
- let fullUrl;
- if (REQUEST_CONFIG.baseURL.startsWith('/')) {
- // 开发环境,baseURL是'/api',需要使用完整的服务器URL
- fullUrl = `${REQUEST_CONFIG.devServerUrl}${REQUEST_CONFIG.baseURL}${url}`;
- } else {
- // 生产环境,直接拼接
- fullUrl = REQUEST_CONFIG.baseURL + url;
- }
- console.log('📥 下载文件URL:', fullUrl);
- const headers = {
- authorization: token,
- clientid: clientid,
- };
- // #ifdef H5
- // H5端使用fetch + blob的方式实现浏览器下载
- console.log('🌐 H5端下载处理');
- fetch(fullUrl, {
- method: 'GET',
- headers: headers,
- })
- .then((response) => {
- if (!response.ok) {
- throw new Error(`HTTP error! status: ${response.status}`);
- }
- return response.blob();
- })
- .then((blob) => {
- // 创建下载链接
- const downloadUrl = window.URL.createObjectURL(blob);
- const link = document.createElement('a');
- link.href = downloadUrl;
- // 尝试从响应头获取文件名,或使用传入的文件名
- let downloadFileName = fileName;
- if (!downloadFileName) {
- // 从URL中提取文件名
- const urlParts = url.split('/');
- downloadFileName = urlParts[urlParts.length - 1] || 'download';
- }
- link.download = downloadFileName;
- document.body.appendChild(link);
- link.click();
- document.body.removeChild(link);
- // 清理blob URL
- window.URL.revokeObjectURL(downloadUrl);
- console.log('✅ H5下载触发成功');
- resolve({ statusCode: 200, message: 'H5下载已触发' });
- })
- .catch((error) => {
- console.error('❌ H5下载失败:', error);
- reject(new Error(error.message || 'H5下载失败'));
- });
- // #endif
- // #ifndef H5
- // 非H5端使用uni.downloadFile
- uni.downloadFile({
- url: fullUrl,
- header: headers,
- success: (res) => {
- console.log('✅ 下载成功:', res);
- resolve(res);
- },
- fail: (err) => {
- console.error('❌ 下载失败:', err);
- reject(new Error(err.errMsg || '下载失败'));
- },
- });
- // #endif
- });
- };
- // 通用下载方法
- export const download = (url, params, fileName) => {
- // 显示加载提示
- uni.showLoading({
- title: '正在下载数据,请稍候',
- mask: true,
- });
- return request({
- url: url,
- method: 'POST',
- data: params,
- header: {
- 'Content-Type': 'application/x-www-form-urlencoded',
- },
- timeout: 1200000, // 20分钟超时
- responseType: 'arraybuffer',
- })
- .then((resp) => {
- // 处理下载响应
- console.log('文件下载完成:', fileName);
- uni.hideLoading();
- // 这里需要根据平台进行不同的文件保存处理
- // 具体实现可能需要平台特定的代码
- return resp;
- })
- .catch((error) => {
- console.error('下载失败:', error);
- uni.hideLoading();
- uni.showToast({
- title: '下载文件出现错误,请联系管理员!',
- icon: 'none',
- });
- throw error;
- });
- };
- // 微信环境专用文件上传方法(解决微信浏览器兼容性问题)
- export const uploadFileForWeChat = (url, file, formData, options = {}) => {
- return new Promise((resolve, reject) => {
- const token = getToken();
- const clientid = uni.getStorageSync('clientid') || REQUEST_CONFIG.clientId;
- console.log('🔧 微信环境专用文件上传...');
- console.log('📁 文件对象:', file);
- console.log('📊 表单数据:', formData);
- // 构建完整URL
- let fullUrl;
- if (REQUEST_CONFIG.baseURL.startsWith('/')) {
- fullUrl = `${REQUEST_CONFIG.devServerUrl}${REQUEST_CONFIG.baseURL}${url}`;
- } else {
- fullUrl = REQUEST_CONFIG.baseURL + url;
- }
- console.log('🚀 上传URL:', fullUrl);
- // 检测是否为blob文件
- if (file._blob || (file.url && file.url.startsWith('blob:'))) {
- console.log('🎨 检测到Blob文件,使用FormData+fetch方案');
- return uploadBlobFileWithFetch(fullUrl, file, formData, token, clientid)
- .then(resolve)
- .catch(reject);
- }
- // 检测文件路径格式并尝试不同的上传策略
- const filePath = file.url || file.tempFilePath || file.path;
- if (!filePath) {
- const error = new Error('文件路径为空,无法上传');
- console.error('❌', error.message);
- return reject(error);
- }
- console.log('📂 使用文件路径上传:', filePath);
- // 策略1: 先尝试标准的uni.uploadFile
- console.log('🔄 策略1: 尝试标准uni.uploadFile');
- uni.uploadFile({
- url: fullUrl,
- filePath: filePath,
- name: 'file',
- formData,
- header: {
- authorization: token,
- clientid: clientid,
- },
- success: (res) => {
- console.log('✅ 标准uni.uploadFile成功:', res);
- try {
- const data = JSON.parse(res.data);
- resolve(data);
- } catch (error) {
- console.error('❌ 解析响应数据失败:', error);
- reject(new Error('解析响应数据失败'));
- }
- },
- fail: (err) => {
- console.log('⚠️ 标准uni.uploadFile失败,尝试备用方案:', err);
- // 策略2: 尝试使用FileReader转换后上传
- if (typeof FileReader !== 'undefined') {
- console.log('🔄 策略2: 尝试FileReader+fetch方案');
- // 通过input[type=file]重新选择文件进行上传
- createFileInputForUpload(fullUrl, formData, token, clientid, file)
- .then(resolve)
- .catch((fetchError) => {
- console.error('❌ FileReader+fetch方案也失败:', fetchError);
- reject(
- new Error(
- `所有上传方案失败: ${err.errMsg || err.message} / ${
- fetchError.message
- }`,
- ),
- );
- });
- } else {
- // 策略3: 提示用户使用系统相册
- console.log('🔄 策略3: 引导用户使用系统相册');
- reject(new Error('当前环境不支持此文件格式,请使用系统相册选择图片'));
- }
- },
- });
- });
- };
- // 使用FormData+fetch上传Blob文件(专门处理Canvas生成的图片)
- function uploadBlobFileWithFetch(url, file, formData, token, clientid) {
- return new Promise((resolve, reject) => {
- try {
- console.log('🎨 开始Blob文件上传流程...');
- const formDataObj = new FormData();
- // 添加基本表单数据
- Object.keys(formData || {}).forEach((key) => {
- formDataObj.append(key, formData[key]);
- });
- // 处理Blob文件
- let blob = file._blob;
- let fileName = file.name || 'upload-image.png';
- let mimeType = file.type || 'image/png';
- if (!blob && file.url && file.url.startsWith('blob:')) {
- // 如果没有直接的blob引用,尝试从blob URL获取
- console.log('🔗 从blob URL获取文件数据...');
- fetch(file.url)
- .then((response) => response.blob())
- .then((fetchedBlob) => {
- formDataObj.append('file', fetchedBlob, fileName);
- return performFetchUpload(url, formDataObj, token, clientid);
- })
- .then(resolve)
- .catch(reject);
- return;
- }
- if (!blob) {
- throw new Error('无法获取Blob数据');
- }
- // 直接添加blob到formData
- console.log('📎 添加Blob到FormData:', {
- fileName,
- mimeType,
- size: blob.size,
- });
- formDataObj.append('file', blob, fileName);
- // 执行fetch上传
- performFetchUpload(url, formDataObj, token, clientid).then(resolve).catch(reject);
- } catch (error) {
- console.error('❌ Blob文件上传准备失败:', error);
- reject(error);
- }
- });
- }
- // 执行fetch上传请求
- function performFetchUpload(url, formData, token, clientid) {
- return fetch(url, {
- method: 'POST',
- headers: {
- authorization: token,
- clientid: clientid,
- // 注意:不要设置Content-Type,让浏览器自动设置multipart/form-data边界
- },
- body: formData,
- })
- .then((response) => {
- console.log('📡 Fetch上传响应状态:', response.status);
- if (!response.ok) {
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
- }
- return response.text();
- })
- .then((responseText) => {
- console.log('📥 Fetch上传响应数据:', responseText);
- try {
- const data = JSON.parse(responseText);
- return data;
- } catch (parseError) {
- console.error('❌ 解析响应JSON失败:', parseError);
- throw new Error('服务器返回数据格式错误');
- }
- });
- }
- // 创建隐藏的file input来重新选择文件(微信环境后备方案)
- function createFileInputForUpload(url, formData, token, clientid, originalFile) {
- return new Promise((resolve, reject) => {
- try {
- console.log('📝 创建隐藏文件选择器...');
- // 在微信环境中提示用户重新选择文件
- uni.showModal({
- title: '文件上传',
- content: '检测到上传兼容性问题,需要重新选择文件。点击确定后请重新选择图片。',
- showCancel: true,
- success: (modalRes) => {
- if (modalRes.confirm) {
- // 重新选择文件
- uni.chooseImage({
- count: 1,
- sourceType: ['album', 'camera'],
- success: (chooseRes) => {
- console.log('🔄 重新选择文件成功:', chooseRes);
- if (chooseRes.tempFilePaths && chooseRes.tempFilePaths.length > 0) {
- const newFilePath = chooseRes.tempFilePaths[0];
- // 使用新选择的文件进行上传
- uni.uploadFile({
- url: url,
- filePath: newFilePath,
- name: 'file',
- formData,
- header: {
- authorization: token,
- clientid: clientid,
- },
- success: (res) => {
- console.log('✅ 重新上传成功:', res);
- try {
- const data = JSON.parse(res.data);
- resolve(data);
- } catch (error) {
- reject(new Error('解析响应数据失败'));
- }
- },
- fail: (err) => {
- console.error('❌ 重新上传失败:', err);
- reject(new Error(err.errMsg || '重新上传失败'));
- },
- });
- } else {
- reject(new Error('未选择任何文件'));
- }
- },
- fail: (err) => {
- console.error('❌ 重新选择文件失败:', err);
- reject(new Error('重新选择文件失败'));
- },
- });
- } else {
- reject(new Error('用户取消了重新选择文件'));
- }
- },
- });
- } catch (error) {
- console.error('❌ 创建文件选择器失败:', error);
- reject(error);
- }
- });
- }
- // 检测是否在微信环境
- export const isWeChat = () => {
- if (typeof navigator === 'undefined') return false;
- return /MicroMessenger/i.test(navigator.userAgent || '');
- };
- // 智能文件上传方法(根据环境自动选择最佳方案)
- export const smartUploadFile = (url, fileOrPath, formData, options = {}) => {
- console.log('🧠 智能文件上传开始...');
- console.log('🌐 当前环境:', {
- isWeChat: isWeChat(),
- userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : 'unknown',
- });
- // 如果在微信环境或遇到特殊文件格式,使用增强版上传
- if (
- isWeChat() ||
- (typeof fileOrPath === 'object' &&
- (fileOrPath._blob || fileOrPath.url?.startsWith('blob:')))
- ) {
- console.log('📱 使用微信环境专用上传方法');
- return uploadFileForWeChat(url, fileOrPath, formData, options);
- }
- // 否则使用标准上传方法
- console.log('💻 使用标准上传方法');
- const filePath =
- typeof fileOrPath === 'string'
- ? fileOrPath
- : fileOrPath.url || fileOrPath.tempFilePath || fileOrPath.path;
- return uploadFile(url, filePath, formData);
- };
|