Explorar o código

添加自主练习——查看练习结果页面(交互待完善)

lm hai 4 días
pai
achega
37aa9a8142

+ 172 - 0
src/views/targetImprove/components/Table.vue

@@ -0,0 +1,172 @@
+<template>
+  <div class="page_table">
+    <el-table
+      class="el-table--border"
+      ref="tableRef"
+      :show-header="showHeader"
+      :data="tableData"
+      stripe
+      v-loading="loading"
+      element-loading-text="拼命加载中……"
+      element-loading-spinner="el-icon-loading"
+      element-loading-background="#ffffff"
+      element-loading-custom-class="loading_icon"
+      :row-class-name="tableRowClassName"
+      @row-click="(row, column) => $emit('rowClick', row)"
+      :span-method="spanMethod"
+    >
+      <template v-for="(item, index) in tableColumns">
+        <el-table-column
+          :key="item?.name"
+          v-if="!item.hidden"
+          :prop="item.name"
+          :min-width="item.minWidth"
+          :width="item.width"
+          :label="item.label"
+          :fixed="item.fixed ? item.fixed : false"
+          :align="item.align"
+        >
+          <template v-if="item.customHeader" v-slot:header>
+            <slot :name="'header-' + item.name"></slot>
+          </template>
+
+          <template v-if="item.custom" v-slot:default="row">
+            <slot :name="item.name" :row="row.row" :currentIndex="(row.$index + 1)"></slot>
+          </template>
+        </el-table-column>
+      </template>
+    </el-table>
+
+    <div class="page_pagination" v-if="!hidePagination">
+      <el-pagination
+        :hide-on-single-page="hidesinglePage"
+        :current-page="currentPage"
+        :page-size="pageSize"
+        :page-sizes="[20, 50, 100]"
+        background
+        layout="prev, pager, next"
+        :total="Number(totalNum)"
+        @current-change="(val) => $emit('paginationChange', { type: 'currentPage', val })"
+        @size-change="(val) => $emit('paginationChange', { type: 'pageSize', val })"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+/*
+interface tableColumnItm  {
+  name:String,
+  label:String,
+  width?:String,
+  fixed?:String,
+  align?:String,
+  minWidth?:String,
+  custom:Boolean,
+  customHeader?:Boolean,
+  hidden:Boolean,
+}
+*/
+export default {
+  name: 'Table',
+  props: {
+    tableData: {
+      type: Array,
+      required: true
+    },
+    tableColumns: {
+      type: Array,  //类型为 tableColumnItm[]
+      required: true
+    },
+    currentPage: {
+      type: Number,
+      default: 1
+    },
+    pageSize: {
+      type: Number,
+      default: 20
+    },
+    totalNum: {
+      type: Number,
+      default: 0
+    },
+    loading: {
+      type: Boolean,
+      default: false
+    },
+    hidesinglePage: {
+      type: Boolean
+    },
+    hidePagination: {
+      type: Boolean,
+      default: false
+    },
+    spanMethod: {
+      type: Function,
+      required: false
+    },
+    tableRowClassName: {
+      type: Function,
+      required: false
+    },
+    showHeader: {
+      type: Boolean,
+      default: true
+    }
+  },
+  data() {
+    return {
+      // Vue 2 中没有 defineModel,tableRef 仅作为内部状态或普通 ref
+      // 父组件获取表格实例请使用 this.$refs.tableRef
+      tableRef: null 
+    };
+  },
+  mounted(){
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.page_table {
+  overflow: auto;
+  display: flex;
+  flex-direction: column;
+  justify-content: flex-start;
+
+  ::v-deep .el-table {
+    tr th.el-table__cell {
+      font-size: 14px;
+    }
+  }
+
+  .el-table {
+    flex-grow: 1;
+    ::v-deep .el-scrollbar__view {
+      height: 100%;
+    }
+  }
+
+  ::v-deep .el-table__body {
+    tbody tr.even_row td {
+      background-color: white;
+    }
+    tbody tr.odd_row td {
+      background-color: rgb(250, 250, 250);
+    }
+    tbody tr.hover-row td {
+      background-color: rgb(245, 247, 250) !important; 
+    }
+    tbody tr td:last-child:not([rowspan="1"]) {
+      border-left: solid rgba(235, 238, 245) 1px;
+    }
+  }
+}
+
+::v-deep .loading_icon {
+  .el-loading-spinner {
+    .el-loading-text {
+      color: #2e64fa;
+    }
+  }
+}
+</style>

+ 71 - 0
src/views/targetImprove/components/TableRowStatus.vue

@@ -0,0 +1,71 @@
+<template>
+  <span class="table_row_status">
+    <span :class="statusNumToName(useStatus)?.themeClass"></span>
+    {{ statusNumToName(useStatus)?.title }}
+  </span>
+</template>
+
+<script>
+
+/*
+interface statusMsgItm {
+  statusFlag:Number | String,
+  title:String,
+  themeClass: 'not_included_icon' | 'no_release_icon' 
+              | 'normal_icon' | 'abnormal_icon' | 'audit_icon' 
+              | 'yes_release_icon' | 'right_icon' | 'ready_close_icon' | 'need_summary_icon'
+}
+*/
+
+export default {
+  name: 'TableRowStatus',
+  props: {
+    useStatus: {
+      type: [String, Number],
+      required: true,
+      default: null
+    },
+    statusMsg: {
+      type: Array, //类型为  statusMsgItm[]
+      required: true,
+      // 引用类型 default 必须是函数
+      default: () => [] 
+    }
+  },
+  methods: {
+    /**
+     * 根据状态值查找对应的配置项
+     * @param {String|Number} useStatus 
+     * @returns {Object}
+     */
+    statusNumToName(useStatus) {
+      if (!this.statusMsg || !this.statusMsg.length) return {};
+      const result = this.statusMsg.find(item => item.statusFlag == useStatus);
+      if (result) {
+        return result;
+      }
+      // 未找到时返回默认空对象,防止模板渲染报错
+      return {
+        title: '',
+        themeClass: ''
+      };
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.table_row_status {
+  display: inline-flex;
+  align-items: center;
+  
+  span:first-child {
+    display: inline-block;
+    margin-right: 4px;
+    // 这里可以定义图标的基础样式,例如宽高
+    width: 6px;
+    height: 6px;
+    border-radius: 50%;
+  }
+}
+</style>

+ 227 - 0
src/views/targetImprove/practice/practiceResults.vue

@@ -0,0 +1,227 @@
+<!-- 自主练习——查看练习结果 -->
+<template>
+    <div class="target_item">
+        <div class="page_search">
+            <div class="search_content">
+                <div class="content_left">
+                    <div class="grade_title">练习记录</div>
+                </div>
+            </div>
+        </div>
+
+        <FiltersItem :filtersData="filtersData"  @selectItem="ChangeFilters"/>
+      
+        <Table class="practice_table" 
+            :currentPage="currentPage" :pageSize="pageSize" :totalNum="totalNum"
+            :tableData="tableData"  :tableColumns="tableColumns">
+            <template v-slot:gradingStatus="{row}">
+                <TableRowStatus :useStatus="row.gradingStatus"
+                    :statusMsg="[
+                        {
+                            statusFlag:0,
+                            title:'未批阅',
+                            themeClass:'need_summary_icon'
+                        },
+                            {
+                            statusFlag:1,
+                            title:'已批阅',
+                            themeClass:'normal_icon'
+                        },
+                        {
+                            statusFlag:2,
+                            title:'批阅中',
+                            themeClass:'no_release_icon'
+                        },
+                    ]">
+                </TableRowStatus>
+            </template>
+            <template v-slot:action="{row}">
+                <div class="table_row_operation">
+                    <el-button type="text" @click="viewDetails(scope.row)">查看</el-button>
+                </div>
+            </template>
+        </Table>
+    </div>
+
+</template>
+
+<script>
+import FiltersItem from "@/components/FiltersItem_ruoyan.vue"//筛选组件
+import Table from "../components/Table.vue";
+import TableRowStatus from "../components/TableRowStatus.vue";
+export default ({
+    components: {
+        FiltersItem,
+        Table,
+        TableRowStatus
+    },
+    data(){
+        return {
+            currentPage:1,
+            pageSize:20,
+            totalNum:0,
+            tableColumns: [
+                {
+                    name: 'practiceTime',      
+                    label: '练习时间',
+                    minWidth: '180',              
+                    hidden: false,
+                    custom: false,
+                },
+                {
+                    name: 'practiceType',     
+                    label: '练习类型',
+                    minWidth: '120',
+                    align: 'center',         
+                    hidden: false,
+                    custom: false,
+                },
+                {
+                    name: 'knowledgeName',     
+                    label: '知识点名称',
+                    minWidth: '150',           
+                    hidden: false,
+                    custom: false,
+                },
+                {
+                    name: 'questionCount',    
+                    label: '试题数量',
+                    minWidth: '100',
+                    align: 'center',
+                    hidden: false,
+                    custom: false,
+                },
+                {
+                    name: 'gradingStatus',   
+                    label: '批阅状态',
+                    minWidth: '120',
+                    align: 'center',
+                    hidden: false,
+                    custom: true,             
+                },
+                {
+                    name: 'preScoreRate',    
+                    label: '练前得分率',
+                    minWidth: '120',
+                    align: 'center',
+                    hidden: false,
+                    custom: false,            
+                },
+                {
+                    name: 'postScoreRate',    
+                    label: '练后得分率',
+                    minWidth: '120',
+                    align: 'center',
+                    hidden: false,
+                    custom: false,
+                },
+                {
+                    name: 'improvement',       
+                    label: '提升情况',
+                    minWidth: '120',
+                    align: 'center',
+                    hidden: false,
+                    custom: true,              
+                },
+                {
+                    name: 'action',       
+                    label: '操作',
+                    minWidth: '100',
+                    fixed: 'right',   
+                    align: 'center',
+                    hidden: false,
+                    custom: true,   
+                }
+            ],
+            tableData: [
+                {
+                    practiceTime: '2023-08-09 16:00:00',
+                    practiceType: '指定练习',
+                    knowledgeName: '一般词语',
+                    questionCount: 3,
+                    // 状态对象,方便 custom 插槽渲染绿点和文字
+                    gradingStatus: 0,
+                    preScoreRate: '64.37%',
+                    postScoreRate: '54.38%',
+                    // 提升情况对象,方便 custom 插槽判断箭头颜色
+                    improvement: { type: 'up', value: '80.37%' },
+                },
+                {
+                    practiceTime: '2023-08-09 15:30:00',
+                    practiceType: '指定练习',
+                    knowledgeName: '句式仿写',
+                    questionCount: 3,
+                    gradingStatus: 1,
+                    preScoreRate: '91.29%',
+                    postScoreRate: '64.37%',
+                    improvement: { type: 'down', value: '89.36%' },
+                },
+                {
+                    practiceTime: '2023-08-09 14:15:00',
+                    practiceType: '指定练习',
+                    knowledgeName: '现代诗歌',
+                    questionCount: 3,
+                    gradingStatus: 2,
+                    preScoreRate: '64.29%',
+                    postScoreRate: '89.36%',
+                    improvement: { type: 'none', value: '0' },
+                }
+            ],
+            filtersData: [
+                {
+                    name: '时间',
+                    value: 'all', // 默认选中项
+                    list: [
+                        { label: '全部', value: 'all' },
+                        { label: '本周', value: 'this_week' },
+                        { label: '最近1月', value: 'last_1_month' },
+                        { label: '最近3月', value: 'last_3_months' },
+                        { label: '自定义', value: 'custom' }
+                    ]
+                },
+                {
+                    name: '类型',
+                    value: 'all', // 默认选中项
+                    list: [
+                        { label: '全部', value: 'all' },
+                        { label: '指定练习', value: 'assigned_practice' },
+                        { label: '自主练习', value: 'self_practice' }
+                    ]
+                }
+            ]
+        }
+    },
+    methods: {
+        // 筛选组件回调
+        ChangeFilters(e) {
+            // console.log('当前选中的信息',e)
+            this.filtersData[e.index].value = e.value;
+        },
+     },
+    computed:{},
+    mounted() {},
+
+})
+
+
+</script>
+
+
+<style lang="scss" scoped>
+
+.page_search{
+    margin-bottom: 16px;
+}
+.practice_table{
+    margin-top: 2px;
+    ::v-deep .el-table {
+        thead{
+            height: 40px !important;
+        }
+        .el-table__cell {
+            height: 40px;
+        }
+    }
+}
+
+</style>