Explorar o código

feat: PC 活动分类支持多选

活动表单 (add.vue):
- 活动分类字段由单选 <el-select> 改为 <el-select multiple>
- 新增 categoryIdsArr 数组字段,加载时从后端 CSV 解析,
  提交前 syncCategoryIds() 同步为 categoryId(主) + categoryIds(CSV)
- 校验规则:至少选 1 个分类
- 保留 categoryId 单值字段作主分类,JOIN 不变

活动列表 (list.vue):
- 筛选条件中"活动分类"改为多选
- queryParams.categoryIds: []
- 重置时清空

后端配合 (ActivityDao.xml):
- getById SELECT 增加 t.category_ids
- 列表查询(getPageByApp / getPageByWeb)优先用 params.categoryIds 列表,
  每个值用 OR (category_id = X OR FIND_IN_SET(X, category_ids)) 展开;
  单值 categoryId 仍兼容(小程序端 allActivity.vue 暂未升级)

Co-Authored-By: MiniMax <noreply@MiniMax.ai>
Developer hai 1 mes
pai
achega
53cce67d0f
Modificáronse 3 ficheiros con 29 adicións e 3 borrados
  1. BIN=BIN
      dist.zip
  2. 26 2
      src/views/modules/activity/add.vue
  3. 3 1
      src/views/modules/activity/list.vue

BIN=BIN
dist.zip


+ 26 - 2
src/views/modules/activity/add.vue

@@ -20,8 +20,8 @@
                             <el-option v-for="item in typeOptions" :key="item.id" :label="item.typeName" :value="item.id"></el-option>
                             <el-option v-for="item in typeOptions" :key="item.id" :label="item.typeName" :value="item.id"></el-option>
                         </el-select>
                         </el-select>
                     </el-form-item>
                     </el-form-item>
-                    <el-form-item label="活动分类" prop="categoryId">
-                        <el-select v-model="basicForm.categoryId" placeholder="请选择活动分类" class="select-box" style="width: 440px;">
+                    <el-form-item label="活动分类" prop="categoryIdsArr">
+                        <el-select v-model="basicForm.categoryIdsArr" placeholder="请选择活动分类(可多选)" class="select-box" style="width: 440px;" multiple collapse-tags>
                             <el-option v-for="item in categoryOptions" :key="item.id" :label="item.categoryName" :value="item.id"></el-option>
                             <el-option v-for="item in categoryOptions" :key="item.id" :label="item.categoryName" :value="item.id"></el-option>
                         </el-select>
                         </el-select>
                     </el-form-item>
                     </el-form-item>
