소스 검색

```
feat(workflow): 实现工作流发布和详情功能

- 在CourseCard组件中添加工作流数据绑定,替换静态内容为动态数据
- 实现Home页面获取工作流列表并渲染
- 完善WorkflowAdd页面表单功能,添加分类选择、封面图上传等字段
- 实现WorkflowDetail页面显示工作流详情信息
- 在SearchPlatform页面集成工作流搜索功能
- 添加工作流文件下载功能和错误处理
- 优化课程卡片点击事件,防止事件冒泡
```

zhangningning 1 개월 전
부모
커밋
c86b6745b1

+ 14 - 0
src/api/publish.js

@@ -0,0 +1,14 @@
+import request from './request.js'
+
+// 新增发布工作流
+export function publishAdd(data = {}) {
+  return request.post('/publish',data)
+}
+// 查询发布工作流列表
+export function getPublishList(data = {}) {
+  return request.get('/publish/list',data)
+}
+// 查询发布工作流列表
+export function getPublishDetail(data = {}) {
+  return request.get('/publish/'+data.id)
+}

+ 14 - 12
src/components/course-card.vue

@@ -1,32 +1,34 @@
 <template>
-  <div class="course-card list_item_animation"  @click="goWorkflowDetail">
-    <div class="bg_color_f5 coverImg"></div>
+  <div class="course-card list_item_animation" >
+    <div class="bg_color_f5 coverImg" @click.stop.prevent="goWorkflowDetail">
+      <img :src="info.coverImage" alt="" class="coverImg" />
+    </div>
     <div class="course-card-bottom-height"></div>
     <div class="padding16 course-card-bottom">
       <div class="gap10">
         <img :src="riliIcon" alt="" style="width: 16px; height: 16px;">
-        <div class="font_size13">2023-10-15</div>
+        <div class="font_size13">{{info.createTime || ''}}</div>
       </div>
-      <div style="min-height: 82px;">
+      <div style="min-height: 82px;" @click.stop.prevent="goWorkflowDetail">
         <div class="line2 font_size18 line_height26 bold mt10">
-          【Linux】【操作】Linux操作集Linux操作集Linux操作集Linux操作集Linux操作集Linux操作集Linux操作集Linux操作集
+          {{info.workflowTitle || ''}}
         </div>
         <div class="mt10 line1 gray font_size13">
-          - 本文介绍两款开源的密码破解工具John the Ripper和PDFCrack,用于破解PDF、Word、Excel、ZIP、RAR等文件的密码。John the Ripper支持字典和暴力破解两种模
+          {{info.description || ''}}
         </div>
       </div>
       <div class="mt10 flex-center-between">
         <div class="gap10">
-          <el-avatar :size="24" :src="appStore.avatar" />
-          <div class="font_size14">张三</div>
+          <el-avatar :size="24" :src="info.userAvatar || appStore.avatarDefault" />
+          <div class="font_size14">{{info.nickName || '张三'}}</div>
         </div>
         <div class="gap10 contactInfo_bg border_radius_4">
-          <img :src="yunIcon" alt="" style="width: 16px; height: 16px;">
-          <div class="font_size13">n8n平台</div>
+          <img :src="yunIcon" alt="" style="width: 16px; height: 16px;" />
+          <div class="font_size13">{{info.categoryName1}}平台</div>
         </div>
       </div>
       <div class="gap10 mt16 button-container">
-        <el-button type="primary" class="flex_1" size="large" plain>
+        <el-button type="primary" class="flex_1" size="large" plain @click.stop.prevent="goWorkflowDetail">
           <el-icon class="mr10"><Document /></el-icon>
           查看详情
         </el-button>
