更新dev到main

main
Wayne Hsu 3 years ago
commit 0f7e559ce1

@ -0,0 +1,13 @@
NODE_ENV = production
VUE_ENV = h888
VUE_APP_LINE_LIFF_ID = 1657876696-564NGMxy
VUE_APP_BASE_URL = https://card.h888.fun
VUE_APP_SEND_URL = https://liff.line.me/1657876696-564NGMxy
VUE_APP_API_URL = https://card.h888.fun/appapi/v1
VUE_APP_IMAGE_URL = https://card.h888.fun/storage

@ -11,3 +11,5 @@ VUE_APP_SEND_URL = https://liff.line.me/1661025693-veEM0lwZ
VUE_APP_API_URL = https://card.slash1000.com/appapi/v1 VUE_APP_API_URL = https://card.slash1000.com/appapi/v1
VUE_APP_IMAGE_URL = https://card.slash1000.com/storage VUE_APP_IMAGE_URL = https://card.slash1000.com/storage
VUE_APP_MC_URL = https://liff.line.me/1656907652-p38ddKzQ

25
package-lock.json generated

@ -10,6 +10,8 @@
"dependencies": { "dependencies": {
"axios": "^0.26.1", "axios": "^0.26.1",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"dayjs": "^1.11.7",
"js-cookie": "^3.0.1",
"vant": "^3.4.7", "vant": "^3.4.7",
"vue": "^3.0.0", "vue": "^3.0.0",
"vue-router": "^4.0.0-0", "vue-router": "^4.0.0-0",
@ -5422,6 +5424,11 @@
"node": ">=0.10" "node": ">=0.10"
} }
}, },
"node_modules/dayjs": {
"version": "1.11.7",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz",
"integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ=="
},
"node_modules/debug": { "node_modules/debug": {
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@ -8466,6 +8473,14 @@
"integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==",
"dev": true "dev": true
}, },
"node_modules/js-cookie": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.1.tgz",
"integrity": "sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw==",
"engines": {
"node": ">=12"
}
},
"node_modules/js-message": { "node_modules/js-message": {
"version": "1.0.7", "version": "1.0.7",
"resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.7.tgz", "resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.7.tgz",
@ -19164,6 +19179,11 @@
"assert-plus": "^1.0.0" "assert-plus": "^1.0.0"
} }
}, },
"dayjs": {
"version": "1.11.7",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz",
"integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ=="
},
"debug": { "debug": {
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@ -21504,6 +21524,11 @@
"integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==",
"dev": true "dev": true
}, },
"js-cookie": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.1.tgz",
"integrity": "sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw=="
},
"js-message": { "js-message": {
"version": "1.0.7", "version": "1.0.7",
"resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.7.tgz", "resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.7.tgz",

@ -8,11 +8,14 @@
"build:slash": "vue-cli-service build --mode slash", "build:slash": "vue-cli-service build --mode slash",
"build:u168": "vue-cli-service build --mode u168", "build:u168": "vue-cli-service build --mode u168",
"build:dev": "vue-cli-service build --mode development", "build:dev": "vue-cli-service build --mode development",
"build:sta": "vue-cli-service build --mode stage" "build:sta": "vue-cli-service build --mode stage",
"build:h888": "vue-cli-service build --mode h888"
}, },
"dependencies": { "dependencies": {
"axios": "^0.26.1", "axios": "^0.26.1",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"dayjs": "^1.11.7",
"js-cookie": "^3.0.1",
"vant": "^3.4.7", "vant": "^3.4.7",
"vue": "^3.0.0", "vue": "^3.0.0",
"vue-router": "^4.0.0-0", "vue-router": "^4.0.0-0",

@ -1,11 +1,15 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang=""> <html lang="">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <meta
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> name="viewport"
<link rel="stylesheet" href="<%= BASE_URL %>css/flex2html.css"> content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<link rel="stylesheet" href="<%= BASE_URL %>css/flex2html.css" />
<link href="https://dev.iconly.io/public/1osUDQK8vVhk/iconly.css" rel="stylesheet"/>
<title><%= htmlWebpackPlugin.options.title %></title> <title><%= htmlWebpackPlugin.options.title %></title>
<style> <style>
[v-cloak] { [v-cloak] {

@ -1,7 +1,8 @@
import Cookies from 'js-cookie'
import axios from 'axios' import axios from 'axios'
import store from '../store' import store from '../store'
const instance = axios.create({ const instance = axios.create({
baseURL: process.env.VUE_APP_API_URL, baseURL: process.env.VUE_APP_API_URL,
timeout: 5000, timeout: 5000,
@ -13,15 +14,15 @@ instance.interceptors.request.use(
// if(config.data.showloading || config.params.showloading){ // if(config.data.showloading || config.params.showloading){
// console.log('showloading') // console.log('showloading')
// } // }
if (sessionStorage.getItem('token')) { // 判斷是否存在token如果存在的話則每個http header都加上token if (Cookies.get('token')) { // 判斷是否存在token如果存在的話則每個http header都加上token
config.headers.Authorization = `${sessionStorage.getItem('token')}`; config.headers.Authorization = `${Cookies.get('token')}`;
} }
if (config.method === 'post') { if (config.method === 'post') {
config.data = { config.data = {
uid: sessionStorage.getItem('uid'), uid: Cookies.get('uid'),
...config.data ...config.data
} }
@ -33,7 +34,7 @@ instance.interceptors.request.use(
} else if (config.method === 'get') { } else if (config.method === 'get') {
config.params = { config.params = {
uid: sessionStorage.getItem('uid'), uid: Cookies.get('uid'),
...config.params ...config.params
} }
@ -75,7 +76,6 @@ instance.interceptors.response.use(
function refreshToken(response) { function refreshToken(response) {
let token = response.headers.authorization let token = response.headers.authorization
if (token) { if (token) {
console.log('change token')
sessionStorage.setItem('token', token); sessionStorage.setItem('token', token);
} }
} }

@ -1,5 +1,11 @@
import ajax from './ajax' import ajax from './ajax'
export const addFavorite = async (userid)=> ajax(`/user/addFavorite`,{userid},"POST")
export const uploadUserConnections = async (uc)=> ajax(`/user/uploadConnections`,{uc},"POST")
export const getUserConnections = async () => ajax(`/user/getConnections`);
export const login = async (params)=> ajax(`/auth/login`,params,"POST") export const login = async (params)=> ajax(`/auth/login`,params,"POST")
export const checkLineId = async (lineid)=> ajax(`/auth/checkLineId`,{lineid},"GET") export const checkLineId = async (lineid)=> ajax(`/auth/checkLineId`,{lineid},"GET")

@ -19,4 +19,5 @@ p {
:root{ :root{
--van-nav-bar-background-color: #000; --van-nav-bar-background-color: #000;
--van-nav-bar-title-text-color: #FFF; --van-nav-bar-title-text-color: #FFF;
--van-nav-bar-text-color: #fff;
} }

@ -1,59 +0,0 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

@ -1,7 +1,7 @@
import { import {
Locale , Button , Toast, ShareSheet , NavBar , Locale , Button , Toast, ShareSheet , NavBar ,
Tab, Tabs, Form, Field, CellGroup , Uploader , Tab, Tabs, Form, Field, CellGroup , Uploader ,
Dialog Dialog, Popup, List, Step, Steps , SwipeCell
} from 'vant' } from 'vant'
import zhTW from 'vant/es/locale/lang/zh-TW'; import zhTW from 'vant/es/locale/lang/zh-TW';
@ -20,4 +20,10 @@ export function vant(app){
.use(CellGroup) .use(CellGroup)
.use(Uploader) .use(Uploader)
.use(Dialog) .use(Dialog)
.use(Popup)
.use(List)
.use(Step)
.use(Steps)
.use(SwipeCell)
} }

@ -1,8 +1,10 @@
<template> <template>
<div id="home"> <div id="home">
<van-nav-bar title="我的名片" /> <van-nav-bar title="我的名片" left-text="Slash" @click-left="goSlash" v-if="nolog == 1"/>
<van-nav-bar title="我的名片" left-text="Slash" @click-left="goSlash" right-text="" @click-right="showUserConn = true" v-else/>
<div class="tab-section" v-cloak> <div class="tab-section" v-cloak>
<van-tabs :lazy-render="true" v-model:active="activeName" v-show="user.nc_type > 1 && cid !== '1'"> <van-tabs :lazy-render="true" v-model:active="activeName" v-show="user.level > 0">
<van-tab title="我的名片" name="0"> <van-tab title="我的名片" name="0">
</van-tab> </van-tab>
<van-tab :title="card_title" name="1" v-if="showCusCard"> <van-tab :title="card_title" name="1" v-if="showCusCard">
@ -18,6 +20,7 @@
</div> </div>
</div> </div>
<div class="recommend" v-if="activeName == '0'"> <div class="recommend" v-if="activeName == '0'">
<div>
<img class="avatar" :src="user.avatar" style="display:block; margin:auto;"> <img class="avatar" :src="user.avatar" style="display:block; margin:auto;">
<br /> <br />
<p style="text-align: center; font-size: 35px; "><strong>{{ user.name }}</strong><br /></p> <p style="text-align: center; font-size: 35px; "><strong>{{ user.name }}</strong><br /></p>
@ -27,8 +30,6 @@
<p style="text-align: center; font-size: 15px;" v-html="user.mark"> <p style="text-align: center; font-size: 15px;" v-html="user.mark">
</p> </p>
</div> </div>
</div>
<div class="btn-area" v-if="user.level > 0"> <div class="btn-area" v-if="user.level > 0">
<dl class="dl02"> <dl class="dl02">
<a :href="`${imgUrl}/${user.user_id}/${user.user_id}.vcf`"> <a :href="`${imgUrl}/${user.user_id}/${user.user_id}.vcf`">
@ -70,12 +71,32 @@
</div> </div>
</div> </div>
</div>
</div>
<van-popup v-model:show="showUserConn" position="right" :style="{ width: '70%',height: '100%' }">
<van-steps direction="vertical" :active="0">
<van-step v-for="(v,i) in userConnections" :key="i">
<div class="user-conn">
<div class="user-conn-left">{{ v.name }}</div>
<div class="user-conn-right" >
<i class="icon-heart" @click="handleAddFavorite"></i>
<i class="icon-eye-circle" @click="goUC(v.nfcurl)"></i>
</div>
</div>
<p>{{ v.company }}</p>
<p>{{ v.time }}</p>
</van-step>
</van-steps>
</van-popup>
</template> </template>
<script> <script>
import { nextTick, onBeforeMount, reactive, ref, toRefs, watch } from 'vue' import dayjs from 'dayjs'
import Cookies from 'js-cookie'
import { nextTick, onBeforeMount, reactive, ref, toRefs, watch, computed } from 'vue'
import { checkUser, getCard, getCusCard, getVipCard } from '@/api' import { checkUser, getCard, getCusCard, getVipCard, addFavorite, uploadUserConnections, getUserConnections } from '@/api'
import { changeMeta } from '@/utils/meta' import { changeMeta } from '@/utils/meta'
@ -106,9 +127,12 @@ export default {
let flexRef = ref(null) let flexRef = ref(null)
//user id //user id
let token = encodeURIComponent(new URLSearchParams(window.location.search).get('params')) let token = encodeURIComponent(new URLSearchParams(window.location.search).get('params'))
let cardid = encodeURIComponent(new URLSearchParams(window.location.search).get('cardid')) let cardid = encodeURIComponent(new URLSearchParams(window.location.search).get('cardid'))
let nouc = encodeURIComponent(new URLSearchParams(window.location.search).get('nouc'))
let nolog = ref(encodeURIComponent(new URLSearchParams(window.location.search).get('nolog')))
cid.value = cardid cid.value = cardid
@ -116,6 +140,7 @@ export default {
var u = navigator.userAgent; var u = navigator.userAgent;
isIOs.value = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); isIOs.value = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
const uc_temp = ref()
onBeforeMount(async () => { onBeforeMount(async () => {
@ -141,7 +166,6 @@ export default {
const card1Res = await getCard(params) const card1Res = await getCard(params)
console.log('card1Res', card1Res)
if (card1Res.code !== 200) { if (card1Res.code !== 200) {
Toast('操作錯誤') Toast('操作錯誤')
return return
@ -157,7 +181,7 @@ export default {
state.user = card1Res.data state.user = card1Res.data
if (card1Res.data.nc_type > 1 && card1Res.data.has_cuscard === 1 && card1Res.data.show_cus === 1) { if (card1Res.data.level > 0 && card1Res.data.has_cuscard === 1 && card1Res.data.show_cus === 1) {
state.showCusCard = true state.showCusCard = true
state.card_title = card1Res.data.card_title state.card_title = card1Res.data.card_title
} }
@ -170,6 +194,14 @@ export default {
state.vip_card = [] state.vip_card = []
} }
//
if(nouc != '1'){
saveConnection(card1Res.data)
}
})
// activeName.value = '0' // activeName.value = '0'
watch(() => activeName.value, function (newVal, oldVal) { watch(() => activeName.value, function (newVal, oldVal) {
@ -180,7 +212,6 @@ export default {
} }
}, { immediate: true }) }, { immediate: true })
})
async function showFlex(id) { async function showFlex(id) {
@ -193,7 +224,7 @@ export default {
// flex2html("flex", JSON.parse(card)) // flex2html("flex", JSON.parse(card))
break break
case '1': case '1':
if (state.user.nc_type > 1) { if (state.user.level > 0) {
let card2Res = await getCusCard({ userid: state.user.user_id }) let card2Res = await getCusCard({ userid: state.user.user_id })
if (card2Res.code === 200) { if (card2Res.code === 200) {
if (card2Res.data.cus_card) { if (card2Res.data.cus_card) {
@ -236,12 +267,85 @@ export default {
} }
} }
//
const showUserConn = ref(false)
async function saveConnection(data){
let connData = {
userid: data.user_id,
name: data.name,
nfcurl: data.nfcurl,
company: data.company,
title: data.title,
avatar: data.avatar,
time: dayjs().format('YYYY/MM/DD HH:mm')
}
let n_user_conn = []
if(localStorage.getItem('user_conn')){
//
let i = 0
let t_connData = JSON.parse(localStorage.getItem('user_conn')).filter(item=>{
i++
return item.userid !=connData.userid && i < 5
})
n_user_conn = [connData,...t_connData]
}else{
n_user_conn = [connData]
}
localStorage.setItem('user_conn',JSON.stringify(n_user_conn))
if(Cookies.get('token')){
let res = await uploadUserConnections(JSON.stringify(n_user_conn))
if(res.code === 200){
uc_temp.value = n_user_conn
}
}
}
const userConnections = computed(()=>{
if(uc_temp.value && uc_temp.value.length > 0){
return uc_temp.value
}
return JSON.parse(localStorage.getItem('user_conn'))
})
const goUC = (url)=>{
showUserConn.value = false
window.location.href = url + '&nouc=1'
// window.location.href = url
}
const handleAddFavorite = async (userid)=>{
if(!Cookies.get('token')){
return Toast('您尚未登入Slash會員中心請按左上角Slash會員中心登入或加入')
}
let res = await addFavorite(state.user.user_id)
if(res.code === 200){
return Toast('收藏成功')
}
}
const goSlash=()=>{
window.location.href = 'https://card.slash1000.com/home/?refer=' + state.user.code
}
return { return {
...toRefs(state), ...toRefs(state),
showUserConn,
activeName, activeName,
cid, cid,
nolog,
flexRef, flexRef,
isIOs isIOs,
userConnections,
goUC,
goSlash,
handleAddFavorite
} }
} }
} }
@ -334,9 +438,27 @@ export default {
.recommend { .recommend {
width: 100%; width: 100%;
padding-top: 20px; padding-top: 20px;
.avatar { .avatar {
width: 50%; width: 50%;
border-radius: 50%; border-radius: 50%;
} }
} }
.user-conn{
display: flex;
margin-bottom: 10px;
.user-conn-left{
flex: 1;
font-size: 18px;
font-weight: 500;
}
.user-conn-right{
width: 70px;
i{
font-size: 18px;
margin:0 5px;
}
}
}
</style> </style>

Loading…
Cancel
Save