urbanu 1 ماه پیش
والد
کامیت
5a95191d2d
1فایلهای تغییر یافته به همراه72 افزوده شده و 9 حذف شده
  1. 72 9
      src/views/daytask/material/materialList.vue

+ 72 - 9
src/views/daytask/material/materialList.vue

@@ -14,6 +14,7 @@
           <el-select v-model="searchForm.type" placeholder="类型" clearable style="width:100px">
             <el-option label="图片" value="image" />
             <el-option label="视频" value="video" />
+            <el-option label="文字" value="text" />
             <el-option label="音频" value="audio" />
             <el-option label="文档" value="document" />
           </el-select>
@@ -58,13 +59,25 @@
                 <el-icon><VideoPlay /></el-icon>
               </div>
             </div>
+            <el-popover v-else-if="row.type === 'text'" placement="top" :width="300" trigger="hover">
+              <template #reference>
+                <el-icon size="24" color="#409eff"><Document /></el-icon>
+              </template>
+              <div class="text-preview-popover">{{ row.content }}</div>
+            </el-popover>
             <el-button v-else type="primary" link @click="viewUrl(row.url)">查看</el-button>
           </template>
         </el-table-column>
-        <el-table-column prop="url" label="URL" align="center" min-width="200" show-overflow-tooltip>
+        <el-table-column prop="url" label="URL/内容" align="center" min-width="200" show-overflow-tooltip>
           <template #default="{ row }">
-            <el-button type="primary" link size="small" @click="copyUrl(row.url)">复制</el-button>
-            {{ row.url }}
+            <template v-if="row.type === 'text'">
+              <el-button type="primary" link size="small" @click="copyUrl(row.content)">复制</el-button>
+              {{ row.content }}
+            </template>
+            <template v-else>
+              <el-button type="primary" link size="small" @click="copyUrl(row.url)">复制</el-button>
+              {{ row.url }}
+            </template>
           </template>
         </el-table-column>
         <el-table-column prop="size" label="大小" align="center" width="100">
@@ -105,10 +118,27 @@
           <el-option v-for="item in groupOptions" :key="item.id" :label="item.name" :value="item.id" />
         </el-select>
       </el-form-item>
+      <el-form-item label="素材类型" prop="type">
+        <el-radio-group v-model="formData.type" @change="handleTypeChange">
+          <el-radio value="image">图片</el-radio>
+          <el-radio value="video">视频</el-radio>
+          <el-radio value="text">文字</el-radio>
+        </el-radio-group>
+      </el-form-item>
       <el-form-item label="名称" prop="name">
         <el-input v-model="formData.name" placeholder="请输入名称" />
       </el-form-item>
-      <el-form-item label="上传文件" prop="url">
+      <!-- 文字类型:文本内容输入 -->
+      <el-form-item v-if="formData.type === 'text'" label="文字内容" prop="content">
+        <el-input
+          v-model="formData.content"
+          type="textarea"
+          :rows="6"
+          placeholder="请输入文字内容"
+        />
+      </el-form-item>
+      <!-- 文件类型:上传文件 -->
+      <el-form-item v-else label="上传文件" prop="url">
         <div class="upload-container">
           <el-upload
             ref="uploadRef"
@@ -218,10 +248,10 @@ const tableData = ref([]);
 const pageable = reactive({ pageNum: 1, pageSize: 30, total: 0 });
 const groupOptions = ref([]);
 
-const typeMap = { image: "图片", video: "视频", audio: "音频", document: "文档" };
+const typeMap = { image: "图片", video: "视频", audio: "音频", document: "文档", text: "文字" };
 
 const getTypeColor = (type) => {
-  const colors = { image: "success", video: "primary", audio: "warning", document: "info" };
+  const colors = { image: "success", video: "primary", audio: "warning", document: "info", text: "" };
   return colors[type] || "default";
 };
 
@@ -246,19 +276,36 @@ const formData = ref({
   name: "",
   type: "image",
   url: "",
+  content: "",
   cover: "",
   size: 0,
   sort: 0,
   status: 1
 });
 
+// 动态表单验证规则
 const formRules = ref({
   groupId: [{ required: true, message: "请选择分组", trigger: "change" }],
   name: [{ required: true, message: "请输入名称", trigger: "blur" }],
-  url: [{ required: true, message: "请上传文件", trigger: "change" }],
   status: [{ required: true, message: "请选择状态", trigger: "change" }]
 });
 
+// 类型切换时清空相关数据
+const handleTypeChange = (type) => {
+  if (type === 'text') {
+    formData.value.url = "";
+    formData.value.cover = "";
+    formData.value.size = 0;
+    previewUrl.value = "";
+  } else {
+    formData.value.content = "";
+  }
+  // 清除验证
+  if (formRef.value) {
+    formRef.value.clearValidate();
+  }
+};
+
 const formatUnix = (val) => {
   if (!val) return "";
   return dayjs.unix(val).format("YYYY-MM-DD HH:mm:ss");
@@ -343,7 +390,7 @@ const openDialog = (row) => {
   previewUrl.value = "";
   pendingFile.value = null;
   if (row) {
-    formData.value = { ...row };
+    formData.value = { ...row, content: row.content || "" };
   } else {
     formData.value = {
       id: null,
@@ -351,6 +398,7 @@ const openDialog = (row) => {
       name: "",
       type: "image",
       url: "",
+      content: "",
       cover: "",
       size: 0,
       sort: 0,
@@ -477,6 +525,20 @@ const handleCoverUpload = async (options) => {
 
 const handleSubmit = async () => {
   if (!formRef.value) return;
+
+  // 验证:文字类型需要内容,其他类型需要URL
+  if (formData.value.type === 'text') {
+    if (!formData.value.content || !formData.value.content.trim()) {
+      ElNotification.warning("请输入文字内容");
+      return;
+    }
+  } else {
+    if (!formData.value.url) {
+      ElNotification.warning("请上传文件");
+      return;
+    }
+  }
+
   await formRef.value.validate(async (valid) => {
     if (!valid) return;
     submitLoading.value = true;
@@ -488,7 +550,8 @@ const handleSubmit = async () => {
           group_id: formData.value.groupId,
           name: formData.value.name,
           type: formData.value.type,
-          url: formData.value.url,
+          url: formData.value.type === 'text' ? "" : formData.value.url,
+          content: formData.value.type === 'text' ? formData.value.content : "",
           cover: formData.value.cover || "",
           size: formData.value.size,
           sort: formData.value.sort,