Browse Source

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

bianjiang 1 year ago
parent
commit
c06f5bb7de
46 changed files with 1050 additions and 298 deletions
  1. 1 1
      scripts/deployHtmlToServer.js
  2. 9 0
      src/hooks/initRemSize.ts
  3. 5 0
      src/modules/editor/components/CompUI/basicUI/Image2/component.tsx
  4. 36 16
      src/modules/editor/components/CompUI/basicUI/Image2/index.ts
  5. 32 6
      src/modules/editor/components/CompUI/basicUI/Text/component.tsx
  6. 7 7
      src/modules/editor/components/CompUI/basicUI/Text/index.ts
  7. 65 80
      src/modules/editor/components/CompUI/basicUI/Transfer/select.tsx
  8. 15 15
      src/modules/editor/components/CompUI/basicUI/Video/index.ts
  9. 4 4
      src/modules/editor/components/CompUI/basicUI/View.tsx
  10. 3 3
      src/modules/editor/components/CompUI/basicUI/Web3D/index.ts
  11. 2 0
      src/modules/editor/components/CompUI/basicUI/hooks.ts
  12. 1 1
      src/modules/editor/components/CompUI/customUI/Cards/Card15/component.tsx
  13. 38 26
      src/modules/editor/components/CompUI/defines/createAttrsForm.tsx
  14. 132 0
      src/modules/editor/components/CompUI/formItems/Slider.tsx
  15. 6 6
      src/modules/editor/components/Viewport/Header/ShareBox.tsx
  16. 93 39
      src/modules/editor/controllers/SelectCtrl/index.ts
  17. 1 1
      src/modules/editor/controllers/SelectCtrl/objects/displayObject.ts
  18. 18 18
      src/modules/editor/controllers/TransferCtrl/GroupCtrl.ts
  19. 0 2
      src/modules/editor/controllers/TransferCtrl/index.ts
  20. 19 5
      src/modules/editor/module/actions/edit.ts
  21. 16 0
      src/modules/editor/module/actions/editWithManualHistory.ts
  22. 1 0
      src/modules/editor/module/helpers/index.ts
  23. 3 3
      src/modules/editor/module/index.ts
  24. 5 3
      src/modules/editor/objects/DesignTemp/creates/createCompStyle.ts
  25. 5 2
      src/modules/editor/objects/Toolbars/CompToolbars.ts
  26. 2 1
      src/modules/editor/objects/Toolbars/TreeToolbars.ts
  27. 44 0
      src/modules/editor/objects/Toolbars/default.ts
  28. 1 0
      src/modules/editor/typings.ts
  29. 5 0
      src/modules/launcher/actions/index.ts
  30. 7 0
      src/modules/launcher/components/Viewport/index.tsx
  31. 5 0
      src/modules/launcher/components/index.ts
  32. 206 0
      src/modules/launcher/controllers/natsController.ts
  33. 15 0
      src/modules/launcher/index.ts
  34. 7 0
      src/modules/launcher/stores/index.ts
  35. 5 5
      src/modules/resource/actions/material.ts
  36. 12 12
      src/modules/resource/actions/promotion.tsx
  37. 5 5
      src/modules/resource/components/PromotionItem.tsx
  38. 6 4
      src/modules/resource/components/ResourceManager/Toolbar.tsx
  39. 5 5
      src/modules/resource/controllers/ComponentController.ts
  40. 10 10
      src/modules/resource/controllers/PromotionController.ts
  41. 3 1
      src/pages/website/Material2/controller.tsx
  42. 6 7
      src/pages/website/Promotion2/components/ShareModal.tsx
  43. 112 0
      src/pages/website/Settings/ResetForm.tsx
  44. 22 0
      src/pages/website/Settings/ResetPassModal.tsx
  45. 46 2
      src/pages/website/Settings/index.tsx
  46. 9 8
      src/pages/website/components/layout/LeftContent.tsx

+ 1 - 1
scripts/deployHtmlToServer.js

@@ -23,7 +23,7 @@ fs.writeFileSync(nativePath + path.sep + 'share.html', shareHtml);
 // var consoleHtml = fs.readFileSync('dist/console.html');
 // fs.writeFileSync(nativePath + path.sep + 'console.html', consoleHtml);
 
-var serverPath = `/var/www/html/projects/queenshowv1`;
+var serverPath = `/var/www/queenshow`;
 
 var ftpUtils = new sftp({
     remotePath: serverPath,

+ 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,
   },
 ]);

+ 32 - 6
src/modules/editor/components/CompUI/basicUI/Text/component.tsx

@@ -7,10 +7,11 @@ import { FontColor, FontFamily, FontSize } from "@ckeditor/ckeditor5-font";
 import { Link } from "@ckeditor/ckeditor5-link";
 import { Paragraph } from "@ckeditor/ckeditor5-paragraph";
 import { css } from "@linaria/core";
-import { defineComponent, onUnmounted, watch, watchEffect } from "vue";
-import { string } from "vue-types";
+import { defineComponent, onUnmounted, watch, watchEffect , ref} from "vue";
+import { string} from "vue-types";
 import { useCompData } from ".";
 import { View } from "../View";
