hookehuyr

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

新增邮件白名单提示组件、工具函数及全局混入方法,在资源下载和密码重置的操作前弹出提示框,提醒用户确认已将官方发件邮箱hagerminisite_cn@163.com加入收件白名单,仅用户确认后才执行后续对应操作,同时更新全局组件类型声明与组件注册配置。
......@@ -34,6 +34,7 @@ declare module 'vue' {
HagerMore: typeof import('./src/components/hagerMore.vue')['default']
HagerService: typeof import('./src/components/common/hagerService.vue')['default']
LoginPrompt: typeof import('./src/components/common/loginPrompt.vue')['default']
MailWhitelistPrompt: typeof import('./src/components/common/mailWhitelistPrompt.vue')['default']
Navbar: typeof import('./src/components/navbar.vue')['default']
Privacy: typeof import('./src/components/privacy.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
......
......@@ -11,6 +11,7 @@
<router-view :class="[!isLoginPage ? 'wrapper' : '', is_xs ? 'xs' : '']"></router-view>
<hager-footer v-if="!isLoginPage" @send-openid="sendOpenid"></hager-footer>
<login-prompt></login-prompt>
<mail-whitelist-prompt></mail-whitelist-prompt>
<div v-if="showMask" class="mask">
</div>
</div>
......@@ -20,6 +21,7 @@
import hagerHeader from '@/components/common/hagerHeader.vue';
import hagerFooter from '@/components/common/hagerFooter.vue';
import loginPrompt from '@/components/common/loginPrompt.vue';
import mailWhitelistPrompt from '@/components/common/mailWhitelistPrompt.vue';
import mixin from '@/common/mixin';
import { wxInfo } from '@/utils/tools';
......@@ -32,7 +34,7 @@ export default {
{ name: 'description', content: '海格电气 构建未来电气世界 让人们的生活更安全、更清洁、更愉悦。' },
]
},
components: { hagerHeader, hagerFooter, loginPrompt },
components: { hagerHeader, hagerFooter, loginPrompt, mailWhitelistPrompt },
mixins: [mixin.init],
data () {
return {
......
......@@ -11,6 +11,7 @@ import { throttle } from 'lodash-es';
import axios from '@/utils/axios';
import { getUserInfoAPI } from '@/api/hager';
import { openLoginPrompt } from '@/utils/loginPrompt';
import { openMailWhitelistPrompt } from '@/utils/mailWhitelistPrompt';
export default {
// 初始化设置
......@@ -81,6 +82,13 @@ export default {
return false;
},
async showMailWhitelistPrompt (options = {}) {
return openMailWhitelistPrompt({
title: options.title || '温馨提示',
message: options.message || '请确保我们的发件邮箱:hagerminisite_cn@163.com,在您的收件白名单中',
confirmText: options.confirmText || '确定',
});
},
// 埋点支持两种传参方式:
// this.maEvent('h5_contact')
// this.maEvent({ p: 'h5_contact', event: 'document_preview' })
......
......@@ -83,6 +83,10 @@ export default {
this.$emit('input', event.target.value);
},
async resetPwd () {
const confirmed = await this.showMailWhitelistPrompt();
if (!confirmed) {
return;
}
this.$emit('send', this.value);
}
}
......
<template>
<div>
<el-dialog
v-if="!is_xs"
:visible.sync="dialogVisible"
:close-on-click-modal="false"
:show-close="false"
width="30rem"
custom-class="mail-whitelist-dialog">
<div class="mail-whitelist-content">
<div class="title">{{ prompt.title }}</div>
<div class="message">{{ prompt.message }}</div>
<div class="action-row">
<div class="action-btn confirm" @click="handleConfirm">{{ prompt.confirmText }}</div>
</div>
</div>
</el-dialog>
<transition v-else name="mail-mobile-fade">
<div
v-if="drawerVisible"
class="mail-whitelist-mobile-mask"
@click.self="handleConfirm">
<div class="mail-whitelist-mobile-panel">
<div class="mail-whitelist-content xs">
<div class="title">{{ prompt.title }}</div>
<div class="message">{{ prompt.message }}</div>
<div class="action-column">
<div class="action-btn confirm" @click="handleConfirm">{{ prompt.confirmText }}</div>
</div>
</div>
</div>
</div>
</transition>
</div>
</template>
<script>
import mixin from '@/common/mixin';
import { closeMailWhitelistPrompt, mailWhitelistPromptState } from '@/utils/mailWhitelistPrompt';
export default {
name: 'MailWhitelistPrompt',
mixins: [mixin.init],
computed: {
prompt () {
return mailWhitelistPromptState;
},
dialogVisible: {
get () {
return this.prompt.visible && !this.is_xs;
},
set (visible) {
if (!visible) {
this.handleConfirm();
}
}
},
drawerVisible: {
get () {
return this.prompt.visible && this.is_xs;
},
set (visible) {
if (!visible) {
this.handleConfirm();
}
}
}
},
methods: {
handleConfirm () {
closeMailWhitelistPrompt(true);
}
}
}
</script>
<style lang="less">
.mail-whitelist-dialog {
border-radius: 0.75rem;
}
.mail-whitelist-content {
padding: 0.5rem 0;
text-align: center;
&.xs {
padding: 1.5rem 1rem 1rem;
}
.title {
font-size: 1.25rem;
font-weight: bold;
color: @primary-color;
}
.message {
margin-top: 1rem;
color: @text-color;
line-height: 1.8;
word-break: break-word;
}
.action-row,
.action-column {
margin-top: 1.5rem;
display: flex;
justify-content: center;
}
.action-column {
flex-direction: column;
}
.action-btn {
min-width: 8rem;
padding: 0.75rem 1rem;
border-radius: 0.5rem;
border: 1px solid @primary-color;
background-color: @primary-color;
color: #fff;
box-sizing: border-box;
&:hover {
cursor: pointer;
}
}
}
.mail-whitelist-mobile-mask {
position: fixed;
inset: 0;
z-index: 2008;
display: flex;
align-items: center;
justify-content: center;
padding: 1rem 0.75rem;
background: rgba(0, 0, 0, 0.45);
box-sizing: border-box;
}
.mail-whitelist-mobile-panel {
width: 100%;
max-width: 22rem;
background: #fff;
border-radius: 1rem;
box-shadow: 0 0.75rem 2rem rgba(0, 0, 0, 0.16);
}
.mail-mobile-fade-enter-active,
.mail-mobile-fade-leave-active {
transition: opacity 0.24s ease;
}
.mail-mobile-fade-enter-active .mail-whitelist-mobile-panel,
.mail-mobile-fade-leave-active .mail-whitelist-mobile-panel {
transition: transform 0.24s ease;
}
.mail-mobile-fade-enter,
.mail-mobile-fade-leave-to {
opacity: 0;
}
.mail-mobile-fade-enter .mail-whitelist-mobile-panel,
.mail-mobile-fade-leave-to .mail-whitelist-mobile-panel {
transform: translateY(1rem) scale(0.96);
}
</style>
import Vue from 'vue';
const defaultOptions = {
title: '温馨提示',
message: '请确保我们的发件邮箱:hagerminisite_cn@163.com,在您的收件白名单中',
confirmText: '确定',
};
export const mailWhitelistPromptState = Vue.observable({
visible: false,
title: defaultOptions.title,
message: defaultOptions.message,
confirmText: defaultOptions.confirmText,
});
let resolver = null;
const resetState = () => {
mailWhitelistPromptState.visible = false;
mailWhitelistPromptState.title = defaultOptions.title;
mailWhitelistPromptState.message = defaultOptions.message;
mailWhitelistPromptState.confirmText = defaultOptions.confirmText;
resolver = null;
};
export const openMailWhitelistPrompt = (options = {}) => {
if (resolver) {
resolver(false);
resetState();
}
mailWhitelistPromptState.title = options.title || defaultOptions.title;
mailWhitelistPromptState.message = options.message || defaultOptions.message;
mailWhitelistPromptState.confirmText = options.confirmText || defaultOptions.confirmText;
mailWhitelistPromptState.visible = true;
return new Promise(resolve => {
resolver = resolve;
});
};
export const closeMailWhitelistPrompt = (confirmed = false) => {
if (resolver) {
resolver(confirmed);
}
resetState();
};
......@@ -311,6 +311,10 @@ export default {
if (!canDownload) {
return;
}
const confirmed = await this.showMailWhitelistPrompt();
if (!confirmed) {
return;
}
if (this.is_download_checked) {
let ids = [];
this.download_list.forEach(item => {
......@@ -348,6 +352,10 @@ export default {
if (!canDownload) {
return;
}
const confirmed = await this.showMailWhitelistPrompt();
if (!confirmed) {
return;
}
let loadingInstance = Loading.service({ fullscreen: true, background: 'rgba(0, 0, 0, 0.3)' });
const { code, data } = await downEmailAPI();
if (code) {
......
......@@ -311,6 +311,10 @@ export default {
if (!canDownload) {
return;
}
const confirmed = await this.showMailWhitelistPrompt();
if (!confirmed) {
return;
}
if (this.is_download_checked) {
let ids = [];
this.download_list.forEach(item => {
......@@ -348,6 +352,10 @@ export default {
if (!canDownload) {
return;
}
const confirmed = await this.showMailWhitelistPrompt();
if (!confirmed) {
return;
}
let loadingInstance = Loading.service({ fullscreen: true, background: 'rgba(0, 0, 0, 0.3)' });
const { code, data } = await downEmailAPI();
if (code) {
......