feat: 增加发邮件功能

This commit is contained in:
kenny
2025-10-16 19:15:42 +08:00
parent 617f4f6acf
commit 728dc5e559
4 changed files with 625 additions and 219 deletions
+21 -6
View File
@@ -68,7 +68,10 @@
"schemes": "shopro"
},
"ios": {
"urlschemewhitelist" : [ "baidumap", "iosamap" ],
"urlschemewhitelist": [
"baidumap",
"iosamap"
],
"dSYMs": false,
"privacyDescription": {
"NSPhotoLibraryUsageDescription": "需要同意访问您的相册选取图片才能完善该条目",
@@ -79,7 +82,9 @@
"urltypes": "shopro",
"capabilities": {
"entitlements": {
"com.apple.developer.associated-domains" : [ "applinks:shopro.sheepjs.com" ]
"com.apple.developer.associated-domains": [
"applinks:shopro.sheepjs.com"
]
}
},
"idfa": true
@@ -96,12 +101,18 @@
},
"payment": {
"weixin": {
"__platform__" : [ "ios", "android" ],
"__platform__": [
"ios",
"android"
],
"appid": "wxae7a0c156da9383b",
"UniversalLinks": "https://shopro.sheepjs.com/uni-universallinks/__UNI__082C0BA/"
},
"alipay": {
"__platform__" : [ "ios", "android" ]
"__platform__": [
"ios",
"android"
]
}
},
"share": {
@@ -111,7 +122,9 @@
}
}
},
"orientation" : [ "portrait-primary" ],
"orientation": [
"portrait-primary"
],
"splashscreen": {
"androidStyle": "common",
"iosStyle": "common",
@@ -182,7 +195,9 @@
"lazyCodeLoading": "requiredComponents",
"usingComponents": {},
"permission": {},
"requiredPrivateInfos" : [ "chooseAddress" ]
"requiredPrivateInfos": [
"chooseAddress"
]
},
"mp-alipay": {
"usingComponents": true
@@ -0,0 +1,186 @@
<template>
<div class="dialog" v-if="visible && info">
<div class="dialog-main">
<div class="dialog-title">{{ info.name }}</div>
<div class="dialog-body">
<!-- <div class="dialog-score" v-if="info.result">
<div class="text" :style="{ color: info.color }">
{{ info.result }}
</div>
<div class="count">{{ info.userValue }}</div>
</div> -->
<!-- <div class="dialog-text" v-if="info.text">
{{ info.text }}
</div>
<div class="dialog-box" v-if="!info.text">
<div
v-for="(item, index) in [
info.explanationAnalyzeResult.advicesList,
info.explanationAnalyzeResult.detailsList,
].flat(Infinity)"
:key="index"
>
<div class="dialog-box-title" :style="{ margin: 0 }">
{{ item.name }}
</div>
<div
class="dialog-box-item"
v-for="(value, idx) in item.valuesList"
:key="idx + value"
>
{{ value }}
</div>
</div>
</div> -->
<div class="dialog-text">xxxxxxxxxxxxxxx</div>
</div>
<div class="dialog-btn" @click="onClose">知道了</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {};
},
props: {
visible: {
type: Boolean,
default: false,
},
info: {
type: Object,
default: null,
},
},
methods: {
onClose() {
console.log("onClose: xxxxxxxxx", this.info);
this.$emit("update:visible", false);
},
},
};
</script>
<style scoped lang="scss">
.dialog {
position: fixed;
inset: 0;
background-color: rgba(0, 0, 0, 0.4);
.dialog-main {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
// background-color: red;
width: 380rpx;
// height: 548rpx;
// min-height: 363rpx;
// max-height: 548rpx;
background: #f5f7fb;
border-radius: 25rpx;
box-sizing: border-box;
padding: 25rpx;
.dialog-title {
color: #000000;
font-size: 20rpx;
text-align: center;
font-weight: bolder;
padding-bottom: 25rpx;
border-bottom: 1rpx solid #d9d9d9;
}
.dialog-body {
// padding: 25rpx;
margin-top: 25rpx;
padding-bottom: 25rpx;
// overflow-y: scroll;
flex: 1;
.dialog-score {
display: flex;
align-items: center;
flex-direction: column;
margin-bottom: 25rpx;
// margin-top: 25rpx;
// display: none;
.text {
font-size: 23rpx;
color: #5ea2f0;
font-weight: bold;
line-height: 1;
}
.count {
font-size: 18rpx;
color: #343434;
line-height: 1;
margin-top: 3rpx;
}
}
.dialog-text {
font-size: 16rpx;
color: #343434;
line-height: 21rpx;
// margin: 25rpx 0;
letter-spacing: 3rpx;
// margin-top: 25rpx;
// background-color: red;
}
.dialog-box {
overflow-y: scroll;
max-height: 600rpx;
// padding-top: 25rpx;
// background-color: red;
.dialog-box-title {
font-size: 18rpx;
color: #000000;
font-weight: bolder;
margin-top: 25rpx;
}
.dialog-box-item {
font-size: 16rpx;
color: #515f65;
line-height: 21rpx;
letter-spacing: 3rpx;
margin-top: 6rpx;
}
}
}
.dialog-btn {
height: 50rpx;
background: #5ea2f0;
border-radius: 15rpx;
font-size: 16rpx;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
&:active {
opacity: 0.4;
}
}
}
}
</style>
+161 -4
View File
@@ -310,7 +310,22 @@
</view>
<view class="btn-bottom" v-if="collect">
<button class="next-btn" >马上体验</button>
<button class="next-btn" @click="openEmailDialog">发送到邮件</button>
</view>
<view class="m-dialog" v-if="dialog.visible">
<div class="m-dialog-main">
<div class="email">
邮箱<input
v-model="email"
focus
placeholder="请输入您的邮箱"
placeholder-class="placeholder"
/>
</div>
<button class="btn" @click="sendEmail">发送</button>
</div>
</view>
</template>
@@ -348,6 +363,8 @@
} from '@/constant/aiText';
import { praiseTextApi } from '@/sheep/api/doubao';
const email = ref('');
const {
// praiseTextApi,
getStyleApi,
@@ -359,6 +376,7 @@
getAiFaceResult,
getUserInfo,
getUserAvatar,
sendMail,
} = ReportApi;
const collect = ref(null);
@@ -864,12 +882,45 @@
}
activeTab.value = tabIndex;
}
const dialog = ref({
visible: false,
});
const openEmailDialog = () => {
console.log('openEmailDialog: ');
dialog.value.visible = true;
};
const sendEmail = async () => {
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
if (!emailRegex.test(email.value)) {
uni.showToast({ title: '请输入正确的邮箱', icon: 'none' });
return;
}
const res = await sendMail({
timeout: 100 * 1000,
pageUrl: window.location.href,
email: email.value,
});
if (res.data.code == 0) {
dialog.value.visible = false;
email.value = '';
uni.showToast({ title: '已经进入发送队列,稍后请查收邮件', icon: 'none' });
}
};
</script>
<style>
.report {
padding: 20px 20px 0;
}
.report-title {
font-family: 'PingFang SC', 'Microsoft YaHei', 'Arial', sans-serif !important;
font-weight: 400;
@@ -877,6 +928,7 @@
line-height: 28px !important;
letter-spacing: 0px;
}
.report-title-en {
font-family: 'PingFang SC', 'Microsoft YaHei', 'Arial', sans-serif !important;
font-weight: 400;
@@ -885,57 +937,69 @@
letter-spacing: 0px;
color: rgba(216, 216, 216, 1);
}
.padding-top20 {
padding: 20px 20px 0;
}
.color-tab-content {
display: flex;
flex-direction: column;
align-items: center;
}
.color-img {
width: 100%;
max-width: 400px;
border-radius: 8px;
margin-bottom: 12px;
}
.color-desc {
text-align: center;
color: #666;
font-size: 16px;
}
.title {
padding: 0 20px;
}
.swiper-container {
position: relative;
}
.avatar-box {
display: flex;
position: absolute;
width: 100%;
height: 235px;
}
.avatar {
position: absolute;
width: 235px;
height: 235px;
z-index: 9;
}
.avatar img {
/* width: 235px; */
height: 235px;
transform: scale(1.2);
}
.swiper {
width: 100%;
height: 235px;
margin-top: 20px;
}
.img-box {
width: 235px;
position: relative;
}
.btn {
position: absolute;
z-index: 999;
@@ -946,13 +1010,16 @@
align-items: center;
justify-content: center;
}
.btn img {
width: 32px;
height: 32px;
}
.left-btn {
left: 0;
}
.right-btn {
right: 0;
}
@@ -966,6 +1033,7 @@
justify-content: center;
/* background-color: red; */
}
.swiper-instructions {
display: flex;
flex-direction: column;
@@ -973,6 +1041,7 @@
/* justify-content: center; */
padding-top: 10px;
}
.swiper-type-name {
font-family: 'PingFang SC', 'Microsoft YaHei', 'Arial', sans-serif !important;
font-weight: 400;
@@ -980,6 +1049,7 @@
line-height: 28px !important;
letter-spacing: 94%;
}
.swiper-type-name-en {
font-family: 'PingFang SC', 'Microsoft YaHei', 'Arial', sans-serif !important;
font-weight: 400;
@@ -990,6 +1060,7 @@
color: rgba(216, 216, 216, 1);
margin-top: 5px;
}
.swiper-type-text {
font-family: 'PingFang SC', 'Microsoft YaHei', 'Arial', sans-serif !important;
font-weight: 400;
@@ -998,6 +1069,7 @@
letter-spacing: 0%;
margin-top: 5px;
}
.image {
width: 100%;
}
@@ -1009,14 +1081,17 @@
line-height: 28px !important;
letter-spacing: 0% !important;
}
.reference-title {
width: 100%;
height: 17px;
}
.reference-title img {
width: 100%;
height: 17px;
}
.reference-img-box {
height: 195.5px;
margin-top: 20px;
@@ -1024,14 +1099,17 @@
justify-content: space-between;
margin-bottom: 30px;
}
.reference-img-box .reference-img1 {
width: 100%;
height: 195.5px;
}
.reference-img-box .reference-img2 {
width: 45px;
height: 165px;
}
.reference-complate {
width: 100%;
height: 21px;
@@ -1047,6 +1125,7 @@
color: rgba(216, 216, 216, 1);
margin: 20px 0;
}
.avatar-warp {
width: 100%;
height: 192px;
@@ -1054,6 +1133,7 @@
align-items: center;
justify-content: center;
}
.avatar-main {
width: 116px;
height: 160px;
@@ -1061,11 +1141,13 @@
border-radius: 40px;
overflow: hidden;
}
.avatar-main img {
width: 100%;
height: 100%;
object-fit: cover;
}
.avatar-side {
width: 80px;
height: 120px;
@@ -1073,28 +1155,34 @@
border-radius: 40px;
overflow: hidden;
}
.avatar-side img {
width: 100%;
height: 100%;
object-fit: cover;
}
.rich-text-content {
padding: 0 20px 20px;
}
.face-img-box {
width: 336px;
height: 338px;
}
.face-img-box img {
width: 100%;
height: 100%;
/* border-radius: 8px; */
}
.more-hairstyle {
width: 100%;
/* height: 135px; */
margin-top: 20px;
}
.more-hairstyle img {
width: 100%;
height: 100%;
@@ -1105,18 +1193,22 @@
min-height: 950px;
/* overflow-y: hidden; */
}
.shengxiao {
width: 100%;
height: 283px;
}
.shengxiao img {
width: 100%;
height: 100%;
}
.five-attribute-box {
position: relative;
/* margin-bottom: 20px; */
}
.numblock {
width: 50px;
height: 50px;
@@ -1128,15 +1220,18 @@
color: white;
z-index: 999;
}
.five-attribute {
width: 100%;
/* height: 597px; */
position: relative;
}
.five-attribute img {
width: 100%;
height: 100%;
}
.avatorLogo {
position: absolute;
left: 50%;
@@ -1149,11 +1244,13 @@
overflow: hidden;
border: 3.22px solid rgba(167, 178, 179, 1);
}
.avatorLogo img {
width: 100%;
height: 100%;
object-fit: cover;
}
.style-type {
line-height: 28px !important;
font-family: 'Microsoft YaHei', 'Arial', sans-serif !important;
@@ -1166,6 +1263,7 @@
/* height: 900px;
background-color: red; */
}
.trends-title {
font-family: 'PingFang SC', 'Microsoft YaHei', 'Arial', sans-serif !important;
margin-bottom: 16px;
@@ -1174,15 +1272,18 @@
line-height: 28px !important;
letter-spacing: 0px;
}
.trends-img-box {
display: flex;
width: 100%;
height: 330px;
justify-content: space-between;
}
.trends-img-box1 {
width: 220px;
}
.trends-img-box1 img {
width: 100%;
height: 100%;
@@ -1194,14 +1295,17 @@
flex-direction: column;
justify-content: space-between;
}
.trends-img {
width: 102px;
height: 134px;
}
.trends-img img {
width: 100%;
height: 100%;
}
.trends-one-try-btn {
width: 102px;
height: 24px;
@@ -1218,22 +1322,29 @@
line-height: 28px !important;
letter-spacing: 0px;
}
.scroll-box {
width: 100%;
overflow-x: auto;
display: flex;
white-space: nowrap;
scrollbar-width: none; /* Firefox 隐藏滚动条 */
-ms-overflow-style: none; /* IE/Edge 隐藏滚动条 */
scrollbar-width: none;
/* Firefox 隐藏滚动条 */
-ms-overflow-style: none;
/* IE/Edge 隐藏滚动条 */
}
.scroll-box::-webkit-scrollbar {
display: none; /* Chrome/Safari/Opera 隐藏滚动条 */
display: none;
/* Chrome/Safari/Opera 隐藏滚动条 */
}
.fixed {
position: fixed;
top: 0;
z-index: 9999;
}
/* 预览遮罩层样式 */
.preview-mask {
position: fixed;
@@ -1268,6 +1379,7 @@
margin-top: 20rpx;
height: 300rpx;
.next-btn {
width: 80% !important;
height: 80rpx;
@@ -1277,4 +1389,49 @@
font-size: 32rpx;
}
}
.m-dialog {
position: fixed;
inset: 0;
background-color: rgba(0, 0, 0, 0.4);
z-index: 9999;
.m-dialog-main {
position: absolute;
left: 50%;
top: 50%;
width: 80%;
height: 50%;
background-color: white;
transform: translate(-50%, -60%);
border-radius: 15rpx;
// display: flex;
// align-items: center;
// flex-direction: column;
// justify-content: center;
padding-top: 250rpx;
box-sizing: border-box;
padding-left: 30rpx;
.email {
// font-size: 35rpx;
display: flex;
}
.placeholder {
font-size: 35rpx;
line-height: 1;
}
.btn {
width: 80% !important;
height: 80rpx;
border-radius: 16rpx;
margin-top: 50rpx;
background-color: #0d232c;
color: white;
font-size: 32rpx;
}
}
}
</style>
+48
View File
@@ -1,4 +1,5 @@
import request from '@/sheep/request';
import Request from 'luch-request';
const ReportApi = {
getHairApi: (data) => {
@@ -81,6 +82,53 @@ const ReportApi = {
method: 'get',
}),
// sendMail: () =>
// request({
// url: '/sendMail',
// method: 'post',
// }),
sendMail: (data) => {
// const init = () => {
// const http = new Request({
// baseURL: 'http://42.193.102.139:4000/api/pdf',
// timeout: 100 * 1000,
// method: 'POST',
// header: {
// Accept: 'text/json',
// 'Content-Type': 'application/json;charset=UTF-8',
// },
// // #ifdef H5
// // 跨域请求时是否携带凭证(cookies)仅H5支持(HBuilderX 2.6.15+
// withCredentials: false,
// // #endif
// });
// return http;
// };
const http = new Request({
baseURL: 'http://42.193.102.139:4000/api/pdf',
timeout: 100 * 1000,
method: 'GET',
header: {
Accept: 'text/json',
'Content-Type': 'application/json;charset=UTF-8',
Authorization: 'Bearer 14fc0280-fc65-462d-ac2d-50178c0212e3',
},
// #ifdef H5
// 跨域请求时是否携带凭证(cookies)仅H5支持(HBuilderX 2.6.15+
withCredentials: false,
// #endif
});
// const http = init();
return http.request({
method: 'POST',
data,
});
},
// https://puton.huimeimeta.com/app-api/cloth/getFaceList
};
export default ReportApi;