Alsmile 1 năm trước cách đây
mục cha
commit
182672d406

+ 4 - 0
index.html

@@ -23,6 +23,10 @@
         overflow: hidden;
       }
     </style>
+    <link
+      href="//at.alicdn.com/t/c/font_4042197_yrikqthz1j.css"
+      rel="stylesheet"
+    />
     <script src="//at.alicdn.com/t/c/font_4042197_yrikqthz1j.js"></script>
   </head>
   <body>

+ 60 - 3
src/services/common.ts

@@ -1,15 +1,72 @@
 import { reactive, ref } from 'vue';
-import router from '@/router/index';
-import { useUser } from '@/services/user';
-import { showNotification, Meta2dBackData, checkData } from '@/services/utils';
 import { MessagePlugin } from 'tdesign-vue-next';
 import localforage from 'localforage';
 import dayjs from 'dayjs';
+import axios from 'axios';
+import router from '@/router/index';
+import { useUser } from '@/services/user';
+import { showNotification, Meta2dBackData, checkData } from '@/services/utils';
 import { noLoginTip, localStorageName } from '@/services/utils';
 import { upload, dataURLtoBlob } from '@/services/file';
 import { delImage, addCollection, updateCollection } from '@/services/api';
 import { baseVer } from '@/services/upgrade';
 
+const assets = reactive({
+  home: 'https://le5le.com',
+  account: 'https://account.le5le.com',
+  helps: [
+    {
+      name: '产品介绍',
+      url: 'https://doc.le5le.com/document/118756411',
+    },
+    {
+      name: '快速上手',
+      url: 'https://doc.le5le.com/document/119363000',
+    },
+    {
+      name: '使用手册',
+      url: 'https://doc.le5le.com/document/118764244',
+    },
+    {
+      name: '快捷键',
+      url: 'https://doc.le5le.com/document/119620214',
+      divider: true,
+    },
+    {
+      name: '企业服务与支持',
+      url: 'https://doc.le5le.com/document/119296274',
+      divider: true,
+    },
+    {
+      name: '关于我们',
+      url: 'https://le5le.com/about.html',
+    },
+  ],
+});
+
+export const useAssets = () => {
+  const getAssets = async () => {
+    // 官网或安装包版本
+    if (
+      import.meta.env.VITE_TRIAL == undefined ||
+      import.meta.env.VITE_TRIAL == 1
+    ) {
+      return;
+    }
+
+    // 企业版
+    const ret = await axios.get('/api/assets');
+    if (ret) {
+      Object.assign(assets, ret);
+    }
+  };
+
+  return {
+    assets,
+    getAssets,
+  };
+};
+
 const dot = ref(false);
 
 export const useDot = () => {

+ 1 - 1
src/services/defaults.ts

@@ -2110,7 +2110,7 @@ export const formComponents = [
           width: 100,
           height: 100,
           name: 'image',
-          icon: '\ue668',
+          icon: '\ue8c6',
           iconFamily: 'l-icon',
         },
       },

+ 42 - 0
src/services/html.ts

@@ -6,3 +6,45 @@ export function getHtmlText(html: string, trimSpace?: boolean) {
 
   return text;
 }
+
+export async function addIcons(url: string) {
+  return new Promise((resolve, reject) => {
+    const xhr = new XMLHttpRequest();
+    xhr.open('GET', url, true);
+    xhr.send();
+    xhr.onreadystatechange = () => {
+      if (xhr.readyState === 4 && xhr.status === 200) {
+        try {
+          const iconfont = JSON.parse(xhr.responseText);
+          const iconGroup = {
+            name: iconfont.name,
+            loaded: true,
+            show: true,
+            list: [],
+          };
+
+          iconfont.glyphs.forEach((item: any) => {
+            iconGroup.list.push({
+              name: item.name,
+              icon:
+                iconfont.font_family +
+                ' ' +
+                iconfont.css_prefix_text +
+                item.font_class,
+              data: {
+                width: 100,
+                height: 100,
+                name: 'image',
+                iconFamily: iconfont.font_family,
+                icon: String.fromCharCode(item.unicode_decimal),
+              },
+            });
+          });
+          resolve(iconGroup);
+        } catch (error) {
+          reject(error);
+        }
+      }
+    };
+  });
+}

