feat : 一体机定位直到成功,其他环境循环2分钟定位, 上传加入文件校验
This commit is contained in:
12
App.vue
12
App.vue
@@ -24,6 +24,7 @@ onLaunch((options) => {
|
|||||||
getUserInfo();
|
getUserInfo();
|
||||||
useUserStore().changMiniProgramAppStatus(false);
|
useUserStore().changMiniProgramAppStatus(false);
|
||||||
useUserStore().changMachineEnv(false);
|
useUserStore().changMachineEnv(false);
|
||||||
|
useLocationStore().getLocationLoop()//循环获取定位
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isY9MachineType()) {
|
if (isY9MachineType()) {
|
||||||
@@ -32,7 +33,14 @@ onLaunch((options) => {
|
|||||||
useUserStore().logOutApp();
|
useUserStore().logOutApp();
|
||||||
useUserStore().changMiniProgramAppStatus(true);
|
useUserStore().changMiniProgramAppStatus(true);
|
||||||
useUserStore().changMachineEnv(true);
|
useUserStore().changMachineEnv(true);
|
||||||
useLocationStore().getLocation();
|
useLocationStore().getLocation()
|
||||||
|
.then(({longitude,latitude})=>{
|
||||||
|
console.log(`✅一体机获取定位成功:lng:${longitude},lat${latitude}`)
|
||||||
|
})
|
||||||
|
.catch(err=>{
|
||||||
|
console.log('❌一体机获取定位失败,30s后尝试重新获取')
|
||||||
|
useLocationStore().getLocation()
|
||||||
|
})
|
||||||
uQRListen = new IncreaseRevie();
|
uQRListen = new IncreaseRevie();
|
||||||
inactivityManager = new GlobalInactivityManager(handleInactivity, 60 * 1000);
|
inactivityManager = new GlobalInactivityManager(handleInactivity, 60 * 1000);
|
||||||
inactivityManager.start();
|
inactivityManager.start();
|
||||||
@@ -40,6 +48,7 @@ onLaunch((options) => {
|
|||||||
}
|
}
|
||||||
// 正式上线去除此方法
|
// 正式上线去除此方法
|
||||||
console.warn('浏览器环境');
|
console.warn('浏览器环境');
|
||||||
|
useLocationStore().getLocationLoop()//循环获取定位
|
||||||
useUserStore().changMiniProgramAppStatus(true);
|
useUserStore().changMiniProgramAppStatus(true);
|
||||||
useUserStore().changMachineEnv(false);
|
useUserStore().changMachineEnv(false);
|
||||||
useUserStore().initSeesionId(); //更新
|
useUserStore().initSeesionId(); //更新
|
||||||
@@ -57,6 +66,7 @@ onLaunch((options) => {
|
|||||||
|
|
||||||
onMounted(() => {});
|
onMounted(() => {});
|
||||||
|
|
||||||
|
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
console.log('App Show');
|
console.log('App Show');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ const { userInfo } = storeToRefs(useUserStore());
|
|||||||
const { getUserResume } = useUserStore();
|
const { getUserResume } = useUserStore();
|
||||||
const { dictLabel, oneDictData } = useDictStore();
|
const { dictLabel, oneDictData } = useDictStore();
|
||||||
const openSelectPopup = inject('openSelectPopup');
|
const openSelectPopup = inject('openSelectPopup');
|
||||||
|
import {FileValidator} from "@/utils/fileValidator" //文件校验
|
||||||
|
|
||||||
const percent = ref('0%');
|
const percent = ref('0%');
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
@@ -278,7 +279,15 @@ function selectAvatar() {
|
|||||||
sizeType: ['original', 'compressed'],
|
sizeType: ['original', 'compressed'],
|
||||||
sourceType: ['album', 'camera'],
|
sourceType: ['album', 'camera'],
|
||||||
count: 1,
|
count: 1,
|
||||||
success: ({ tempFilePaths, tempFiles }) => {
|
success: async(res) => {
|
||||||
|
const tempFilePaths = res.tempFilePaths;
|
||||||
|
const file = res.tempFiles[0];
|
||||||
|
|
||||||
|
const imageValidator = new FileValidator()
|
||||||
|
|
||||||
|
try {
|
||||||
|
await imageValidator.validate(file)
|
||||||
|
|
||||||
$api.uploadFile(tempFilePaths[0], true)
|
$api.uploadFile(tempFilePaths[0], true)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
res = JSON.parse(res);
|
res = JSON.parse(res);
|
||||||
@@ -287,6 +296,9 @@ function selectAvatar() {
|
|||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
$api.msg('上传失败');
|
$api.msg('上传失败');
|
||||||
});
|
});
|
||||||
|
} catch (error) {
|
||||||
|
$api.msg(error);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
fail: (error) => {},
|
fail: (error) => {},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -281,6 +281,8 @@ const { messages, isTyping, textInput, chatSessionID } = storeToRefs(useChatGrou
|
|||||||
import successIcon from '@/static/icon/success.png';
|
import successIcon from '@/static/icon/success.png';
|
||||||
import useUserStore from '@/stores/useUserStore';
|
import useUserStore from '@/stores/useUserStore';
|
||||||
const { isMachineEnv } = storeToRefs(useUserStore());
|
const { isMachineEnv } = storeToRefs(useUserStore());
|
||||||
|
|
||||||
|
import {FileValidator} from "@/utils/fileValidator" //文件校验
|
||||||
// hook
|
// hook
|
||||||
// 语音识别
|
// 语音识别
|
||||||
const {
|
const {
|
||||||
@@ -536,10 +538,14 @@ function uploadCamera(type = 'camera') {
|
|||||||
count: 1, //默认9
|
count: 1, //默认9
|
||||||
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
|
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
|
||||||
sourceType: [type], //从相册选择
|
sourceType: [type], //从相册选择
|
||||||
success: function (res) {
|
success: async (res)=> {
|
||||||
const tempFilePaths = res.tempFilePaths;
|
const tempFilePaths = res.tempFilePaths;
|
||||||
const file = res.tempFiles[0];
|
const file = res.tempFiles[0];
|
||||||
// 继续上传
|
|
||||||
|
const imageValidator = new FileValidator()
|
||||||
|
try {
|
||||||
|
await imageValidator.validate(file)
|
||||||
|
|
||||||
$api.uploadFile(tempFilePaths[0], true).then((resData) => {
|
$api.uploadFile(tempFilePaths[0], true).then((resData) => {
|
||||||
resData = JSON.parse(resData);
|
resData = JSON.parse(resData);
|
||||||
console.log(file.type,'++')
|
console.log(file.type,'++')
|
||||||
@@ -552,6 +558,9 @@ function uploadCamera(type = 'camera') {
|
|||||||
textInput.value = state.uploadFileTips;
|
textInput.value = state.uploadFileTips;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} catch (error) {
|
||||||
|
$api.msg(error)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -560,15 +569,17 @@ function getUploadFile(type = 'camera') {
|
|||||||
if (VerifyNumberFiles()) return;
|
if (VerifyNumberFiles()) return;
|
||||||
uni.chooseFile({
|
uni.chooseFile({
|
||||||
count: 1,
|
count: 1,
|
||||||
success: (res) => {
|
success: async(res) => {
|
||||||
const tempFilePaths = res.tempFilePaths;
|
const tempFilePaths = res.tempFilePaths;
|
||||||
const file = res.tempFiles[0];
|
const file = res.tempFiles[0];
|
||||||
const allowedTypes = config.allowedFileTypes || [];
|
const allowedTypes = config.allowedFileTypes || [];
|
||||||
const size = $api.formatFileSize(file.size);
|
const size = $api.formatFileSize(file.size);
|
||||||
if (!allowedTypes.includes(file.type)) {
|
|
||||||
return $api.msg('仅支持 txt md word pdf ppt csv excel 格式类型');
|
const imageValidator = new FileValidator({allowedExtensions:config.allowedFileTypes})
|
||||||
}
|
|
||||||
// 继续上传
|
try{
|
||||||
|
await imageValidator.validate(file)
|
||||||
|
|
||||||
$api.uploadFile(tempFilePaths[0], true).then((resData) => {
|
$api.uploadFile(tempFilePaths[0], true).then((resData) => {
|
||||||
resData = JSON.parse(resData);
|
resData = JSON.parse(resData);
|
||||||
filesList.value.push({
|
filesList.value.push({
|
||||||
@@ -579,6 +590,9 @@ function getUploadFile(type = 'camera') {
|
|||||||
});
|
});
|
||||||
textInput.value = state.uploadFileTips;
|
textInput.value = state.uploadFileTips;
|
||||||
});
|
});
|
||||||
|
}catch(error){
|
||||||
|
$api.msg(error)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -470,7 +470,6 @@ const { columnCount, columnSpace } = useColumnCount(() => {
|
|||||||
getJobRecommend('refresh');
|
getJobRecommend('refresh');
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
waterfallsFlowRef.value?.refresh?.();
|
waterfallsFlowRef.value?.refresh?.();
|
||||||
useLocationStore().getLocation();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -129,7 +129,6 @@ const { columnCount, columnSpace } = useColumnCount(() => {
|
|||||||
pageSize.value = 10 * (columnCount.value - 1);
|
pageSize.value = 10 * (columnCount.value - 1);
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
waterfallsFlowRef.value?.refresh?.();
|
waterfallsFlowRef.value?.refresh?.();
|
||||||
useLocationStore().getLocation();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -151,7 +151,6 @@ const { columnCount, columnSpace } = useColumnCount(() => {
|
|||||||
pageSize.value = 10 * (columnCount.value - 1);
|
pageSize.value = 10 * (columnCount.value - 1);
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
waterfallsFlowRef.value?.refresh?.();
|
waterfallsFlowRef.value?.refresh?.();
|
||||||
useLocationStore().getLocation();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -11,13 +11,15 @@ import config from '../config';
|
|||||||
|
|
||||||
const defalutLongLat = {
|
const defalutLongLat = {
|
||||||
longitude: 120.382665,
|
longitude: 120.382665,
|
||||||
latitude: 36.066938
|
latitude: 36.066938,
|
||||||
}
|
}
|
||||||
|
|
||||||
const useLocationStore = defineStore("location", () => {
|
const useLocationStore = defineStore("location", () => {
|
||||||
// 定义状态
|
// 定义状态
|
||||||
const longitudeVal = ref(null) // 经度
|
const longitudeVal = ref(null) // 经度
|
||||||
const latitudeVal = ref(null) //纬度
|
const latitudeVal = ref(null) //纬度
|
||||||
|
const timer = ref(null)
|
||||||
|
const count = ref(0)
|
||||||
|
|
||||||
function getLocation() { // 获取经纬度两个平台
|
function getLocation() { // 获取经纬度两个平台
|
||||||
return new Promise((resole, reject) => {
|
return new Promise((resole, reject) => {
|
||||||
@@ -66,6 +68,21 @@ const useLocationStore = defineStore("location", () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
function getLocationLoop(gap = 1000 * 60 * 2) {
|
||||||
|
console.log(`🔄开始循环获取定位,间隔:${Math.floor(gap/1000)}秒`)
|
||||||
|
const run = () => {
|
||||||
|
count.value++
|
||||||
|
console.log(`📍第${count.value}次获取定位`)
|
||||||
|
getLocation()
|
||||||
|
}
|
||||||
|
run()
|
||||||
|
timer.value = setInterval(run,gap);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearGetLocationLoop(params) {
|
||||||
|
clearInterval(timer.value)
|
||||||
|
timer.value = null
|
||||||
|
}
|
||||||
|
|
||||||
function longitude() {
|
function longitude() {
|
||||||
return longitudeVal.value
|
return longitudeVal.value
|
||||||
@@ -78,9 +95,10 @@ const useLocationStore = defineStore("location", () => {
|
|||||||
// 导入
|
// 导入
|
||||||
return {
|
return {
|
||||||
getLocation,
|
getLocation,
|
||||||
|
getLocationLoop,
|
||||||
|
clearGetLocationLoop,
|
||||||
longitudeVal,
|
longitudeVal,
|
||||||
latitudeVal
|
latitudeVal,
|
||||||
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
unistorage: true,
|
unistorage: true,
|
||||||
|
|||||||
@@ -42,30 +42,59 @@ export class FileValidator {
|
|||||||
* 构造函数
|
* 构造函数
|
||||||
* @param {Object} options 配置项
|
* @param {Object} options 配置项
|
||||||
* @param {number} [options.maxSizeMB=10] 最大文件大小 (MB)
|
* @param {number} [options.maxSizeMB=10] 最大文件大小 (MB)
|
||||||
* @param {string[]} [options.allowedExtensions] 允许的扩展名列表 (如 ['jpg', 'png']),默认允许全部已知类型
|
* @param {string[]} [options.allowedExtensions = ['png','jpg','jpeg','gif','webp','svg','bmp','ico','pdf','doc','docx','xls','xlsx','csv','ppt','pptx','txt','md']] 允许的扩展名列表 (如 ['jpg', 'png']),默认允许全部已知类型
|
||||||
*/
|
*/
|
||||||
version = '1.0.0';
|
version = '1.0.0';
|
||||||
constructor(options = {}) {
|
constructor(options = {}) {
|
||||||
// 配置大小 (默认 10MB)
|
// 配置大小 (默认 10MB)
|
||||||
this.maxSizeMB = options.maxSizeMB || 10;
|
this.maxSizeMB = options.maxSizeMB || 10;
|
||||||
|
|
||||||
|
// 扩展名到 MIME 的映射(用于反向查找)
|
||||||
|
this.extToMime = {
|
||||||
|
png: 'image/png',
|
||||||
|
jpg: 'image/jpeg',
|
||||||
|
jpeg: 'image/jpeg',
|
||||||
|
gif: 'image/gif',
|
||||||
|
webp: 'image/webp',
|
||||||
|
pdf: 'application/pdf',
|
||||||
|
txt: 'text/plain',
|
||||||
|
md: 'text/markdown',
|
||||||
|
json: 'application/json',
|
||||||
|
csv: 'text/csv',
|
||||||
|
doc: 'application/msword',
|
||||||
|
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||||
|
xls: 'application/vnd.ms-excel',
|
||||||
|
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||||
|
ppt: 'application/vnd.ms-powerpoint',
|
||||||
|
pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||||
|
};
|
||||||
|
|
||||||
|
// 如果传入的是 MIME 类型,转换为扩展名
|
||||||
|
let allowedExtensions = options.allowedExtensions || Object.keys(KNOWN_SIGNATURES);
|
||||||
|
|
||||||
// 配置允许的类型
|
// 配置允许的类型
|
||||||
// 如果传入了 allowedExtensions,则只使用传入的;否则使用全部 KNOWN_SIGNATURES
|
|
||||||
if (options.allowedExtensions && Array.isArray(options.allowedExtensions)) {
|
|
||||||
this.allowedConfig = {};
|
this.allowedConfig = {};
|
||||||
options.allowedExtensions.forEach((ext) => {
|
allowedExtensions.forEach((extOrMime) => {
|
||||||
const key = ext.toLowerCase();
|
const key = extOrMime.toLowerCase();
|
||||||
if (KNOWN_SIGNATURES[key]) {
|
|
||||||
this.allowedConfig[key] = KNOWN_SIGNATURES[key];
|
// 如果是 MIME 类型,尝试转换为扩展名
|
||||||
|
let ext = key;
|
||||||
|
if (key.includes('/')) {
|
||||||
|
// 查找对应的扩展名
|
||||||
|
for (const [e, mime] of Object.entries(this.extToMime)) {
|
||||||
|
if (mime === key) {
|
||||||
|
ext = e;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (KNOWN_SIGNATURES[ext]) {
|
||||||
|
this.allowedConfig[ext] = KNOWN_SIGNATURES[ext];
|
||||||
} else {
|
} else {
|
||||||
console.warn(`[FileValidator] 未知的文件类型: .${key},已忽略`);
|
console.warn(`[FileValidator] 未知的文件类型: ${key},已忽略`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
this.allowedConfig = {
|
|
||||||
...KNOWN_SIGNATURES
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,7 +104,7 @@ export class FileValidator {
|
|||||||
try {
|
try {
|
||||||
// fatal: true 会在遇到无效编码时抛出错误,而不是用 替换
|
// fatal: true 会在遇到无效编码时抛出错误,而不是用 替换
|
||||||
const decoder = new TextDecoder('utf-8', {
|
const decoder = new TextDecoder('utf-8', {
|
||||||
fatal: true
|
fatal: true,
|
||||||
});
|
});
|
||||||
decoder.decode(buffer);
|
decoder.decode(buffer);
|
||||||
return true;
|
return true;
|
||||||
@@ -128,7 +157,6 @@ export class FileValidator {
|
|||||||
return rowCount;
|
return rowCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 【核心】:校验纯文本内容
|
* 【核心】:校验纯文本内容
|
||||||
* 1. 检查是否包含乱码 (非 UTF-8)
|
* 1. 检查是否包含乱码 (非 UTF-8)
|
||||||
@@ -139,7 +167,7 @@ export class FileValidator {
|
|||||||
let contentStr = '';
|
let contentStr = '';
|
||||||
try {
|
try {
|
||||||
const decoder = new TextDecoder('utf-8', {
|
const decoder = new TextDecoder('utf-8', {
|
||||||
fatal: true
|
fatal: true,
|
||||||
});
|
});
|
||||||
contentStr = decoder.decode(buffer);
|
contentStr = decoder.decode(buffer);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -177,6 +205,7 @@ export class FileValidator {
|
|||||||
*/
|
*/
|
||||||
validate(file) {
|
validate(file) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
console.log('开始校验文件');
|
||||||
// 1. 基础对象检查
|
// 1. 基础对象检查
|
||||||
if (!file || !file.name) return reject('无效的文件对象');
|
if (!file || !file.name) return reject('无效的文件对象');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user