@@ -92,7 +94,7 @@ const goWorkflowDetail = () => {
   router.push({
     path: path,
     query: {
-      id:2,
+      publishId:props.info.publishId,
       metaTitle: 'route.WorkflowDetail'
     }
   })

+ 3 - 1
src/pages/CourseDetail.vue

@@ -80,7 +80,9 @@ const currentCourseChapters = ref(null)
 
 const videoPlayer = ref(null)
 // const currentVideoUrl = ref('')
-const currentVideoUrl = ref('http://jcxxpt.oss-cn-beijing.aliyuncs.com/common/2025/12/19/actmOvmq0xOBc8448561c73a066a523821c6f7ae4868_20251219094240A008.mp4')
+// const currentVideoUrl = ref('http://jcxxpt.oss-cn-beijing.aliyuncs.com/common/2025/12/19/actmOvmq0xOBc8448561c73a066a523821c6f7ae4868_20251219094240A008.mp4')
+// const currentVideoUrl = ref('http://baomiai.oss-cn-shanghai.aliyuncs.com/video/2025/12/30/123_20251226133117A047_20251230095248A001.mp4?response-content-disposition=inline&response-content-type=video%2Fmp4&x-oss-date=20251230T015258Z&x-oss-expires=7200&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI5tG5dEtkqwDGcU6AtaYE%2F20251230%2Fcn-shanghai%2Foss%2Faliyun_v4_reque')
+const currentVideoUrl = ref('http://baomiai.oss-cn-shanghai.aliyuncs.com/video/2025/12/30/123_20251226133117A047_20251230095248A001.mp4?response-content-disposition=inline&x-oss-date=20251230T015720Z&x-oss-expires=7199&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI5tG5dEtkqwDGcU6AtaYE%2F20251230%2Fcn-shanghai%2Foss%2Faliyun_v4_request&x-oss-signature=f93c20421dcfdc6822cd03d42ae66f8a28acd2c4d25c79ce16e2312537eabaa5')
 const currentPlayingVideoId = ref(null)
 const currentVideoDuration = ref(0)
 const currentPlayTime = ref(0)

+ 15 - 1
src/pages/Home.vue

@@ -69,7 +69,7 @@
     <!-- 工作流列表 -->
     <div class="course-list">
       <div class="course-grid">
-        <CourseCard v-for="item in 4" :key="item" fromPage="home"/>
+        <CourseCard v-for="item in list" :key="item.workflowId" :info="item" fromPage="home"/>
       </div>
     </div>
     
@@ -88,6 +88,7 @@ import detailIcon from '@/assets/imgs/detail.png'
 import CourseCard from '@/components/course-card.vue'
 
 import { getCategoryListTree } from '@/api/category.js'
+import { getPublishList } from '@/api/publish.js'
 
 
 import { onMounted,ref } from 'vue'
@@ -99,11 +100,13 @@ const categoryListTree = ref([])
 onMounted(() => {
   console.log('Home mounted')
   getCategoryListTreeFn();
+  getList();
 })
 
 const router = useRouter()
 const activePlatform = ref('');
 const categoryId = ref('');
+const list = ref([]);
 
 
 // 监听图片加载完成,动态设置轮播图高度
@@ -147,6 +150,17 @@ const getCategoryListTreeFn = () => {
     categoryId.value = categoryListTree.value[0]?.categoryId || '';
   })
 };
+
+// 查询寻找工作流列表
+const getList = async (type) => {
+  const res = await getPublishList({
+    pageNum: 1,
+    pageSize: 10,
+  })
+  if(res.code === 200){
+    list.value = res.rows || [];
+  }
+};
 </script>
 
 <style lang="scss">

+ 16 - 13
src/pages/SearchPlatform.vue

@@ -12,7 +12,7 @@
               class="search-input"
               v-model="searchFom.workflowTitle"
             />
-            <button class="search-btn bg_color_primary gradient" @click.stop.prevent="getList">
+            <button class="search-btn bg_color_primary gradient" @click.stop.prevent="getList('init')">
               <img :src="searchIcon" alt="" class="icon-search">
               {{$t('common.shousuo')}}
             </button>
@@ -63,7 +63,7 @@
       <!-- 列表 -->
       <div class="course-list mt20">
         <div class="course-grid">
-          <CourseCard v-for="item in 4" :key="item"/>
+          <CourseCard v-for="item in list" :key="item.publishId" :info="item"/>
         </div>
       </div>
       <!-- 分页 -->
@@ -88,29 +88,30 @@
   import Pagination from '@/components/Pagination.vue'
 
   import { getCategoryListTree } from '@/api/category.js'
+  import { getPublishList } from '@/api/publish.js'
 
 
   import { useRouter, useRoute } from 'vue-router'
-  const router = useRouter()
-  const route = useRoute()
-  console.log(router,route)
+  const router = useRouter();
+  const route = useRoute();
   import { ref, computed, reactive, onMounted } from 'vue'
   //获取参数
   const query = route.query
