| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- <!-- 刷题练习列表 -->
- <template>
- <view class="safetyEducationExamination-practice">
- <!-- 顶部类型标签 -->
- <view class="tag-bar" v-if="!hideTagBar">
- <scroll-view scroll-x class="tag-scroll">
- <view class="tag-scroll-inner">
- <text
- v-for="(tag, index) in typeTags"
- :key="index"
- class="tag-item"
- :class="{ 'tag-item-active': activeTagIndex === index }"
- @click="onTagChange(index)"
- >{{ tag.label }}</text>
- </view>
- </scroll-view>
- </view>
- <!-- 列表 -->
- <scroll-view scroll-y class="scroll-content">
- <view class="panel">
- <view
- v-for="(item, index) in practiceList"
- :key="index"
- class="practice-card"
- @click="goToPractice(item)"
- >
- <view class="card-top">
- <text class="tag" :class="item.tagClass">{{ item.knowledgePointName }}</text>
- <text class="total-count" :style="'color:' + item.progressColor">{{ item.totalCount }} 题</text>
- </view>
- <text class="card-title">{{ item.knowledgePointName }}</text>
- <text class="card-sub" :class="item.practiceStatus > 0 ? '' : 'text-gray'">
- {{ item.practiceStatus > 0 ? '已答 ' + item.answeredCount + ' 题 · 正确率 ' + item.correctRate + '%' : '未开始' }}
- </text>
- <view class="progress-row">
- <view class="progress-wrap">
- <view class="progress-bar" :style="'width:' + (item.progress || 0) + '%;background:' + item.progressColor"></view>
- </view>
- <text class="progress-text" :style="'color:' + item.progressColor">{{ item.progress || 0 }}%</text>
- </view>
- </view>
- <view v-if="!practiceList[0] && !loading" class="empty-tip">暂无题库数据</view>
- <view v-if="loading" class="loading-tip">加载中...</view>
- </view>
- </scroll-view>
- </view>
- </template>
- <script>
- import {
- examUserPracticeList,
- examElKnowledgePointTreeList,
- } from '@/pages_safetyEducationExamination/api/index.js'
- // 根据索引返回标签样式类和进度条颜色
- const TAG_COLORS = [
- { tagClass: 'tag-blue', color: '#1677ff' },
- { tagClass: 'tag-green', color: '#52c41a' },
- { tagClass: 'tag-orange', color: '#fa8c16' },
- { tagClass: 'tag-purple', color: '#722ed1' },
- { tagClass: 'tag-cyan', color: '#13c2c2' },
- ];
- export default {
- data() {
- return {
- typeTags: [{ label: '全部', value: null }],
- activeTagIndex: 0,
- practiceList: [],
- loading: false,
- // 跳转参数
- hideTagBar: false,
- disciplineTypeId: null,
- knowledgePointId: null,
- }
- },
- onLoad(options) {
- // 接收跳转参数
- if (options.disciplineTypeId || options.knowledgePointId) {
- this.disciplineTypeId = options.disciplineTypeId || null;
- this.knowledgePointId = options.knowledgePointId || null;
- this.hideTagBar = true;
- }
- },
- created() {
- this.loadTypeTags();
- },
- onShow() {
- this.loadPracticeList();
- },
- methods: {
- // 加载知识点类型标签(dataScope=2)
- async loadTypeTags() {
- try {
- const { data } = await examElKnowledgePointTreeList({ dataScope: 2 });
- if (data.code === 200 && data.data) {
- const tags = (data.data || []).map(item => ({
- label: item.knowledgePointName,
- value: item.id,
- }));
- this.$set(this, 'typeTags', [{ label: '全部', value: null }, ...tags]);
- }
- } catch (e) {
- console.error('获取知识点类型失败', e);
- }
- },
- // 加载题库分组列表
- async loadPracticeList() {
- if (this.loading) return;
- this.loading = true;
- try {
- const tag = this.typeTags[this.activeTagIndex];
- const obj = {
- page: 1,
- pageSize: 50,
- knowledgePointId: this.knowledgePointId || tag.value || undefined,
- disciplineTypeId: this.disciplineTypeId || undefined,
- };
- const { data } = await examUserPracticeList(obj);
- if (data.code === 200) {
- const records = (data.data.records || []).map((item, index) => {
- const colorInfo = TAG_COLORS[index % TAG_COLORS.length];
- return {
- ...item,
- tagClass: colorInfo.tagClass,
- progressColor: item.practiceStatus > 0 ? colorInfo.color : '#bbb',
- };
- });
- this.$set(this, 'practiceList', records);
- }
- } catch (e) {
- console.error('获取题库列表失败', e);
- } finally {
- this.loading = false;
- }
- },
- onTagChange(index) {
- this.activeTagIndex = index;
- this.loadPracticeList();
- },
- goToPractice(item) {
- // 跳转刷题详情,传递 knowledgePointId
- },
- },
- }
- </script>
- <style lang="stylus" scoped>
- .safetyEducationExamination-practice
- height 100%
- display flex
- flex-direction column
- overflow hidden
- background-color #f0f4fb
- // 顶部标签栏
- .tag-bar
- background #fff
- border-bottom 1rpx solid #e8edf3
- flex-shrink 0
- padding 0 24rpx
- .tag-scroll
- white-space nowrap
- .tag-scroll-inner
- display inline-flex
- gap 16rpx
- padding 16rpx 0
- .tag-item
- display inline-block
- font-size 24rpx
- padding 10rpx 24rpx
- border-radius 30rpx
- background #eef1f6
- color #666
- border 1rpx solid transparent
- white-space nowrap
- .tag-item-active
- background #e6f0ff
- color #1677ff
- border-color #91caff
- font-weight 600
- // 内容滚动区
- .scroll-content
- flex 1
- overflow hidden
- .panel
- padding 24rpx
- // 题库卡片
- .practice-card
- background #fff
- border-radius 20rpx
- padding 24rpx 28rpx
- margin-bottom 20rpx
- box-shadow 0 2rpx 12rpx rgba(0,0,0,0.04)
- border 1rpx solid #dde3ed
- .card-top
- display flex
- justify-content space-between
- align-items center
- margin-bottom 16rpx
- // 标签
- .tag
- font-size 20rpx
- padding 4rpx 12rpx
- border-radius 8rpx
- border 1rpx solid transparent
- .tag-blue
- background #e6f4ff
- color #1677ff
- border-color #91caff
- .tag-green
- background #f6ffed
- color #389e0d
- border-color #b7eb8f
- .tag-orange
- background #fff7e6
- color #d46b08
- border-color #ffd591
- .tag-purple
- background #f9f0ff
- color #722ed1
- border-color #d3adf7
- .tag-cyan
- background #e6fffb
- color #08979c
- border-color #87e8de
- .total-count
- font-size 22rpx
- color #1677ff
- font-weight 600
- .text-hint
- color #bbb
- // 卡片文字
- .card-title
- display block
- font-size 28rpx
- font-weight 600
- color #222
- margin-bottom 8rpx
- .card-sub
- display block
- font-size 22rpx
- color #666
- margin-bottom 16rpx
- .text-gray
- color #999
- // 进度条
- .progress-row
- display flex
- align-items center
- gap 12rpx
- .progress-wrap
- flex 1
- height 10rpx
- background #eef1f6
- border-radius 10rpx
- overflow hidden
- .progress-bar
- height 100%
- border-radius 10rpx
- background #1677ff
- transition width 0.3s
- .progress-text
- font-size 22rpx
- font-weight 700
- width 64rpx
- text-align right
- // 提示
- .empty-tip
- text-align center
- line-height 80rpx
- color #aaa
- font-size 24rpx
- .loading-tip
- text-align center
- line-height 60rpx
- color #aaa
- font-size 22rpx
- </style>
|