Browse Source

Merge branch 'dev' of http://124.70.149.18:10880/lianghj/queenshow into dev

liwei 1 year ago
parent
commit
7f6fa0ac1d
29 changed files with 752 additions and 134 deletions
  1. 1 1
      package.json
  2. 27 26
      public/index.html
  3. 9 0
      src/hooks/initRemSize.ts
  4. 5 0
      src/modules/editor/components/CompUI/basicUI/Image2/component.tsx
  5. 36 16
      src/modules/editor/components/CompUI/basicUI/Image2/index.ts
  6. 155 0
      src/modules/editor/components/CompUI/basicUI/Text/TextForm.tsx
  7. 3 1
      src/modules/editor/components/CompUI/basicUI/Text/component2.tsx
  8. 11 8
      src/modules/editor/components/CompUI/basicUI/Text/index.ts
  9. 15 15
      src/modules/editor/components/CompUI/basicUI/Video/index.ts
  10. 7 7
      src/modules/editor/components/CompUI/basicUI/View.tsx
  11. 3 3
      src/modules/editor/components/CompUI/basicUI/Web3D/index.ts
  12. 1 1
      src/modules/editor/components/CompUI/customUI/Cards/Card15/component.tsx
  13. 40 28
      src/modules/editor/components/CompUI/defines/createAttrsForm.tsx
  14. 132 0
      src/modules/editor/components/CompUI/formItems/Slider.tsx
  15. 18 18
      src/modules/editor/controllers/TransferCtrl/GroupCtrl.ts
  16. 0 2
      src/modules/editor/controllers/TransferCtrl/index.ts
  17. 1 0
      src/modules/editor/module/helpers/index.ts
  18. 5 3
      src/modules/editor/objects/DesignTemp/creates/createCompStyle.ts
  19. 1 0
      src/modules/editor/typings.ts
  20. 5 0
      src/modules/launcher/actions/index.ts
  21. 7 0
      src/modules/launcher/components/Viewport/index.tsx
  22. 5 0
      src/modules/launcher/components/index.ts
  23. 206 0
      src/modules/launcher/controllers/natsController.ts
  24. 15 0
      src/modules/launcher/index.ts
  25. 7 0
      src/modules/launcher/stores/index.ts
  26. 31 0
      src/pages/website/Login/index.tsx
  27. 1 1
      src/pages/website/router.ts
  28. 1 0
      src/styles/theme.less
  29. 4 4
      yarn.lock

+ 1 - 1
package.json

@@ -31,7 +31,7 @@
     "@queenjs-modules/queentree": "^0.0.10",
     "@queenjs-modules/queentree-explorer": "^0.0.6",
     "@queenjs-modules/queentree-explorer-viewer": "^0.0.3",
-    "@queenjs/components": "^0.0.15",
+    "@queenjs/components": "^0.0.19",
     "@queenjs/controllers": "^0.0.6",
     "@queenjs/icons": "^0.0.20",
     "@queenjs/theme": "^0.0.8",

+ 27 - 26
public/index.html

@@ -1,29 +1,30 @@
 <!DOCTYPE html>
 <html lang="">
+  <head>
+    <meta charset="utf-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico" />
+    <title><%= htmlWebpackPlugin.options.title %></title>
+    <script type="text/javascript">
+      var userAgent = navigator.userAgent;
+      if (/micromessenger/i.test(userAgent)) {
+        document.write(
+          '<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"><\/script>'
+        );
+      }
+    </script>
+  </head>
 
-<head>
-  <meta charset="utf-8">
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="viewport" content="width=device-width,initial-scale=1.0">
-  <link rel="icon" href="<%= BASE_URL %>favicon.ico">
-  <title>
-    <%= htmlWebpackPlugin.options.title %>
-  </title>
-  <script type="text/javascript">
-    var userAgent = navigator.userAgent;
-    if (/micromessenger/i.test(userAgent)) {
-      document.write('<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"><\/script>');
-    }
-  </script>
-</head>
-
-<body>
-  <noscript>
-    <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
-        Please enable it to continue.</strong>
-  </noscript>
-  <div id="app"></div>
-  <!-- built files will be auto injected -->
-</body>
-
-</html>
+  <body>
+    <noscript>
+      <strong
+        >We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
+        properly without JavaScript enabled. Please enable it to
+        continue.</strong
+      >
+    </noscript>
+    <div id="app"></div>
+    <!-- built files will be auto injected -->
+  </body>
+</html>

+ 9 - 0
src/hooks/initRemSize.ts

