Bläddra i källkod

[dev] post edit publish

wenliming 2 år sedan
förälder
incheckning
ec7a6611dd

+ 17 - 0
src/http/toolBoxApi.js

@@ -0,0 +1,17 @@
+import { service } from "./request";
+
+export function convertUrl(params) {
+    return service({
+        url: `/post/editor/convertUrl`,
+        method: 'post',
+        data: params
+    })
+}
+
+export function getAllPostEditorAppData(params) {
+    return service({
+        url: `/post/editor/getAllPostEditorAppData`,
+        method: 'post',
+        data: params
+    })
+}

+ 13 - 0
src/uilts/help.js

@@ -190,4 +190,17 @@ export function formatSecondsAsDaysOrTime(secs) {
     text = formatSecondsAsTime(secs)
   }
   return text
+}
+
+export function checkURL(URL) {
+  var str = URL;
+  //判断URL地址的正则表达式为:http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?
+  // /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\*\+,;=.]+$/
+  var Expression = /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/;
+  var objExp = new RegExp(Expression);
+  if (objExp.test(str) == true) {
+      return true;
+  } else {
+      return false;
+  }
 }

+ 57 - 22
src/view/iframe/publish/give-dialog.vue

@@ -15,16 +15,26 @@
                 <div class="left">
                     <!-- 关闭按钮 -->
                     <div class="close-btn" @click="close">
-                        <img  class="icon-close"
+                        <template v-if="publishType == 'TOOL_BOX'">
+                            <img  class="icon-close"
+                            :src="require('@/assets/svg/icon-close.svg')"
+                            v-if="toolBoxPageData.activePage == 'EDITOR'"/>
+                            <img class="icon-close"
+                                :src="require('@/assets/svg/icon-back.svg')"
+                                v-else/>
+                        </template>
+                        <template v-else>
+                            <img  class="icon-close"
                             :src="require('@/assets/svg/icon-close.svg')"
                             v-if="showComType == 'default'"/>
-                        <img class="icon-close"
-                            :src="require('@/assets/svg/icon-back.svg')"
-                            v-else/>
+                            <img class="icon-close"
+                                :src="require('@/assets/svg/icon-back.svg')"
+                                v-else/>
+                        </template>
                     </div>
                     <!-- 标题 -->
                     <div class="title">
-                        {{ currentComData[showComType]["title"] }}
+                        {{publishType.value == 'REDPACKET' ? currentComData[showComType]["title"] : 'Tool Box' }}
                     </div>
                 </div>
                 <div class="right">
@@ -70,7 +80,7 @@
                             @selectCurrency="selectCurrencyAfter"></currency-select>
                     </div>
 
-                    <div class="left" v-if="showComType != 'preview'">
+                    <div class="left" v-if="showComType != 'preview' && toolBoxPageData.activePage != 'PREVIEW'">
                         <div class="tab-item" 
                             :class="{'active-tab': item.type == publishType}"
                             v-for="(item, index) in leftTabList" 
@@ -82,12 +92,17 @@
                     </div>
 
                     <div class="right"  
-                        :class="{'fill-right': showComType == 'preview'}">
+                        :class="{'fill-right': showComType == 'preview' || toolBoxPageData.activePage == 'PREVIEW'}">
                         <global-tip :type="'2'"></global-tip>
 
                         
                         <template v-if="publishType == 'TOOL_BOX'">
-                            <tool-box></tool-box>
+                            <tool-box 
+                                :pageData="{
+                                    'linkInputDescImage': toolBoxPageData.postEditorLinkInputDescImage
+                                }"
+                                :activePage="toolBoxPageData.activePage" @onPageChange="onToolBoxPageChange"
+                                @toolBoxPublishFinish="toolBoxPublishFinish"></tool-box>
                         </template>
                         <template v-else>
                             <div class="form-wrapper"  v-if="showComType == 'default'">
@@ -405,8 +420,6 @@ import topUp from "@/view/iframe/publish/components/top-up.vue";
 import topUp2 from "@/view/iframe/publish/components/top-up2.vue";
 import toolBox from '@/view/iframe/publish/tool-box/index.vue'
 
-import axios from 'axios';
-
 const config = {
     number: 'BigNumber',
 }
@@ -427,8 +440,8 @@ provide('installStatus', installStatus)
 let publishRes = reactive({});
 
 //弹窗是否展示
