Преглед на файлове

Merge branch 'dev-5.3.1' of Software/android-cloud-H5 into test

zengzhixiang преди 3 години
родител
ревизия
1e9368c889
променени са 11 файла, в които са добавени 277 реда и са изтрити 5317 реда
  1. 30 0
      modules/vee-validate/index.js
  2. 9 0
      modules/vee-validate/plugin.js
  3. 27 2
      nuxt.config.js
  4. 27 5227
      package-lock.json
  5. 2 0
      package.json
  6. 16 20
      pages/activity/invite-user.vue
  7. 2 23
      pages/index.vue
  8. 2 2
      pages/inspire.vue
  9. 58 16
      pages/login.vue
  10. 94 21
      pages/register-for-invite.vue
  11. 10 6
      schemes/password.js

+ 30 - 0
modules/vee-validate/index.js

@@ -0,0 +1,30 @@
+import path from 'path';
+import unpluginVueComponents from 'unplugin-vue-components/webpack';
+export default function (c, i) {
+  this.nuxt.hook('build:before', (nuxt, buildOptions) => {
+    buildOptions.plugins.push(
+      unpluginVueComponents({
+        resolvers: [
+          {
+            type: 'component',
+            resolve(componentName) {
+              if (componentName.startsWith('Validation')) {
+                // console.log(
+                //   '🚀 ~ file: nuxt.config.js ~ line 230 ~ resolve ~ componentName',
+                //   componentName,
+                // );
+                return {
+                  name: componentName,
+                  from: 'vee-validate',
+                  // sideEffects: getSideEffects(importName, options),
+                };
+              }
+            },
+          },
+        ],
+      }),
+    );
+  });
+
+  this.addPlugin(path.resolve(__dirname, 'plugin.js'));
+}

+ 9 - 0
modules/vee-validate/plugin.js

@@ -0,0 +1,9 @@
+import { extend, localize } from 'vee-validate';
+import * as rules from 'vee-validate/dist/rules';
+import zhCN from 'vee-validate/dist/locale/zh_CN';
+
+// localize({ zhCN });
+localize('zhCN', zhCN);
+Object.entries(rules).forEach(([name, value]) => {
+  extend(name, value);
+});

+ 27 - 2
nuxt.config.js

@@ -1,3 +1,4 @@
+import unpluginVueComponents from 'unplugin-vue-components/webpack';
 // import colors from 'vuetify/es5/util/colors'
 import zhHans from 'vuetify/lib/locale/zh-Hans';
 import dotenv from 'dotenv';
@@ -86,6 +87,7 @@ export default {
   // Auto import components: https://go.nuxtjs.dev/config-components
   components: [
     '~/components',
+
     // {
     //   path: 'vant/es',
     //   level: 1,
@@ -110,6 +112,7 @@ export default {
     // https://go.nuxtjs.dev/vuetify
     '@nuxtjs/vuetify',
     '@unocss/nuxt',
+    '~/modules/vee-validate',
     // '@nuxtjs/composition-api/module',
   ],
 
@@ -141,7 +144,7 @@ export default {
         process.env.API_HOST
       }:${process.env.API_PORT}`,
       pathRewrite: {
-        // '^/api/': ''
+        // '^/api': ''
       },
     },
     '/file': {
@@ -149,7 +152,7 @@ export default {
         process.env.FILE_HOST
       }:${process.env.FILE_PORT}`,
       pathRewrite: {
-        '^/file/': '',
+        '^/file': '',
       },
     },
   },