@@ -6,6 +6,15 @@ export function initRemSize() {
     const width = clientWidth > 750 ? 750 : clientWidth;
     const fontSize = (width / 750) * (isPc() ? 50 : 100);
     document.documentElement.style.fontSize = fontSize + "px";
+
+    // if (!isPc()) {
+    //   const meta = document.querySelector(
+    //     "meta[name=viewport]"
+    //   ) as HTMLMetaElement;
+    //   if (meta) {
+    //     meta.content = `width=375,initial-scale=${window.outerWidth / 375}`;
+    //   }
+    // }
   }
 
   window.addEventListener("resize", setRem);

+ 5 - 0
src/modules/editor/components/CompUI/basicUI/Image2/component.tsx

@@ -55,6 +55,11 @@ export const Component = defineComponent({
           class="overflow-hidden"
           compId={props.compId}
           onDblclick={store.isEditMode ? changeVal : undefined}
+          onClick={() => {
+            if (value.showLink && value.link && !store.isEditMode) {
+              window.location.href = value.link;
+            }
+          }}
         >
           <img
             crossorigin="anonymous"

+ 36 - 16
src/modules/editor/components/CompUI/basicUI/Image2/index.ts

@@ -10,31 +10,51 @@ export const options = {
 };
 
 export const { createComp, useCompData } = createCompHooks({
-  value: { url: Dict_Imgs.Default, x: 0, y: 0, s: 1 },
+  value: {
+    url: Dict_Imgs.Default,
+    x: 0,
+    y: 0,
+    s: 1,
+    showLink: false,
+    link: "",
+  },
   layout: {
     size: [750, 400],
   },
 });
 
 export const Form = createAttrsForm([
+  // {
+  //   label: "图片",
+  //   dataIndex: "value.url",
+  //   component: "Input",
+  // },
+  // {
+  //   label: "x偏移",
+  //   dataIndex: "value.x",
+  //   component: "Input",
+  // },
+  // {
+  //   label: "y偏移",
+  //   dataIndex: "value.y",
+  //   component: "Input",
+  // },
+  // {
+  //   label: "缩放",
+  //   dataIndex: "value.s",
+  //   component: "Input",
+  // },
   {
-    label: "图片",
-    dataIndex: "value.url",
-    component: "Input",
-  },
-  {
-    label: "x偏移",
-    dataIndex: "value.x",
-    component: "Input",
-  },
-  {
-    label: "y偏移",
-    dataIndex: "value.y",
-    component: "Input",
+    label: "添加链接",
+    dataIndex: "value.showLink",
+    component: "Switch",
   },
   {
-    label: "缩放",
-    dataIndex: "value.s",
+    dataIndex: "value.link",
     component: "Input",
+    props: {
+      placeholder: "http://",
+    },
+    isVisible: (value, data) => data?.value?.showLink == true,
   },
 ]);

+ 155 - 0
src/modules/editor/components/CompUI/basicUI/Text/TextForm.tsx

@@ -0,0 +1,155 @@
+import { useEditor } from "@/modules/editor";
+import { DesignComp } from "@/modules/editor/objects/DesignTemp/DesignComp";
+import FormUI, { ColumnItem } from "@queenjs/components/FormUI";
+import { defineComponent } from "vue";
+import { any } from "vue-types";
+import { isEmpty } from "lodash";
+import { css } from "@linaria/core";
+import { bgColumns, layoutColumns } from "../../defines/createAttrsForm";
+import {
+  InputNumber,
+  Button,
+  Space,
+  Tooltip,
+  Select,
+  Input,
+} from "ant-design-vue";
+import {
+  BoldOutlined,
+  ItalicOutlined,
+  UnderlineOutlined,
+  StrikethroughOutlined,
+  AlignLeftOutlined,
+  AlignCenterOutlined,
+  AlignRightOutlined,
+} from "@ant-design/icons-vue";
+import { createColorOpts } from "../../defines/formOpts/createColorOpts";
+
+const StyleButtons = defineComponent({
+  setup() {
+    return () => (
+      <div class={ButtonsStyle}>
+        <Tooltip title={"加粗"}>
+          <Button icon={<BoldOutlined />} class={"active"} type="text"></Button>
+        </Tooltip>
+        <Tooltip title={"斜体"}>
+          <Button icon={<ItalicOutlined />} type="text"></Button>
+        </Tooltip>
+        <Tooltip title={"下划线"}>
+          <Button icon={<UnderlineOutlined />} type="text"></Button>
+        </Tooltip>
+        <Tooltip title={"删除线"}>
+          <Button icon={<StrikethroughOutlined />} type="text"></Button>
+        </Tooltip>
+        <Tooltip title={"左对齐"}>
+          <Button icon={<AlignLeftOutlined />} type="text"></Button>
+        </Tooltip>
+        <Tooltip title={"居中对齐"}>
+          <Button icon={<AlignCenterOutlined />} type="text"></Button>
+        </Tooltip>
+        <Tooltip title={"右对齐"}>
+          <Button icon={<AlignRightOutlined />} type="text"></Button>
+        </Tooltip>
+      </div>
+    );
+  },
+});
+
+const TextColumns: ColumnItem[] = [
+  {
+    label: "字体",
+    dataIndex: "fontFamily",
+    component: Select,
+    props: {
+      class: "w-full",
+      options: [{ label: "默认字体", value: "" }]
+        .concat
+        // Object.entries(compMasks).map(([key, value]) => {
+        //   return {
+        //     label: value.name,
+        //     value: key,
+        //   };
+        // })
+        (),
+    },
+  },
+  {
+    label: "字号",
+    dataIndex: "fontSize",
+    component: InputNumber,
+    props: {
+      class: "w-full",
+      min: 12,
+      max: 99,
+    },
+  },
+  {
+    label: "颜色",
+    dataIndex: "color",
+    ...createColorOpts(),
+  },
+  {
+    label: "",
+    dataIndex: "style",
+    component: StyleButtons,
+  },
+];
+
+export const TextForm = defineComponent({
+  props: {
+    component: any<DesignComp>().isRequired,
+  },
+  setup(props) {
+    const { actions } = useEditor();
+    function changeVal(e: { dataIndex: string; value: any }) {
+      actions.updateCompData(props.component, e.dataIndex, e.value);
+    }
+    return () => {
+      const { component } = props;
+      return (
+        <div>
+          <FormUI
+            columns={TextColumns}
+            data={{}}
+            onChange={(v) => {
+              console.log(v);
+            }}
+          />
+          <div>布局</div>
+          <div>
+            <FormUI
+              data={component}
+              columns={layoutColumns}
+              onChange={changeVal}
+            />
+            {!isEmpty(component?.layout?.background) ? (
+              <>
+                <div>背景</div>
+                <FormUI
+                  data={component}
+                  columns={bgColumns}
+                  onChange={changeVal}
+                />
+              </>
+            ) : null}
+          </div>
+        </div>
+      );
+    };
+  },
+});
+const ButtonsStyle = css`
+  width: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  background-color: @inf-form-bg;
+  border-radius: 2px;
+  .ant-btn {
+    flex: 1;
+    &.active {
+      color: @inf-primary-color;
+    }
+  }
+`;
+const FormStyle = css``;

+ 3 - 1
src/modules/editor/components/CompUI/basicUI/Text/component2.tsx

@@ -68,6 +68,7 @@ export const Component = defineComponent({
       if (!dom) return;
       editorInstance = await InlineEditor.create(dom as any, config);
       editorInstance.setData(comp.value);
+      console.log(comp);
       if (store.isPreview) {
         editorInstance.enableReadOnlyMode("editor");
       }
@@ -107,7 +108,8 @@ export const Component = defineComponent({
 });
 
 const textStyle = css`
-  font-size: 12px;
+  height: 100%;
+  font-size: 16px;
   color: #666;
   p {
     margin: 0;

+ 11 - 8
src/modules/editor/components/CompUI/basicUI/Text/index.ts

@@ -1,6 +1,7 @@
+import "@ckeditor/ckeditor5-build-classic/build/translations/zh-cn";
 import { createAttrsForm } from "../../defines/createAttrsForm";
 import { createCompHooks } from "../../defines/createCompHooks";
-import "@ckeditor/ckeditor5-build-classic/build/translations/zh-cn";
+// import { TextForm } from "./TextForm";
 export { Component } from "./component";
 
 export const options = {
@@ -11,14 +12,16 @@ export const options = {
 export const { createComp, useCompData } = createCompHooks({
   value: `<p><span style="font-size:0.36rem;">请输入内容</span></p>`,
   layout: {
-    size: [750, 60]
-  }
+    size: [750, 60],
+  },
 });
 
+// export const Form = TextForm;
+
 export const Form = createAttrsForm([
-  {
-    label: "文本",
-    dataIndex: "value",
-    component: "Input",
-  },
+  // {
+  //   label: "文本",
+  //   dataIndex: "value",
+  //   component: "Input",
+  // },
 ]);

+ 15 - 15
src/modules/editor/components/CompUI/basicUI/Video/index.ts

@@ -22,11 +22,11 @@ export const { createComp, useCompData } = createCompHooks({
 });
 
 export const Form = createAttrsForm([
-  {
-    label: "视频地址",
-    dataIndex: "value.url",
-    component: "Input",
-  },
+  // {
+  //   label: "视频地址",
+  //   dataIndex: "value.url",
+  //   component: "Input",
+  // },
   {
     label: "视频比例",
     dataIndex: "value.ratio",
@@ -42,19 +42,19 @@ export const Form = createAttrsForm([
       ],
     },
   },
-  {
-    label: "自动播放",
-    dataIndex: "value.autoplay",
-    component: "Switch",
-  },
+  // {
+  //   label: "自动播放",
+  //   dataIndex: "value.autoplay",
+  //   component: "Switch",
+  // },
   {
     label: "循环播放",
     dataIndex: "value.loop",
     component: "Switch",
   },
-  {
-    label: "显示控制器",
-    dataIndex: "value.controls",
-    component: "Switch",
-  },
+  // {
+  //   label: "显示控制器",
+  //   dataIndex: "value.controls",
+  //   component: "Switch",
+  // },
 ]);

+ 7 - 7
src/modules/editor/components/CompUI/basicUI/View.tsx

@@ -11,7 +11,7 @@ export const View = defineComponent({
   props: {
     compId: string().isRequired,
   },
-  emits: ["dblclick"],
+  emits: ["dblclick", "click"],
   setup(props, { slots, emit }) {
     const { store, actions, helper, controls } = useEditor();
     const compRef = useCompRef(props.compId);
@@ -35,12 +35,12 @@ export const View = defineComponent({
             store.currStreamCardId == props.compId && CurrCompStyle,
           ]}
           style={helper.createStyle(comp.layout)}
-          // onClick={(e) => {
-          //   e.stopPropagation();
-          //   if (store.isEditMode) {
-          //     actions.pickComp(props.compId);
-          //   }
-          // }}
+          onClick={(e) => {
+            if (!store.isEditMode) {
+              e.stopPropagation();
+              emit("click");
+            }
+          }}
           onDblclick={() => emit("dblclick")}
         >
           <div

+ 3 - 3
src/modules/editor/components/CompUI/basicUI/Web3D/index.ts

@@ -18,8 +18,8 @@ export const { createComp, useCompData } = createCompHooks({
     ratio: 1,
   },
   layout: {
-    size: [750, 750]
-  }
+    size: [750, 750],
+  },
 });
 
 export const Form = createAttrsForm([
@@ -34,7 +34,7 @@ export const Form = createAttrsForm([
     component: ImagePicker,
   },
   {
-    label: "视频比例",
+    label: "场景比例",
     dataIndex: "value.ratio",
     component: "Select",
     props: {

+ 1 - 1
src/modules/editor/components/CompUI/customUI/Cards/Card15/component.tsx

@@ -35,7 +35,7 @@ export const Component = createUIComp({
             >
               <Text.Component
                 compId={children.colorText}
-                class="min-w-1.25rem px-0.1rem bg-light-50"
+                class="min-w-1.25rem bg-light-50"
               />
             </div>
           </div>

+ 40 - 28
src/modules/editor/components/CompUI/defines/createAttrsForm.tsx

@@ -2,14 +2,15 @@ import { useEditor } from "@/modules/editor";
 import { DesignComp } from "@/modules/editor/objects/DesignTemp/DesignComp";
 import { compMasks } from "@/modules/editor/objects/DesignTemp/creates/CompMasks";
 import FormUI, { ColumnItem } from "@queenjs/components/FormUI";
-import { InputNumber, Select } from "ant-design-vue";
+import { Input, InputNumber, Select } from "ant-design-vue";
 import { isEmpty } from "lodash";
 import { defineComponent } from "vue";
 import { any } from "vue-types";
 import { GroupNumber } from "../formItems/GroupNumber";
+import Slider from "../formItems/Slider";
 import { createColorOpts } from "./formOpts/createColorOpts";
 
-const layoutColumns: ColumnItem[] = [
+export const layoutColumns: ColumnItem[] = [
   {
     label: "尺寸",
     dataIndex: "layout.size",
@@ -41,11 +42,11 @@ const layoutColumns: ColumnItem[] = [
   //   dataIndex: "layout.padding",
   //   component: "Input",
   // },
-  {
-    label: "偏移矩阵",
-    dataIndex: "layout.transformMatrix",
-    component: "Input",
-  },
+  // {
+  //   label: "偏移矩阵",
+  //   dataIndex: "layout.transformMatrix",
+  //   component: Input,
+  // },
   // {
   //   label: "上下偏移",
   //   dataIndex: "layout.offsetY",
@@ -56,34 +57,45 @@ const layoutColumns: ColumnItem[] = [
   //   },
   //   getValue: (v) => v || 0,
   // },
+  // {
+  //   label: "层级",
+  //   dataIndex: "layout.zIndex",
+  //   component: InputNumber,
+  //   props: {
+  //     min: 0,
+  //     max: 99,
+  //   },
+  // },
+  // {
+  //   label: "遮罩",
+  //   dataIndex: "layout.mask",
+  //   component: Select,
+  //   props: {
+  //     class: "w-full",
+  //     options: [{ label: "无", value: "" }].concat(
+  //       Object.entries(compMasks).map(([key, value]) => {
+  //         return {
+  //           label: value.name,
+  //           value: key,
+  //         };
+  //       })
+  //     ),
+  //   },
+  // },
   {
-    label: "层级",
-    dataIndex: "layout.zIndex",
-    component: InputNumber,
+    label: "透明度",
+    dataIndex: "layout.opacity",
+    component: Slider,
     props: {
+      defaultValue: 1,
       min: 0,
-      max: 99,
-    },
-  },
-  {
-    label: "遮罩",
-    dataIndex: "layout.mask",
-    component: Select,
-    props: {
-      class: "w-full",
-      options: [{ label: "无", value: "" }].concat(
-        Object.entries(compMasks).map(([key, value]) => {
-          return {
-            label: value.name,
-            value: key,
-          };
-        })
-      ),
+      max: 1,
+      step: 0.01,
     },
   },
 ];
 
-const bgColumns: ColumnItem[] = [
+export const bgColumns: ColumnItem[] = [
   {
     label: "背景颜色",
     dataIndex: "layout.background.color",

+ 132 - 0
src/modules/editor/components/CompUI/formItems/Slider.tsx

@@ -0,0 +1,132 @@
+import { css } from "@linaria/core";
+import { InputNumber, Slider } from "ant-design-vue";
+import { defineComponent, reactive, watchEffect } from "vue";
+import { bool, number } from "vue-types";
+
+export default defineComponent({
+  props: {
+    defaultValue: number().def(0),
+    disabled: bool().def(false),
+    value: number(),
+    min: number(),
+    max: number(),
+    step: number(),
+  },
+  emits: ["change"],
+  setup(props, { emit }) {
+    const state = reactive({
+      value: props.value,
+    });
+
+    const changeVal = () => {
+      if (state.value == props.value) return;
+      emit("change", state.value);
+    };
+
+    watchEffect(() => {
+      if (props.value != undefined) {
+        state.value = props.value;
+      }
+    });
+
+    return () => {
+      const { defaultValue, disabled, min, max, step } = props;
+      const attr = {
+        defaultValue,
+        disabled: disabled,
+        value: state.value,
+        min,
+        max,
+        step,
+        onChange: (value: any) => {
+          state.value = value;
+          changeVal();
+        },
+      };
+      return (
+        <div class={SliderView}>
+          <Slider
+            class="item_slider"
+            tooltipVisible={false}
+            {...attr}
+            onAfterChange={() => changeVal()}
+          />
+          <InputNumber
+            class="item_input"
+            {...attr}
+            onPressEnter={() => changeVal()}
+            // onBlur={() => {
+            //   if (state.value !== props.value) changeVal();
+            // }}
+          />
+        </div>
+      );
+    };
+  },
+});
+const SliderView = css`
+  flex: 1;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  .item_slider {
+    flex: 1;
+  }
+  /* slider style */
+  .ant-slider-disabled {
+    opacity: 0.7;
+  }
+  .ant-slider-step {
+    background-color: rgba(255, 255, 255, 0.27);
+  }
+  .ant-slider-track {
+    border-radius: 4px;
+    background-color: rgba(255, 255, 255, 1);
+  }
+
+  .ant-slider:not(.ant-slider-disabled):hover {
+    .ant-slider-handle {
+      background-color: @inf-primary-color;
+      &:not(.ant-tooltip-open) {
+        border-color: #fff;
+      }
+    }
+  }
+  .ant-slider {
+    &.ant-slider-disabled {
+      .ant-slider-handle {
+        background-color: #bbb;
+        opacity: 0.8;
+      }
+    }
+  }
+  .ant-slider-handle {
+    width: 8px;
+    border-radius: 2px;
+    border-color: #fff;
+    background-color: #fff;
+  }
+
+  .ant-slider-handle-click-focused {
+    border-color: #fff;
+    background-color: @inf-primary-color;
+  }
+  /* input style */
+  .item_input {
+    width: 42px;
+    margin-left: 10px;
+    border: none;
+    padding: 2px 0;
+    text-align: center;
+    font-size: 12px;
+    background-color: rgba(252, 254, 255, 0.1);
+    .ant-input-number-handler-wrap {
+      display: none;
+    }
+    .ant-input-number-input {
+      height: auto;
+      padding: 0 2px;
+      text-align: center;
+    }
+  }
+`;

+ 18 - 18
src/modules/editor/controllers/TransferCtrl/GroupCtrl.ts

@@ -4,24 +4,24 @@ import { DesignComp } from "../../objects/DesignTemp/DesignComp";
 import { Matrix } from "./Matrix";
 
 export class GroupActionCtrl extends ModuleControl<EditorModule> {
-  init() {
-    document.body.addEventListener("keydown", this.enableGroupMode);
-  }
-  enableGroupMode = (event: KeyboardEvent) => {
-    if (event.key === "Control" && !this.store.groupModeStatus) {
-      this.actions.enableGroupMode();
-      document.body.addEventListener("keyup", this.disableGroupMode);
-    }
-  };
-  disableGroupMode = (event: KeyboardEvent) => {
-    if (event.key === "Control") {
-      this.actions.disableGroupMode();
-      document.body.removeEventListener("keyup", this.disableGroupMode);
-    }
-  };
-  destroy() {
-    document.body.removeEventListener("keydown", this.enableGroupMode);
-  }
+  // init() {
+  //   document.body.addEventListener("keydown", this.enableGroupMode);
+  // }
+  // enableGroupMode = (event: KeyboardEvent) => {
+  //   if (event.key === "Control" && !this.store.groupModeStatus) {
+  //     this.actions.enableGroupMode();
+  //     document.body.addEventListener("keyup", this.disableGroupMode);
+  //   }
+  // };
+  // disableGroupMode = (event: KeyboardEvent) => {
+  //   if (event.key === "Control") {
+  //     this.actions.disableGroupMode();
+  //     document.body.removeEventListener("keyup", this.disableGroupMode);
+  //   }
+  // };
+  // destroy() {
+  //   document.body.removeEventListener("keydown", this.enableGroupMode);
+  // }
 
   async combineGroup() {
     const { helper, store } = this;

+ 0 - 2
src/modules/editor/controllers/TransferCtrl/index.ts

@@ -51,8 +51,6 @@ export class TransferCtrl extends ModuleControl<EditorModule> {
   };
 
   init(pageEl: HTMLElement) {
-    this.groupCtrl.init();
-
     this.currComp = this.module.store.currComp;
     this.compEl = this.currComp.$el;
     this.pageEl = pageEl;

+ 1 - 0
src/modules/editor/module/helpers/index.ts

@@ -7,6 +7,7 @@ import { Layout } from "../../typings";
 export const helpers = EditorModule.helper({
   designToNaturalSize(value: number) {
     return parseFloat((value / 100).toFixed(2)) + "rem";
+    // return value / 2 + "px";
   },
   pxToDesignSize(value: number) {
     return value * 2;

+ 5 - 3
src/modules/editor/objects/DesignTemp/creates/createCompStyle.ts

@@ -15,6 +15,10 @@ export function createCompStyle(module: EditorModule, layout: Layout) {
     style.display = "none";
   }
 
+  if (layout.opacity !== undefined) {
+    style["opacity"] = layout.opacity;
+  }
+
   if (layout.zIndex) {
     style["zIndex"] = layout.zIndex;
   }
@@ -59,12 +63,10 @@ export function createCompStyle(module: EditorModule, layout: Layout) {
   if (layout.transformMatrix) {
     style.transform = layout.transformMatrix;
     style.transformOrigin = "0 0";
-
   } else {
-    const v = parseTransform(transform)
+    const v = parseTransform(transform);
     if (v) style.transform = v;
   }
-  
 
   if (layout.background) {
     if (layout.background.color) {

+ 1 - 0
src/modules/editor/typings.ts

@@ -20,6 +20,7 @@ export type Layout = {
   margin?: string;
   padding?: string;
   transformMatrix?: string;
+  opacity?: number;
 
   background?: Background;
 };

+ 5 - 0
src/modules/launcher/actions/index.ts

@@ -0,0 +1,5 @@
+import { LauncherModule } from "..";
+
+export const actions = LauncherModule.action({
+  init() {},
+});

+ 7 - 0
src/modules/launcher/components/Viewport/index.tsx

@@ -0,0 +1,7 @@
+import { defineComponent } from "vue";
+
+export const Viewport = defineComponent({
+  setup() {
+    return () => <div></div>;
+  },
+});

+ 5 - 0
src/modules/launcher/components/index.ts

@@ -0,0 +1,5 @@
+import { Viewport } from "./Viewport";
+
+export const components = {
+  Viewport,
+};

+ 206 - 0
src/modules/launcher/controllers/natsController.ts

@@ -0,0 +1,206 @@
+import { Empty, StringCodec, connect } from "nats.ws";
+import { queenApi } from "queenjs";
+
+export class BusController {
+  _params = new URLSearchParams(decodeURIComponent(location.search));
+
+  _conn: any;
+  _isConned = false;
+  _startInit = false;
+
+  getQuery(name: string): string {
+    return this._params.get(name) as string;
+  }
+
+  async init(host?: string) {
+    const wsHost = host ? host : this.getQuery("host");
+    if (this._startInit || !wsHost || wsHost == "null") return;
+    this._startInit = true;
+  
+    queenApi.showLoading("服务连接中...");
+   
+    console.log("ws host=>", wsHost)
+
+    
+    let ret = false;
+    try {
+      this._conn = await connect({ servers: wsHost });
+      this._isConned = !!this._conn;
+
+      ret = true;
+    } catch (error) {
+      console.log(error);
+      queenApi.messageError("连接失败!");
+    }
+    queenApi.hideLoading();
+    this._startInit = false;
+
+    return ret;
+  }
+
+  async subscribe(subject: string, callback: any) {
+    if (!this._isConned) {
+      await this.init();
+    }
+
+    if (!this._isConned) {
+      console.error("建立连接失败");
+      return;
+    }
+
+    const sc = StringCodec();
+    const sub = this._conn.subscribe(subject);
+    console.log(sub);
+
+    (async () => {
+      for await (const m of sub) {
+        console.log(sub);
+
+        const ret = sc.decode(m.data);
+        console.log(subject, "=>recieved");
+        try {
+          if (ret) {
+            const msg = JSON.parse(ret);
+            callback(msg);
+          } else {
+            callback(ret);
+          }
+        } catch (error) {
+          console.log(subject, "=>recieved json parse eror", ret);
+          console.log(error);
+        }
+      }
+      console.log(subject, "subscription closed");
+    })();
+    return function () {
+      sub.unsubscribe();
+    };
+  }
+  async requestApi(subject: string, data?: any, timeout?: number) {
+     const ret = await this.request(subject, data, timeout)
+     console.log("request api=>", ret)
+     
+     if (ret.error || (ret.result.ErrorNo && ret.result.ErrorNo != 200) ) {
+       queenApi.messageError(ret.error || ret.result.ErrorDesc );
+       return
+     }
+     try {
+        const retJson = ret.result.Result;
+        if (!retJson) return;
+        if (retJson[0] != '{' && retJson[0] != '[') return retJson;
+        return JSON.parse(retJson)
+     } catch (error) {
+        console.log( ret );
+        console.error(error);
+     }
+  }
+
+  RequestWebView(name: string, data:any) {
+    return new Promise((r)=>{
+      let cancel:any = null;
+      this.subscribe("webview.close."+name, function(payload:any){
+        cancel&&cancel();
+        r(payload)
+      }).then(c=>{
+         cancel = c;
+      })
+      this.requestApi("webview.open", {...data, name})
+    })
+  }
+
+  async request(subject: string, data?: any, timeout?: number) {
+    if (!this._isConned) {
+      await this.init();
+    }
+
+    const ret: { error: string; result: any } = { error: "", result: null };
+    if (!this._isConned) {
+      console.error("建立连接失败");
+      ret.error = "建立连接失败";
+
+      queenApi.showConfirm({
+        title: "数据请求失败",
+        content: "请求数据失败,请重新启动后再试",
+        type: "danger",
+      });
+      return ret;
+    }
+
+    const sc = StringCodec();
+    try {
+      let req = Empty;
+      if (data) {
+        if (typeof data != "string") {
+          req = sc.encode(JSON.stringify(data));
+        } else {
+          req = sc.encode(data);
+        }
+      }
+      const options = { timeout: 5000 };
+      if (timeout) {
+        options.timeout = timeout;
+      }
+      const m = await this._conn.request(subject, req, options);
+      let payload = sc.decode(m.data);
+      try {
+        payload = JSON.parse(payload);
+        console.log("m=>", payload);
+      } catch (error) {
+        console.log(error);
+      }
+      ret.result = payload;
+    } catch (error: any) {
+      console.error(error);
+      ret.error = error.message || "请求" + subject + "出错";
+      if (ret.error == "503") {
+        //NoResponders
+        ret.error = "网路异常,请重新服务";
+      }
+    }
+    return ret;
+  }
+
+  close() {
+    if (!this._isConned) {
+      return;
+    }
+    return this._conn.close();
+  }
+
+  
+  async Public(subject:string, data:any) {
+    if (!this._isConned) {
+      await this.init();
+    }
+    const ret: { error: string; result: any } = { error: "", result: null };
+    if (!this._isConned) {
+      console.error("建立连接失败");
+      ret.error = "建立连接失败";
+      queenApi.showConfirm({
+        title: "数据请求失败",
+        content: "请求数据失败,请重新启动后再试",
+        type: "danger",
+      });
+      return false;
+    }
+
+    const sc = StringCodec();
+    try {
+      let req = Empty;
+      if (data) {
+        if (typeof data != "string") {
+          req = sc.encode(JSON.stringify(data));
+        } else {
+          req = sc.encode(data);
+        }
+      }
+      this._conn.publish(subject,req);
+
+    } catch (error: any) {
+      console.log( error);
+      return false
+    }
+
+    return true;
+  }
+}

+ 15 - 0
src/modules/launcher/index.ts

@@ -0,0 +1,15 @@
+import { ModuleRoot } from "queenjs";
+import { actions } from "./actions";
+import { components } from "./components";
+import { stores } from "./stores";
+import { BusController } from "@/controllers/natsController";
+
+export class LauncherModule extends ModuleRoot {
+  components = this.useComponents(components);
+  store = this.createStore(stores);
+  actions = this.createActions(actions);
+
+  controls = {
+    natsCtrl: new BusController(),
+  };
+}

+ 7 - 0
src/modules/launcher/stores/index.ts

@@ -0,0 +1,7 @@
+import { LauncherModule } from "..";
+
+export const stores = LauncherModule.store({
+  state: () => ({
+    readyState: false,
+  }),
+});

+ 31 - 0
src/pages/website/Login/index.tsx

@@ -0,0 +1,31 @@
+import { css } from "@linaria/core";
+import Login from "@queenjs-modules/auth/components/Login";
+import { defineComponent } from "vue";
+export default defineComponent(() => {
+  return () => (
+    <div class={LoginStyle}>
+      <Login class="!h-auto flex-1" />
+      <div class="footer_copy">
+        <a href="https://beian.miit.gov.cn" target="_blank">
+          蜀ICP备18008991号-3
+        </a>
+        版权所有:3Dqueen
+      </div>
+    </div>
+  );
+});
+const LoginStyle = css`
+  height: 100vh;
+  display: flex;
+  flex-direction: column;
+  .footer_copy {
+    padding: 10px 0;
+    text-align: center;
+    color: #999;
+  }
+
+  .footer_copy a {
+    margin-right: 5px;
+    color: #fff;
+  }
+`;

+ 1 - 1
src/pages/website/router.ts

@@ -52,7 +52,7 @@ const routes: Array<RouteRecordRaw> = [
   {
     path: "/login",
     name: "login",
-    component: () => import("@queenjs-modules/auth/components/Login"),
+    component: () => import("./Login"),
   },
   {
     path: "/forget",

+ 1 - 0
src/styles/theme.less

@@ -28,4 +28,5 @@
 @inf-primary-hover-bg: darken(@inf-primary-bg, 10%);
 
 @inf-header-height: 72px;
+@inf-form-bg: #383838;
 @inf-input-padding-inline: 0;

+ 4 - 4
yarn.lock

@@ -1763,10 +1763,10 @@
   resolved "http://124.70.149.18:4873/@queenjs-modules%2fqueentree/-/queentree-0.0.10.tgz#f6344ab32ba0163a3b8cf4f4b9fe6641aef2bea7"
   integrity sha512-P4cIjXKgcvd8h3vVs4f1rGLNf3/Kd5G+qGiZN+idkLjiu22HU6SNmOVLUwV6PuKg+9sTPRn7FKamSHuFxXWX5g==
 
-"@queenjs/components@^0.0.15":
-  version "0.0.15"
-  resolved "http://124.70.149.18:4873/@queenjs%2fcomponents/-/components-0.0.15.tgz#5dcb42d8615ab2d64441e3ecb0c0d097d7361669"
-  integrity sha512-c6yqk7NxIMrrE5ULX8d7iubBJoUKYlDGvCjfmPGSQV6i8UZJHzcnauH2BIsm5ASO5XeTuFxsuRCuXq8AKA0gpQ==
+"@queenjs/components@^0.0.19":
+  version "0.0.19"
+  resolved "http://124.70.149.18:4873/@queenjs%2fcomponents/-/components-0.0.19.tgz#b3a0a91cf24fd2b46610c338ab1f0d68e0e6af60"
+  integrity sha512-XEuCLkyy9o2CFZu1nPf+9ND/m+1D+ib6zn8oSfKtwcB1rvz/lL6e/iqSqdZnUZ6ia2GAI0gRKcA0/3FRYJDL6g==
   dependencies:
     "@queenjs/utils" "^0.0.1"