+ 5 - 0
src/styles/app.css

@@ -106,6 +106,7 @@ h5 {
 
 .ellipsis {
   text-overflow: ellipsis;
+  overflow: hidden;
 }
 
 a {
@@ -336,6 +337,10 @@ a.hover:hover {
   padding-bottom: 4px;
 }
 
+.pl-8 {
+  padding-left: 8px;
+}
+
 .px-8 {
   padding-left: 8px;
   padding-right: 8px;

+ 81 - 2
src/views/components/FileProps.vue

@@ -79,7 +79,7 @@
         </t-space>
         <t-space direction="vertical" size="small" class="mt-8">
           <t-collapse
-            :defaultValue="['1']"
+            :defaultValue="['1', '2']"
             expandIconPlacement="right"
             :borderless="true"
           >
@@ -131,6 +131,55 @@
             </t-collapse-panel>
             <t-collapse-panel value="2" header="进阶设置">
               <t-space direction="vertical" size="small">
+                <div class="form-item">
+                  <label>
+                    图标URL
+                    <span>
+                      <label
+                        class="vip-label"
+                        style="font-size: 10px; padding: 0 2px"
+                      >
+                        VIP
+                      </label>
+                    </span>
+                  </label>
+                  <div class="px-8" style="width: 200px">
+                    <template v-if="data.meta2dData.iconUrls">
+                      <div
+                        v-for="(icon, i) of data.meta2dData.iconUrls"
+                        class="flex middle between"
+                        style="height: 30px"
+                      >
+                        <div>
+                          {{ icon.substring(0, 8) }}...{{ icon.substr(-16) }}
+                        </div>
+                        <t-icon
+                          name="close"
+                          class="hover"
+                          @click="removeIconUrl(i)"
+                        />
+                      </div>
+                    </template>
+                    <div class="flex middle" v-if="user.isVip">
+                      <t-input
+                        v-model="data.iconUrl"
+                        placeholder="Font class方式URL"
+                        style="width: 150px; margin-left: -8px"
+                      />
+                      <t-button
+                        theme="default"
+                        style="padding: 4px 8px; margin-left: 8px"
+                        @click="addIconUrl"
+                      >
+                        添加
+                      </t-button>
+                    </div>
+                    <div v-else class="desc mt-4">
+                      支持添加iconfont。
+                      <a :href="assets.account" target="_blank">VIP</a> 功能
+                    </div>
+                  </div>
+                </div>
                 <div class="form-item">
                   <label>初始化动作</label>
                   <t-button
@@ -188,20 +237,28 @@
 </template>
 
 <script lang="ts" setup>
-import { onMounted, reactive, onUnmounted, ref } from 'vue';
+import { onMounted, reactive, onUnmounted } from 'vue';
+import { useUser } from '@/services/user';
 import { getCookie } from '@/services/cookie';
 import ElementTree from './ElementTree.vue';
 import CodeEditor from '@/views/components/common/CodeEditor.vue';
+import { autoSave, useAssets } from '@/services/common';
+import { MessagePlugin } from 'tdesign-vue-next';
 
 const headers = {
   Authorization: 'Bearer ' + (localStorage.token || getCookie('token') || ''),
 };
 const updataData = { directory: '/项目' };
 
+const { assets } = useAssets();
+
+const { user } = useUser();
+
 const data = reactive<any>({
   tab: 1,
   background: [],
   meta2dData: {},
+  iconUrl: '',
 });
 
 const screenList = reactive([
@@ -331,6 +388,28 @@ const onOkDataTransformation = () => {
   meta2d.store.data.socketCbJs = dataTransformationDialog.data;
   dataTransformationDialog.show = false;
 };
+
+const addIconUrl = () => {
+  if (!data.iconUrl || data.iconUrl.substr(-4) !== '.css') {
+    MessagePlugin.error('请填写以.css结尾的font-class引用方式的URL地址');
+    return;
+  }
+  if (!data.meta2dData.iconUrls) {
+    data.meta2dData.iconUrls = [];
+  }
+  data.meta2dData.iconUrls.push(data.iconUrl);
+  // @ts-ignore
+  meta2d.store.data.iconUrls = data.meta2dData.iconUrls;
+  data.iconUrl = '';
+  autoSave(true);
+};
+
+const removeIconUrl = (i: number) => {
+  data.meta2dData.iconUrls.splice(i, 1);
+  // @ts-ignore
+  meta2d.store.data.iconUrls = data.meta2dData.iconUrls;
+  autoSave(true);
+};
 </script>
 <style lang="postcss" scoped>
 .props {

+ 3 - 45
src/views/components/Header.vue

@@ -309,6 +309,7 @@ import {
   magnifier,
   useDot,
   delAttrs,
+  useAssets,
 } from '@/services/common';
 
 const router = useRouter();
@@ -316,38 +317,7 @@ const route = useRoute();
 
 const baseUrl = import.meta.env.BASE_URL || '/';
 
-const assets = reactive({
-  home: 'https://le5le.com',
-  account: 'https://account.le5le.com',
-  helps: [
-    {
-      name: '产品介绍',
-      url: 'https://doc.le5le.com/document/118756411',
-    },
-    {
-      name: '快速上手',
-      url: 'https://doc.le5le.com/document/119363000',
-    },
-    {
-      name: '使用手册',
-      url: 'https://doc.le5le.com/document/118764244',
-    },
-    {
-      name: '快捷键',
-      url: 'https://doc.le5le.com/document/119620214',
-      divider: true,
-    },
-    {
-      name: '企业服务与支持',
-      url: 'https://doc.le5le.com/document/119296274',
-      divider: true,
-    },
-    {
-      name: '关于我们',
-      url: 'https://le5le.com/about.html',
-    },
-  ],
-});
+const { assets, getAssets } = useAssets();
 
 const { user, signout } = useUser();
 const { setDot } = useDot();
@@ -356,19 +326,7 @@ const data = reactive({
 });
 
 onBeforeMount(async () => {
-  // 官网或安装包版本
-  if (
-    import.meta.env.VITE_TRIAL == undefined ||
-    import.meta.env.VITE_TRIAL == 1
-  ) {
-    return;
-  }
-
-  // 企业版
-  const ret = await axios.get('/api/assets');
-  if (ret) {
-    Object.assign(assets, ret);
-  }
+  getAssets();
 });
 
 const onInputName = () => {

+ 28 - 3
src/views/components/PenProps.vue

@@ -270,7 +270,7 @@
                     theme="normal"
                     placeholder="线条宽度"
                     v-model="data.pen.lineWidth"
-                    :min="1"
+                    :min="0"
                     :decimalPlaces="0"
                     @change="changeValue('lineWidth')"
                     class="ml-4"
@@ -817,8 +817,27 @@
               </t-space>
             </t-collapse-panel>
             <t-collapse-panel
-              v-if="data.pen.props.custom"
+              v-if="data.pen.props.icon"
               value="4"
+              header="图标"
+            >
+              <t-space direction="vertical" size="small" class="w-full">
+                <div class="form-item">
+                  <label style="width: 32px">图标 </label>
+                  <i
+                    class="ml-8"
+                    :class="data.pen.iconFamily"
+                    style="line-height: 30px; height: 30px; color: var(--color)"
+                  >
+                    {{ data.pen.icon }}
+                  </i>
+                  <a class="ml-12 mt-4">选择</a>
+                </div>
+              </t-space>
+            </t-collapse-panel>
+            <t-collapse-panel
+              v-if="data.pen.props.custom"
+              value="5"
               header="属性"
             >
               <t-space direction="vertical" size="small" class="w-full">
@@ -1040,10 +1059,16 @@ function initPenData() {
     }
   }
   if (!data.pen.props.image) {
-    if (data.pen.image || data.pen.name === 'image') {
+    if (data.pen.image) {
       data.pen.props.image = true;
     }
   }
+  if (!data.pen.props.icon) {
+    if (data.pen.icon) {
+      data.pen.props.icon = true;
+    }
+  }
+
   if (data.pen.image) {
     data.images = [
       {