hookehuyr

feat: 新增邮件白名单提示,在下载和重置密码前增加校验

新增邮件白名单提示组件、工具函数及全局混入方法,在资源下载和密码重置的操作前弹出提示框,提醒用户确认已将官方发件邮箱hagerminisite_cn@163.com加入收件白名单,仅用户确认后才执行后续对应操作,同时更新全局组件类型声明与组件注册配置。
...@@ -34,6 +34,7 @@ declare module 'vue' { ...@@ -34,6 +34,7 @@ declare module 'vue' {
34 HagerMore: typeof import('./src/components/hagerMore.vue')['default'] 34 HagerMore: typeof import('./src/components/hagerMore.vue')['default']
35 HagerService: typeof import('./src/components/common/hagerService.vue')['default'] 35 HagerService: typeof import('./src/components/common/hagerService.vue')['default']
36 LoginPrompt: typeof import('./src/components/common/loginPrompt.vue')['default'] 36 LoginPrompt: typeof import('./src/components/common/loginPrompt.vue')['default']
37 + MailWhitelistPrompt: typeof import('./src/components/common/mailWhitelistPrompt.vue')['default']
37 Navbar: typeof import('./src/components/navbar.vue')['default'] 38 Navbar: typeof import('./src/components/navbar.vue')['default']
38 Privacy: typeof import('./src/components/privacy.vue')['default'] 39 Privacy: typeof import('./src/components/privacy.vue')['default']
39 RouterLink: typeof import('vue-router')['RouterLink'] 40 RouterLink: typeof import('vue-router')['RouterLink']
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
11 <router-view :class="[!isLoginPage ? 'wrapper' : '', is_xs ? 'xs' : '']"></router-view> 11 <router-view :class="[!isLoginPage ? 'wrapper' : '', is_xs ? 'xs' : '']"></router-view>
12 <hager-footer v-if="!isLoginPage" @send-openid="sendOpenid"></hager-footer> 12 <hager-footer v-if="!isLoginPage" @send-openid="sendOpenid"></hager-footer>
13 <login-prompt></login-prompt> 13 <login-prompt></login-prompt>
14 + <mail-whitelist-prompt></mail-whitelist-prompt>
14 <div v-if="showMask" class="mask"> 15 <div v-if="showMask" class="mask">
15 </div> 16 </div>
16 </div> 17 </div>
...@@ -20,6 +21,7 @@ ...@@ -20,6 +21,7 @@
20 import hagerHeader from '@/components/common/hagerHeader.vue'; 21 import hagerHeader from '@/components/common/hagerHeader.vue';
21 import hagerFooter from '@/components/common/hagerFooter.vue'; 22 import hagerFooter from '@/components/common/hagerFooter.vue';
22 import loginPrompt from '@/components/common/loginPrompt.vue'; 23 import loginPrompt from '@/components/common/loginPrompt.vue';
24 +import mailWhitelistPrompt from '@/components/common/mailWhitelistPrompt.vue';
23 import mixin from '@/common/mixin'; 25 import mixin from '@/common/mixin';
24 import { wxInfo } from '@/utils/tools'; 26 import { wxInfo } from '@/utils/tools';
25 27
...@@ -32,7 +34,7 @@ export default { ...@@ -32,7 +34,7 @@ export default {
32 { name: 'description', content: '海格电气 构建未来电气世界 让人们的生活更安全、更清洁、更愉悦。' }, 34 { name: 'description', content: '海格电气 构建未来电气世界 让人们的生活更安全、更清洁、更愉悦。' },
33 ] 35 ]
34 }, 36 },
35 - components: { hagerHeader, hagerFooter, loginPrompt }, 37 + components: { hagerHeader, hagerFooter, loginPrompt, mailWhitelistPrompt },
36 mixins: [mixin.init], 38 mixins: [mixin.init],
37 data () { 39 data () {
38 return { 40 return {
......
...@@ -11,6 +11,7 @@ import { throttle } from 'lodash-es'; ...@@ -11,6 +11,7 @@ import { throttle } from 'lodash-es';
11 import axios from '@/utils/axios'; 11 import axios from '@/utils/axios';
12 import { getUserInfoAPI } from '@/api/hager'; 12 import { getUserInfoAPI } from '@/api/hager';
13 import { openLoginPrompt } from '@/utils/loginPrompt'; 13 import { openLoginPrompt } from '@/utils/loginPrompt';
14 +import { openMailWhitelistPrompt } from '@/utils/mailWhitelistPrompt';
14 15
15 export default { 16 export default {
16 // 初始化设置 17 // 初始化设置
...@@ -81,6 +82,13 @@ export default { ...@@ -81,6 +82,13 @@ export default {
81 82
82 return false; 83 return false;
83 }, 84 },
85 + async showMailWhitelistPrompt (options = {}) {
86 + return openMailWhitelistPrompt({
87 + title: options.title || '温馨提示',
88 + message: options.message || '请确保我们的发件邮箱:hagerminisite_cn@163.com,在您的收件白名单中',
89 + confirmText: options.confirmText || '确定',
90 + });
91 + },
84 // 埋点支持两种传参方式: 92 // 埋点支持两种传参方式:
85 // this.maEvent('h5_contact') 93 // this.maEvent('h5_contact')
86 // this.maEvent({ p: 'h5_contact', event: 'document_preview' }) 94 // this.maEvent({ p: 'h5_contact', event: 'document_preview' })
......
...@@ -83,6 +83,10 @@ export default { ...@@ -83,6 +83,10 @@ export default {
83 this.$emit('input', event.target.value); 83 this.$emit('input', event.target.value);
84 }, 84 },
85 async resetPwd () { 85 async resetPwd () {
86 + const confirmed = await this.showMailWhitelistPrompt();
87 + if (!confirmed) {
88 + return;
89 + }
86 this.$emit('send', this.value); 90 this.$emit('send', this.value);
87 } 91 }
88 } 92 }
......
1 +<template>
2 + <div>
3 + <el-dialog
4 + v-if="!is_xs"
5 + :visible.sync="dialogVisible"
6 + :close-on-click-modal="false"
7 + :show-close="false"
8 + width="30rem"
9 + custom-class="mail-whitelist-dialog">
10 + <div class="mail-whitelist-content">
11 + <div class="title">{{ prompt.title }}</div>
12 + <div class="message">{{ prompt.message }}</div>
13 + <div class="action-row">
14 + <div class="action-btn confirm" @click="handleConfirm">{{ prompt.confirmText }}</div>
15 + </div>
16 + </div>
17 + </el-dialog>
18 +
19 + <transition v-else name="mail-mobile-fade">
20 + <div
21 + v-if="drawerVisible"
22 + class="mail-whitelist-mobile-mask"
23 + @click.self="handleConfirm">
24 + <div class="mail-whitelist-mobile-panel">
25 + <div class="mail-whitelist-content xs">
26 + <div class="title">{{ prompt.title }}</div>
27 + <div class="message">{{ prompt.message }}</div>
28 + <div class="action-column">
29 + <div class="action-btn confirm" @click="handleConfirm">{{ prompt.confirmText }}</div>
30 + </div>
31 + </div>
32 + </div>
33 + </div>
34 + </transition>
35 + </div>
36 +</template>
37 +
38 +<script>
39 +import mixin from '@/common/mixin';
40 +import { closeMailWhitelistPrompt, mailWhitelistPromptState } from '@/utils/mailWhitelistPrompt';
41 +
42 +export default {
43 + name: 'MailWhitelistPrompt',
44 + mixins: [mixin.init],
45 + computed: {
46 + prompt () {
47 + return mailWhitelistPromptState;
48 + },
49 + dialogVisible: {
50 + get () {
51 + return this.prompt.visible && !this.is_xs;
52 + },
53 + set (visible) {
54 + if (!visible) {
55 + this.handleConfirm();
56 + }
57 + }
58 + },
59 + drawerVisible: {
60 + get () {
61 + return this.prompt.visible && this.is_xs;
62 + },
63 + set (visible) {
64 + if (!visible) {
65 + this.handleConfirm();
66 + }
67 + }
68 + }
69 + },
70 + methods: {
71 + handleConfirm () {
72 + closeMailWhitelistPrompt(true);
73 + }
74 + }
75 +}
76 +</script>
77 +
78 +<style lang="less">
79 +.mail-whitelist-dialog {
80 + border-radius: 0.75rem;
81 +}
82 +
83 +.mail-whitelist-content {
84 + padding: 0.5rem 0;
85 + text-align: center;
86 +
87 + &.xs {
88 + padding: 1.5rem 1rem 1rem;
89 + }
90 +
91 + .title {
92 + font-size: 1.25rem;
93 + font-weight: bold;
94 + color: @primary-color;
95 + }
96 +
97 + .message {
98 + margin-top: 1rem;
99 + color: @text-color;
100 + line-height: 1.8;
101 + word-break: break-word;
102 + }
103 +
104 + .action-row,
105 + .action-column {
106 + margin-top: 1.5rem;
107 + display: flex;
108 + justify-content: center;
109 + }
110 +
111 + .action-column {
112 + flex-direction: column;
113 + }
114 +
115 + .action-btn {
116 + min-width: 8rem;
117 + padding: 0.75rem 1rem;
118 + border-radius: 0.5rem;
119 + border: 1px solid @primary-color;
120 + background-color: @primary-color;
121 + color: #fff;
122 + box-sizing: border-box;
123 +
124 + &:hover {
125 + cursor: pointer;
126 + }
127 + }
128 +}
129 +
130 +.mail-whitelist-mobile-mask {
131 + position: fixed;
132 + inset: 0;
133 + z-index: 2008;
134 + display: flex;
135 + align-items: center;
136 + justify-content: center;
137 + padding: 1rem 0.75rem;
138 + background: rgba(0, 0, 0, 0.45);
139 + box-sizing: border-box;
140 +}
141 +
142 +.mail-whitelist-mobile-panel {
143 + width: 100%;
144 + max-width: 22rem;
145 + background: #fff;
146 + border-radius: 1rem;
147 + box-shadow: 0 0.75rem 2rem rgba(0, 0, 0, 0.16);
148 +}
149 +
150 +.mail-mobile-fade-enter-active,
151 +.mail-mobile-fade-leave-active {
152 + transition: opacity 0.24s ease;
153 +}
154 +
155 +.mail-mobile-fade-enter-active .mail-whitelist-mobile-panel,
156 +.mail-mobile-fade-leave-active .mail-whitelist-mobile-panel {
157 + transition: transform 0.24s ease;
158 +}
159 +
160 +.mail-mobile-fade-enter,
161 +.mail-mobile-fade-leave-to {
162 + opacity: 0;
163 +}
164 +
165 +.mail-mobile-fade-enter .mail-whitelist-mobile-panel,
166 +.mail-mobile-fade-leave-to .mail-whitelist-mobile-panel {
167 + transform: translateY(1rem) scale(0.96);
168 +}
169 +</style>
1 +import Vue from 'vue';
2 +
3 +const defaultOptions = {
4 + title: '温馨提示',
5 + message: '请确保我们的发件邮箱:hagerminisite_cn@163.com,在您的收件白名单中',
6 + confirmText: '确定',
7 +};
8 +
9 +export const mailWhitelistPromptState = Vue.observable({
10 + visible: false,
11 + title: defaultOptions.title,
12 + message: defaultOptions.message,
13 + confirmText: defaultOptions.confirmText,
14 +});
15 +
16 +let resolver = null;
17 +
18 +const resetState = () => {
19 + mailWhitelistPromptState.visible = false;
20 + mailWhitelistPromptState.title = defaultOptions.title;
21 + mailWhitelistPromptState.message = defaultOptions.message;
22 + mailWhitelistPromptState.confirmText = defaultOptions.confirmText;
23 + resolver = null;
24 +};
25 +
26 +export const openMailWhitelistPrompt = (options = {}) => {
27 + if (resolver) {
28 + resolver(false);
29 + resetState();
30 + }
31 +
32 + mailWhitelistPromptState.title = options.title || defaultOptions.title;
33 + mailWhitelistPromptState.message = options.message || defaultOptions.message;
34 + mailWhitelistPromptState.confirmText = options.confirmText || defaultOptions.confirmText;
35 + mailWhitelistPromptState.visible = true;
36 +
37 + return new Promise(resolve => {
38 + resolver = resolve;
39 + });
40 +};
41 +
42 +export const closeMailWhitelistPrompt = (confirmed = false) => {
43 + if (resolver) {
44 + resolver(confirmed);
45 + }
46 + resetState();
47 +};
...@@ -311,6 +311,10 @@ export default { ...@@ -311,6 +311,10 @@ export default {
311 if (!canDownload) { 311 if (!canDownload) {
312 return; 312 return;
313 } 313 }
314 + const confirmed = await this.showMailWhitelistPrompt();
315 + if (!confirmed) {
316 + return;
317 + }
314 if (this.is_download_checked) { 318 if (this.is_download_checked) {
315 let ids = []; 319 let ids = [];
316 this.download_list.forEach(item => { 320 this.download_list.forEach(item => {
...@@ -348,6 +352,10 @@ export default { ...@@ -348,6 +352,10 @@ export default {
348 if (!canDownload) { 352 if (!canDownload) {
349 return; 353 return;
350 } 354 }
355 + const confirmed = await this.showMailWhitelistPrompt();
356 + if (!confirmed) {
357 + return;
358 + }
351 let loadingInstance = Loading.service({ fullscreen: true, background: 'rgba(0, 0, 0, 0.3)' }); 359 let loadingInstance = Loading.service({ fullscreen: true, background: 'rgba(0, 0, 0, 0.3)' });
352 const { code, data } = await downEmailAPI(); 360 const { code, data } = await downEmailAPI();
353 if (code) { 361 if (code) {
......
...@@ -311,6 +311,10 @@ export default { ...@@ -311,6 +311,10 @@ export default {
311 if (!canDownload) { 311 if (!canDownload) {
312 return; 312 return;
313 } 313 }
314 + const confirmed = await this.showMailWhitelistPrompt();
315 + if (!confirmed) {
316 + return;
317 + }
314 if (this.is_download_checked) { 318 if (this.is_download_checked) {
315 let ids = []; 319 let ids = [];
316 this.download_list.forEach(item => { 320 this.download_list.forEach(item => {
...@@ -348,6 +352,10 @@ export default { ...@@ -348,6 +352,10 @@ export default {
348 if (!canDownload) { 352 if (!canDownload) {
349 return; 353 return;
350 } 354 }
355 + const confirmed = await this.showMailWhitelistPrompt();
356 + if (!confirmed) {
357 + return;
358 + }
351 let loadingInstance = Loading.service({ fullscreen: true, background: 'rgba(0, 0, 0, 0.3)' }); 359 let loadingInstance = Loading.service({ fullscreen: true, background: 'rgba(0, 0, 0, 0.3)' });
352 const { code, data } = await downEmailAPI(); 360 const { code, data } = await downEmailAPI();
353 if (code) { 361 if (code) {
......