1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764 |
- <template>
- <div class="app-header">
- <a class="logo" :href="enterprise.home" target="_blank">
- <img src="/favicon.ico" />
- <span> {{ enterprise.name }}</span>
- </a>
- <t-dropdown
- :minColumnWidth="200"
- :maxHeight="560"
- :delay2="[10, 150]"
- overlayClassName="header-dropdown"
- trigger1="click"
- >
- <a> 文件 </a>
- <t-dropdown-menu>
- <t-dropdown-item @click="newFile">
- <a>新建文件</a>
- </t-dropdown-item>
- <t-dropdown-item @click="load(true)">
- <a>打开文件</a>
- </t-dropdown-item>
- <t-dropdown-item divider="true" @click="load">
- <a>导入文件</a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="save()">保存</a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="save(SaveType.SaveAs, '', undefined, 1)">另存为</a>
- </t-dropdown-item>
- <t-dropdown-item divider="true">
- <a @click="downloadJson">下载JSON文件</a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="downloadZip">
- <div class="flex">
- 导出为ZIP文件 <span class="flex-grow"></span>
- <span><label>VIP</label></span>
- </div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="downloadHtml">
- <div class="flex">
- 下载离线部署包 <span class="flex-grow"></span>
- <span><label>企</label></span>
- </div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="downloadVue3">
- <div class="flex">
- 下载Vue3组件包 <span class="flex-grow"></span>
- <span><label>企</label></span>
- </div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="downloadVue2">
- <div class="flex">
- 下载Vue2组件包 <span class="flex-grow"></span>
- <span><label>企</label></span>
- </div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item divider="true">
- <a @click="downloadReact">
- <div class="flex">
- 下载React组件包 <span class="flex-grow"></span>
- <span><label>企</label></span>
- </div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="downloadPng">下载为PNG</a>
- </t-dropdown-item>
- <t-dropdown-item divider="true">
- <a @click="downloadSvg">下载为SVG</a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="switchTheme('light')">明亮主题</a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="switchTheme('dark')">暗黑主题</a>
- </t-dropdown-item>
- </t-dropdown-menu>
- </t-dropdown>
- <t-dropdown
- :minColumnWidth="180"
- :maxHeight="500"
- :delay2="[10, 150]"
- overlayClassName="header-dropdown"
- >
- <a> 编辑 </a>
- <t-dropdown-menu>
- <t-dropdown-item>
- <a @click="onUndo">
- <div class="flex">
- 撤销 <span class="flex-grow"></span> Ctrl + Z
- </div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item divider="true">
- <a @click="onRedo">
- <div class="flex">
- 重做 <span class="flex-grow"></span> Ctrl + Y
- </div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="onCut">
- <div class="flex">
- 剪切 <span class="flex-grow"></span> Ctrl + X
- </div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="onCopy">
- <div class="flex">
- 复制 <span class="flex-grow"></span> Ctrl + C
- </div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item divider="true">
- <a @click="onPaste">
- <div class="flex">
- 粘贴 <span class="flex-grow"></span> Ctrl + V
- </div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="onAll">
- <div class="flex">
- 全选 <span class="flex-grow"></span> Ctrl + A
- </div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="onDelete">
- <div class="flex">删除 <span class="flex-grow"></span> DELETE</div>
- </a>
- </t-dropdown-item>
- </t-dropdown-menu>
- </t-dropdown>
- <t-dropdown
- :minColumnWidth="180"
- :maxHeight="500"
- :delay2="[10, 150]"
- overlayClassName="header-dropdown"
- >
- <a> 工具 </a>
- <t-dropdown-menu>
- <t-dropdown-item>
- <a @click="onScaleWindow">窗口大小</a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="onScaleUp">放大</a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="onScaleDown">缩小</a>
- </t-dropdown-item>
- <t-dropdown-item divider="true">
- <a @click="onScaleFull">100%视图</a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="showMap">
- <div class="flex middle">
- 鹰眼地图 <span class="flex-grow"></span>
- <!-- <t-icon v-show="map" name="check" /> -->
- <check-icon v-show="map" />
- </div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item divider="true">
- <a @click="showMagnifier">
- <div class="flex middle">
- 放大镜 <span class="flex-grow"></span>
- <!-- <t-icon v-show="magnifier" name="check" /> -->
- <check-icon v-show="magnifier" />
- </div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="onAutoAnchor">
- <div class="flex middle">
- 自动锚点 <span class="flex-grow"></span>
- <!-- <t-icon v-show="autoAnchor" name="check" /> -->
- <check-icon v-show="autoAnchor" />
- </div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item divider="true">
- <a @click="onDisableAnchor">
- <div class="flex middle">
- 显示锚点 <span class="flex-grow"></span>
- <!-- <t-icon v-show="showAnchor" name="check" /> -->
- <check-icon v-show="showAnchor" />
- </div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="onToggleAnchor">
- <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"
- >
- <a> 帮助 </a>
- <t-dropdown-menu>
- <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>
- </t-dropdown>
- <div style="width: 148px; flex-shrink: 0"></div>
- <input v-model="meta2dData.name" @change="onInputName($event)" />
- <a :href="enterprise.account" target="_blank">
- <!-- <t-icon name="home" /> -->
- <home-icon />
- 账户中心
- </a>
- <a :href="enterprise['v']" target="_blank" class="active">
- <!-- <t-icon name="desktop" /> -->
- <desktop-icon />
- 大屏可视化
- </a>
- <a :href="enterprise['3d']" target="_blank">
- <!-- <t-icon name="control-platform" /> -->
- <control-platform-icon />
- 3D可视化
- </a>
- <a :href="enterprise['2d']" target="_blank">
- <!-- <t-icon name="app" /> -->
- <app-icon />
- 2D可视化
- </a>
- <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'"
- />
- </a>
- <t-dropdown-menu>
- <t-dropdown-item divider="true">
- <a :href="enterprise.account" target="_blank">
- {{ user.username }}
- <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">
- <a :href="`${enterprise.account}/v`" target="_blank"> 我的大屏 </a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a :href="`${enterprise.account}/account/teams`" target="_blank">
- 我的团队
- </a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a :href="`${enterprise.account}/account/info`" target="_blank">
- 账号信息
- </a>
- </t-dropdown-item>
- <t-dropdown-item divider="true">
- <a :href="`${enterprise.account}/account/security`" target="_blank">
- 安全设置
- </a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="logout">退出</a>
- </t-dropdown-item>
- </t-dropdown-menu>
- </t-dropdown>
- <div class="flex middle" v-else>
- <a class="button primary solid" style="width: 80px" :href="login()">
- 登录
- </a>
- </div>
- </div>
- <t-dialog
- v-if="payListDialog.show"
- v-model:visible="payListDialog.show"
- class="pay-dialog"
- :close-on-overlay-click="false"
- :top="95"
- :width="700"
- :cancel-btn="{
- content: '下载试用',
- variant: 'outline',
- style: {
- width: '100px',
- color:'#707B8F',
- marginRight:'8px'
- }
- }"
- confirm-btn="去支付"
- @cancel="downloadTrial"
- @close="payListDialog.show = false"
- @confirm="prePay"
- >
- <template #header>
- <div>
- <span style="vertical-align: middle">{{ payListDialog.title }}</span>
- <!-- <t-tooltip content="这是Tooltip内容"> -->
- <!-- @vue-ignore -->
- <a
- :href="payListDialog.href"
- target="_blank"
- class="hover"
- >
- <HelpCircleIcon class="hover" style="margin-left:12px;" />
- </a>
- <!-- </t-tooltip> -->
- </div>
- </template>
- <div class="pay-box">
- <div class="pay-title">{{ payListDialog.title }}</div>
- <div class="pay-price">
- <p>¥</p>
- <p>{{ data.deploy.price }}</p>
- </div>
- </div>
- <div class="pay-box pay-diagram">
- <div class="pay-up">
- <div class="pay-title">
- <t-checkbox v-model="data.payDiagram.checked"> 企业图形库
-
- </t-checkbox>
- <ChevronDownIcon @click="data.payDiagram.expend=false" v-if="data.payDiagram.expend" />
- <ChevronRightIcon @click="data.payDiagram.expend=true" v-else />
- </div>
- <div class="pay-price">
- <p>¥</p>
- <p>{{ data.payDiagram.price }}</p>
- </div>
- </div>
- <div v-if="data.payDiagram.expend" class="pay-down">
- <div v-for="item in data.payDiagram.list">
- <img v-if="item.img" :src="item.img" />
- <div v-else-if="item.svg" v-html="item.svg" ></div>
- <svg v-else class="l-icon" aria-hidden="true">
- <use :xlink:href="'#' + iotPensMap[item.name]?.icon"></use>
- </svg>
- </div>
- <p v-if="data.payDiagram.payAll">
- 【说明】检查到当前项目为老版本格式,需要购买整套SVG线性图元。
- </p>
- </div>
- </div>
- <div class="pay-footer">
- 合计
- <div>
- <p>¥</p>
- <p>{{ data.deploy.price+(data.payDiagram.checked?data.payDiagram.price:0) }}</p>
- </div>
- </div>
- </t-dialog>
- <t-dialog
- v-if="downloadZipDialog.show"
- v-model:visible="downloadZipDialog.show"
- class="pay-dialog"
- :close-on-overlay-click="false"
- :top="95"
- :width="700"
- :cancel-btn="{
- content: '直接下载',
- variant: 'outline',
- style: {
- width: '100px',
- color:'#707B8F',
- marginRight:'8px'
- }
- }"
- :confirm-btn="downloadZipDialog.checked?'去支付':null"
- @close="downloadZipDialog.show = false"
- @confirm="prePayDownloadZip"
- @cancel="doDownloadZip"
- >
- <template #header>
- <div>
- <span style="vertical-align: middle">导出为Zip文件</span>
- <t-tooltip content="这是Tooltip内容">
- <a
- :href="`https://doc${rootDomain}/document/155692631#%E5%AF%BC%E5%87%BA%E4%B8%BAZip%E6%96%87%E4%BB%B6`"
- target="_blank"
- class="hover"
- >
- <HelpCircleIcon style="margin-left:12px;" />
- </a>
- </t-tooltip>
- </div>
- </template>
- <div class="pay-box pay-diagram" style="font-size: 14px;
- line-height: 30px;
- color: #6E7B91;">
- Zip包仅包含数据文件和图片文件,不包含js等依赖库。
- <div >- 注意</div>Zip包用于平台(已包含js等依赖库)的快捷导入导出项目,无法作为独立部署包使用。
- <p v-if="downloadZipDialog.hasJs">
- <p>- 当前图纸包含js企业图形依赖库。</p>
- 项目中打开如果没有js企业图形依赖库,对应的图元将无法显示。
- 推荐下载为离线部署包(包含js企业图形依赖库)。
- </p>
- </div>
- <div class="pay-box pay-diagram">
- <div class="pay-up">
- <div class="pay-title">
- <t-checkbox v-model="downloadZipDialog.checked"> 企业图形库
-
- </t-checkbox>
- <ChevronDownIcon @click="downloadZipDialog.expend=false" v-if="downloadZipDialog.expend" />
- <ChevronRightIcon @click="downloadZipDialog.expend=true" v-else />
- </div>
- <div class="pay-price">
- <p>¥</p>
- <p>{{ downloadZipDialog.price }}</p>
- </div>
- </div>
- <div v-if="downloadZipDialog.expend" class="pay-down">
- <div v-for="item in downloadZipDialog.list">
- <img :src="item" />
- </div>
- </div>
- </div>
- <div class="pay-footer">
- 合计
- <div>
- <p>¥</p>
- <p>{{downloadZipDialog.checked? downloadZipDialog.price:0 }}</p>
- </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="wechatPayDialog.show = false"
- :footer="false"
- >
- <Pay
- :order="data.order"
- :alipay-url="data.order.alipayUrl"
- :code-url="data.order.codeUrl"
- @success="onSuccess"
- />
- </t-dialog>
- </template>
- <script lang="ts" setup>
- import {
- reactive,
- ref,
- onBeforeMount,
- onUnmounted,
- nextTick,
- computed,
- } from 'vue';
- import { useRouter, useRoute } from 'vue-router';
- import { useUser } from '@/services/user';
- import { MessagePlugin } from 'tdesign-vue-next';
- import {
- Meta2dBackData,
- dealwithFormatbeforeOpen,
- gotoAccount,
- checkData,
- } from '@/services/utils';
- import { readFile } from '@/services/file';
- import { compareVersion, baseVer, upgrade } from '@/services/upgrade';
- import { parseSvg } from '@meta2d/svg';
- import { Pen, getGlobalColor, isShowChild } from '@meta2d/core';
- import { cdn, upCdn } from '@/services/api';
- // import JSZip from 'jszip';
- import axios from 'axios';
- import { switchTheme } from '@/services/theme';
- import { noLoginTip } from '@/services/utils';
- import {
- save,
- blank,
- newFile,
- SaveType,
- onScaleFull,
- onScaleWindow,
- showMagnifier,
- showMap,
- drawPen,
- map,
- magnifier,
- useDot,
- delAttrs,
- // useAssets,
- // autoSaveAS
- } from '@/services/common';
- import { useEnterprise } from '@/services/enterprise';
- import {
- CheckIcon,
- HomeIcon,
- DesktopIcon,
- ControlPlatformIcon,
- AppIcon,
- ChevronRightIcon,
- ChevronDownIcon,
- HelpCircleIcon
- } from 'tdesign-icons-vue-next';
- import {
- getDownloadList,
- getPayList,
- getComponentPurchased,
- get2dComponentJs,
- getTemPngs,
- getGoods,
- // preFrameDownload,
- zipBkImg,
- zipImages,
- Frame,
- img_cdn,
- img_upCdn,
- getDeployGoods,
- getFrameDownloadList
- } from '@/services/download';
- import { formComponents, rootDomain } from '@/services/defaults';
- import Pay from './Pay.vue';
- import {getNetJsDiagram} from '@/services/material';
- import { useMeta2dData } from '@/services/common';
- const { enterprise } = useEnterprise();
- const router = useRouter();
- const route = useRoute();
- const { meta2dData, setMeta2dData } = useMeta2dData();
- const baseUrl = import.meta.env.BASE_URL || '/';
- // const { assets, getAssets } = useAssets();
- const { user, signout } = useUser();
- const { setDot } = useDot();
- const data = reactive<any>({
- name: '新建项目',
- order: {
- codeUrl: '',
- id: '', //订单id
- },
- goods: [], //所有商品类型
- purchasedList: [], //已经购买的列表
- deploy:{
- price:400,
- },
- payDiagram: {
- price: 400,
- checked:true,
- expend:false,
- list:[],
- payAll:false
- },
- payGoods:{},
- });
- onBeforeMount(async () => {
- // getAssets();
- // getNetJsDiagram();
- });
- const logout = () => {
- signout();
- meta2d.emit('logout');
- };
- const onInputName = (e) => {
- // (meta2d.store.data as Meta2dBackData).name = data.name;
- setMeta2dData({ name: e.target.value });
- setDot(true);
- };
- const initMeta2dName = () => {
- data.name = (meta2d.store.data as Meta2dBackData).name || '';
- setMeta2dData({ name: (meta2d.store.data as Meta2dBackData).name || '新建项目' });
- };
- let downloadList = new Set<any>();
- let iframeNum = 0;
- let compareNum = 0;
- const prePayList = reactive({
- pngs: new Set<string>(),
- jsPens: new Set<string>(),
- iotPens: new Set<string>(),
- svgPens: new Set<string>(),
- });
- let payListNum = 0;
- let comparePayListNum = 0;
- // let purchasedList = []; //已购买列表
- const iotPensMap = {};
- let downloadType: Frame = null;
- // const payPrice = ref(0);
- const getIotPensMap = () => {
- formComponents.forEach((item) => {
- item.list.forEach((_item) => {
- iotPensMap[_item.data.name] = { name: _item.name, icon: _item.icon };
- });
- });
- };
- nextTick(() => {
- meta2d.on('opened', initMeta2dName);
- window.addEventListener('message', dealWithMessage);
- getIotPensMap();
- });
- const dealWithMessage = async (e) => {
- if (
- typeof e.data !== 'string' ||
- !e.data ||
- e.data.startsWith('setImmediate')
- ) {
- return;
- }
- try {
- let data = JSON.parse(e.data);
- if (typeof data === 'object') {
- if (data.type) {
- if (data.name === 'download') {
- let list = data.data;
- let folderName =downloadType===Frame.vue3?'meta2d-vue3':downloadType===Frame.vue2?'meta2d-vue2': 'meta2d-react';
- list.forEach((item) => {
- if(item.path.startsWith('/meta3d/')){
- item.path = `/${folderName}/public/${item.path}`;
- }
- });
- downloadList = new Set([...downloadList, ...list]);
- compareNum += 1;
- if (compareNum >= iframeNum) {
- saveDownload();
- }
- } else if (data.name === 'payList') {
- prePayList.pngs = new Set([...prePayList.pngs, ...data.data.pngs]);
- prePayList.jsPens = new Set([
- ...prePayList.jsPens,
- ...data.data.jsPens,
- ]);
- prePayList.iotPens = new Set([
- ...prePayList.iotPens,
- ...data.data.iotPens,
- ]);
- prePayList.svgPens = new Set([
- ...prePayList.svgPens,
- ...data.data.svgPens,
- ]);
- comparePayListNum += 1;
- if (comparePayListNum >= payListNum) {
- await showPayListDialog();
- }
- }
- // else if(data.name==='saveas'){
- // await autoSaveAS(data.id);
- // }
- } else {
- meta2d.emit(data.name);
- }
- } else {
- meta2d.emit(data);
- }
- } catch (e) {
- console.info(e);
- }
- };
- onUnmounted(() => {
- meta2d.off('opened', initMeta2dName);
- window.removeEventListener('message', dealWithMessage);
- });
- const login = () => {
- if(import.meta.env.BASE_URL.startsWith('/') ){
- return `${enterprise['account']}?cb=${encodeURIComponent(location.href)}`;
- }else{
- return `https://account${rootDomain}/login?cb=${encodeURIComponent(location.href)}`;
- }
- };
- function load(isNew = false) {
- const input = document.createElement('input');
- input.type = 'file';
- input.onchange = (event) => {
- const elem = event.target as HTMLInputElement;
- if (elem.files && elem.files[0]) {
- // 路由跳转 可能在 openFile 后执行
- if (elem.files[0].name.endsWith('.json')) {
- blank();
- openJson(elem.files[0]);
- if (isNew) {
- router.push({
- path: '/',
- query: {
- r: Date.now() + '',
- },
- });
- }
- } else if (elem.files[0].name.endsWith('.svg')) {
- MessagePlugin.info(
- '可二次编辑但转换存在损失,若作为图片使用,请使用右侧属性面板的上传图片功能'
- );
- openSvg(elem.files[0]);
- } else if (elem.files[0].name.endsWith('.zip')) {
- blank();
- router.push({
- path: '/',
- query: {
- r: Date.now() + '',
- },
- });
- setTimeout(() => {
- openZip(elem.files[0]);
- }, 500);
- } else {
- MessagePlugin.info('打开文件只支持 json,svg,zip 格式');
- }
- }
- };
- input.click();
- }
- const openJson = async (file: File) => {
- const text = await readFile(file);
- try {
- let data: Meta2dBackData = JSON.parse(text);
- if (!data.name) {
- data.name = file.name.replace('.json', '');
- }
- if (!data.version || compareVersion(data.version, baseVer) === -1) {
- // 如果版本号不存在或者版本号 version < 1.0.0
- data = upgrade(data, baseVer);
- }
- dealwithFormatbeforeOpen(data);
- for (const k of delAttrs) {
- delete (data as any)[k];
- }
- meta2d.open(data);
- } catch (e) {
- console.error(e);
- }
- };
- const openSvg = async (file: File) => {
- const text = await readFile(file);
- const pens: Pen[] = parseSvg(text);
- meta2d.canvas.addCaches = pens;
- MessagePlugin.info('svg转换成功,请点击画布决定放置位置');
- };
- const openZip = async (file: File) => {
- if (!(user && user.id)) {
- MessagePlugin.warning(noLoginTip);
- return;
- }
- // if (!user.isVip) {
- // gotoAccount();
- // return;
- // }
- if (!user.vip) {
- MessagePlugin.info('需要开通普通会员~');
- gotoAccount();
- return;
- }
- const { default: JSZip } = await import('jszip');
- const zip = new JSZip();
- await zip.loadAsync(file);
- let dataStr = '';
- for (const key in zip.files) {
- if (zip.files[key].dir) {
- continue;
- }
- if (key.endsWith('.json')) {
- // 认为只有一个 json 文件
- // dataStr = await zip.file(key).async('string');
- break;
- }
- }
- if (!dataStr) {
- return false;
- }
- for (const key in zip.files) {
- if (zip.files[key].dir) {
- continue;
- }
- // let _png = key.indexOf('/png');
- // let _img = key.indexOf('/img');
- // let _image = key.indexOf('/image');
- // let _file = key.indexOf('/file');
- let _keyLower = key.toLowerCase();
- // if (!key.endsWith('.json') && (_png !== -1 || _img !== -1 || _image !== -1 || _file !== -1)) {
- if (
- _keyLower.endsWith('.png') ||
- _keyLower.endsWith('.svg') ||
- _keyLower.endsWith('.gif') ||
- _keyLower.endsWith('.jpg') ||
- _keyLower.endsWith('.jpeg')
- ) {
- let filename = key.substr(key.lastIndexOf('/') + 1);
- const extPos = filename.lastIndexOf('.');
- let ext = '';
- if (extPos > 0) {
- ext = filename.substr(extPos);
- }
- filename = filename.substring(0, extPos > 8 ? 8 : extPos);
- // 上传文件
- const result: any = {};
- // await upload(
- // // await zip.file(key).async('blob'),
- // true,
- // filename + ext,
- // "/2D/默认"
- // );
- let _key = key;
- // if (_png) {
- // _key = key.substring(_png);
- // } else if (_image) {
- // _key = key.substring(_png);
- // } else if (_img) {
- // _key = key.substring(_img);
- // } else if (_file) {
- // _key = key.substring(_file);
- // }
- if (result) {
- if (dataStr.replaceAll) {
- //'le5le.meta2d'
- dataStr = dataStr.replaceAll(_key.slice(12), result.url);
- } else {
- while (dataStr.includes(_key)) {
- dataStr = dataStr.replace(_key.slice(12), result.url);
- // 正则 gm 在特殊情况下报错,例如如下场景
- /**
- *
- const data = '{"image":"/image/materials/IoT-Chemical(化学)/Air stripper 2(汽提塔2).svg"}';
- const key = '/image/materials/IoT-Chemical(化学)/Air stripper 2(汽提塔2).svg';
- data.replace(key, '123');
- data.replaceAll(key, '123')
- data.replace(new RegExp(key, 'gm'), '123');
- data.replace(new RegExp(key, 'g'), '123');
- */
- }
- }
- }
- }
- }
- try {
- let data: Meta2dBackData = JSON.parse(dataStr);
- if (data) {
- if (!data.name) {
- data.name = file.name.replace('.zip', '');
- }
- if (!data.version || compareVersion(data.version, baseVer) === -1) {
- // 如果版本号不存在或者版本号 version < 1.0.0
- data = upgrade(data, baseVer);
- }
- dealwithFormatbeforeOpen(data);
- const delAttrs = [
- 'userId',
- 'shared',
- 'team',
- 'owner',
- 'username',
- 'editor',
- 'editorId',
- 'editorName',
- 'createdAt',
- 'folder',
- 'image',
- 'id',
- '_id',
- 'view',
- 'updatedAt',
- 'star',
- 'recommend',
- ];
- for (const k of delAttrs) {
- delete (data as any)[k];
- }
- meta2d.open(data);
- }
- } catch (e) {
- return false;
- }
- };
- const downloadJson = () => {
- const data: Meta2dBackData = meta2d.data();
- if (data._id) delete data._id;
- if (data.id) delete data.id;
- checkData(data);
- import('file-saver').then(({ saveAs }) => {
- saveAs(
- new Blob(
- [JSON.stringify(data).replaceAll(cdn, '').replaceAll(upCdn, '')],
- {
- type: 'text/plain;charset=utf-8',
- }
- ),
- `${data.name || 'le5le.meta2d'}.json`
- );
- });
- };
- const downloadZip = async () => {
- if (!(user && user.id)) {
- MessagePlugin.warning(noLoginTip);
- return;
- }
- // if (!user.isVip) {
- // // gotoAccount();
- // return;
- // }
- if(!meta2d.store.data.pens.length){
- MessagePlugin.info('画布没有画笔!');
- return;
- }
- if (!user.vip) {
- MessagePlugin.info('需要开通会员~');
- gotoAccount();
- return;
- }
- preDownloadZip();
- return;
- MessagePlugin.info('正在下载打包中,可能需要几分钟,请耐心等待...');
- const [{ default: JSZip }, { saveAs }] = await Promise.all([
- import('jszip'),
- import('file-saver'),
- ]);
- const zip: any = new JSZip();
- const data: Meta2dBackData = meta2d.data();
- let _fileName =
- (data.name && data.name.replace(/\//g, '_').replace(/:/g, '_')) ||
- 'le5le.meta2d';
- const _zip = zip.folder(`${_fileName}`);
- if (data._id) delete data._id;
- if (data.id) delete data.id;
- checkData(data);
- _zip.file(
- `${_fileName}.json`,
- JSON.stringify(data).replaceAll(cdn, '').replaceAll(upCdn, '')
- );
- await zipBkImg(_zip);
- await zipImages(_zip, meta2d.store.data.pens);
- const blob = await zip.generateAsync({ type: 'blob' });
- saveAs(blob, `${_fileName}.zip`);
- };
- const preDownloadZip =async () =>{
- const meta2dData = meta2d.data();
- let payList = getPayList(meta2dData);
- let purchased =await getComponentPurchased({
- pngs: payList.pngs,
- jsPens: [],
- iotPens: [],
- svgPens: [],
- });
- downloadZipDialog.checked = true;
- if(payList.jsPens.length||payList.iotPens.length||payList.svgPens.length){
- downloadZipDialog.hasJs = true;
- }else{
- downloadZipDialog.hasJs = false;
- }
- let names = purchased.map((item) => item.name);
- data.goods = await getGoods();
- let list = payList.pngs.filter((item) => !names.includes(item));
- if(!list.length){
- doDownloadZip();
- }else{
- let unitPrice = data.goods.find((item)=>item.type==='图片图元').unitPrice;
- downloadZipDialog.price = unitPrice*list.length;
- downloadZipDialog.show = true;
- downloadZipDialog.list = list;
- }
- }
- const prePayDownloadZip = async ()=>{
- if(downloadZipDialog.checked){
- const res: any = await axios.post('/api/order/deployment/submit', {
- goods:{},
- '2ds':downloadZipDialog.list.map((item)=>{return { type: '图片图元', name: item}}),
- });
- wechatPayDialog.show = true;
- wechatPayDialog.isZip = true;
- data.order = res;
- }else {
- doDownloadZip();
- }
- }
- const doDownloadZip = async ()=>{
- downloadZipDialog.show = false;
- MessagePlugin.info('正在下载打包中,可能需要几分钟,请耐心等待...');
- const [{ default: JSZip }, { saveAs }] = await Promise.all([
- import('jszip'),
- import('file-saver'),
- ]);
- const zip: any = new JSZip();
- const data: Meta2dBackData = meta2d.data();
- let _fileName =
- (data.name && data.name.replace(/\//g, '_').replace(/:/g, '_')) ||
- 'le5le.meta2d';
- const _zip = zip.folder(`${_fileName}`);
- if (data._id) delete data._id;
- if (data.id) delete data.id;
- checkData(data);
- _zip.file(
- `${_fileName}.json`,
- JSON.stringify(data).replaceAll(cdn, '').replaceAll(upCdn, '')
- );
- await zipBkImg(_zip);
- await zipImages(_zip, meta2d.store.data.pens);
- const blob = await zip.generateAsync({ type: 'blob' });
- saveAs(blob, `${_fileName}.zip`);
- }
- // const zip3D = (name: string) => {
- // const pen_3d = meta2d.store.data.pens.filter(
- // (pen) =>
- // pen.name === 'iframe' &&
- // (pen.tags.includes('meta3d') || pen.iframe.indexOf('3d') !== -1)
- // );
- // if (pen_3d && pen_3d.length) {
- // //存在3d场景
- // pen_3d.forEach((pen) => {
- // //发送消息
- // let params = queryURLParams(pen.iframe.split('?')[1]);
- // (
- // pen.calculative.singleton.div.children[0] as HTMLIFrameElement
- // ).contentWindow.postMessage(
- // JSON.stringify({
- // type: 1,
- // name,
- // id: params.id,
- // }),
- // '*'
- // );
- // });
- // }
- // };
- // 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);
- const params = Object.fromEntries(urlSearchParams.entries());
- return params;
- }
- const downloadHtml = async () => {
- if (!(user && user.id)) {
- MessagePlugin.warning(noLoginTip);
- return;
- }
- downloadType = Frame.html;
- await preGetPayList();
- };
- const preGetPayList = async () => {
- //图形库需要购买
- const meta2dData = meta2d.data();
- if(!meta2dData.pens.length){
- MessagePlugin.info('画布没有画笔!');
- return;
- }
- let list = getPayList(meta2dData);
- prePayList.pngs = new Set(list.pngs);
- prePayList.jsPens = new Set(list.jsPens);
- prePayList.iotPens = new Set(list.iotPens);
- prePayList.svgPens = new Set(list.svgPens);
- downloadList = new Set();
- //向iframe发送消息
- payListNum = 0;
- comparePayListNum = 0;
- const pen_pay = meta2dData.pens.filter(
- (pen) =>
- pen.name === 'iframe' &&
- (pen.iframe.indexOf(`2d${rootDomain}`) !== -1 ||
- pen.iframe.indexOf('/2d') !== -1 || pen.iframe.indexOf('data=2d') !== -1 ||
- pen.iframe.indexOf(`v${rootDomain}`) !== -1 ||
- pen.iframe.indexOf('/view/v') !== -1 ||pen.iframe.indexOf('data=v') !== -1 ||
- pen.iframe.indexOf('/preview') !== -1)
- );
- if (pen_pay && pen_pay.length) {
- pen_pay.forEach((pen) => {
- //发送消息
- (
- meta2d.store.pens[pen.id].calculative.singleton.div
- .children[0] as HTMLIFrameElement
- ).contentWindow.postMessage(
- JSON.stringify({
- name: 'prePayList',
- type: 1,
- }),
- '*'
- );
- payListNum += 1;
- });
- }
- if (payListNum === 0) {
- await showPayListDialog();
- }
- };
- const showPayListDialog = async () => {
- //下载离线部署包
- const deploys =await getDeployGoods();
- const pen_3d = meta2d.store.data.pens.filter(
- (pen) =>
- pen.name === 'iframe' &&
- (pen.iframe.indexOf(`3d${rootDomain}`) !== -1 ||
- pen.iframe.indexOf('/3d') !== -1)
- );
- const pen_2d = meta2d.store.data.pens.filter(
- (pen) =>
- pen.name === 'iframe' &&
- (pen.iframe.indexOf(`2d${rootDomain}`) !== -1 ||
- pen.iframe.indexOf('/2d') !== -1)
- );
- const pen_v = meta2d.store.data.pens.filter(
- (pen) =>
- pen.name === 'iframe' &&
- (pen.iframe.indexOf(`v${rootDomain}`) !== -1 ||
- pen.iframe.indexOf('/view/v') !== -1||pen.iframe.indexOf('data=v') !== -1)
- );
- let price = 0;
- data.payDiagram.checked = true;
- data.payDiagram.expend = false;
- data.payGoods ={}
- deploys.forEach((item) => {
- if(item.name==="3D离线部署下载"){
- price+=item.price*pen_3d.length;
- if(pen_3d.length){
- data.payGoods[item.id]=pen_3d.length;
- }
- }else if(item.name==="2D离线部署下载"){
- price+=item.price*pen_2d.length;
- if(pen_2d.length){
- data.payGoods[item.id]=pen_2d.length;
- }
- }else if(item.name==="大屏离线部署下载"){
- price+=item.price*(pen_v.length+1);
- data.payGoods[item.id]=pen_v.length+1;
- }
- });
- data.deploy.price = price;
- //图形库
- data.goods = await getGoods();
- data.purchasedList = await getComponentPurchased(prePayList);
- data.payDiagram.list =[];
- data.payDiagram.payAll = false;
- data.goods.forEach((goods)=>{
- let purchased = data.purchasedList?.filter(
- (_item) => _item.type === goods.type
- );
- let names = purchased.map((item) => item.name);
- let list = [];
- if(goods.type==='图片图元'){
- list = [...prePayList.pngs];
- }else if(goods.type==='JS线性图元'){
- list = [...prePayList.jsPens];
- }else if(goods.type==='SVG线性图元'){
- list = [...prePayList.svgPens];
- }else if(goods.type==='控件'){
- list = [...prePayList.iotPens];
- }
- let num =0;
- if (goods.type==='SVG线性图元'&&[...prePayList.svgPens].includes('*')) {
- //需要购买全部
- num = goods.count-names.length;
- data.payDiagram.payAll = true;
- }else{
- list.forEach((item)=>{
- if(!names.includes(item)){
- if(goods.type==='控件'){
- data.payDiagram.list.push({
- name:item
- });
- }else if(goods.type==='JS线性图元'){
- data.payDiagram.list.push({
- svg:globalThis.jsPensMap?globalThis.jsPensMap[item]:item
- });
- }else{
- data.payDiagram.list.push({
- img:item
- });
- }
- num+=1;
- }
- })};
- goods.num = num;
- })
- price = 0;
- data.goods.forEach((item, index) => {
- price += item.num * item.unitPrice;
- });
- data.payDiagram.price = price;
- // data.goods.forEach((item, index) => {
- // item.checked = true;
- // let purchased = data.purchasedList?.filter(
- // (_item) => _item.type === item.type
- // );
- // if (index === 0) {
- // item.total = [...prePayList.pngs].length;
- // item.unPurchased = item.total - purchased.length;
- // } else if (index === 1) {
- // item.total = [...prePayList.iotPens].length;
- // item.unPurchased = item.total - purchased.length;
- // } else if (index === 3) {
- // item.total = [...prePayList.jsPens].length;
- // item.unPurchased = item.total - purchased.length;
- // } else if (index === 2) {
- // if (purchased.length === 1 && !purchased[0].name) {
- // //说明已经购买全部 //TODO
- // item.total = item.count;
- // item.unPurchased = 0;
- // } else {
- // //需要购买全部
- // if ([...prePayList.svgPens].includes('*')) {
- // item.total = item.count;
- // item.unPurchased = item.total;
- // } else {
- // item.total = [...prePayList.svgPens].length;
- // item.unPurchased = item.total - purchased.length;
- // }
- // }
- // }
- // });
- payListDialog.show = true;
- switch (downloadType) {
- case Frame.html:
- payListDialog.title = '下载离线部署包';
- payListDialog.href = `https://doc${rootDomain}/document/155692631#%E4%B8%8B%E8%BD%BD%E7%A6%BB%E7%BA%BF%E9%83%A8%E7%BD%B2%E5%8C%85`;
- payListDialog.downloadUrl =img_cdn+ '/deployment/大厦电力管理系统(html).zip';
- break;
- case Frame.vue2:
- payListDialog.title = '下载vue2组件包';
- payListDialog.href = `https://doc${rootDomain}/document/155692631#%E4%B8%8B%E8%BD%BDVue2%E7%BB%84%E4%BB%B6%E5%8C%85`;
- payListDialog.downloadUrl = img_cdn+ '/deployment/大厦电力管理系统(vue2).zip';
- break;
- case Frame.vue3:
- payListDialog.title = '下载vue3组件包';
- payListDialog.href = `https://doc${rootDomain}/document/155692631#%E4%B8%8B%E8%BD%BDVue3%E7%BB%84%E4%BB%B6%E5%8C%85`;
- payListDialog.downloadUrl = img_cdn+ '/deployment/大厦电力管理系统(vue3).zip';
- break;
- case Frame.react:
- payListDialog.title = '下载react组件包';
- payListDialog.href = `https://doc${rootDomain}/document/155692631#%E4%B8%8B%E8%BD%BDReact%E7%BB%84%E4%BB%B6%E5%8C%85`;
- payListDialog.downloadUrl = img_cdn+ '/deployment/大厦电力管理系统(react).zip';
- break;
- }
- // let price = 0;
- // if (price === 0) {
- // skipPay(); //如果计算价格为0,直接下载
- // } else {
- // payListDialog.show = true;
- // }
- };
- const preDownload =() => {
- iframeNum = 0;
- compareNum = 0;
- const meta2dData:any = meta2d.data();
- meta2dData.userId = user.id;
- const pen_3d = meta2dData.pens.filter(
- (pen) =>
- pen.name === 'iframe' &&
- (pen.iframe.indexOf(`3d${rootDomain}`) !== -1 ||
- pen.iframe.indexOf('/3d') !== -1)
- );
- if (pen_3d && pen_3d.length) {
- //存在3d场景
- if (pen_3d.length === 1) {
- let params = queryURLParams(pen_3d[0].iframe.split('?')[1]);
- meta2d.store.pens[
- pen_3d[0].id
- ].calculative.singleton.div.children[0].contentWindow.postMessage(
- JSON.stringify({
- name: 'deploy',
- // id: params.id,
- type: 1, //用于区分是系统消息
- path: `3d`,
- }),
- '*'
- );
- pen_3d[0].iframe = '/view?data=3d';
- } else {
- pen_3d.forEach((pen) => {
- //发送消息
- let params = queryURLParams(pen.iframe.split('?')[1]);
- (
- meta2d.store.pens[pen.id].calculative.singleton.div
- .children[0] as HTMLIFrameElement
- ).contentWindow.postMessage(
- JSON.stringify({
- name: 'deploy',
- // id: params.id,
- type: 1,
- path: `3d-${params.id}`,
- }),
- '*'
- );
- pen.iframe = `/view?data=3d-${params.id}`;
- });
- }
- iframeNum += pen_3d.length;
- }
- const pen_2d = meta2dData.pens.filter(
- (pen) =>
- pen.name === 'iframe' &&
- (pen.iframe.indexOf(`2d${rootDomain}`) !== -1 ||
- pen.iframe.indexOf('/2d') !== -1)
- );
- if (pen_2d && pen_2d.length) {
- //存在3d场景
- if (pen_2d.length === 1) {
- let params = queryURLParams(pen_2d[0].iframe.split('?')[1]);
- meta2d.store.pens[
- pen_2d[0].id
- ].calculative.singleton.div.children[0].contentWindow.postMessage(
- JSON.stringify({
- name: 'downloadHtml',
- id: params.id,
- type: 1,
- path: `2d`,
- }),
- '*'
- );
- pen_2d[0].iframe = '/view?data=2d';
- } else {
- pen_2d.forEach((pen) => {
- //发送消息
- let params = queryURLParams(pen.iframe.split('?')[1]);
- (
- meta2d.store.pens[pen.id].calculative.singleton.div
- .children[0] as HTMLIFrameElement
- ).contentWindow.postMessage(
- JSON.stringify({
- name: 'downloadHtml',
- // id: params.id,
- type: 1,
- path: `2d-${params.id}`,
- }),
- '*'
- );
- pen.iframe = `/view?data=2d-${params.id}`;
- });
- }
- iframeNum += pen_2d.length;
- }
- const pen_v = meta2dData.pens.filter(
- (pen) =>
- pen.name === 'iframe' &&
- (pen.iframe.indexOf(`v${rootDomain}`) !== -1 ||
- pen.iframe.indexOf('/view/v') !== -1||pen.iframe.indexOf('data=v') !== -1)
- );
- if (pen_v && pen_v.length) {
- //存在3d场景
- pen_v.forEach((pen) => {
- //发送消息
- let params = queryURLParams(pen.iframe.split('?')[1]);
- (
- meta2d.store.pens[pen.id].calculative.singleton.div
- .children[0] as HTMLIFrameElement
- ).contentWindow.postMessage(
- JSON.stringify({
- name: 'downloadHtml',
- // id: params.id,
- type: 1,
- path: `v-${params.id}`,
- }),
- '*'
- );
- pen.iframe = `/view?data=v-${params.id}`;
- });
- iframeNum += pen_v.length;
- }
- downloadList = getDownloadList(meta2dData,undefined);
- if (iframeNum === 0) {
- //如果没有嵌入场景
- saveDownload();
- } else {
- setTimeout(() => {
- if (compareNum < iframeNum) {
- //message阻塞/报错的情况
- saveDownload();
- }
- }, 10000);
- }
- };
- const preFrameDownload = async () => {
- iframeNum = 0;
- compareNum = 0;
- const meta2dData:any = meta2d.data();
- meta2dData.userId = user.id;
- const pen_3d = meta2dData.pens.filter(
- (pen) =>
- pen.name === 'iframe' &&
- (pen.iframe.indexOf(`3d${rootDomain}`) !== -1 ||
- pen.iframe.indexOf('/3d') !== -1)
- );
- let name_3d = (downloadType===Frame.vue3?'toVue3':downloadType===Frame.vue2?'toVue2':'toReact');
- let flag_3d = false; //标记是否存在3d场景
- if (pen_3d && pen_3d.length) {
- //存在3d场景
- if (pen_3d.length === 1) {
- let params = queryURLParams(pen_3d[0].iframe.split('?')[1]);
- meta2d.store.pens[
- pen_3d[0].id
- ].calculative.singleton.div.children[0].contentWindow.postMessage(
- JSON.stringify({
- name: name_3d,
- type: 1, //用于区分是系统消息
- path: `3d`,
- }),
- '*'
- );
- pen_3d[0].iframe = '/3d?id=3d';
- } else {
- pen_3d.forEach((pen) => {
- //发送消息
- let params = queryURLParams(pen.iframe.split('?')[1]);
- (
- meta2d.store.pens[pen.id].calculative.singleton.div
- .children[0] as HTMLIFrameElement
- ).contentWindow.postMessage(
- JSON.stringify({
- name:name_3d,
- // id: params.id,
- type: 1,
- path: `3d-${params.id}`,
- }),
- '*'
- );
- pen.iframe = `/3d?id=3d-${params.id}`;
- });
- }
- iframeNum += pen_3d.length;
- flag_3d = true;
- }
- const pen_2d = meta2dData.pens.filter(
- (pen) =>
- pen.name === 'iframe' &&
- (pen.iframe.indexOf(`2d${rootDomain}`) !== -1 ||
- pen.iframe.indexOf('/2d') !== -1)
- );
- let name_2d = (downloadType===Frame.vue3?'downloadVue3':downloadType===Frame.vue2?'downloadVue2':'downloadReact');
- if (pen_2d && pen_2d.length) {
- //存在3d场景
- if (pen_2d.length === 1) {
- let params = queryURLParams(pen_2d[0].iframe.split('?')[1]);
- meta2d.store.pens[
- pen_2d[0].id
- ].calculative.singleton.div.children[0].contentWindow.postMessage(
- JSON.stringify({
- name: name_2d,
- id: params.id,
- type: 1,
- path: `2d`,
- }),
- '*'
- );
- pen_2d[0].iframe = '/2d?id=2d';
- } else {
- pen_2d.forEach((pen) => {
- //发送消息
- let params = queryURLParams(pen.iframe.split('?')[1]);
- (
- meta2d.store.pens[pen.id].calculative.singleton.div
- .children[0] as HTMLIFrameElement
- ).contentWindow.postMessage(
- JSON.stringify({
- name:name_2d,
- // id: params.id,
- type: 1,
- path: `2d-${params.id}`,
- }),
- '*'
- );
- pen.iframe = `/2d?id=2d-${params.id}`;
- });
- }
- iframeNum += pen_2d.length;
- }
- const pen_v = meta2dData.pens.filter(
- (pen) =>
- pen.name === 'iframe' &&
- (pen.iframe.indexOf(`v${rootDomain}`) !== -1 ||
- pen.iframe.indexOf('/view/v') !== -1||pen.iframe.indexOf('data=v') !== -1||pen.iframe.indexOf('/preview') !== -1)
- );
- if (pen_v && pen_v.length) {
- //存在大屏场景
- pen_v.forEach((pen) => {
- //发送消息
- let params = queryURLParams(pen.iframe.split('?')[1]);
- (
- meta2d.store.pens[pen.id].calculative.singleton.div
- .children[0] as HTMLIFrameElement
- ).contentWindow.postMessage(
- JSON.stringify({
- name: name_2d,
- // id: params.id,
- type: 1,
- path: `v-${params.id}`,
- }),
- '*'
- );
- pen.iframe = `/2d?id=v-${params.id}`;
- });
- iframeNum += pen_v.length;
- }
- downloadList = getFrameDownloadList(meta2dData,undefined,downloadType,flag_3d);
- if (iframeNum === 0) {
- //如果没有嵌入场景
- saveDownload();
- } else {
- setTimeout(() => {
- if (compareNum < iframeNum) {
- //message阻塞/报错的情况
- saveDownload();
- }
- }, 10000);
- }
- }
- const saveDownload = async () => {
- const list = [...downloadList];
- //控件
- let jsPath= '';
- let jsPensPath = '';
- switch (downloadType) {
- case Frame.html:
- jsPath = '/view/js/2d-components.js';
- jsPensPath = `/view/js/1.js`;
- break;
- case Frame.vue2:
- jsPath = '/meta2d-vue2/public/js/2d-components.js';
- jsPensPath = `/meta2d-vue2/public/js/1.js`;
- break;
- case Frame.vue3:
- jsPath = '/meta2d-vue3/public/js/2d-components.js';
- jsPensPath = `/meta2d-vue3/public/js/1.js`;
- break;
- case Frame.react:
- jsPath = '/meta2d-react/public/js/2d-components.js';
- jsPensPath = `/meta2d-react/public/js/1.js`;
- break;
- }
- const js = await get2dComponentJs([...prePayList.iotPens]);
- list.push({
- data: js,
- path:jsPath,
- });
- ///png图形库
- const pngs = await getTemPngs([...prePayList.pngs]);
- list.forEach((item) => {
- if(item.url){
- let url =item.url.replace(img_cdn, '').replace(img_upCdn, '')
- if (pngs[url]) {
- item.url = pngs[url];
- }
- }
- });
- //js线性图元
- const res: any = await axios.post('/api/paid/2d/component?pageSize=1000', {
- type: 'JS线性图元',
- });
- let purchased = res.list.map((item) => item.name);
- let arr = [];
- [...prePayList.jsPens].forEach((item) => {
- if(purchased.includes(item)){
- arr.push(item);
- }
- });
- const res_list: Blob = await axios.post(
- '/api/2d/tools',
- {
- list: arr.map((item) => {
- return {
- type: 'JS线性图元',
- name: item,
- };
- }),
- },
- {
- responseType: 'blob',
- }
- );
- list.push({
- data: res_list,
- path: jsPensPath,
- });
- //SVG线性图元
- if ([...prePayList.svgPens].length) {
- // let purchased = data.purchasedList?.filter(
- // (_item) => _item.type === 'SVG线性图元'
- // );
- const res: any = await axios.post('/api/paid/2d/component?pageSize=1000', {
- type: 'SVG线性图元',
- });
- let purchased = res.list;
- let count = data.goods.find((item) => item.type === 'SVG线性图元').count;
- if(purchased.length === count){
- // if (purchased.length === 1 && !purchased[0].name) {
- //已经购买全部
- list.forEach((item) => {
- if (item.data &&
- (item.path.indexOf('/projects/2d') !== -1 || item.path.indexOf('/projects/v') !== -1 || item.path.indexOf('/public/json')!==-1) &&
- item.path.indexOf('/projects/v/png/') === -1 && item.path.indexOf('/projects/2d/png/') === -1) {
- //清空所有svgpath
- let meta2dData = JSON.parse(item.data);
- for (let key of Object.keys(meta2dData.paths)) {
- let path = meta2dData.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
- ) {
- meta2dData.paths[key] = '';
- }
- }
- item.data = JSON.stringify(meta2dData);
- }
- });
- } else {
- let svgnames = purchased.map(i=>i.name);
- list.forEach((item) => {
- if (
- item.data &&
- (item.path.indexOf('/projects/2d') !== -1 || item.path.indexOf('/projects/v') !== -1 || item.path.indexOf('/public/json')!==-1) &&
- item.path.indexOf('/projects/v/png/') === -1 && item.path.indexOf('/projects/2d/png/') === -1
- ) {
- //2d 图纸数据
- let meta2dData = JSON.parse(item.data);
- meta2dData.pens.forEach((pen) => {
- if (pen.name === 'svgPath' && pen.svgUrl) {
- if (svgnames.includes(pen.svgUrl.replace(img_cdn, ''))) {
- pen.pathId = null;
- }
- }
- });
- item.data = JSON.stringify(meta2dData);
- }
- });
- }
- }
- //开始下载list
- const [{ default: JSZip }, { saveAs }] = await Promise.all([
- import('jszip'),
- import('file-saver'),
- ]);
- const zip = new JSZip();
- await Promise.all(
- list.map(async (item: any) => {
- if (item.url) {
- //接口请求
- try{
- const res: Blob = await axios.get(item.url.startsWith('/')?(cdn+item.url):item.url, {
- responseType: 'blob',
- });
- zip.file(item.path, res, { createFolders: true });
- }catch(e){
- console.log(e);
- }
- } else if (item.data) {
- //直接写数据
- zip.file(item.path, item.data, { createFolders: true });
- }
- })
- );
- let _fileName =
- (meta2d.store.data.name &&
- meta2d.store.data.name.replace(/\//g, '_').replace(/:/g, '_')) ||
- 'le5le.meta2d';
- const blob = await zip.generateAsync({ type: 'blob' });
- saveAs(blob, `${_fileName}.zip`);
- };
- // const _downloadHtml = async () => {
- // if (!(user && user.id)) {
- // MessagePlugin.warning(noLoginTip);
- // return;
- // }
- // // if (!user.isVip) {
- // // gotoAccount();
- // // return;
- // // }
- // if (user.vipDesc !== '超级会员' && user.vipDesc !== '旗舰会员') {
- // MessagePlugin.info('需要开通超级会员~');
- // gotoAccount();
- // return;
- // }
- // frameFlag = -1;
- // MessagePlugin.info('正在下载打包中,可能需要几分钟,请耐心等待...');
- // const data: Meta2dBackData = meta2d.data();
- // if (data._id) delete data._id;
- // if (data.id) delete data.id;
- // if (data.image) delete data.image;
- // checkData(data);
- // const [{ default: JSZip }, { saveAs }] = await Promise.all([
- // import('jszip'),
- // import('file-saver'),
- // ]);
- // const zip = new JSZip();
- // let _fileName =
- // (data.name && data.name.replace(/\//g, '_').replace(/:/g, '_')) ||
- // 'le5le.meta2d';
- // //处理cdn图片地址
- // const _zip: any = zip.folder(`${_fileName}`);
- // _zip.file(
- // 'data.json',
- // JSON.stringify(data).replaceAll(cdn, '').replaceAll(upCdn, '')
- // );
- // await Promise.all([
- // zipBkImg(_zip),
- // zipImages(_zip, meta2d.store.data.pens),
- // zipFiles(_zip),
- // ]);
- // const blob = await zip.generateAsync({ type: 'blob' });
- // saveAs(blob, `${_fileName}.zip`);
- // };
- // async function zipBkImg(zip: JSZip) {
- // let img = meta2d.store.data.bkImage;
- // if (img) {
- // if (img.startsWith('/') || img.startsWith(cdn) || img.startsWith(upCdn)) {
- // const pngs = await getTemPngs([img.replace(cdn, '').replace(upCdn, '')]);
- // await zipImage(zip, img, pngs[img.replace(cdn, '').replace(upCdn, '')]);
- // }
- // }
- // }
- // enum Frame {
- // vue2,
- // vue3,
- // react,
- // html
- // }
- const downloadVue3 = async () => {
- downloadAsFrame(Frame.vue3);
- };
- const downloadVue2 = async () => {
- downloadAsFrame(Frame.vue2);
- };
- const downloadReact = async () => {
- downloadAsFrame(Frame.react);
- };
- async function downloadAsFrame(type: Frame) {
- if (!(user && user.id)) {
- MessagePlugin.warning(noLoginTip);
- return;
- }
- // if (user.vipDesc !== '旗舰会员') {
- // MessagePlugin.info('需要开通旗舰会员~');
- // gotoAccount();
- // return;
- // }
- downloadType = type;
- await preGetPayList();
- }
- // const preFrameDownload = async (type: Frame) => {
- // frameFlag = type;
- // MessagePlugin.info('正在下载打包中,可能需要几分钟,请耐心等待...');
- // zip3D(
- // type === Frame.vue3 ? 'toVue3' : type === Frame.vue2 ? 'toVue2' : 'toReact'
- // );
- // 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'),
- // import('file-saver'),
- // ]);
- // const zip = new JSZip();
- // 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
- // ? 'meta2d-vue2'
- // : 'meta2d-react'
- // }/public/json/data.json`,
- // JSON.stringify(data).replaceAll(cdn, '').replaceAll(upCdn, '')
- // );
- // await Promise.all([
- // zipJs(_zip),
- // zipBkImg(_zip),
- // zipImages(_zip, meta2d.store.data.pens),
- // type === Frame.vue3
- // ? zipVue3Files(_zip)
- // : type === Frame.vue2
- // ? 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(
- // files.map(async (filePath) => {
- // const res: Blob = await axios.get(filePath, {
- // responseType: 'blob',
- // });
- // zip.file(
- // `${frameFlag === Frame.vue3
- // ? 'meta2d-vue3'
- // : frameFlag === Frame.vue2
- // ? 'meta2d-vue2'
- // : 'meta2d-react'
- // }/public` + filePath.replace('/view', ''),
- // res,
- // { createFolders: true }
- // );
- // })
- // );
- // }
- // async function _zipVue3Files(zip: JSZip) {
- // const files = [
- // '/view/js/marked.min.js',
- // '/view/js/lcjs.iife.js',
- // '/view/vue3/Meta2d.vue',
- // '/view/index.html',
- // '/view/js/meta2d.js',
- // '/view/使用说明.md',
- // ] as const;
- // // 文件同时加载
- // await Promise.all(files.map((filePath) => zipFile(zip, filePath)));
- // }
- //新
- // async function zipVue3Files(zip: JSZip) {
- // const files = [
- // '/view/meta2d-vue3/src/components/Meta2d.vue',
- // '/view/meta2d-vue3/src/App.vue',
- // '/view/meta2d-vue3/src/main.js',
- // '/view/meta2d-vue3/src/style.css',
- // '/view/meta2d-vue3/index.html',
- // '/view/meta2d-vue3/package.json',
- // '/view/meta2d-vue3/README.md',
- // '/view/meta2d-vue3/vite.config.js',
- // ] as const;
- // // 文件同时加载
- // await Promise.all(files.map((filePath) => zipFile(zip, filePath)));
- // }
- // async function _zipVue2Files(zip: JSZip) {
- // const files = [
- // '/view/js/marked.min.js',
- // '/view/js/lcjs.iife.js',
- // '/view/vue2/Meta2d.vue',
- // '/view/index.html',
- // '/view/js/meta2d.js',
- // '/view/使用说明.md',
- // ] as const;
- // // 文件同时加载
- // await Promise.all(files.map((filePath) => zipFile(zip, filePath)));
- // }
- // async function zipVue2Files(zip: JSZip) {
- // const files = [
- // '/view/meta2d-vue2/src/components/Meta2d.vue',
- // '/view/meta2d-vue2/src/App.vue',
- // '/view/meta2d-vue2/src/main.js',
- // // '/view/meta2d-vue2/src/style.css',
- // '/view/meta2d-vue2/public/index.html',
- // '/view/meta2d-vue2/package.json',
- // '/view/meta2d-vue2/README.md',
- // // '/view/meta2d-vue3/vite.config.js',
- // ] as const;
- // // 文件同时加载
- // await Promise.all(files.map((filePath) => zipFile(zip, filePath)));
- // }
- // async function _zipReactFiles(zip: JSZip) {
- // const files = [
- // '/view/js/marked.min.js',
- // '/view/js/lcjs.iife.js',
- // '/view/react/Meta2d.jsx',
- // '/view/react/Meta2d.css',
- // '/view/index.html',
- // '/view/js/meta2d.js',
- // '/view/使用说明.md',
- // ] as const;
- // // 文件同时加载
- // await Promise.all(files.map((filePath) => zipFile(zip, filePath)));
- // }
- // async function zipReactFiles(zip: JSZip) {
- // const files = [
- // '/view/meta2d-react/src/index.css',
- // '/view/meta2d-react/src/index.js',
- // '/view/meta2d-react/src/Meta2d.css',
- // '/view/meta2d-react/src/Meta2d.jsx',
- // '/view/meta2d-react/package.json',
- // '/view/meta2d-react/README.md',
- // '/view/meta2d-react/public/index.html',
- // ] as const;
- // // 文件同时加载
- // await Promise.all(files.map((filePath) => zipFile(zip, filePath)));
- // }
- // async function zipFiles(zip: JSZip) {
- // const files = [
- // '/view/js/marked.min.js',
- // '/view/js/lcjs.iife.js',
- // '/view/js/index.js',
- // '/view/js/meta2d.js',
- // '/view/index.html',
- // '/view/index.css',
- // '/view/favicon.ico',
- // '/view/使用说明.pdf',
- // ] as const;
- // // 文件同时加载
- // await Promise.all(files.map((filePath) => zipFile(zip, filePath)));
- // }
- // async function zipFile(zip: JSZip, filePath: string) {
- // const res: Blob = await axios.get(
- // (cdn ? cdn + '/v' : import.meta.env.BASE_URL.slice(0, -1)) + filePath,
- // {
- // responseType: 'blob',
- // }
- // );
- // zip.file(filePath.replace('/view', ''), res, { createFolders: true });
- // }
- // /**
- // * 图片放到 zip 里
- // * @param pens 可以是非具有 calculative 的 pen
- // */
- // async function zipImages(zip: JSZip, pens: Pen[]) {
- // if (!pens) {
- // return;
- // }
- // // 不止 image 上有图片, strokeImage ,backgroundImage 也有图片
- // const imageKeys = [
- // {
- // string: 'image',
- // },
- // { string: 'strokeImage' },
- // { string: 'backgroundImage' },
- // ] as const;
- // const images: string[] = [];
- // for (const pen of pens) {
- // for (const i of imageKeys) {
- // const image = pen[i.string];
- // if (image) {
- // // HTMLImageElement 无法精确控制图片格式
- // if (
- // image.startsWith('/') ||
- // image.startsWith(cdn) ||
- // image.startsWith(upCdn)
- // ) {
- // // 只考虑相对路径下的 image ,绝对路径图片无需下载
- // if (!images.includes(image)) {
- // images.push(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, temImage?: string) {
- // const res: Blob = await axios.get(temImage || image, {
- // responseType: 'blob',
- // // 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),
- // res,
- // {
- // createFolders: true,
- // }
- // );
- // }
- const downloadImageTips =
- '无法下载,宽度不合法,画布可能没有画笔/画布大小超出浏览器最大限制';
- const downloadPng = () => {
- if (!meta2d.store.data.pens.length) {
- MessagePlugin.warning(downloadImageTips);
- return;
- }
- try {
- meta2d.downloadPng();
- } catch (e) {
- MessagePlugin.warning(downloadImageTips);
- }
- };
- async function getIconDefs(url: string) {
- let res: any = await axios.get(url);
- let str = res.match(/@font-face([\s\S]*?)\}/)[1];
- str = `@font-face ${str} }`;
- return str;
- }
- const downloadSvg = async () => {
- // await import('@/assets/canvas2svg');
- for (const pen of meta2d.store.data.pens) {
- if (pen.calculative.img) {
- //重新生成绘制图片
- pen.onRenderPenRaw?.(pen);
- }
- }
- if (!C2S) {
- MessagePlugin.error('请先加载乐吾乐官网下的canvas2svg.js');
- return;
- }
- const rect: any = meta2d.getRect();
- if (!isFinite(rect.width)) {
- MessagePlugin.error(downloadImageTips);
- return;
- }
- rect.x -= 10;
- rect.y -= 10;
- const ctx = new C2S(rect.width + 20, rect.height + 20);
- ctx.textBaseline = 'middle';
- ctx.strokeStyle = getGlobalColor(meta2d.store);
- for (const pen of meta2d.store.data.pens) {
- // 不使用 calculative.inView 的原因是,如果 pen 在 view 之外,那么它的 calculative.inView 为 false,但是它的绘制还是需要的
- if (!isShowChild(pen, meta2d.store) || pen.visible == false) {
- continue;
- }
- meta2d.renderPenRaw(ctx, pen, rect);
- }
- let mySerializedSVG = ctx.getSerializedSvg();
- let icon_pens = meta2d.store.data.pens.filter(
- (item) => item.iconFamily && item.icon
- );
- if (icon_pens && icon_pens.length > 0) {
- let iconList = [
- '/icon/国家电网/iconfont.css',
- '/icon/电气工程/iconfont.css',
- '/icon/通用图标/iconfont.css',
- ];
- let defsList: any = await Promise.all(
- iconList.map((item) => getIconDefs(item))
- );
- mySerializedSVG = mySerializedSVG.replace(
- '<defs/>',
- `<defs>
- <style type="text/css">
- ${defsList.join('\n')}
- </style>
- {{bk}}
- </defs>
- {{bkRect}}`
- );
- }
- /* mySerializedSVG = mySerializedSVG.replace(
- '<defs/>',
- `<defs>
- <style type="text/css">
- @font-face {
- font-family: 'ticon';
- src: url('icon/通用图标/iconfont.ttf') format('truetype');
- }
- </style>
- {{bk}}
- </defs>
- {{bkRect}}`
- );
- */
- if (meta2d.store.data.background) {
- mySerializedSVG = mySerializedSVG.replace('{{bk}}', '');
- mySerializedSVG = mySerializedSVG.replace(
- '{{bkRect}}',
- `<rect x="0" y="0" width="100%" height="100%" fill="${meta2d.store.data.background}"></rect>`
- );
- } else {
- mySerializedSVG = mySerializedSVG.replace('{{bk}}', '');
- mySerializedSVG = mySerializedSVG.replace('{{bkRect}}', '');
- }
- mySerializedSVG = mySerializedSVG.replace(/--le5le--/g, '&#x');
- const urlObject: any = (window as any).URL || window;
- const export_blob = new Blob([mySerializedSVG]);
- const url = urlObject.createObjectURL(export_blob);
- const a = document.createElement('a');
- a.setAttribute(
- 'download',
- `${(meta2d.store.data as Meta2dBackData).name || 'le5le.meta2d'}.svg`
- );
- a.setAttribute('href', url);
- const evt = document.createEvent('MouseEvents');
- evt.initEvent('click', true, true);
- a.dispatchEvent(evt);
- };
- const onUndo = () => {
- meta2d.undo();
- };
- const onRedo = () => {
- meta2d.redo();
- };
- const onCut = () => {
- meta2d.cut();
- };
- const onCopy = () => {
- meta2d.copy();
- };
- const onPaste = () => {
- meta2d.paste();
- };
- const onAll = () => {
- meta2d.activeAll();
- };
- const onDelete = () => {
- meta2d.delete();
- };
- const onToggleAnchor = () => {
- //取消连线状态
- // meta2d.store.options.disableAnchor = false;
- if (!meta2d.store.options.disableAnchor) {
- meta2d.canvas.drawingLineName && drawPen();
- meta2d.toggleAnchorMode();
- }
- };
- const onAddAnchorHand = () => {
- meta2d.addAnchorHand();
- };
- const onRemoveAnchorHand = () => {
- meta2d.removeAnchorHand();
- };
- const onToggleAnchorHand = () => {
- meta2d.toggleAnchorHand();
- };
- const onScaleUp = () => {
- const _scale = meta2d.store.data.scale + 0.1;
- meta2d.scale(_scale);
- };
- const onScaleDown = () => {
- const _scale = meta2d.store.data.scale - 0.1;
- meta2d.scale(_scale);
- };
- const autoAnchor = ref(true);
- const onAutoAnchor = () => {
- meta2d.store.options.autoAnchor = !meta2d.store.options.autoAnchor;
- autoAnchor.value = meta2d.store.options.autoAnchor;
- };
- const showAnchor = ref(false);
- const onDisableAnchor = () => {
- meta2d.store.options.disableAnchor = !meta2d.store.options.disableAnchor;
- changeDisableAnchor();
- };
- const changeDisableAnchor = () => {
- const { disableAnchor, autoAnchor } = meta2d.store.options;
- showAnchor.value = !disableAnchor || false;
- if (disableAnchor && autoAnchor) {
- // 禁用瞄点开了,需要关闭自动瞄点
- onAutoAnchor();
- }
- };
- const payListDialog = reactive({
- show: false,
- title:'',
- href:'',
- downloadUrl:''
- });
- const downloadZipDialog = reactive({
- show: false,
- checked:true,
- expend:false,
- price:0,
- list:[],
- hasJs:false,
- });
- const prePay = async () => {
- let list = [];
- let names = data.purchasedList.map((item) => item.name);
- if(data.payDiagram.checked){
- prePayList.pngs.forEach((item) => {
- if(!names.includes(item)){
- list.push({
- type: '图片图元',
- name: item,
- });
- }
- });
- prePayList.jsPens.forEach((item) => {
- if(!names.includes(item)){
- list.push({
- type: 'JS线性图元',
- name: item,
- });
- }
- });
- prePayList.iotPens.forEach((item) => {
- if(!names.includes(item)){
- list.push({
- type: '控件',
- name: item,
- });
- }
- });
- if ([...prePayList.svgPens].includes('*')) {
- list.push({
- type: 'SVG线性图元',
- });
- } else {
- prePayList.svgPens.forEach((item) => {
- if(!names.includes(item)){
- list.push({
- type: 'SVG线性图元',
- name: item,
- });
- }
- });
- }
- }
- const res: any = await axios.post('/api/order/deployment/submit', {
- goods:data.payGoods,
- '2ds':list,
- });
- wechatPayDialog.show = true;
- data.order = res;
- };
- const downloadTrial = () => {
- MessagePlugin.info('正在下载中,可能需要几分钟,请耐心等待...');
- //下载试用版
- window.open(payListDialog.downloadUrl, '_blank');
- }
- const skipPay = () => {
- //跳过支付,直接下载
- MessagePlugin.info('正在下载打包中,可能需要几分钟,请耐心等待...');
- if (downloadType === Frame.html) {
- preDownload();
- } else {
- preFrameDownload();
- }
- };
- const finishPay = async () => {
- // let id = data.order.id;
- // const result: { state: number } = await axios.post('/api/order/pay/state', {
- // id,
- // });
- // if (result && result.state) {
- MessagePlugin.success('支付成功');
- wechatPayDialog.show = false;
- if(wechatPayDialog.isZip){
- // downloadZipDialog.show = false;
- wechatPayDialog.isZip = false;
- doDownloadZip();
- }else{
- payListDialog.show = false;
- MessagePlugin.info('正在下载打包中,可能需要几分钟,请耐心等待...');
- if (downloadType === Frame.html) {
- preDownload();
- } else {
- preFrameDownload();
- }
- }
- // } else {
- // MessagePlugin.error('支付失败');
- // // wechatPayDialog.show = false;
- // }
- };
- const finalPrice = computed(() => {
- let total = 0;
- let price = 0;
- data.goods.forEach((item, index) => {
- if (item.checked) {
- total += item.unPurchased;
- price += item.unPurchased * item.unitPrice;
- }
- });
- return {
- total,
- price,
- };
- });
- const wechatPayDialog = reactive({
- show: false,
- isZip:false
- });
- const emit = defineEmits(['success']);
- const onSuccess = (success: boolean) => {
- finishPay();
- emit('success', success);
- };
- </script>
- <style lang="postcss" scoped>
- .app-header {
- display: flex;
- height: 40px;
- background-color: var(--color-background);
- position: relative;
- z-index: 2;
- .logo {
- display: flex;
- padding: 0 16px;
- align-items: center;
- font-size: 14px;
- font-weight: 500;
- img {
- height: 20px;
- margin-right: 6px;
- }
- }
- a {
- display: flex;
- padding: 0 8px;
- margin: 0 8px;
- align-items: center;
- color: var(--color);
- text-decoration: none;
- white-space: nowrap;
- &:hover {
- color: var(--color-primary);
- }
- svg {
- font-size: 15px;
- margin: 2px 4px 0 0;
- }
- &.active {
- background-color: var(--color-primary);
- color: #ffffff;
- }
- }
- input {
- font-size: var(--font-size);
- flex-grow: 1;
- background: none;
- outline: none;
- border: none;
- text-align: center;
- color: var(--color-title);
- }
- }
- .pay-box{
- background: rgba(175,202,255,0.04);
- border-radius: 4px;
- margin-bottom:24px;
- padding:20px 24px;
- position:relative;
- display:flex;
- .pay-up{
- display:flex;
- }
- :deep(.t-checkbox__label){
- font-size: 16px;
- color: #6e7b91;
- margin-left:16px;
- }
- .pay-title{
- font-size: 16px;
- color: #6e7b91;
- .t-icon{
- margin-top:-5px;
- margin-left:12px;
- }
- :deep(.t-checkbox__input){
- background:#fff0;
- }
- :deep(.t-is-checked){
- .t-checkbox__input{
- background:var(--color-primary);
- }
- }
- }
- .pay-price{
- position:absolute;
- right:24px;
- color:#4480F9;
- display:flex;
- p:nth-child(2){
- font-size: 20px;
- }
- }
- .pay-down{
- margin-top:16px;
- display:flex;
- flex-wrap:wrap;
- /* justify-content:space-between; */
- /* padding-top:24px; */
- max-height: 200px;
- overflow-y: scroll;
- &>div{
- width: 48px;
- height: 48px;
- background: #1c283b;
- border-radius: 4px;
- margin-right:2.5px;
- margin-bottom:2.5px;
- &:nth-child(12n){
- margin-right: 0px;
- }
- img{
- margin:4px;
- width:40px;
- height:40px;
- }
- .l-icon{
- /* width: 80px; */
- /* height: 80px; */
- /* margin:8px; */
- font-size:24px;
- margin:12px;
- }
- &>div{
- margin: 8px 12px;
- }
- }
- &>p{
- display: block;
- margin-top:8px;
- width:100%;
- }
- }
- }
- .pay-footer{
- display:flex;
- margin-bottom: -48px;
- margin-left:24px;
- font-size: 14px;
- &>div{
- color:#4480F9;
- display:flex;
- p:nth-child(2){
- font-size: 24px;
- font-weight: 800;
- margin-top:-3px;
- }
- p:nth-child(1){
- margin:0px 4px;
- }
- }
- }
- .pay-diagram{
- flex-direction:column;
- }
- /* .pay-dialog {
- background-color: red;
- } */
- /* .pay-body {
- 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;
- }
- }
- }
- } */
- /* .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;
- margin-top: 7px;
- width: 30%;
- }
- }
- .pay-p{
- overflow:hidden;
- text-overflow:ellipsis;
- white-space:nowrap;
- }
- & > 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;
- }
- p:nth-child(2) {
- font-size: 32px;
- font-weight: Semibold;
- color: #4480f9;
- line-height: 20px;
- }
- p:nth-child(1) {
- font-size: 14px;
- color: #4480f9;
- }
- }
- } */
- /* .pay-title {
- margin: 18px 0px 12px 18px;
- } */
- </style>
|