Merge branch 'feature_231027' into dev

dev
bruce68410 3 years ago
commit 19b067628d

@ -4,9 +4,9 @@ VITE_ENV = development
VITE_APP_BASE_URL = https://utel.zltest.com.tw VITE_APP_BASE_URL = https://utel.zltest.com.tw
VITE_APP_LINE_LIFF_ID = 1656907652-p38ddKzQ VITE_APP_LINE_LIFF_ID = 2000917272-PBWoXdOl
VITE_APP_SEND_URL = https://liff.line.me/1656907652-VJq33Pdg VITE_APP_SEND_URL = https://liff.line.me/2000917272-PBWoXdOl
VITE_APP_API_URL = https://utel.zltest.com.tw/appapi/v1 VITE_APP_API_URL = https://utel.zltest.com.tw/appapi/v1

@ -1,18 +1,31 @@
@charset "UTF-8"; @charset "UTF-8";
@import url("https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Open+Sans:ital,wght@0,300;0,400;0,600;0,700;0,800;1,300;1,400;1,600;1,700;1,800&family=Raleway:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"); @import url("https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Open+Sans:ital,wght@0,300;0,400;0,600;0,700;0,800;1,300;1,400;1,600;1,700;1,800&family=Raleway:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap");
.text-skyBlue { .text-lightBlue {
color: #b2c4ce !important; color: #b2c4ce !important;
} }
.bg-skyBlue { .bg-lightBlue {
background-color: #b2c4ce !important; background-color: #b2c4ce !important;
} }
.bd-skyBlue { .bd-lightBlue {
border-style: solid; border-style: solid;
border-color: #b2c4ce !important; border-color: #b2c4ce !important;
} }
.text-skyBlue {
color: #5b7b94 !important;
}
.bg-skyBlue {
background-color: #5b7b94 !important;
}
.bd-skyBlue {
border-style: solid;
border-color: #5b7b94 !important;
}
.text-moBlue { .text-moBlue {
color: #486499 !important; color: #486499 !important;
} }
@ -39,17 +52,17 @@
border-color: #345068 !important; border-color: #345068 !important;
} }
.text-pink { .text-lightPink {
color: #fdebeb !important; color: #f1e6e2 !important;
} }
.bg-pink { .bg-lightPink {
background-color: #fdebeb !important; background-color: #f1e6e2 !important;
} }
.bd-pink { .bd-lightPink {
border-style: solid; border-style: solid;
border-color: #fdebeb !important; border-color: #f1e6e2 !important;
} }
.text-cherry { .text-cherry {
@ -298,23 +311,33 @@ h1, h2, h3, h4, h5, h6 {
margin: 0; margin: 0;
} }
.btn-outline-earthGold, .btn-outline-tomatoRed, .btn-outline-limeGreen, .btn-outline-cherry, .btn-outline-pink, .btn-outline-darkBlue, .btn-outline-moBlue, .btn-outline-skyBlue, .btn-earthGold, .btn-tomatoRed, .btn-limeGreen, .btn-cherry, .btn-pink, .btn-darkBlue, .btn-moBlue, .btn-skyBlue { .btn-outline-earthGold, .btn-outline-tomatoRed, .btn-outline-limeGreen, .btn-outline-cherry, .btn-outline-lightPink, .btn-outline-darkBlue, .btn-outline-moBlue, .btn-outline-skyBlue, .btn-outline-lightBlue, .btn-earthGold, .btn-tomatoRed, .btn-limeGreen, .btn-cherry, .btn-lightPink, .btn-darkBlue, .btn-moBlue, .btn-skyBlue, .btn-lightBlue {
border-radius: 3px; border-radius: 3px;
} }
.limit.btn-outline-earthGold, .limit.btn-outline-tomatoRed, .limit.btn-outline-limeGreen, .limit.btn-outline-cherry, .limit.btn-outline-pink, .limit.btn-outline-darkBlue, .limit.btn-outline-moBlue, .limit.btn-outline-skyBlue, .limit.btn-earthGold, .limit.btn-tomatoRed, .limit.btn-limeGreen, .limit.btn-cherry, .limit.btn-pink, .limit.btn-darkBlue, .limit.btn-moBlue, .limit.btn-skyBlue { .limit.btn-outline-earthGold, .limit.btn-outline-tomatoRed, .limit.btn-outline-limeGreen, .limit.btn-outline-cherry, .limit.btn-outline-lightPink, .limit.btn-outline-darkBlue, .limit.btn-outline-moBlue, .limit.btn-outline-skyBlue, .limit.btn-outline-lightBlue, .limit.btn-earthGold, .limit.btn-tomatoRed, .limit.btn-limeGreen, .limit.btn-cherry, .limit.btn-lightPink, .limit.btn-darkBlue, .limit.btn-moBlue, .limit.btn-skyBlue, .limit.btn-lightBlue {
width: 200px; width: 200px;
} }
.btn-skyBlue { .btn-lightBlue {
border: 1px solid #b2c4ce !important; border: 1px solid #b2c4ce !important;
color: #fff; color: #fff;
background-color: #b2c4ce; background-color: #b2c4ce;
} }
.btn-skyBlue:hover { .btn-lightBlue:hover {
color: #fff; color: #fff;
background-color: #93acba; background-color: #93acba;
} }
.btn-skyBlue {
border: 1px solid #5b7b94 !important;
color: #fff;
background-color: #5b7b94;
}
.btn-skyBlue:hover {
color: #fff;
background-color: #486174;
}
.btn-moBlue { .btn-moBlue {
border: 1px solid #486499 !important; border: 1px solid #486499 !important;
color: #fff; color: #fff;
@ -335,14 +358,14 @@ h1, h2, h3, h4, h5, h6 {
background-color: #233646; background-color: #233646;
} }
.btn-pink { .btn-lightPink {
border: 1px solid #fdebeb !important; border: 1px solid #f1e6e2 !important;
color: #fff; color: #fff;
background-color: #fdebeb; background-color: #f1e6e2;
} }
.btn-pink:hover { .btn-lightPink:hover {
color: #fff; color: #fff;
background-color: #f8bdbd; background-color: #e0c8c0;
} }
.btn-cherry { .btn-cherry {
@ -385,20 +408,33 @@ h1, h2, h3, h4, h5, h6 {
background-color: #ab8753; background-color: #ab8753;
} }
.btn-outline-skyBlue { .btn-outline-lightBlue {
border: 1px solid #b2c4ce; border: 1px solid #b2c4ce;
color: #b2c4ce; color: #b2c4ce;
background-color: transparent; background-color: transparent;
background-color: #fff;
} }
.btn-outline-skyBlue:hover { .btn-outline-lightBlue:hover {
color: #fff; color: #fff;
background-color: #b2c4ce; background-color: #b2c4ce;
} }
.btn-outline-skyBlue {
border: 1px solid #5b7b94;
color: #5b7b94;
background-color: transparent;
background-color: #fff;
}
.btn-outline-skyBlue:hover {
color: #fff;
background-color: #5b7b94;
}
.btn-outline-moBlue { .btn-outline-moBlue {
border: 1px solid #486499; border: 1px solid #486499;
color: #486499; color: #486499;
background-color: transparent; background-color: transparent;
background-color: #fff;
} }
.btn-outline-moBlue:hover { .btn-outline-moBlue:hover {
color: #fff; color: #fff;
@ -409,26 +445,29 @@ h1, h2, h3, h4, h5, h6 {
border: 1px solid #345068; border: 1px solid #345068;
color: #345068; color: #345068;
background-color: transparent; background-color: transparent;
background-color: #fff;
} }
.btn-outline-darkBlue:hover { .btn-outline-darkBlue:hover {
color: #fff; color: #fff;
background-color: #345068; background-color: #345068;
} }
.btn-outline-pink { .btn-outline-lightPink {
border: 1px solid #fdebeb; border: 1px solid #f1e6e2;
color: #fdebeb; color: #f1e6e2;
background-color: transparent; background-color: transparent;
background-color: #fff;
} }
.btn-outline-pink:hover { .btn-outline-lightPink:hover {
color: #fff; color: #fff;
background-color: #fdebeb; background-color: #f1e6e2;
} }
.btn-outline-cherry { .btn-outline-cherry {
border: 1px solid #E31D64; border: 1px solid #E31D64;
color: #E31D64; color: #E31D64;
background-color: transparent; background-color: transparent;
background-color: #fff;
} }
.btn-outline-cherry:hover { .btn-outline-cherry:hover {
color: #fff; color: #fff;
@ -439,6 +478,7 @@ h1, h2, h3, h4, h5, h6 {
border: 1px solid #94ac5e; border: 1px solid #94ac5e;
color: #94ac5e; color: #94ac5e;
background-color: transparent; background-color: transparent;
background-color: #fff;
} }
.btn-outline-limeGreen:hover { .btn-outline-limeGreen:hover {
color: #fff; color: #fff;
@ -449,6 +489,7 @@ h1, h2, h3, h4, h5, h6 {
border: 1px solid #f85d5d; border: 1px solid #f85d5d;
color: #f85d5d; color: #f85d5d;
background-color: transparent; background-color: transparent;
background-color: #fff;
} }
.btn-outline-tomatoRed:hover { .btn-outline-tomatoRed:hover {
color: #fff; color: #fff;
@ -459,6 +500,7 @@ h1, h2, h3, h4, h5, h6 {
border: 1px solid #BC9F75; border: 1px solid #BC9F75;
color: #BC9F75; color: #BC9F75;
background-color: transparent; background-color: transparent;
background-color: #fff;
} }
.btn-outline-earthGold:hover { .btn-outline-earthGold:hover {
color: #fff; color: #fff;
@ -498,10 +540,154 @@ h1, h2, h3, h4, h5, h6 {
display: none; display: none;
} }
.home { /* ========================================= vant ============================================= */
background-color: #f1e6e2; .van-notice-bar {
font-size: 18px;
}
.van-popup.van-toast {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
padding: 30px;
}
.van-popup.cropPopup {
display: block;
max-width: 400px;
width: 90%;
height: 430px;
top: 30%;
margin: auto;
padding: 0;
}
.van-tabs {
padding: 20px 0 0px;
}
.van-tabs .van-tabs__wrap {
height: initial !important;
}
.van-tabs .van-tabs__wrap .van-tabs__nav {
padding: 0;
background-color: transparent;
}
.van-tabs .van-tabs__wrap .van-tabs__nav .van-tab.van-tab--active .tab_item {
color: #345068;
}
.van-tabs .van-tabs__wrap .van-tabs__nav .van-tab .tab_item {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
color: #5b7b94;
}
.van-tabs .van-tabs__wrap .van-tabs__nav .van-tabs__line {
bottom: 0;
background: #345068;
}
.van-cell-group {
border-radius: 5px;
margin-bottom: 15px;
overflow: hidden;
}
.van-cell-group .van-cell {
padding: 6px 16px;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.van-cell-group .van-cell::after {
border-bottom: 1px #e3e3e3 solid;
-webkit-transform: none;
transform: none;
}
.van-cell-group .van-cell.longText .van-field__label {
width: 160px;
}
.van-cell-group .van-cell .van-field__label {
position: relative;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
padding: 4px 0;
font-weight: bold;
}
.van-cell-group .van-cell .van-field__label:before {
position: absolute;
left: -8px;
}
.van-cell-group .van-cell .van-field__label i, .van-cell-group .van-cell .van-field__label svg {
color: #5b7b94;
margin-top: 5px;
margin-right: 5px;
}
.van-cell-group .van-cell .van-field__label--top i, .van-cell-group .van-cell .van-field__label--top svg {
color: #5b7b94;
margin-top: 0px;
margin-right: 5px;
}
/* ========================================= stage ============================================= */
.content {
padding: 15px 0;
background-color: #b2c4ce;
}
.upload-main {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.upload-main .upload-img {
width: 100px;
aspect-ratio: 1/1;
border-radius: 50%;
border: 1px #d8d8d8 solid;
}
.cropper {
height: 300px;
background: #DDD;
}
.cropper-section {
margin: 0 auto;
position: fixed;
text-align: center;
top: 60px;
width: 100%;
max-width: 500px;
z-index: 8888;
}
.cropper-section .crop-area {
margin: 5 auto;
width: 100%;
}
.cropper-section .crop-btn {
background-color: #666;
text-align: center;
} }
/* ========================================= other ============================================= */
.imgCnt { .imgCnt {
position: relative; position: relative;
overflow: hidden; overflow: hidden;
@ -511,8 +697,6 @@ h1, h2, h3, h4, h5, h6 {
height: 100%; height: 100%;
-o-object-fit: cover; -o-object-fit: cover;
object-fit: cover; object-fit: cover;
-webkit-transition: all 0.3s;
transition: all 0.3s;
} }
/*! /*!

@ -1,144 +0,0 @@
.my-account {
position: relative;
width: 100%;
padding: 20px 15px;
}
.my-account .avatar {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.my-account .avatar .left {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-flex: 1;
-ms-flex: 1 0 0px;
flex: 1 0 0;
}
.my-account .avatar .left .imgCnt {
width: 80px;
height: 80px;
min-width: 80px;
border-radius: 50%;
border: 2px #fff solid;
overflow: hidden;
margin-right: 15px;
}
.my-account .avatar .left .imgCnt img {
width: 100%;
height: 100%;
-o-object-fit: cover;
object-fit: cover;
}
.my-account .avatar .left .info .name {
font-weight: bold;
color: #303a47;
}
.my-account .avatar .left .info .conpany {
margin-top: 5px;
}
.my-account .avatar .right {
-webkit-box-flex: 0;
-ms-flex: 0 0 auto;
flex: 0 0 auto;
}
.my-account .recommend {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
padding: 20px 0 10px;
}
.my-account .recommend .btn {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
width: 30%;
height: 100px;
background-color: #fff;
border-radius: 0;
}
.my-account .recommend .btn .img {
font-size: 35px;
line-height: 45px;
color: #345068;
}
.my-account .recommend .btn .text {
font-size: 16px;
font-weight: bold;
color: #345068;
}
.content {
padding: 15px;
background-color: #b2c4ce;
}
.content .card {
border: none;
margin-bottom: 15px;
}
.content .card .card-body {
padding: 5px 15px;
}
.content .card .card-body .item {
position: relative;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
width: 100%;
font-size: 15px;
}
.content .card .card-body .item + .item {
border-top: 1px solid #e3e3e3;
}
.content .card .card-body .item .left {
-webkit-box-flex: 0;
-ms-flex: 0 0 auto;
flex: 0 0 auto;
padding: 8px 0;
font-weight: bold;
}
.content .card .card-body .item .right {
-webkit-box-flex: 1;
-ms-flex: 1 0 0px;
flex: 1 0 0;
color: #666;
}
.content .card .card-body .item .right a {
color: #666;
}
.content .card .card-body .item i, .content .card .card-body .item svg {
color: #839eb6;
margin-right: 6px;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 17 KiB

@ -16,10 +16,11 @@ $radius: (
// //
$basicColor: ( $basicColor: (
skyBlue:#b2c4ce, lightBlue:#b2c4ce,
skyBlue:#5b7b94,
moBlue:#486499, moBlue:#486499,
darkBlue:#345068, darkBlue:#345068,
pink:#fdebeb, lightPink:#f1e6e2,
cherry:#E31D64, cherry:#E31D64,
mintGreen:#f2f8e7, mintGreen:#f2f8e7,
limeGreen:#94ac5e, limeGreen:#94ac5e,
@ -31,10 +32,11 @@ $basicColor: (
$textArr: $textArr:
(lightBlue, map-get($basicColor, lightBlue)),
(skyBlue, map-get($basicColor, skyBlue)), (skyBlue, map-get($basicColor, skyBlue)),
(moBlue, map-get($basicColor, moBlue)), (moBlue, map-get($basicColor, moBlue)),
(darkBlue, map-get($basicColor, darkBlue)), (darkBlue, map-get($basicColor, darkBlue)),
(pink, map-get($basicColor, pink)), (lightPink, map-get($basicColor, lightPink)),
(cherry, map-get($basicColor, cherry)), (cherry, map-get($basicColor, cherry)),
(mintGreen, map-get($basicColor, mintGreen)), (mintGreen, map-get($basicColor, mintGreen)),
(limeGreen, map-get($basicColor, limeGreen)), (limeGreen, map-get($basicColor, limeGreen)),

@ -1,8 +1,9 @@
$normalArr: $normalArr:
(lightBlue, #fff, map-get($basicColor, lightBlue), map-get($basicColor, lightBlue)),
(skyBlue, #fff, map-get($basicColor, skyBlue), map-get($basicColor, skyBlue)), (skyBlue, #fff, map-get($basicColor, skyBlue), map-get($basicColor, skyBlue)),
(moBlue, #fff, map-get($basicColor, moBlue), map-get($basicColor, moBlue)), (moBlue, #fff, map-get($basicColor, moBlue), map-get($basicColor, moBlue)),
(darkBlue, #fff, map-get($basicColor, darkBlue), map-get($basicColor, darkBlue)), (darkBlue, #fff, map-get($basicColor, darkBlue), map-get($basicColor, darkBlue)),
(pink, #fff, map-get($basicColor, pink), map-get($basicColor, pink)), (lightPink, #fff, map-get($basicColor, lightPink), map-get($basicColor, lightPink)),
(cherry, #fff, map-get($basicColor, cherry), map-get($basicColor, cherry)), (cherry, #fff, map-get($basicColor, cherry), map-get($basicColor, cherry)),
(limeGreen, #fff, map-get($basicColor, limeGreen), map-get($basicColor, limeGreen)), (limeGreen, #fff, map-get($basicColor, limeGreen), map-get($basicColor, limeGreen)),
(tomatoRed, #fff, map-get($basicColor, tomatoRed), map-get($basicColor, tomatoRed)), (tomatoRed, #fff, map-get($basicColor, tomatoRed), map-get($basicColor, tomatoRed)),
@ -10,10 +11,11 @@ $normalArr:
; ;
$outlineArr: $outlineArr:
(lightBlue, 1px, map-get($basicColor, lightBlue), transparent, map-get($basicColor, lightBlue)),
(skyBlue, 1px, map-get($basicColor, skyBlue), transparent, map-get($basicColor, skyBlue)), (skyBlue, 1px, map-get($basicColor, skyBlue), transparent, map-get($basicColor, skyBlue)),
(moBlue, 1px, map-get($basicColor, moBlue), transparent, map-get($basicColor, moBlue)), (moBlue, 1px, map-get($basicColor, moBlue), transparent, map-get($basicColor, moBlue)),
(darkBlue, 1px, map-get($basicColor, darkBlue), transparent, map-get($basicColor, darkBlue)), (darkBlue, 1px, map-get($basicColor, darkBlue), transparent, map-get($basicColor, darkBlue)),
(pink, 1px, map-get($basicColor, pink), transparent, map-get($basicColor, pink)), (lightPink, 1px, map-get($basicColor, lightPink), transparent, map-get($basicColor, lightPink)),
(cherry, 1px, map-get($basicColor, cherry), transparent, map-get($basicColor, cherry)), (cherry, 1px, map-get($basicColor, cherry), transparent, map-get($basicColor, cherry)),
(limeGreen, 1px, map-get($basicColor, limeGreen), transparent, map-get($basicColor, limeGreen)), (limeGreen, 1px, map-get($basicColor, limeGreen), transparent, map-get($basicColor, limeGreen)),
(tomatoRed, 1px, map-get($basicColor, tomatoRed), transparent, map-get($basicColor, tomatoRed)), (tomatoRed, 1px, map-get($basicColor, tomatoRed), transparent, map-get($basicColor, tomatoRed)),
@ -32,6 +34,7 @@ $outlineArr:
@each $class, $bdWidth, $color, $bgColor, $bdColor in $outlineArr { @each $class, $bdWidth, $color, $bgColor, $bdColor in $outlineArr {
.btn-outline-#{"" + $class} { .btn-outline-#{"" + $class} {
@include outlineBtn($bdWidth, $color, $bgColor, $bdColor); @include outlineBtn($bdWidth, $color, $bgColor, $bdColor);
background-color: #fff;
} }
} }

@ -2,10 +2,143 @@
display: none; display: none;
} }
.home{ /* ========================================= vant ============================================= */
background-color: #f1e6e2;
.van-notice-bar{
font-size: 18px;
}
.van-popup{
&.van-toast{
display: flex;
justify-content: center;
align-items: center;
padding: 30px;
}
&.cropPopup{
display: block;
max-width: 400px;
width: 90%;
height: 430px;
top: 30%;
margin: auto;
padding: 0;
}
}
.van-tabs{
padding:20px 0 0px;
.van-tabs__wrap{
height:initial !important;
.van-tabs__nav{
padding:0;
background-color: transparent;
.van-tab{
&.van-tab--active{
.tab_item{
color: #345068;
}
}
.tab_item{
display: flex;
align-items: center;
flex-direction: column;
color: #5b7b94;
}
}
.van-tabs__line{
bottom:0;
background: #345068;
}
}
}
} }
.van-cell-group{
border-radius: 5px;
margin-bottom: 15px;
overflow: hidden;
.van-cell{
padding: 6px 16px;
align-items: center;
&::after{
border-bottom:1px #e3e3e3 solid;
transform: none;
}
&.longText{
.van-field__label{
width:160px;
}
}
.van-field__label{
position: relative;
display: flex;
padding: 4px 0;
font-weight: bold;
&:before{
position: absolute;
left:-8px;
}
i,svg{
color: #5b7b94;
margin-top: 5px;
margin-right: 5px;
}
}
.van-field__label--top{
i,svg{
color: #5b7b94;
margin-top: 0px;
margin-right: 5px;
}
}
}
}
/* ========================================= stage ============================================= */
.content{
padding: 15px 0;
background-color: #b2c4ce;
}
.upload-main{
display: flex;
justify-content: center;
align-items: center;
.upload-img{
width: 100px;
aspect-ratio: 1/1;
border-radius: 50%;
border:1px #d8d8d8 solid;
}
}
.cropper {
height: 300px;
background: #DDD;
}
.cropper-section{
margin: 0 auto;
position: fixed;
text-align: center;
top: 60px;
width: 100%;
max-width: 500px;
z-index: 8888;
.crop-area{
margin: 5 auto;
width: 100%;
}
.crop-btn{
background-color: #666;
text-align: center;
}
}
/* ========================================= other ============================================= */
.imgCnt{ .imgCnt{
position: relative; position: relative;
overflow: hidden; overflow: hidden;
@ -13,6 +146,14 @@
width:100%; width:100%;
height:100%; height:100%;
object-fit: cover; object-fit: cover;
transition: all .3s;
} }
} }

@ -1,109 +0,0 @@
.my-account {
position: relative;
width: 100%;
padding: 20px 15px;
.avatar{
display: flex;
justify-content: space-between;
align-items: center;
.left{
display: flex;
align-items: center;
flex: 1 0 0;
.imgCnt{
width:80px;
height: 80px;
min-width: 80px;
border-radius: 50%;
border:2px #fff solid;
overflow: hidden;
margin-right: 15px;
img{
width:100%;
height: 100%;
object-fit: cover;
}
}
.info{
.name{
font-weight: bold;
color: #303a47;
}
.conpany{
margin-top: 5px;
}
}
}
.right{
flex: 0 0 auto;
}
}
.recommend{
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 0 10px;
.btn{
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width:30%;
height: 100px;
background-color: #fff;
border-radius: 0;
.img{
font-size: 35px;
line-height: 45px;
color: #345068;
}
.text{
font-size: 16px;
font-weight: bold;
color: #345068;
}
}
}
}
.content{
padding: 15px;
background-color: #b2c4ce;
.card {
border: none;
// border-radius: 0;
margin-bottom: 15px;
.card-body{
padding: 5px 15px;
.item {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
width:100%;
font-size: 15px;
&+.item{
border-top: 1px solid #e3e3e3;
}
.left{
flex: 0 0 auto;
padding: 8px 0;
font-weight: bold;
}
.right{
flex: 1 0 0;
color: #666;
a{
color: #666;
}
}
i,svg{
color: #839eb6;
margin-right: 6px;
}
}
}
}
}

@ -243,11 +243,13 @@ const handleLogout = () => {
</script> </script>
<template> <template>
<div class="home" v-cloak> <div class="home bg-lightPink" v-cloak>
<div class="header"> <van-nav-bar class="bg-darkBlue py-3">
<h4 class="uname">UTEL電子名片系統</h4> <template #title>
<a href="javascript:;"><h5 class="umoney phone">歡迎來到會員中心</h5></a> <h4 class="text-white mb-1"><strong>UTEL電子名片系統</strong></h4>
</div> <a href="javascript:;"><h5 class="text-gray">歡迎來到會員中心</h5></a>
</template>
</van-nav-bar>
<van-notice-bar <van-notice-bar
color="#ffffff" color="#ffffff"
@ -280,8 +282,8 @@ const handleLogout = () => {
/> />
</div> </div>
<div class="info"> <div class="info">
<h4 class="name">{{ userInfo.real_name }}</h4> <h3 class="name">{{ userInfo.real_name }}</h3>
<h6 class="conpany">{{ userInfo.company }}</h6> <h5 class="conpany">{{ userInfo.company }}</h5>
</div> </div>
</div> </div>
<div class="right"> <div class="right">
@ -295,15 +297,15 @@ const handleLogout = () => {
</div> </div>
<div class="recommend"> <div class="recommend">
<div class="btn btn-outline-skyBlue" @click="router.push('/shop')"> <div class="btn btn-outline-lightBlue" @click="router.push('/shop')">
<div class="img"><i class="fa-solid fa-cart-arrow-down"></i></div> <div class="img"><i class="fa-solid fa-cart-arrow-down"></i></div>
<div class="text">立即開通</div> <div class="text">立即開通</div>
</div> </div>
<div class="btn btn-outline-skyBlue" @click="goCardEdit"> <div class="btn btn-outline-lightBlue" @click="goCardEdit">
<div class="img"><i class="fa-solid fa-id-card"></i></div> <div class="img"><i class="fa-solid fa-id-card"></i></div>
<div class="text">商務卡片</div> <div class="text">商務卡片</div>
</div> </div>
<div class="btn btn-outline-skyBlue"> <div class="btn btn-outline-lightBlue">
<div class="img"><i class="fa-solid fa-address-book"></i></div> <div class="img"><i class="fa-solid fa-address-book"></i></div>
<div class="text">通訊錄</div> <div class="text">通訊錄</div>
</div> </div>
@ -317,148 +319,81 @@ const handleLogout = () => {
></a> ></a>
</div> </div>
<div class="content"> <div class="content" v-if="userInfo">
<div class="card shadow" v-if="userInfo"> <van-cell-group inset>
<div class="card-body"> <van-field :model-value="userInfo.create_time" input-align="right" readonly>
<div class="item"> <template #label><i class="fa-regular fa-fw fa-calendar-days"></i> 建立日期</template>
<div class="left"> </van-field>
<i class="fa-regular fa-fw fa-calendar-days"></i> 建立日期 <van-field :model-value="userInfo.user_id" input-align="right" readonly>
</div> <template #label><i class="fa-solid fa-fw fa-fingerprint"></i> 會員編號</template>
<div class="right text-right"> <template #button>
{{ userInfo.create_time }} <van-button size="small" @click="doCopyUid">
</div> <i class="fa-regular fa-copy"></i>
</div> </van-button>
<div class="item"> </template>
<div class="left"> </van-field>
<i class="fa-solid fa-fw fa-fingerprint"></i> 會員編號 <van-field :model-value="userInfo.level_name" input-align="right" readonly>
</div> <template #label><i class="fa-solid fa-fw fa-layer-group"></i> 會員等級</template>
<div class="right text-right"> </van-field>
<a href="javascript:;" @click="doCopyUid">{{ <van-field :model-value="overdue" input-align="right" readonly>
userInfo.user_id <template #label><i class="fa-regular fa-fw fa-calendar-check"></i> 使用期限</template>
}}</a> </van-field>
<!-- <span class="btn btn-sm btn-tomatoRed" @click="doCopyUid"></span> --> <van-field input-align="right" readonly>
</div> <template #label><i class="fa-solid fa-fw fa-qrcode"></i> QRcode</template>
</div> <template #button><van-button size="small" class="bg-darkBlue text-white border-0" @click="handleShowNfc"></van-button></template>
<div class="item"> </van-field>
<div class="left"> <van-field input-align="right" readonly>
<i class="fa-solid fa-fw fa-layer-group"></i> 會員等級 <template #label><i class="fa-solid fa-fw fa-link"></i> 名片連結</template>
</div> <template #button><van-button size="small" class="bg-tomatoRed text-white border-0" @click="doCopy"></van-button></template>
<div class="right text-right"> </van-field>
{{ userInfo.level_name }} </van-cell-group>
</div>
</div> <van-cell-group inset>
<div class="item"> <van-field :model-value="userInfo.title" input-align="right" readonly>
<div class="left"> <template #label><i class="fa-regular fa-fw fa-building"></i> 職稱</template>
<i class="fa-regular fa-fw fa-calendar-check"></i> 使用期限 </van-field>
</div> <van-field :model-value="userInfo.phone" input-align="right" readonly>
<div class="right text-right"> <template #label><i class="fa-solid fa-fw fa-mobile-retro"></i> 手機</template>
{{ overdue }} </van-field>
</div> <van-field :model-value="userInfo.tel" input-align="right" readonly>
<template #label><i class="fa-solid fa-fw fa-phone"></i> 市話</template>
<!-- <div class="col text-right" @click="router.push('/shop/inputsn')" v-if="!is_due">{{overdue}}<br/>點此輸入購買序號</div> </van-field>
<div class="col text-right input-sn" @click="router.push('/shop/inputsn')" v-else>,<br/>點此輸入購買序號</div> --> <van-field :model-value="userInfo.email" input-align="right" readonly>
</div> <template #label><i class="fa-regular fa-fw fa-envelope"></i> Email</template>
<div class="item"> </van-field>
<div class="left"> <van-field :model-value="userInfo.address" input-align="right" readonly>
<i class="fa-solid fa-fw fa-qrcode"></i> 會員QRcode <template #label><i class="fa-solid fa-fw fa-location-dot"></i> 住址</template>
</div> </van-field>
<div class="right text-right"> </van-cell-group>
<div class="btn btn-sm btn-darkBlue" @click="handleShowNfc">
開啟掃描 <van-cell-group inset>
</div> <van-field input-align="right" class="longText" readonly>
</div> <template #label><i class="fa-solid fa-fw fa-user-tie"></i> 授權商務卡片編輯</template>
</div> <template #button>
<div class="item"> <van-button size="small" @click="$router.push('/auth/auth')">
<div class="left"> 授權
<i class="fa-solid fa-fw fa-link"></i> 名片連結 </van-button>
</div> </template>
<div class="right text-right"> </van-field>
<div class="btn btn-sm btn-tomatoRed" @click="doCopy"> <van-field input-align="right" class="longText" readonly>
複製連結 <template #label><i class="fa-regular fa-fw fa-handshake"></i> 代客編輯商務卡片</template>
</div> <template #button>
</div> <van-button size="small" @click="$router.push('/auth/getauth')">
</div> 編輯
</div> </van-button>
</div> </template>
</van-field>
<div class="card shadow" v-if="userInfo"> <van-field input-align="right" class="longText" readonly>
<div class="card-body"> <template #label><i class="fa-solid fa-fw fa-award"></i> 綁定UTel淘金購會員</template>
<div class="item"> <template #button>
<div class="left"> <van-button size="small" @click="bindTggo">
<i class="fa-regular fa-fw fa-building"></i> 職稱 點擊後前往綁定
</div> </van-button>
<div class="right text-right"> </template>
{{ userInfo.title }} </van-field>
</div> <van-field input-align="right" class="longText" readonly>
</div> <template #label><i class="fa-regular fa-fw fa-paper-plane"></i> 發送名片帶廣告</template>
<div class="item"> <template #input>
<div class="left">
<i class="fa-solid fa-fw fa-mobile-retro"></i> 手機
</div>
<div class="right text-right">
{{ userInfo.phone }}
</div>
</div>
<div class="item">
<div class="left"><i class="fa-solid fa-fw fa-phone"></i> 市話</div>
<div class="right text-right">
{{ userInfo.tel }}
</div>
</div>
<div class="item">
<div class="left">
<i class="fa-regular fa-fw fa-envelope"></i> Email
</div>
<div class="right text-right">
{{ userInfo.email }}
</div>
</div>
<div class="item">
<div class="left">
<i class="fa-solid fa-fw fa-location-dot"></i> 住址
</div>
<div class="right text-right">
{{ userInfo.address }}
</div>
</div>
</div>
</div>
<div class="card shadow" v-if="userInfo">
<div class="card-body">
<div class="item">
<div class="left">
<i class="fa-solid fa-fw fa-user-tie"></i> 授權商務卡片編輯
</div>
<div class="right text-right">
<a href="javascript:;" @click="$router.push('/auth/auth')"
>授權</a
>
</div>
</div>
<div class="item">
<div class="left">
<i class="fa-regular fa-fw fa-handshake"></i> 代客編輯商務卡片
</div>
<div class="right text-right">
<a href="javascript:;" @click="$router.push('/auth/getauth')"
>編輯</a
>
</div>
</div>
<div class="item" v-if="userInfo.uniqid">
<div class="left">
<i class="fa-solid fa-fw fa-award"></i> 綁定UTel淘金購會員
</div>
<div class="right text-right">
<a href="javascript:;" @click="bindTggo"></a>
</div>
</div>
<div class="item">
<div class="left">
<i class="fa-regular fa-fw fa-paper-plane"></i> 發送名片帶廣告
</div>
<div class="right text-right">
<van-switch <van-switch
v-model="adSwitchStatus" v-model="adSwitchStatus"
@update:model-value="onUpdateValue" @update:model-value="onUpdateValue"
@ -466,10 +401,9 @@ const handleLogout = () => {
active-color="#345068" active-color="#345068"
inactive-color="#888888" inactive-color="#888888"
/> />
</div> </template>
</div> </van-field>
</div> </van-cell-group>
</div>
</div> </div>
<!-- <Footer /> --> <!-- <Footer /> -->
@ -534,7 +468,6 @@ const handleLogout = () => {
</template> </template>
<style src="@/assets/css/main.css"></style> <style src="@/assets/css/main.css"></style>
<style src="@/assets/css/page/index.css"></style>
<style lang="less" scoped> <style lang="less" scoped>
.wrapper { .wrapper {
@ -579,4 +512,73 @@ const handleLogout = () => {
} }
} }
} }
.my-account {
position: relative;
width: 100%;
padding: 20px 25px;
.avatar{
display: flex;
justify-content: space-between;
align-items: center;
.left{
display: flex;
align-items: center;
flex: 1 0 0;
.imgCnt{
width:80px;
height: 80px;
min-width: 80px;
border-radius: 50%;
border:2px #fff solid;
overflow: hidden;
margin-right: 15px;
img{
width:100%;
height: 100%;
object-fit: cover;
}
}
.info{
.name{
font-weight: bold;
color: #303a47;
}
.conpany{
margin-top: 5px;
}
}
}
.right{
flex: 0 0 auto;
}
}
.recommend{
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 0 10px;
.btn{
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width:30%;
height: 100px;
background-color: #fff;
border-radius: 0;
.img{
font-size: 35px;
line-height: 45px;
color: #345068;
}
.text{
font-size: 16px;
font-weight: bold;
color: #345068;
}
}
}
}
</style> </style>

@ -1,4 +1,4 @@
<script> <script setup>
import _ from 'lodash' import _ from 'lodash'
import axios from 'axios' import axios from 'axios'
@ -18,444 +18,531 @@ import { getUserInfo , updateCard , getMovie } from '@/api'
const URL = window.URL || window.webkitURL; const URL = window.URL || window.webkitURL;
export default { const store = useStore()
name: 'EditForm', const router = useRouter()
components: {
Footer,
Cropper
},
async setup(){
const store = useStore()
const router = useRouter()
const form = ref({addon:[]})
const fileList = ref([]);
const myCrop = ref(null)
const active = ref(0)
const showChangeIcon = ref(false)
const crop = ref({
show: false,
img: null,
})
const validatorUrl = (val) => {
if(val.length>0){
return /(https?:\/\/|line:\/\/|tel:|mailto:)\S+/.test(val)
}else{
return true
}
};
const validatorTel = (val) => {
if(val.length>0){
return /(\d{2,3}-?|\(\d{2,3}\))\d{3,4}-?\d{4}/.test(val)
}else{
return true
}
};
// onMounted(async ()=>{
let userRes = await getUserInfo()
if(userRes.code===200){
form.value = userRes.data
}else{
}
// })
if (userRes.data.nfc_addon && (userRes.data.nfc_addon.length > 0)) {
form.value.addon = JSON.parse(userRes.data.nfc_addon)
}
const onCrop = () => {
const { canvas } = myCrop.value.getResult();
if (canvas) {
const imgFile = new FormData();
canvas.toBlob(async (blob) => {
let ufile = new File([blob], "image.jpg");
imgFile.append("user_id", form.value.user_id)
imgFile.append("fileType", "IMAGE")
imgFile.append('file', ufile)
crop.value.show = false
showLoadingToast({
duration: 0,
message: '圖片上傳中...',
forbidClick: true,
});
let res = await axios.post(
`${import.meta.env.VITE_APP_API_URL}/user/uploadAvatar`,
imgFile,
{
}
)
if (res.data.code == 200) {
form.value.avatar = res.data.data
showSuccessToast('上傳成功');
}else{
showToast.fail('上傳失敗');
}
}, 'image/jpeg');
}
return
}
const onClose = () =>{
crop.value.show = false
}
const afterRead = async(file, name) => { const form = ref({addon:[]})
crop.value.show = true const activeName = ref(0)
const ofile = file.file
crop.value.img = URL.createObjectURL(ofile);
// crop.value.img = ofile
return
};
const onAddBtn = () => {
if(form.value.addon){
form.value.addon.push({icon:'',name:'',link:''})
}else{
form.value.addon = [{icon:'',name:'',link:''}]
}
}
const onDelBtn = (index) => {
form.value.addon.splice(index, 1)
}
const onMoveBtn = (type, index) => { const fileList = ref([]);
if (type === 0) {
if (index !== 0) {
[form.value.addon[index], form.value.addon[index - 1]] = [form.value.addon[index - 1], form.value.addon[index]]
}
} else {
if (index + 1 !== form.value.addon.length) {
[form.value.addon[index + 1], form.value.addon[index]] = [form.value.addon[index], form.value.addon[index + 1]]
}
}
} const myCrop = ref(null)
const onSubmit = async () => { const tabActive = ref(0)
showLoadingToast({ const tabItemObj = ref([
duration: 0, {title:"基本資料",icon:"fa-id-card-clip"},
message: '資料更新中...', {title:"社群分享",icon:"fa-share-nodes"},
forbidClick: true, {title:"人脈資訊",icon:"fa-gem"},
}); {title:"版型設定",icon:"fa-layer-group"}
]);
let res = await updateCard(form.value)
if(res.code===200){
showSuccessToast('更新成功')
store.commit('user/setUserInfo',form.value)
router.push('/')
}else{
showToast.fail('更新失敗')
}
};
return {
form,
fileList,
crop,
myCrop,
active,
showChangeIcon,
onAddBtn,
onDelBtn,
onMoveBtn,
validatorUrl,
validatorTel,
onCrop,
onClose,
afterRead,
onSubmit
}
}
}
</script>
<template> const crop = ref({
<div class="member-container"> show: false,
<van-nav-bar title="個人資料修改" right-text="" @click-right="$router.push('/')" /> img: null,
})
<van-tabs :lazy-render="true" v-model:active="active"> const validatorUrl = (val) => {
<van-tab title="基本資料"> if(val.length>0){
</van-tab> return /(https?:\/\/|line:\/\/|tel:|mailto:)\S+/.test(val)
<van-tab title="更多連結"> }else{
</van-tab> return true
</van-tabs> }
};
<van-form @submit="onSubmit">
<van-cell-group inset v-show="active === 0">
<van-field
v-model="form.real_name"
label="姓名"
name="pattern"
placeholder="請輸入您的姓名"
:rules="[{ required: true, message: '姓名為必填' }]"
/>
<van-field
v-model="form.company"
label="公司名稱"
name=""
placeholder="請輸入您的公司名稱"
:rules="[{ required: true, message: '公司名稱必填' }]"
/>
<van-field
v-model="form.title"
label="職稱"
name=""
placeholder="請輸入您的職稱"
/>
<van-field
v-model="form.phone"
label="手機"
name=""
type="tel"
placeholder="Ex. 0900000001 不要有空格"
:rules="[{ required: true, message: '手機號必填' },{ pattern: /\d{10}/ , message: '手機號格式錯誤' }]"
/>
<van-field
v-model="form.tel"
label="市話"
name=""
type="tel"
placeholder="請輸入您的市話"
:rules="[{ validator: validatorTel, message: '市話格式不正確,Ex. 02xxxx or 02-xxxx' }]"
/>
<van-field
v-model="form.email"
label="Email"
name=""
placeholder="請輸入您的Email"
:rules="[{ required: true, message: 'Email必填' },{ pattern: /^([\w\.\-]){1,64}\@([\w\.\-]){1,64}/ , message: 'Email格式錯誤' }]"
/>
<van-field
v-model="form.address"
label="住址"
name=""
placeholder="請輸入您的地址"
/>
<van-field
v-model="form.url"
label="網址"
name=""
placeholder="請輸入您的網址"
:rules="[{ validator: validatorUrl, message: '網址格式不正確,Ex. http://' }]"
/>
<van-field
v-model="form.line"
label="Line"
name=""
placeholder="請輸入您的Line ID"
/>
<van-field
v-model="form.facebook"
label="Facebook"
name=""
placeholder="請輸入您的臉書連結"
/>
<van-field
v-model="form.ig"
label="IG"
name=""
placeholder="請輸入您的IG ID"
/>
<van-field
v-model="form.youtube"
label="YouTube"
name=""
placeholder="請輸入您的Youtube連結"
/>
<van-field
v-model="form.mark"
rows="3"
autosize
label="簡介"
type="textarea"
maxlength="100"
placeholder="請輸入簡介"
show-word-limit
/>
<van-uploader
:after-read="afterRead"
:max-count="1"
name="averter"
>
<div class="upload-main">
<img class="upload-img" :src="form.avatar" alt="">
<p>上傳圖片</p>
</div>
</van-uploader>
</van-cell-group>
<van-cell-group inset v-show="active === 1" v-for="(v,idx) in form.addon" :key="idx">
<div class="act-btn">
<van-button type="primary" icon="arrow-up" plain hairline @click="onMoveBtn(0,idx)"></van-button>
<van-button type="primary" icon="arrow-down" plain hairline @click="onMoveBtn(1,idx)"></van-button>
<van-button type="danger" icon="delete-o" plain hairline @click="onDelBtn(idx)"></van-button>
</div>
<!-- <div class="field">
<div class="label">圖示</div>
<div class="content"><i class="iconfont icon-home"></i><span style="padding: 0 10px" @click="showChangeIcon=true"></span></div>
</div> -->
<van-field
label="名稱"
name=""
v-model="form.addon[idx].name"
placeholder="按鈕名稱"
/>
<van-field
label="連結"
name=""
v-model="form.addon[idx].link"
placeholder="按鈕連結"
/>
</van-cell-group>
<div class="add-btn" v-show="active === 1" @click="onAddBtn">
<van-button type="success" plain hairline>新增按鈕</van-button>
</div>
<div style="margin: 16px;">
<van-button round block type="primary" native-type="submit">
送出
</van-button>
</div>
</van-form>
<van-popup v-model:show="showChangeIcon">
<div class="icon-list">
<div class="icon-item">
<i class="iconfont icon-home" style="font-size: 40px"></i>
</div>
<div class="icon-item">
<i class="iconfont icon-home" style="font-size: 40px"></i>
</div>
<div class="icon-item">
<i class="iconfont icon-home" style="font-size: 40px"></i>
</div>
<div class="icon-item">
<i class="iconfont icon-home" style="font-size: 40px"></i>
</div>
<div class="icon-item">
<i class="iconfont icon-home" style="font-size: 40px"></i>
</div>
<div class="icon-item">
<i class="iconfont icon-home" style="font-size: 40px"></i>
</div>
<div class="icon-item">
<i class="iconfont icon-home" style="font-size: 40px"></i>
</div>
<div class="icon-item">
</div>
</div>
</van-popup>
<Footer/>
<van-overlay :show="crop.show" @click="crop.show = false" />
<div class="cropper-section" v-if="crop.show">
<div class="crop-area">
<cropper
class="cropper"
ref="myCrop"
:src="crop.img"
:stencil-props="{
aspectRatio: 1/1
}"
:auto-zoom="true"
/>
</div>
<div class="crop-btn">
<van-button type="primary" size="small" plain @click="onClose"></van-button>
<van-button type="success" size="small" plain @click="onCrop"></van-button>
</div>
</div>
</div> const validatorTel = (val) => {
</template> if(val.length>0){
return /(\d{2,3}-?|\(\d{2,3}\))\d{3,4}-?\d{4}/.test(val)
}else{
return true
}
};
// onMounted(async ()=>{
let userRes = await getUserInfo()
if(userRes.code===200){
form.value = userRes.data
console.log(form);
}else{
<style lang="less" scoped> }
.container{ // })
padding-bottom: 30px; if (userRes.data.nfc_addon && (userRes.data.nfc_addon.length > 0)) {
} form.value.addon = JSON.parse(userRes.data.nfc_addon)
.title{
font-size: 20px;
text-align: center;
} }
.upload-img{ const onCrop = () => {
width: 80px; const { canvas } = myCrop.value.getResult();
} if (canvas) {
const imgFile = new FormData();
canvas.toBlob(async (blob) => {
let ufile = new File([blob], "image.jpg");
imgFile.append("user_id", form.value.user_id)
imgFile.append("fileType", "IMAGE")
imgFile.append('file', ufile)
crop.value.show = false
showLoadingToast({
duration: 0,
message: '圖片上傳中...',
forbidClick: true,
});
let res = await axios.post(
`${import.meta.env.VITE_APP_API_URL}/user/uploadAvatar`,
imgFile,
{
}
)
.cropper { if (res.data.code == 200) {
height: 300px; form.value.avatar = res.data.data
// width: 300px; showSuccessToast('上傳成功');
background: #DDD; }else{
} showToast.fail('上傳失敗');
}
.cropper-section{ }, 'image/jpeg');
margin: 0 auto;
position: fixed;
text-align: center;
top: 50px;
// left: 0;
height: 350px;
width: 100%;
max-width: 500px;
background: #DDD;
z-index: 8888;
.crop-area{
margin: 5 auto;
width: 100%;
height: 330px;
}
.crop-btn{
background-color: #666;
text-align: center;
} }
return
} }
.act-btn{ const onClose = () =>{
text-align: center; crop.value.show = false
} }
.add-btn{ const afterRead = async(file, name) => {
margin: 0 16px; crop.value.show = true
padding: 10px 16px;
} const ofile = file.file
crop.value.img = URL.createObjectURL(ofile);
// crop.value.img = ofile
return
};
.field{ const onAddBtn = () => {
display: flex; if(form.value.addon){
// margin: 0 16px; form.value.addon.push({icon:'',name:'',link:''})
padding: 10px 16px; }else{
.label{ form.value.addon = [{icon:'',name:'',link:''}]
width: var(--van-field-label-width);
margin-right: var(--van-field-label-margin-right);
color: var(--van-field-label-color);
} }
} }
.icon-list{ const onDelBtn = (index) => {
display: flex; form.value.addon.splice(index, 1)
width: 280px; }
flex-wrap: wrap;
justify-content: center; const onMoveBtn = (type, index) => {
align-items: center; if (type === 0) {
.icon-item{ if (index !== 0) {
// flex:1; [form.value.addon[index], form.value.addon[index - 1]] = [form.value.addon[index - 1], form.value.addon[index]]
width: 70px; }
text-align: center; } else {
} if (index + 1 !== form.value.addon.length) {
[form.value.addon[index + 1], form.value.addon[index]] = [form.value.addon[index], form.value.addon[index + 1]]
}
}
} }
const onSubmit = async () => {
showLoadingToast({
duration: 0,
message: '資料更新中...',
forbidClick: true,
});
let res = await updateCard(form.value)
if(res.code===200){
showSuccessToast('更新成功')
store.commit('user/setUserInfo',form.value)
router.push('/')
}else{
showToast.fail('更新失敗')
}
};
</script>
<template>
<div class="member bg-lightPink">
<van-nav-bar class="bg-skyBlue py-1" left-arrow @click-left="$router.push('/')">
<template #title>
<h5 class="text-white mb-1"><strong>會員資料</strong></h5>
</template>
<template #left>
<h4><i class="fa-solid fa-angle-left text-white" :style="{opacity:0.5}"></i></h4>
</template>
</van-nav-bar>
<van-tabs class="van-tabs" :lazy-render="true" v-model:active="tabActive">
<van-tab v-for="(item,index) in tabItemObj" :key="index">
<template #title>
<div class="tab_item">
<i :class="`fa-solid ${item.icon} fa-2x mb-1`"></i>
<p class="mb-3">{{item.title}}</p>
</div>
</template>
</van-tab>
</van-tabs>
<div class="content" v-show="tabActive === 0">
<van-cell-group inset>
<van-form @submit="onSubmit">
<div class="text-center p-4">
<van-uploader :after-read="afterRead" :max-count="1" name="averter" class="mb-4">
<div class="upload-main">
<img
class="upload-img"
:src="form.avatar"
alt=""
v-if="form.avatar"
/>
<img
class="upload-img"
src="@/assets/images/upload.jpg"
alt=""
v-else
/>
<div class="ml-3">
<p class="text-skyBlue mb-2">上傳圖片預設為Line頭像</p>
<van-button class="btn-darkBlue" icon="plus" block size="small">上傳檔案</van-button>
</div>
</div>
</van-uploader>
<van-field
v-model="form.mark"
rows="3"
type="textarea"
maxlength="100"
placeholder="請輸入100字以內的簡介"
show-word-limit
:style="{border:'1px #e3e3e3 solid',borderRadius:'6px'}"
/>
</div>
<van-field
v-model="form.real_name"
label="姓名"
name="pattern"
placeholder="請輸入您的姓名"
:rules="[{ required: true, message: '姓名為必填' }]"
/>
<van-field
v-model="form.company"
label="公司名稱"
name=""
placeholder="請輸入您的公司名稱"
:rules="[{ required: true, message: '公司名稱必填' }]"
/>
<van-field
v-model="form.title"
label="職稱"
name=""
placeholder="請輸入您的職稱"
/>
<van-field
v-model="form.phone"
label="手機"
name=""
type="tel"
placeholder="Ex. 0900000001 不要有空格"
:rules="[{ required: true, message: '手機號必填' },{ pattern: /\d{10}/ , message: '手機號格式錯誤' }]"
/>
<van-field
v-model="form.tel"
label="市話"
name=""
type="tel"
placeholder="請輸入您的市話"
:rules="[{ validator: validatorTel, message: '市話格式不正確,Ex. 02xxxx or 02-xxxx' }]"
/>
<van-field
v-model="form.email"
label="Email"
name=""
placeholder="請輸入您的Email"
:rules="[{ required: true, message: 'Email必填' },{ pattern: /^([\w\.\-]){1,64}\@([\w\.\-]){1,64}/ , message: 'Email格式錯誤' }]"
/>
<van-field
v-model="form.address"
label="住址"
name=""
placeholder="請輸入您的地址"
/>
<van-field
v-model="form.url"
label="年齡"
name=""
placeholder="請輸入您的年齡"
/>
<van-field name="radio" label="性別">
<template #input>
<van-radio-group v-model="checked" direction="horizontal">
<van-radio name="1"></van-radio>
<van-radio name="2"></van-radio>
</van-radio-group>
</template>
</van-field>
<van-field
v-model="fieldValue"
is-link
readonly
label="區域"
placeholder="請選擇縣市區域"
@click="show = true"
/>
<van-popup v-model:show="show" round position="bottom">
<van-cascader
v-model="cascaderValue"
title="請選擇縣市區域"
:options="options"
@close="show = false"
@finish="onFinish"
/>
</van-popup>
<van-field
v-model="fieldValue"
is-link
readonly
label="工作性質"
placeholder="請選擇工作性質"
@click="show = true"
/>
<van-popup v-model:show="show" round position="bottom">
<van-cascader
v-model="cascaderValue"
title="請選擇工作性質"
:options="options"
@close="show = false"
@finish="onFinish"
/>
</van-popup>
<van-field readonly>
<template #label>是否公開<br/>資料搜尋</template>
<template #input>
<van-switch
v-model="adSwitchStatus"
@update:model-value="onUpdateValue"
size="18px"
active-color="#345068"
inactive-color="#888888"
/>
</template>
</van-field>
<div class="p-5">
<van-button block class="btn-darkBlue" native-type="submit">
確認修改
</van-button>
</div>
</van-form>
</van-cell-group>
<van-cell-group inset>
<van-form @submit="onSubmit12">
<van-nav-bar class="bg-lightPink">
<template #title>
<h6 class="text-darkBlue"><strong>人脈資訊</strong></h6>
</template>
</van-nav-bar>
<van-field
name="pattern"
placeholder="請輸入簡短的自我介紹"
label-align="top"
>
<template #label>
<h6><i class="fa-regular fa-gem text-darkBlue"></i> 一句話介紹自己</h6>
</template>
</van-field>
<van-collapse v-model="activeName" accordion>
<van-collapse-item name="1">
<template #title>
<h6><i class="fa-regular fa-gem text-darkBlue"></i> 我能分享的資源</h6>
</template>
<van-field
rows="3"
type="textarea"
maxlength="100"
placeholder="請填寫能分享的資源"
show-word-limit
>
</van-field>
<van-field
name="pattern"
placeholder="分享網址"
/>
</van-collapse-item>
<van-collapse-item title="标题2" name="2">
技术无非就是那些开发它的人的共同灵魂
</van-collapse-item>
<van-collapse-item title="标题3" name="3">
在代码阅读过程中人们说脏话的频率是衡量代码质量的唯一标准
</van-collapse-item>
</van-collapse>
</van-form>
</van-cell-group>
</div>
<!-- <div class="content" v-show="tabActive === 1" v-for="(v,idx) in form.addon" :key="idx"> -->
<div class="content" v-show="tabActive === 1">
<van-cell-group inset>
<van-form @submit="onSubmit2">
<van-field
v-model="form.real_name"
label="姓名"
name="pattern"
placeholder="請輸入您的姓名"
:rules="[{ required: true, message: '姓名為必填' }]"
/>
<van-field
v-model="form.company"
label="公司名稱"
name=""
placeholder="請輸入您的公司名稱"
:rules="[{ required: true, message: '公司名稱必填' }]"
/>
<van-field
v-model="form.title"
label="職稱"
name=""
placeholder="請輸入您的職稱"
/>
<van-field
v-model="form.phone"
label="手機"
name=""
type="tel"
placeholder="Ex. 0900000001 不要有空格"
:rules="[{ required: true, message: '手機號必填' },{ pattern: /\d{10}/ , message: '手機號格式錯誤' }]"
/>
<van-field
v-model="form.tel"
label="市話"
name=""
type="tel"
placeholder="請輸入您的市話"
:rules="[{ validator: validatorTel, message: '市話格式不正確,Ex. 02xxxx or 02-xxxx' }]"
/>
<van-field
v-model="form.email"
label="Email"
name=""
placeholder="請輸入您的Email"
:rules="[{ required: true, message: 'Email必填' },{ pattern: /^([\w\.\-]){1,64}\@([\w\.\-]){1,64}/ , message: 'Email格式錯誤' }]"
/>
<van-field
v-model="form.address"
label="住址"
name=""
placeholder="請輸入您的地址"
/>
<van-field
v-model="form.url"
label="年齡"
name=""
placeholder="請輸入您的年齡"
/>
<div class="p-5">
<van-button block class="btn-darkBlue" native-type="submit">
確認修改
</van-button>
</div>
</van-form>
</van-cell-group>
<!-- <van-cell-group inset>
<div class="text-center">
<van-button type="primary" icon="arrow-up" plain hairline @click="onMoveBtn(0,idx)"></van-button>
<van-button type="primary" icon="arrow-down" plain hairline @click="onMoveBtn(1,idx)"></van-button>
<van-button type="danger" icon="delete-o" plain hairline @click="onDelBtn(idx)"></van-button>
</div>
<van-field
label="名稱"
name=""
v-model="form.addon[idx].name"
placeholder="按鈕名稱"
/>
<van-field
label="連結"
name=""
v-model="form.addon[idx].link"
placeholder="按鈕連結"
/>
<div class="add-btn" @click="onAddBtn">
<van-button type="success" plain hairline>新增按鈕</van-button>
</div>
</van-cell-group> -->
</div>
<div class="content" v-show="tabActive === 2">
<van-cell-group inset>
<form action="/">
<van-search
v-model="value"
show-action
placeholder="请输入搜索关键词"
@search="onSearch"
@cancel="onCancel"
/>
<van-list
v-model:loading="loading"
:finished="finished"
finished-text="没有更多了"
@load="onLoad"
>
<van-cell v-for="item in list" :key="item" :title="item" />
</van-list>
</form>
</van-cell-group>
</div>
<div class="content" v-show="tabActive === 3">
<van-cell-group inset>
test3
</van-cell-group>
</div>
<!-- <Footer/> -->
<van-popup class="cropPopup" v-model:show="crop.show" closeable>
<h5 class="text-center mt-3">檔案裁切上傳</h5>
<div class="cropper-section">
<div class="crop-area">
<cropper
class="cropper"
ref="myCrop"
:src="crop.img"
:stencil-props="{
aspectRatio: 1 / 1,
}"
:auto-zoom="true"
/>
</div>
<van-button round class="btn-tomatoRed rounded-pill w-50 mt-3" size="small" @click="onCrop">
裁切確認
</van-button>
</div>
</van-popup>
</div>
</template>
<style src="@/assets/css/main.css"></style>
<style lang="less" scoped>
</style> </style>

@ -0,0 +1,461 @@
<script>
import _ from 'lodash'
import axios from 'axios'
import { ref , nextTick} from 'vue'
import { Cropper } from 'vue-advanced-cropper';
import 'vue-advanced-cropper/dist/style.css';
import Footer from '@/components/Footer.vue'
import { useStore } from 'vuex'
import { useRouter } from 'vue-router'
import { showToast } from 'vant'
import { showLoadingToast,showSuccessToast } from 'vant';
import { getUserInfo , updateCard , getMovie } from '@/api'
const URL = window.URL || window.webkitURL;
export default {
name: 'EditForm',
components: {
Footer,
Cropper
},
async setup(){
const store = useStore()
const router = useRouter()
const form = ref({addon:[]})
const fileList = ref([]);
const myCrop = ref(null)
const active = ref(0)
const showChangeIcon = ref(false)
const crop = ref({
show: false,
img: null,
})
const validatorUrl = (val) => {
if(val.length>0){
return /(https?:\/\/|line:\/\/|tel:|mailto:)\S+/.test(val)
}else{
return true
}
};
const validatorTel = (val) => {
if(val.length>0){
return /(\d{2,3}-?|\(\d{2,3}\))\d{3,4}-?\d{4}/.test(val)
}else{
return true
}
};
// onMounted(async ()=>{
let userRes = await getUserInfo()
if(userRes.code===200){
form.value = userRes.data
}else{
}
// })
if (userRes.data.nfc_addon && (userRes.data.nfc_addon.length > 0)) {
form.value.addon = JSON.parse(userRes.data.nfc_addon)
}
const onCrop = () => {
const { canvas } = myCrop.value.getResult();
if (canvas) {
const imgFile = new FormData();
canvas.toBlob(async (blob) => {
let ufile = new File([blob], "image.jpg");
imgFile.append("user_id", form.value.user_id)
imgFile.append("fileType", "IMAGE")
imgFile.append('file', ufile)
crop.value.show = false
showLoadingToast({
duration: 0,
message: '圖片上傳中...',
forbidClick: true,
});
let res = await axios.post(
`${import.meta.env.VITE_APP_API_URL}/user/uploadAvatar`,
imgFile,
{
}
)
if (res.data.code == 200) {
form.value.avatar = res.data.data
showSuccessToast('上傳成功');
}else{
showToast.fail('上傳失敗');
}
}, 'image/jpeg');
}
return
}
const onClose = () =>{
crop.value.show = false
}
const afterRead = async(file, name) => {
crop.value.show = true
const ofile = file.file
crop.value.img = URL.createObjectURL(ofile);
// crop.value.img = ofile
return
};
const onAddBtn = () => {
if(form.value.addon){
form.value.addon.push({icon:'',name:'',link:''})
}else{
form.value.addon = [{icon:'',name:'',link:''}]
}
}
const onDelBtn = (index) => {
form.value.addon.splice(index, 1)
}
const onMoveBtn = (type, index) => {
if (type === 0) {
if (index !== 0) {
[form.value.addon[index], form.value.addon[index - 1]] = [form.value.addon[index - 1], form.value.addon[index]]
}
} else {
if (index + 1 !== form.value.addon.length) {
[form.value.addon[index + 1], form.value.addon[index]] = [form.value.addon[index], form.value.addon[index + 1]]
}
}
}
const onSubmit = async () => {
showLoadingToast({
duration: 0,
message: '資料更新中...',
forbidClick: true,
});
let res = await updateCard(form.value)
if(res.code===200){
showSuccessToast('更新成功')
store.commit('user/setUserInfo',form.value)
router.push('/')
}else{
showToast.fail('更新失敗')
}
};
return {
form,
fileList,
crop,
myCrop,
active,
showChangeIcon,
onAddBtn,
onDelBtn,
onMoveBtn,
validatorUrl,
validatorTel,
onCrop,
onClose,
afterRead,
onSubmit
}
}
}
</script>
<template>
<div class="member-container">
<van-nav-bar title="個人資料修改" right-text="" @click-right="$router.push('/')" />
<van-tabs :lazy-render="true" v-model:active="active">
<van-tab title="基本資料">
</van-tab>
<van-tab title="更多連結">
</van-tab>
</van-tabs>
<van-form @submit="onSubmit">
<van-cell-group inset v-show="active === 0">
<van-field
v-model="form.real_name"
label="姓名"
name="pattern"
placeholder="請輸入您的姓名"
:rules="[{ required: true, message: '姓名為必填' }]"
/>
<van-field
v-model="form.company"
label="公司名稱"
name=""
placeholder="請輸入您的公司名稱"
:rules="[{ required: true, message: '公司名稱必填' }]"
/>
<van-field
v-model="form.title"
label="職稱"
name=""
placeholder="請輸入您的職稱"
/>
<van-field
v-model="form.phone"
label="手機"
name=""
type="tel"
placeholder="Ex. 0900000001 不要有空格"
:rules="[{ required: true, message: '手機號必填' },{ pattern: /\d{10}/ , message: '手機號格式錯誤' }]"
/>
<van-field
v-model="form.tel"
label="市話"
name=""
type="tel"
placeholder="請輸入您的市話"
:rules="[{ validator: validatorTel, message: '市話格式不正確,Ex. 02xxxx or 02-xxxx' }]"
/>
<van-field
v-model="form.email"
label="Email"
name=""
placeholder="請輸入您的Email"
:rules="[{ required: true, message: 'Email必填' },{ pattern: /^([\w\.\-]){1,64}\@([\w\.\-]){1,64}/ , message: 'Email格式錯誤' }]"
/>
<van-field
v-model="form.address"
label="住址"
name=""
placeholder="請輸入您的地址"
/>
<van-field
v-model="form.url"
label="網址"
name=""
placeholder="請輸入您的網址"
:rules="[{ validator: validatorUrl, message: '網址格式不正確,Ex. http://' }]"
/>
<van-field
v-model="form.line"
label="Line"
name=""
placeholder="請輸入您的Line ID"
/>
<van-field
v-model="form.facebook"
label="Facebook"
name=""
placeholder="請輸入您的臉書連結"
/>
<van-field
v-model="form.ig"
label="IG"
name=""
placeholder="請輸入您的IG ID"
/>
<van-field
v-model="form.youtube"
label="YouTube"
name=""
placeholder="請輸入您的Youtube連結"
/>
<van-field
v-model="form.mark"
rows="3"
autosize
label="簡介"
type="textarea"
maxlength="100"
placeholder="請輸入簡介"
show-word-limit
/>
<van-uploader
:after-read="afterRead"
:max-count="1"
name="averter"
>
<div class="upload-main">
<img class="upload-img" :src="form.avatar" alt="">
<p>上傳圖片</p>
</div>
</van-uploader>
</van-cell-group>
<van-cell-group inset v-show="active === 1" v-for="(v,idx) in form.addon" :key="idx">
<div class="act-btn">
<van-button type="primary" icon="arrow-up" plain hairline @click="onMoveBtn(0,idx)"></van-button>
<van-button type="primary" icon="arrow-down" plain hairline @click="onMoveBtn(1,idx)"></van-button>
<van-button type="danger" icon="delete-o" plain hairline @click="onDelBtn(idx)"></van-button>
</div>
<!-- <div class="field">
<div class="label">圖示</div>
<div class="content"><i class="iconfont icon-home"></i><span style="padding: 0 10px" @click="showChangeIcon=true"></span></div>
</div> -->
<van-field
label="名稱"
name=""
v-model="form.addon[idx].name"
placeholder="按鈕名稱"
/>
<van-field
label="連結"
name=""
v-model="form.addon[idx].link"
placeholder="按鈕連結"
/>
</van-cell-group>
<div class="add-btn" v-show="active === 1" @click="onAddBtn">
<van-button type="success" plain hairline>新增按鈕</van-button>
</div>
<div style="margin: 16px;">
<van-button round block type="primary" native-type="submit">
送出
</van-button>
</div>
</van-form>
<van-popup v-model:show="showChangeIcon">
<div class="icon-list">
<div class="icon-item">
<i class="iconfont icon-home" style="font-size: 40px"></i>
</div>
<div class="icon-item">
<i class="iconfont icon-home" style="font-size: 40px"></i>
</div>
<div class="icon-item">
<i class="iconfont icon-home" style="font-size: 40px"></i>
</div>
<div class="icon-item">
<i class="iconfont icon-home" style="font-size: 40px"></i>
</div>
<div class="icon-item">
<i class="iconfont icon-home" style="font-size: 40px"></i>
</div>
<div class="icon-item">
<i class="iconfont icon-home" style="font-size: 40px"></i>
</div>
<div class="icon-item">
<i class="iconfont icon-home" style="font-size: 40px"></i>
</div>
<div class="icon-item">
</div>
</div>
</van-popup>
<Footer/>
<van-overlay :show="crop.show" @click="crop.show = false" />
<div class="cropper-section" v-if="crop.show">
<div class="crop-area">
<cropper
class="cropper"
ref="myCrop"
:src="crop.img"
:stencil-props="{
aspectRatio: 1/1
}"
:auto-zoom="true"
/>
</div>
<div class="crop-btn">
<van-button type="primary" size="small" plain @click="onClose"></van-button>
<van-button type="success" size="small" plain @click="onCrop"></van-button>
</div>
</div>
</div>
</template>
<style lang="less" scoped>
.container{
padding-bottom: 30px;
}
.title{
font-size: 20px;
text-align: center;
}
.upload-img{
width: 80px;
}
.cropper {
height: 300px;
// width: 300px;
background: #DDD;
}
.cropper-section{
margin: 0 auto;
position: fixed;
text-align: center;
top: 50px;
// left: 0;
height: 350px;
width: 100%;
max-width: 500px;
background: #DDD;
z-index: 8888;
.crop-area{
margin: 5 auto;
width: 100%;
height: 330px;
}
.crop-btn{
background-color: #666;
text-align: center;
}
}
.act-btn{
text-align: center;
}
.add-btn{
margin: 0 16px;
padding: 10px 16px;
}
.field{
display: flex;
// margin: 0 16px;
padding: 10px 16px;
.label{
width: var(--van-field-label-width);
margin-right: var(--van-field-label-margin-right);
color: var(--van-field-label-color);
}
}
.icon-list{
display: flex;
width: 280px;
flex-wrap: wrap;
justify-content: center;
align-items: center;
.icon-item{
// flex:1;
width: 70px;
text-align: center;
}
}
</style>

@ -1,153 +1,3 @@
<template>
<div class="reg-container">
<van-nav-bar :title="title" />
<van-form @submit="onSubmit">
<van-cell-group inset>
<van-field
v-model="form.real_name"
label="姓名"
name="pattern"
required
placeholder="請輸入您的姓名"
:rules="[{ required: true, message: '姓名為必填' }]"
/>
<van-field
v-model="form.company"
label="公司名稱"
name=""
required
placeholder="請輸入您的公司名稱"
:rules="[{ required: true, message: '公司名稱必填' }]"
/>
<van-field
v-model="form.title"
label="職稱"
name=""
placeholder="請輸入您的職稱"
/>
<van-field
v-model="form.phone"
label="手機"
name=""
required
placeholder="Ex. 0900000001 不要有空格"
:rules="[
{ required: true, message: '手機號必填' },
{ pattern: /\d{10}/, message: '手機號格式錯誤' },
]"
/>
<van-field
v-model="form.tel"
label="市話"
name=""
placeholder="請輸入您的市話"
/>
<van-field
v-model="form.email"
label="Email"
name=""
required
placeholder="請輸入您的Email"
:rules="[
{ required: true, message: 'Email必填' },
{
pattern: /^([\w\.\-]){1,64}\@([\w\.\-]){1,64}/,
message: 'Email格式錯誤',
},
]"
/>
<van-field
v-model="form.address"
label="住址"
name=""
placeholder="請輸入您的地址"
/>
<van-field
v-model="form.url"
label="網址"
name=""
placeholder="請輸入您的網址"
:rules="[
{ validator: validatorUrl, message: '網址格式不正確,Ex. http://' },
]"
/>
<van-field
v-model="form.line"
label="Line"
name=""
placeholder="請輸入您的Line ID"
/>
<van-field
v-model="form.facebook"
label="Facebook"
name=""
placeholder="請輸入您的臉書連結"
/>
<van-field
v-model="form.ig"
label="IG"
name=""
placeholder="請輸入您的IG ID"
/>
<van-field
v-model="form.youtube"
label="YouTube"
name=""
placeholder="請輸入您的Youtube連結"
/>
<van-uploader :after-read="afterRead" :max-count="1" name="averter">
<div class="upload-main">
<img
class="upload-img"
:src="form.avatar"
alt=""
v-if="form.avatar"
/>
<img
class="upload-img"
src="@/assets/images/upload.jpg"
alt=""
v-else
/>
<p>上傳圖片,預設為Line頭像</p>
</div>
</van-uploader>
</van-cell-group>
<div style="margin: 16px">
<van-button round block type="primary" native-type="submit">
送出註冊
</van-button>
<br />
<van-button round block type="default" @click="leaveReg">
以後在說
</van-button>
</div>
</van-form>
<van-overlay :show="crop.show" @click="crop.show = false" />
<div class="cropper-section" v-if="crop.show">
<div class="crop-area">
<cropper
class="cropper"
ref="myCrop"
:src="crop.img"
:stencil-props="{
aspectRatio: 1 / 1,
}"
:auto-zoom="true"
/>
</div>
<div class="crop-btn">
<van-button type="primary" size="small" plain @click="onClose"
>取消</van-button
>
<van-button type="success" size="small" plain @click="onCrop"
>剪裁</van-button
>
</div>
</div>
</div>
</template>
<script setup> <script setup>
import axios from "axios"; import axios from "axios";
@ -282,7 +132,7 @@ const onSubmit = async () => {
token: id_token, token: id_token,
...form.value, ...form.value,
}); });
console.log(regRes.code,"regRes.code")
if (regRes.code === 500) { if (regRes.code === 500) {
if (liff.isLoggedIn()) { if (liff.isLoggedIn()) {
liff.logout(); liff.logout();
@ -301,44 +151,168 @@ const onSubmit = async () => {
}; };
</script> </script>
<style lang="less" scoped> <template>
.container { <div class="reg-container bg-lightPink">
padding-bottom: 30px; <van-nav-bar class="bg-skyBlue py-2">
} <template #title>
.title { <h5 class="text-white mb-1"><strong>{{title}}</strong></h5>
font-size: 20px; </template>
text-align: center; </van-nav-bar>
}
<div class="content">
<van-form @submit="onSubmit">
<van-cell-group inset>
<div class="text-center">
<van-uploader :after-read="afterRead" :max-count="1" name="averter" class="my-4">
<div class="upload-main">
<img
class="upload-img"
:src="form.avatar"
alt=""
v-if="form.avatar"
/>
<img
class="upload-img"
src="@/assets/images/upload.jpg"
alt=""
v-else
/>
<div class="ml-3">
<p class="text-skyBlue mb-2">上傳圖片預設為Line頭像</p>
<van-button class="btn-darkBlue" icon="plus" block type="primary" size="small">上傳檔案</van-button>
</div>
</div>
</van-uploader>
</div>
.upload-img { <van-field
width: 80px; v-model="form.real_name"
} label="姓名"
name="pattern"
required
placeholder="請輸入您的姓名"
:rules="[{ required: true, message: '姓名為必填' }]"
/>
<van-field
v-model="form.company"
label="公司名稱"
name=""
required
placeholder="請輸入您的公司名稱"
:rules="[{ required: true, message: '公司名稱必填' }]"
/>
<van-field
v-model="form.title"
label="職稱"
name=""
placeholder="請輸入您的職稱"
/>
<van-field
v-model="form.phone"
label="手機"
name=""
required
placeholder="Ex. 0900000001 不要有空格"
:rules="[
{ required: true, message: '手機號必填' },
{ pattern: /\d{10}/, message: '手機號格式錯誤' },
]"
/>
<van-field
v-model="form.tel"
label="市話"
name=""
placeholder="請輸入您的市話"
/>
<van-field
v-model="form.email"
label="Email"
name=""
required
placeholder="請輸入您的Email"
:rules="[
{ required: true, message: 'Email必填' },
{
pattern: /^([\w\.\-]){1,64}\@([\w\.\-]){1,64}/,
message: 'Email格式錯誤',
},
]"
/>
<van-field
v-model="form.address"
label="住址"
name=""
placeholder="請輸入您的地址"
/>
<van-field
v-model="form.url"
label="網址"
name=""
placeholder="請輸入您的網址"
:rules="[
{ validator: validatorUrl, message: '網址格式不正確,Ex. http://' },
]"
/>
<van-field
v-model="form.line"
label="Line"
name=""
placeholder="請輸入您的Line ID"
/>
<van-field
v-model="form.facebook"
label="Facebook"
name=""
placeholder="請輸入您的臉書連結"
/>
<van-field
v-model="form.ig"
label="IG"
name=""
placeholder="請輸入您的IG ID"
/>
<van-field
v-model="form.youtube"
label="YouTube"
name=""
placeholder="請輸入您的Youtube連結"
/>
</van-cell-group>
<div class="m-3 d-flex">
<van-button round block class="btn-skyBlue rounded-pill mx-1" @click="leaveReg">
<h6>以後在說</h6>
</van-button>
<van-button round block class="btn-darkBlue rounded-pill mx-1" native-type="submit">
<h6>送出註冊</h6>
</van-button>
</div>
</van-form>
</div>
.cropper { <van-popup class="cropPopup" v-model:show="crop.show" round closeable>
height: 300px; <h5 class="text-center mt-3">檔案裁切上傳</h5>
// width: 300px; <div class="cropper-section">
background: #ddd; <div class="crop-area">
} <cropper
class="cropper"
ref="myCrop"
:src="crop.img"
:stencil-props="{
aspectRatio: 1 / 1,
}"
:auto-zoom="true"
/>
</div>
<van-button round class="btn-tomatoRed rounded-pill w-50 mt-3" size="small" @click="onCrop">
<h6>裁切確認</h6>
</van-button>
</div>
</van-popup>
</div>
</template>
<style src="@/assets/css/main.css"></style>
<style lang="less" scoped>
.cropper-section {
margin: 0 auto;
position: fixed;
text-align: center;
top: 50px;
// left: 0;
height: 350px;
width: 100%;
max-width: 500px;
background: #ddd;
z-index: 8888;
.crop-area {
margin: 5 auto;
width: 100%;
height: 330px;
}
.crop-btn {
background-color: #666;
text-align: center;
}
}
</style> </style>

