123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- import { Pen, Meta2dData } from '@meta2d/core';
- import { MessagePlugin, NotifyPlugin, Button } from 'tdesign-vue-next';
- import { h, ref } from 'vue';
- import { upCdn } from './api';
- import axios from 'axios';
- import i18n from '../i18n';
- const $t = i18n.global.t;
- export const noLoginTip = $t('请先登录,否则无法保存!');
- export const localStorageName = 'le5leV';
- export interface Meta2dBackData extends Meta2dData {
- id?: string;
- name?: string;
- userId?: string;
- image?: string;
- component?: boolean;
- componentDatas?: Pen[];
- version?: string;
- folder?: string;
- shared?: boolean; // 是否分享
- class?: string; // 分类,架构拓扑图那些
- // 组合为状态,组件保存使用,无需存储到后端
- showChild?: number;
- _id?: string;
- owner?: {
- id?: string;
- };
- folderId?: string;
- editor?: {
- id?: string;
- username?: string;
- };
- username?: string;
- editorId?: string;
- editorName?: string;
- teams?: { id?: string; name?: string }[];
- tags?: string[]; //标签数组
- filename?: string; //后端存储的文件名
- ownerId?:string;
- ownerName?:string;
- case?:string;
- isSystem?:boolean;
- isTemplate?:boolean;
- }
- const notification = ref<any>(null);
- export function showNotification(title: string): Promise<boolean> {
- return new Promise<boolean>((resolve) => {
- const btnClick = () => {
- NotifyPlugin.close(notification.value);
- notification.value = null;
- resolve(true);
- };
- if (!notification.value) {
- notification.value = NotifyPlugin.info({
- title: $t('提示'),
- content: title,
- closeBtn: true,
- onCloseBtnClick: () => {
- //关闭按钮
- notification.value = null;
- resolve(false);
- },
- // duration: 1000000,
- // @ts-ignore
- footer: h(
- Button,
- {
- theme: 'primary',
- size: 'small',
- style: {
- 'margin-top': '16px',
- 'margin-left': '256px',
- },
- onClick: btnClick,
- },
- $t('确定')
- ),
- });
- }
- });
- }
- export function startViewTransition(callback) {
- if (!document.startViewTransition) {
- callback();
- return;
- }
- document.startViewTransition(callback);
- }
- export async function dealwithFormatbeforeOpen(data: Meta2dBackData) {
- if (!data) {
- return;
- }
- if ((!data.https || data.https?.length == 0) && data.http) {
- data.https = [
- {
- http: data.http,
- httpTimeInterval: data.httpTimeInterval,
- httpHeaders: data.httpHeaders,
- },
- ];
- delete data.http;
- delete data.httpHeaders;
- delete data.httpTimeInterval;
- }
- //新版渐进色
- data.pens &&
- data.pens.forEach((pen) => {
- if (pen.lineGradientFromColor && pen.lineGradientToColor) {
- pen.lineGradientColors = `linear-gradient(${
- pen.lineGradientAngle ? Number(pen.lineGradientAngle) + 90 : 0
- }deg,${pen.lineGradientFromColor} 0%,${pen.lineGradientToColor} 100%)`;
- }
- if (pen.gradientFromColor && pen.gradientToColor) {
- pen.gradientColors = `linear-gradient(${
- pen.gradientAngle ? Number(pen.gradientAngle) + 90 : 0
- }deg,${pen.gradientFromColor} 0%,${pen.gradientToColor} 100%)`;
- }
- if (
- pen.image &&
- pen.image.startsWith('/') &&
- !pen.image.startsWith('/v/') &&
- !pen.image.startsWith('/png/')
- ) {
- pen.image = upCdn + pen.image;
- }
- });
- }
- export function gotoAccount() {
- MessagePlugin.info({
- content: $t('请开通vip,即将跳转到开通页面...'),
- duration: 3,
- });
- setTimeout(() => {
- if (import.meta.env.BASE_URL[0] === '/') {
- window.open('/account?unVip=true');
- } else {
- let arr = location.host.split('.');
- arr[0] = 'http://account';
- let accountUrl = arr.join('.');
- window.open(`${accountUrl}?unVip=true`);
- }
- }, 3000);
- }
- export async function isGif(url: string): Promise<boolean> {
- if (url.endsWith('.svg')) {
- //请求svg图片
- // if (url.startsWith('https://drive.le5lecdn.com/')) {
- let res: any = await axios.get(url);
- if ((res as string).indexOf('@keyframes') !== -1) {
- //有动画的svg
- return true;
- } else {
- return false;
- }
- // } else {
- // return false;
- // }
- } else {
- let arr = url.split('?');
- return arr[0].endsWith('.gif');
- }
- }
- /**
- * 正常的 assign 操作,是存在弊端的,
- * 若源对象存在该属性,但目标对象不存在该属性(不存在并非 undefined),则会导致无法覆盖
- * 该方法会把源对象的属性全部清空,然后再把目标对象的属性覆盖到源对象上
- * source 可能是个监听的对象,所有最后一步再更改它的属性值
- * @param source 原对象
- * @param target 目标对象
- */
- export function strictAssign(
- source: Record<string, any>,
- target: Record<string, any>
- ) {
- // source 的全部属性都是 undefined 的对象,而非没有这个属性
- const undefinedSource: Record<string, any> = {};
- Object.keys(source).forEach((key) => {
- undefinedSource[key] = undefined;
- });
- Object.assign(undefinedSource, target);
- Object.assign(source, undefinedSource);
- }
- export function checkData(data: Meta2dData) {
- const pens: Pen[] = data.pens || [];
- for (let i = 0; i < pens.length; i++) {
- const pen: any = pens[i];
- pen.props?.custom?.forEach((prop) => {
- if (prop.key?.includes('.')) {
- delete pen[prop.key];
- }
- });
- pen.realTimes?.forEach((realTime) => {
- if (realTime.key?.includes('.')) {
- delete pen[realTime.key];
- }
- });
- pen.events?.forEach((event: any) => {
- delete event.setProps;
- });
- //处理画笔是脏数据的情况
- if (
- !(
- pen.x > -Infinity &&
- pen.x < Infinity &&
- pen.y > -Infinity &&
- pen.y < Infinity &&
- pen.width > -Infinity &&
- pen.width < Infinity &&
- pen.height > -Infinity &&
- pen.height < Infinity
- )
- ) {
- pens.splice(i, 1);
- --i;
- } else if (
- pen.x == null ||
- pen.y == null ||
- pen.width == null ||
- pen.height == null
- ) {
- pens.splice(i, 1);
- --i;
- }
- }
- if (Array.isArray(data.mqttOptions)) {
- // mqttOptions 是数组则认为是脏数据,删掉
- data.mqttOptions = {};
- }
- }
- export const transformData = (obj,operation) => {
- let newObj:any = null;
- if(operation == 'toMetaNetwork') {
- newObj = {
- name:obj.name,
- type:obj.type,
- ...obj.data,
- id:obj.id,
- }
- } else {
- newObj = {
- name:obj.name,
- type:obj.type,
- data:{}
- }
- if(obj.id) {
- newObj.id = obj.id;
- }
- if(obj.type == 'dataset') {
- newObj.data = {
- devices:obj.devices,
- mode: obj.mode,
- url: obj.url
- }
- } else {
- if( obj.protocol == 'http') {
- newObj.data = {
- body: obj.body,
- headers: obj.headers,
- httpTimeInterval: obj.httpTimeInterval,
- method: obj.method,
- url: obj.url,
- protocol: obj.protocol
- }
- } else {
- newObj.data = {
- options:obj.options,
- protocol: obj.protocol,
- topics: obj.topics,
- url: obj.url
- }
- }
- }
- // return {
- // data:{
- // body: obj.body,
- // headers: obj.headers,
- // httpTimeInterval: obj.httpTimeInterval,
- // method: obj.method,
- // options:obj.options,
- // protocol: obj.protocol,
- // topics: obj.topics,
- // url: obj.url
- // }
- // }
- }
- return newObj;
- }
- export const getImgUrl = (url: string) => {
- if (url.startsWith('http')) {
- return url
- }
- return import.meta.env.VITE_IMG_API + '/' + url
- }
- // monaco代码提示类型管理
- export class MonacoTypeManager {
- private monaco: any;
- constructor(monacoInstance) {
- this.monaco = monacoInstance;
- }
- loadTypeFile(path: string,callback) {
- fetch(path)
- .then(response => response.text())
- .then(data => {
- this.registerTypeFile(data)
- callback()
- })
- .catch(error => {
- console.error('Error fetching type file:', error);
- });
- }
- /**
- * 加载并注册 .d.ts 文件内容
- * @param {string} typeContent - 类型声明字符串内容
- * @param {string} filePath - 唯一虚拟文件路径
- */
- registerTypeFile(typeContent) {
- this.monaco.languages.typescript.javascriptDefaults.addExtraLib(
- typeContent,
- );
- }
- clearTypeFiles() {
- this.monaco.languages.typescript.javascriptDefaults.setExtraLibs([]);
- }
- /**
- * 为指定变量生成类型声明并注入
- * @param {string} varName - 变量名,例如 ctx
- * @param {string} typeName - 类型名,例如 CanvasRenderingContext2D
- */
- injectVariableType(varName, typeName) {
- // const filePath = `file:///injected-types/${varName}.d.ts`;
- const typeContent = `
- /** @type {${typeName}} */
- var ${varName};
- `;
- this.registerTypeFile(typeContent);
- }
- /**
- * 批量注册变量类型
- * @param {Array<{ varName: string, typeName: string }>} typeList
- */
- injectMultipleVariables(typeList) {
- typeList.forEach(({ varName, typeName }) => {
- this.injectVariableType(varName, typeName);
- });
- }
- }
|