parent
f1bda3fd50
commit
29b69d5138
@ -0,0 +1,11 @@
|
||||
import liff from "@line/liff";
|
||||
|
||||
async function initLiff(app) {
|
||||
await liff.init({ liffId: process.env.VUE_APP_LINE_LIFF_ID });
|
||||
if (!liff.isLoggedIn()){
|
||||
liff.login({ redirectUri: window.location.href });
|
||||
}
|
||||
app.provide('liff', liff);
|
||||
}
|
||||
|
||||
export default initLiff;
|
||||
@ -1,330 +1,343 @@
|
||||
<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-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"
|
||||
/>
|
||||
<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>
|
||||
<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 axios from "axios";
|
||||
|
||||
import { ref, inject } from "vue";
|
||||
|
||||
import { ref } from 'vue'
|
||||
import store from "@/store";
|
||||
import router from "@/router";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
import store from '@/store'
|
||||
import router from '@/router'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { Toast } from "vant";
|
||||
|
||||
import {Toast} from 'vant'
|
||||
import { Cropper } from "vue-advanced-cropper";
|
||||
import "vue-advanced-cropper/dist/style.css";
|
||||
|
||||
import { Cropper } from 'vue-advanced-cropper';
|
||||
import 'vue-advanced-cropper/dist/style.css';
|
||||
|
||||
import { register , checkLineId } from '@/api'
|
||||
import { register, checkLineId } from "@/api";
|
||||
|
||||
const URL = window.URL || window.webkitURL;
|
||||
|
||||
const route = useRoute()
|
||||
const route = useRoute();
|
||||
|
||||
const form = ref({
|
||||
verify: route.query.verify || null,
|
||||
aid: route.query.aid || undefined
|
||||
})
|
||||
aid: route.query.aid || undefined,
|
||||
});
|
||||
|
||||
const title = ref('註冊成為會員')
|
||||
const title = ref("註冊成為會員");
|
||||
|
||||
const myCrop = ref(null)
|
||||
const myCrop = ref(null);
|
||||
|
||||
const crop = ref({
|
||||
show: false,
|
||||
img: null,
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
if(route.query.verify){
|
||||
title.value = '會員開通'
|
||||
if (route.query.verify) {
|
||||
title.value = "會員開通";
|
||||
}
|
||||
|
||||
const validatorUrl = (val) => {
|
||||
if(val.length>0){
|
||||
return /(https?:\/\/|line:\/\/|tel:|mailto:)\S+/.test(val)
|
||||
}else{
|
||||
return true
|
||||
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;
|
||||
|
||||
Toast.loading({
|
||||
duration: 0,
|
||||
message: "圖片上傳中...",
|
||||
forbidClick: true,
|
||||
});
|
||||
|
||||
let res = await axios.post(
|
||||
`${process.env.VUE_APP_API_URL}/user/uploadAvatar`,
|
||||
imgFile,
|
||||
{}
|
||||
);
|
||||
|
||||
if (res.data.code == 200) {
|
||||
form.value.avatar = res.data.data;
|
||||
Toast.success("上傳成功");
|
||||
} else {
|
||||
Toast.fail("上傳失敗");
|
||||
}
|
||||
}, "image/jpeg");
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
const leaveReg = ()=>{
|
||||
window.location.replace('/error.html')
|
||||
}
|
||||
const onClose = () => {
|
||||
crop.value.show = false;
|
||||
};
|
||||
|
||||
const afterRead = async (file, name) => {
|
||||
crop.value.show = true;
|
||||
|
||||
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
|
||||
|
||||
Toast.loading({
|
||||
duration: 0,
|
||||
message: '圖片上傳中...',
|
||||
forbidClick: true,
|
||||
});
|
||||
|
||||
let res = await axios.post(
|
||||
`${process.env.VUE_APP_API_URL}/user/uploadAvatar`,
|
||||
imgFile,
|
||||
{
|
||||
}
|
||||
)
|
||||
|
||||
if (res.data.code == 200) {
|
||||
form.value.avatar = res.data.data
|
||||
Toast.success('上傳成功');
|
||||
}else{
|
||||
Toast.fail('上傳失敗');
|
||||
}
|
||||
|
||||
}, 'image/jpeg');
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const onClose = () =>{
|
||||
crop.value.show = false
|
||||
}
|
||||
|
||||
const afterRead = async(file, name) => {
|
||||
crop.value.show = true
|
||||
|
||||
const ofile = file.file
|
||||
const ofile = file.file;
|
||||
|
||||
crop.value.img = URL.createObjectURL(ofile);
|
||||
return
|
||||
}
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
const onSubmit = async () => {
|
||||
try{
|
||||
if(!liff){
|
||||
console.log('liff is undefined')
|
||||
Toast('系統錯誤,請重新登入')
|
||||
router.push('/login')
|
||||
}
|
||||
}catch(e){
|
||||
console.log(e.message)
|
||||
Toast('系統錯誤,請重新登入')
|
||||
router.push('/login')
|
||||
|
||||
}
|
||||
|
||||
const profile = await liff.getProfile()
|
||||
const liff = window.liff;
|
||||
try {
|
||||
if (!liff.isLoggedIn()) liff.login({ redirectUri: window.location.href });
|
||||
} catch (err) {
|
||||
console.log(`liff.state init error ${err}`);
|
||||
Toast("登入失敗。請聯絡管理員");
|
||||
router.push("/login");
|
||||
}
|
||||
|
||||
let checkRes = await checkLineId(profile.userId)
|
||||
|
||||
if(checkRes.code!==200){
|
||||
Toast('您已是我們的會員,請直接登入')
|
||||
router.push('/login')
|
||||
}
|
||||
const profile = await liff.getProfile();
|
||||
|
||||
const id_token = liff.getIDToken()
|
||||
|
||||
Toast.loading({
|
||||
duration: 0,
|
||||
message: '資料傳送中...',
|
||||
forbidClick: true,
|
||||
});
|
||||
let checkRes = await checkLineId(profile.userId);
|
||||
|
||||
let regRes = await register({line_id: profile.userId, token: id_token , ...form.value})
|
||||
if (checkRes.code !== 200) {
|
||||
Toast("您已是我們的會員,請直接登入");
|
||||
router.push("/login");
|
||||
}
|
||||
|
||||
if(regRes.code === 500){
|
||||
if (liff.isLoggedIn()) {
|
||||
liff.logout();
|
||||
}
|
||||
Toast('line 登入已過期')
|
||||
// return router.push('/login')
|
||||
}else if(regRes.code === 200){
|
||||
Toast('註冊成功')
|
||||
sessionStorage.setItem('token',regRes.data.token)
|
||||
sessionStorage.setItem('uid',regRes.data.uid)
|
||||
return router.push('/')
|
||||
}else{
|
||||
Toast('註冊失敗')
|
||||
// return router.push('/login')
|
||||
const id_token = liff.getIDToken();
|
||||
|
||||
Toast.loading({
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
Toast("line 登入已過期");
|
||||
return;
|
||||
} else if (regRes.code === 200) {
|
||||
Toast("註冊成功");
|
||||
sessionStorage.setItem("token", regRes.data.token);
|
||||
sessionStorage.setItem("uid", regRes.data.uid);
|
||||
return router.push("/");
|
||||
} else {
|
||||
Toast("註冊失敗");
|
||||
return;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<style lang="less" scoped>
|
||||
.container{
|
||||
padding-bottom: 30px;
|
||||
.container {
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
.title{
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
.title {
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.upload-img{
|
||||
.upload-img {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.cropper {
|
||||
height: 300px;
|
||||
// width: 300px;
|
||||
background: #DDD;
|
||||
height: 300px;
|
||||
// width: 300px;
|
||||
background: #ddd;
|
||||
}
|
||||
|
||||
.cropper-section{
|
||||
.cropper-section {
|
||||
margin: 0 auto;
|
||||
position: fixed;
|
||||
text-align: center;
|
||||
top: 50px;
|
||||
// left: 0;
|
||||
height: 350px;
|
||||
width: 100%;
|
||||
height: 350px;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
background: #DDD;
|
||||
background: #ddd;
|
||||
z-index: 8888;
|
||||
.crop-area{
|
||||
.crop-area {
|
||||
margin: 5 auto;
|
||||
width: 100%;
|
||||
height: 330px;
|
||||
}
|
||||
.crop-btn{
|
||||
.crop-btn {
|
||||
background-color: #666;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
}
|
||||
</style>
|
||||
|
||||
Loading…
Reference in new issue