main
Wayne Hsu 3 years ago
parent f517f1b385
commit c9e2ddd6f8

@ -2,9 +2,7 @@ NODE_ENV = production
VUE_ENV = development
# VUE_APP_BASE_URL = https://localhost:8080
VUE_APP_BASE_URL = https://557d-220-129-38-157.jp.ngrok.io
VUE_APP_BASE_URL = http://localhost:8080
VUE_APP_SEND_URL = https://liff.line.me/1657876696-MKYDJKgm
@ -14,7 +12,7 @@ VUE_APP_SSO_URL = https://sso.h888.fun/api/v1
VUE_APP_IMAGE_URL = https://card.h888.fun/storage
VUE_APP_DOMAIN = 557d-220-129-38-157.jp.ngrok.io
VUE_APP_DOMAIN = localhost
VUE_APP_LINE_CLINE_ID = 1657876696

80
package-lock.json generated

@ -18,6 +18,7 @@
"lodash": "^4.17.21",
"moment": "^2.29.1",
"nprogress": "^0.2.0",
"pinia": "^2.0.35",
"pwacompat": "^2.0.17",
"qrcode.vue": "^3.3.3",
"register-service-worker": "^1.7.1",
@ -3459,9 +3460,9 @@
"dev": true
},
"node_modules/@vue/devtools-api": {
"version": "6.0.12",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.0.12.tgz",
"integrity": "sha512-iO/4FIezHKXhiDBdKySCvJVh8/mZPxHpiQrTy+PXVqJZgpTPTdHy4q8GXulaY+UKEagdkBb0onxNQZ0LNiqVhw=="
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz",
"integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
},
"node_modules/@vue/preload-webpack-plugin": {
"version": "1.1.2",
@ -11122,6 +11123,56 @@
"node": ">=6"
}
},
"node_modules/pinia": {
"version": "2.0.35",
"resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.35.tgz",
"integrity": "sha512-P1IKKQWhxGXiiZ3atOaNI75bYlFUbRxtJdhPLX059Z7+b9Z04rnTZdSY8Aph1LA+/4QEMAYHsTQ638Wfe+6K5g==",
"dependencies": {
"@vue/devtools-api": "^6.5.0",
"vue-demi": "*"
},
"funding": {
"url": "https://github.com/sponsors/posva"
},
"peerDependencies": {
"@vue/composition-api": "^1.4.0",
"typescript": ">=4.4.4",
"vue": "^2.6.14 || ^3.2.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
},
"typescript": {
"optional": true
}
}
},
"node_modules/pinia/node_modules/vue-demi": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz",
"integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/pinkie": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
@ -18780,9 +18831,9 @@
}
},
"@vue/devtools-api": {
"version": "6.0.12",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.0.12.tgz",
"integrity": "sha512-iO/4FIezHKXhiDBdKySCvJVh8/mZPxHpiQrTy+PXVqJZgpTPTdHy4q8GXulaY+UKEagdkBb0onxNQZ0LNiqVhw=="
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz",
"integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
},
"@vue/preload-webpack-plugin": {
"version": "1.1.2",
@ -24911,6 +24962,23 @@
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
"dev": true
},
"pinia": {
"version": "2.0.35",
"resolved": "https://registry.npmjs.org/pinia/-/pinia-2.0.35.tgz",
"integrity": "sha512-P1IKKQWhxGXiiZ3atOaNI75bYlFUbRxtJdhPLX059Z7+b9Z04rnTZdSY8Aph1LA+/4QEMAYHsTQ638Wfe+6K5g==",
"requires": {
"@vue/devtools-api": "^6.5.0",
"vue-demi": "*"
},
"dependencies": {
"vue-demi": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz",
"integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==",
"requires": {}
}
}
},
"pinkie": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",

@ -21,6 +21,7 @@
"lodash": "^4.17.21",
"moment": "^2.29.1",
"nprogress": "^0.2.0",
"pinia": "^2.0.35",
"pwacompat": "^2.0.17",
"qrcode.vue": "^3.3.3",
"register-service-worker": "^1.7.1",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

@ -1,6 +1,5 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">