@ -0,0 +1,344 @@
<template>
<div class="reg-container">
<van-nav-bar :title="title" />
<van-form @submit="onSubmit">
<van-cell-group inset>
<van-field
v-model="form.real_name"
label="姓名"
name="pattern"
required
placeholder="請輸入您的姓名"
:rules="[{ required: true, message: '姓名為必填' }]"
/>
<van-field
v-model="form.company"
label="公司名稱"
name=""
required
placeholder="請輸入您的公司名稱"
:rules="[{ required: true, message: '公司名稱必填' }]"
/>
<van-field
v-model="form.title"
label="職稱"
name=""
placeholder="請輸入您的職稱"
/>
<van-field
v-model="form.phone"
label="手機"
name=""
required
placeholder="Ex. 0900000001 不要有空格"
:rules="[
{ required: true, message: '手機號必填' },
{ pattern: /\d{10}/, message: '手機號格式錯誤' },
]"
/>
<van-field
v-model="form.tel"
label="市話"
name=""
placeholder="請輸入您的市話"
/>
<van-field
v-model="form.email"
label="Email"
name=""
required
placeholder="請輸入您的Email"
:rules="[
{ required: true, message: 'Email必填' },
{
pattern: /^([\w\.\-]){1,64}\@([\w\.\-]){1,64}/,
message: 'Email格式錯誤',
},
]"
/>
<van-field
v-model="form.address"
label="住址"
name=""
placeholder="請輸入您的地址"
/>
<van-field
v-model="form.url"
label="網址"
name=""
placeholder="請輸入您的網址"
:rules="[
{ validator: validatorUrl, message: '網址格式不正確,Ex. http://' },
]"
/>
<van-field
v-model="form.line"
label="Line"
name=""
placeholder="請輸入您的Line ID"
/>
<van-field
v-model="form.facebook"
label="Facebook"
name=""
placeholder="請輸入您的臉書連結"
/>
<van-field
v-model="form.ig"
label="IG"
name=""
placeholder="請輸入您的IG ID"
/>
<van-field
v-model="form.youtube"
label="YouTube"
name=""
placeholder="請輸入您的Youtube連結"
/>
<van-uploader :after-read="afterRead" :max-count="1" name="averter">
<div class="upload-main">
<img
class="upload-img"
:src="form.avatar"
alt=""
v-if="form.avatar"
/>
<img
class="upload-img"
src="@/assets/images/upload.jpg"
alt=""
v-else
/>
<p>上傳圖片,預設為Line頭像</p>
</div>
</van-uploader>
</van-cell-group>
<div style="margin: 16px">
<van-button round block type="primary" native-type="submit">
送出註冊
</van-button>
<br />
<van-button round block type="default" @click="leaveReg">
以後在說
</van-button>
</div>
</van-form>
<van-overlay :show="crop.show" @click="crop.show = false" />
<div class="cropper-section" v-if="crop.show">
<div class="crop-area">
<cropper
class="cropper"
ref="myCrop"
:src="crop.img"
:stencil-props="{
aspectRatio: 1 / 1,
}"
:auto-zoom="true"
/>
</div>
<div class="crop-btn">
<van-button type="primary" size="small" plain @click="onClose"
>取消</van-button
>
<van-button type="success" size="small" plain @click="onCrop"
>剪裁</van-button
>
</div>
</div>
</div>
</template>
<script setup>
import axios from "axios";
import { ref, inject } from "vue";
import store from "@/store";
import router from "@/router";
import { useRoute } from "vue-router";
import { showToast } from "vant";
import { showLoadingToast,showSuccessToast } from 'vant';
import { Cropper } from "vue-advanced-cropper";
import "vue-advanced-cropper/dist/style.css";
import { register, checkLineId } from "@/api";
const URL = window.URL || window.webkitURL;
const route = useRoute();
const form = ref({
verify: route.query.verify || null,
aid: route.query.aid || undefined,
});
const title = ref("註冊成為會員");
const myCrop = ref(null);
const crop = ref({
show: false,
img: null,
});
if (route.query.verify) {
title.value = "會員開通";
}
const validatorUrl = (val) => {
if (val.length > 0) {
return /(https?:\/\/|line:\/\/|tel:|mailto:)\S+/.test(val);
} else {
return true;
}
};
const leaveReg = () => {
window.location.replace("/error.html");
};
const onCrop = () => {
const { canvas } = myCrop.value.getResult();
if (canvas) {
const imgFile = new FormData();
canvas.toBlob(async (blob) => {
let ufile = new File([blob], "image.jpg");
imgFile.append("user_id", form.value.user_id);
imgFile.append("fileType", "IMAGE");
imgFile.append("file", ufile);
crop.value.show = false;
showLoadingToast({
duration: 0,
message: "圖片上傳中...",
forbidClick: true,
});
let res = await axios.post(
`${import.meta.env.VITE_APP_API_URL}/user/uploadAvatar`,
imgFile,
{}
);
if (res.data.code == 200) {
form.value.avatar = res.data.data;
showSuccessToast("上傳成功");
} else {
showToast.fail("上傳失敗");
}
}, "image/jpeg");
}
return;
};
const onClose = () => {
crop.value.show = false;
};
const afterRead = async (file, name) => {
crop.value.show = true;
const ofile = file.file;
crop.value.img = URL.createObjectURL(ofile);
return;
};
const onSubmit = async () => {
const liff = window.liff;
try {
if (!liff.isLoggedIn()) liff.login({ redirectUri: window.location.href });
} catch (err) {
console.log(`liff.state init error ${err}`);
showToast("登入失敗。請聯絡管理員");
router.push("/login");
}
const profile = await liff.getProfile();
let checkRes = await checkLineId(profile.userId);
if (checkRes.code !== 200) {
showToast("您已是我們的會員,請直接登入");
router.push("/login");
}
const id_token = liff.getIDToken();
showLoadingToast({
duration: 0,
message: "資料傳送中...",
forbidClick: true,
});
let regRes = await register({
line_id: profile.userId,
line_name: profile.displayName,
line_picture: profile.pictureUrl,
token: id_token,
...form.value,
});
if (regRes.code === 500) {
if (liff.isLoggedIn()) {
liff.logout();
}
showToast("line 登入已過期");
return;
} else if (regRes.code === 200) {
showToast("註冊成功");
sessionStorage.setItem("token", regRes.data.token);
sessionStorage.setItem("uid", regRes.data.uid);
return router.push("/");
} else {
showToast("註冊失敗");
return;
}
};
</script>
<style lang="less" scoped>
.container {
padding-bottom: 30px;
}
.title {
font-size: 20px;
text-align: center;
}
.upload-img {
width: 80px;
}
.cropper {
height: 300px;
// width: 300px;
background: #ddd;
}
.cropper-section {
margin: 0 auto;
position: fixed;
text-align: center;
top: 50px;
// left: 0;
height: 350px;
width: 100%;
max-width: 500px;
background: #ddd;
z-index: 8888;
.crop-area {
margin: 5 auto;
width: 100%;
height: 330px;
}
.crop-btn {
background-color: #666;
text-align: center;
}
}
</style>
Loading…
Cancel
Save