+import { nextTick } from "process";
 
 export const Component = defineComponent({
   props: {
@@ -18,7 +19,13 @@ export const Component = defineComponent({
   },
   setup(props) {
     const comp = useCompData(props.compId);
-    const { store, actions } = useEditor();
+    const { store, actions , helper, controls} = useEditor();
+
+    const fontSizeOptions=[];
+    const list = [12, 14, 16, 18, 20, 24, 28, 32, 38, 42, 46, 52, 60]
+    for (const s of list) {
+      fontSizeOptions.push({title: s+"", model: s + "px"})
+    }
     const config = {
       language: "zh-cn",
       plugins: [
@@ -33,7 +40,8 @@ export const Component = defineComponent({
         Alignment,
       ],
       fontSize: {
-        options: [12, 14, 16, 18, 20, 24, 28, 32, 38, "2rem", 46, 52, 60],
+        options: fontSizeOptions,
+        supportAllValues:true,
       },
       toolbar: {
         items: [
@@ -94,7 +102,18 @@ export const Component = defineComponent({
         document.removeEventListener("mousedown", blur, { capture: true });
       };
     }
+    const inputRef = ref<any>();
+    if (store.isEditMode) {
+      actions.on("textFocus", (compId, focus:boolean)=>{
+        if (compId != props.compId) return;
 
+        if (focus) {
+          editorInstance.focus();
+          return;
+        } 
+      })  
+    }
+    
     return () => (
       <View
         class={[textStyle, store.currCompId === props.compId && "drag-disable"]}
@@ -102,13 +121,19 @@ export const Component = defineComponent({
       >
         <ckeditor
           class={textStyle}
+          ref={inputRef}
           editor={InlineEditor}
           onFocus={() => {
+            console.log("on  onn focus !!!")
             store.setTextEditingState(true);
           }}
           onInput={(value: any) => {
             if (editorInstance && comp.value !== value) {
-              actions.updateCompData(comp, "value", value);
+              // actions.updateCompData(comp, "value", value);
+              nextTick(()=>{
+                actions.updateCompDatas(comp, ["value", "layout.size.1"], [value, helper.pxToDesignSize(inputRef.value?.$el.clientHeight)])
+                controls.selectCtrl.upgateGizmoStyle();
+              })
             }
           }}
           onReady={(editor: InlineEditor) => {
@@ -126,7 +151,8 @@ export const Component = defineComponent({
 });
 
 const textStyle = css`
-  font-size: 12px;
+  font-size: 0.24rem;
+  width: 100%;
   color: #666;
   p {
     margin: 0;

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

@@ -1,6 +1,6 @@
+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";
 
@@ -10,7 +10,7 @@ export const options = {
 };
 
 export const { createComp, useCompData } = createCompHooks({
-  value: "<p>请输入内容</p>",
+  value: `<p><span style="font-size:0.36rem;">请输入内容</span></p>`,
   layout: {
     size: [750, 60],
   },
@@ -19,9 +19,9 @@ export const { createComp, useCompData } = createCompHooks({
 // export const Form = TextForm;
 
 export const Form = createAttrsForm([
-  {
-    label: "文本",
-    dataIndex: "value",
-    component: "Input",
-  },
+  // {
+  //   label: "文本",
+  //   dataIndex: "value",
+  //   component: "Input",
+  // },
 ]);

+ 65 - 80
src/modules/editor/components/CompUI/basicUI/Transfer/select.tsx

@@ -1,9 +1,9 @@
-import { IconRotate } from "@/assets/icons";
+import { IconRotate , IconMove} from "@/assets/icons";
 import { CompToolbars } from "@/modules/editor/objects/Toolbars";
 import { css } from "@linaria/core";
 import { defineComponent, onMounted, onUnmounted, ref, nextTick } from "vue";
 import { useEditor } from "../../../..";
-import { styles } from "dom7";
+
 
 export const SelectTransfer = defineComponent({
   setup() {
@@ -12,55 +12,21 @@ export const SelectTransfer = defineComponent({
     const { selectCtrl } = controls;
     const { transferStyle } = selectCtrl;
 
-    const selectRectRef = ref();
-    const rotateRef = ref();
-    const rotateRef2 = ref();
-    const rotateRef3 = ref();
-    const scaleBottomrightRef = ref();
-    const scaleBottomLeftRef = ref();
-    const scaleTopLeftRef = ref();
-    const scaleTopRightRef = ref();
-    const scaleRightRef = ref();
-    const scaleLeftRef = ref();
-
-    const scaleTopRef = ref();
-    const scaleBottomRef = ref();
-    const toolbarRef = ref();
-
-    onMounted(() => {
-      nextTick(() => {
-        selectRectRef.value.editable = "move";
-        rotateRef.value.editable = "rotate";
-        rotateRef2.value.editable = "rotate";
-        rotateRef3.value.editable = "rotate";
-        scaleBottomrightRef.value.editable = "scaleBottomright";
-
-        scaleBottomLeftRef.value.editable = "scaleBottomleft";
-        scaleTopLeftRef.value.editable = "scaleTopleft";
-        scaleTopRightRef.value.editable = "scaleTopright";
-        toolbarRef.value.editable = "toolbar"
-      });
-    });
 
     return () => {
-      if (selectCtrl.transferStyle.showOrthScale) {
-        nextTick(() => {
-          scaleRightRef.value.editable = "scaleright";
-          scaleLeftRef.value.editable = "scaleleft";
-          scaleTopRef.value.editable = "scaletop";
-          scaleBottomRef.value.editable = "scalebottom";
-        });
-      }
-
       let toolbarOpts = CompToolbars.default;
       let comp: any = null;
       if (selectCtrl.selected.length == 1) {
         comp = selectCtrl.selected[0].comp;
         //@ts-ignore
         toolbarOpts = CompToolbars[comp.compKey] || toolbarOpts;
+      }  else {
+        toolbarOpts = CompToolbars.MultiSelector;
       }
+
       const w = selectCtrl.objContainer?.getBound();
-      
+      const isTextEdit = selectCtrl.selected.length == 1 && selectCtrl.selected[0].comp.compKey == "Text";
+
       return (
         <div
           class={[
@@ -72,14 +38,14 @@ export const SelectTransfer = defineComponent({
           }}
         >
           <div
-            ref={toolbarRef}
+            id= "toolbar"
             class={toolbarStyle}
             style={{
               top: w?.y + "px",
               left: w?.x + "px",
             }}
           >
-            {comp &&
+            {
               toolbarOpts.map((item) => {
                 return item.getVisible.call(editor, comp) ? (
                   <item.component
@@ -88,12 +54,13 @@ export const SelectTransfer = defineComponent({
                     onClick={() => item.onClick.call(editor, comp)}
                   />
                 ) : null;
-              })}
+              })
+            }
           </div>
 
           <div
             class={["absolute", selctRectStyle]}
-            ref={selectRectRef}
+            id="movecenter"
             style={{
               width: transferStyle.width + "px",
               height: transferStyle.height + "px",
@@ -105,63 +72,81 @@ export const SelectTransfer = defineComponent({
                 <div class={borderContentStyle} style={{width: transferStyle.relWidth + "px", height: transferStyle.relHeight + "px"}}></div>
             </div>
             <>
-              <div
-                class={[resizeStyle, scaleBottomRightStyle]}
-                style={{ transform: transferStyle.matrixInvert }}
-                ref={scaleBottomrightRef}
-              />
-              <div
-                class={[resizeStyle, scaleBottomLeftStyle]}
-                style={{ transform: transferStyle.matrixInvert }}
-                ref={scaleBottomLeftRef}
-              />
-              <div
-                class={[resizeStyle, scaleTopLeftStyle]}
-                style={{ transform: transferStyle.matrixInvert }}
-                ref={scaleTopLeftRef}
-              />
+              
+              {
+                !isTextEdit &&  <div
+                  class={[resizeStyle, scaleBottomRightStyle]}
+                  style={{ transform: transferStyle.matrixInvert }}
+                  id="scaleBottomright"
+                />
+              }
+
+                {
+                  !isTextEdit &&   <div
+                    class={[resizeStyle, scaleBottomLeftStyle]}
+                    style={{ transform: transferStyle.matrixInvert }}
+                    id="scaleBottomleft"
+                  />
+                }
 
-              <div
-                class={[resizeStyle, scaleTopRightStyle]}
-                style={{ transform: transferStyle.matrixInvert }}
-                ref={scaleTopRightRef}
-              />
+              {
+                  !isTextEdit &&<div
+                  class={[resizeStyle, scaleTopLeftStyle]}
+                  style={{ transform: transferStyle.matrixInvert }}
+                  id="scaleTopleft"
+                />
+              }
+              {
+                  !isTextEdit && <div
+                  class={[resizeStyle, scaleTopRightStyle]}
+                  style={{ transform: transferStyle.matrixInvert }}
+                  id="scaleTopright"
+                />
+              }
+
+              <div class={transformBtnsStyle} style={{ transform: transferStyle.matrixInvert }}>
+
+                <div
+                    class={transBtnStyle}
+                    id="moveicon"
+                  >
+                    <IconMove />
+                </div>
 
-              <div class={transformBtnsStyle} ref={rotateRef3} style={{ transform: transferStyle.matrixInvert }}>
                 <div
                   class={transBtnStyle}
-                  ref={rotateRef}
+                  id = "rotate"
                 >
-                  <IconRotate ref={rotateRef2} />
+                  <IconRotate  />
                 </div>
               </div>
 
-              {transferStyle.showOrthScale && (
+              {transferStyle.showOrthScale && !isTextEdit && (
                 <div
                   class={[resizeHeightBtnCls, scaleTopCls]}
                   style={{ transform: transferStyle.matrixInvert }}
-                  ref={scaleTopRef}
+                  id="scaletop"
                 />
               )}
-              {transferStyle.showOrthScale && (
+              {transferStyle.showOrthScale && !isTextEdit && (
                 <div
                   class={[resizeHeightBtnCls, scaleBottomCls]}
                   style={{ transform: transferStyle.matrixInvert }}
-                  ref={scaleBottomRef}
+                  id="scalebottom"
                 />
               )}
-              {transferStyle.showOrthScale && (
+              {transferStyle.showOrthScale &&  (
                 <div
                   class={[resizeWidthBtnCls, scaleRightCls]}
                   style={{ transform: transferStyle.matrixInvert }}
-                  ref={scaleRightRef}
+                  id="scaleright"
                 />
               )}
               {transferStyle.showOrthScale && (
                 <div
                   class={[resizeWidthBtnCls, scaleLeftCls]}
                   style={{ transform: transferStyle.matrixInvert }}
-                  ref={scaleLeftRef}
+                  id="scaleleft"
                 />
               )}
             </>
@@ -241,7 +226,7 @@ const transformBtnsStyle = css`
   @apply space-x-10px whitespace-nowrap;
   position: absolute;
   bottom: 0px;
-  left:calc(50% - 18px);
+  left:calc(50% - 32px);
   font-size: 16px;
   z-index: 999;
   pointer-events: auto;
@@ -250,13 +235,13 @@ const transformBtnsStyle = css`
 
 const transBtnStyle = css`
   display: inline-block;
-  width: 36px;
-  height: 36px;
+  width: 28px;
+  height: 28px;
   border-radius: 50%;
   background-color: #fff;
   text-align: center;
-  line-height: 36px;
-  font-size: 20px;
+  line-height: 28px;
+  font-size: 16px;
   color: #333;
   position: relative;
   top: 50px;

+ 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",
+  // },
 ]);

+ 4 - 4
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);
@@ -36,9 +36,9 @@ export const View = defineComponent({
           ]}
           style={helper.createStyle(comp.layout)}
           onClick={(e) => {
-            e.stopPropagation();
-            if (store.isEditMode) {
-              actions.pickComp(props.compId);
+            if (!store.isEditMode) {
+              e.stopPropagation();
+              emit("click");
             }
           }}
           onDblclick={() => emit("dblclick")}

+ 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: {

+ 2 - 0
src/modules/editor/components/CompUI/basicUI/hooks.ts

@@ -19,6 +19,8 @@ export function useCompRef(compId: string) {
           configurable: true,
         },
       });
+      compRef.value.compId= compId;
+      compRef.value.compKey= comp.compKey;
     }
   });
   return compRef;

+ 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>

+ 38 - 26
src/modules/editor/components/CompUI/defines/createAttrsForm.tsx

@@ -2,11 +2,12 @@ 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, Input } 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";
 
 export const layoutColumns: ColumnItem[] = [
@@ -41,11 +42,11 @@ export 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,29 +57,40 @@ export 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,
     },
   },
 ];

+ 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;
+    }
+  }
+`;

+ 6 - 6
src/modules/editor/components/Viewport/Header/ShareBox.tsx

@@ -8,12 +8,12 @@ export const ShareBox = defineComponent({
   setup() {
     const { store } = useEditor();
     let shareLink = location.origin + "/share.html?id=" + store.designData._id;
-    if (location.host == "www.infish.cn") {
-      shareLink =
-        location.origin +
-        "/projects/queenshowv1/share.html?id=" +
-        store.designData._id;
-    }
+    // if (location.host == "www.infish.cn") {
+    //   shareLink =
+    //     location.origin +
+    //     "/projects/queenshowv1/share.html?id=" +
+    //     store.designData._id;
+    // }
 
     const qrUrl = useQRCode(shareLink);
 

+ 93 - 39
src/modules/editor/controllers/SelectCtrl/index.ts

@@ -7,6 +7,7 @@ import Event from "./event";
 import { Matrix } from "./matrix";
 import { Project, VectorLenth } from "./objects/mathUtils";
 import { Point } from "./objects/point";
+import { indexOf } from "lodash";
 
 /**
  *  页面画布空间进行选择
@@ -31,6 +32,7 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
   transferStyle = reactive({
     baseCardTop: "0px",
     showGizmo: false,
+    editingText: false,
     width: 0,
     height: 0,
     relWidth: 0,
@@ -116,9 +118,17 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
     }
   }
 
+  _downClickedCompId = "";
   onDocMouseDown(e: MouseEvent) {
     this._mouseDownTimestamp = Date.now();
 
+    const compKey = this.getDivFlag(e.target as any, "compKey");
+    console.log("compKey === >", compKey);
+    if (compKey == "Text" && !this.transferStyle.editingText) {
+       e.preventDefault();
+       e.stopPropagation();
+    }
+
     if (!this.pageEl || !this.selCanvas) return;
     if (this.store.textEditingState) return;
 
@@ -147,10 +157,10 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
     this._downClientX = e.clientX;
     this._downClientY = e.clientY;
 
-    // console.log(cardX, selX, cardY, sely);
+    this._downClickedCompId = this.compClickTest2(e);
 
     this._downed = true;
-    this._mouseDownFlag = this.getDivFlag(e.target as any);
+    this._mouseDownFlag = this.getDivTransformFlag(e.target as any);
     if (!this._mouseDownFlag) {
       //选框点击判断
       let isClickSelRect = false;
@@ -164,19 +174,9 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
           this._state = MODE_MOVING;
         }
       }
-      if (!isClickSelRect) {
-        //判断是否有点击到card stream
-        const comps = this.compClickTest(e);
-        console.log("comps=>", comps);
-        if (comps.length < 1) {
-          const test = this.streamCardClickTest(e);
-          if (test) {
-            const childs = this.compMap[test.id].children.default || [];
-            if (childs.length < 1) {
-              return;
-            }
-          }
-
+      if (!isClickSelRect) { //点击在选框之外
+        
+        if (!this._downClickedCompId) {//没有点击到组件
           const view = this.viewport?.getBoundingClientRect() as any;
           const isOut =
             e.clientX < view.left ||
@@ -187,7 +187,7 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
             this._state = MODE_SEL_RECT;
           }
         }
-        //else {
+        //else {//点击到选框之外的组件, 把时间放到mouseup 时相应.
         //   this._state = MODE_MOVING;
         //   const obj = this.compMap[comps[0].id];
         //   this.selecteObjs([new CompObject(obj)]);
@@ -195,7 +195,7 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
       }
     } else if (this._mouseDownFlag == "rotate") {
       this._state = MODE_ROTATE;
-    } else if (this._mouseDownFlag == "move") {
+    } else if (this._mouseDownFlag.indexOf("move") > -1) {
       this._state = MODE_MOVING;
     } else if (this._mouseDownFlag.indexOf("scale") > -1) {
       this._state = MODE_SCALE;
@@ -203,20 +203,33 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
 
     this._movePreClientX = this._downClientX;
     this._movePreClientY = this._downClientY;
+    this._initMovePos.x = -1;
+    this._initMovePos.y = -1;
 
-    if (this._state == MODE_MOVING) {
-      const obj = this.objContainer as ObjsContainer;
-      this._initMovePos = { x: obj.parent.x, y: obj.parent.y };
-    }
   }
-  _initMovePos = { x: 0, y: 0 };
+  _initMovePos = { x: -1, y: -1 };
+
+  getDivFlag(div: HTMLElement, flag="editable") {
+    let c: any = div;
+    if (!c) return ""
+    let i = 0;
+    do {
+      if (c[flag]) return c[flag];
+      c = c.parentElement;
+      i += 1;
+      if (i > 16) {
+        return ""
+      }
+    } while (c);
+    return "";
+  }
 
-  getDivFlag(div: HTMLElement) {
+  getDivId(div: HTMLElement) {
     let c: any = div;
     if (!c) return;
     let i = 0;
     do {
-      if (c.editable) return c.editable;
+      if (c.id) return c.id;
       c = c.parentElement;
       i += 1;
       if (i > 5) {
@@ -224,6 +237,20 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
       }
     } while (c);
   }
+  
+  getDivTransformFlag(div: HTMLElement) {
+     const id = this.getDivId(div);
+     if (!id) return "";
+     if ( id.indexOf("rotate")>-1 || id.indexOf("move") > -1 || id.indexOf("scale") > -1 || id.indexOf("toolbar") > -1) return id;
+     return "";
+  }
+
+  compClickTest2(e: MouseEvent) {
+    const compId = this.getDivFlag(e.target as any, "compId");
+    console.log("down click=>", compId);
+
+    return compId;
+  }
 
   compClickTest(e: MouseEvent) {
     const cards = this.store.streamCardIds;
@@ -300,6 +327,10 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
   movingMousemove(e: MouseEvent) {
     const objContainer = this.objContainer as ObjsContainer;
 
+    if (this._initMovePos.x == -1 && this._initMovePos.y == -1) {
+        const obj = this.objContainer as ObjsContainer;
+        this._initMovePos = { x: obj.parent.x, y: obj.parent.y };
+    }
     objContainer.setPivot(0);
     objContainer.translate(
       e.clientX - this._movePreClientX,
@@ -346,6 +377,13 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
   }
 
   onDocMouseUp(e: MouseEvent) {
+    let isClick = false;
+    let offsetT = Date.now() - this._mouseDownTimestamp;
+    const dx = Math.abs(e.clientX - this._downClientX);
+    const dy = Math.abs(e.clientY - this._downClientY);
+    if (dx < 2 && dy < 2 && offsetT < 200) {
+      isClick = true;
+    }
     document.removeEventListener("mousemove", this.onDocMouseMove, {
       capture: true,
     });
@@ -354,23 +392,26 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
       return;
     }
 
-    let isClick = false;
-    let offsetT = Date.now() - this._mouseDownTimestamp;
-    const dx = Math.abs(e.clientX - this._downClientX);
-    const dy = Math.abs(e.clientY - this._downClientY);
-    if (dx < 2 && dy < 2 && !this.store.textEditingState && offsetT < 200) {
-      isClick = true;
+    if (isClick) {
+      this.actions.pickComp(this._downClickedCompId);
     }
+
     if (isClick) {
       this._state = MODE_NONE;
-      const comps = this.compClickTest(e);
-      if (comps.length < 1) {
-        setTimeout(() => {
-            this.actions.selectObjs([]) //清空选择
-        }, 0);
+
+      if (this._downClickedCompId) {
+        const compKey = this.getDivFlag(e.target as any, "compKey");
+        console.log("up compKey === >", compKey);
+        if (compKey == "Text" ) { //点击鼠标上来后 focus文本选中
+             const compId = this.getDivFlag(e.target as any, "compId");
+             if ( this.selected.length ==  1 && this.store.currComp.id == compId ) {
+                //取消当前选择
+                this.selecteObjs([])
+                this.actions.textFocus(compId);
+                this.transferStyle.editingText = true;
+             }
+        }
       }
-    } else {
-      e.stopPropagation();
     }
 
     if (this._state == MODE_SEL_RECT && !isClick) {
@@ -390,7 +431,7 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
     } else if (this._state == MODE_SCALE) {
       this.scaleMouseUp(e);
     } else if (this._state == MODE_MOVING) {
-      this.moveMouseUp(e);
+      this.moveMouseUp(e, isClick);
     }
 
     this._state = MODE_NONE;
@@ -405,7 +446,7 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
     this.upgateGizmoStyle();
     this.helper.extendStreamCard(this.store.currStreamCardId);
   }
-  moveMouseUp(e: MouseEvent) {
+  moveMouseUp(e: MouseEvent, clicked:boolean) {
     const history = this.controls.historyCtrl.history;
 
     const obj = this.objContainer as ObjsContainer;
@@ -415,6 +456,16 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
     const initX = this._initMovePos.x,
       initY = this._initMovePos.y;
 
+      this._initMovePos.x = -1;
+      this._initMovePos.y = -1;
+
+      if ( !clicked && this.store.selected.length == 1 && this.store.currComp.compKey == "Text") {
+          this.actions.textFocus(this.store.currCompId, false)
+      }
+
+      if (initX == -1 && initY == -1) return;
+
+
       obj.setPivot(0);
 
     history.record({
@@ -458,6 +509,9 @@ export class SelectCtrl extends ModuleControl<EditorModule> {
       }
     }
     this.actions.selectObjs(outs);
+    if (outs.length < 1) {
+      this.actions.pickComp(this.store.currStreamCardId);
+    }
   }
   
   upgateGizmoStyle() {

+ 1 - 1
src/modules/editor/controllers/SelectCtrl/objects/displayObject.ts

@@ -8,7 +8,7 @@ export class DisplayObject {
 
   tempDisplayObjectParent?:DisplayObject;
 
-  transform = new Transform();
+transform = new Transform();
 
   visible = true;
 

+ 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;

+ 19 - 5
src/modules/editor/module/actions/edit.ts

@@ -9,6 +9,9 @@ import { ICompKeys, Layout } from "../../typings";
 export const editActions = EditorModule.action({
 
   pickComp(compId: string) {
+    if (compId == "") {//空的时候,就选择根页面
+      compId = "root";
+    }
     const selectCardChild = (id:string)=>{
       const paths = this.helper.getCompTrees(id)
         const cardChilds = paths[2];
@@ -16,14 +19,14 @@ export const editActions = EditorModule.action({
             this.actions.selectObjs([cardChilds.id])
         } else  {
           this.actions.selectObjs([])
+          if (id != "root") {
+             this.store.setCurrComp(this.store.currStreamCardId);
+          }
         }
     }
+
     if (this.store.currCompId == compId) {
-      // if (this.controls.selectCtrl.selected.length < 1 ) {
-      //   selectCardChild(compId);
-      // }else {
-      //     this.controls.selectCtrl.upgateGizmoStyle();
-      //   }
+      //this.controls.selectCtrl.upgateGizmoStyle();
       return;
     }
 
@@ -175,6 +178,17 @@ export const editActions = EditorModule.action({
     const parentComp = this.helper.findParentComp(compId);
     parentComp && this.store.setCurrComp(parentComp.id);
   },
+
+  // 删除组件
+  removeSelectComps() {
+    const selected = this.store.selected.slice(0);
+    this.actions.selectObjs([]);
+    let n = selected.length;
+    while( n--) {
+      this.actions.removeComp(selected[n]);
+    }
+  },
+
   // 删除组件
   removeComp(compId: string) {
     if (this.helper.isCompCanDelete(compId)) {

+ 16 - 0
src/modules/editor/module/actions/editWithManualHistory.ts

@@ -22,7 +22,23 @@ export const manualActions = EditorModule.action({
     historyCtrl.historyActionDoing = false;
   },
 
+  updateCompDatas(comp: DesignComp, paths: string[], values: any[]) {
+    const { historyCtrl } = this.controls;
+    historyCtrl.historyActionDoing = true;
+    historyCtrl.historyCombine = true;
+    let n = paths.length;
+    while(n--) {
+      set(comp, paths[n], values[n]);
+    }
+    // call action method
+    historyCtrl.historyCombine = false;
+    historyCtrl.historyActionDoing = false;
+  },
+
   submitUpdate() {
     this.controls.historyCtrl.history.submit();
   },
+  textFocus(compId:string, focus=true) {
+    console.log("text focus", compId,  focus);
+  },
 });

+ 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;

+ 3 - 3
src/modules/editor/module/index.ts

@@ -58,9 +58,9 @@ export class EditorModule extends ModuleRoot {
     const _params = new URLSearchParams(decodeURIComponent(location.search));
     const host = _params.get("host");
     let link = `${location.origin}/index.html?host=${host}${route}`;
-    if (location.host == "www.infish.cn") {
-      link = `${location.origin}/projects/queenshowv1/index.html?host=${host}${route}`;
-    }
+    // if (location.host == "www.infish.cn") {
+    //   link = `${location.origin}/projects/queenshowv1/index.html?host=${host}${route}`;
+    // }
     location.href = link;
   }
 }

+ 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) {

+ 5 - 2
src/modules/editor/objects/Toolbars/CompToolbars.ts

@@ -1,4 +1,4 @@
-import { ICompToolbars, toolbars } from "./default";
+import { ICompToolbars, toolbars, multiSelToolbar } from "./default";
 
 export const CompToolbars: ICompToolbars = {
   default: [
@@ -13,5 +13,8 @@ export const CompToolbars: ICompToolbars = {
   ],
   Group: [
     toolbars.cancelGroup,
-  ]
+  ],
+  MultiSelector: [
+    multiSelToolbar.delete,
+  ],
 };

+ 2 - 1
src/modules/editor/objects/Toolbars/TreeToolbars.ts

@@ -1,4 +1,4 @@
-import { ICompToolbars, toolbars } from "./default";
+import { ICompToolbars, toolbars, multiSelToolbar } from "./default";
 
 export const TreeToolbars: ICompToolbars = {
   default: [
@@ -10,4 +10,5 @@ export const TreeToolbars: ICompToolbars = {
     toolbars.delete,
   ],
   Page: [],
+  MultiSelector: [multiSelToolbar.delete]
 };

+ 44 - 0
src/modules/editor/objects/Toolbars/default.ts

@@ -33,6 +33,7 @@ class ToolbarItem {
 
 export type ICompToolbars = { [name in ICompKeys]?: ToolbarItem[] } & {
   default: ToolbarItem[];
+  MultiSelector: ToolbarItem[];
 };
 
 function createToolbars<T extends Record<string, ItemParams>>(obj: T) {
@@ -43,6 +44,49 @@ function createToolbars<T extends Record<string, ItemParams>>(obj: T) {
   return data as { [name in keyof T]: ToolbarItem };
 }
 
+export const multiSelToolbar = createToolbars({
+    // 删除
+  delete: {
+    component: TipIcons.Delete,
+    getVisible() {
+      return true;
+    },
+    onClick() {
+      this.actions.removeSelectComps();
+    },
+  },
+  // // 清除变换
+  // clearTransform: {
+  //   component: TipIcons.ClearTransform,
+  //   getVisible() {
+  //     return true;
+  //   },
+  //   onClick() {
+  //     //this.actions.clearCompTransform(comp);
+  //   },
+  // },
+  // // 定位图层上移
+  // layerUp: {
+  //   component: TipIcons.LayerUp,
+  //   getVisible() {
+  //     return true;
+  //   },
+  //   onClick() {
+  //     // this.actions.setCompLayer(comp, 1);
+  //   },
+  // },
+  // // 定位图层下移
+  // layerDown: {
+  //   component: TipIcons.LayerDown,
+  //   getVisible() {
+  //     return true;
+  //   },
+  //   onClick() {
+  //     // this.actions.setCompLayer(comp, -1);
+  //   },
+  // },
+})
+
 export const toolbars = createToolbars({
   // 显示/隐藏
   visible: {

+ 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,
+  }),
+});

+ 5 - 5
src/modules/resource/actions/material.ts

@@ -39,11 +39,11 @@ export const materialActions = ResourceModule.action({
     const _params = new URLSearchParams(decodeURIComponent(location.search));
     const host = _params.get("host");
 
-    if (location.host == "www.infish.cn") {
-      const url = `${location.origin}/projects/queenshowv1/index.html?host=${host}#/create/${record._id}`;
-      location.href = url;
-      return;
-    }
+    // if (location.host == "www.infish.cn") {
+    //   const url = `${location.origin}/projects/queenshowv1/index.html?host=${host}#/create/${record._id}`;
+    //   location.href = url;
+    //   return;
+    // }
 
     const url = `${location.origin}/index.html?host=${host}#/create/${record._id}`;
     location.href = url;

+ 12 - 12
src/modules/resource/actions/promotion.tsx

@@ -28,12 +28,12 @@ export const promotionAction = ResourceModule.action({
     });
     if (!title) return;
     const res = await this.https.createPromotion({ title });
-    console.log(location.host, location.host == "www.infish.cn");
-    if (location.host == "www.infish.cn") {
-      const url = `${location.origin}/projects/queenshowv1/editor.html#/?id=${res.result}`;
-      location.href = url;
-      return;
-    }
+    //console.log(location.host, location.host == "www.infish.cn");
+    // if (location.host == "www.infish.cn") {
+    //   const url = `${location.origin}/projects/queenshowv1/editor.html#/?id=${res.result}`;
+    //   location.href = url;
+    //   return;
+    // }
 
     const url = `${location.origin}/editor.html#/?id=${res.result}`;
     location.href = url;
@@ -45,12 +45,12 @@ export const promotionAction = ResourceModule.action({
     });
     if (!title) return;
     const res = await this.https.createComp({ title });
-    console.log(location.host, location.host == "www.infish.cn");
-    if (location.host == "www.infish.cn") {
-      const url = `${location.origin}/projects/queenshowv1/editor.html#/?id=${res.result}&mode=editComp`;
-      location.href = url;
-      return;
-    }
+    // console.log(location.host, location.host == "www.infish.cn");
+    // if (location.host == "www.infish.cn") {
+    //   const url = `${location.origin}/projects/queenshowv1/editor.html#/?id=${res.result}&mode=editComp`;
+    //   location.href = url;
+    //   return;
+    // }
 
     const url = `${location.origin}/editor.html#/?id=${res.result}&mode=editComp`;
     location.href = url;

+ 5 - 5
src/modules/resource/components/PromotionItem.tsx

@@ -16,11 +16,11 @@ export default defineComponent({
     const resource = useResource();
 
     const goEdit = () => {
-      if (location.host == "www.infish.cn") {
-        const url = `${location.origin}/projects/queenshow/editor.html#/?id=${props.record._id}`;
-        location.href = url;
-        return;
-      }
+      // if (location.host == "www.infish.cn") {
+      //   const url = `${location.origin}/projects/queenshowv1/editor.html#/?id=${props.record._id}`;
+      //   location.href = url;
+      //   return;
+      // }
       const url = `${location.origin}/editor.html#/?id=${props.record._id}`;
       location.href = url;
     };

+ 6 - 4
src/modules/resource/components/ResourceManager/Toolbar.tsx

@@ -3,6 +3,7 @@ import { defineComponent } from "vue";
 import { useResource } from "../..";
 import MaterialTemplateModal from "./MaterialTemplateModal";
 import { css, cx } from "@linaria/core";
+import { queenApi } from "queenjs";
 
 const materialType = [
   { name: "视频", key: "video" },
@@ -17,10 +18,11 @@ export default defineComponent({
     const { store } = resource;
 
     const showModal = (type: string) => {
-      resource.showModal(<MaterialTemplateModal type={type} />, {
-        title: `${type === "image" ? "图片" : "视频"}模板中心`,
-        width: "1000px",
-      });
+      // resource.showModal(<MaterialTemplateModal type={type} />, {
+      //   title: `${type === "image" ? "图片" : "视频"}模板中心`,
+      //   width: "1000px",
+      // });
+       queenApi.messageSuccess("努力开发中,尽请期待!")
     };
 
     return () => {

+ 5 - 5
src/modules/resource/controllers/ComponentController.ts

@@ -12,11 +12,11 @@ export class ComponentController {
     const _params = new URLSearchParams(decodeURIComponent(location.search));
     const host = _params.get("host");
 
-    if (location.host == "www.infish.cn") {
-      const url = `${location.origin}/projects/queenshowv1/editor.html?host=${host}#/?id=${item._id}&mode=editComp`;
-      location.href = url;
-      return;
-    }
+    // if (location.host == "www.infish.cn") {
+    //   const url = `${location.origin}/projects/queenshowv1/editor.html?host=${host}#/?id=${item._id}&mode=editComp`;
+    //   location.href = url;
+    //   return;
+    // }
 
     const url = `${location.origin}/editor.html?host=${host}#/?id=${item._id}&mode=editComp`;
     location.href = url;

+ 10 - 10
src/modules/resource/controllers/PromotionController.ts

@@ -12,21 +12,21 @@ export class PromotionController {
     const _params = new URLSearchParams(decodeURIComponent(location.search));
     const host = _params.get("host");
 
-    if (location.host == "www.infish.cn") {
-      const url = `${location.origin}/projects/queenshowv1/editor.html?host=${host}#/?id=${item._id}`;
-      location.href = url;
-      return;
-    }
+    // if (location.host == "www.infish.cn") {
+    //   const url = `${location.origin}/projects/queenshowv1/editor.html?host=${host}#/?id=${item._id}`;
+    //   location.href = url;
+    //   return;
+    // }
 
     const url = `${location.origin}/editor.html?host=${host}#/?id=${item._id}`;
     location.href = url;
   }
   onPreview(item: any) {
-    if (location.host == "www.infish.cn") {
-      const url = `${location.origin}/projects/queenshowv1/share.html#/?id=${item._id}`;
-      location.href = url;
-      return;
-    }
+    // if (location.host == "www.infish.cn") {
+    //   const url = `${location.origin}/projects/queenshowv1/share.html#/?id=${item._id}`;
+    //   location.href = url;
+    //   return;
+    // }
     const url = `${location.origin}/share.html#/?id=${item._id}`;
     location.href = url;
   }

+ 3 - 1
src/pages/website/Material2/controller.tsx

@@ -1,6 +1,7 @@
 import SelectListItemModal from "./components/SelectListItemModal";
 import { MaterialController } from "../../../modules/resource/controllers/MaterialController";
 import PreviewModal from "../components/PreviewModal";
+import { queenApi } from "queenjs";
 
 export default function createController(resource:any, isSelectModel:boolean, selectType :string) {
     const {controls, actions} = resource;
@@ -53,7 +54,8 @@ export default function createController(resource:any, isSelectModel:boolean, se
         ctrl.getCurrControl().loadPage(1);
         return;
       }
-      showModal(name);
+      queenApi.messageSuccess("功能开发中, 敬请期待!")
+      //showModal(name);
     };
     ctrl.onItemClick = async function (name, record) {
       if (name == "delete") {

+ 6 - 7
src/pages/website/Promotion2/components/ShareModal.tsx

@@ -14,13 +14,12 @@ export default defineComponent({
   },
   setup(props, { slots }) {
     let shareLink = location.origin + "/share.html?id=" + props.record._id;
-
-    if (location.host == "www.infish.cn") {
-      shareLink =
-        location.origin +
-        "/projects/queenshowv1/share.html?id=" +
-        props.record._id;
-    }
+    // if (location.host == "www.infish.cn") {
+    //   shareLink =
+    //     location.origin +
+    //     "/projects/queenshowv1/share.html?id=" +
+    //     props.record._id;
+    // }
 
     const qrUrl = useQRCode(shareLink, { margin: 2 });
 

+ 112 - 0
src/pages/website/Settings/ResetForm.tsx

@@ -0,0 +1,112 @@
+import { useAuth } from "@queenjs-modules/auth";
+import { CaptchaInput } from "@queenjs-modules/auth/components/components/captcha";
+import { Button, Form, Input } from "ant-design-vue";
+import { queenApi } from "queenjs";
+import { defineComponent, reactive } from "vue";
+
+const layout = {
+  wrapperCol: { span: 24 },
+};
+const tailLayout = {
+  wrapperCol: { span: 24 },
+};
+
+export default defineComponent({
+  emits: ["success"],
+  setup(props, { emit }) {
+    const auth = useAuth();
+
+    const state = reactive({
+      loading: false,
+    });
+
+    const formState = reactive({
+      phone: "",
+      code: "",
+      password: "",
+      rePwd: "",
+    });
+
+    const rules = reactive({
+      phone: [{ required: true, message: "手机号不能为空", trigger: "change" }],
+      code: [{ required: true, message: "验证码不能为空", trigger: "change" }],
+      password: [
+        { required: true, message: "密码不能为空", trigger: "change" },
+      ],
+      rePwd: [{ required: true, message: "请确认密码", trigger: "change" }],
+    });
+
+    const { validate, validateInfos } = Form.useForm(formState, rules);
+
+    const submit = async () => {
+      try {
+        state.loading = true;
+        const { rePwd, ...formData } = await validate();
+        if (rePwd !== formData.password) {
+          queenApi.messageError("输入密码不一致!");
+          return;
+        }
+        await auth.actions.resetPassword(formData);
+        emit("success");
+      } finally {
+        state.loading = false;
+      }
+    };
+
+    function getCodeByClick() {
+      return auth.actions.getSmsCode({
+        phone: formState.phone,
+        use: "resetPasswd",
+      });
+    }
+
+    return () => (
+      <Form {...layout} name="basic">
+        <Form.Item name="phone" {...validateInfos.phone}>
+          <Input
+            placeholder="请输入手机号码"
+            v-model={[formState.phone, "value"]}
+            maxlength={30}
+          />
+        </Form.Item>
+        <Form.Item name="code" {...validateInfos.code}>
+          <CaptchaInput
+            disabled={!/^1[3456789]\d{9}$/.test(formState.phone)}
+            value={formState.code}
+            onChange={(v) => (formState.code = v)}
+            onGetCode={getCodeByClick}
+          />
+        </Form.Item>
+        <Form.Item name="password" {...validateInfos.password}>
+          <Input
+            type="password"
+            placeholder="请设置密码"
+            v-model={[formState.password, "value"]}
+            maxlength={12}
+          />
+        </Form.Item>
+        <Form.Item name="rePwd" {...validateInfos.rePwd}>
+          <Input
+            type="password"
+            placeholder="再次确认密码"
+            v-model={[formState.rePwd, "value"]}
+            maxlength={12}
+          />
+        </Form.Item>
+        <Form.Item {...tailLayout}>
+          <Button
+            htmlType="submit"
+            block
+            type="primary"
+            size="large"
+            shape="round"
+            loading={state.loading}
+            onClick={submit}
+          >
+            修改密码
+          </Button>
+        </Form.Item>
+      </Form>
+    );
+  },
+});

+ 22 - 0
src/pages/website/Settings/ResetPassModal.tsx

@@ -0,0 +1,22 @@
+import { useModal } from "queenjs";
+import { defineComponent } from "vue";
+import ResetForm from "./ResetForm";
+import { useAuth } from "@queenjs-modules/auth";
+
+export default defineComponent({
+  setup() {
+    const modal = useModal();
+    const auth = useAuth();
+
+    return () => {
+      return (
+        <ResetForm
+          onSuccess={() => {
+            modal.cancel();
+            auth.actions.logout();
+          }}
+        />
+      );
+    };
+  },
+});

+ 46 - 2
src/pages/website/Settings/index.tsx

@@ -1,5 +1,49 @@
+import { IconLock } from "@queenjs/icons";
+import { Button, Tabs } from "ant-design-vue";
+import { queenApi } from "queenjs";
 import { defineComponent } from "vue";
+import ResetPassModal from "./ResetPassModal";
 
-export default defineComponent(() => {
-  return () => <div>Settings</div>;
+const options = ["账户与安全"];
+
+export default defineComponent({
+  setup() {
+    // const modal = useModal();
+
+    const showModal = () => {
+      queenApi.dialog(<ResetPassModal />, {
+        width: "400px",
+        title: "修改密码",
+      });
+    };
+
+    return () => (
+      <div>
+        <h3 class="text-22px">个人资料</h3>
+        <Tabs>
+          {options.map((d, i) => (
+            <Tabs.TabPane key={i} tab={d} />
+          ))}
+        </Tabs>
+        <div>
+          <div class="flex items-center justify-between">
+            <div class="flex items-center">
+              <div class="flex items-center justify-center w-48px h-48px rounded-4px bg-light-50">
+                <IconLock class="text-24px !text-orange" />
+              </div>
+              <div class="ml-10px">
+                <div class="text-14px text-light-50">登录密码</div>
+                <div class="mt-10px text-12px opacity-80">
+                  建议使用6-16个字符,可包括大小写字母和数字
+                </div>
+              </div>
+            </div>
+            <Button type="link" onClick={showModal}>
+              修改密码
+            </Button>
+          </div>
+        </div>
+      </div>
+    );
+  },
 });

+ 9 - 8
src/pages/website/components/layout/LeftContent.tsx

@@ -3,7 +3,8 @@ import {
   IconCamera,
   IconCube,
   IconDashboard,
-  IconDownload
+  IconDownload,
+  IconSettings,
 } from "@queenjs/icons";
 import { Avatar, Divider } from "ant-design-vue";
 import { defineUI } from "queenjs";
@@ -44,11 +45,11 @@ export default defineUI({
         icon: IconCamera,
         // suffix: "32",
       },
-      // {
-      //   link: "/settings",
-      //   label: "设置",
-      //   icon: IconSettings,
-      // },
+      {
+        link: "/settings",
+        label: "个人资料",
+        icon: IconSettings,
+      },
     ];
     return () => {
       const { userInfo } = props.Controller.state;
@@ -62,8 +63,8 @@ export default defineUI({
             <Avatar size={76} src={userInfo.avatar} />
             <div class="ml-20px flex-1">
               <p class="mb-10px text-16px font-bold">{userInfo.name}</p>
-              <div class="text-12px text-gray">
-                {userInfo.desc || "这个人很懒,什么都没留下..."}
+              <div class="text-12px text-gray" style={{color:"#E88B00"}}>
+                { "免费版(限3个推广)" }
               </div>
             </div>
           </div>