zlwu 1 vuosi sitten
vanhempi
commit
f625777484

+ 10 - 0
backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/domain/XskhDisciplineType.java

@@ -57,6 +57,16 @@ public class XskhDisciplineType extends TenantEntity {
      */
     private java.math.BigDecimal maxScore;
 
+    /**
+     * 是否均化(0-否 1-是)
+     */
+    private String isEqualized;
+
+    /**
+     * 均化阈值
+     */
+    private java.math.BigDecimal equalizedThreshold;
+
     /**
      * 类型说明
      */

+ 10 - 0
backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/domain/XskhRewardType.java

@@ -42,6 +42,16 @@ public class XskhRewardType extends TenantEntity {
      */
     private String description;
 
+    /**
+     * 是否均化(0-否 1-是)
+     */
+    private String isEqualized;
+
+    /**
+     * 均化阈值
+     */
+    private java.math.BigDecimal equalizedThreshold;
+
     /**
      * 状态(0-正常 1-停用)
      */

+ 11 - 0
backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/domain/bo/XskhDisciplineTypeBo.java

@@ -67,6 +67,17 @@ public class XskhDisciplineTypeBo extends BaseEntity {
     @DecimalMax(value = "100.00", message = "最高扣分不能大于100", groups = { AddGroup.class, EditGroup.class })
     private java.math.BigDecimal maxScore;
 
+    /**
+     * 是否均化(0-否 1-是)
+     */
+    private String isEqualized;
+
+    /**
+     * 均化阈值
+     */
+    @DecimalMin(value = "0.00", message = "均化阈值不能小于0", groups = { AddGroup.class, EditGroup.class })
+    private java.math.BigDecimal equalizedThreshold;
+
     /**
      * 类型说明
      */

+ 11 - 0
backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/domain/bo/XskhRewardTypeBo.java

@@ -43,6 +43,17 @@ public class XskhRewardTypeBo extends BaseEntity {
      */
     private String description;
 
+    /**
+     * 是否均化(0-否 1-是)
+     */
+    private String isEqualized;
+
+    /**
+     * 均化阈值
+     */
+    @DecimalMin(value = "0.00", message = "均化阈值不能小于0", groups = { AddGroup.class, EditGroup.class })
+    private java.math.BigDecimal equalizedThreshold;
+
     /**
      * 状态(0-正常 1-停用)
      */

+ 13 - 0
backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/domain/vo/XskhDisciplineTypeVo.java

@@ -70,6 +70,19 @@ public class XskhDisciplineTypeVo implements Serializable {
     @ExcelProperty(value = "最高扣分")
     private java.math.BigDecimal maxScore;
 
+    /**
+     * 是否均化(0-否 1-是)
+     */
+    @ExcelProperty(value = "是否均化", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_yes_no")
+    private String isEqualized;
+
+    /**
+     * 均化阈值
+     */
+    @ExcelProperty(value = "均化阈值")
+    private java.math.BigDecimal equalizedThreshold;
+
     /**
      * 类型说明
      */

+ 13 - 3
backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/domain/vo/XskhRewardTypeVo.java

@@ -12,8 +12,6 @@ import java.io.Serial;
 import java.io.Serializable;
 import java.util.Date;
 
-
-
 /**
  * 学生奖励类型视图对象 xskh_reward_type
  *
@@ -52,6 +50,19 @@ public class XskhRewardTypeVo implements Serializable {
     @ExcelProperty(value = "类型说明")
     private String description;
 
+    /**
+     * 是否均化(0-否 1-是)
+     */
+    @ExcelProperty(value = "是否均化", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "sys_yes_no")
+    private String isEqualized;
+
+    /**
+     * 均化阈值
+     */
+    @ExcelProperty(value = "均化阈值")
+    private java.math.BigDecimal equalizedThreshold;
+
     /**
      * 状态(0-正常 1-停用)
      */
@@ -71,5 +82,4 @@ public class XskhRewardTypeVo implements Serializable {
     @ExcelProperty(value = "删除标志(0-未删除 1-已删除)")
     private Long deleted;
 
-
 }

+ 4 - 0
docs/设计文档/database/学生考核管理/学生考核管理数据库模型.sql

@@ -15,6 +15,8 @@ CREATE TABLE `xskh_discipline_type` (
   `area_type` char(1) DEFAULT '1' COMMENT '区域类型(1-宿舍区违纪 2-教学区违纪)' ,
   `min_score` decimal(5,2) DEFAULT 0.00 COMMENT '最低扣分',
   `max_score` decimal(5,2) DEFAULT 100.00 COMMENT '最高扣分',
+  `is_equalized` char(1) DEFAULT '0' COMMENT '是否均化(0-否 1-是)',
+  `equalized_threshold` decimal(10,2) DEFAULT NULL COMMENT '均化阈值',
   `status` char(1) DEFAULT '0' COMMENT '状态(0-正常 1-停用)',
   `sort_order` int(4) DEFAULT 0 COMMENT '排序号',
   `create_by` bigint(20) DEFAULT NULL COMMENT '创建者',
@@ -134,6 +136,8 @@ CREATE TABLE `xskh_reward_type` (
   `type_code` varchar(50) NOT NULL COMMENT '类型编码',
   `type_name` varchar(100) NOT NULL COMMENT '类型名称',
   `description` varchar(500) DEFAULT NULL COMMENT '类型说明',
+  `is_equalized` char(1) DEFAULT '0' COMMENT '是否均化(0-否 1-是)',
+  `equalized_threshold` decimal(10,2) DEFAULT NULL COMMENT '均化阈值',
   `status` char(1) DEFAULT '0' COMMENT '状态(0-正常 1-停用)',
   `sort_order` int(4) DEFAULT 0 COMMENT '排序号',
   `create_by` bigint(20) DEFAULT NULL COMMENT '创建者',

+ 20 - 0
web/src/api/xskh/disciplineType/disciplineType/types.ts

@@ -34,6 +34,16 @@ export interface DisciplineTypeVO {
    */
   maxScore: number;
 
+  /**
+   * 是否均化(0-否 1-是)
+   */
+  isEqualized: string;
+
+  /**
+   * 均化阈值
+   */
+  equalizedThreshold: number;
+
   /**
    * 类型说明
    */
@@ -91,6 +101,16 @@ export interface DisciplineTypeForm extends BaseEntity {
    */
   maxScore?: number;
 
+  /**
+   * 是否均化(0-否 1-是)
+   */
+  isEqualized?: string;
+
+  /**
+   * 均化阈值
+   */
+  equalizedThreshold?: number;
+
   /**
    * 类型说明
    */

+ 30 - 0
web/src/api/xskh/rewardType/rewardType/types.ts

@@ -19,6 +19,16 @@ export interface RewardTypeVO {
    */
   description: string;
 
+  /**
+   * 是否均化(0-否 1-是)
+   */
+  isEqualized: string;
+
+  /**
+   * 均化阈值
+   */
+  equalizedThreshold: number;
+
   /**
    * 状态(0-正常 1-停用)
    */
@@ -56,6 +66,16 @@ export interface RewardTypeForm extends BaseEntity {
    */
   description?: string;
 
+  /**
+   * 是否均化(0-否 1-是)
+   */
+  isEqualized?: string;
+
+  /**
+   * 均化阈值
+   */
+  equalizedThreshold?: number;
+
   /**
    * 状态(0-正常 1-停用)
    */
@@ -88,6 +108,16 @@ export interface RewardTypeQuery extends PageQuery {
    */
   description?: string;
 
+  /**
+   * 是否均化(0-否 1-是)
+   */
+  isEqualized?: string;
+
+  /**
+   * 均化阈值
+   */
+  equalizedThreshold?: number;
+
   /**
    * 状态(0-正常 1-停用)
    */

+ 59 - 4
web/src/views/xskh/disciplineType/index.vue

@@ -3,7 +3,7 @@
     <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
       <div v-show="showSearch" class="mb-[10px]">
         <el-card shadow="hover">
-          <el-form ref="queryFormRef" :model="queryParams">
+          <el-form ref="queryFormRef" :model="queryParams" label-width="80px">
             <el-row :gutter="20">
               <el-col :span="6">
                 <el-form-item label="类型编码" prop="typeCode">
@@ -113,6 +113,17 @@
           </template>
         </el-table-column>
         <el-table-column label="类型说明" align="center" prop="remark" />
+        <el-table-column label="是否均化" align="center" prop="isEqualized">
+          <template #default="scope">
+            <dict-tag :options="sys_yesno" :value="scope.row.isEqualized" />
+          </template>
+        </el-table-column>
+        <el-table-column label="均化阈值" align="center" prop="equalizedThreshold">
+          <template #default="scope">
+            <span v-if="scope.row.isEqualized === '1' && scope.row.equalizedThreshold"> {{ scope.row.equalizedThreshold }}分 </span>
+            <span v-else>-</span>
+          </template>
+        </el-table-column>
         <el-table-column label="状态" align="center" prop="status">
           <template #default="scope">
             <dict-tag :options="sys_msg_status" :value="scope.row.status" />
@@ -191,6 +202,22 @@
         <el-form-item label="类型说明" prop="remark">
           <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
         </el-form-item>
+        <el-form-item label="是否均化" prop="isEqualized">
+          <el-radio-group v-model="form.isEqualized">
+            <el-radio v-for="dict in sys_yesno" :key="dict.value" :value="dict.value">{{ dict.label }}</el-radio>
+          </el-radio-group>
+          <div class="form-tip">
+            <el-text size="small" type="info">启用均化后,同一学生在设定时间内的相同违纪将按阈值进行分数调整</el-text>
+          </div>
+        </el-form-item>
+        <el-form-item label="均化阈值" prop="equalizedThreshold" v-show="form.isEqualized === '1'">
+          <el-input v-model="form.equalizedThreshold" placeholder="请输入均化阈值">
+            <template #append>分</template>
+          </el-input>
+          <div class="form-tip">
+            <el-text size="small" type="info">当累计扣分超过此阈值时,其他学生相同违纪的扣分将进行递减处理</el-text>
+          </div>
+        </el-form-item>
         <el-form-item label="状态" prop="status">
           <el-radio-group v-model="form.status">
             <el-radio v-for="dict in sys_msg_status" :key="dict.value" :value="dict.value">{{ dict.label }}</el-radio>
@@ -225,8 +252,8 @@ import {
 import { DisciplineTypeVO, DisciplineTypeQuery, DisciplineTypeForm } from '@/api/xskh/disciplineType/disciplineType/types';
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const { student_discipline_category, sys_msg_status, discipline_area_type } = toRefs<any>(
-  proxy?.useDict('student_discipline_category', 'sys_msg_status', 'discipline_area_type')
+const { student_discipline_category, sys_msg_status, discipline_area_type, sys_yesno } = toRefs<any>(
+  proxy?.useDict('student_discipline_category', 'sys_msg_status', 'discipline_area_type', 'sys_yesno')
 );
 
 const disciplineTypeList = ref<DisciplineTypeVO[]>([]);
@@ -255,7 +282,9 @@ const initFormData: DisciplineTypeForm = {
   minScore: 0, // 默认最低扣分
   maxScore: 100, // 默认最高扣分
   remark: undefined,
-  status: undefined,
+  isEqualized: '0', // 默认不启用均化
+  equalizedThreshold: undefined,
+  status: '0', // 默认启用状态(正常)
   sortOrder: undefined,
   deleted: undefined
 };
@@ -319,6 +348,32 @@ const data = reactive<PageData<DisciplineTypeForm, DisciplineTypeQuery>>({
         },
         trigger: 'blur'
       }
+    ],
+    equalizedThreshold: [
+      {
+        pattern: /^(0|[1-9]\d*)(\.\d{1,2})?$/,
+        message: '请输入有效的数字(支持最多2位小数)',
+        trigger: 'blur'
+      },
+      {
+        validator: (rule: any, value: any, callback: any) => {
+          if (form.value.isEqualized === '1') {
+            if (!value && value !== 0) {
+              callback(new Error('启用均化时,均化阈值不能为空'));
+              return;
+            }
+            const numValue = parseFloat(value);
+            if (isNaN(numValue) || numValue < 0) {
+              callback(new Error('均化阈值必须大于等于0'));
+            } else {
+              callback();
+            }
+          } else {
+            callback();
+          }
+        },
+        trigger: 'blur'
+      }
     ]
   }
 });

+ 66 - 3
web/src/views/xskh/rewardType/index.vue

@@ -62,6 +62,17 @@
         <el-table-column label="类型编码" align="center" prop="typeCode" />
         <el-table-column label="类型名称" align="center" prop="typeName" />
         <el-table-column label="类型说明" align="center" prop="description" />
+        <el-table-column label="是否均化" align="center" prop="isEqualized">
+          <template #default="scope">
+            <dict-tag :options="sys_yesno" :value="scope.row.isEqualized" />
+          </template>
+        </el-table-column>
+        <el-table-column label="均化阈值" align="center" prop="equalizedThreshold">
+          <template #default="scope">
+            <span v-if="scope.row.isEqualized === '1' && scope.row.equalizedThreshold"> {{ scope.row.equalizedThreshold }}分 </span>
+            <span v-else>-</span>
+          </template>
+        </el-table-column>
         <el-table-column label="状态" align="center" prop="status">
           <template #default="scope">
             <dict-tag :options="sys_msg_status" :value="scope.row.status" />
@@ -95,6 +106,22 @@
         <el-form-item label="类型说明" prop="description">
           <el-input v-model="form.description" type="textarea" placeholder="请输入内容" />
         </el-form-item>
+        <el-form-item label="是否均化" prop="isEqualized">
+          <el-radio-group v-model="form.isEqualized">
+            <el-radio v-for="dict in sys_yesno" :key="dict.value" :value="dict.value">{{ dict.label }}</el-radio>
+          </el-radio-group>
+          <div class="form-tip">
+            <el-text size="small" type="info">启用均化后,同一学生在设定时间内的相同奖励将按阈值进行分数调整</el-text>
+          </div>
+        </el-form-item>
+        <el-form-item label="均化阈值" prop="equalizedThreshold" v-show="form.isEqualized === '1'">
+          <el-input v-model="form.equalizedThreshold" placeholder="请输入均化阈值">
+            <template #append>分</template>
+          </el-input>
+          <div class="form-tip">
+            <el-text size="small" type="info">当累计加分超过此阈值时,其他学生相同奖励的加分将进行递减处理</el-text>
+          </div>
+        </el-form-item>
         <el-form-item label="状态" prop="status">
           <el-select v-model="form.status" placeholder="请选择状态">
             <el-option v-for="dict in sys_msg_status" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
@@ -118,11 +145,12 @@
 </template>
 
 <script setup name="RewardType" lang="ts">
+import { ref, reactive, toRefs, getCurrentInstance, onMounted, ComponentInternalInstance } from 'vue';
 import { listRewardType, getRewardType, delRewardType, addRewardType, updateRewardType } from '@/api/xskh/rewardType/rewardType';
 import { RewardTypeVO, RewardTypeQuery, RewardTypeForm } from '@/api/xskh/rewardType/rewardType/types';
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const { sys_msg_status } = toRefs<any>(proxy?.useDict('sys_msg_status'));
+const { sys_msg_status, sys_yesno } = toRefs<any>(proxy?.useDict('sys_msg_status', 'sys_yesno'));
 
 const rewardTypeList = ref<RewardTypeVO[]>([]);
 const buttonLoading = ref(false);
@@ -146,7 +174,9 @@ const initFormData: RewardTypeForm = {
   typeCode: undefined,
   typeName: undefined,
   description: undefined,
-  status: undefined,
+  isEqualized: '0', // 默认不启用均化
+  equalizedThreshold: undefined,
+  status: '0', // 默认启用状态(正常)
   sortOrder: undefined,
   deleted: undefined
 };
@@ -166,7 +196,33 @@ const data = reactive<PageData<RewardTypeForm, RewardTypeQuery>>({
   rules: {
     id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }],
     typeCode: [{ required: true, message: '类型编码不能为空', trigger: 'blur' }],
-    typeName: [{ required: true, message: '类型名称不能为空', trigger: 'blur' }]
+    typeName: [{ required: true, message: '类型名称不能为空', trigger: 'blur' }],
+    equalizedThreshold: [
+      {
+        pattern: /^(0|[1-9]\d*)(\.\d{1,2})?$/,
+        message: '请输入有效的数字(支持最多2位小数)',
+        trigger: 'blur'
+      },
+      {
+        validator: (rule: any, value: any, callback: any) => {
+          if (form.value.isEqualized === '1') {
+            if (!value && value !== '0') {
+              callback(new Error('启用均化时,均化阈值不能为空'));
+              return;
+            }
+            const numValue = parseFloat(value);
+            if (isNaN(numValue) || numValue < 0) {
+              callback(new Error('均化阈值必须大于等于0'));
+            } else {
+              callback();
+            }
+          } else {
+            callback();
+          }
+        },
+        trigger: 'blur'
+      }
+    ]
   }
 });
 
@@ -270,3 +326,10 @@ onMounted(() => {
   getList();
 });
 </script>
+
+<style scoped>
+/* 表单提示样式 */
+.form-tip {
+  margin-top: 5px;
+}
+</style>