@@ -234,6 +234,8 @@ const getInitialBasicForm = () => ({
   id: '',
   id: '',
   typeId: '',
   typeId: '',
   categoryId: '',
   categoryId: '',
+  categoryIds: '',
+  categoryIdsArr: [],
   activityName: '',
   activityName: '',
   signupStartEnd: [],
   signupStartEnd: [],
   signupStartTime: '',
   signupStartTime: '',
@@ -302,6 +304,9 @@ export default {
         categoryId: [
         categoryId: [
           { required: true, message: '请选择活动分类', trigger: 'change' }
           { required: true, message: '请选择活动分类', trigger: 'change' }
         ],
         ],
+        categoryIdsArr: [
+          { required: true, type: 'array', min: 1, message: '请选择至少一个活动分类', trigger: 'change' }
+        ],
         activityName: [
         activityName: [
           { required: true, message: '请输入活动名称', trigger: 'blur' }
           { required: true, message: '请输入活动名称', trigger: 'blur' }
         ],
         ],
@@ -424,6 +429,14 @@ export default {
         if (res.code !== 0) return this.$message.error(res.msg)
         if (res.code !== 0) return this.$message.error(res.msg)
         // this.basicForm = { ...this.basicForm, ...res.data }
         // this.basicForm = { ...this.basicForm, ...res.data }
         this.updateObjectFromSource(this.basicForm, res.data)
         this.updateObjectFromSource(this.basicForm, res.data)
+        // 解析后端存的 CSV(category_ids)到数组供 el-select multiple 使用
+        if (res.data.categoryIds) {
+          this.basicForm.categoryIdsArr = res.data.categoryIds.split(',').map(Number).filter(n => !isNaN(n))
+        } else if (res.data.categoryId) {
+          this.basicForm.categoryIdsArr = [res.data.categoryId]
+        } else {
+          this.basicForm.categoryIdsArr = []
+        }
         this.activityDetailsTemp = res.data.activityDetails
         this.activityDetailsTemp = res.data.activityDetails
         this.basicForm.signupStartEnd = [this.basicForm.signupStartTime, this.basicForm.signupEndTime]
         this.basicForm.signupStartEnd = [this.basicForm.signupStartTime, this.basicForm.signupEndTime]
         this.basicForm.activityStartEnd = [this.basicForm.activityStartTime, this.basicForm.activityEndTime]
         this.basicForm.activityStartEnd = [this.basicForm.activityStartTime, this.basicForm.activityEndTime]
@@ -464,6 +477,13 @@ export default {
     getEditor (val) {
     getEditor (val) {
       this.basicForm.activityDetails = val
       this.basicForm.activityDetails = val
     },
     },
+    // 把 el-select multiple 的数组(categoryIdsArr)同步到后端期望的字段:
+    // categoryId = 第一个(主分类,兼容 JOIN), categoryIds = CSV(供筛选/详情)
+    syncCategoryIds () {
+      const arr = this.basicForm.categoryIdsArr || []
+      this.basicForm.categoryId = arr.length > 0 ? arr[0] : null
+      this.basicForm.categoryIds = arr.join(',')
+    },
     getTypeOptions () {
     getTypeOptions () {
       this.$http.get('/core/activity/type/page', { params: { page: 1, limit: -1 } }).then(res => {
       this.$http.get('/core/activity/type/page', { params: { page: 1, limit: -1 } }).then(res => {
         this.typeOptions = res.data.data.list.filter(l => l.enable === 1) || []
         this.typeOptions = res.data.data.list.filter(l => l.enable === 1) || []
@@ -623,6 +643,8 @@ export default {
       })
       })
     },
     },
     handleTempSave () {
     handleTempSave () {
+      // 同步 categoryIdsArr 到 categoryId(主分类)/categoryIds(CSV)字段再校验
+      this.syncCategoryIds()
       if (this.basicForm.signupStartTime && this.basicForm.signupEndTime && (Date.parse(this.basicForm.signupStartTime) > Date.parse(this.basicForm.signupEndTime))) return this.$message.error('报名结束时间不能小于报名开始时间')
       if (this.basicForm.signupStartTime && this.basicForm.signupEndTime && (Date.parse(this.basicForm.signupStartTime) > Date.parse(this.basicForm.signupEndTime))) return this.$message.error('报名结束时间不能小于报名开始时间')
       if (this.basicForm.signupEndTime && (Date.parse(this.basicForm.signupEndTime) < Date.parse(new Date()))) return this.$message.error('报名结束时间不能小于当前时间')
       if (this.basicForm.signupEndTime && (Date.parse(this.basicForm.signupEndTime) < Date.parse(new Date()))) return this.$message.error('报名结束时间不能小于当前时间')
       if (this.basicForm.signupEndTime && this.basicForm.activityStartTime && (Date.parse(this.basicForm.signupEndTime) > Date.parse(this.basicForm.activityStartTime))) return this.$message.error('活动开始时间不能小于报名结束时间')
       if (this.basicForm.signupEndTime && this.basicForm.activityStartTime && (Date.parse(this.basicForm.signupEndTime) > Date.parse(this.basicForm.activityStartTime))) return this.$message.error('活动开始时间不能小于报名结束时间')
@@ -664,6 +686,8 @@ export default {
       }).catch(() => { this.autoSaving = false })
       }).catch(() => { this.autoSaving = false })
     },
     },
     handleSave () {
     handleSave () {
+      // 同步 categoryIdsArr 到 categoryId(主分类)/categoryIds(CSV)字段再校验
+      this.syncCategoryIds()
       this.$refs.moreRef.validate(valid => {
       this.$refs.moreRef.validate(valid => {
         if (valid) {
         if (valid) {
           if (this.moreForm.recruitmentFlag === 1) {
           if (this.moreForm.recruitmentFlag === 1) {

+ 3 - 1
src/views/modules/activity/list.vue

@@ -11,7 +11,7 @@
             </el-col>
             </el-col>
             <el-col :span="6" class="adfac">
             <el-col :span="6" class="adfac">
               <div class="query_text">活动分类</div>
               <div class="query_text">活动分类</div>
-              <el-select v-model="queryParams.categoryId" placeholder="请选择活动分类" class="select-box" style="width: 100%;" clearable>
+              <el-select v-model="queryParams.categoryIds" placeholder="请选择活动分类(可多选)" class="select-box" style="width: 100%;" multiple collapse-tags clearable>
                 <el-option v-for="item in categoryOptions" :key="item.id" :label="item.categoryName" :value="item.id"></el-option>
                 <el-option v-for="item in categoryOptions" :key="item.id" :label="item.categoryName" :value="item.id"></el-option>
               </el-select>
               </el-select>
             </el-col>
             </el-col>
@@ -132,6 +132,7 @@ export default {
         limit: 10,
         limit: 10,
         typeId: '',
         typeId: '',
         categoryId: '',
         categoryId: '',
+        categoryIds: [],
         activityName: '',
         activityName: '',
         startEndDate: '',
         startEndDate: '',
         startDate: '',
         startDate: '',
@@ -168,6 +169,7 @@ export default {
         limit: 10,
         limit: 10,
         typeId: '',
         typeId: '',
         categoryId: '',
         categoryId: '',
+        categoryIds: [],
         activityName: '',
         activityName: '',
         startEndDate: '',
         startEndDate: '',
         startDate: '',
         startDate: '',