qinyan 1 year ago
parent
commit
b74f4115f8

+ 1 - 3
.eslintrc.js

@@ -1,7 +1,4 @@
 module.exports = {
-  globals: {
-    wx: true,
-  },
   root: true,
   env: {
     node: true,
@@ -23,6 +20,7 @@ module.exports = {
     "prettier/prettier": "off",
     "@typescript-eslint/no-var-requires": "off",
     "@typescript-eslint/no-namespace": "off",
+    "@typescript-eslint/no-this-alias": "off"
   },
   overrides: [
     {

+ 10 - 0
src/assets/icons/components/IconWechat.tsx

@@ -0,0 +1,10 @@
+
+import { createIcon } from '@queenjs/icons';
+export const IconWechat = createIcon(<svg viewBox="0 0 1024 1024">
+    <path
+        d="M690.1 377.4c5.9 0 11.8 0.2 17.6 0.5-24.4-128.7-158.3-227.1-319.9-227.1C209 150.8 64 271.4 64 420.2c0 81.1 43.6 154.2 111.9 203.6 5.5 3.9 9.1 10.3 9.1 17.6 0 2.4-0.5 4.6-1.1 6.9-5.5 20.3-14.2 52.8-14.6 54.3-0.7 2.6-1.7 5.2-1.7 7.9 0 5.9 4.8 10.8 10.8 10.8 2.3 0 4.2-0.9 6.2-2l70.9-40.9c5.3-3.1 11-5 17.2-5 3.2 0 6.4 0.5 9.5 1.4 33.1 9.5 68.8 14.8 105.7 14.8 6 0 11.9-0.1 17.8-0.4-7.1-21-10.9-43.1-10.9-66 0-135.8 132.2-245.8 295.3-245.8z m-194.3-86.5c23.8 0 43.2 19.3 43.2 43.1s-19.3 43.1-43.2 43.1c-23.8 0-43.2-19.3-43.2-43.1s19.4-43.1 43.2-43.1z m-215.9 86.2c-23.8 0-43.2-19.3-43.2-43.1s19.3-43.1 43.2-43.1 43.2 19.3 43.2 43.1-19.4 43.1-43.2 43.1z"
+        fill="currentColor"></path>
+    <path
+        d="M866.7 792.7c56.9-41.2 93.2-102 93.2-169.7 0-124-120.8-224.5-269.9-224.5-149 0-269.9 100.5-269.9 224.5S540.9 847.5 690 847.5c30.8 0 60.6-4.4 88.1-12.3 2.6-0.8 5.2-1.2 7.9-1.2 5.2 0 9.9 1.6 14.3 4.1l59.1 34c1.7 1 3.3 1.7 5.2 1.7 2.4 0 4.7-0.9 6.4-2.6 1.7-1.7 2.6-4 2.6-6.4 0-2.2-0.9-4.4-1.4-6.6-0.3-1.2-7.6-28.3-12.2-45.3-0.5-1.9-0.9-3.8-0.9-5.7 0.1-5.9 3.1-11.2 7.6-14.5zM600.2 587.2c-19.9 0-36-16.1-36-35.9 0-19.8 16.1-35.9 36-35.9s36 16.1 36 35.9c0 19.8-16.2 35.9-36 35.9z m179.9 0c-19.9 0-36-16.1-36-35.9 0-19.8 16.1-35.9 36-35.9s36 16.1 36 35.9c-0.1 19.8-16.2 35.9-36 35.9z"
+        fill="currentColor"></path>
+</svg>)

+ 1 - 0
src/assets/icons/index.ts

@@ -10,3 +10,4 @@ export * from "./components/IconLayerDown";
 export * from "./components/IconLayerUp";
 export * from "./components/IconMove";
 export * from "./components/IconRotate";
+export * from "./components/IconWechat";

+ 8 - 0
src/assets/icons/svg/wechat.svg

@@ -0,0 +1,8 @@
+<svg viewBox="0 0 1024 1024">
+    <path
+        d="M690.1 377.4c5.9 0 11.8 0.2 17.6 0.5-24.4-128.7-158.3-227.1-319.9-227.1C209 150.8 64 271.4 64 420.2c0 81.1 43.6 154.2 111.9 203.6 5.5 3.9 9.1 10.3 9.1 17.6 0 2.4-0.5 4.6-1.1 6.9-5.5 20.3-14.2 52.8-14.6 54.3-0.7 2.6-1.7 5.2-1.7 7.9 0 5.9 4.8 10.8 10.8 10.8 2.3 0 4.2-0.9 6.2-2l70.9-40.9c5.3-3.1 11-5 17.2-5 3.2 0 6.4 0.5 9.5 1.4 33.1 9.5 68.8 14.8 105.7 14.8 6 0 11.9-0.1 17.8-0.4-7.1-21-10.9-43.1-10.9-66 0-135.8 132.2-245.8 295.3-245.8z m-194.3-86.5c23.8 0 43.2 19.3 43.2 43.1s-19.3 43.1-43.2 43.1c-23.8 0-43.2-19.3-43.2-43.1s19.4-43.1 43.2-43.1z m-215.9 86.2c-23.8 0-43.2-19.3-43.2-43.1s19.3-43.1 43.2-43.1 43.2 19.3 43.2 43.1-19.4 43.1-43.2 43.1z"
+        fill="currentColor"></path>
+    <path
+        d="M866.7 792.7c56.9-41.2 93.2-102 93.2-169.7 0-124-120.8-224.5-269.9-224.5-149 0-269.9 100.5-269.9 224.5S540.9 847.5 690 847.5c30.8 0 60.6-4.4 88.1-12.3 2.6-0.8 5.2-1.2 7.9-1.2 5.2 0 9.9 1.6 14.3 4.1l59.1 34c1.7 1 3.3 1.7 5.2 1.7 2.4 0 4.7-0.9 6.4-2.6 1.7-1.7 2.6-4 2.6-6.4 0-2.2-0.9-4.4-1.4-6.6-0.3-1.2-7.6-28.3-12.2-45.3-0.5-1.9-0.9-3.8-0.9-5.7 0.1-5.9 3.1-11.2 7.6-14.5zM600.2 587.2c-19.9 0-36-16.1-36-35.9 0-19.8 16.1-35.9 36-35.9s36 16.1 36 35.9c0 19.8-16.2 35.9-36 35.9z m179.9 0c-19.9 0-36-16.1-36-35.9 0-19.8 16.1-35.9 36-35.9s36 16.1 36 35.9c-0.1 19.8-16.2 35.9-36 35.9z"
+        fill="currentColor"></path>
+</svg>

+ 79 - 55
src/pages/share/sdk.ts → src/controllers/wxController.ts

@@ -1,75 +1,88 @@
-/* eslint-disable */
-// @ts-nocheck
-import { Dict_Apis } from "@/dict";
 import axios from "axios";
-var signSuccess = false; //是否已经签名成功
+
+declare const wx: any;
+
+const ua = navigator.userAgent.toLowerCase();
 
 function isWeixinBrowser() {
-  const ua = navigator.userAgent.toLowerCase();
   return /micromessenger/.test(ua) ? true : false;
 }
 
-const WxSdk = {
-  defaults: {
+function isIos() {
+  if (/(iphone|ipad|ipod|ios)/i.test(ua)) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+function isAndroid() {
+  if (/(android)/i.test(ua)) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+export class wxController {
+  signSuccess = false;
+  requestUrl = ""; //获取signature地址
+
+  configData = {
     debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
     appId: "", // 必填,公众号的唯一标识
     timestamp: 0, // 必填,生成签名的时间戳
     nonceStr: "", // 必填,生成签名的随机串
     signature: "", // 必填,签名
     jsApiList: ["updateAppMessageShareData", "updateTimelineShareData"], // 必填,需要使用的JS接口列表
-  },
+  };
+
   //默认分享设置
-  defaultShare: {
+  shareData = {
     title: "",
     link: location.href,
-    imgUrl:
-      "//infishwaibao.oss-cn-chengdu.aliyuncs.com/queenshow/img/Logo.8478c1b4.png",
+    imgUrl: "",
     desc: "",
-  },
+  };
 
-  setConfig: function (options: any) {
-    const { app_id, nonce_str, signature, timestamp } = options;
-    this.defaults = Object.assign(this.defaults, {
-      appId: app_id,
-      timestamp: timestamp,
-      nonceStr: nonce_str,
-      signature: signature,
-    });
-  },
+  init(url: string) {
+    if (isWeixinBrowser()) {
+      this.requestUrl = url;
+      const signUrl = window.location.href;
+      this.signSuccess = false;
+      this.sign(signUrl);
+    } else {
+      console.error("非微信浏览器");
+    }
+  }
 
-  sign: function (url: string) {
-    var that = this;
+  sign(url: string) {
+    const _this = this;
+
+    if (!url) url = window.location.href;
 
     //签名接口
-    axios(`${Dict_Apis.promotion}/wechat/share?`, {
+    axios(this.requestUrl, {
       method: "get",
       params: { url },
     })
       .then(function (response) {
         const data = response.data.result;
-        that.setConfig(data);
-        wx.config(that.defaults);
+        _this.setConfig(data);
+        wx.config(_this.configData);
         wx.ready(function () {
-          signSuccess = true;
-          that.setShare(that.defaultShare);
+          _this.signSuccess = true;
+          _this.setShare();
         });
-        wx.error(function (res) {
+        wx.error(function (res: any) {
+          _this.signSuccess = false;
           console.error("error: ", res);
         });
       })
       .catch(function (error) {
         console.error(error);
       });
-  },
-  init: function () {
-    if (isWeixinBrowser()) {
-      var signUrl = window.location.href;
-      signSuccess = false;
-      this.sign(signUrl);
-    } else {
-      console.error("非微信浏览器");
-    }
-  },
+  }
 
   setShareData(shareData: {
     title: string;
@@ -77,20 +90,30 @@ const WxSdk = {
     imgUrl: string;
     desc: string;
   }) {
-    shareData = Object.assign({}, this.defaultShare, shareData);
-    this.defaultShare = shareData;
-  },
-
-  setShare: function (options: {
-    link: any;
-    title: any;
-    desc: any;
-    imgUrl: any;
+    shareData = Object.assign({}, this.shareData, shareData);
+    this.shareData = shareData;
+    console.error("shareData **************: ", shareData);
+  }
+
+  setConfig(options: any) {
+    const { app_id, nonce_str, signature, timestamp } = options;
+    this.configData = Object.assign(this.configData, {
+      appId: app_id,
+      timestamp: timestamp,
+      nonceStr: nonce_str,
+      signature: signature,
+    });
+  }
+
+  setShare(options?: {
+    link: string;
+    title: string;
+    desc: string;
+    imgUrl: string;
   }) {
-    var that = this;
-    options = Object.assign({}, that.defaultShare, options);
+    options = Object.assign({}, this.shareData, options);
 
-    if (!signSuccess) return;
+    if (!this.signSuccess || !options.title) return;
 
     wx.updateAppMessageShareData({
       title: options.title, // 分享标题
@@ -112,8 +135,9 @@ const WxSdk = {
       success: function () {
         console.log("设置成功");
       },
+      fail: function (msg: any) {
+        console.error("设置失败:" + JSON.stringify(msg));
+      },
     });
-  },
-};
-
-export default WxSdk;
+  }
+}

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

@@ -55,7 +55,7 @@ export default defineComponent({
             <div>
               <div class="text-white text-bold">{record.title}</div>
               <div class="flex items-center text-opacity-60 text-white text-12px mt-5px">
-                {dayjs(record.updateTime).format("YYYY.MM.DD")} 发布{" "}
+                {dayjs(record.updateTime).format("YYYY.MM.DD")} 发布
                 <Divider type="vertical"></Divider>
                 23次浏览
               </div>

+ 8 - 1
src/modules/resource/controllers/PromotionController.ts

@@ -10,7 +10,7 @@ export class PromotionController {
   }
   onEdit(item: any) {
     const _params = new URLSearchParams(decodeURIComponent(location.search));
-    const host = _params.get("host")
+    const host = _params.get("host");
 
     if (location.host == "www.infish.cn") {
       const url = `${location.origin}/projects/queenshow/editor.html?host=${host}#/?id=${item._id}`;
@@ -30,4 +30,11 @@ export class PromotionController {
     const url = `${location.origin}/share.html#/?id=${item._id}`;
     location.href = url;
   }
+
+  changeThumbnail() {
+    //
+  }
+  updateDesign(record: any, data: any) {
+    console.log("record: ", record, data);
+  }
 }

+ 11 - 8
src/pages/share/Promotion/index.tsx

@@ -1,12 +1,17 @@
+import { wxController } from "@/controllers/wxController";
+import { Dict_Apis } from "@/dict";
 import { initEditor } from "@/modules/editor";
-import { defineComponent, onMounted } from "vue";
-import WxSdk from "../sdk";
+import { defineComponent } from "vue";
 
 export default defineComponent(() => {
   const editor = initEditor();
   const params = new URLSearchParams(location.href.split("?")[1]);
   const id = params.get("id");
 
+  const wxSdk = new wxController();
+  const url = `${Dict_Apis.promotion}/wechat/share?`;
+  wxSdk.init(url);
+
   editor.actions.switchMode("preview");
 
   if (id) {
@@ -15,18 +20,16 @@ export default defineComponent(() => {
     editor.actions.on("initDesign:success", () => {
       const data = editor.store.designData;
       document.title = data.title;
-      WxSdk.setShareData({
+      const shareData = {
         title: data.title,
         link: location.href,
         imgUrl: data.thumbnail || "",
         desc: data.desc,
-      });
+      };
+      wxSdk.setShareData(shareData);
+      wxSdk.setShare(shareData);
     });
   }
 
-  onMounted(() => {
-    WxSdk.init();
-  });
-
   return () => <editor.components.Preview />;
 });

+ 4 - 4
src/pages/website/Promotion2/components/PromotionItem.tsx

@@ -58,14 +58,14 @@ export default defineUI({
             </Tag> */}
             <div class="absolute inset-0 flex items-center justify-center opacity-0 hover:opacity-100 transition-opacity">
               <div
-                class="text-white icon_action w-60px leading-60px orange cursor-pointer rounded-1/2 text-center"
+                class="text-white icon_action w-60px leading-60px orange cursor-pointer rounded-1/2 text-center transition-opacity hover:opacity-90 active:opacity-80"
                 onClick={() => emit("edit", props.record)}
               >
                 编辑
               </div>
 
               <div
-                class="text-white icon_action w-60px leading-60px ml-10px cursor-pointer rounded-1/2 text-center"
+                class="text-white icon_action w-60px leading-60px ml-10px cursor-pointer rounded-1/2 text-center transition-opacity hover:opacity-90 active:opacity-80"
                 onClick={() => emit("menu", "share")}
               >
                 {/* 预览 */}
@@ -112,9 +112,9 @@ const itemStyles = css`
     background: #414141;
   }
   .icon_action {
-    background-color: rgba(0, 0, 0, 0.5);
+    background-color: rgba(0, 0, 0, 0.8);
     &.orange {
-      background-color: rgba(232, 139, 0, 0.5);
+      background-color: rgba(232, 139, 0, 0.8);
     }
   }
 `;

+ 52 - 27
src/pages/website/Promotion2/components/ShareModal.tsx

@@ -1,17 +1,20 @@
+import { IconWechat } from "@/assets/icons";
+import { PromotionController } from "@/modules/resource/controllers/PromotionController";
 import { clipboard } from "@/utils";
 import { Image } from "@queenjs/ui";
 import { useQRCode } from "@vueuse/integrations/useQRCode";
-import { Button, Input } from "ant-design-vue";
-import { defineComponent } from "vue";
+import { Button, Divider, Input } from "ant-design-vue";
+import { defineComponent, reactive } from "vue";
 import { any } from "vue-types";
 
 export default defineComponent({
   props: {
     record: any().isRequired,
+    controller: any<PromotionController>().isRequired,
   },
-  emits: ["edit", "update", "changeThumnb"],
-  setup(props, { slots, emit }) {
+  setup(props, { slots }) {
     let shareLink = location.origin + "/share.html?id=" + props.record._id;
+
     if (location.host == "www.infish.cn") {
       shareLink =
         location.origin +
@@ -21,33 +24,44 @@ export default defineComponent({
 
     const qrUrl = useQRCode(shareLink, { margin: 2 });
 
+    const state = reactive({
+      ...props.record,
+    });
+
     return () => {
-      const { record } = props;
+      const { controller, record } = props;
+      const { desc, thumbnail, title } = state;
 
       return (
         <div class="flex items-start">
           <div>
-            <div class="scrollbar w-375px h-600px pr-10px overflow-y-auto ">
+            <div class="scrollbar w-375px h-600px pr-10px overflow-y-auto">
               {slots.preview?.()}
             </div>
             <div class="mt-20px text-center">
-              <Button type="primary" ghost onClick={() => emit("edit")}>
+              <Button
+                ghost
+                type="primary"
+                onClick={() => controller.onEdit(record)}
+              >
                 编辑作品
               </Button>
             </div>
           </div>
           <div class="flex-1 ml-40px">
             <h3 class="mb-20px text-16px">分享设置</h3>
-
-            <div class="flex">
+            <div class="flex items-start">
               <div class="relative">
                 <Image
                   class="w-80px h-80px object-contain rounded-4px border-1px border-solid border-[#434343]"
-                  src={record.thumbnail}
+                  src={thumbnail}
                 />
                 <div
                   class="absolute left-0 bottom-0 w-1/1 text-center py-5px text-14px bg-dark-200 bg-opacity-80 cursor-pointer"
-                  onClick={() => emit("changeThumnb")}
+                  onClick={async () => {
+                    const res: any = await controller.changeThumbnail();
+                    state.thumbnail = res?.file?.url;
+                  }}
                 >
                   更换封面
                 </div>
@@ -56,39 +70,50 @@ export default defineComponent({
                 <Input
                   class="w-1/1"
                   placeholder="请输入标题"
-                  defaultValue={record.title}
-                  onBlur={(e: any) => {
+                  defaultValue={title}
+                  onChange={(e: any) => {
                     const title = e.target.value;
-                    if (!title) return;
-                    emit("update", { title });
+                    // if (!title) return;
+                    state.title = title;
                   }}
                 />
                 <Input
                   class="mt-10px w-1/1"
                   placeholder="请输入描述"
-                  defaultValue={record.desc}
-                  onBlur={(e: any) => {
+                  defaultValue={desc}
+                  onChange={(e: any) => {
                     const desc = e.target.value;
-                    if (!desc) return;
-                    emit("update", { desc });
+                    // if (!desc) return;
+                    state.desc = desc;
                   }}
                 />
               </div>
             </div>
+            <div class="mt-30px text-center">
+              <Button
+                type="primary"
+                class="w-150px"
+                onClick={() => controller.updateDesign(record, state)}
+              >
+                保存
+              </Button>
+            </div>
+            <Divider />
             <div class="mt-40px flex">
               <div>
-                <h3 class=" text-16px">二维码</h3>
-                <img class="mt-20px w-120px" src={qrUrl.value} />
-                <div class="mt-10px text-center">
-                  <span class="ml-5px text-12px opacity-80">
-                    微信扫一扫分享
-                  </span>
+                <h3 class="text-16px">二维码</h3>
+                <div class="mt-20px">
+                  <img class="w-120px" src={qrUrl.value} />
+                </div>
+                <div class="flex items-center justify-center mt-6px">
+                  <IconWechat class="mr-5px text-20px !text-[#69bb64] leading-0" />
+                  <span class="opacity-80 text-12px">微信扫一扫分享</span>
                 </div>
               </div>
-              <div class="flex-1 w-0 ml-60px">
+              <div class="flex-1 w-0 ml-50px">
                 <h3 class=" text-16px">链接分享</h3>
                 <div class="mt-20px">
-                  <div class="w-1/1 py-4px px-10px border-solid border-1px border-[#434343] rounded-2px truncate opacity-80">
+                  <div class="w-1/1 py-4px px-10px rounded-2px truncate opacity-80 bg-light-50 bg-opacity-8">
                     {shareLink}
                   </div>
                   <Button

+ 16 - 14
src/pages/website/Promotion2/controller.tsx

@@ -2,6 +2,7 @@ import { EditorModule } from "@/modules/editor/module";
 import { ResourceModule } from "@/modules/resource";
 import { PromotionController } from "@/modules/resource/controllers/PromotionController";
 import { PageListController } from "@queenjs/controllers";
+import { queenApi } from "queenjs";
 import ShareModal from "./components/ShareModal";
 
 export function createPromotinController(
@@ -13,29 +14,30 @@ export function createPromotinController(
   ctrl.ListCtrl = new PageListController(resource.config?.httpConfig);
   ctrl.ListCtrl.setCrudPrefix("/h5");
   ctrl.createPromotion = resource.actions.createPromotion;
+  ctrl.changeThumbnail = resource.helper.uploadResource;
+
+  ctrl.updateDesign = (record: any, data: any) => {
+    if (data.title == "") {
+      queenApi.messageError("标题不能为空!");
+      return;
+    }
+    if (record.desc && data.desc == "") {
+      queenApi.messageError("描述不能为空!");
+      return;
+    }
 
-  function updateDesign(record: any, data: any) {
     for (const [key, value] of Object.entries(data)) {
       record[key] = value;
     }
-
-    const designData: any = Object.assign({}, { _id: record._id }, data);
-    editor.https.saveDesign(designData);
-  }
+    editor.https.saveDesign(data);
+    queenApi.messageSuccess("保存成功!");
+  };
 
   async function sharePromotion(record: any) {
     editor.actions.initDesign(record._id);
     editor.actions.switchMode("preview");
     resource.showModal(
-      <ShareModal
-        record={record}
-        onEdit={() => ctrl.onEdit(record)}
-        onUpdate={(data) => updateDesign(record, data)}
-        onChangeThumnb={async () => {
-          const { file } = await resource.helper.uploadResource();
-          updateDesign(record, { thumbnail: file.url });
-        }}
-      >
+      <ShareModal record={record} controller={ctrl}>
         {{
           preview: () => <editor.components.Preview />,
         }}