jinxia.mo 2 недель назад
Родитель
Сommit
bc3b1bd060

+ 10 - 27
back-ui/src/api/dz/cards.js

@@ -59,29 +59,14 @@ export function issueCard(institutionId, type, count) {
 }
 
 // 分配卡
-export function assignCard(
-  cardType,
-  agentId,
-  begin,
-  end,
-  location,
-  examType,
-  schoolId,
-  days
-) {
+export function assignCard(params) {
+  // 支持两种方式:
+  // 1. 通过cardIds(选中的卡片ID列表)
+  // 2. 通过begin和end(卡号段)
   return request({
     url: "/dz/cards/assignCard",
     method: "post",
-    params: {
-      cardType,
-      agentId,
-      begin,
-      end,
-      location,
-      examType,
-      schoolId,
-      days,
-    },
+    params: params,
   });
 }
 
@@ -196,16 +181,14 @@ export function getCampusSchoolList(query) {
 }
 
 // 关联校区
-export function associateCampus(beginCardNo, endCardNo, campusId, campusClassId) {
+export function associateCampus(params) {
+  // 支持两种方式:
+  // 1. 通过cardIds(选中的卡片ID列表)
+  // 2. 通过begin和end(卡号段)
   return request({
     url: "/dz/cards/changeCampus",
     method: "post",
-    params: {
-      campusId,
-      campusClassId,
-      begin: beginCardNo,
-      end: endCardNo,
-    },
+    params: params,
   });
 }
 

+ 41 - 7
back-ui/src/views/dz/cards/components/AssignDialog.vue

@@ -8,11 +8,16 @@
       <el-form-item label="卡类型" prop="cardType">
         <ie-select v-model="form.cardType" :options="card_type" class="w-[350px]!" clearable />
       </el-form-item>
-      <el-form-item label="卡号段" prop="cardNoRange" required>
+      <el-form-item label="卡号段" prop="cardNoRange" :required="!cardIds || cardIds.length === 0">
         <div class="flex items-center gap-x-3">
-          <el-input v-model="form.begin" type="text" maxlength="8" v-number class="w-[160px]!" placeholder="请输入开始卡号" />
+          <el-input v-model="form.begin" type="text" maxlength="8" v-number class="w-[160px]!" 
+                    placeholder="请输入开始卡号" :disabled="cardIds && cardIds.length > 0" />
           <span class="text-gray-500">-</span>
-          <el-input v-model="form.end" type="text" maxlength="8" v-number class="w-[160px]!" placeholder="请输入结束卡号" />
+          <el-input v-model="form.end" type="text" maxlength="8" v-number class="w-[160px]!" 
+                    placeholder="请输入结束卡号" :disabled="cardIds && cardIds.length > 0" />
+        </div>
+        <div v-if="cardIds && cardIds.length > 0" class="text-sm text-gray-500 mt-1">
+          已选择 {{ cardIds.length }} 张卡片,将使用选中的卡片进行分配
         </div>
       </el-form-item>
       <el-form-item label="代理商" prop="agentId" required>
@@ -65,6 +70,7 @@ const {
 
 const modalRef = ref(null);
 const formRef = ref(null);
+const cardIds = ref(null) // 选中的卡片ID列表
 const defaultForm = {
   deptId: null,
   agentId: null,
@@ -77,8 +83,14 @@ const defaultForm = {
 const form = ref({ ...defaultForm })
 // 自定义验证
 const validateCardNoRange = (rule, value, callback) => {
+  // 如果有选中的卡片ID,则不需要验证卡号段
+  if (cardIds.value && cardIds.value.length > 0) {
+    callback()
+    return
+  }
+  // 如果没有选中卡片,则需要验证卡号段
   if (!form.value.begin || !form.value.end) {
-    callback(new Error('请输入卡号段'))
+    callback(new Error('请输入卡号段或选择卡片'))
   } else if (Number(form.value.begin) > Number(form.value.end)) {
     callback(new Error('开始卡号不能大于结束卡号'))
   } else {
@@ -114,12 +126,15 @@ const rules = ref({
 
 const handleBeforeClose = () => {
   form.value = { ...defaultForm };
+  cardIds.value = null;
   reset();
 }
 
-const open = () => {
+const open = (selectedCardIds = null) => {
   init();
   form.value = { ...defaultForm };
+  // 如果传入了选中的卡片ID列表,则使用它
+  cardIds.value = selectedCardIds && selectedCardIds.length > 0 ? selectedCardIds : null;
   modalRef.value.open()
 }
 const close = () => {
@@ -129,12 +144,31 @@ const emit = defineEmits(['refresh'])
 const handleConfirm = () => {
   formRef.value.validate(async (valid) => {
     if (valid) {
-      let { cardType, agentId, begin, end, location, assignExamType, schoolId, days } = form.value;
+      let { cardType, agentId, location, assignExamType, schoolId, days } = form.value;
       modalRef.value.showLoading()
       if (cardType !== '9') {
         days = undefined;
       }
-      assignCard(cardType, agentId, begin, end, location, assignExamType, schoolId, days).then(res => {
+      
+      // 构建参数对象
+      const params = {
+        cardType,
+        agentId,
+        location,
+        assignExamType,
+        schoolId,
+        days
+      }
+      
+      // 如果有选中的卡片ID,使用cardIds;否则使用begin和end
+      if (cardIds.value && cardIds.value.length > 0) {
+        params.cardIds = Array.isArray(cardIds.value) ? cardIds.value.join(",") : cardIds.value
+      } else {
+        params.begin = form.value.begin
+        params.end = form.value.end
+      }
+      
+      assignCard(params).then(res => {
         proxy.$modal.msgSuccess('分配卡成功')
         close();
         setTimeout(() => {

+ 38 - 6
back-ui/src/views/dz/cards/components/RelateDialog.vue

@@ -2,11 +2,16 @@
   <IeModal title="关联校区" confirmText="确认关联" ref="modalRef" width="500px" @beforeClose="handleBeforeClose"
     @confirm="handleConfirm">
     <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
-      <el-form-item label="卡号段" prop="cardNoRange" required>
+      <el-form-item label="卡号段" prop="cardNoRange" :required="!cardIds || cardIds.length === 0">
         <div class="flex items-center gap-x-3">
-          <el-input v-model="form.begin" type="text" maxlength="8" v-number class="w-[160px]!" placeholder="请输入开始卡号" />
+          <el-input v-model="form.begin" type="text" maxlength="8" v-number class="w-[160px]!" 
+                    placeholder="请输入开始卡号" :disabled="cardIds && cardIds.length > 0" />
           <span class="text-gray-500">-</span>
-          <el-input v-model="form.end" type="text" maxlength="8" v-number class="w-[160px]!" placeholder="请输入结束卡号" />
+          <el-input v-model="form.end" type="text" maxlength="8" v-number class="w-[160px]!" 
+                    placeholder="请输入结束卡号" :disabled="cardIds && cardIds.length > 0" />
+        </div>
+        <div v-if="cardIds && cardIds.length > 0" class="text-sm text-gray-500 mt-1">
+          已选择 {{ cardIds.length }} 张卡片,将使用选中的卡片进行关联
         </div>
       </el-form-item>
       <el-form-item label="校区" prop="campusId" required>
@@ -43,6 +48,7 @@ const selectedCampusClass = ref(null);
 
 const modalRef = ref(null);
 const formRef = ref(null);
+const cardIds = ref(null) // 选中的卡片ID列表
 const form = ref({
   institutionId: null,
   cardType: null,
@@ -50,8 +56,14 @@ const form = ref({
 })
 // 自定义验证
 const validateCardNoRange = (rule, value, callback) => {
+  // 如果有选中的卡片ID,则不需要验证卡号段
+  if (cardIds.value && cardIds.value.length > 0) {
+    callback()
+    return
+  }
+  // 如果没有选中卡片,则需要验证卡号段
   if (!form.value.begin || !form.value.end) {
-    callback(new Error('请输入卡号段'))
+    callback(new Error('请输入卡号段或选择卡片'))
   } else if (Number(form.value.begin) > Number(form.value.end)) {
     callback(new Error('开始卡号不能大于结束卡号'))
   } else {
@@ -87,18 +99,23 @@ const rules = ref({
 
 const handleBeforeClose = () => {
   form.value = {};
+  cardIds.value = null;
   selectedCampusClass.value = null;
   campusClassOptions.value = [];
   reset();
 }
 
 
-const open = () => {
+const open = (selectedCardIds = null) => {
   getCampusList();
   form.value = {};
+  // 如果传入了选中的卡片ID列表,则使用它
+  cardIds.value = selectedCardIds && selectedCardIds.length > 0 ? selectedCardIds : null;
   modalRef.value.open()
 }
 const close = () => {
+  form.value = {};
+  cardIds.value = null;
   selectedCampusClass.value = null;
   campusClassOptions.value = [];
   reset();
@@ -109,7 +126,22 @@ const handleConfirm = () => {
   formRef.value.validate(async (valid) => {
     if (valid) {
       modalRef.value.showLoading()
-      associateCampus(form.value.begin, form.value.end, form.value.campusId, form.value.campusClassId).then(res => {
+      // 如果有选中的卡片ID,使用cardIds;否则使用begin和end
+      const params = {
+        campusId: form.value.campusId,
+        campusClassId: form.value.campusClassId
+      }
+      
+      if (cardIds.value && cardIds.value.length > 0) {
+        // 使用选中的卡片ID列表
+        params.cardIds = Array.isArray(cardIds.value) ? cardIds.value.join(",") : cardIds.value
+      } else {
+        // 使用卡号段
+        params.begin = form.value.begin
+        params.end = form.value.end
+      }
+      
+      associateCampus(params).then(res => {
         proxy.$modal.msgSuccess('关联校区成功')
         close();
         setTimeout(() => {

+ 6 - 2
back-ui/src/views/dz/cards/index.vue

@@ -339,7 +339,9 @@ const handleDeleteBatch = () => {
 
 const relateDialogRef = ref(null);
 const handleRelateCampus = () => {
-  relateDialogRef.value.open()
+  // 如果有选中的卡片,传递cardIds;否则传递null(使用卡号段方式)
+  const selectedCardIds = selectedRows.value.length > 0 ? ids.value : null
+  relateDialogRef.value.open(selectedCardIds)
 }
 
 const openDialogRef = ref(null);
@@ -431,7 +433,9 @@ const handleEdit = () => {
 
 const assignDialogRef = ref(null);
 const handleAssign = () => {
-  assignDialogRef.value.open()
+  // 如果有选中的卡片,传递cardIds;否则传递null(使用卡号段方式)
+  const selectedCardIds = selectedRows.value.length > 0 ? ids.value : null
+  assignDialogRef.value.open(selectedCardIds)
 }
 
 const handleExport = () => {

+ 38 - 2
ie-admin/src/main/java/com/ruoyi/web/controller/dz/DzCardsController.java

@@ -254,8 +254,44 @@ public class DzCardsController extends BaseController
     @PostMapping("/changeCampus")
     @ApiOperation("分配校区")
     @PreAuthorize("@ss.hasPermi('dz:cards:associateCampus')")
-    public AjaxResult changeCampus(@ApiParam("校区") Long campusId, @ApiParam("校区班级") Long campusClassId, @ApiParam("开始号") String begin, @ApiParam("结束号") String end) {
-        return AjaxResult.success(dzCardsService.changeCampus(campusId, campusClassId, begin, end));
+    public AjaxResult changeCampus(@ApiParam("校区") Long campusId, 
+                                   @ApiParam("校区班级") @RequestParam(required = false) Long campusClassId,
+                                   @ApiParam("开始号") @RequestParam(required = false) String begin, 
+                                   @ApiParam("结束号") @RequestParam(required = false) String end,
+                                   @ApiParam("卡片ID列表") @RequestParam(required = false) String cardIds) {
+        // 如果cardIds不为空,使用cardIds方式;否则使用begin和end方式
+        if (StringUtils.isNotBlank(cardIds)) {
+            // 将cardIds字符串转换为Long数组
+            String[] cardIdArray = cardIds.split(",");
+            if (cardIdArray.length == 0) {
+                throw new ValidationException("卡片ID列表不能为空");
+            }
+            Long[] cardIdLongArray = new Long[cardIdArray.length];
+            for (int i = 0; i < cardIdArray.length; i++) {
+                String cardIdStr = cardIdArray[i].trim();
+                if (StringUtils.isBlank(cardIdStr)) {
+                    throw new ValidationException("卡片ID不能为空");
+                }
+                try {
+                    cardIdLongArray[i] = Long.parseLong(cardIdStr);
+                } catch (NumberFormatException e) {
+                    throw new ValidationException("卡片ID格式错误: " + cardIdStr);
+                }
+            }
+            if (cardIdLongArray.length == 0) {
+                throw new ValidationException("卡片ID列表不能为空");
+            }
+            return AjaxResult.success(dzCardsService.changeCampusByCardIds(campusId, campusClassId, cardIdLongArray));
+        } else {
+            // 使用begin和end方式,验证不能为空
+            if (StringUtils.isBlank(begin)) {
+                throw new ValidationException("开始卡号不能为空");
+            }
+            if (StringUtils.isBlank(end)) {
+                throw new ValidationException("结束卡号不能为空");
+            }
+            return AjaxResult.success(dzCardsService.changeCampus(campusId, campusClassId, begin, end));
+        }
     }
 
     @Log(title = "支付", businessType = BusinessType.UPDATE)

+ 10 - 0
ie-system/src/main/java/com/ruoyi/dz/service/IDzCardsService.java

@@ -127,6 +127,16 @@ public interface IDzCardsService
      * @return
      */
     public Boolean changeCampus(Long campusId, Long campusClassId, String beginNo, String endNo);
+    
+    /**
+     * 通过卡片ID列表分配校区
+     * @param campusId
+     * @param campusClassId
+     * @param cardIds
+     * @return
+     */
+    public Boolean changeCampusByCardIds(Long campusId, Long campusClassId, Long[] cardIds);
+    
     public List<DzCards> selectCardsByCardIds(List<Long> cardIds);
 
     /**

+ 23 - 2
ie-system/src/main/java/com/ruoyi/dz/service/impl/DzCardsServiceImpl.java

@@ -3,6 +3,7 @@ package com.ruoyi.dz.service.impl;
 import java.util.*;
 import java.util.function.Function;
 import java.util.stream.Collectors;
+import java.util.Arrays;
 
 import cn.hutool.core.util.RandomUtil;
 import com.fasterxml.jackson.annotation.JsonFormat;
@@ -455,8 +456,14 @@ public class DzCardsServiceImpl implements IDzCardsService
         if(cards.isEmpty()) {
             return false;
         }
+        
+        return changeCampusByCards( campusId,  campusClassId, cards);
+    }
+
+    private Boolean changeCampusByCards(Long campusId, Long campusClassId, List<DzCards> cards) {
         DzCards dzCards = new DzCards();
-        Map<Long, SysUser> userMap = userMapper.selectUserByCardIds(cards.stream().map(DzCards::getCardId).collect(Collectors.toList())).stream() .collect(Collectors.toMap( SysUser::getCardId, user -> user, (existing, replacement) -> existing));
+        Map<Long, SysUser> userMap = userMapper.selectUserByCardIds(cards.stream().map(DzCards::getCardId).collect(Collectors.toList())).stream()
+                .collect(Collectors.toMap(SysUser::getCardId, user -> user, (existing, replacement) -> existing));
         cards.stream().forEach(c -> {
             dzCards.setCardId(c.getCardId());
             dzCards.setCampusId(campusId);
@@ -464,7 +471,7 @@ public class DzCardsServiceImpl implements IDzCardsService
             dzCardsMapper.updateDzCards(dzCards);
 
             SysUser u = userMap.get(c.getCardId());
-            if(null != u) {
+            if (null != u) {
                 LearnStudent upStudent = new LearnStudent();
                 upStudent.setStudentId(u.getUserId());
                 upStudent.setClassId(campusClassId);
@@ -475,6 +482,20 @@ public class DzCardsServiceImpl implements IDzCardsService
         return true;
     }
 
+    @Override
+    public Boolean changeCampusByCardIds(Long campusId, Long campusClassId, Long[] cardIds) {
+        if (cardIds == null || cardIds.length == 0) {
+            return false;
+        }
+        // 通过cardIds获取卡片列表
+        List<Long> cardIdList = Arrays.asList(cardIds);
+        List<DzCards> cards = selectCardsByCardIds(cardIdList);
+        if (CollectionUtils.isEmpty(cards)) {
+            return false;
+        }
+        return changeCampusByCards( campusId,  campusClassId, cards);
+    }
+
     @Override
     public List<DzCards> selectCardsByCardIds(List<Long> cardIds){
         //cardIds转换为数组