-  const categoryId = ref(query.categoryId || '')
-  const activePlatform = ref(query.activePlatform || '')
+  const categoryId = ref(query.categoryId || '');
+  const activePlatform = ref(query.activePlatform || '');
   //获取当前路由路径
   // const currentPath = ref(router.currentRoute.value.path)
   const isChildRoute = computed(() => {
     return route.matched.length > 1
-  })
+  });
   // 一级分类列表
-  const categoryListTree = ref([])
+  const categoryListTree = ref([]);
   // 二级分类列表
-  const categoryListTree2 = ref([])
+  const categoryListTree2 = ref([]);
   // 活动平台
 
   // 添加分页相关数据
+  const list = ref([]);
   const listTotal = ref(0);
   const searchFom = reactive({
     categoryId1: categoryId.value,
@@ -131,9 +132,11 @@
     if(type === 'init'){
       searchFom.pageNum = 1
     }
-    // const res = await getQuestList(searchFom)
-    // if(res.code === 200){
-    // }
+    const res = await getPublishList(searchFom)
+    if(res.code === 200){
+      list.value = res.rows || [];
+      listTotal.value = res.total || 0;
+    }
   }
   const handlePageChange = (page) => {
     searchFom.pageNum = page

+ 124 - 59
src/pages/WorkflowAdd.vue

@@ -14,13 +14,11 @@
             ref="fileUploader"
             accept=".json,.yaml,.yml,.zip"
             :multiple="false"
+            :limit="1"
             :auto-upload="true"
             :drag="true"
             v-model="files"
             tip="请上传JSON、YAML、ZIP格式的文件,最大10MB"
-            @success="handleUploadSuccess"
-            @error="handleUploadError"
-            @progress="handleUploadProgress"
           />
         </div>
       </div>
@@ -30,11 +28,43 @@
           <div class="font_size20 bold">基本信息</div>
         </div>
         <div class="mt10">
-          <el-form-item label="工作流标题" prop="name">
-            <el-input v-model="ruleForm.name" placeholder="请输入工作流标题"  maxlength="50"/>
+          <el-form-item label="工作流标题" prop="workflowTitle">
+            <el-input v-model="ruleForm.workflowTitle" placeholder="请输入工作流标题"  maxlength="50"/>
           </el-form-item>
-          <el-form-item label="工作流类型" prop="name">
-            <el-input v-model="ruleForm.name" placeholder="请输入工作流标题"  maxlength="50" />
+          <el-form-item label="工作流类型" prop="categoryId3">
+            <el-cascader 
+              v-model="categoryIdList"
+              :options="categoryListTree"
+              placeholder="请选择工作流类型"
+              style="width:100%"
+              :props="{
+                label: 'categoryName',
+                value: 'categoryId',
+                children: 'children',
+              }"
+            />
+          </el-form-item>
+          <el-form-item label="工作流描述" prop="description">
+            <el-input type="textarea" v-model="ruleForm.description" placeholder="请输入工作流描述"  maxlength="500" show-word-limit/>
+          </el-form-item>
+          <el-form-item label="封面图" prop="coverImage">
+            <div>支持批量上传文件,文件格式不限,最多只能上传 5 份文件</div>
+            <!-- 图片类型 -->
+            <FileUploader
+              ref="fileUploader"
+              accept="image/*"
+              :multiple="false"
+              :limit="1"
+              :auto-upload="true"
+              list-type="picture-card"
+              :data="{ directory: 'workflow' }"
+              buttonText=""
+              v-model="coverImage"
+              tip=""
+              @success="handleUploadSuccess"
+              @error="handleUploadError"
+              @progress="handleUploadProgress"
+            />
           </el-form-item>
           <el-form-item label="工作流预览">
             <div>支持批量上传文件,文件格式不限,最多只能上传 5 份文件</div>
@@ -42,7 +72,6 @@
             <FileUploader
               ref="fileUploader"
               accept="image/*"
-              :max-size="100"
               :multiple="true"
               :auto-upload="true"
               list-type="picture-card"
@@ -55,7 +84,7 @@
               @progress="handleUploadProgress"
             />
           </el-form-item>
-          <el-form-item label="详情">
+          <el-form-item label="详情" prop="workflowContent">
             <BlockNoteEditor v-model="editorContent" :editable="true"/>
           </el-form-item>
         </div>
@@ -68,16 +97,18 @@
        
         <el-form-item label="付费设置" style="width: 500px">
           <div class="gap20 mt10 mb20">
-            <div class="payType active gap10">
+            <div class="payType gap10" @click="workflowPriceType = 'pay'" 
+            :class="{'active': workflowPriceType === 'pay'}">
               <div class="checkType"></div>
               <div>付费(用户需付费后使用)</div>
             </div>
-            <div class="payType gap10">
+            <div class="payType gap10" @click="workflowPriceType = 'free';ruleForm.workflowPrice=''" 
+            :class="{'active': workflowPriceType === 'free'}">
               <div class="checkType"></div>
-              <div>付费(用户需付费后使用)</div>
+              <div>免费(所有用户可免费数据)</div>
             </div>
           </div>
-          <el-input v-model="ruleForm.name" placeholder="请输入暴米币数量"  maxlength="50" type="number">
+          <el-input v-model="ruleForm.workflowPrice" placeholder="请输入暴米币数量"  maxlength="50" type="number" v-if="workflowPriceType === 'pay'">
             <template #append>暴米币</template>
           </el-input>
         </el-form-item>
@@ -97,7 +128,7 @@
 </template>
 
 <script setup>
-import { ref, onMounted, reactive } from 'vue'
+import { ref, onMounted, reactive, watchEffect } from 'vue'
 import { useRoute, useRouter } from 'vue-router'
 import FileUploader from '@/components/FileUploader.vue'
 import DGTMessage from '@/utils/message'
@@ -105,77 +136,104 @@ import BlockNoteEditor from '@/components/BlockNoteEditor.vue';
 const route = useRoute()
 const router = useRouter()
 
-
+import { getCategoryListTree } from '@/api/category.js'
+import { publishAdd } from '@/api/publish.js'
 
 // 从路由参数中获取 activePlatform
 const activePlatform = ref(route.query.activePlatform || '');
 
-// 上传文件列表
-const uploadedFiles = ref([])
-// 图片列表
-const images = ref(
-  [
-    {
-     url:"http://jcxxpt.oss-cn-beijing.aliyuncs.com/id_card/2025/12/26/MFE1Qdqi9tXdc0cb704ec71877b97f0f0bde3a1bbb72_20251226111105A001.jpg"
-    }
-  ]
-)
-const files = ref(
-  [
-    {
-     url:"http://jcxxpt.oss-cn-beijing.aliyuncs.com/common/2025/12/26/Iwk7y3ArgL5Of52f7c2309b56d382f14540de00dd6ea_20251226111356A002.zip"
-    }
-  ]
-)
-
-// const uploadUrl = ref('/api/upload') // 实际项目中替换为真实的上传接口地址
-
-const editorContent = ref(
-  [
-    {
-      type: "paragraph",
-      content: [{ type: "text", text: "只读模式" }]
-    },
-    // {
-    // "id": "378ce968-02c2-4856-888b-c35a355aa84b",
-    // "type": "codeBlock",
-    // "props": {
-    //     "language": "text"
-    // },
-    // "content": [],
-    // "children": []
-    // }
-  ]
-);
+// 图片
+const images = ref([]);
+const coverImage = ref([]);
+//附件
+const files = ref([]);
+// 分类列表树
+const categoryListTree = ref([]);
+// 选择的分类id列表
+const categoryIdList = ref([])
+// 编辑器内容
+const editorContent = ref(null);
+const workflowPriceType = ref('pay'); // 价格类型,默认免费
 // 表单实例
 const ruleFormRef = ref(null)
 const ruleForm = reactive({
-  name: '',
-  uploadedFiles: []
+  workflowTitle: '',
+  categoryId1: '',
+  categoryId2: '',
+  categoryId3: '',
+  workflowFile: '',
+  workflowPrice: '',
+  description: '',
+  previewImage: '',
+  coverImage: '',
+  workflowContent: '',
+})
+watchEffect(() => {
+  // 将选择的分类id列表赋值给表单的categoryId1、categoryId2、categoryId3
+  ruleForm.categoryId1 = categoryIdList.value[0] || ''
+  ruleForm.categoryId2 = categoryIdList.value[1] || ''
+  ruleForm.categoryId3 = categoryIdList.value[2] || ''
+  // 将编辑器内容赋值给表单的workflowContent
+  ruleForm.workflowContent = JSON.stringify(editorContent.value);
+  ruleForm.coverImage = coverImage.value.map(img => img.url).join(',');;
+
 })
 // 校验规则
 const rules = reactive({
-  name: [
+  workflowTitle: [
     { required: true, message: '请输入工作流标题', trigger: 'blur' },
   ],
+  categoryId3: [
+    { required: true, message: '请输入工作流标题', trigger: 'blur' },
+  ],
+  description: [
+    { required: true, message: '请输入工作流描述', trigger: 'blur' },
+  ],
+  coverImage: [
+    { required: true, message: '请上传封面图', trigger: 'change' },
+  ],
+  workflowContent: [
+    { required: true, message: '请输入工作流详情内容', trigger: 'change' },
+  ],
 })
 
 
 
 onMounted(() => {
+  getCategoryListTreeFn();
 });
 
 // 提交表单
 const submitForm = async () => {
-  console.log('提交表单', ruleForm,images.value)
-  return;
+  ruleForm.workflowFile = files.value[0]?.url || '';
+  ruleForm.previewImage = images.value.map(img => img.url).join(',');
+  
+  if(!editorContent.value || editorContent.value.length === 0){
+    DGTMessage.warning('请输入工作流详情内容')
+    return
+  }
+  if(workflowPriceType.value === 'pay'){
+    if(!ruleForm.workflowPrice){
+      DGTMessage.warning('请输入暴米币数量')
+      return
+    }
+  }
+  console.log('工作流详情内容',ruleForm)
   await ruleFormRef.value.validate((valid, fields) => {
     console.log(valid, fields)
     if (!valid) {
       DGTMessage.warning(fields.name[0].message)
       return
     }
-    DGTMessage.success('表单提交成功')
+    publishAdd(ruleForm).then(res => {
+      console.log(res)
+      if(res.code === 200){
+        DGTMessage.success('提交成功')
+        setTimeout(() => {
+          goBack();
+        }, 2000);
+      }
+    })
   })
 }
 
@@ -198,7 +256,14 @@ const handleUploadProgress = (event, file, uploadedFiles) => {
 
 const goBack = () => {
   router.back()
-}
+};
+
+const getCategoryListTreeFn = () => {
+  getCategoryListTree().then(res => {
+    console.log(res)
+    categoryListTree.value = res.rows || [];
+  })
+};
 </script>
 <style lang="scss">
 .workflow-add{

+ 71 - 49
src/pages/WorkflowDetail.vue

@@ -4,30 +4,30 @@
     <div class="flex-between mt10">
       <div class="flex_1 mr20">
         <div class="padding16 bg_color_fff border_radius_16">
-          <div class="bold font_size30">AI智能线索富集与多渠道通知系统</div>
+          <div class="bold font_size30">{{ruleForm.workflowTitle || ''}}</div>
           <div class="gap20 mt10">
             <div class="gap5">
               <img :src="yuangong" alt="员工" style="width: 16px; height: 16px;">
-              <span class="font_size14">张三</span>
+              <span class="font_size14">{{ruleForm.nickName || ''}}</span>
             </div>
             <div class="gap5">
               <img :src="riliIcon" alt="员工" style="width: 16px; height: 16px;">
-              <span class="font_size14">2024-10-16</span>
+              <span class="font_size14">{{ruleForm.createTime || ''}}</span>
             </div>
             <div class="gap5">
               <img :src="shiyongIcon" alt="员工" style="width: 16px; height: 16px;">
-              <span class="font_size14">2,456使用</span>
+              <span class="font_size14">{{ruleForm.downCount ?? ''}} 使用</span>
             </div>
             <div class="gap5">
               <img :src="yunIcon" alt="员工" style="width: 16px; height: 16px;">
-              <span class="font_size14">n8n平台</span>
+              <span class="font_size14">{{ruleForm.categoryName1 || ''}}</span>
             </div>
             <div class="gap5">
               <img :src="biaoqianIcon" alt="员工" style="width: 16px; height: 16px;">
-              <span class="font_size14">二级分类名称-三级分类名称</span>
+              <span class="font_size14">{{ruleForm.categoryName2 || ''}}-{{ruleForm.categoryName3 || ''}}</span>
             </div>
           </div>
-          <div class="font_size16 gray mt10">此n8n工作流是一款强大的AI驱动的潜在客户富集与通知系统,专为市场营销和销售团队设计。它通过智能表单收集线索,利用OpenAI深度分析并丰富客户数据,自动识别关键信息。系统能根据预设条件,通过多种渠道即时发送个性化通知,显著提升线索质量、转化率及团队协作效率,是优化客户关系管理的关键工具。</div>
+          <div class="font_size16 gray mt10">{{ruleForm.description || ''}}</div>
           
         </div>
         <!-- 工作流预览 -->
@@ -36,6 +36,10 @@
             <div class="line_vertical"></div>
             <div class="font_size20 bold">工作流预览</div>
           </div>
+          <div class="mt20">
+            <img :src="item || ''" alt="工作流预览" v-for="(item, index) in coverImage" :key="index"
+            style="width: 100%; height: auto;" />
+          </div>
         </div>
         <!-- 工作流预览 -->
         <div class="padding16 bg_color_fff border_radius_10 mt10">
@@ -54,11 +58,11 @@
               <div class="flex-column">
                 <div class="font_size16">当前及格</div>
                 <div class="color_price">
-                  <span class="font_size32">0</span> 
+                  <span class="font_size32">{{ruleForm.workflowPrice || 0}}</span> 
                   <span>{{$t('common.mibi')}}</span>
                 </div>
               </div>
-              <el-button type="success" plain size="mini">免费</el-button>
+              <el-button type="success" plain size="mini" v-if="ruleForm.workflowPrice === 0">免费</el-button>
             </div>
             <div class="mt20">
               <el-button type="primary" class="font_size16" size="large" style="width: 100%;">
@@ -67,7 +71,7 @@
               </el-button>
             </div>
             <div class="mt20">
-              <el-button type="primary" size="large" plain style="width: 100%;">
+              <el-button type="primary" size="large" plain style="width: 100%;" @click="downloadFile(ruleForm.workflowFile)">
                 <img :src="downIcon" alt="员工" style="width: 30px; height: 30px;">
                 <span class="font_size18">下载工作流</span>
               </el-button>
@@ -131,46 +135,64 @@
 </template>
 
 <script setup>
-  import yuangong from '@/assets/imgs/yuangong.png'
-  import riliIcon from '@/assets/imgs/rili.png'
-  import shiyongIcon from '@/assets/imgs/shiyong.png'
-  import yunIcon from '@/assets/imgs/yun.png'
-  import biaoqianIcon from '@/assets/imgs/biaoqian.png'
-  import useNowIcon from '@/assets/imgs/useNow.png'
-  import downIcon from '@/assets/imgs/down.png'
-  import weiguanzhuIcon from '@/assets/imgs/weiguanzhu.png'
-  import yiguanzhuIcon from '@/assets/imgs/yiguanzhu.png'
-  import geshiIcon from '@/assets/imgs/geshi.png'
-  import neicunIcon from '@/assets/imgs/neicun.png'
-  import banbenIcon from '@/assets/imgs/banben.png'
+import yuangong from '@/assets/imgs/yuangong.png'
+import riliIcon from '@/assets/imgs/rili.png'
+import shiyongIcon from '@/assets/imgs/shiyong.png'
+import yunIcon from '@/assets/imgs/yun.png'
+import biaoqianIcon from '@/assets/imgs/biaoqian.png'
+import useNowIcon from '@/assets/imgs/useNow.png'
+import downIcon from '@/assets/imgs/down.png'
+import weiguanzhuIcon from '@/assets/imgs/weiguanzhu.png'
+import yiguanzhuIcon from '@/assets/imgs/yiguanzhu.png'
+import geshiIcon from '@/assets/imgs/geshi.png'
+import neicunIcon from '@/assets/imgs/neicun.png'
+import banbenIcon from '@/assets/imgs/banben.png'
+import { downloadFile } from '@/utils/util'
+
+import { getPublishDetail } from '@/api/publish.js'
+
+import BlockNoteEditor from '@/components/BlockNoteEditor.vue';
+import { useRoute } from 'vue-router'
+const route = useRoute()
+import { useAppStore } from '@/pinia/appStore'
+const appStore = useAppStore()
+import { ref, onMounted, nextTick } from 'vue'
+//获取参数
+const query = route.query
+const publishId = ref(query.publishId || '');
+// 详情内容
+const editorContent = ref(null);
+const coverImage = ref([]);
+// 表单数据
+const ruleForm = ref({
+  workflowTitle: '',
+  categoryId1: '',
+  categoryId2: '',
+  categoryId3: '',
+  workflowFile: '',
+  workflowPrice: '',
+  description: '',
+  previewImage: '',
+  coverImage: '',
+  workflowContent: '',
+})
 
-  import BlockNoteEditor from '@/components/BlockNoteEditor.vue';
-  import { useRoute } from 'vue-router'
-  const route = useRoute()
-  import { useAppStore } from '@/pinia/appStore'
-  const appStore = useAppStore()
-  import { ref } from 'vue'
-  //获取参数
-  const query = route.query
-  const id = ref(query.id || '');
-  // 详情内容
-  const editorContent = ref(
-  [
-    {
-      type: "paragraph",
-      content: [{ type: "text", text: "只读模式" }]
-    },
-    {
-    "id": "378ce968-02c2-4856-888b-c35a355aa84b",
-    "type": "codeBlock",
-    "props": {
-        "language": "text"
-    },
-    "content": [],
-    "children": []
-    }
-  ]
-);
+onMounted(() => {
+  getPublishDetail({id:publishId.value}).then(res => {
+    console.log(res)
+    ruleForm.value = res.data || {};
+    nextTick(() => {
+      if(ruleForm.value.coverImage){
+        coverImage.value = ruleForm.value.coverImage.split(',');
+      };
+      setTimeout(() => {
+        if(ruleForm.value.workflowContent){
+          editorContent.value = JSON.parse(ruleForm.value.workflowContent);
+        }
+      }, 500);
+    });
+  })
+});
 </script>
 
 <style scoped lang="scss">

+ 8 - 8
src/pages/workflowTrade/workflowTrade.vue

@@ -12,7 +12,7 @@
               :placeholder="$t('common.qingshuruyaosousuodegongzuoliu')"
               class="search-input"
             />
-            <button class="search-btn bg_color_primary" @click="getList('init')">
+            <button class="search-btn bg_color_primary" @click.stop.prevent="getList('init')">
               <img :src="searchIcon" alt="" class="icon-search">
               {{$t('common.shousuo')}}
             </button>
@@ -160,22 +160,22 @@
   console.log(router,route)
   import { ref, computed, reactive, onMounted } from 'vue'
   import { useAppStore } from '@/pinia/appStore'
-  const appStore = useAppStore()
+  const appStore = useAppStore();
 
   //获取参数
-  const query = route.query
+  const query = route.query;
   //获取当前路由路径
   // const currentPath = ref(router.currentRoute.value.path)
   const isChildRoute = computed(() => {
     return route.matched.length > 1
-  })
+  });
   // 一级分类列表
-  const CategoryList = ref([])
+  const CategoryList = ref([]);
 
   // 添加分页相关数据
-  const list = ref([])
-  const listTotal = ref(0)
-  const publishTime = ref(['', ''])
+  const list = ref([]);
+  const listTotal = ref(0);
+  const publishTime = ref(['', '']);
   const searchFom = reactive({
     categoryId1: '',
     title: '',

+ 2 - 1
src/pinia/appStore.js

@@ -8,10 +8,11 @@ export const useAppStore = defineStore('app', {
     // 当前语言
     userInfo: localStorage.getItem('userInfo') ? JSON.parse(localStorage.getItem('userInfo')) : null,
     token: localStorage.getItem('token') || null,
+    avatarDefault: 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png',
   }),
   getters: {
     avatar() {
-      return this.userInfo?.avatar || 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png';
+      return this.userInfo?.avatar || this.avatarDefault;
     },
   },
   actions: {

+ 5 - 1
src/utils/util.js

@@ -1,5 +1,9 @@
-//浏览器下载文件
+import DGTMessage from '@/utils/message'//浏览器下载文件
 export function downloadFile(url, fileName) {
+  if (!url) {
+    DGTMessage.error('文件地址不存在');
+    return;
+  }
   const link = document.createElement('a');
   link.href = url;
   link.download = fileName || '';