zhou преди 3 седмици
родител
ревизия
9461ed7b90

+ 17 - 9
src/components/ImageOrUrlInput/index.vue

@@ -37,7 +37,7 @@
         </div>
       </el-tab-pane>
       
-             <el-tab-pane label="输入链接" name="url">
+      <el-tab-pane label="输入链接" name="url">
          <div class="url-container">
            <el-input
              v-model="urlValue"
@@ -52,7 +52,7 @@
              <el-alert title="请输入有效的链接地址" type="warning" :closable="false" />
            </div>
          </div>
-       </el-tab-pane>
+      </el-tab-pane>
     </el-tabs>
 
     <el-dialog v-model="dialogVisible" title="预览" width="800px" append-to-body>
@@ -129,15 +129,17 @@ const validateUrl = (url: string) => {
 const handleUrlInput = (value: string) => {
   urlValue.value = value;
   isValidUrl.value = validateUrl(value);
-  if (isValidUrl.value) {
-    emit('update:modelValue', value);
-  }
 };
 
-// 处理URL失焦
+// 修改: 在blur事件中处理modelValue的更新,无论URL是否合法
 const handleUrlBlur = () => {
-  if (urlValue.value && isValidUrl.value) {
-    emit('update:modelValue', urlValue.value);
+  if (urlValue.value) {
+    emit('update:modelValue', urlValue.value); // 直接更新modelValue,无论URL是否合法
+    if (!isValidUrl.value) {
+      proxy?.$modal.msgWarning('请输入有效的链接地址');
+    }
+  } else {
+    emit('update:modelValue', ''); // 如果urlValue为空,清空modelValue
   }
 };
 
@@ -152,7 +154,7 @@ const handleTabClick = () => {
   }
 };
 
-// 监听 modelValue 变化
+// 修改: 监听 modelValue 变化,正确设置 urlValue
 watch(
   () => props.modelValue,
   (val: string) => {
@@ -167,7 +169,13 @@ watch(
         if (/^\d+$/.test(val)) {
           activeTab.value = 'upload';
           loadOssData(val);
+        }else{
+          // 如果不是ossID可能是普通文本,也显示在输入框中
+          activeTab.value = 'url';
+          urlValue.value = val;
+          isValidUrl.value = false;
         }
+        
       }
     } else {
       urlValue.value = '';

+ 10 - 3
src/components/ImageUploadCropper/index.vue

@@ -253,8 +253,15 @@ watch(
       if (Array.isArray(val)) {
         list = val as OssVO[];
       } else {
-        const res = await listByIds(val);
-        list = res.data;
+        // 判断是否为URL路径(包含http/https协议或相对路径)
+        if (typeof val === 'string' && (val.startsWith('http') || val.startsWith('/'))) {
+          // 直接使用URL路径作为图片显示
+          list = [{ url: val } as OssVO];
+        } else {
+          // 原有逻辑,调用API获取信息
+          const res = await listByIds(val);
+          list = res.data;
+        }
       }
       // 然后将数组转为对象数组
       fileList.value = list.map((item) => {
@@ -264,7 +271,7 @@ watch(
           itemData = { name: item, url: item };
         } else {
           // 此处name使用ossId 防止删除出现重名
-          itemData = { name: item.ossId, url: item.url, ossId: item.ossId };
+          itemData = { name: item.ossId || item.url, url: item.url, ossId: item.ossId };
         }
         return itemData;
       });

+ 12 - 6
src/views/system/gameEventConfig/index.vue

@@ -15,7 +15,7 @@
             </el-form-item>
             <el-form-item label="是否启用" prop="isEnabled">
               <el-select v-model="queryParams.isEnabled" placeholder="请选择是否启用" clearable >
-                <el-option v-for="dict in sys_yes_no" :key="dict.value" :label="dict.label" :value="dict.value"/>
+                <el-option v-for="dict in game_yes_no" :key="dict.value" :label="dict.label" :value="dict.value"/>
               </el-select>
             </el-form-item>
             <el-form-item label="状态" prop="status">
@@ -61,7 +61,7 @@
         <el-table-column label="配置描述" align="center" prop="configDesc" />
         <el-table-column label="是否启用" align="center" prop="isEnabled">
           <template #default="scope">
-            <dict-tag :options="sys_yes_no" :value="scope.row.isEnabled"/>
+            <dict-tag :options="game_yes_no" :value="scope.row.isEnabled"/>
           </template>
         </el-table-column>
         <el-table-column label="状态" align="center" prop="status">
@@ -102,7 +102,7 @@
         <el-form-item label="是否启用" prop="isEnabled">
           <el-radio-group v-model="form.isEnabled">
             <el-radio
-              v-for="dict in sys_yes_no"
+              v-for="dict in game_yes_no"
               :key="dict.value"
               :value="dict.value"
             >{{dict.label}}</el-radio>
@@ -136,7 +136,7 @@ import { listGameEventConfig, getGameEventConfig, delGameEventConfig, addGameEve
 import { GameEventConfigVO, GameEventConfigQuery, GameEventConfigForm } from '@/api/system/gameEventConfig/types';
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const { game_event_status, sys_yes_no } = toRefs<any>(proxy?.useDict('game_event_status', 'sys_yes_no'));
+const { game_event_status, game_yes_no } = toRefs<any>(proxy?.useDict('game_event_status', 'game_yes_no'));
 
 const gameEventConfigList = ref<GameEventConfigVO[]>([]);
 const buttonLoading = ref(false);
@@ -180,9 +180,15 @@ const data = reactive<PageData<GameEventConfigForm, GameEventConfigQuery>>({
     }
   },
   rules: {
-    configValue: [
-      { required: true, message: "配置值不能为空", trigger: "blur" }
+    eventId: [
+      { required: true, message: "赛事ID不能为空", trigger: "blur" }
     ],
+    configKey: [
+      { required: true, message: "配置键不能为空", trigger: "blur" }
+    ],
+    // configValue: [
+    //   { required: true, message: "配置值不能为空", trigger: "blur" }
+    // ],
     configDesc: [
       { required: true, message: "配置描述不能为空", trigger: "blur" }
     ],

+ 87 - 10
src/views/system/gameEventSchedule/index.vue

@@ -49,15 +49,15 @@
           <el-tab-pane
             v-for="group in projectGroups"
             :key="group.type"
-            :label="`${group.type}项目 (${group.projects.length})`"
+            :label="`${group.type} (${group.projects.length})`"
             :name="group.type"
           >
             <el-table :data="group.projects" border class="mb-4">
               <el-table-column label="项目名称" prop="projectName" width="150" />
-              <el-table-column label="项目组别" prop="groupType" width="120" />
+              <!-- <el-table-column label="项目组别" prop="groupType" width="120" /> -->
               <el-table-column label="项目类型" width="100">
                 <template #default="scope">
-                  {{ scope.row.projectType === '0' ? '个人' : '团体' }}
+                  <dict-tag :options="game_project_type" :value="scope.row.projectType || ''" />
                 </template>
               </el-table-column>
               <el-table-column label="比赛日期" width="180">
@@ -99,7 +99,7 @@
                   <el-input v-model="scope.row.location" placeholder="输入比赛场地" />
                 </template>
               </el-table-column>
-              <el-table-column label="分组数" width="100">
+              <el-table-column label="分组数" width="150">
                 <template #default="scope">
                   <el-input-number
                     v-model="scope.row.groupNum"
@@ -110,7 +110,7 @@
                   />
                 </template>
               </el-table-column>
-              <el-table-column label="每组人数" width="100">
+              <el-table-column label="每组人数" width="150">
                 <template #default="scope">
                   <el-input-number
                     v-model="scope.row.participateNum"
@@ -146,13 +146,25 @@
           <el-table-column label="项目名称" prop="projectName" width="150" />
           <el-table-column label="项目类型" width="100">
             <template #default="scope">
-              {{ scope.row.projectType === '0' ? '个人' : '团体' }}
+              <dict-tag :options="game_project_type" :value="scope.row.projectType || ''" />
             </template>
           </el-table-column>
-          <el-table-column label="项目组别" prop="groupType" width="120" />
+          <!-- <el-table-column label="项目组别" prop="groupType" width="120" /> -->
           <el-table-column label="比赛场地" prop="location" width="120" />
           <el-table-column label="分组数" prop="groupNum" width="80" />
           <el-table-column label="每组人数" prop="participateNum" width="100" />
+          <el-table-column label="操作" width="100">
+            <template #default="scope">
+              <el-button 
+                type="danger" 
+                size="small" 
+                @click="deleteSchedule(scope.row)"
+                v-hasPermi="['system:gameeventproject:remove']"
+              >
+                删除
+              </el-button>
+            </template>
+          </el-table-column>
         </el-table>
       </el-card>
     </el-card>
@@ -167,6 +179,10 @@ import { GameEventVO } from '@/api/system/gameEvent/types'
 import { GameEventProjectVO } from '@/api/system/gameEventProject/types'
 import { parseTime } from '@/utils/ruoyi'
 import { ElMessage, ElMessageBox } from 'element-plus'
+import DictTag from '@/components/DictTag/index.vue'
+
+const { proxy } = getCurrentInstance() as any
+const { game_project_type } = toRefs<any>(proxy?.useDict('game_project_type'));
 
 // 赛事列表
 const eventList = ref<GameEventVO[]>([])
@@ -189,6 +205,13 @@ const loadEventList = async () => {
       pageSize: 1000
     })
     eventList.value = res.rows
+    
+    // 如果赛事列表不为空,默认选择第一条赛事
+    if (eventList.value.length > 0 && !selectedEventId.value) {
+      selectedEventId.value = eventList.value[0].eventId
+      // 自动加载第一条赛事的数据
+      await loadEventData(selectedEventId.value)
+    }
   } catch (error) {
     ElMessage.error('加载赛事列表失败')
   }
@@ -202,8 +225,8 @@ const loadEventData = async (eventId: string | number) => {
     // 获取赛事基本信息
     const eventRes = await listGameEvent({
       eventId: eventId,
-      pageNum: 0,
-      pageSize: 0
+      pageNum: 1,
+      pageSize: 1000
     })
     currentEvent.value = eventRes.rows[0] || ({} as GameEventVO)
     
@@ -217,7 +240,9 @@ const loadEventData = async (eventId: string | number) => {
     // 按项目类型分组
     const groups: { [key: string]: GameEventProjectVO[] } = {}
     projectRes.rows.forEach(project => {
-      const type = project.projectType === '0' ? '个人' : '团体'
+      // 使用字典标签作为分组键
+      const projectTypeDict = game_project_type.value.find((dict: any) => dict.value === project.projectType)
+      const type = projectTypeDict ? projectTypeDict.label : '未知类型'
       if (!groups[type]) {
         groups[type] = []
       }
@@ -321,6 +346,58 @@ const saveSchedule = async () => {
   }
 }
 
+// 删除日程安排
+const deleteSchedule = async (project: GameEventProjectVO) => {
+  try {
+    await ElMessageBox.confirm(
+      `确定要删除项目 "${project.projectName}" 的日程安排吗?`,
+      '删除确认',
+      {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }
+    )
+    
+    // 清除该项目的时间安排
+    await updateGameEventProject({
+      projectId: project.projectId,
+      startTime: null,
+      endTime: null,
+      location: project.location,
+      groupNum: project.groupNum,
+      participateNum: project.participateNum,
+      //其他字段
+      eventId: selectedEventId.value,
+      projectName: project.projectName,
+      projectType: project.projectType,
+      groupType: project.groupType,
+    } as any)
+    
+    // 更新本地数据
+    const group = projectGroups.value.find(g => {
+      const projectTypeDict = game_project_type.value.find((dict: any) => dict.value === project.projectType)
+      const type = projectTypeDict ? projectTypeDict.label : '未知类型'
+      return g.type === type
+    })
+    if (group) {
+      const projectItem = group.projects.find(p => p.projectId === project.projectId)
+      if (projectItem) {
+        projectItem.scheduleDate = ''
+        projectItem.startTime = ''
+        projectItem.endTime = ''
+      }
+    }
+    
+    ElMessage.success('日程安排删除成功')
+    updateScheduleData()
+  } catch (error) {
+    if (error !== 'cancel') {
+      ElMessage.error('删除日程安排失败')
+    }
+  }
+}
+
 // 导出日程表
 const exportSchedule = () => {
   if (scheduleData.value.length === 0) {