ソースを参照

feat:download组件

ananzhusen 1 年間 前
コミット
c316ccccfd

+ 1 - 0
public/view/meta2d-vue3/index.html

@@ -8,6 +8,7 @@
   </head>
   <body>
     <div id="app"></div>
+    <script src="js/r.js"></script>
     <script src="js/lcjs.iife.js"></script>
     <script src="js/marked.min.js"></script>
     <script crossorigin="anonymous" integrity="sha512-ppWbHq6q2f7HAwS481w6qikuC0XEeBnmkRg6KWnWg3zSIbJwWWBgsCDMAxzSB7SVqXzWwSYQ2s8TSJKjnaikMg==" src="https://lib.baomitu.com/echarts/5.1.2/echarts.min.js"></script>

+ 8 - 0
public/view/meta2d-vue3/src/components/Meta2d.vue

@@ -41,10 +41,18 @@ onMounted(async () => {
     var data = JSON.parse(text);
     data.locked = 1;
     data.rule = false;
+    window.userId = data.userId;
     meta2d.open(data);
     // meta2d.fitSizeView(true, 0); //大屏充满屏幕
     // meta2d.fitView(true,0); //充满屏幕
   });
+
+
+  //注册控件
+  setTimeout(async()=>{
+    window.registerIot(window.userId,'/js/2d-components.js');
+    meta2d.render();
+  },1000);
 });
 
 function _fetch(url, cb) {

+ 3 - 1
src/services/download.ts

@@ -113,6 +113,7 @@ export const getDownloadList = (meta2dData: any, path: string = 'v') => {
     '/view/js/highcharts-more.js',
     // '/view/js/2d-components.js',
 
+    '/view/js/r.js',
     '/view/index.html',
     '/view/favicon.ico',
     '/view/view.conf',
@@ -255,7 +256,7 @@ export const getComponentPurchased = async (list: any) => {
   return res.list;
 };
 
-export const get2dComponentJs = async (names: string[]) => {
+export const get2dComponentJs = async (names: string[]=components) => {
   let list = [];
   names.forEach((item) => {
     list.push({
@@ -287,3 +288,4 @@ export const getGoods = async () => {
   // console.log("res",res);
   return res;
 };
+

+ 9 - 2
src/views/Preview.vue

@@ -52,6 +52,12 @@ const dealWithMessage = (e) => {
           doDownload(data.path);
         } else if (data.name === 'prePayList') {
           doGetPayList();
+        } else if (data.name === 'downloadVue3') {
+
+        } else if (data.name === 'downloadVue2') {
+
+        } else if (data.name === 'downloadReact') {
+
         }
       } else {
         meta2d.emit(data.name);
@@ -92,8 +98,8 @@ const opened = () => {
     (meta2d.store.data as any).scaleMode === '3'
       ? 'height'
       : (meta2d.store.data as any).scaleMode === '2'
-      ? 'width'
-      : true;
+        ? 'width'
+        : true;
   meta2d.fitSizeView(fit, 10);
   meta2d.setOptions({
     scroll: (meta2d.store.data as any).scroll,
@@ -139,6 +145,7 @@ onUnmounted(() => {
 .preview {
   width: 100vw;
   height: 100vh;
+
   /* background-color: var(--color-background-editor); */
   .meta2d-canvas {
     width: 100%;

+ 212 - 185
src/views/components/Header.vue

@@ -4,13 +4,8 @@
       <img src="/favicon.ico" />
       <span> {{ enterprise.name }}</span>
     </a>
-    <t-dropdown
-      :minColumnWidth="200"
-      :maxHeight="560"
-      :delay2="[10, 150]"
-      overlayClassName="header-dropdown"
-      trigger1="click"
-    >
+    <t-dropdown :minColumnWidth="200" :maxHeight="560" :delay2="[10, 150]" overlayClassName="header-dropdown"
+      trigger1="click">
       <a> 文件 </a>
       <t-dropdown-menu>
         <t-dropdown-item @click="newFile">
@@ -85,12 +80,7 @@
         </t-dropdown-item>
       </t-dropdown-menu>
     </t-dropdown>
-    <t-dropdown
-      :minColumnWidth="180"
-      :maxHeight="500"
-      :delay2="[10, 150]"
-      overlayClassName="header-dropdown"
-    >
+    <t-dropdown :minColumnWidth="180" :maxHeight="500" :delay2="[10, 150]" overlayClassName="header-dropdown">
       <a> 编辑 </a>
       <t-dropdown-menu>
         <t-dropdown-item>
@@ -142,12 +132,7 @@
         </t-dropdown-item>
       </t-dropdown-menu>
     </t-dropdown>
-    <t-dropdown
-      :minColumnWidth="180"
-      :maxHeight="500"
-      :delay2="[10, 150]"
-      overlayClassName="header-dropdown"
-    >
+    <t-dropdown :minColumnWidth="180" :maxHeight="500" :delay2="[10, 150]" overlayClassName="header-dropdown">
       <a> 工具 </a>
       <t-dropdown-menu>
         <t-dropdown-item>
@@ -200,30 +185,19 @@
         </t-dropdown-item>
         <t-dropdown-item>
           <a @click="onToggleAnchor">
-            <div
-              class="flex"
-              :style="{
-                color: showAnchor ? '' : '#4f5b75',
-              }"
-            >
+            <div class="flex" :style="{
+              color: showAnchor ? '' : '#4f5b75',
+            }">
               添加/删除锚点 <span class="flex-grow"></span> A
             </div>
           </a>
         </t-dropdown-item>
       </t-dropdown-menu>
     </t-dropdown>
-    <t-dropdown
-      :minColumnWidth="180"
-      :maxHeight="500"
-      :delay2="[10, 150]"
-      overlayClassName="header-dropdown"
-    >
+    <t-dropdown :minColumnWidth="180" :maxHeight="500" :delay2="[10, 150]" overlayClassName="header-dropdown">
       <a> 帮助 </a>
       <t-dropdown-menu>
-        <t-dropdown-item
-          v-for="item in enterprise.helps"
-          :divider="item.divider"
-        >
+        <t-dropdown-item v-for="item in enterprise.helps" :divider="item.divider">
           <a :href="item.url" target="_blank">{{ item.name }}</a>
         </t-dropdown-item>
       </t-dropdown-menu>
@@ -252,31 +226,19 @@
       <app-icon />
       2D可视化
     </a>
-    <t-dropdown
-      v-if="user.id"
-      :minColumnWidth="200"
-      :maxHeight="500"
-      :delay2="[10, 150]"
-      overlayClassName="custom-dropdown header"
-    >
+    <t-dropdown v-if="user.id" :minColumnWidth="200" :maxHeight="500" :delay2="[10, 150]"
+      overlayClassName="custom-dropdown header">
       <a style="margin-left: 32px; margin-right: 12px">
-        <t-avatar
-          size="small"
-          :image="user.avatarUrl ? user.avatarUrl : baseUrl + 'img/avatar.png'"
-        />
+        <t-avatar size="small" :image="user.avatarUrl ? user.avatarUrl : baseUrl + 'img/avatar.png'" />
       </a>
       <t-dropdown-menu>
         <t-dropdown-item divider="true">
           <a :href="enterprise.account">
             {{ user.username }}
-            <label
-              class="ml-16 vip-label"
-              :style="{
-                color: user.limit > 1 ? '#ff4000' : '#D5C781',
-                background: user.limit > 1 ? '#ff400030' : '#D5C78133',
-              }"
-              >VIP</label
-            >
+            <label class="ml-16 vip-label" :style="{
+              color: user.limit > 1 ? '#ff4000' : '#D5C781',
+              background: user.limit > 1 ? '#ff400030' : '#D5C78133',
+            }">VIP</label>
           </a>
         </t-dropdown-item>
         <t-dropdown-item divider="true">
@@ -308,20 +270,9 @@
       </a>
     </div>
   </div>
-  <t-dialog
-    v-if="payListDialog.show"
-    v-model:visible="payListDialog.show"
-    class="pay-dialog"
-    header="图纸用到的企业图形库"
-    :close-on-overlay-click="false"
-    :top="95"
-    :width="700"
-    cancel-btn="跳过"
-    confirm-btn="结算(不支持退款)"
-    @cancel="skipPay"
-    @close="payListDialog.show = false"
-    @confirm="prePay"
-  >
+  <t-dialog v-if="payListDialog.show" v-model:visible="payListDialog.show" class="pay-dialog" header="图纸用到的企业图形库"
+    :close-on-overlay-click="false" :top="95" :width="700" cancel-btn="跳过" confirm-btn="结算(不支持退款)" @cancel="skipPay"
+    @close="payListDialog.show = false" @confirm="prePay">
     <div class="pay-line">
       <div></div>
       <div>已购买</div>
@@ -329,11 +280,7 @@
     </div>
     <div class="pay-body">
       <t-collapse defaultExpandAll>
-        <t-collapse-panel
-          v-if="[...prePayList.pngs].length"
-          value="0"
-          :header="data.goods[0].type"
-        >
+        <t-collapse-panel v-if="[...prePayList.pngs].length" value="0" :header="data.goods[0].type">
           <template #headerRightContent>
             <t-space size="small">
               <t-checkbox v-model="data.goods[0].checked"></t-checkbox>
@@ -350,16 +297,13 @@
               }}
             </div>
             <div>
-              <check-icon
-                v-show="data.purchasedList.some((item) => item.name === pngPen)"
-                style="color: #4480f9ff"
-              />
+              <check-icon v-show="data.purchasedList.some((item) => item.name === pngPen)" style="color: #4480f9ff" />
             </div>
             <div>
               {{
                 data.purchasedList.some((item) => item.name === pngPen)
-                  ? 0
-                  : data.goods[0].unitPrice
+                ? 0
+                : data.goods[0].unitPrice
               }}
             </div>
           </div>
@@ -372,11 +316,7 @@
             <p v-else>已选择0个图元 小计:¥0</p>
           </div>
         </t-collapse-panel>
-        <t-collapse-panel
-          v-if="[...prePayList.iotPens].length"
-          value="1"
-          :header="data.goods[1].type"
-        >
+        <t-collapse-panel v-if="[...prePayList.iotPens].length" value="1" :header="data.goods[1].type">
           <template #headerRightContent>
             <t-space size="small">
               <t-checkbox v-model="data.goods[1].checked"></t-checkbox>
@@ -390,16 +330,13 @@
               {{ iotPensMap[iotPen]?.name || iotPen }}
             </div>
             <div>
-              <check-icon
-                v-show="data.purchasedList.some((item) => item.name === iotPen)"
-                style="color: #4480f9ff"
-              />
+              <check-icon v-show="data.purchasedList.some((item) => item.name === iotPen)" style="color: #4480f9ff" />
             </div>
             <div>
               {{
                 data.purchasedList.some((item) => item.name === iotPen)
-                  ? 0
-                  : data.goods[1].unitPrice
+                ? 0
+                : data.goods[1].unitPrice
               }}
             </div>
           </div>
@@ -412,11 +349,7 @@
             <p v-else>已选择0个图元 小计:¥0</p>
           </div>
         </t-collapse-panel>
-        <t-collapse-panel
-          v-if="[...prePayList.svgPens].length"
-          value="2"
-          :header="data.goods[2].type"
-        >
+        <t-collapse-panel v-if="[...prePayList.svgPens].length" value="2" :header="data.goods[2].type">
           <template #headerRightContent>
             <t-space size="small">
               <t-checkbox v-model="data.goods[2].checked"></t-checkbox>
@@ -429,21 +362,13 @@
               }}个)。【说明】检查到当前项目为老版本格式,需要购买整套SVG线性图元。
             </div>
             <div>
-              <check-icon
-                v-show="data.goods[2].unPurchased === 0"
-                style="color: #4480f9ff"
-              />
+              <check-icon v-show="data.goods[2].unPurchased === 0" style="color: #4480f9ff" />
             </div>
           </template>
           <template v-else>
             <div v-for="svgPen in prePayList.svgPens" class="pay-line">
               <div>
-                <t-image
-                  class="pay-svg"
-                  :src="svgPen"
-                  :lazy="true"
-                  fit="contain"
-                />
+                <t-image class="pay-svg" :src="svgPen" :lazy="true" fit="contain" />
                 {{
                   svgPen.slice(
                     svgPen.lastIndexOf('/') + 1,
@@ -452,18 +377,14 @@
                 }}
               </div>
               <div>
-                <check-icon
-                  v-show="
-                    data.purchasedList.some((item) => item.name === svgPen)
-                  "
-                  style="color: #4480f9ff"
-                />
+                <check-icon v-show="data.purchasedList.some((item) => item.name === svgPen)
+                    " style="color: #4480f9ff" />
               </div>
               <div>
                 {{
                   data.purchasedList.some((item) => item.name === svgPen)
-                    ? 0
-                    : data.goods[2].unitPrice
+                  ? 0
+                  : data.goods[2].unitPrice
                 }}
               </div>
             </div>
@@ -477,11 +398,7 @@
             <p v-else>已选择0个图元 小计:¥0</p>
           </div>
         </t-collapse-panel>
-        <t-collapse-panel
-          v-if="[...prePayList.jsPens].length"
-          value="3"
-          :header="data.goods[3].type"
-        >
+        <t-collapse-panel v-if="[...prePayList.jsPens].length" value="3" :header="data.goods[3].type">
           <template #headerRightContent>
             <t-space size="small">
               <t-checkbox v-model="data.goods[3].checked"></t-checkbox>
@@ -490,16 +407,13 @@
           <div v-for="jsPen in prePayList.jsPens" class="pay-line">
             <div style="margin-left: 16px">{{ jsPen }}</div>
             <div>
-              <check-icon
-                v-show="data.purchasedList.some((item) => item.name === jsPen)"
-                style="color: #4480f9ff"
-              />
+              <check-icon v-show="data.purchasedList.some((item) => item.name === jsPen)" style="color: #4480f9ff" />
             </div>
             <div>
               {{
                 data.purchasedList.some((item) => item.name === jsPen)
-                  ? 0
-                  : data.goods[3].unitPrice
+                ? 0
+                : data.goods[3].unitPrice
               }}
             </div>
           </div>
@@ -523,24 +437,10 @@
       </div>
     </div>
   </t-dialog>
-  <t-dialog
-    v-if="wechatPayDialog.show"
-    v-model:visible="wechatPayDialog.show"
-    class="pay-dialog"
-    header="乐吾乐收银台"
-    :close-on-overlay-click="false"
-    :top="95"
-    :width="700"
-    confirm-btn="支付完成"
-    :cancel-btn="null"
-    @close="finishPay"
-    @confirm="finishPay"
-  >
-    <WechatPay
-      :order="data.order"
-      :code-url="data.order.codeUrl"
-      @success="onSuccess"
-    />
+  <t-dialog v-if="wechatPayDialog.show" v-model:visible="wechatPayDialog.show" class="pay-dialog" header="乐吾乐收银台"
+    :close-on-overlay-click="false" :top="95" :width="700" confirm-btn="支付完成" :cancel-btn="null" @close="finishPay"
+    @confirm="finishPay">
+    <WechatPay :order="data.order" :code-url="data.order.codeUrl" @success="onSuccess" />
   </t-dialog>
 </template>
 
@@ -601,11 +501,12 @@ import {
   getComponentPurchased,
   get2dComponentJs,
   getTemPngs,
-  getGoods,
+  getGoods
 } from '@/services/download';
 import { formComponents } from '@/services/defaults';
 import WechatPay from './WechatPay.vue';
 
+
 const { enterprise } = useEnterprise();
 const router = useRouter();
 const route = useRoute();
@@ -656,6 +557,7 @@ let payListNum = 0;
 let comparePayListNum = 0;
 // let purchasedList = []; //已购买列表
 const iotPensMap = {};
+let downloadType: Frame = null;
 // const payPrice = ref(0);
 
 const getIotPensMap = () => {
@@ -713,7 +615,11 @@ const dealWithMessage = async (e) => {
               ![...prePayList.svgPens].length
             ) {
               //直接下载
-              preDownload(meta2d.data());
+              if (downloadType === Frame.html) {
+                preDownload(meta2d.data());
+              } else {
+                preFrameDownload(downloadType);
+              }
             } else {
               await showPayListDialog();
             }
@@ -1024,6 +930,7 @@ const zip3D = (name: string) => {
         pen.calculative.singleton.div.children[0] as HTMLIFrameElement
       ).contentWindow.postMessage(
         JSON.stringify({
+          type: 1,
           name,
           id: params.id,
         }),
@@ -1032,6 +939,34 @@ const zip3D = (name: string) => {
     });
   }
 };
+
+const zip2D = (name: string) => {
+  const pen_2d = meta2d.store.data.pens.filter(
+    (pen) =>
+      pen.name === 'iframe' &&
+      (pen.iframe.indexOf('2d.le5le.com') !== -1 ||
+        pen.iframe.indexOf('/2d/') !== -1 ||
+        pen.iframe.indexOf('v.le5le.com') !== -1 ||
+        pen.iframe.indexOf('/v/') !== -1)
+  );
+  if (pen_2d && pen_2d.length) {
+    //存在3d场景
+    pen_2d.forEach((pen) => {
+      //发送消息
+      // let params = queryURLParams(pen.iframe.split('?')[1]);
+      (
+        pen.calculative.singleton.div.children[0] as HTMLIFrameElement
+      ).contentWindow.postMessage(
+        JSON.stringify({
+          name,
+          type: 1,
+        }),
+        '*'
+      );
+    });
+  }
+}
+
 function queryURLParams(value?: string) {
   let url = value || window.location.href.split('?')[1];
   const urlSearchParams = new URLSearchParams(url);
@@ -1050,7 +985,11 @@ const downloadHtml = async () => {
     gotoAccount();
     return;
   }
+  downloadType = Frame.html;
+  await preGetPayList(Frame.html);
+};
 
+const preGetPayList = async (key: Frame) => {
   //图形库需要购买
   const meta2dData = meta2d.data();
   let list = getPayList(meta2dData);
@@ -1095,12 +1034,18 @@ const downloadHtml = async () => {
       !list.iotPens.length &&
       !list.svgPens.length
     ) {
-      preDownload(meta2dData);
+      if (key === Frame.html) {
+        preDownload(meta2dData);
+      } else {
+        preFrameDownload(key);
+      }
     } else {
       await showPayListDialog();
     }
   }
-};
+}
+
+
 
 const showPayListDialog = async () => {
   data.goods = await getGoods();
@@ -1142,10 +1087,10 @@ const showPayListDialog = async () => {
       price += item.unPurchased * item.unitPrice;
     }
   });
-  if(price===0){
+  if (price === 0) {
     skipPay();//如果计算价格为0,直接下载
-  }else{
-   payListDialog.show = true;
+  } else {
+    payListDialog.show = true;
   }
 };
 
@@ -1153,7 +1098,7 @@ const preDownload = (meta2dData: any) => {
   MessagePlugin.info('正在下载打包中,可能需要几分钟,请耐心等待...');
   iframeNum = 0;
   compareNum = 0;
-
+  meta2dData.userId = user.id;
   const pen_3d = meta2dData.pens.filter(
     (pen) =>
       pen.name === 'iframe' &&
@@ -1303,7 +1248,6 @@ const saveDownload = async () => {
     }
   });
   //js线性图元 由对应页面处理
-
   //SVG线性图元
   if ([...prePayList.svgPens].length) {
     let purchased = data.purchasedList?.filter(
@@ -1331,7 +1275,7 @@ const saveDownload = async () => {
       });
     } else {
       list.forEach((item) => {
-        if (item.data && item.path.indexOf('/projects/v') !== 1) {
+        if (item.data && item.path.indexOf('/projects/v') !== -1 && item.path.indexOf('/projects/v/png/') === -1) {
           //2d 图纸数据
           let meta2dData = JSON.parse(item.data);
           meta2dData.pens.forEach((pen) => {
@@ -1428,7 +1372,8 @@ async function zipBkImg(zip: JSZip) {
   let img = meta2d.store.data.bkImage;
   if (img) {
     if (img.startsWith('/') || img.startsWith(cdn) || img.startsWith(upCdn)) {
-      await zipImage(zip, img);
+      const pngs = await getTemPngs([img.replace(cdn, '').replace(upCdn, '')]);
+      await zipImage(zip, img, pngs[img.replace(cdn, '').replace(upCdn, '')]);
     }
   }
 }
@@ -1437,6 +1382,7 @@ enum Frame {
   vue2,
   vue3,
   react,
+  html
 }
 
 const downloadVue3 = async () => {
@@ -1458,25 +1404,29 @@ async function downloadAsFrame(type: Frame) {
     MessagePlugin.warning(noLoginTip);
     return;
   }
-
-  // if (!user.isVip) {
-  //   gotoAccount();
-  //   return;
-  // }
   if (user.vipDesc !== '旗舰会员') {
     MessagePlugin.info('需要开通旗舰会员~');
     gotoAccount();
     return;
   }
+  downloadType = type;
+  await preGetPayList(type);
+}
+
+const preFrameDownload = async (type: Frame) => {
   frameFlag = type;
   MessagePlugin.info('正在下载打包中,可能需要几分钟,请耐心等待...');
   zip3D(
     type === Frame.vue3 ? 'toVue3' : type === Frame.vue2 ? 'toVue2' : 'toReact'
   );
-  const data: Meta2dBackData = meta2d.data();
+  zip2D(
+    type === Frame.vue3 ? 'downloadVue3' : type === Frame.vue2 ? 'downloadVue2' : 'downloadReact'
+  );
+  const data: any = meta2d.data();
   if (data._id) delete data._id;
   if (data.id) delete data.id;
   if (data.image) delete data.image;
+  data.userId = user.id;
   checkData(data);
   const [{ default: JSZip }, { saveAs }] = await Promise.all([
     import('jszip'),
@@ -1486,12 +1436,44 @@ async function downloadAsFrame(type: Frame) {
   let _fileName =
     (data.name && data.name.replace(/\//g, '_').replace(/:/g, '_')) ||
     'le5le.meta2d';
+  //处理付费svg
+  if (Object.keys(data.paths).length >= 3) {
+    //简单判断有无svg图元
+    const res: any = await axios.post('/api/paid/2d/component', {
+      type: 'SVG线性图元',
+    });
+    if (res.list.length === 1 && !res.list[0].name) {
+      //已经购买全部
+      for (let key of Object.keys(data.paths)) {
+        let path = data.paths[key];
+        if (
+          path.indexOf('-1.18Zm4-1') !== -1 ||
+          path.indexOf('-1.19Zm4-1') !== -1 ||
+          path.indexOf('2.85ZM') !== -1 ||
+          path.indexOf('-1-2.39.3') !== -1
+        ) {
+          data.paths[key] = '';
+        }
+      }
+    } else {
+      //购买部分
+      let purchasedList = res.list.map((i) => i.name);
+      data.pens.forEach((pen) => {
+        if (pen.name === 'svgPath' && pen.svgUrl) {
+          if (purchasedList.includes(pen.svgUrl)) {
+            pen.pathId = null;
+          }
+        }
+      });
+
+    }
+  }
+
   const _zip: any = zip.folder(`${_fileName}`);
   _zip.file(
-    `${
-      type === Frame.vue3
-        ? 'meta2d-vue3'
-        : type === Frame.vue2
+    `${type === Frame.vue3
+      ? 'meta2d-vue3'
+      : type === Frame.vue2
         ? 'meta2d-vue2'
         : 'meta2d-react'
     }/public/json/data.json`,
@@ -1504,14 +1486,35 @@ async function downloadAsFrame(type: Frame) {
     type === Frame.vue3
       ? zipVue3Files(_zip)
       : type === Frame.vue2
-      ? zipVue2Files(_zip)
-      : zipReactFiles(_zip),
+        ? zipVue2Files(_zip)
+        : zipReactFiles(_zip),
+    zipIotPens(_zip),
   ]);
   const blob = await zip.generateAsync({ type: 'blob' });
   saveAs(blob, `${_fileName}.zip`);
   frameFlag = -1;
 }
 
+async function zipIotPens(zip: JSZip) {
+  //处理控件
+  const js = await get2dComponentJs();
+  zip.file(`${frameFlag === Frame.vue3
+      ? 'meta2d-vue3'
+      : frameFlag === Frame.vue2
+        ? 'meta2d-vue2'
+        : 'meta2d-react'
+    }/public/js/2d-components.js`, js, { createFolders: true });
+  const res: Blob = await axios.get('/view/js/r.js', {
+    responseType: 'blob',
+  });
+  zip.file(`${frameFlag === Frame.vue3
+      ? 'meta2d-vue3'
+      : frameFlag === Frame.vue2
+        ? 'meta2d-vue2'
+        : 'meta2d-react'
+    }/public/js/r.js`, res, { createFolders: true });
+}
+
 async function zipJs(zip: JSZip) {
   const files = ['/view/js/marked.min.js', '/view/js/lcjs.iife.js'];
   await Promise.all(
@@ -1520,10 +1523,9 @@ async function zipJs(zip: JSZip) {
         responseType: 'blob',
       });
       zip.file(
-        `${
-          frameFlag === Frame.vue3
-            ? 'meta2d-vue3'
-            : frameFlag === Frame.vue2
+        `${frameFlag === Frame.vue3
+          ? 'meta2d-vue3'
+          : frameFlag === Frame.vue2
             ? 'meta2d-vue2'
             : 'meta2d-react'
         }/public` + filePath.replace('/view', ''),
@@ -1681,26 +1683,27 @@ async function zipImages(zip: JSZip, pens: Pen[]) {
     }
     // 无需递归遍历子节点,现在所有的节点都在外层
   }
-  await Promise.all(images.map((image) => zipImage(zip, image)));
+  //付费pngs
+  const pngs = await getTemPngs(images.map(i => i.replace(cdn, '').replace(upCdn, '')));
+  await Promise.all(images.map((image) => zipImage(zip, image, pngs[image.replace(cdn, '').replace(upCdn, '')])));
 }
 
-async function zipImage(zip: JSZip, image: string) {
-  const res: Blob = await axios.get(image, {
+async function zipImage(zip: JSZip, image: string, temImage?: string) {
+  const res: Blob = await axios.get(temImage || image, {
     responseType: 'blob',
-    params: {
-      isZip: true,
-    },
+    // params: {
+    //   isZip: true,
+    // },
   });
   zip.file(
     (frameFlag === -1
       ? ''
-      : `${
-          frameFlag === Frame.vue3
-            ? 'meta2d-vue3'
-            : frameFlag === Frame.vue2
-            ? 'meta2d-vue2'
-            : 'meta2d-react'
-        }/public`) + (cdn ? image.replace(cdn, '').replace(upCdn, '') : image),
+      : `${frameFlag === Frame.vue3
+        ? 'meta2d-vue3'
+        : frameFlag === Frame.vue2
+          ? 'meta2d-vue2'
+          : 'meta2d-react'
+      }/public`) + (cdn ? image.replace(cdn, '').replace(upCdn, '') : image),
     res,
     {
       createFolders: true,
@@ -1958,7 +1961,11 @@ const prePay = async () => {
 
 const skipPay = () => {
   //跳过支付,直接下载
-  preDownload(meta2d.data());
+  if (downloadType === Frame.html) {
+    preDownload(meta2d.data());
+  } else {
+    preFrameDownload(downloadType);
+  }
 };
 
 const finishPay = async () => {
@@ -1970,7 +1977,11 @@ const finishPay = async () => {
     MessagePlugin.success('支付成功');
     wechatPayDialog.show = false;
     payListDialog.show = false;
-    preDownload(meta2d.data());
+    if (downloadType === Frame.html) {
+      preDownload(meta2d.data());
+    } else {
+      preFrameDownload(downloadType);
+    }
   } else {
     MessagePlugin.error('支付失败');
     wechatPayDialog.show = false;
@@ -2009,6 +2020,7 @@ const onSuccess = (success: boolean) => {
   background-color: var(--color-background);
   position: relative;
   z-index: 2;
+
   .logo {
     display: flex;
     padding: 0 16px;
@@ -2065,14 +2077,18 @@ const onSuccess = (success: boolean) => {
   height: 300px;
   overflow-y: scroll;
   margin-bottom: 30px;
+
   .t-collapse {
     border: 0px;
+
     :deep(.t-collapse-panel__wrapper .t-collapse-panel__header) {
       border-bottom: 0px;
     }
+
     :deep(.t-collapse-panel__wrapper .t-collapse-panel__body) {
       background: #fff0;
       border-bottom: 0px;
+
       .t-collapse-panel__content {
         padding: 0;
         color: #c1c8d7;
@@ -2080,25 +2096,30 @@ const onSuccess = (success: boolean) => {
     }
   }
 }
+
 .pay-line {
   display: flex;
   height: 54px;
   background-color: #afcaff0a;
   margin-top: 1px;
+
   div {
     width: 30%;
     text-align: center;
     line-height: 54px;
+
     :deep(.t-image) {
       width: 40px;
       height: 40px;
       margin-top: 7px;
     }
+
     :deep(.pay-svg) {
       .t-image {
         background: #fff;
       }
     }
+
     .l-icon {
       width: 40px;
       height: 40px;
@@ -2107,30 +2128,35 @@ const onSuccess = (success: boolean) => {
     }
   }
 
-  & > div:first-child {
+  &>div:first-child {
     width: 40%;
     display: flex;
   }
 }
+
 .pay-tip {
   height: 54px;
   width: 100%;
   position: relative;
+
   p {
     position: absolute;
     right: 16px;
     color: var(--color-desc);
   }
 }
+
 .pay-footer {
   margin-bottom: -42px;
   position: relative;
+
   .pay-price {
     position: absolute;
     right: 215px;
     /* margin-left: 50px; */
     align-items: flex-end;
     line-height: 10px;
+
     /* p{
     vertical-align: bottom;
     line-height: normal;
@@ -2141,6 +2167,7 @@ const onSuccess = (success: boolean) => {
       color: #4480f9;
       line-height: 20px;
     }
+
     p:nth-child(1) {
       font-size: 14px;
       color: #4480f9;