更新
This commit is contained in:
@@ -82,8 +82,8 @@
|
||||
</view>
|
||||
<view class="heatmap-foot">
|
||||
<text class="heatmap-foot-text">{{ todayChecked ? '今日已完成记录' : '今日还没有记录' }}</text>
|
||||
<view v-if="!todayChecked" class="heatmap-foot-cta" @click="goGlucosePage()">
|
||||
<text>去记血糖</text>
|
||||
<view class="heatmap-foot-cta" @click="openInputForm()">
|
||||
<text>{{ todayChecked ? '编辑血糖' : '去记血糖' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -173,7 +173,7 @@
|
||||
<view
|
||||
class="record-quick-chip"
|
||||
:class="{ done: todayChecked, pending: !todayChecked }"
|
||||
@click="goGlucosePage()"
|
||||
@click="openInputForm()"
|
||||
>
|
||||
<view class="record-quick-icon-wrap">
|
||||
<TongjiIcon name="glucose" size="md" :color="todayChecked ? '#386641' : '#204E2B'" />
|
||||
@@ -501,6 +501,104 @@
|
||||
<text>数据每日同步 · 阈值仅作参考,请遵医嘱</text>
|
||||
</view>
|
||||
|
||||
<!-- 录入今日血糖 -->
|
||||
<view v-if="inputForm.visible" class="input-modal-mask" @click="closeInputForm">
|
||||
<view class="input-modal" @click.stop>
|
||||
<view class="input-modal-grip" />
|
||||
<view class="input-modal-head">
|
||||
<view class="input-modal-title-wrap">
|
||||
<text class="input-modal-title">{{ inputForm.id ? '修改今日血糖' : '录入今日血糖' }}</text>
|
||||
<text class="input-modal-sub">{{ todayText }} · {{ patientName || '本人' }}</text>
|
||||
</view>
|
||||
<view class="input-modal-close" @click="closeInputForm">
|
||||
<text class="input-modal-close-icon">×</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="inputForm.loading" class="input-modal-loading">
|
||||
<text>加载今日数据中…</text>
|
||||
</view>
|
||||
<scroll-view v-else scroll-y class="input-modal-body input-modal-body-ready">
|
||||
<view class="input-modal-tip">
|
||||
<text>请如实填写,留空表示该项不上传。当天可多次修改。</text>
|
||||
</view>
|
||||
<view class="input-section-title">血糖(mmol/L)</view>
|
||||
<view class="input-field">
|
||||
<view class="input-field-label">
|
||||
<view class="input-field-dot input-field-dot-fasting" />
|
||||
<text>空腹血糖</text>
|
||||
</view>
|
||||
<view class="input-field-input">
|
||||
<input
|
||||
type="digit"
|
||||
:value="inputForm.fasting_blood_sugar"
|
||||
placeholder="如 6.5"
|
||||
placeholder-class="input-placeholder"
|
||||
@input="onInputField('fasting_blood_sugar', $event)"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="input-field">
|
||||
<view class="input-field-label">
|
||||
<view class="input-field-dot input-field-dot-postprandial" />
|
||||
<text>餐后血糖</text>
|
||||
</view>
|
||||
<view class="input-field-input">
|
||||
<input
|
||||
type="digit"
|
||||
:value="inputForm.postprandial_blood_sugar"
|
||||
placeholder="如 8.0"
|
||||
placeholder-class="input-placeholder"
|
||||
@input="onInputField('postprandial_blood_sugar', $event)"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="input-field">
|
||||
<view class="input-field-label">
|
||||
<view class="input-field-dot input-field-dot-other" />
|
||||
<text>其他血糖</text>
|
||||
</view>
|
||||
<view class="input-field-input">
|
||||
<input
|
||||
type="digit"
|
||||
:value="inputForm.other_blood_sugar"
|
||||
placeholder="如 7.2"
|
||||
placeholder-class="input-placeholder"
|
||||
@input="onInputField('other_blood_sugar', $event)"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="input-section-title">备注</view>
|
||||
<view class="input-field input-field-textarea">
|
||||
<textarea
|
||||
:value="inputForm.remark"
|
||||
placeholder="如:饭前空腹测量、餐后2小时测量等(选填)"
|
||||
placeholder-class="input-placeholder"
|
||||
:show-confirm-bar="false"
|
||||
:auto-height="true"
|
||||
@input="onInputField('remark', $event)"
|
||||
/>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="input-modal-actions">
|
||||
<view
|
||||
v-if="inputForm.id"
|
||||
class="input-modal-btn danger"
|
||||
:class="{ disabled: inputForm.submitting }"
|
||||
@click="deleteInputRecord"
|
||||
>
|
||||
<text>删除</text>
|
||||
</view>
|
||||
<view
|
||||
class="input-modal-btn primary"
|
||||
:class="{ disabled: inputForm.submitting || inputForm.loading }"
|
||||
@click="submitInputForm"
|
||||
>
|
||||
<text>{{ inputForm.submitting ? '提交中…' : (inputForm.id ? '保存修改' : '提交录入') }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 录入血压弹层 -->
|
||||
<view v-if="bpForm.visible" class="input-modal-mask" @click="closeBpForm">
|
||||
<view class="input-modal" @click.stop>
|
||||
@@ -1576,6 +1674,18 @@ const todayText = computed(() => {
|
||||
return `${d.getFullYear()}-${m}-${day} ${weekdays[d.getDay()]}`
|
||||
})
|
||||
|
||||
const emptyInputForm = () => ({
|
||||
visible: false,
|
||||
loading: false,
|
||||
submitting: false,
|
||||
id: 0,
|
||||
fasting_blood_sugar: '',
|
||||
postprandial_blood_sugar: '',
|
||||
other_blood_sugar: '',
|
||||
remark: ''
|
||||
})
|
||||
const inputForm = ref(emptyInputForm())
|
||||
|
||||
const emptyBpForm = () => ({
|
||||
visible: false,
|
||||
loading: false,
|
||||
@@ -1593,6 +1703,124 @@ function prepareRecordOverlay() {
|
||||
ttsStop()
|
||||
}
|
||||
|
||||
function onInputField(field, e) {
|
||||
inputForm.value[field] = e?.detail?.value ?? ''
|
||||
}
|
||||
|
||||
async function openInputForm() {
|
||||
if (!diagnosisId.value) {
|
||||
showUserToast('请先选择就诊卡')
|
||||
return
|
||||
}
|
||||
const token = uni.getStorageSync('token')
|
||||
if (!token) {
|
||||
showUserToast('请先登录后再录入')
|
||||
return
|
||||
}
|
||||
prepareRecordOverlay()
|
||||
inputForm.value = { ...emptyInputForm(), visible: true, loading: true }
|
||||
try {
|
||||
const res = await proxy.apiUrl({
|
||||
url: '/api/tcm/dailyTodayBloodRecord',
|
||||
method: 'GET',
|
||||
data: { diagnosis_id: diagnosisId.value }
|
||||
}, false)
|
||||
if (res && res.code === 1 && res.data && res.data.record) {
|
||||
const r = res.data.record
|
||||
inputForm.value.id = Number(r.id) || 0
|
||||
inputForm.value.fasting_blood_sugar = numToStr(r.fasting_blood_sugar)
|
||||
inputForm.value.postprandial_blood_sugar = numToStr(r.postprandial_blood_sugar)
|
||||
inputForm.value.other_blood_sugar = numToStr(r.other_blood_sugar)
|
||||
inputForm.value.remark = String(r.remark || '')
|
||||
}
|
||||
} catch (e) {
|
||||
/* 静默:拉取失败时仍允许新增录入 */
|
||||
} finally {
|
||||
inputForm.value.loading = false
|
||||
}
|
||||
}
|
||||
|
||||
function closeInputForm() {
|
||||
if (inputForm.value.submitting) return
|
||||
inputForm.value.visible = false
|
||||
}
|
||||
|
||||
async function submitInputForm() {
|
||||
if (inputForm.value.submitting || inputForm.value.loading) return
|
||||
const f = inputForm.value
|
||||
const hasAny = [
|
||||
f.fasting_blood_sugar, f.postprandial_blood_sugar, f.other_blood_sugar
|
||||
].some((v) => v !== '' && v !== null && Number(v) > 0) || !!(f.remark && f.remark.trim())
|
||||
if (!hasAny) {
|
||||
showUserToast('请至少填写一项数据')
|
||||
return
|
||||
}
|
||||
inputForm.value.submitting = true
|
||||
try {
|
||||
const res = await proxy.apiUrl({
|
||||
url: '/api/tcm/dailySaveBloodRecord',
|
||||
method: 'POST',
|
||||
data: {
|
||||
diagnosis_id: diagnosisId.value,
|
||||
fasting_blood_sugar: f.fasting_blood_sugar,
|
||||
postprandial_blood_sugar: f.postprandial_blood_sugar,
|
||||
other_blood_sugar: f.other_blood_sugar,
|
||||
remark: f.remark
|
||||
}
|
||||
}, false)
|
||||
if (res && res.code === 1) {
|
||||
showUserToast(res.msg || '已保存', { icon: 'success' })
|
||||
inputForm.value.visible = false
|
||||
await fetchAll()
|
||||
await fetchGamifyState()
|
||||
if (claimablePoints.value > 0) {
|
||||
showUserToast('血糖已记录,点击浇水领取积分', { duration: 2800 })
|
||||
}
|
||||
} else {
|
||||
showUserToast((res && res.msg) || '保存失败')
|
||||
}
|
||||
} catch (e) {
|
||||
showUserToast('网络异常,请稍后再试')
|
||||
} finally {
|
||||
inputForm.value.submitting = false
|
||||
}
|
||||
}
|
||||
|
||||
function deleteInputRecord() {
|
||||
if (!inputForm.value.id || inputForm.value.submitting) return
|
||||
uni.showModal({
|
||||
title: '删除确认',
|
||||
content: '确定删除今天已录入的血糖数据吗?删除后无法恢复。',
|
||||
confirmColor: '#dc2626',
|
||||
success: async (m) => {
|
||||
if (!m.confirm) return
|
||||
inputForm.value.submitting = true
|
||||
try {
|
||||
const res = await proxy.apiUrl({
|
||||
url: '/api/tcm/dailyDeleteBloodRecord',
|
||||
method: 'POST',
|
||||
data: {
|
||||
diagnosis_id: diagnosisId.value,
|
||||
id: inputForm.value.id
|
||||
}
|
||||
}, false)
|
||||
if (res && res.code === 1) {
|
||||
uni.showToast({ title: '已删除', icon: 'success' })
|
||||
inputForm.value.visible = false
|
||||
await fetchAll()
|
||||
await fetchGamifyState()
|
||||
} else {
|
||||
showUserToast((res && res.msg) || '删除失败')
|
||||
}
|
||||
} catch (e) {
|
||||
uni.showToast({ title: '网络异常,请稍后再试', icon: 'none' })
|
||||
} finally {
|
||||
inputForm.value.submitting = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onBpField(field, e) {
|
||||
const val = e?.detail?.value ?? ''
|
||||
bpForm.value[field] = val
|
||||
@@ -1760,7 +1988,7 @@ const exerciseForm = ref(emptyExerciseForm())
|
||||
|
||||
/** 任一录入弹层打开时需卸载 canvas(小程序原生组件会盖住普通 view)*/
|
||||
const recordOverlayOpen = computed(() =>
|
||||
bpForm.value.visible || dietForm.value.visible || exerciseForm.value.visible
|
||||
inputForm.value.visible || bpForm.value.visible || dietForm.value.visible || exerciseForm.value.visible
|
||||
)
|
||||
|
||||
function onExerciseField(field, e) {
|
||||
@@ -3082,7 +3310,7 @@ function onGamifyTaskTap(task) {
|
||||
}
|
||||
if (!task.completed) {
|
||||
if (task.id === 'blood') {
|
||||
goGlucosePage()
|
||||
openInputForm()
|
||||
return
|
||||
}
|
||||
if (task.id === 'diet') {
|
||||
@@ -4843,6 +5071,7 @@ function onFamilyLikeStripTap() {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
animation: input-modal-mask-in 0.38s cubic-bezier(0.22, 1, 0.36, 1) both;
|
||||
}
|
||||
.input-modal {
|
||||
width: 100%;
|
||||
@@ -4854,13 +5083,22 @@ function onFamilyLikeStripTap() {
|
||||
max-height: 88vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
animation: input-modal-rise 0.28s cubic-bezier(0.16, 1, 0.3, 1);
|
||||
animation: input-modal-rise 0.46s cubic-bezier(0.22, 1, 0.36, 1) both;
|
||||
position: relative;
|
||||
z-index: 1000;
|
||||
will-change: transform, opacity;
|
||||
}
|
||||
@keyframes input-modal-mask-in {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
@keyframes input-modal-rise {
|
||||
from { transform: translateY(60rpx); opacity: 0.5; }
|
||||
to { transform: translateY(0); opacity: 1; }
|
||||
from { transform: translate3d(0, 100%, 0); opacity: 0.96; }
|
||||
to { transform: translate3d(0, 0, 0); opacity: 1; }
|
||||
}
|
||||
@keyframes input-modal-content-in {
|
||||
from { opacity: 0; transform: translate3d(0, 24rpx, 0); }
|
||||
to { opacity: 1; transform: translate3d(0, 0, 0); }
|
||||
}
|
||||
.input-modal-grip {
|
||||
width: 80rpx;
|
||||
@@ -4912,19 +5150,27 @@ function onFamilyLikeStripTap() {
|
||||
font-weight: 700;
|
||||
}
|
||||
.input-modal-loading {
|
||||
padding: 80rpx 0;
|
||||
min-height: 520rpx;
|
||||
padding: 120rpx 0;
|
||||
text-align: center;
|
||||
color: var(--slate-600);
|
||||
font-size: 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.input-modal-body {
|
||||
flex: 1;
|
||||
min-height: 520rpx;
|
||||
padding: 20rpx 32rpx 28rpx;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
}
|
||||
.input-modal-body-ready {
|
||||
animation: input-modal-content-in 0.34s cubic-bezier(0.22, 1, 0.36, 1) both;
|
||||
}
|
||||
.input-modal-tip {
|
||||
background: var(--primary-light);
|
||||
border: 1rpx dashed #99f6e4;
|
||||
|
||||
Reference in New Issue
Block a user