-let visible = ref(true);
-let publishType = ref('TOOL_BOX');
+let visible = ref(false);
+let publishType = ref('REDPACKET');
 
 
 //弹窗高度
@@ -618,6 +631,11 @@ let leftTabList = reactive([
     }
 ])
 
+let toolBoxPageData = reactive({
+    activePage: 'EDITOR', //EDITOR PREVIEW
+    postEditorLinkInputDescImage: ''
+})
+
 
 const props = defineProps({
     dialogData: {
@@ -661,15 +679,27 @@ watch(
     }
 );
 
-const emits = defineEmits(["close", "confirm", "payPalFinsh"]);
+const emits = defineEmits(["close", "confirm", "postPublishFinish"]);
 
 const close = () => {
-    if (showComType.value != "default") {
-        showComType.value = "default";
-        isBack.value = true;
+    if(publishType.value == 'TOOL_BOX') {
+        closeToolBoxPage()
     } else {
-        initParams();
+        if (showComType.value != "default") {
+            showComType.value = "default";
+            isBack.value = true;
+        } else {
+            initParams();
+            emits("close", false);
+        }
+    }
+};
+
+const closeToolBoxPage = () => {
+    if(toolBoxPageData.activePage == "EDITOR") {
         emits("close", false);
+    } else if(toolBoxPageData.activePage == "PREVIEW") {
+        toolBoxPageData.activePage = "EDITOR";
     }
 };
 
@@ -1091,7 +1121,7 @@ const payStatusHandle = (payStatus) => {
     //支付状态 0:未支付,1:支付成功,2:支付失败,3:已关闭,4:已退款
     switch (payStatus) {
         case 1:
-            emits("payPalFinsh", { publishRes });
+            emits("postPublishFinish", { publishRes });
             showComType.value = "default";
             initParams();
             break;
@@ -1571,6 +1601,7 @@ const setFrontConfig = () => {
         if (res.code == 0) {
             paypalHtml.value = res.data.paypalHtml;
             lotteryMaxHourDuration = res.data.lotteryMaxHourDuration;
+            toolBoxPageData.postEditorLinkInputDescImage = res.data.postEditorLinkInputDescImage;
         }
     });
 };
@@ -1631,6 +1662,14 @@ const clickLeftTab = (params, index) => {
     publishType.value = params.type;
 }
 
+const onToolBoxPageChange = (params) => {
+    toolBoxPageData.activePage = params.page;
+};
+
+const toolBoxPublishFinish = (params) => {
+    emits("postPublishFinish", { publishRes: params.publishRes });
+}
+
 onMounted(() => {
     setFrontConfig();
     setPayConfig();
@@ -1638,10 +1677,6 @@ onMounted(() => {
     window.addEventListener('resize', function () {
         setDialogStyle(true);
     })
-
-    axios.get('https://www.baidu.com/s?wd=%E5%BA%86%E7%A5%9D%E9%A6%99%E6%B8%AF%E5%9B%9E%E5%BD%9225%E5%91%A8%E5%B9%B4%E5%A4%A7%E4%BC%9A&sa=fyb_n_homepage&rsv_dl=fyb_n_homepage&from=super&cl=3&tn=baidutop10&fr=top1000&rsv_idx=2&hisfilter=1').then(res => {
-        console.log(res);
-    })
 });
 </script>
 

+ 4 - 4
src/view/iframe/publish/publish.vue

@@ -4,7 +4,7 @@
         <give-dialog
             :dialogData="dialogData"
             @close="close"
-            @payPalFinsh="payPalFinsh" ></give-dialog>
+            @postPublishFinish="finish" ></give-dialog>
         <select-publish-content 
             :visible="selectVisible" 
             @close="hideSelectDialog"
@@ -29,7 +29,7 @@ const close = () => {
     hideIframe();
 };
 
-const payPalFinsh = (params) => {
+const finish = (params) => {
     close();
     window.parent.postMessage({ actionType: "IFRAME_SHOW_TWITTER_PUBLISH_DIALOG", publishRes: params.publishRes }, "*");
 };
@@ -39,11 +39,11 @@ const hideIframe = () => {
 };
 
 const hideSelectDialog = () => {
-    selectVisible.value = false;
+    close();
 }
 
 const selectPublishType = (params) => {
-    hideSelectDialog();
+    selectVisible.value = false;
     dialogData.visible = true;
     dialogData.type = params.type;
 }

+ 243 - 384
src/view/iframe/publish/tool-box/child/editor.vue

@@ -1,408 +1,267 @@
 <template>
-    <div class="editor-wrapper">
-        <div class="top">
-            <div class="title">
-                Enter Link to Embed in Tweet
-            </div>
-            <div class="search-wrapper">
-                <input class="input" type="text" placeholder="Enter link ">
-                <div class="btn">></div>
-            </div>
-            <div class="desc">
-                desc
+  <div class="editor-wrapper">
+    <div class="top">
+      <div class="title">
+        Enter Link to Embed in Tweet
+      </div>
+      <div class="search-wrapper">
+        <input class="input" type="text" v-model="siteUrl" placeholder="Enter link">
+        <div class="btn" @click="searchHandler">
+          <img :src="require('@/assets/svg/icon-tool-box-search-arrow.svg')" />
+        </div>
+      </div>
+      <div class="desc">
+        <img :src="linkInputDescImage" alt="">
+      </div>
+    </div>
+    <div class="bottom">
+      <div class="content">
+        <div class="cate-item history-wrapper" v-for="(item) in historyList" :key="item.cateId">
+          <div class="cate">
+            <img :src="item.iconPath">
+          </div>
+          <div class="app-list">
+            <div class="app" v-for="(app, idx) in item.apps" :key="idx">
+              <img :src="app.iconPath" alt="">
+              {{ app.name }}
             </div>
+          </div>
         </div>
-        <div class="bottom">
-            <div class="content">
-                <div class="cate-item history-wrapper" v-for="(item) in historyList" :key="item.cateId">
-                    <div class="cate">
-                        <img :src="item.iconPath">
-                    </div>
-                    <div class="app-list">
-                        <div class="app" v-for="(app, idx) in item.apps" :key="idx">
-                            <img :src="app.iconPath" alt="">
-                            {{app.name}}
-                        </div>
-                    </div>
-                </div>
-                <div class="cate-item" v-for="(item) in appList" :key="item.cateId">
-                    <div class="cate">
-                        <img :src="item.iconPath">
-                    </div>
-                    <div class="app-list">
-                        <div class="app" v-for="(app, idx) in item.apps" :key="idx">
-                            <img :src="app.iconPath" alt="">
-                            {{app.name}}
-                        </div>
-                    </div>
-                </div>
+        <div class="cate-item" v-for="(item) in appList" :key="item.cateId">
+          <div class="cate">
+            <img :src="item.iconPath">
+          </div>
+          <div class="app-list">
+            <div class="app" v-for="(app, idx) in item.apps" :key="idx" @click="clickAppHandler(app)">
+              <img :src="app.iconPath" alt="">
+              {{ app.name }}
             </div>
+          </div>
         </div>
+      </div>
     </div>
+  </div>
 </template>
 
 <script setup>
-import { ref, watch, reactive, defineProps, defineEmits, onMounted, nextTick } from "vue";
+import { ref, reactive, defineProps, defineEmits, onMounted } from "vue";
+import axios from 'axios';
+import { message } from "ant-design-vue";
+import { convertUrl, getAllPostEditorAppData } from "@/http/toolBoxApi";
+import { checkURL } from "@/uilts/help"
 
-let historyList = reactive([
-     {
-      "apps": [
-        {
-          "appId": 0,
-          "cateId": 0,
-          "createType": 0,
-          "defaultUrl": "string",
-          "guideData": "string",
-          "iconPath": "https://www.baidu.com/favicon.ico",
-          "interactType": 0,
-          "linkImagePath": "string",
-          "name": "history 1"
-        },
-         {
-          "appId": 0,
-          "cateId": 0,
-          "createType": 0,
-          "defaultUrl": "string",
-          "guideData": "string",
-          "iconPath": "https://www.baidu.com/favicon.ico",
-          "interactType": 0,
-          "linkImagePath": "string",
-          "name": "string2"
-        },
-         {
-          "appId": 0,
-          "cateId": 0,
-          "createType": 0,
-          "defaultUrl": "string",
-          "guideData": "string",
-          "iconPath": "https://www.baidu.com/favicon.ico",
-          "interactType": 0,
-          "linkImagePath": "string",
-          "name": "string1"
-        },
-      ],
-      "cateId": 0,
-      "iconPath": "https://www.baidu.com/favicon.ico",
-      "name": "history"
+const props = defineProps({
+    linkInputDescImage: {
+        type: String,
+        default: '',
     },
+});
+
+
+let siteUrl = ref('');
+
+let historyList = reactive([
+  // {
+  //   "apps": [
+  //     {
+  //       "appId": '',
+  //       "cateId": 0,
+  //       "createType": 0,
+  //       "defaultUrl": "string",
+  //       "guideData": "string",
+  //       "iconPath": "https://www.baidu.com/favicon.ico",
+  //       "interactType": 0,
+  //       "linkImagePath": "string",
+  //       "name": "history 1"
+  //     }
+  //   ],
+  //   "cateId": 0,
+  //   "iconPath": "https://www.baidu.com/favicon.ico",
+  //   "name": "history"
+  // },
 ])
 
-let appList = reactive([
-    {
-      "apps": [
-        {
-          "appId": 0,
-          "cateId": 0,
-          "createType": 0,
-          "defaultUrl": "string",
-          "guideData": "string",
-          "iconPath": "https://www.baidu.com/favicon.ico",
-          "interactType": 0,
-          "linkImagePath": "string",
-          "name": "string1"
-        },
-         {
-          "appId": 0,
-          "cateId": 0,
-          "createType": 0,
-          "defaultUrl": "string",
-          "guideData": "string",
-          "iconPath": "https://www.baidu.com/favicon.ico",
-          "interactType": 0,
-          "linkImagePath": "string",
-          "name": "string2"
-        },
-         {
-          "appId": 0,
-          "cateId": 0,
-          "createType": 0,
-          "defaultUrl": "string",
-          "guideData": "string",
-          "iconPath": "https://www.baidu.com/favicon.ico",
-          "interactType": 0,
-          "linkImagePath": "string",
-          "name": "string1"
-        },
-         {
-          "appId": 0,
-          "cateId": 0,
-          "createType": 0,
-          "defaultUrl": "string",
-          "guideData": "string",
-          "iconPath": "https://www.baidu.com/favicon.ico",
-          "interactType": 0,
-          "linkImagePath": "string",
-          "name": "string2"
-        },
-         {
-          "appId": 0,
-          "cateId": 0,
-          "createType": 0,
-          "defaultUrl": "string",
-          "guideData": "string",
-          "iconPath": "https://www.baidu.com/favicon.ico",
-          "interactType": 0,
-          "linkImagePath": "string",
-          "name": "string1"
-        },
-         {
-          "appId": 0,
-          "cateId": 0,
-          "createType": 0,
-          "defaultUrl": "string",
-          "guideData": "string",
-          "iconPath": "https://www.baidu.com/favicon.ico",
-          "interactType": 0,
-          "linkImagePath": "string",
-          "name": "string2"
-        },
-         {
-          "appId": 0,
-          "cateId": 0,
-          "createType": 0,
-          "defaultUrl": "string",
-          "guideData": "string",
-          "iconPath": "https://www.baidu.com/favicon.ico",
-          "interactType": 0,
-          "linkImagePath": "string",
-          "name": "string1"
-        },
-         {
-          "appId": 0,
-          "cateId": 0,
-          "createType": 0,
-          "defaultUrl": "string",
-          "guideData": "string",
-          "iconPath": "https://www.baidu.com/favicon.ico",
-          "interactType": 0,
-          "linkImagePath": "string",
-          "name": "string2"
-        },
-         {
-          "appId": 0,
-          "cateId": 0,
-          "createType": 0,
-          "defaultUrl": "string",
-          "guideData": "string",
-          "iconPath": "https://www.baidu.com/favicon.ico",
-          "interactType": 0,
-          "linkImagePath": "string",
-          "name": "string1"
-        },
-         {
-          "appId": 0,
-          "cateId": 0,
-          "createType": 0,
-          "defaultUrl": "string",
-          "guideData": "string",
-          "iconPath": "https://www.baidu.com/favicon.ico",
-          "interactType": 0,
-          "linkImagePath": "string",
-          "name": "string2"
-        },
-         {
-          "appId": 0,
-          "cateId": 0,
-          "createType": 0,
-          "defaultUrl": "string",
-          "guideData": "string",
-          "iconPath": "https://www.baidu.com/favicon.ico",
-          "interactType": 0,
-          "linkImagePath": "string",
-          "name": "string1"
-        },
-         {
-          "appId": 0,
-          "cateId": 0,
-          "createType": 0,
-          "defaultUrl": "string",
-          "guideData": "string",
-          "iconPath": "https://www.baidu.com/favicon.ico",
-          "interactType": 0,
-          "linkImagePath": "string",
-          "name": "string2"
-        }
-      ],
-      "cateId": 0,
-      "iconPath": "https://www.baidu.com/favicon.ico",
-      "name": "string"
-    },
-     {
-      "apps": [
-        {
-          "appId": 0,
-          "cateId": 0,
-          "createType": 0,
-          "defaultUrl": "string",
-          "guideData": "string",
-          "iconPath": "https://www.baidu.com/favicon.ico",
-          "interactType": 0,
-          "linkImagePath": "string",
-          "name": "s1"
-        },
-         {
-          "appId": 0,
-          "cateId": 0,
-          "createType": 0,
-          "defaultUrl": "string",
-          "guideData": "string",
-          "iconPath": "https://www.baidu.com/favicon.ico",
-          "interactType": 0,
-          "linkImagePath": "string",
-          "name": "s2"
-        }
-      ],
-      "cateId": 0,
-      "iconPath": "https://www.baidu.com/favicon.ico",
-      "name": "s0"
-    },
-     {
-      "apps": [
-        {
-          "appId": 0,
-          "cateId": 0,
-          "createType": 0,
-          "defaultUrl": "string",
-          "guideData": "string",
-          "iconPath": "https://www.baidu.com/favicon.ico",
-          "interactType": 0,
-          "linkImagePath": "string",
-          "name": "string1"
-        },
-         {
-          "appId": 0,
-          "cateId": 0,
-          "createType": 0,
-          "defaultUrl": "string",
-          "guideData": "string",
-          "iconPath": "https://www.baidu.com/favicon.ico",
-          "interactType": 0,
-          "linkImagePath": "string",
-          "name": "string2"
-        }
-      ],
-      "cateId": 0,
-      "iconPath": "https://www.baidu.com/favicon.ico",
-      "name": "string"
-    },
-]);
+let appList = ref();
+
+const emits = defineEmits(["changeShowCom"]);
+
+const searchHandler = async () => {
+  siteUrl.value = siteUrl.value.trim();
+  if(!checkURL(siteUrl.value)) {
+    //提示
+    return;
+  } 
+  const loadingHide = message.loading('loading...', 0);
+  let siteRes = await axios.get(siteUrl.value);
+
+  if(siteRes) {
+    if(siteRes.headers['content-type'].indexOf('text/html') < 0 || siteRes.request.status > 399) {
+      // 提示
+      return;
+    }
+  }
+
+  let convertRes = await convertUrl({params: {originUrl: siteUrl.value}});
+  let params = { convertUrl: siteUrl.value, originUrl: siteUrl.value, appId: '' };
+
+  loadingHide();
+
+  if(convertRes && convertRes.code == 0) {
+    let {convertUrl} = convertRes.data || {};
+    params.convertUrl = convertUrl;
+  }
+  emits('changeShowCom', params)
+}
+
+const clickAppHandler = (params) => {
+  let { createType, defaultUrl, appId, linkImagePath } = params;
+  switch (createType) {
+    case 1:
+      emits('changeShowCom', { convertUrl: defaultUrl, originUrl: defaultUrl, appId, linkImagePath })
+      break;
+    case 2:
+
+      break;
+  }
+}
 
+const getAppList = () => {
+  getAllPostEditorAppData({params: {}}).then(res => {
+    if(res.code == 0) {
+      appList.value = res.data || [];
+    }
+  })
+}
+
+onMounted(() => {
+  getAppList();
+})
 </script>
 
 <style lang="scss" scoped>
-    .editor-wrapper {
-        width: 100%;
+.editor-wrapper {
+  width: 100%;
+  height: 100%;
+
+  .top {
+    padding: 25px 40px 30px 40px;
+    border-bottom: 0.5px solid #D1D9DD;
+    box-sizing: border-box;
+
+    .title {
+      font-weight: 500;
+      font-size: 20px;
+    }
+
+    .search-wrapper {
+      margin: 20px 0;
+      border-radius: 8px;
+      width: 100%;
+      height: 49px;
+      display: flex;
+      align-items: center;
+
+      .input {
+        background: #F1F3F4;
+        border: none;
+        outline: none;
+        font-weight: 400;
+        font-size: 16px;
+        color: #636363;
         height: 100%;
-        .top {
-            padding: 25px 40px 30px 40px;
-            border-bottom: 0.5px solid #D1D9DD;
-            box-sizing: border-box;
-            
-            .title {
-                font-weight: 500;
-                font-size: 20px;
-            }
+        width: calc(100% - 49px);
+        padding-left: 20px;
+        border-bottom-left-radius: 8px;
+        border-top-left-radius: 8px;
+      }
 
-            .search-wrapper {
-                margin: 20px 0;
-                border-radius: 8px;
-                width: 100%;
-                height: 49px;
-                display: flex;
-                align-items: center;
-
-                .input {
-                    background: #F1F3F4;
-                    border: none;
-                    outline: none;
-                    font-weight: 400;
-                    font-size: 16px;
-                    color: #636363;
-                    height: 100%;
-                    width: calc(100% - 49px);
-                    padding-left: 20px;
-                    border-bottom-left-radius: 8px;
-                    border-top-left-radius: 8px;
-                }
-
-                .btn {
-                    width: 49px;
-                    height: 49px;
-                    background: #1D9BF0;
-                    border-bottom-right-radius: 8px;
-                    border-top-right-radius: 8px;
-                    display: flex;
-                    align-items: center;
-                    justify-content: center;
-                    cursor: pointer;
-                }
-            }
+      .btn {
+        width: 49px;
+        height: 49px;
+        background: #1D9BF0;
+        border-bottom-right-radius: 8px;
+        border-top-right-radius: 8px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        cursor: pointer;
+      }
+    }
+
+    .desc {
+      img {
+        width: 315px;
+        height: 14px;
+        object-fit: cover;
+      }
+    }
+  }
+
+  .bottom {
+    width: 100%;
+    height: calc(100% - 185px);
+    overflow-y: auto;
+
+    .content {
+      width: 100%;
+      padding: 36px 30px 20px 50px;
+      box-sizing: border-box;
+
+      .history-wrapper {
+        height: 110px !important;
+        overflow: hidden;
+
+        .app-list {
+          flex-wrap: nowrap !important;
         }
-        .bottom {
-            width: 100%;
-            height: calc(100% - 185px);
-            overflow-y: auto;
-
-            .content {
-                width: 100%;
-                padding: 36px 30px 20px 50px;
-                box-sizing: border-box;
-
-                .history-wrapper {
-                    height: 110px !important;
-                    overflow: hidden;
-
-                    .app-list {
-                        flex-wrap: nowrap !important;
-                    }
-                }
-
-                .cate-item {
-                    min-height: 110px;
-                    display: flex;
-                    margin-bottom: 12px;
-
-                    .cate {
-                        width: 20px;
-                        height: 110px;
-                        margin-right: 26px;
-                        display: flex;
-                        align-items: center;
-                        margin-top: -10px;
-
-                        img {
-                            width: 20px;
-                            height: 20px;
-                        }
-                    }
-
-                    .app-list {
-                        display: flex;
-                        align-content: center;
-                        flex-wrap: wrap;
-                        
-                        .app {
-                            display: flex;
-                            flex-direction: column;
-                            justify-content: center;
-                            align-items: center;
-                            width: 100px;
-                            height: 110px;
-                            font-weight: 500;
-                            font-size: 12px;
-                            color: #636363;
-                            cursor: pointer;
-
-                            img {
-                                width: 60px;
-                                height: 60px;
-                                border-radius: 10px;
-                                margin-bottom: 10px;
-                            }
-                        }
-                    }
-                }
+      }
+
+      .cate-item {
+        min-height: 110px;
+        display: flex;
+        margin-bottom: 12px;
+
+        .cate {
+          width: 20px;
+          height: 110px;
+          margin-right: 26px;
+          display: flex;
+          align-items: center;
+          margin-top: -10px;
+
+          img {
+            width: 20px;
+            height: 20px;
+          }
+        }
+
+        .app-list {
+          display: flex;
+          align-content: center;
+          flex-wrap: wrap;
+
+          .app {
+            display: flex;
+            flex-direction: column;
+            justify-content: center;
+            align-items: center;
+            width: 100px;
+            height: 110px;
+            font-weight: 500;
+            font-size: 12px;
+            color: #636363;
+            cursor: pointer;
+
+            img {
+              width: 60px;
+              height: 60px;
+              border-radius: 10px;
+              margin-bottom: 10px;
             }
+          }
         }
+      }
     }
+  }
+}
 </style>

+ 104 - 20
src/view/iframe/publish/tool-box/child/preview.vue

@@ -3,7 +3,7 @@
         <div class="top">
             <div class="card-container">
                 <!-- 安装之后的卡片样式 -->
-                <div v-show="installStatus" class="content-after" :style="{ 'width': reviewCanvasParams.width + 'px' }">
+                <div class="content-after" v-show="installStatus" :style="{ 'width': reviewCanvasParams.width + 'px' }">
                     <div class="head" :style="{ 'zoom': reviewCanvasParams.zoom }">
                         <img :src="userInfo.avatarUrl" class="avatar" />
                         <div class="article-wrapper">
@@ -15,11 +15,10 @@
                             </div>
                         </div>
                     </div>
-                    <div class="after-cover-wrapper-parent" :style="{ 'zoom': reviewCanvasParams.zoom }">
-                        <div class="after-cover-wrapper"
-                            style="width: 425px;height: 458px;border: 1px solid;border-radius: 10px">
-
-                        </div>
+                    <div class="after-cover-wrapper" :style="{ 'zoom': reviewCanvasParams.zoom }">
+                        <iframe
+                            style="height: 100%;width: 100%"
+                            :src="previewData.convertUrl"></iframe>
                     </div>
                 </div>
 
@@ -37,8 +36,11 @@
                             </div>
                         </div>
                     </div>
-                    <div class="card-wrapper" :style="{ 'zoom': reviewCanvasParams.zoom }" style="height: 284px">
-
+                    <div class="card-wrapper" :style="{ 'zoom': reviewCanvasParams.zoom }">
+                        <img class="cover" v-if="previewData.linkImagePath && previewData.appId" :src="previewData.linkImagePath" />
+                        <iframe class="iframe" 
+                            :src="previewData.convertUrl"
+                            v-else></iframe>
                     </div>
                 </div>
             </div>
@@ -46,18 +48,23 @@
                 Preview: <span>{{ installStatus ? 'After' : 'Before' }}</span> DeNet Installed
             </div>
         </div>
+        <div class="bottom">
+            <div class="btn" @click="publishHandler">NEXT</div>
+        </div>
     </div>
 </template>
 
 <script setup>
-import { ref, watch, reactive, defineProps, onMounted, nextTick, onUnmounted } from "vue";
+import { ref, defineEmits, reactive, defineProps, onMounted, nextTick, onUnmounted } from "vue";
+import { postPublish } from "@/http/publishApi";
 
 import { getChromeStorage } from "@/uilts/chromeExtension"
 import { getUser } from "@/http/publishApi"
 
-let installStatus = ref(true);
+let installStatus = ref(false);
 
 let userInfo = ref({});
+let submitIng = ref(false);
 
 let reviewCanvasParams = reactive({
     width: 620,
@@ -65,13 +72,19 @@ let reviewCanvasParams = reactive({
 });
 let timer = ref(null);
 
-defineProps({
-    amountFontSize: {
-        type: Number,
-        default: '56'
+const props = defineProps({
+    previewData: {
+        type: Object,
+        default: {
+            convertUrl: '',
+            originUrl: '',
+            appId: ''
+        }
     }
 })
 
+const emits = defineEmits(["publishFinish"]);
+
 const getUserInfo = (cb) => {
     getChromeStorage('userInfo', (res) => {
         if (res) {
@@ -121,6 +134,38 @@ const calcPreviewCanvasParams = () => {
     });
 }
 
+const publishHandler = () => {
+    if(submitIng.value) {
+        return;
+    }
+    let {convertUrl, originUrl, appId} = props.previewData;
+    let postBizData = {
+        convertUrl,
+        originUrl,
+        appId
+    };
+    let data = {
+        params: {
+            postBizData: JSON.stringify(postBizData),
+            postSrc: 1, // 1 twitter
+            postType: 3, //3 Tool box
+        },
+    };
+
+    submitIng.value = true;
+    postPublish(data).then((res) => {
+        submitIng.value = false;
+        if (res.code == 0) {
+            let publishRes = res.data;
+            emits("publishFinish", { publishRes });
+        } else {
+        }
+    })
+    .catch((err) => {
+        console.log(err);
+    });
+}
+
 onMounted(() => {
     calcPreviewCanvasParams();
     getUserInfo((res) => {
@@ -210,16 +255,15 @@ onUnmounted(() => {
                 border-radius: 13px;
                 box-sizing: border-box;
 
-                .after-cover-wrapper-parent {
+                .after-cover-wrapper {
                     position: absolute;
                     z-index: 100;
                     top: 108px;
                     left: 78px;
-
-                    .after-cover-wrapper {
-                        position: relative;
-                        width: 375px;
-                    }
+                    width: 425px;
+                    height: 458px;
+                    border-radius: 10px;
+                    // border: 1px solid #D1D9DD;
                 }
 
             }
@@ -235,6 +279,7 @@ onUnmounted(() => {
 
                 .card-wrapper {
                     width: 491px;
+                    height: 284px;
                     border: 1px solid #D1D9DD;
                     background: #ffffff;
                     box-sizing: border-box;
@@ -244,6 +289,20 @@ onUnmounted(() => {
                     border-radius: 16px;
                     left: 73px;
                     top: 100px;
+
+                    .iframe {
+                        height: 100%;
+                        width: 100%;
+                        border: none;    
+                        pointer-events: none;
+                        cursor: default;
+                    }
+
+                    .cover {
+                        width: 100%;
+                        height: 100%;
+                        object-fit: contain;
+                    }
                 }
             }
 
@@ -260,5 +319,30 @@ onUnmounted(() => {
         }
     }
 
+    .bottom {
+        width: 100%;
+        height: 80px;
+        box-shadow: 0px -1px 0px #ECECEC;
+        box-sizing: border-box;
+        border-bottom-left-radius: 16px;
+        display: flex;
+        align-items: center;
+        justify-content: flex-end;
+        .btn {
+            width: 200px;
+            height: 50px;
+            background: #1D9BF0;
+            border-radius: 10000px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            font-weight: 700;
+            font-size: 18px;
+            color: #fff;
+            margin-right: 30px;
+            cursor: pointer;
+        }
+    }
+
 }
 </style>

+ 50 - 5
src/view/iframe/publish/tool-box/index.vue

@@ -1,18 +1,63 @@
 <template>
     <div class="page-wrapper">
-        <editor v-if="showCom == 'EDITOR'" />  
-        <preview v-else />
+        <editor v-show="showCom == 'EDITOR'" :linkInputDescImage="pageData.linkInputDescImage" @changeShowCom="changeShowCom" />  
+        <preview v-show="showCom == 'PREVIEW'" :previewData="previewData" 
+        @publishFinish="publishFinish" />
     </div>
 </template>
 
 <script setup>
-import { ref, watch, reactive, defineProps, defineEmits, onMounted, nextTick, provide } from "vue";
-
-let showCom = ref('PERVIEW'); //PERVIEW
+import { ref, reactive, watch, defineProps, defineEmits } from "vue";
 
 import editor from '@/view/iframe/publish/tool-box/child/editor.vue'
 import preview from '@/view/iframe/publish/tool-box/child/preview.vue'
 
+const props = defineProps({
+    pageData: {
+        type: Object,
+        default: {
+            linkInputDescImage: ''
+        }
+    },
+    activePage: {
+        type: String,
+        default: 'EDITOR', // EDITOR PREVIEW
+    },
+});
+
+const emits = defineEmits(["onToolBoxPageChange"]);
+
+watch(
+    () => props.activePage,
+    (newVal) => {
+        showCom.value = newVal;
+    },
+    {
+        deep: true
+    }
+);
+
+let showCom = ref('EDITOR'); 
+let previewData = reactive({
+    convertUrl: '',
+    originUrl: '',
+    appId: '',
+})
+
+const changeShowCom = (params) => {
+    showCom.value = 'PREVIEW';
+    previewData.convertUrl = params.convertUrl;
+    previewData.originUrl = params.originUrl;
+    previewData.appId = params.appId
+    previewData.linkImagePath = params.linkImagePath || '';
+
+    emits("onPageChange", {page: showCom.value});
+}
+
+const publishFinish = (params) => {
+    emits("toolBoxPublishFinish", params);
+}
+
 </script>
 
 <style lang="scss" scoped>