@@ -219,6 +222,28 @@ export default {
     //     },
     //   };
     // },
+    plugins: [
+      // unpluginVueComponents({
+      //   resolvers: [
+      //     {
+      //       type: 'component',
+      //       resolve(componentName) {
+      //         if (componentName.startsWith('Validation')) {
+      //           console.log(
+      //             '🚀 ~ file: nuxt.config.js ~ line 230 ~ resolve ~ componentName',
+      //             componentName,
+      //           );
+      //           return {
+      //             name: componentName,
+      //             from: 'vee-validate',
+      //             // sideEffects: getSideEffects(importName, options),
+      //           };
+      //         }
+      //       },
+      //     },
+      //   ],
+      // }),
+    ],
     babel: {
       plugins: [],
     },

Файловите разлики са ограничени, защото са твърде много
+ 27 - 5227
package-lock.json


+ 2 - 0
package.json

@@ -25,6 +25,7 @@
     "@nuxtjs/axios": "^5.13.6",
     "axios": "^0.27.2",
     "clipboard": "^2.0.11",
+    "clipboard-polyfill": "^4.0.0-rc1",
     "clipboardy": "^3.0.0",
     "core-js": "^3.19.3",
     "dayjs": "^1.11.3",
@@ -35,6 +36,7 @@
     "numeral": "^2.0.6",
     "nuxt": "^2.15.8",
     "vant": "^2.12.47",
+    "vee-validate": "^3.4.14",
     "vue": "^2.6.14",
     "vue-data-dict": "^1.0.6",
     "vue-server-renderer": "^2.6.14",

+ 16 - 20
pages/activity/invite-user.vue

@@ -80,8 +80,9 @@
 </template>
 
 <script>
-import qs from 'qs';
-import clipboard from 'clipboardy/browser';
+// import qs from 'qs';
+// import clipboard from 'clipboardy/browser';
+import * as clipboard from 'clipboard-polyfill/text';
 import { getStarCoinOverview } from '~/api/activity/invite-user.js';
 
 export default {
@@ -98,6 +99,7 @@ export default {
         todayBuyOrderSuccessCount: 0,
         totalBuyOrderSuccessCount: 0,
         withdrawStarCoinNum: 0,
+        inviteUserName: null,
       },
     };
   },
