sdsd
This commit is contained in:
parent
49c0136bff
commit
8ef6a6693e
56
api/ocr.js
56
api/ocr.js
@ -28,7 +28,7 @@ export const getOcr = (url) => {
|
||||
}]
|
||||
},
|
||||
success(res) {
|
||||
const data = parseMarkdownTable(res.data.choices[0].message.content)
|
||||
const data = parseOcrResult(res.data.choices[0].message.content)
|
||||
resolve(data);
|
||||
},
|
||||
fail(err) {
|
||||
@ -63,3 +63,57 @@ function parseMarkdownTable(md) {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析类似 ```json ... ``` 格式的字符串,提取检测项目数组
|
||||
* @param {string} str
|
||||
* @returns {Array<Object>}
|
||||
*/
|
||||
function parseJsonBlock(str) {
|
||||
// 去除包裹的代码块标记
|
||||
const jsonStr = str.replace(/^[\s`]*```json[\s`]*|```$/g, '').replace(/↵/g, '\n').trim();
|
||||
|
||||
// 用正则提取所有 "key": "value"
|
||||
const regex = /"([^"]+)":\s*"([^"]*)"/g;
|
||||
const pairs = [];
|
||||
let match;
|
||||
while ((match = regex.exec(jsonStr)) !== null) {
|
||||
pairs.push([match[1], match[2]]);
|
||||
}
|
||||
|
||||
// 按“序号”分组
|
||||
const items = [];
|
||||
let current = {};
|
||||
const itemFields = ['序号', '项目名称', '缩写', '结果', '单位', '参考区间', '测定方法'];
|
||||
pairs.forEach(([key, value]) => {
|
||||
if (key === '序号' && Object.keys(current).length > 0) {
|
||||
items.push({ ...current });
|
||||
current = {};
|
||||
}
|
||||
if (itemFields.includes(key)) {
|
||||
current[key] = value;
|
||||
}
|
||||
});
|
||||
if (Object.keys(current).length > 0) {
|
||||
items.push({ ...current });
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动判断OCR返回内容格式并调用对应解析方法
|
||||
* @param {string} content
|
||||
* @returns {Array<Object>}
|
||||
*/
|
||||
function parseOcrResult(content) {
|
||||
// 判断是否为JSON代码块
|
||||
if (/^```json/.test(content.trim())) {
|
||||
return parseJsonBlock(content);
|
||||
}
|
||||
// 判断是否为Markdown表格(以|开头,且有---分隔行)
|
||||
if (/\|.*\|/.test(content) && /\|[\s\-:|]+\|/.test(content)) {
|
||||
return parseMarkdownTable(content);
|
||||
}
|
||||
// 其它情况返回空数组或原始内容
|
||||
return [];
|
||||
}
|
||||
@ -13,7 +13,7 @@ Page({
|
||||
|
||||
form: {
|
||||
follow_name: '',
|
||||
liver_function_image:[],
|
||||
liver_function_image: [],
|
||||
b_mode_image: [],
|
||||
blood_routine_image: [],
|
||||
coagulation_function_image: [],
|
||||
@ -126,7 +126,7 @@ Page({
|
||||
onInput(e) {
|
||||
const { key, tips } = e.currentTarget.dataset;
|
||||
|
||||
if(e.detail.value){
|
||||
if (e.detail.value) {
|
||||
this.setData({
|
||||
[tips]: true,
|
||||
[`form.${key}`]: e.detail.value
|
||||
@ -140,9 +140,9 @@ Page({
|
||||
|
||||
|
||||
},
|
||||
onInputTime(e){
|
||||
onInputTime(e) {
|
||||
const { tips } = e.currentTarget.dataset;
|
||||
if(e.detail.value){
|
||||
if (e.detail.value) {
|
||||
this.setData({
|
||||
[tips]: true,
|
||||
});
|
||||
@ -162,7 +162,7 @@ Page({
|
||||
|
||||
},
|
||||
onPickerChange(e) {
|
||||
if(e.detail.value){
|
||||
if (e.detail.value) {
|
||||
this.setData({
|
||||
isTime: true,
|
||||
['form.follow_date']: e.detail.value
|
||||
@ -193,32 +193,32 @@ Page({
|
||||
console.log(e.detail.file);
|
||||
},
|
||||
|
||||
planId:'',
|
||||
planId: '',
|
||||
questionnaire_id: '',
|
||||
async toQuestionnaire() {
|
||||
let valid = true;
|
||||
// 必填项校验
|
||||
if(!this.data.form.follow_name){
|
||||
if (!this.data.form.follow_name) {
|
||||
this.setData({ isName: false });
|
||||
valid = false;
|
||||
}
|
||||
if(!this.data.form.follow_date){
|
||||
if (!this.data.form.follow_date) {
|
||||
this.setData({ isTime: false });
|
||||
valid = false;
|
||||
}
|
||||
if(!this.data.form.follow_hospital){
|
||||
if (!this.data.form.follow_hospital) {
|
||||
this.setData({ isDoctor: false });
|
||||
valid = false;
|
||||
}
|
||||
if(!this.data.form.height){
|
||||
if (!this.data.form.height) {
|
||||
this.setData({ isHeight: false });
|
||||
valid = false;
|
||||
}
|
||||
if(!this.data.form.weight){
|
||||
if (!this.data.form.weight) {
|
||||
this.setData({ isWeight: false });
|
||||
valid = false;
|
||||
}
|
||||
if(!valid) return
|
||||
if (!valid) return
|
||||
const data = this.data.form
|
||||
data.liver_function_image = data.liver_function_image.length > 0 ? data.liver_function_image.join(',') : ''
|
||||
data.b_mode_image = data.b_mode_image.length > 0 ? data.b_mode_image.join(',') : '',
|
||||
@ -228,7 +228,7 @@ Page({
|
||||
data.nutritional_indicator_image = data.nutritional_indicator_image.length > 0 ? data.nutritional_indicator_image.join(',') : ''
|
||||
data.is_have_cyst = data.is_have_cyst ? Number(data.is_have_cyst) : 0
|
||||
data.is_have_ascites = data.is_have_ascites ? Number(data.is_have_ascites) : 0
|
||||
await request('patient/follow_questionnaire', 'post',{plan_id: Number(this.planId), questionnaire_id: Number(this.questionnaire_id), ...data})
|
||||
await request('patient/follow_questionnaire', 'post', { plan_id: Number(this.planId), questionnaire_id: Number(this.questionnaire_id), ...data })
|
||||
wx.showToast({
|
||||
title: '提交成功',
|
||||
icon: 'success',
|
||||
@ -278,7 +278,7 @@ Page({
|
||||
success(res) {
|
||||
console.log('上传响应:', res);
|
||||
if (res.statusCode === 200) {
|
||||
callback(null, 'https://image-fudan.oss-cn-beijing.aliyuncs.com/upload_file/'+ fileName); // 上传成功
|
||||
callback(null, 'https://image-fudan.oss-cn-beijing.aliyuncs.com/upload_file/' + fileName); // 上传成功
|
||||
} else {
|
||||
console.error('上传失败,状态码:', res.statusCode);
|
||||
console.error('失败响应:', res);
|
||||
@ -295,7 +295,7 @@ Page({
|
||||
},
|
||||
handleUpload(e) {
|
||||
const { mode } = e.currentTarget.dataset;
|
||||
if(this.data.form[mode].length >= 9){
|
||||
if (this.data.form[mode].length >= 9) {
|
||||
wx.showToast({ title: '最多上传9张图片!', icon: 'none' });
|
||||
return
|
||||
}
|
||||
@ -316,14 +316,18 @@ Page({
|
||||
console.error('上传失败:', error); // 输出具体的错误信息
|
||||
} else {
|
||||
// getOcr(data)
|
||||
wx.showToast({ title: '上传成功!', icon: 'success' });
|
||||
wx.showToast({ title: '上传成功,正在识别内容!', icon: 'success' });
|
||||
const { mode } = e.currentTarget.dataset;
|
||||
let arr = this.data.form[mode]
|
||||
arr.unshift(data)
|
||||
this.setData({
|
||||
[`form.${mode}`]: arr
|
||||
})
|
||||
getOcr(data)
|
||||
getOcr(data).then(ocrRes => {
|
||||
console.log(ocrRes)
|
||||
wx.showToast({ title: '识别完成!', icon: 'success' })
|
||||
this.setFormData(ocrRes, mode)
|
||||
})
|
||||
console.log('上传成功:', data); // 输出上传成功后的数据
|
||||
}
|
||||
});
|
||||
@ -338,8 +342,8 @@ Page({
|
||||
});
|
||||
},
|
||||
|
||||
imageKey:'',
|
||||
handleImagePreview(e){
|
||||
imageKey: '',
|
||||
handleImagePreview(e) {
|
||||
const { mode, index } = e.currentTarget.dataset;
|
||||
this.imageKey = mode
|
||||
console.log(this.data.form[mode])
|
||||
@ -349,12 +353,12 @@ Page({
|
||||
imageVisible: true
|
||||
})
|
||||
},
|
||||
onClose(){
|
||||
onClose() {
|
||||
this.setData({
|
||||
imageVisible: false
|
||||
})
|
||||
},
|
||||
handleDelete(e){
|
||||
handleDelete(e) {
|
||||
const { mode, index } = e.currentTarget.dataset;
|
||||
let arr = this.data.form[mode]
|
||||
arr.splice(index, 1)
|
||||
@ -363,7 +367,7 @@ Page({
|
||||
})
|
||||
},
|
||||
|
||||
onDelete(e){
|
||||
onDelete(e) {
|
||||
console.log(e)
|
||||
let arr = this.data.form[this.imageKey]
|
||||
arr.splice(e.detail.index, 1)
|
||||
@ -388,13 +392,13 @@ Page({
|
||||
['form.follow_date']: options.time
|
||||
})
|
||||
console.log(options)
|
||||
if(options.questionnaire_id != 0){
|
||||
if (options.questionnaire_id != 0) {
|
||||
this.getDetail()
|
||||
}
|
||||
},
|
||||
|
||||
async getDetail(){
|
||||
const res = await request('patient/questionnaire_info', 'post',{patient_id : 0, questionnaire_id: Number(this.questionnaire_id)})
|
||||
async getDetail() {
|
||||
const res = await request('patient/questionnaire_info', 'post', { patient_id: 0, questionnaire_id: Number(this.questionnaire_id) })
|
||||
const data = res
|
||||
data.liver_function_image = data.liver_function_image ? data.liver_function_image.split(',') : []
|
||||
data.b_mode_image = data.b_mode_image ? data.b_mode_image.split(',') : []
|
||||
@ -407,6 +411,71 @@ Page({
|
||||
form: data
|
||||
})
|
||||
},
|
||||
|
||||
// 遍历识别结果,填充字段
|
||||
setFormData(ocrs, mode) {
|
||||
console.log(ocrs, mode)
|
||||
ocrs.forEach(ocr => {
|
||||
console.log(ocr['项目名称'], ocr['结果'])
|
||||
// 血常规
|
||||
if (mode == 'blood_routine_image') {
|
||||
if (ocr['项目名称'] == '血红蛋白') {
|
||||
this.setData({
|
||||
[`form.hemoglobin`]: ocr['结果']
|
||||
})
|
||||
}
|
||||
}
|
||||
// 凝血功能
|
||||
if (mode == 'coagulation_function_image') {
|
||||
|
||||
if (ocr['项目名称'] == '凝血酶原时间') {
|
||||
this.setData({
|
||||
[`form.pt`]: ocr['结果']
|
||||
})
|
||||
}
|
||||
if (ocr['项目名称'] == '凝血酶原活动度') {
|
||||
this.setData({
|
||||
[`form.pta`]: ocr['结果']
|
||||
})
|
||||
}
|
||||
if (ocr['项目名称'] == '国际标准化比值') {
|
||||
this.setData({
|
||||
[`form.inr`]: ocr['结果']
|
||||
})
|
||||
}
|
||||
if (ocr['项目名称'] == '活化部分凝血活酶时间') {
|
||||
this.setData({
|
||||
[`form.aptt`]: ocr['结果']
|
||||
})
|
||||
}
|
||||
if (ocr['项目名称'] == '凝血酶时间') {
|
||||
this.setData({
|
||||
[`form.tt`]: ocr['结果']
|
||||
})
|
||||
}
|
||||
if (ocr['项目名称'] == '纤维蛋白原') {
|
||||
this.setData({
|
||||
[`form.fib`]: ocr['结果']
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 肝功能
|
||||
if (mode == 'liver_function_image') {
|
||||
|
||||
}
|
||||
// 营养指数
|
||||
if (mode == 'nutritional_indicator_image') {
|
||||
|
||||
}
|
||||
// B超
|
||||
if (mode == 'b_mode_image') {
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
|
||||
@ -91,7 +91,7 @@
|
||||
<t-col span="12">
|
||||
<view class="dark">
|
||||
<view class="input-example">
|
||||
<view class="input-example__label">总胆红素(µmol/L)</view>
|
||||
<view class="input-example__label">总胆红素(µmol/L)</view>
|
||||
<t-input placeholder="请输入" size="small" bind:change="onInput" value="{{form.total_bilirubin}}" data-key="total_bilirubin" borderless="{{true}}" style="{{style}}"
|
||||
type="digit" />
|
||||
</view>
|
||||
@ -100,7 +100,7 @@
|
||||
<t-col span="12">
|
||||
<view class="dark">
|
||||
<view class="input-example">
|
||||
<view class="input-example__label">直接胆红素(µmol/L)</view>
|
||||
<view class="input-example__label">直接胆红素(µmol/L)</view>
|
||||
<t-input placeholder="请输入" bind:change="onInput" value="{{form.direct_bilirubin}}" data-key="direct_bilirubin" borderless="{{true}}" style="{{style}}"
|
||||
type="digit" />
|
||||
</view>
|
||||
@ -354,7 +354,7 @@
|
||||
<t-col span="12">
|
||||
<view class="dark">
|
||||
<view class="input-example">
|
||||
<view class="input-example__label">25(OH)D3 (ng/ml)</view>
|
||||
<view class="input-example__label">25(OH)D3(ng/ml)</view>
|
||||
<t-input type="digit" placeholder="请输入" bind:change="onInput" value="{{form.oh_d3}}" data-key="oh_d3" size="small" borderless="{{true}}" style="{{style}}" />
|
||||
</view>
|
||||
</view>
|
||||
@ -362,7 +362,7 @@
|
||||
<t-col span="12">
|
||||
<view class="dark">
|
||||
<view class="input-example">
|
||||
<view class="input-example__label">25(OH)D2 (ng/ml)</view>
|
||||
<view class="input-example__label">25(OH)D2(ng/ml)</view>
|
||||
<t-input type="digit" placeholder="请输入" bind:change="onInput" value="{{form.oh_d2}}" data-key="oh_d2" size="small" borderless="{{true}}" style="{{style}}" />
|
||||
</view>
|
||||
</view>
|
||||
@ -370,7 +370,7 @@
|
||||
<t-col span="12">
|
||||
<view class="dark">
|
||||
<view class="input-example">
|
||||
<view class="input-example__label">25(OH)D (ng/ml)</view>
|
||||
<view class="input-example__label">25(OH)D(ng/ml)</view>
|
||||
<t-input type="digit" placeholder="请输入" bind:change="onInput" value="{{form.oh_d}}" data-key="oh_d" size="small" borderless="{{true}}" style="{{style}}" />
|
||||
</view>
|
||||
</view>
|
||||
@ -378,7 +378,7 @@
|
||||
<t-col span="12">
|
||||
<view class="dark">
|
||||
<view class="input-example">
|
||||
<view class="input-example__label">维生素A (ng/ml)</view>
|
||||
<view class="input-example__label">维生素A(ng/ml)</view>
|
||||
<t-input type="digit" placeholder="请输入" bind:change="onInput" value="{{form.vitamin_a}}" data-key="vitamin_a" borderless="{{true}}" style="{{style}}" />
|
||||
</view>
|
||||
</view>
|
||||
@ -386,7 +386,7 @@
|
||||
<t-col span="12">
|
||||
<view class="dark">
|
||||
<view class="input-example">
|
||||
<view class="input-example__label">维生素K (ng/ml)</view>
|
||||
<view class="input-example__label">维生素K(ng/ml)</view>
|
||||
<t-input type="digit" placeholder="请输入" bind:change="onInput" value="{{form.vitamin_k}}" data-key="vitamin_k" borderless="{{true}}" style="{{style}}" />
|
||||
</view>
|
||||
</view>
|
||||
@ -394,7 +394,7 @@
|
||||
<t-col span="12">
|
||||
<view class="dark">
|
||||
<view class="input-example">
|
||||
<view class="input-example__label">维生素E (ng/ml)</view>
|
||||
<view class="input-example__label">维生素E(ng/ml)</view>
|
||||
<t-input type="digit" placeholder="请输入" bind:change="onInput" value="{{form.vitamin_e}}" data-key="vitamin_e" borderless="{{true}}" style="{{style}}" />
|
||||
</view>
|
||||
</view>
|
||||
@ -433,7 +433,7 @@
|
||||
<t-col span="12">
|
||||
<view class="dark">
|
||||
<view class="input-example">
|
||||
<view class="input-example__label">肝肋下(mm)</view>
|
||||
<view class="input-example__label">肝肋下(mm)</view>
|
||||
<t-input type="digit" placeholder="请输入" bind:change="onInput" value="{{form.under_the_liver_rib}}" data-key="under_the_liver_rib" size="small" borderless="{{true}}" style="{{style}}" />
|
||||
</view>
|
||||
</view>
|
||||
@ -441,7 +441,7 @@
|
||||
<t-col span="12">
|
||||
<view class="dark">
|
||||
<view class="input-example">
|
||||
<view class="input-example__label">肝剑突下(mm)</view>
|
||||
<view class="input-example__label">肝剑突下(mm)</view>
|
||||
<t-input type="digit" placeholder="请输入" bind:change="onInput" value="{{form.under_the_xiphoid_liver}}" data-key="under_the_xiphoid_liver" borderless="{{true}}" style="{{style}}" />
|
||||
</view>
|
||||
</view>
|
||||
@ -449,7 +449,7 @@
|
||||
<t-col span="12">
|
||||
<view class="dark">
|
||||
<view class="input-example">
|
||||
<view class="input-example__label">脾肋下(mm)</view>
|
||||
<view class="input-example__label">脾肋下(mm)</view>
|
||||
<t-input type="digit" placeholder="请输入" bind:change="onInput" value="{{form.spleen_rib_area}}" data-key="spleen_rib_area" borderless="{{true}}" style="{{style}}" />
|
||||
</view>
|
||||
</view>
|
||||
@ -457,7 +457,7 @@
|
||||
<t-col span="12">
|
||||
<view class="dark">
|
||||
<view class="input-example">
|
||||
<view class="input-example__label">门静脉主干内径(mm)</view>
|
||||
<view class="input-example__label">门静脉主干内径(mm)</view>
|
||||
<t-input placeholder="请输入" bind:change="onInput" value="{{form.main_portal_vein}}" data-key="main_portal_vein" borderless="{{true}}" style="{{style}}" />
|
||||
</view>
|
||||
</view>
|
||||
@ -473,7 +473,7 @@
|
||||
<t-col span="12">
|
||||
<view class="dark">
|
||||
<view class="input-example">
|
||||
<view class="input-example__label">胆囊大小(mm)</view>
|
||||
<view class="input-example__label">胆囊大小(mm)</view>
|
||||
<t-input type="digit" placeholder="请输入" bind:change="onInput" value="{{form.gallbladder_size}}" data-key="gallbladder_size" size="small" borderless="{{true}}" style="{{style}}" />
|
||||
</view>
|
||||
</view>
|
||||
@ -481,7 +481,7 @@
|
||||
<t-col span="12">
|
||||
<view class="dark">
|
||||
<view class="input-example">
|
||||
<view class="input-example__label">胆总管(mm)</view>
|
||||
<view class="input-example__label">胆总管(mm)</view>
|
||||
<t-input type="digit" placeholder="请输入" bind:change="onInput" value="{{form.common_bile_duct}}" data-key="common_bile_duct" size="small" borderless="{{true}}" style="{{style}}" />
|
||||
</view>
|
||||
</view>
|
||||
@ -489,7 +489,7 @@
|
||||
<t-col span="12">
|
||||
<view class="dark">
|
||||
<view class="input-example">
|
||||
<view class="input-example__label">纤维块大小(mm)</view>
|
||||
<view class="input-example__label">纤维块大小(mm)</view>
|
||||
<t-input type="digit" placeholder="请输入" bind:change="onInput" value="{{form.fiber_block_size}}" data-key="fiber_block_size" size="small" borderless="{{true}}" style="{{style}}" />
|
||||
</view>
|
||||
</view>
|
||||
@ -532,6 +532,30 @@
|
||||
</view>
|
||||
</view>
|
||||
</t-col>
|
||||
<t-col span="12">
|
||||
<view class="dark">
|
||||
<view class="input-example">
|
||||
<view class="input-example__label">弹性成像最小值(kPa)</view>
|
||||
<t-input type="digit" placeholder="请输入" bind:change="onInput" value="{{form.elastography_median}}" data-key="elastography_median" borderless="{{true}}" style="{{style}}" />
|
||||
</view>
|
||||
</view>
|
||||
</t-col>
|
||||
<t-col span="12">
|
||||
<view class="dark">
|
||||
<view class="input-example">
|
||||
<view class="input-example__label">弹性成像最大值(kPa)</view>
|
||||
<t-input type="digit" placeholder="请输入" bind:change="onInput" value="{{form.elastography_maximum}}" data-key="elastography_maximum" borderless="{{true}}" style="{{style}}" />
|
||||
</view>
|
||||
</view>
|
||||
</t-col>
|
||||
<t-col span="12">
|
||||
<view class="dark">
|
||||
<view class="input-example">
|
||||
<view class="input-example__label">弹性成像中位数(kPa)</view>
|
||||
<t-input type="digit" placeholder="请输入" bind:change="onInput" value="{{form.elastography_median}}" data-key="elastography_median" borderless="{{true}}" style="{{style}}" />
|
||||
</view>
|
||||
</view>
|
||||
</t-col>
|
||||
</t-row>
|
||||
</view>
|
||||
<view class="follow-item">
|
||||
|
||||
0
pages/followUp/ocrDate.js
Normal file
0
pages/followUp/ocrDate.js
Normal file
Loading…
x
Reference in New Issue
Block a user