feat: 电子药箱小程序 - 4Tab药品管理

- 电子药箱: 药品库存管理 + 手动录入 + 今日用药打卡
- 药品百科: 搜索 + 分类筛选 + 20种药品静态数据
- 惠教中心: 4条药品使用指南课程
- 我的: 家庭成员信息管理
- 自定义TabBar + navigation-bar组件
- SVG药品分类插图
This commit is contained in:
陈誉午
2026-07-29 11:20:52 +08:00
commit 994b267f5c
683 changed files with 43849 additions and 0 deletions
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"component":true,"usingComponents":{"Drawer":"../../../pubComponents/drawer/drawer","mp-loading":"weui-miniprogram/loading/loading","count-down":"../count-down/count-down","mp-icon":"weui-miniprogram/icon/icon"}}
@@ -0,0 +1,100 @@
<wxs module="m1">
var getMax = function(array, str) {
return array ? array.indexOf(str) > -1 : false;
}
module.exports.getMax = getMax;
</wxs>
<Drawer id='quiz-drawer' custom-drawer="quiz-drawer" needCancel="{{false}}" bind:myCancel="myCancel">
<view class="quiz-drawer-wrap {{useDarkTheme ? 'quiz-drawer-wrap-dark' : ''}}">
<!-- <mp-loading show="{{loading}}" class="quiz-loading" /> -->
<view class="quiz-content-wrap">
<!-- 标题 -->
<view class="quiz-title-wrap" wx:if="{{data}}">
<view class="quiz-sub-title">
[{{data.QuizTitleType === 0 ? '单选' : '多选'}}]
<mp-icon bindtap="closeQuizDrawer" icon="close" color="#939aa3" size="{{20}}" class="close drawer-close-shadow" />
</view>
<view class="quiz-title">
{{data.QuizTitle}}
</view>
</view>
<view class="quiz-content">
<!-- 答题结果 -->
<view wx:if="{{isShowResult && data}}" class="quiz-result-wrapper {{data.IsRight ? 'quiz-is-right' : ''}}">
<view >
正确答案:<view class="quiz-right-answer">{{data.RightOptions}}</view>
</view>
<view >你的答案:
<view class="quiz-answer">{{data.SubmitOptions}}</view>
</view>
<view wx:if="{{data.QuizAnalysis}}" className="quiz-explain">答案解析:{{data.QuizAnalysis}}</view>
</view>
<scroll-view scroll-y class="quiz-options-scroll">
<!-- 答题表单 -->
<form>
<!-- 单选 -->
<view wx:if="{{data && data.QuizTitleType === 0}}" class="page-section page-section-gap">
<radio-group bindchange="valueChange" >
<label class="quiz-option-wrapper" wx:for="{{data.QuizOptions || []}}" wx:for-index="index" wx:for-item="item" wx:key="index">
<radio class="quiz-option-radio" disabled="{{isDisableForm}}" value="{{item.OptionSite}}" checked="{{formValue[0] === item.OptionSite}}" color="#3370ff"/>
<view class="quiz-option-text">
{{item.OptionSite}}. {{item.OptionName}}
<view wx:if="{{isShowResult}}" class="quiz-progress-container">
<view class="quiz-progress-container-text">
<view>{{item.OptionCount || 0}}人</view>
<view>{{item.OptionPercent || 0}}%</view>
</view>
<progress percent="{{item.OptionPercent || 0}}" border-radius="6" backgroundColor="{{useDarkTheme ? '#37383a' : '#f0f1f2'}}" activeColor="#3370ff" stroke-width="6" />
</view>
</view>
</label>
</radio-group>
</view>
<!-- 多选 -->
<view wx:if="{{data && data.QuizTitleType === 1}}" class="page-section page-section-gap">
<checkbox-group bindchange="valueChange">
<label class="quiz-option-wrapper {{m1.getMax(formValue, item.OptionSite) ? 'quiz-option-wrapper-checked' : ''}}" wx:for="{{data.QuizOptions || []}}" wx:for-index="index" wx:for-item="item" wx:key="index">
<checkbox disabled="{{isDisableForm}}" value="{{item.OptionSite}}" checked="{{m1.getMax(formValue, item.OptionSite)}}" color="#3370ff"/>
<view class="quiz-option-text">
{{item.OptionSite}}. {{item.OptionName}}
<view wx:if="{{isShowResult}}" class="quiz-progress-container">
<view class="quiz-progress-container-text">
<view>{{item.OptionCount || 0}}人</view>
<view>{{item.OptionPercent || 0}}%</view>
</view>
<progress percent="{{item.OptionPercent || 0}}" border-radius="6" backgroundColor="{{useDarkTheme ? '#37383a' : '#f0f1f2'}}" activeColor="#3370ff" stroke-width="6" />
</view>
</view>
</label>
</checkbox-group>
</view>
</form>
</scroll-view>
</view>
</view>
<!-- footer -->
<view class="quiz-footer">
<view class="quiz-footer-tip" wx:if="{{!isShowResult && data.QuizResultType === 2 && isSubmitted}}">
<view class="quiz-footer-wait-tip">等待公布答案</view>
</view>
<view class="quiz-footer-tip {{isDownWarn ? 'quiz-footer-tip-warn' : ''}}" wx:if="{{!isShowResult && data.QuizResultType !== 2}}">
<image src="{{isDownWarn ? '../../../assets/alarmWarn.svg' : '../../../assets/alarm.svg'}}" />
距答题截止
<count-down
type="quiz"
wx:if="{{data.SendTime}}"
sendTime="{{data.SendTime}}"
deadLine="{{data.Deadline / 60}}"
isDownWarn="{{isDownWarn}}"
bind:onCountDown="onCountDown" bind:onCountDownWarn="onCountDownWarn"/>
</view>
<button
loading="{{isSubmitting}}"
disabled="{{statusDisabled}}"
class="quiz-footer-button {{statusDisabled ? 'quiz-footer-button-disabled' : ''}}"
type="primary"
bindtap="formSubmit"
>{{statusText}}</button>
</view>
</view>
</Drawer>
@@ -0,0 +1 @@
.quiz-drawer .frame{overflow:hidden;padding:0!important}.quiz-drawer-wrap{background-color:#fff;padding-bottom:constant(safe-area-inset-bottom);padding-bottom:env(safe-area-inset-bottom)}.quiz-content-wrap{overflow:hidden}.quiz-title-wrap{padding:16rpx 40rpx;background:transparent linear-gradient(180deg,#e7edff,#fff)}.quiz-sub-title{color:#6f7680;font-size:calc(26rpx + .5 * (1rem - 16px));font-weight:400;line-height:calc(44rpx + .5 * (1rem - 16px));margin-bottom:16rpx;margin-top:16rpx;display:flex;justify-content:space-between}.drawer-close-shadow{background:0 0;box-shadow:none}.quiz-title{color:#1d2129;font-size:calc(36rpx + .5 * (1rem - 16px));word-break:break-all;font-weight:700;line-height:calc(40rpx + .5 * (1rem - 16px));margin-bottom:10rpx}.quiz-content{padding:16rpx 40rpx}.quiz-options-scroll{max-height:400rpx}.quiz-result-wrapper{color:#6f7680;margin-bottom:40rpx;font-size:calc(28rpx + .5 * (1rem - 16px));word-break:break-all}.quiz-answer,.quiz-right-answer{display:inline-block;margin-bottom:16rpx}.quiz-answer{color:#ee4d38}.quiz-is-right .quiz-answer{color:#0fbf60}.quiz-right-answer{color:#0fbf60}.quiz-option-wrapper{display:flex;background-color:#f6f8fa;border-radius:8rpx;padding:32rpx;margin-bottom:20rpx;font-weight:400}.quiz-option-wrapper .wx-radio-input.wx-radio-input-checked{border-color:#3370ff!important;background:#3370ff!important}.quiz-option-wrapper-checked{background-color:#ecf3ff}.quiz-option-text{flex:auto;color:#1d2129}.quiz-progress-container-text{margin-top:16rpx;display:flex;justify-content:space-between;font-size:calc(24rpx + .5 * (1rem - 16px));line-height:calc(32rpx + .5 * (1rem - 16px));margin-bottom:8rpx;color:#6f7680}.quiz-footer{padding-top:20rpx;padding-left:40rpx;padding-right:40rpx;padding-bottom:40rpx}.quiz-footer-button{width:100%!important;border-radius:50px;background-color:#3370ff!important;font-size:calc(28rpx + .5 * (1rem - 16px));font-weight:400}.quiz-footer-button-disabled{background-color:#8baeff!important;color:#fff!important}.quiz-footer-tip{font-size:calc(26rpx + .5 * (1rem - 16px));font-weight:700;padding:16rpx 0;color:#3370ff;display:flex;justify-content:center;align-items:center}.quiz-footer-wait-tip{font-size:calc(26rpx + .5 * (1rem - 16px));font-weight:700;color:#ee4d38;line-height:calc(40rpx + .5 * (1rem - 16px))}.quiz-footer-tip image{width:32rpx;height:32rpx;margin-right:6rpx}.quiz-footer-tip-warn{color:#ee4d38}.quiz-drawer-wrap-dark{background-color:#202124}.quiz-drawer-wrap-dark .quiz-title-wrap{padding:16rpx 40rpx;background:#202124}.quiz-drawer-wrap-dark .quiz-sub-title{color:#909090}.quiz-drawer-wrap-dark .quiz-title{color:#fff}.quiz-drawer-wrap-dark .quiz-option-text{color:#fff}.quiz-drawer-wrap-dark .quiz-progress-container-text{color:#fff}.quiz-drawer-wrap-dark .quiz-result-wrapper{color:#909090}.quiz-drawer-wrap-dark .quiz-option-wrapper{background-color:#2c2d30}