@@ -136,7 +138,7 @@ export default {
   mounted() {},
   methods: {
     async share() {
-      console.log(this);
+      // console.log(this);
       this.$tongji.trackEvent('活动', '分享', '', 0);
 
       const url =
@@ -144,36 +146,30 @@ export default {
         this.$router.resolve({
           path: '/register-for-invite',
           query: {
-            invitationUserName: this.$auth.user?.phone,
-            activityId: 1,
+            invitationUserName: this.data.invitationUserName,
+            activityId: this.$route.query.activityId,
           },
         }).href;
 
       if (this.$userAgent.isMiniProgram) {
         // 小程序环境
-        await clipboard.write(url);
+        await clipboard.writeText(url);
         this.$toast.success('链接复制成功');
       } else if (this.$userAgent.isApp) {
         // app环境
         this.$native.share({
           title: '双子星APP',
           content: '分享好友购买云机套餐,返星币换现金',
-          gotoUrl: `${location.origin}${location.pathname}${qs.stringify(
-            { id: 666 },
-            { addQueryPrefix: true },
-          )}`,
-          shareImg: url,
+          gotoUrl: url,
+          shareImg: 'sdsa.png',
         });
       } else {
         // 浏览器环境
-        // await clipboard.write(url);
-        throw new Error('1231');
-        // this.$toast.success('链接复制成功');
+        await clipboard.writeText(url);
+        // throw new Error('1231');
+        this.$toast.success('链接复制成功');
       }
     },
-    share2() {
-      throw new Error('1231');
-    },
   },
 };
 </script>
@@ -251,8 +247,8 @@ export default {
   .share-button {
     display: block;
     margin: auto;
-    width: 302px;
-    height: 62px;
+    width: 302px !important;
+    height: 62px !important;
     background-image: url('~/assets/image/activity/invite-user/share-button@2x.png');
     background-size: 100% 100%;
     margin-top: 24px;
@@ -275,7 +271,7 @@ export default {
 .box4 {
   .box-main {
     // padding-left: 20px;
-    padding-top: 0;
+    // padding-top: 0;
   }
 }
 </style>

+ 2 - 23
pages/index.vue

@@ -1,13 +1,8 @@
 <template>
   <div>
     <div>
-      <div>title</div>
       <div>
-        <button @click="$router.push('/inspire')">inspire</button>
-      </div>
-      <div class="justify-end">
-        <button @click="getContentByType()">getContentByType</button>
-        <button @click="message()">message</button>
+        <v-btn to="/inspire" nuxt>inspire</v-btn>
       </div>
     </div>
     <div class="">{{ FILE_PREFIX }}</div>
@@ -24,7 +19,6 @@
 </template>
 
 <script>
-import { getContentByType } from '~/api/public/agreement.js';
 export default {
   name: 'IndexPage',
   auth: false,
@@ -42,21 +36,6 @@ export default {
   },
   fetch() {},
   mounted() {},
-  methods: {
-    async getContentByType() {
-      const data = await getContentByType(this, 'XYPZYHXY2004', 1);
-      console.log(
-        '🚀 ~ file: index.vue ~ line 24 ~ getContentByType ~ data',
-        data,
-      );
-    },
-    message() {
-      this.$message({
-        app: true,
-        content: '123456798',
-        icon: '$success',
-      });
-    },
-  },
+  methods: {},
 };
 </script>

+ 2 - 2
pages/inspire.vue

@@ -6,8 +6,8 @@
         <div class="">{{ $auth.user }}</div>
       </div>
       <div class="justify-end">
-        <button v-if="$auth.loggedIn" @click="$auth.logout()">logout</button>
-        <button v-else @click="$auth.redirect('login')">login</button>
+        <v-btn v-if="$auth.loggedIn" @click="$auth.logout()">logout</v-btn>
+        <v-btn v-else @click="$auth.redirect('login')">login</v-btn>
       </div>
     </div>
   </div>

+ 58 - 16
pages/login.vue

@@ -1,16 +1,48 @@
 <template>
-  <div>
-    <div>
-      <div>
-        <input v-model="form.phone" />
-        <input v-model="form.password" />
-      </div>
-      <div>
-        <button v-if="$auth.loggedIn" @click="logout()">logout</button>
-        <button v-else @click="login()">login</button>
-      </div>
-    </div>
-  </div>
+  <v-container class="login-page" fluid>
+    <validation-observer ref="observer" v-slot="{ invalid }" slim>
+      <v-form @submit.prevent="submit()">
+        <validation-provider
+          v-slot="{ errors }"
+          ref="providerPhome"
+          name="手机号码"
+          rules="required|min:11|max:11"
+          slim
+        >
+          <v-text-field
+            v-model="form.phone"
+            label="手机号码"
+            name="phone"
+            required
+            :error-messages="errors"
+            maxlength="11"
+            type="tel"
+          />
+        </validation-provider>
+        <validation-provider
+          v-slot="{ errors }"
+          ref="providerPassword"
+          name="密码"
+          rules="required"
+          slim
+        >
+          <v-text-field
+            v-model="form.password"
+            label="手机号码"
+            name="phone"
+            required
+            :error-messages="errors"
+            type="password"
+          />
+        </validation-provider>
+        <div class="">
+          <v-btn type="submit" :disabled="invalid" :loading="submitting"
+            >login</v-btn
+          >
+        </div>
+      </v-form>
+    </validation-observer>
+  </v-container>
 </template>
 
 <script>
@@ -22,13 +54,23 @@ export default {
         phone: '17600000010',
         password: '1234567890',
       },
+      submitting: false,
     };
   },
   methods: {
-    login() {
-      return this.$auth.loginWith('password', {
-        data: this.form,
-      });
+    async submit() {
+      try {
+        this.submitting = true;
+        const valid = await this.$refs.observer.validate();
+        if (valid) {
+          await this.login(this.form);
+        }
+      } finally {
+        this.submitting = false;
+      }
+    },
+    async login(data) {
+      await this.$auth.loginWith('password', data);
     },
     logout() {
       return this.$auth.logout();

+ 94 - 21
pages/register-for-invite.vue

@@ -1,15 +1,61 @@
 <template>
-  <div class="register-for-invite">
-    <div class="">注册</div>
-    <form @submit.prevent>
-      <input v-model="form.phone" label="phone" name="phone" />
-      <input v-model="form.code" label="code" name="code" maxlength="6" />
-      <div class="">
-        <button @click="register()">注册</button>
-        <button @click="sendSmsCode()">发送验证码</button>
-      </div>
-    </form>
-  </div>
+  <v-container class="register-for-invite" fluid>
+    <div class="title">注册</div>
+    <validation-observer ref="observer" v-slot="{ invalid }" slim>
+      <v-form @submit.prevent="submit()">
+        <validation-provider
+          v-slot="{ errors }"
+          ref="providerPhome"
+          name="手机号码"
+          rules="required|min:11|max:11"
+          slim
+        >
+          <v-text-field
+            v-model="form.phone"
+            label="手机号码"
+            name="phone"
+            required
+            :error-messages="errors"
+            maxlength="11"
+            type="tel"
+          />
+        </validation-provider>
+        <validation-provider
+          v-slot="{ errors }"
+          name="验证码"
+          rules="required|min:6|max:6"
+          slim
+        >
+          <v-text-field
+            v-model="form.code"
+            label="验证码"
+            :error-messages="errors"
+            name="code"
+            maxlength="6"
+            required
+          >
+            <template #append-outer>
+              <v-btn
+                :loading="codeSending"
+                :disabled="codeTime > 0"
+                small
+                @click="sendSmsCode()"
+              >
+                <template v-if="codeTime > 0">{{ codeTime }}s</template>
+                <template v-else>发送验证码</template>
+              </v-btn>
+            </template>
+          </v-text-field>
+        </validation-provider>
+
+        <div class="">
+          <v-btn type="submit" :disabled="invalid" :loading="submitting"
+            >注册并下载app</v-btn
+          >
+        </div>
+      </v-form>
+    </validation-observer>
+  </v-container>
 </template>
 
 <script>
@@ -26,6 +72,9 @@ export default {
         invitationUserName: null,
         activityId: null,
       },
+      codeSending: false,
+      codeTime: 0,
+      submitting: false,
     };
   },
   fetch() {
@@ -35,19 +84,43 @@ export default {
   head: {
     title: '注册',
   },
+  watch: {},
   methods: {
-    async register() {
-      this.$tongji.trackEvent('活动', '注册', '', 0);
-      await registerForInvite(this, this.form);
+    async submit() {
+      try {
+        this.submitting = true;
+        const valid = await this.$refs.observer.validate();
+        if (valid) {
+          this.$tongji.trackEvent('活动', '注册', '', 0);
+          const res = await registerForInvite(this, this.form);
+          this.$toast.success(res.msg);
+        }
+      } finally {
+        this.submitting = false;
+      }
     },
     async sendSmsCode() {
-      this.$tongji.trackEvent('活动', '发送短信', '', 0);
-      const res = await sendSmsCode(this, {
-        type: 'common',
-        authorizationType: 4,
-        phone: this.form.phone,
-      });
-      this.$message({ content: res.msg });
+      try {
+        this.codeSending = true;
+        const validationResult = await this.$refs.providerPhome.validate();
+        if (validationResult.valid) {
+          this.$tongji.trackEvent('活动', '发送短信', '', 0);
+          const res = await sendSmsCode(this, {
+            type: 'common',
+            authorizationType: 4,
+            phone: this.form.phone,
+          });
+          this.codeTime = 60;
+          this.codeInterval = setInterval(() => {
+            if (--this.codeTime <= 0) {
+              clearInterval(this.codeInterval);
+            }
+          }, 1000);
+          this.$toast.success(res.msg);
+        }
+      } finally {
+        this.codeSending = false;
+      }
     },
   },
 };

+ 10 - 6
schemes/password.js

@@ -6,8 +6,12 @@ let publicKey;
 const encrypt = new JSEncrypt();
 
 export default class CustomScheme extends LocalScheme {
-  async login(endpoint, { reset = true } = {}) {
-    endpoint.data = Object.assign({}, endpoint.data);
+  async login(data, { reset = true } = {}) {
+    const endpoint = { data: Object.assign({}, data) };
+
+    // endpoint.data = Object.assign({}, endpoint.data);
+
+    // endpoint.data = endpoint.data;
 
     if (!this.options.endpoints.login) {
       return;
@@ -31,10 +35,10 @@ export default class CustomScheme extends LocalScheme {
       ).data.publicKey;
       encrypt.setPublicKey(publicKey);
     }
-    console.log(
-      '🚀 ~ file: password.js ~ line 37 ~ CustomScheme ~ login ~ publicKey',
-      publicKey,
-    );
+    // console.log(
+    //   '🚀 ~ file: password.js ~ line 37 ~ CustomScheme ~ login ~ publicKey',
+    //   publicKey,
+    // );
     const md5 = createHash('md5');
 
     endpoint.data.password = encrypt.encrypt(