@ -69,8 +69,8 @@ instance.interceptors.response.use(
switch (error.response.status) {
case 401:
// 返回 401 清除token資訊並跳轉到登入頁面
Cookies.remove('token',{ domain: process.env.VUE_APP_DOMAIN})
Cookies.remove('uid',{ domain: process.env.VUE_APP_DOMAIN})
Cookies.remove('token',{ domain: store.state.domain})
Cookies.remove('uid',{ domain: store.state.domain})
store.commit(types.LOGOUT);
@ -91,7 +91,7 @@ function refreshToken(response) {
let token = response.headers.authorization
if (token) {
console.log('change token')
Cookies.set('token', token , { expires: 365 ,domain: process.env.VUE_APP_DOMAIN});
Cookies.set('token', token , { expires: 365 ,domain: store.state.domain});
}
}

@ -1,4 +1,5 @@
import ajax from "./ajax";
export const login = async (params) => ajax(`/auth/login`, params, "POST", {requestBase:'sso'});
export const login = async (params) => ajax(`/auth/login`, params, "POST", { requestBase: 'sso' });
export const sendVerify = async (username) => ajax(`/auth/sendVerify`, {username}, "POST", { requestBase: 'sso' });

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

@ -64,12 +64,12 @@ export default {
const options = [
{ name: '二维码', icon: 'qrcode', key: 'qrcode' },
{ name: '分享連結', icon: 'link', key: 'link' },
{ name: 'Line', icon: 'https://card.h888.fun/images/icons/line.png', key: 'line'},
{ name: 'Facebook', icon: 'https://card.h888.fun/images/icons/facebook.png', key: 'fb'}
{ name: 'Line', icon: 'https://card.'+store.state.domain+'/images/icons/line.png', key: 'line'},
{ name: 'Facebook', icon: 'https://card.'+store.state.domain+'/images/icons/facebook.png', key: 'fb'}
];
const onSelect = (option) => {
let share_url = `https://liff.line.me/${process.env.VUE_APP_LINE_LIFF_ID}/?refer=${store.state.user.userInfo.code}`
let share_url = `https://card.${store.state.domain}/home/?refer=${store.state.user.userInfo.code}`
if (option.key === 'qrcode') {
showShareQrcode.value = true

@ -4,6 +4,7 @@ import router from "./router";
import store from "./store";
import { vant } from "@/plugins/vant";
import { VueClipboard } from "@soerenmartius/vue3-clipboard";
import "@/assets/css/normalize.css";
@ -11,16 +12,19 @@ import "@/assets/css/common.less";
import Cookies from "js-cookie";
// import './registerServiceWorker'
(function init(){
import { initStore, initSession } from './utils/init'
(async function init() {
//使用URLSearchParams API取得query string的refer參數,並寫到Cookie
const urlParams = new URLSearchParams(window.location.search);
//取得refer參數
const refer = urlParams.get('refer');
//將refer參數寫入Cookie
if(!Cookies.get('refer_code') && refer){
if (!Cookies.get('refer_code') && refer) {
Cookies.set('refer_code', refer, { expires: 1 });
}
await initStore()
})()
@ -29,4 +33,6 @@ const vue = createApp(App);
vant(vue);
vue.use(VueClipboard);
vue.use(store).use(router).mount("#app");
vue.use(store)
vue.use(router)
vue.mount("#app");

@ -149,7 +149,7 @@ router.beforeEach((to, from, next) => {
NProgress.start();
if ( to.path !== "/login" && to.path !== "/register" && to.path !== "/linelogin/" && to.path !== "/linelogin") {
if (!Cookies.get("token")) {
Toast('請重新登入,(0001)')
Toast('請重新登入')
next("/login")
}

@ -14,6 +14,7 @@ var ls = new SecureLS({
export default createStore({
state: () => ({
user_id: "",
domain: "",
config: {},
token: Cookies.get("token") || "",
}),
@ -24,6 +25,9 @@ export default createStore({
setSiteConfig(state, payload) {
state.config = payload;
},
setDomain(state, { domain }){
state.domain = domain
}
},
modules: {
user,

@ -1,3 +1,5 @@
import store from '@/store'
function genCard(vcard) {
let vcardLink;
if (vcard.url.trim().length > 0) {
@ -188,7 +190,7 @@ function genCard(vcard) {
contents: [
{
type: "image",
url: process.env.VUE_APP_BASE_URL+"/images/tpl02_bg.png",
url: "https://card."+store.state.domain+"/images/tpl02_bg.png",
size: "full",
aspectMode: "cover",
aspectRatio: "4:3",

@ -1,3 +1,5 @@
import store from '@/store'
function genCard(vcard) {
let vcardLink;
if (vcard.url.trim().length > 0) {
@ -178,7 +180,7 @@ function genCard(vcard) {
contents: [
{
type: "image",
url: process.env.VUE_APP_BASE_URL+"/images/jcibg.png",
url: "https://card."+store.state.domain+"/images/jcibg.png",
size: "full",
aspectMode: "fit",
aspectRatio: "4:3",

@ -1,3 +1,5 @@
import store from '@/store'
function genCard(vcard) {
let vcardLink;
if (vcard.url.trim().length > 0) {
@ -182,7 +184,7 @@ function genCard(vcard) {
aspectMode: "cover",
aspectRatio: "4:3",
gravity: "top",
url: process.env.VUE_APP_BASE_URL+"/images/tpl03_bg.png?v=1",
url: "https://card."+store.state.domain+"/images/tpl03_bg.png?v=1",
},
{
type: "box",

@ -1,3 +1,5 @@
import store from '@/store'
function genCard(vcard) {
let vcardLink;
if (vcard.url.trim().length > 0) {

@ -0,0 +1,36 @@
// import { v1 as uuidv1 } from 'uuid'
import Cookies from 'js-cookie'
// import { useShopStore } from "@/store/Shop"
// import { useUserStore } from "@/store/User"
// import { useCartStore } from "@/store/Cart"
import store from '@/store/index.js'
export async function initSession() {
// if(!Cookies.get('SessionId')){
// Cookies.set('SessionId',uuidv1())
// }
}
export async function initStore() {
// 獲取當前頁面的主機名
const hostname = window.location.hostname;
//判斷hostname是否為ip
const reg = /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/;
if(reg.test(hostname)){
store.commit('setDomain',{domain:hostname})
return
}
// 將主機名按照句點進行拆分
const parts = hostname.split('.');
let domain = '';
// 如果主機名包含至少 3 個部分(例如 subdomain.example.com
if (parts.length >= 3) {
// 獲取第二個部分(即 subdomain
domain = parts[1]+'.'+parts[2];
}else{
domain = hostname;
}
store.commit('setDomain',{domain})
}

@ -3,7 +3,7 @@
<div class="logo-wrap">
<!-- <i class="icon-menu icli nav-bar" @click="toggleMenu"></i> -->
<a href="###">
<img class="logo" src="@/assets/images/logo/logo_w.png" alt="logo" />
<img class="logo" src="@/assets/images/logo/logo_w.jpg" alt="logo" />
</a>
</div>
<div class="avatar-wrap" @click="$router.push('/cart')">

@ -3,7 +3,7 @@
<div class="logo-wrap">
<!-- <i class="icon-menu icli nav-bar" @click="toggleMenu"></i> -->
<a href="###">
<img class="logo" src="@/assets/images/logo/logo_w.png" alt="logo" />
<img class="logo" src="@/assets/images/logo/logo_w.jpg" alt="logo" />
</a>
</div>
<div class="avatar-wrap" @click="$router.push('/cart')">
@ -18,12 +18,17 @@
<div class="user-panel">
<div class="media">
<a href="javascript:void(0)">
<img :src="userInfo.line_picture || import('@/assets/images/user.jpg')" alt="avatar" />
<img
:src="userInfo.line_picture || import('@/assets/images/user.jpg')"
alt="avatar"
/>
</a>
<div class="media-body">
<a href="javascript:void(0)" class="title-color">
{{ userInfo.real_name }}
<span class="content-color font-sm">歡迎來到電子名片會員中心</span>
<span class="content-color font-sm"
>歡迎來到電子名片會員中心</span
>
</a>
</div>
<!-- <div class="media-right" @click="$router.push('/user/setting')"> -->
@ -32,43 +37,34 @@
</div>
<div class="user-info-block">
<div class="user-info" @click="router.push('/member')">
<div >
<div>
<i class="icon-pencil"></i>
修改資料
</div>
<div>
修改名片資料
</div>
<div>修改名片資料</div>
</div>
<div class="user-info" @click="goCardEdit">
<div>
<i class="icon-add-chart"></i>
商務卡片
</div>
<div>
設計商務卡片
</div>
<div>設計商務卡片</div>
</div>
<div class="user-info" @click="goShop">
<div>
<i class="icon-cart-variant"></i>
立即購買
</div>
<div>
付費開通名片
</div>
<div>付費開通名片</div>
</div>
<div class="user-info" @click="handleShowNfc">
<div>
<i class="icon-qrcode"></i>
展示二維碼
</div>
<div>
提供好友掃瞄
<div>提供好友掃瞄</div>
</div>
</div>
</div>
</div>
<!-- Navigation Start -->
@ -79,7 +75,7 @@
<span>會員編號</span>
</a>
<a href="javascript:;">
{{ userInfo.user_id}}
{{ userInfo.user_id }}
</a>
</li>
<li>
@ -88,7 +84,7 @@
<span>姓名</span>
</a>
<a href="javascript:;">
{{ userInfo.real_name}}
{{ userInfo.real_name }}
</a>
</li>
<li>
@ -97,7 +93,7 @@
<span>公司名稱</span>
</a>
<a href="javascript:;">
{{ userInfo.company}}
{{ userInfo.company }}
</a>
</li>
<li>
@ -106,7 +102,7 @@
<span>會員等級</span>
</a>
<a href="javascript:;">
{{ userInfo.level_name}}
{{ userInfo.level_name }}
</a>
</li>
<li>
@ -124,15 +120,24 @@
<span>名片連結</span>
</a>
<!-- <a href="javacript:void(0)"> -->
<button v-clipboard:copy="userInfo.nfcurl"
<button
v-clipboard:copy="userInfo.nfcurl"
v-clipboard:success="onSuccess"
v-clipboard:error="onError"
>複製</button>
>
複製
</button>
<!-- </a> -->
</li>
</ul>
<!-- Navigation End -->
<button class="log-out" data-bs-toggle="offcanvas" data-bs-target="#confirmation" aria-controls="confirmation" @click="handleLogout">
<button
class="log-out"
data-bs-toggle="offcanvas"
data-bs-target="#confirmation"
aria-controls="confirmation"
@click="handleLogout"
>
<i class="icon-logout icli"></i>
登出
</button>
@ -142,168 +147,129 @@
<!-- Footer Start -->
<Footer />
<!-- Footer End -->
<van-dialog v-model:show="showNfcQrcode" title="電子名片二維碼" :show-cancel-button="true" cancel-button-text=""
:show-confirm-button="false">
<van-dialog
v-model:show="showNfcQrcode"
title="電子名片二維碼"
:show-cancel-button="true"
cancel-button-text="關閉"
:show-confirm-button="false"
>
<div class="qrcode">
<qrcode-vue :value="userInfo.nfcurl" size="200" level="M" />
</div>
</van-dialog>
<!-- Pwa Install App Popup Start -->
<div
class="offcanvas offcanvas-bottom addtohome-popup"
:class="{ show: showPwaInstall }"
tabindex="-1"
id="offcanvas"
>
<div class="offcanvas-body small">
<div class="app-info">
<img src="@/assets/images/logo/logo48.png" class="img-fluid" alt="" />
<div class="content">
<h3>
SlashCard <i data-feather="x" data-bs-dismiss="offcanvas"></i>
</h3>
<a href="javascript:;">加入主畫面會讓您使用更方便喔</a>
</div>
</div>
<button
class="btn-solid install-app"
id="installApp"
@click="handlePwaInstall"
>
點擊加入主畫面
</button>
</div>
</div>
<!-- Pwa Install App Popup End -->
<!-- <div class="floating-message">
<p>加入主畫面會更加方便</p>
<button>加入主畫面</button>
</div> -->
</template>
<script setup>
import liff from "@line/liff";
import Cookies from 'js-cookie'
import moment from 'moment'
import QrcodeVue from 'qrcode.vue'
import Cookies from "js-cookie";
import moment from "moment";
import { toClipboard } from '@soerenmartius/vue3-clipboard'
import QrcodeVue from "qrcode.vue";
import { ref, computed, onBeforeMount, nextTick } from "vue";
import { useRoute, useRouter } from 'vue-router';
import { useStore } from 'vuex';
import { toClipboard } from "@soerenmartius/vue3-clipboard";
import { Toast } from 'vant'
import { Dialog } from 'vant';
import { ref, computed, onMounted, onBeforeMount, nextTick } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useStore } from "vuex";
import Footer from '@/components/Footer'
import { Toast } from "vant";
import { Dialog } from "vant";
import { linelogin , bindCard } from '@/api'
import Footer from "@/components/Footer";
import { linelogin, bindCard } from "@/api";
const router = useRouter()
const route = useRoute()
const store = useStore()
const router = useRouter();
const route = useRoute();
const store = useStore();
const showShare = ref(false)
const showShare = ref(false);
const showNfcQrcode = ref(false)
const showNfcQrcode = ref(false);
const imageUrl = ref(process.env.VUE_APP_IMAGE_URL)
const imageUrl = ref(process.env.VUE_APP_IMAGE_URL);
const userLevel = {
0: '未付費',
1: '已付費',
}
0: "未付費",
1: "已付費",
};
const is_due = ref(false)
const is_due = ref(false);
const showPwaInstall = ref(false);
const deferredPrompt = ref(null);
onBeforeMount(async () => {
// await liff.init({ liffId: process.env.VUE_APP_LINE_LIFF_ID });
// if (!Cookies.get('token')) {
// try {
// if (!liff.isLoggedIn()){
// liff.login({ redirectUri: window.location.href });
// }
// } catch (err) {
// console.log(`liff.state init error ${err}`);
// Toast(',(1001)')
// router.push('/login')
// }
// const profile = await liff.getProfile()
// const id_token = liff.getIDToken()
// let loginRes = await linelogin({ line_id: profile.userId, token: id_token })
// if (loginRes.code === 200) {
// if (route.query.act === 'openright') {
// Toast('')
// }
// Cookies.set('token', loginRes.data.token,{ expires: 365 ,domain: process.env.VUE_APP_DOMAIN})
// Cookies.set('uid', loginRes.data.uid,{ expires: 365 ,domain: process.env.VUE_APP_DOMAIN})
// } else if (loginRes.code === 202) {
// if (route.query.act === 'openright') {
// if (route.query.verify) {
// //
// Dialog.confirm({
// title: '',
// message: ''
// }).then(async ()=>{
// //
// let bindRes = await bindCard({ uid: loginRes.data.uid , verify: route.query.verify })
// if(bindRes.code === 200){
// Toast.success('')
// }else{
// Toast.fail('')
// }
// }).catch(()=>{
// })
// }
// }
// Cookies.set('token', loginRes.data.token, { expires: 365 ,domain: process.env.VUE_APP_DOMAIN})
// Cookies.set('uid', loginRes.data.uid, { expires: 365 ,domain: process.env.VUE_APP_DOMAIN})
// } else if (loginRes.code === 201) {
// if (route.query.act === 'openright') {
// if (route.query.verify) {
// router.push({
// path: '/register',
// query: {
// verify: route.query.verify
// }
// })
// return
// }
// } else if (route.query.aid) {
// router.push({
// path: '/register',
// query: {
// aid: route.query.aid
// }
// })
// return
// } else {
// Toast('')
// return router.push({
// path: '/register',
// query: { refer: route.query.refer }
// })
// }
// } else if (loginRes.code === 401) { //token
// handleLogout()
// Toast('(1002)')
// router.push('/login')
// } else {
// Toast(',(1003)')
// router.push('/login')
// }
// }
store.dispatch('user/getUserInfo')
})
store.dispatch("user/getUserInfo");
});
onMounted(() => {
if (localStorage.getItem("pwaInstall")) {
showPwaInstall.value = false;
} else {
window.addEventListener("beforeinstallprompt", (event) => {
event.preventDefault();
deferredPrompt.value = event;
showPwaInstall.value = true;
});
}
});
const userInfo = computed(() => {
return store.state.user.userInfo
})
return store.state.user.userInfo;
});
const nfcurl = computed(() => {
return encodeURI(store.state.user.userInfo.ufcurl)
})
return encodeURI(store.state.user.userInfo.ufcurl);
});
const overdue = computed(() => {
if (store.state.user.userInfo.overdue_time > 0) {
return moment.unix(store.state.user.userInfo.overdue_time).format('YYYY-MM-DD')
return moment
.unix(store.state.user.userInfo.overdue_time)
.format("YYYY-MM-DD");
} else {
return '無期限'
return "無期限";
}
})
});
const goCardEdit = () => {
router.push('/card/edit')
}
router.push("/card/edit");
};
const onSelect = (option) => {
Toast(option.name);
@ -311,83 +277,102 @@ const onSelect = (option) => {
};
const handleShowNfc = () => {
showNfcQrcode.value = true
}
showNfcQrcode.value = true;
};
const doCopy = () => {
toClipboard(userInfo.value.nfcurl)
Toast('已放入剪貼簿')
}
toClipboard(userInfo.value.nfcurl);
Toast("已放入剪貼簿");
};
const onSuccess = () => {
Toast('已放入剪貼簿')
}
Toast("已放入剪貼簿");
};
const onError = () => {
Toast('操作失敗')
}
Toast("操作失敗");
};
const doCopyUid = () => {
toClipboard(userInfo.value.user_id)
Toast('已放入剪貼簿')
}
toClipboard(userInfo.value.user_id);
Toast("已放入剪貼簿");
};
const bindTggo = () => {
console.log(userInfo.value)
console.log(userInfo.value);
let url = `https://www.tggo.com.tw/u.cgi?&mnm=mybinding&ncode=${userInfo.value.uniqid}&name=${userInfo.value.real_name}&openExternalBrowser=1`;
window.open(url,'_blank');
}
window.open(url, "_blank");
};
const handleLogout = () => {
Cookies.remove('token',{ domain: process.env.VUE_APP_DOMAIN})
Cookies.remove('uid',{ domain: process.env.VUE_APP_DOMAIN})
Cookies.remove("token", { domain: store.state.domain });
Cookies.remove("uid", { domain: store.state.domain });
// if (liff.isLoggedIn()) {
// liff.logout()
// }
router.push('/login')
}
router.push("/login");
};
const goShop = () => {
window.open('https://shop.h888.fun/m/card','_blank')
}
window.open("https://shop."+store.state.domain+"/m/card", "_blank");
};
const handlePwaInstall = () => {
const isMobile =
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
navigator.userAgent
);
if (isMobile && !window.navigator.standalone) {
window.navigator.standalone = true;
if (deferredPrompt.value) {
deferredPrompt.value.prompt();
deferredPrompt.value.userChoice.then(function (choiceResult) {
if (choiceResult.outcome === "accepted") {
console.log("User accepted the A2HS prompt");
} else {
console.log("User dismissed the A2HS prompt");
}
deferredPrompt.value = null;
});
}
// window.prompt("");
}
};
</script>
<style src="@/assets/css/style.css">
</style>
<style src="@/assets/css/style.css"></style>
<style lang="less" scoped>
.media{
.media-body{
.media {
.media-body {
width: 100%;
}
.media-right{
.media-right {
width: 100%;
vertical-align: text-top;
text-align: right;
i{
i {
font-size: 20px;
}
}
}
.user-info-block{
.user-info-block {
box-sizing: content-box;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
.user-info{
.user-info {
// flex: 1;
border: 1px gray solid;
border-radius: 8px;
margin: 5px 0;
padding: 5px 10px;
width: 48%;
div:nth-child(1){
div:nth-child(1) {
font-size: 16px;
}
div:nth-child(2){
div:nth-child(2) {
color: #999;
}
}
@ -397,4 +382,37 @@ const goShop = () => {
text-align: center;
}
.floating-message {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
padding: 10px;
background-color: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
border-radius: 4px;
z-index: 9999;
}
.floating-message p {
margin: 0 0 10px 0;
}
.floating-message button {
background-color: #4caf50;
color: #fff;
border: none;
padding: 10px;
border-radius: 4px;
}
.floating-message:before {
content: "";
position: absolute;
bottom: -20px;
left: 50%;
transform: translateX(-50%);
border: 10px solid transparent;
border-top-color: #fff;
}
</style>

@ -7,6 +7,7 @@ import axios from 'axios'
import Cookies from 'js-cookie'
import { useRoute , useRouter } from 'vue-router'
import { useStore } from 'vuex'
import { linelogin } from '@/api/index'
import { Toast } from 'vant'
@ -14,13 +15,15 @@ import { Toast } from 'vant'
const route = useRoute()
const router = useRouter()
const store = useStore()
const code = route.query.code
if(!code){
router.replace('/login')
}else{
const client_id = process.env.VUE_APP_LINE_CLINE_ID
const redirect_uri = `${process.env.VUE_APP_BASE_URL}/home/linelogin`
const redirect_uri = `https://card.${store.state.domain}/home/linelogin`
axios.post('https://api.line.me/oauth2/v2.1/token',new URLSearchParams({
grant_type: 'authorization_code',
@ -35,13 +38,13 @@ if(!code){
}).then(async (response) => {
let res = await linelogin({token:response.data.id_token})
if(res.code == 200){
Cookies.set('token', res.data.token,{ expires: 365 ,domain: process.env.VUE_APP_DOMAIN})
Cookies.set('uid', res.data.uid,{ expires: 365 ,domain: process.env.VUE_APP_DOMAIN})
Cookies.set('token', res.data.token,{ expires: 365 ,domain: store.state.domain})
Cookies.set('uid', res.data.uid,{ expires: 365 ,domain: store.state.domain})
Toast('登入成功')
router.push('/')
}else if(res.code == 201){
sessionStorage.setItem('line',JSON.stringify(response.data))
sessionStorage.setItem('reg',JSON.stringify(response.data))
router.push('/register')
}
})

@ -1,7 +1,6 @@
<template>
<!-- Main Start -->
<main class="main-wrap login-page mb-xxl">
<!-- Login Section Start -->
<section class="login-section p-0">
<!-- Login Form Start -->
@ -10,21 +9,40 @@
<!-- Email Input start -->
<div class="input-box">
<input type="tel" placeholder="手機號碼" required class="form-control" v-model="form.username"/>
<i data-feather="at-sign"></i>
<input
type="tel"
placeholder="手機號"
required
class="form-control"
v-model="form.username"
/>
<i
class="verify"
:class="{ disable: !showGetVerifyBtn }"
@click="handleGetVerify"
>{{ getVerifyMsg }}
<template v-if="countdown > 0">({{ countdown }})</template>
</i>
</div>
<!-- Email Input End -->
<!-- Password Input start -->
<div class="input-box">
<input type="password" placeholder="登入密碼" required class="form-control" v-model="form.password"/>
<input
type="number"
placeholder="驗證碼"
required
class="form-control"
v-model="form.password"
/>
<i class="iconly-Hide icli showHidePassword"></i>
</div>
<!-- Password Input End -->
<!-- <a href="javascript:void(0)" class="content-color font-sm forgot mb-3">忘記密碼 ?</a> -->
<br/>
<button type="button" class="btn-solid" @click="handleLogin"></button>
<span class="content-color font-sm d-block text-center fw-600">還沒有帳號 <router-link to="/register" class="underline">立即註冊 </router-link></span>
<br />
<button type="button" class="btn-solid" @click="handleLogin">
登入
</button>
</form>
<!-- Login Form End -->
@ -34,8 +52,13 @@
<span class="font-sm fw-600 font-theme"> 其他登入方式 </span>
</span>
<div class="social-wrap">
<a href="javascript:void(0)" class="font-md title-color fw-600" @click.prevent="handleLineLogin">
<img src="@/assets/icons/png/line.png" alt="line login" /> Line 登入 </a>
<a
href="javascript:void(0)"
class="font-md title-color fw-600"
@click.prevent="handleLineLogin"
>
<img src="@/assets/icons/png/line.png" alt="line login" /> Line 登入
</a>
<!-- <a href="https://accounts.google.com/ServiceLogin" class="font-md title-color fw-600"><img src="@/assets/icons/png/google.png" alt="phone" /> Continue with Google </a> -->
</div>
</div>
@ -47,44 +70,148 @@
</template>
<script setup>
import Cookies from 'js-cookie'
import Cookies from "js-cookie";
import { ref, watch, onUnmounted, computed } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useStore } from 'vuex'
import { ref } from 'vue'
import { useRoute , useRouter } from 'vue-router'
import { Toast } from 'vant'
import { login } from '@/api/auth'
import { login, sendVerify } from "@/api/auth";
const route = useRoute();
const router = useRouter();
const store = useStore();
const form = ref({
// username:'0983214434',
// password:'123456'
})
const handleLogin = async ()=>{
let res = await login(form.value)
if(res.code === 200){
Cookies.set('token', res.data.token, { expires: 365 ,domain: process.env.VUE_APP_DOMAIN})
Cookies.set('uid', res.data.uid, { expires: 365 ,domain: process.env.VUE_APP_DOMAIN})
router.push('/')
username: "",
password: "",
});
const domain = computed(()=>{
return store.state.domain
});
const getVerifyMsg = ref("獲取驗證碼");
const showGetVerifyBtn = ref(false);
const countdown = ref(0);
const handleGetVerify = async () => {
if(!showGetVerifyBtn.value){
return
}
}
if (!form.value.username) {
return Toast("請輸入手機號");
}
let res = await sendVerify(form.value.username);
if (res.code === 200) {
getVerifyMsg.value = "重新發送";
countdown.value = 60;
Toast("驗證碼已發送");
} else {
countdown.value = res.data.countdown;
Toast('登入錯誤');
}
};
watch(
() => form.value.username,
(nVal) => {
//vVal
let reg = /^09[0-9]{8}$/;
if (reg.test(nVal)) {
if (countdown.value === 0) {
return (showGetVerifyBtn.value = true);
} else {
return (showGetVerifyBtn.value = false);
}
} else {
return (showGetVerifyBtn.value = false);
}
}
);
let timer = null;
watch(
() => countdown.value,
(nVal) => {
if (nVal > 0) {
showGetVerifyBtn.value = false;
if (!timer) {
timer = setInterval(() => {
if (countdown.value >= 0) {
countdown.value--;
}
}, 1000);
}
} else {
clearInterval(timer);
timer = null;
showGetVerifyBtn.value = true;
}
}
);
const handleLogin = async () => {
//
if (!form.value.username || !form.value.password) {
return Toast("請輸入帳號及驗證碼");
}
let res = await login(form.value);
if (res.code === 200) {
console.log('login',domain.value)
Cookies.set("token", res.data.token, {
expires: 365,
domain: domain.value,
});
Cookies.set("uid", res.data.uid, {
expires: 365,
domain: domain.value,
});
router.push("/");
}else{
Toast(res.message);
}
};
const handleLineLogin = async () => {
// router.push('/')
const client_id = process.env.VUE_APP_LINE_CLINE_ID
const redirect_uri = process.env.VUE_APP_BASE_URL + '/home/linelogin'
let link = 'https://access.line.me/oauth2/v2.1/authorize?'
link = link + 'response_type=code'
link += '&client_id=' + client_id
link += '&redirect_uri=' + redirect_uri
link += '&state=login'
link += '&scope=openid%20profile'
window.location.href = link
}
const client_id = process.env.VUE_APP_LINE_CLINE_ID;
const redirect_uri = 'https://card.' + domain.value + "/home/linelogin";
let link = "https://access.line.me/oauth2/v2.1/authorize?";
link = link + "response_type=code";
link += "&client_id=" + client_id;
link += "&redirect_uri=" + redirect_uri;
link += "&state=login";
link += "&scope=openid%20profile";
window.location.href = link;
};
onUnmounted(() => {
clearInterval(timer);
});
</script>
<style lang="less" scoped>
.input-box {
.verify {
font-size: calc(14px + (28 - 22) * ((100vw - 320px) / (1920 - 320)));
position: absolute;
right: 16px;
top: 50%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
.disable {
color: #c9ccd0;
cursor: not-allowed;
}
}
</style>

@ -1,269 +0,0 @@
<template>
<div class="login-container">
<div class="box">
<div class="title">
SlashCard電子名片
</div>
<div class="main-section" @click="handleLogin">
<button type="submit" class="btn">LINE登 </button>
</div>
<div class="footer">
copyright 2022
</div>
</div>
</div>
</template>
<script setup>
import store from '@/store'
import Cookies from 'js-cookie'
import router from '@/router'
import { Toast } from 'vant'
import { login } from '@/api'
import { useRoute } from 'vue-router'
const route = useRoute()
const handleLogin = async()=>{
router.push('/')
}
const handleLogin1 = async()=>{
const client_id = '1657876696'
const redirect_uri = ''
let link = 'https://access.line.me/oauth2/v2.1/authorize?'
link = link + 'response_type=code'
link += '&client_id=' + client_id
link += '&redirect_uri=' + redirect_uri
link += '&state=login'
link += '&scope=openid%20profile'
window.location.href = link
}
</script>
<style lang="less" scoped>
*{
font-family: 'Inter',Arial, Helvetica, sans-serif;
box-sizing: border-box;
margin: 0px;
padding: 0px;
}
*::selection{
background-color: #c7c9ca;
}
body{
background-color: #ecf0f3;
margin: 0px;
padding: 0px;
}
.lead { font-size: 1.5rem; font-weight: 300; }
.container { margin: 150px auto; max-width: 960px; }
.box{
margin: auto;
box-sizing: border-box;
margin-top: 100px;
height:250px;
padding: 80px 40px;
width:340px;
border-radius: 35px;
background-color: #ecf0f3;
box-shadow: -8px -8px 8px #feffff, 8px 8px 8px #161b1d2f;
/* box-shadow: -5px -5px 5px #feffff, 5px 5px 5px #161b1d2f; */
/* box-shadow: inset 5px 5px 5px #cbced1,
inset -5px -5px 5px #ffffff; */
}
/* .box:hover{
box-shadow: inset 5px 5px 5px #cbced1,
inset -5px -5px 5px #ffffff;
} */
.box .title{
font-size: 24px;
font-weight: 500;
color:#858686;
text-align: center;
/* margin-bottom: 10px; */
}
.box .footer{
font-size: 12px;
font-weight: 500;
line-height: 100px;
color:#858686;
text-align: center;
/* margin-bottom: 10px; */
}
.box label{
font-size: 16px;
font-weight: 500;
color:#858686;
/* margin-bottom: 10px; */
}
.box .input-box{
width:100%;
height: 35px;
padding-left: 20px;
border: none;
color:#858686;
margin-top: 10px;
background-color: #ecf0f3;
outline: none;
border-radius: 20px;
box-shadow: inset 5px 5px 5px #cbced1,
inset -5px -5px 5px #ffffff;
}
.box .input-box::placeholder{
color:#9ea0a0;
}
.forget{
margin-top:15px;
}
.forget .fg a{
text-decoration: none;
font-size: 13px;
color:#8f8c8c;
line-height: 24px;
}
.forget .fg{
display: inline-block;
margin-left: 58%;
font-size: 12px;
}
.forget .fg:hover{
text-decoration: underline;
text-decoration-color: #b4b8b8;
}
.forget .checkbox-label{
display:block;
position: relative;
cursor: pointer;
font-size:22px;
line-height: 22px;
}
.label-text{
color:#8f8c8c;
display: inline-block;
/* width: 100%; */
position: absolute;
font-weight: 500;
left:12%;
font-size: 13px;
}
.forget .checkbox-label input{
position: absolute;
opacity: 0;
cursor: pointer;
}
.checkbox-label .checkbox-custom{
position: absolute;
top:0;
left:0px;
height:20px;
width:20px;
background-color: #ecf0f3;
border-radius: 5px;
border: none;
box-shadow:inset 3px 3px 3px #cbced1, inset -3px -3px 3px #ffff;
}
.checkbox-label input:checked ~ .checkbox-custom{
background-color: #ecf0f3;
border-radius: 5px;
-webkit-transform: rotate(0deg) scale(1);
-ms-transform: rotate(0deg) scale(1);
transform:rotate(0deg) scale(1);
opacity: 1;
border:none;
box-shadow: -4px -4px 4px #feffff, 4px 4px 4px #161b1d2f;
}
.checkbox-label .checkbox-custom::after{
position: absolute;
content:"";
left:10px;
top:10px;
height:0px;
width:0px;
border-radius:5px;
border:solid #635f5f;
border-width: 0 3px 3px 0;
-webkit-transform: rotate(0deg) scale(0);
-ms-transform: rotate(0deg) scale(0);
transform: rotate(0deg) scale(0);
opacity:1;
transition: all 0.3s ease-out;
}
.checkbox-label input:checked ~ .checkbox-custom::after {
-webkit-transform: rotate(45deg) scale(1);
-ms-transform: rotate(45deg) scale(1);
transform: rotate(45deg) scale(1);
opacity:1;
left: 7px;
top: 3px;
width: 4px;
height: 8px;
border: solid #635f5f;
border-width: 0 2px 2px 0;
background-color: transparent;
border-radius: 0;
}
.btn{
width:100%;
margin-top: 20px;
height: 38px;
border: none;
outline: none;
border-radius: 20px;
background-color: #57BA18;
font-size: 16px;
font-weight: 500;
color: #ffffff;
cursor: pointer;
box-shadow: -5px -5px 8px #d8e2e6, 5px 5px 10px #2c313378;
transition: 0.8s;
}
.btn:hover{
background-color: #535658;
box-shadow: inset 5px 5px 10px #05050578,
inset -5px -5px 10px #9e9c9c;
}
.social{
display: flex;
justify-content: center;
margin-top: 14px;
}
.box-radius{
border-radius:50%;
width:40px;
display: block;
height:40px;
margin: 6px;
/* margin-top: 50px; */
background-color: #ecf0f3;
box-shadow: 5px 5px 6px #0d275023,-5px -5px 6px #ffffff;
padding: 11px;
cursor: pointer;
}
.box-radius:hover{
box-shadow: inset 5px 5px 5px #cbced1,
inset -5px -5px 5px #ffffff;
}
.box-radius img{
width: 18px;
margin: auto;
height: 18px;
}
.option{
display: block;
margin-top: 35px;
color: #6c6d6d;
text-align: center;
}
</style>

@ -1,27 +1,45 @@
<template>
<div class="reg-container">
<van-nav-bar :title="title" />
<van-form @submit="onSubmit">
<van-nav-bar :title="title" />
<van-form @submit="onSubmit">
<van-cell-group inset>
<van-field
v-model="form.real_name"
label="真實姓名"
name=""
required
:rules="[{ required: true, message: '真實姓名必填' }]"
/>
<van-field
v-model="form.phone"
label="手機號碼"
name=""
required
placeholder="Ex. 0900000001 不要有空格"
:rules="[{ required: true, message: '手機號必填' },{ pattern: /\d{10}/ , message: '手機號格式錯誤' }]"
:rules="[
{ required: true, message: '手機號必填' },
{ pattern: /\d{10}/, message: '手機號格式錯誤' },
]"
/>
<van-field
v-model="form.email"
label="Email"
name=""
required
placeholder="Ex. example@gmail.com "
:rules="[{ required: true, message: 'Email必填' }]"
/>
</van-cell-group>
<div style="margin: 16px;">
<div style="margin: 16px">
<van-button round block type="primary" native-type="submit">
送出註冊
</van-button>
<br/>
<br />
<van-button round block type="default" @click="leaveReg">
以後在說
</van-button>
</div>
</van-form>
</van-form>
<van-overlay :show="crop.show" @click="crop.show = false" />
<div class="cropper-section" v-if="crop.show">
<div class="crop-area">
@ -30,179 +48,181 @@
ref="myCrop"
:src="crop.img"
:stencil-props="{
aspectRatio: 1/1
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 Cookies from 'js-cookie'
import axios from "axios";
import Cookies from "js-cookie";
import { ref } from 'vue'
import { ref } from "vue";
import store from '@/store'
import router from '@/router'
import { useRoute } from 'vue-router'
import { useStore } from "vuex";
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 store = useStore();
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 leaveReg = () => {
window.location.replace("/error.html");
};
const onCrop = () => {
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)
imgFile.append("user_id", form.value.user_id);
imgFile.append("fileType", "IMAGE");
imgFile.append("file", ufile);
crop.value.show = false
crop.value.show = false;
Toast.loading({
duration: 0,
message: '圖片上傳中...',
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('上傳失敗');
form.value.avatar = res.data.data;
Toast.success("上傳成功");
} else {
Toast.fail("上傳失敗");
}
}, 'image/jpeg');
}, "image/jpeg");
}
return
}
return;
};
const onClose = () =>{
crop.value.show = false
}
const onClose = () => {
crop.value.show = false;
};
const afterRead = async(file, name) => {
crop.value.show = true
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 () => {
let { id_token } = JSON.parse(sessionStorage.getItem('line'))
let { id_token } = JSON.parse(sessionStorage.getItem("reg"));
Toast.loading({
duration: 0,
message: '資料傳送中...',
message: "資料傳送中...",
forbidClick: true,
});
if(Cookies.get('refer_code')){
form.value.refer_code = Cookies.get('refer_code')
if (Cookies.get("refer_code")) {
form.value.refer_code = Cookies.get("refer_code");
}
let regRes = await register({token: id_token , ...form.value})
if(regRes.code === 500){
Toast('line 登入已過期')
return router.push('/login')
}else if(regRes.code === 200){
Toast('註冊成功')
Cookies.set('token',regRes.data.token, { expires: 365 ,domain: process.env.VUE_APP_DOMAIN})
Cookies.set('uid',regRes.data.uid, { expires: 365 ,domain: process.env.VUE_APP_DOMAIN})
return router.push('/')
}else{
Toast('註冊失敗')
return router.push('/login')
}
}
let regRes = await register({ token: id_token, ...form.value });
if (regRes.code === 500) {
Toast("line 登入已過期");
return router.push("/login");
} else if (regRes.code === 200) {
Toast("註冊成功");
Cookies.set("token", regRes.data.token, {
expires: 365,
domain: store.state.domain,
});
Cookies.set("uid", regRes.data.uid, {
expires: 365,
domain: store.state.domain,
});
return router.push("/");
} else {
Toast("註冊失敗");
return router.push("/login");
}
};
</script>
<style lang="less" scoped>
.container{
.container {
padding-bottom: 30px;
}
.title{
.title {
font-size: 20px;
text-align: center;
}
.upload-img{
.upload-img {
width: 80px;
}
.cropper {
height: 300px;
// width: 300px;
background: #DDD;
background: #ddd;
}
.cropper-section{
.cropper-section {
margin: 0 auto;
position: fixed;
text-align: center;
@ -211,14 +231,14 @@ const onSubmit = async () => {
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;
}

@ -117,7 +117,7 @@ async function showFlex(id) {
switch (id) {
case '0':
let { data: res } = await getCard({ userid: Cookies.get('uid') })
let { card } = cardFactory({ tid: userInfo.value.nc_template, vcard: res })
let { card } = cardFactory({ tid: userInfo.value.nc_template ,vcard: res })
// let { card } = genCard(res)
state.value.flexContent = JSON.parse(card)
flexRef.value.innerHTML = ''

@ -1978,10 +1978,10 @@
optionalDependencies:
"prettier" "^1.18.2 || ^2.0.0"
"@vue/devtools-api@^6.0.0", "@vue/devtools-api@^6.0.0-beta.11":
"integrity" "sha512-iO/4FIezHKXhiDBdKySCvJVh8/mZPxHpiQrTy+PXVqJZgpTPTdHy4q8GXulaY+UKEagdkBb0onxNQZ0LNiqVhw=="
"resolved" "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.0.12.tgz"
"version" "6.0.12"
"@vue/devtools-api@^6.0.0", "@vue/devtools-api@^6.0.0-beta.11", "@vue/devtools-api@^6.5.0":
"integrity" "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
"resolved" "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz"
"version" "6.5.0"
"@vue/preload-webpack-plugin@^1.1.0":
"integrity" "sha512-LIZMuJk38pk9U9Ur4YzHjlIyMuxPlACdBIHH9/nGYVTsaGKOSnSuELiE8vS9wa+dJpIYspYUOqk+L1Q4pgHQHQ=="
@ -6851,6 +6851,14 @@
"resolved" "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz"
"version" "4.0.1"
"pinia@^2.0.35":
"integrity" "sha512-P1IKKQWhxGXiiZ3atOaNI75bYlFUbRxtJdhPLX059Z7+b9Z04rnTZdSY8Aph1LA+/4QEMAYHsTQ638Wfe+6K5g=="
"resolved" "https://registry.npmjs.org/pinia/-/pinia-2.0.35.tgz"
"version" "2.0.35"
dependencies:
"@vue/devtools-api" "^6.5.0"
"vue-demi" "*"
"pinkie-promise@^2.0.0":
"integrity" "sha1-ITXW36ejWMBprJsXh3YogihFD/o="
"resolved" "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz"
@ -8905,6 +8913,11 @@
"resolved" "https://registry.npmjs.org/vue-cropper/-/vue-cropper-1.0.3.tgz"
"version" "1.0.3"
"vue-demi@*":
"integrity" "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg=="
"resolved" "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz"
"version" "0.14.0"
"vue-hot-reload-api@^2.3.0":
"integrity" "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog=="
"resolved" "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz"
@ -8950,7 +8963,7 @@
"resolved" "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz"
"version" "1.9.1"
"vue@^2 || ^3.0.0-0", "vue@^3.0.0", "vue@^3.0.2", "vue@^3.2.0", "vue@3.2.31":
"vue@^2 || ^3.0.0-0", "vue@^2.6.14 || ^3.2.0", "vue@^3.0.0", "vue@^3.0.0-0 || ^2.6.0", "vue@^3.0.2", "vue@^3.2.0", "vue@3.2.31":
"integrity" "sha512-odT3W2tcffTiQCy57nOT93INw1auq5lYLLYtWpPYQQYQOOdHiqFct9Xhna6GJ+pJQaF67yZABraH47oywkJgFw=="
"resolved" "https://registry.npmjs.org/vue/-/vue-3.2.31.tgz"
"version" "3.2.31"

Loading…
Cancel
Save