Explorar el Código

feat(versionManagement): 优化版本管理功能

- 添加文件上传功能,支持.apk文件
- 更新系统类型和是否强制更新的输入方式,使用单选框
-移除已知问题和系统版本字段
- 优化更新内容字段,使用富文本编辑器
- 调整版本号字段的验证规则
- 优化文件上传后的处理逻辑,自动填充下载链接
fugui001 hace 3 meses
padre
commit
1de6f171ef

+ 2 - 0
src/api/system/business/versionManagement/types.ts

@@ -68,6 +68,8 @@ export interface VersionManagementVO {
    * 更新时间
    */
   updatedAt: string;
+
+  filePath: string;
 }
 
 export interface VersionManagementForm extends BaseEntity {

+ 106 - 20
src/views/system/business/versionManagement/index.vue

@@ -44,7 +44,7 @@
               >删除</el-button
             >
           </el-col>
-<!--          <el-col :span="1.5">
+          <!--          <el-col :span="1.5">
             <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['business:versionManagement:export']">导出</el-button>
           </el-col>-->
           <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
@@ -64,15 +64,15 @@
             </el-tooltip>
           </template>
         </el-table-column>
-        <el-table-column label="已知问题" align="center" width="180">
+<!--        <el-table-column label="已知问题" align="center" width="180">
           <template #default="scope">
             <el-tooltip :content="scope.row.knownIssues" placement="top">
               <span class="truncate">{{ scope.row.knownIssues }}</span>
             </el-tooltip>
           </template>
-        </el-table-column>
+        </el-table-column>-->
         <el-table-column label="操作系统类型" align="center" prop="osType" />
-        <el-table-column label="系统版本" align="center" prop="osSupport" />
+<!--        <el-table-column label="系统版本" align="center" prop="osSupport" />-->
         <el-table-column label="是否强制更新" align="center">
           <template #default="scope">
             {{ formatForceUpdate(scope.row.forceUpdate) }}
@@ -129,6 +129,31 @@
         <el-form-item label="版本名称" prop="versionName">
           <el-input v-model="form.versionName" placeholder="请输入版本名称" />
         </el-form-item>
+
+        <el-form-item label="文件" prop="icon">
+          <div class="upload-container">
+            <el-upload
+              class="upload-icon"
+              action="#"
+              :on-change="handleIconChange"
+              :on-remove="handleIconRemove"
+              :file-list="fileList"
+              :auto-upload="false"
+              :limit="1"
+              accept=".apk"
+            >
+              <template #trigger>
+                <el-button type="primary">点击选择</el-button>
+              </template>
+              <template #tip>
+                <div class="el-upload__tip">
+                  <span v-if="fileList.length > 0">当前已选文件:{{ fileList[0].name }}</span>
+                </div>
+              </template>
+            </el-upload>
+          </div>
+        </el-form-item>
+
         <el-form-item label="下载链接" prop="downloadLink">
           <el-input v-model="form.downloadLink" type="textarea" placeholder="请输入内容" />
         </el-form-item>
@@ -137,27 +162,28 @@
           </el-date-picker>
         </el-form-item>
         <el-form-item label="系统类型" prop="osType">
-          <el-select aria-required="true" v-model="form.osType" placeholder="请选择">
-            <el-option v-for="dict in mobile_sys_type" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
-          </el-select>
+          <el-radio-group v-model="form.osType" size="small">
+            <el-radio v-for="dict in mobile_sys_type" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="是否强制更新" prop="forceUpdate">
+          <el-radio-group v-model="form.forceUpdate" size="small">
+            <el-radio v-for="dict in is_force_update" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
+          </el-radio-group>
         </el-form-item>
         <el-form-item label="更新内容" prop="updateContent">
-          <el-input v-model="form.updateContent" type="textarea" />
+          <editor v-model="form.updateContent" :min-height="192" />
         </el-form-item>
-        <el-form-item label="已知问题" prop="knownIssues">
+        <!--        <el-form-item label="已知问题" prop="knownIssues">
           <el-input v-model="form.knownIssues" type="textarea" placeholder="请输入内容" />
         </el-form-item>
         <el-form-item label="最低系统版本" prop="osSupport">
           <el-input v-model="form.osSupport" placeholder="请输入支持的最低系统版本,如 Android 5.0, iOS 11.0" />
-        </el-form-item>
-        <el-form-item label="是否强制更新" prop="forceUpdate">
-          <el-select aria-required="true" v-model="form.forceUpdate" placeholder="请选择">
-            <el-option v-for="dict in is_force_update" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="更新包大小" prop="updatePackageSize">
+        </el-form-item>-->
+
+<!--        <el-form-item label="更新包大小" prop="updatePackageSize">
           <el-input v-model="form.updatePackageSize" placeholder="请输入更新包大小" />
-        </el-form-item>
+        </el-form-item>-->
       </el-form>
       <template #footer>
         <div class="dialog-footer">
@@ -178,6 +204,7 @@ import {
   updateVersionManagement
 } from '@/api/system/business/versionManagement';
 import { VersionManagementVO, VersionManagementQuery, VersionManagementForm } from '@/api/system/business/versionManagement/types';
+import { uploadTournament } from '@/api/system/business/tournaments';
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 const { is_force_update, mobile_sys_type } = toRefs<any>(proxy?.useDict('is_force_update', 'mobile_sys_type'));
@@ -207,7 +234,7 @@ const initFormData: VersionManagementForm = {
   knownIssues: undefined,
   osType: undefined,
   osSupport: undefined,
-  forceUpdate: undefined,
+  forceUpdate: '0', // ✅ 默认选中“否”
   downloadLink: undefined,
   updatePackageSize: undefined,
   status: undefined,
@@ -236,10 +263,10 @@ const data = reactive<PageData<VersionManagementForm, VersionManagementQuery>>({
   },
   rules: {
     id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }],
-    versionCode: [{ required: true, message: '内部版本号不能为空', trigger: 'blur' }],
+    versionCode: [{ required: true, message: '版本号不能为空', trigger: 'blur' }],
     versionName: [{ required: true, message: '版本名称不能为空', trigger: 'blur' }],
     releaseDate: [{ required: true, message: '发布日期不能为空', trigger: 'blur' }],
-    updateContent: [{ required: true, message: '主要更新内容不能为空', trigger: 'change' }],
+    updateContent: [{ required: true, message: '更新内容不能为空', trigger: 'change' }],
     downloadLink: [{ required: true, message: '下载链接不能为空', trigger: 'blur' }],
     osType: [{ required: true, message: '系统类型不能为空', trigger: 'change' }]
   }
@@ -359,6 +386,65 @@ const formatForceUpdate = (value: number): string => {
 onMounted(() => {
   getList();
 });
+
+//预览图标需要
+const iconPreviewUrl = ref('');
+const competitionIcon = ref('');
+const fileList = ref([]);
+const handleIconChange = async (file) => {
+  const index = fileList.value.findIndex((f) => f.uid === file.uid);
+  fileList.value = [];
+
+  if (file.raw) {
+    iconPreviewUrl.value = URL.createObjectURL(file.raw);
+  }
+
+  if (index === -1) {
+    // 如果文件不在列表中,则添加进去
+    fileList.value.push(file);
+  }
+
+  try {
+    const rawFile = file.raw;
+    const res = await uploadTournament(rawFile);
+    if (res.code === 200) {
+      // 更新文件状态为成功
+      const uploadedFile = {
+        ...file,
+        status: 'success',
+        response: res.data.url,
+        fileName: res.data.fileName // 假设返回了 fileName 字段
+      };
+
+      // 找到刚添加的文件并更新
+      const updatedIndex = fileList.value.findIndex((f) => f.uid === file.uid);
+      if (updatedIndex !== -1) {
+        fileList.value[updatedIndex] = uploadedFile;
+      }
+
+      // 设置下载链接
+      form.value.downloadLink = 'http://oss.hunanpt.cn/' + uploadedFile.fileName;
+      ElMessage.success('上传成功');
+    } else {
+      throw new Error(res.msg);
+    }
+  } catch (error) {
+    // 更新文件状态为失败
+    fileList.value[index] = {
+      ...file,
+      status: 'fail',
+      error: '上传失败'
+    };
+    ElMessage.error('上传失败,请重试');
+  }
+};
+// 删除文件处理函数
+const handleIconRemove = (file, updatedFileList) => {
+  fileList.value = updatedFileList;
+  // 清除预览图和临时链接
+  iconPreviewUrl.value = '';
+  competitionIcon.value = ''; // 如果需要清除后台加载的图标,可以在这里设置为空字符串
+};
 </script>
 <style scoped>
 .truncate {