|
|
<template>
|
|
|
<van-nav-bar
|
|
|
title="商務卡片"
|
|
|
right-text="關閉"
|
|
|
@click-right="$router.push('/auth/getauth')"
|
|
|
/>
|
|
|
<keep-alive>
|
|
|
<div id="app" class="container my-4">
|
|
|
<div class="card-title">
|
|
|
<div>
|
|
|
會員編號:{{$route.query.user_id}}
|
|
|
</div>
|
|
|
<div>
|
|
|
</div>
|
|
|
<div>
|
|
|
<van-button
|
|
|
icon="browsing-history"
|
|
|
type="primary"
|
|
|
@click="handlePreview"
|
|
|
>
|
|
|
預覽
|
|
|
</van-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="card my-2">
|
|
|
<div class="card-header">
|
|
|
<ul class="card-header-tabs nav nav-tabs">
|
|
|
<li class="nav-item" @click="form.page = 'setting'">
|
|
|
<button
|
|
|
type="button"
|
|
|
class="nav-link"
|
|
|
:class="{ active: form.page === 'setting' }"
|
|
|
>
|
|
|
設定
|
|
|
</button>
|
|
|
</li>
|
|
|
<li
|
|
|
class="nav-item"
|
|
|
v-for="(card, index) in form.json5.cards"
|
|
|
:key="index"
|
|
|
@click="form.page = index + 1"
|
|
|
>
|
|
|
<button
|
|
|
type="button"
|
|
|
class="nav-link"
|
|
|
:class="{ active: form.page === index + 1 }"
|
|
|
>
|
|
|
{{ index + 1 }}
|
|
|
</button>
|
|
|
</li>
|
|
|
<li
|
|
|
class="nav-item"
|
|
|
@click="addCard"
|
|
|
v-if="form.json5.cards.length < 10"
|
|
|
>
|
|
|
<button type="button" class="nav-link">
|
|
|
<i class="fa fa-plus-circle"></i> +
|
|
|
</button>
|
|
|
</li>
|
|
|
</ul>
|
|
|
</div>
|
|
|
<!---->
|
|
|
<div class="card-content" v-if="form.page === 'setting'">
|
|
|
<div class="card-body">
|
|
|
<div class="form-group mb-2 was-validated">
|
|
|
<label for="utel-altText">標題文字</label>
|
|
|
<input
|
|
|
pattern=".+"
|
|
|
required="required"
|
|
|
id="utel-altText"
|
|
|
class="form-control form-control-sm"
|
|
|
v-model="form.title"
|
|
|
/>
|
|
|
<small class="form-text text-muted"
|
|
|
>與我的名片切換時顯示的文字。</small
|
|
|
>
|
|
|
</div>
|
|
|
<div class="form-group mb-2 was-validated">
|
|
|
<label for="utel-showNfc">是否顯示於感應名片</label>
|
|
|
<br />
|
|
|
<van-switch v-model="form.showNfc" />
|
|
|
<small class="form-text text-muted"
|
|
|
>與我的名片切換時顯示的文字。</small
|
|
|
>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="card-content" v-else>
|
|
|
<div class="card-body pb-2 pt-3">
|
|
|
<div class="row">
|
|
|
<div class="col-sm-12" v-if="form.json5.cards.length > 1">
|
|
|
<div class="form-group mb-2 mb-2">
|
|
|
<label>控制卡片</label>
|
|
|
<div class="d-flex btn-group mb-1">
|
|
|
<button
|
|
|
type="button"
|
|
|
class="btn btn-sm btn-outline-info"
|
|
|
@click="moveCard(0, form.page)"
|
|
|
>
|
|
|
<i class="iconfont icon-arrow-o-l"></i> 前移
|
|
|
</button>
|
|
|
<button
|
|
|
type="button"
|
|
|
class="btn btn-sm btn-outline-info"
|
|
|
@click="moveCard(1, form.page)"
|
|
|
>
|
|
|
<i class="iconfont icon-arrow-o-r"></i> 後移
|
|
|
</button>
|
|
|
<button
|
|
|
type="button"
|
|
|
class="btn btn-sm btn-outline-danger"
|
|
|
@click="delCard(form.page)"
|
|
|
>
|
|
|
<i class="iconfont icon-delete"></i> 刪除
|
|
|
</button>
|
|
|
</div>
|
|
|
<small class="form-text text-muted"
|
|
|
>你可以點選前後移按鈕來移動卡片。</small
|
|
|
>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="col-sm-12">
|
|
|
<div class="form-group mb-2 was-validated">
|
|
|
<label for="vcard-ratio">圖片長寬比</label>
|
|
|
<input
|
|
|
pattern=".+"
|
|
|
required="required"
|
|
|
id="vcard-ratio"
|
|
|
class="form-control form-control-sm"
|
|
|
v-model="form.json5.cards[form.page - 1].ratio"
|
|
|
/>
|
|
|
<small class="form-text text-muted">20:13 1:1 6:8。</small>
|
|
|
</div>
|
|
|
<div class="form-group mb-2 was-validated">
|
|
|
<label for="vcard-image"> 卡片圖片 </label>
|
|
|
<div>
|
|
|
<van-uploader
|
|
|
:after-read="afterRead"
|
|
|
:max-count="1"
|
|
|
name="cardimage"
|
|
|
@delete="handleDelete"
|
|
|
>
|
|
|
<template
|
|
|
v-if="form.json5.cards[form.page - 1].image.length > 0"
|
|
|
>
|
|
|
<div class="upload-main">
|
|
|
<img
|
|
|
class="upload-img"
|
|
|
:src="form.json5.cards[form.page - 1].image"
|
|
|
alt=""
|
|
|
/>
|
|
|
</div>
|
|
|
</template>
|
|
|
<template v-else>
|
|
|
<div class="upload-main">
|
|
|
<img
|
|
|
class="upload-img"
|
|
|
src="@/assets/images/upload.jpg"
|
|
|
/>
|
|
|
<p>請上傳圖片</p>
|
|
|
</div>
|
|
|
</template>
|
|
|
</van-uploader>
|
|
|
</div>
|
|
|
<small class="form-text text-muted"></small>
|
|
|
</div>
|
|
|
<div class="form-group mb-2 was-validated">
|
|
|
<label for="vcard-link">圖片網址連結</label>
|
|
|
<input
|
|
|
pattern="(https?://|line://|tel:|mailto:)\S+"
|
|
|
id="vcard-link"
|
|
|
inputmode="url"
|
|
|
type="url"
|
|
|
class="form-control form-control-sm"
|
|
|
v-model="form.json5.cards[form.page - 1].link"
|
|
|
/>
|
|
|
<small class="form-text text-muted">
|
|
|
連結(需輸入完整網址,http://..,https://...)
|
|
|
</small>
|
|
|
</div>
|
|
|
<div class="form-group mb-2 was-validated">
|
|
|
<label for="vcard-titleColor">卡片底色</label>
|
|
|
<div class="input-group input-group-sm">
|
|
|
<input
|
|
|
pattern="#[0-9a-fA-F]{6}"
|
|
|
required="required"
|
|
|
id="vcard-bgColor"
|
|
|
inputmode="url"
|
|
|
class="form-control"
|
|
|
v-model="form.json5.cards[form.page - 1].bgColor"
|
|
|
/>
|
|
|
<div class="input-group-append">
|
|
|
<input
|
|
|
type="color"
|
|
|
class="form-control form-control-color"
|
|
|
v-model="form.json5.cards[form.page - 1].bgColor"
|
|
|
/>
|
|
|
色卡
|
|
|
</div>
|
|
|
</div>
|
|
|
<small class="form-text text-muted"
|
|
|
>請填寫卡片標題文字的顏色。</small
|
|
|
>
|
|
|
</div>
|
|
|
<div class="form-group mb-2 was-validated">
|
|
|
<label for="vcard-title">卡片標題</label>
|
|
|
<input
|
|
|
pattern=".+"
|
|
|
required="required"
|
|
|
id="vcard-title"
|
|
|
class="form-control form-control-sm"
|
|
|
v-model="form.json5.cards[form.page - 1].title"
|
|
|
/>
|
|
|
<small class="form-text text-muted">請填寫卡片標題。</small>
|
|
|
</div>
|
|
|
<div class="form-group mb-2 was-validated">
|
|
|
<label for="vcard-titleSize">標題文字大小(最大5xl,最小xxs)</label>
|
|
|
<div class="input-group input-group-sm">
|
|
|
<input
|
|
|
pattern="[0-9a-zA-Z]+"
|
|
|
required="required"
|
|
|
id="vcard-titleSize"
|
|
|
class="form-control form-control-sm"
|
|
|
v-model="form.json5.cards[form.page - 1].titleSize"
|
|
|
/>
|
|
|
<div class="input-group-append">
|
|
|
<button
|
|
|
type="button"
|
|
|
data-toggle="dropdown"
|
|
|
class="btn btn-outline-secondary dropdown-toggle"
|
|
|
aria-expanded="false"
|
|
|
>
|
|
|
請選擇文字大小
|
|
|
</button>
|
|
|
<div class="dropdown-menu py-0" style="">
|
|
|
<button type="button" class="dropdown-item" @click="changeSize('titleSize',size)" v-for="(size,index) in sizeArr" :key="index">{{size}}</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<small class="form-text text-muted"
|
|
|
>請填寫卡片標題的文字大小。
|
|
|
</small>
|
|
|
</div>
|
|
|
<div class="form-group mb-2 was-validated">
|
|
|
<label for="vcard-titleColor">標題文字顏色</label>
|
|
|
<div class="input-group input-group-sm">
|
|
|
<input
|
|
|
pattern="#[0-9a-fA-F]{6}"
|
|
|
required="required"
|
|
|
id="vcard-titleColor"
|
|
|
inputmode="url"
|
|
|
class="form-control"
|
|
|
v-model="form.json5.cards[form.page - 1].titleColor"
|
|
|
/>
|
|
|
<div class="input-group-append">
|
|
|
<input
|
|
|
type="color"
|
|
|
class="form-control form-control-color"
|
|
|
v-model="form.json5.cards[form.page - 1].titleColor"
|
|
|
/>
|
|
|
</div>
|
|
|
</div>
|
|
|
<small class="form-text text-muted"
|
|
|
>請填寫卡片標題文字的顏色。</small
|
|
|
>
|
|
|
</div>
|
|
|
<div class="form-group mb-2 was-validated">
|
|
|
<label for="vcard-desc">卡片說明</label>
|
|
|
<textarea
|
|
|
id="vcard-desc"
|
|
|
pattern=".+"
|
|
|
required="required"
|
|
|
class="form-control form-control-sm"
|
|
|
v-model="form.json5.cards[form.page - 1].desc"
|
|
|
style="height: 100px"
|
|
|
></textarea>
|
|
|
<small class="form-text text-muted">請填寫卡片說明。</small>
|
|
|
</div>
|
|
|
<div class="form-group mb-2 was-validated">
|
|
|
<label for="vcard-descSize">說明文字大小(最大5xl,最小xxs)</label>
|
|
|
<div class="input-group input-group-sm">
|
|
|
<input
|
|
|
pattern="[0-9a-zA-Z]+"
|
|
|
required="required"
|
|
|
id="vcard-descSize"
|
|
|
class="form-control form-control-sm"
|
|
|
v-model="form.json5.cards[form.page - 1].descSize"
|
|
|
/>
|
|
|
<div class="input-group-append">
|
|
|
<button
|
|
|
type="button"
|
|
|
data-toggle="dropdown"
|
|
|
class="btn btn-outline-secondary dropdown-toggle"
|
|
|
aria-expanded="false"
|
|
|
>
|
|
|
請選擇文字大小
|
|
|
</button>
|
|
|
<div class="dropdown-menu py-0" style="">
|
|
|
<button type="button" class="dropdown-item" @click="changeSize('descSize',size)" v-for="(size,index) in sizeArr" :key="index">{{size}}</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<small class="form-text text-muted"
|
|
|
>請填寫卡片標題的文字大小。
|
|
|
</small>
|
|
|
</div>
|
|
|
<div class="form-group mb-2 was-validated">
|
|
|
<label for="vcard-titleColor">說明文字顏色</label>
|
|
|
<div class="input-group input-group-sm">
|
|
|
<input
|
|
|
pattern="#[0-9a-fA-F]{6}"
|
|
|
required="required"
|
|
|
id="vcard-titleColor"
|
|
|
inputmode="url"
|
|
|
class="form-control"
|
|
|
v-model="form.json5.cards[form.page - 1].descColor"
|
|
|
/>
|
|
|
<div class="input-group-append">
|
|
|
<input
|
|
|
type="color"
|
|
|
class="form-control form-control-color"
|
|
|
v-model="form.json5.cards[form.page - 1].descColor"
|
|
|
/>
|
|
|
</div>
|
|
|
</div>
|
|
|
<small class="form-text text-muted"
|
|
|
>請填寫卡片標題文字的顏色。</small
|
|
|
>
|
|
|
</div>
|
|
|
<!-- <div class="form-group mb-2 was-validated">
|
|
|
<label for="vcard-title">卡片連結</label>
|
|
|
<input
|
|
|
pattern=".+"
|
|
|
required="required"
|
|
|
id="vcard-title"
|
|
|
class="form-control form-control-sm"
|
|
|
v-model="form.json5.cards[form.page - 1].title"
|
|
|
/>
|
|
|
<small class="form-text text-muted">請填寫卡片標題。</small>
|
|
|
</div> -->
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<ul class="list-group list-group-flush">
|
|
|
<li
|
|
|
class="list-group-item pb-2 pt-3"
|
|
|
v-for="(btn, index) in form.json5.cards[form.page - 1].btns"
|
|
|
:key="index"
|
|
|
>
|
|
|
<div class="row">
|
|
|
<div class="col-sm-12">
|
|
|
<div class="form-group mb-2">
|
|
|
<label>控制按鈕 {{ index + 1 }}</label>
|
|
|
<div class="d-flex btn-group mb-1">
|
|
|
<button
|
|
|
type="button"
|
|
|
class="btn btn-sm btn-outline-info"
|
|
|
@click="moveBtn(0, index)"
|
|
|
v-if="form.json5.cards[form.page - 1].btns.length > 1"
|
|
|
>
|
|
|
<i class="iconfont icon-arrow-o-u"></i> 上移
|
|
|
</button>
|
|
|
<button
|
|
|
type="button"
|
|
|
class="btn btn-sm btn-outline-info"
|
|
|
@click="moveBtn(1, index)"
|
|
|
v-if="form.json5.cards[form.page - 1].btns.length > 1"
|
|
|
>
|
|
|
<i class="iconfont icon-arrow-o-d"></i> 下移
|
|
|
</button>
|
|
|
<button
|
|
|
type="button"
|
|
|
class="btn btn-sm btn-outline-danger"
|
|
|
@click="delBtn(index)"
|
|
|
>
|
|
|
<i class="iconfont icon-delete"></i> 刪除
|
|
|
</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="col-sm-12">
|
|
|
<div class="form-group mb-2 was-validated">
|
|
|
<label for="cardbtn-text-0"
|
|
|
>按鈕 {{ index + 1 }} 文字</label
|
|
|
>
|
|
|
<input
|
|
|
pattern=".+"
|
|
|
required="required"
|
|
|
id="cardbtn-text-0"
|
|
|
class="form-control form-control-sm"
|
|
|
v-model="btn.text"
|
|
|
/>
|
|
|
</div>
|
|
|
<div class="form-group mb-2 was-validated">
|
|
|
<label for="cardbtn-link-0"
|
|
|
>按鈕
|
|
|
{{
|
|
|
index + 1
|
|
|
}}
|
|
|
連結(需輸入完整網址,http://..,https://...)</label
|
|
|
>
|
|
|
<input
|
|
|
pattern="(https?://|line://|tel:|mailto:)\S+"
|
|
|
required="required"
|
|
|
inputmode="url"
|
|
|
type="url"
|
|
|
id="cardbtn-link-0"
|
|
|
class="form-control form-control-sm"
|
|
|
v-model="btn.link"
|
|
|
/>
|
|
|
</div>
|
|
|
<div class="form-group mb-2 was-validated">
|
|
|
<label for="vcard-titleColor">按鈕文字顏色</label>
|
|
|
<div class="input-group input-group-sm">
|
|
|
<input
|
|
|
pattern="#[0-9a-fA-F]{6}"
|
|
|
required="required"
|
|
|
id="vcard-titleColor"
|
|
|
inputmode="url"
|
|
|
class="form-control"
|
|
|
v-model="btn.color"
|
|
|
/>
|
|
|
<div class="input-group-append">
|
|
|
<input
|
|
|
type="color"
|
|
|
class="form-control form-control-color"
|
|
|
v-model="btn.color"
|
|
|
/>
|
|
|
</div>
|
|
|
</div>
|
|
|
<!-- <small class="form-text text-muted">請填寫卡片標題文字的顏色。</small> -->
|
|
|
</div>
|
|
|
<div class="form-group mb-2 was-validated">
|
|
|
<label for="vcard-btnHeight">按鈕大小</label>
|
|
|
<div class="input-group input-group-sm">
|
|
|
<input
|
|
|
pattern="[0-9a-zA-Z]+"
|
|
|
required="required"
|
|
|
id="vcard-btnHeight"
|
|
|
class="form-control form-control-sm"
|
|
|
v-model="btn.btnHeight"
|
|
|
/>
|
|
|
<div class="input-group-append">
|
|
|
<button
|
|
|
type="button"
|
|
|
data-toggle="dropdown"
|
|
|
class="btn btn-outline-secondary dropdown-toggle"
|
|
|
aria-expanded="false"
|
|
|
>
|
|
|
請選擇按鈕大小
|
|
|
</button>
|
|
|
<div class="dropdown-menu py-0" style="">
|
|
|
<button type="button" class="dropdown-item" @click="btn.btnHeight='sm'" >sm</button>
|
|
|
<button type="button" class="dropdown-item" @click="btn.btnHeight='md'" >md</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<small class="form-text text-muted"
|
|
|
>請填寫卡片標題的文字大小。
|
|
|
</small>
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
</div>
|
|
|
</li>
|
|
|
<li class="list-group-item">
|
|
|
<button
|
|
|
type="button"
|
|
|
class="btn btn-outline-success"
|
|
|
@click="addBtn(form.page)"
|
|
|
>
|
|
|
<i class="fa fa-plus-circle"></i> 新增按鈕
|
|
|
</button>
|
|
|
<button
|
|
|
type="button"
|
|
|
class="btn btn-outline-success"
|
|
|
@click="addShareBtn(form.page)"
|
|
|
>
|
|
|
<i class="fa fa-plus-circle"></i> 新增分享按鈕
|
|
|
</button>
|
|
|
</li>
|
|
|
</ul>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="d-flex mx-n2 my-2 row">
|
|
|
<div class="btn flex-fill mx-2 my-1 btn-primary" @click="handleSubmit">
|
|
|
<i class="fa mr-2 fa-id-card-o"></i> 建立名片
|
|
|
</div>
|
|
|
</div>
|
|
|
<div
|
|
|
id="modal-exportimport"
|
|
|
data-backdrop="static"
|
|
|
data-keyboard="false"
|
|
|
tabindex="-1"
|
|
|
class="fade modal"
|
|
|
>
|
|
|
<div
|
|
|
class="align-items-stretch modal-dialog modal-dialog-centered modal-xl"
|
|
|
>
|
|
|
<div class="modal-content">
|
|
|
<div class="d-flex flex-column modal-body">
|
|
|
<textarea
|
|
|
class="form-control form-control-sm flex-fill"
|
|
|
></textarea>
|
|
|
<small class="form-text text-muted"
|
|
|
>請複製匯出的資料,或貼上之前的資料並點一下「匯入」按鈕。</small
|
|
|
>
|
|
|
</div>
|
|
|
<div class="modal-footer">
|
|
|
<button type="button" class="btn btn-outline-success">
|
|
|
複製
|
|
|
</button>
|
|
|
<button type="button" class="btn btn-secondary">關閉</button>
|
|
|
<button type="button" class="btn btn-primary">匯入</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</keep-alive>
|
|
|
<Footer v-if="showFooter" />
|
|
|
<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: 20 / 13,
|
|
|
}"
|
|
|
: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>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import Footer from "@/components/Footer.vue";
|
|
|
import FlexView from "@/components/FlexView.vue";
|
|
|
|
|
|
import {
|
|
|
ref,
|
|
|
reactive,
|
|
|
toRefs,
|
|
|
watch,
|
|
|
onBeforeMount,
|
|
|
defineComponent,
|
|
|
onMounted,
|
|
|
} from "vue";
|
|
|
|
|
|
import { updateCusCard } from "@/api";
|
|
|
import { useStore } from "vuex";
|
|
|
import { useRouter ,useRoute} from "vue-router";
|
|
|
|
|
|
import axios from "axios";
|
|
|
import _ from "lodash";
|
|
|
|
|
|
import { showToast,showLoadingToast,showSuccessToast } from "vant";
|
|
|
import { Cropper } from "vue-advanced-cropper";
|
|
|
import "vue-advanced-cropper/dist/style.css";
|
|
|
|
|
|
import { genCard1 } from "@/utils/card2";
|
|
|
|
|
|
import { getCusCard } from "@/api";
|
|
|
|
|
|
const URL = window.URL || window.webkitURL;
|
|
|
|
|
|
export default defineComponent({
|
|
|
name: "EditCard",
|
|
|
components: {
|
|
|
Footer,
|
|
|
Cropper,
|
|
|
FlexView,
|
|
|
},
|
|
|
async setup() {
|
|
|
const store = useStore();
|
|
|
const route = useRoute();
|
|
|
const router = useRouter();
|
|
|
|
|
|
const myCrop = ref(null);
|
|
|
|
|
|
const showNfc = ref(false);
|
|
|
const showPreview = ref(false);
|
|
|
let flexRef = ref(null);
|
|
|
|
|
|
const crop = ref({
|
|
|
show: false,
|
|
|
img: null,
|
|
|
outputType: "jpeg",
|
|
|
autoCrop: true,
|
|
|
autoCropWidth: 200,
|
|
|
autoCropHeight: 200,
|
|
|
});
|
|
|
|
|
|
let state = reactive({
|
|
|
imagePath: "",
|
|
|
previewImage: null,
|
|
|
fileList: [],
|
|
|
showFooter: true,
|
|
|
form: {
|
|
|
page: 1,
|
|
|
title: "商務卡片",
|
|
|
showNfc: true,
|
|
|
json5: {
|
|
|
altText: '',
|
|
|
btnHeight: "md",
|
|
|
descSize: "sm",
|
|
|
titleSize: "xl",
|
|
|
cards: [
|
|
|
{
|
|
|
bgColor: "#ffffff",
|
|
|
desc: "",
|
|
|
descColor: "#000000",
|
|
|
image: "",
|
|
|
link: "",
|
|
|
title: "",
|
|
|
titleSize: "xl",
|
|
|
descSize: "sm",
|
|
|
titleColor: "#000000",
|
|
|
ratio: "20:13",
|
|
|
},
|
|
|
],
|
|
|
},
|
|
|
},
|
|
|
});
|
|
|
|
|
|
const sizeArr = ref(['xxs','xs','sm','md','lg','xl','xxl','3xl','4xl','5xl'])
|
|
|
|
|
|
let userid;
|
|
|
|
|
|
onMounted(async()=>{
|
|
|
userid = route.query.user_id;
|
|
|
|
|
|
let res = await getCusCard({ userid })
|
|
|
if(res.code===200){
|
|
|
if(res.data.cus_card && res.data.cus_card.length>0){
|
|
|
state.form = JSON.parse(res.data.cus_card)
|
|
|
}
|
|
|
}
|
|
|
})
|
|
|
|
|
|
watch(()=>state.form.title,(newVal)=>{
|
|
|
state.form.json5.altText = newVal
|
|
|
})
|
|
|
|
|
|
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("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}/card/uploadfile`,
|
|
|
imgFile,
|
|
|
{}
|
|
|
);
|
|
|
|
|
|
if (res.data.code == 200) {
|
|
|
state.form.json5.cards[state.form.page - 1].image = res.data.data;
|
|
|
|
|
|
showSuccessToast("上傳成功");
|
|
|
} else {
|
|
|
showToast.fail("上傳失敗");
|
|
|
}
|
|
|
}, "image/jpeg");
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
};
|
|
|
|
|
|
const onClose = () => {
|
|
|
crop.value.show = false;
|
|
|
};
|
|
|
|
|
|
const addCard = () => {
|
|
|
state.form.json5.cards.push({
|
|
|
bgColor: "#ffffff",
|
|
|
desc: "",
|
|
|
descColor: "#000000",
|
|
|
image: "",
|
|
|
// link: "",
|
|
|
title: "",
|
|
|
titleSize: "xl",
|
|
|
descSize: "sm",
|
|
|
titleColor: "#000000",
|
|
|
ratio: "20:13",
|
|
|
});
|
|
|
state.form.page = state.form.json5.cards.length;
|
|
|
};
|
|
|
|
|
|
const delCard = (page) => {
|
|
|
if (page > 1) {
|
|
|
state.form.page = page - 1;
|
|
|
}
|
|
|
state.form.json5.cards.splice(page - 1, 1);
|
|
|
};
|
|
|
|
|
|
const addBtn = (page) => {
|
|
|
if (!state.form.json5.cards[page - 1].btns) {
|
|
|
state.form.json5.cards[page - 1].btns = [];
|
|
|
}
|
|
|
|
|
|
state.form.json5.cards[page - 1].btns.push({
|
|
|
color: "#42659a",
|
|
|
link: "",
|
|
|
style: "primary",
|
|
|
text: "",
|
|
|
btnHeight: "md"
|
|
|
});
|
|
|
};
|
|
|
|
|
|
const addShareBtn = (page) => {
|
|
|
if (!state.form.json5.cards[page - 1].btns) {
|
|
|
state.form.json5.cards[page - 1].btns = [];
|
|
|
}
|
|
|
|
|
|
state.form.json5.cards[page - 1].btns.push({
|
|
|
color: "#42659a",
|
|
|
link: `${import.meta.env.VITE_APP_SEND_URL}?userid=${userid}&cardid=2`,
|
|
|
style: "primary",
|
|
|
text: "分享好友",
|
|
|
btnHeight: "md"
|
|
|
});
|
|
|
};
|
|
|
|
|
|
const moveCard = (type, page) => {
|
|
|
if (type === 0) {
|
|
|
if (page !== 1) {
|
|
|
[state.form.json5.cards[page - 1], state.form.json5.cards[page - 2]] =
|
|
|
[
|
|
|
state.form.json5.cards[page - 2],
|
|
|
state.form.json5.cards[page - 1],
|
|
|
];
|
|
|
state.form.page = page - 1;
|
|
|
}
|
|
|
} else {
|
|
|
if (page !== state.form.json5.cards.length) {
|
|
|
[state.form.json5.cards[page], state.form.json5.cards[page - 1]] = [
|
|
|
state.form.json5.cards[page - 1],
|
|
|
state.form.json5.cards[page],
|
|
|
];
|
|
|
state.form.page = page + 1;
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
|
|
|
const delBtn = (index) => {
|
|
|
// console.log('index',state.json5.cards[state.page-1].btns)
|
|
|
state.form.json5.cards[state.form.page - 1].btns.splice(index, 1);
|
|
|
if (state.form.json5.cards[state.form.page - 1].btns.length === 0) {
|
|
|
delete state.form.json5.cards[state.form.page - 1].btns;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
const moveBtn = (type, index) => {
|
|
|
if (type === 0) {
|
|
|
if (index !== 0) {
|
|
|
[
|
|
|
state.form.json5.cards[state.form.page - 1].btns[index],
|
|
|
state.form.json5.cards[state.form.page - 1].btns[index - 1],
|
|
|
] = [
|
|
|
state.form.json5.cards[state.form.page - 1].btns[index - 1],
|
|
|
state.form.json5.cards[state.form.page - 1].btns[index],
|
|
|
];
|
|
|
}
|
|
|
} else {
|
|
|
if (
|
|
|
index + 1 !==
|
|
|
state.form.json5.cards[state.form.page - 1].btns.length
|
|
|
) {
|
|
|
[
|
|
|
state.form.json5.cards[state.form.page - 1].btns[index + 1],
|
|
|
state.form.json5.cards[state.form.page - 1].btns[index],
|
|
|
] = [
|
|
|
state.form.json5.cards[state.form.page - 1].btns[index],
|
|
|
state.form.json5.cards[state.form.page - 1].btns[index + 1],
|
|
|
];
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
|
|
|
const afterRead = async (file, name) => {
|
|
|
// crop.value.show = true
|
|
|
// const ofile = file.file
|
|
|
// crop.value.img = URL.createObjectURL(ofile);
|
|
|
|
|
|
const imgFile = new FormData();
|
|
|
imgFile.append("fileType", "IMAGE");
|
|
|
imgFile.append("file", file.file);
|
|
|
|
|
|
showLoadingToast({
|
|
|
duration: 0,
|
|
|
message: "圖片上傳中...",
|
|
|
forbidClick: true,
|
|
|
});
|
|
|
|
|
|
let res = await axios.post(
|
|
|
`${import.meta.env.VITE_APP_API_URL}/card/uploadfile`,
|
|
|
imgFile,
|
|
|
{}
|
|
|
);
|
|
|
|
|
|
if (res.data.code == 200) {
|
|
|
state.form.json5.cards[state.form.page - 1].image = res.data.data;
|
|
|
|
|
|
showSuccessToast("上傳成功");
|
|
|
} else {
|
|
|
showToast.fail("上傳失敗");
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
};
|
|
|
|
|
|
const handleDelete = () => {
|
|
|
state.form.json5.cards[state.form.page - 1].image = "";
|
|
|
};
|
|
|
|
|
|
const handlePreview = () => {
|
|
|
router.push({
|
|
|
name: "AuthPreview",
|
|
|
params: { content: JSON.stringify(state.form) },
|
|
|
});
|
|
|
};
|
|
|
|
|
|
const changeSize = (type,size)=>{
|
|
|
switch(type){
|
|
|
case 'titleSize':
|
|
|
state.form.json5.cards[state.form.page - 1].titleSize = size;
|
|
|
break;
|
|
|
case 'descSize':
|
|
|
state.form.json5.cards[state.form.page - 1].descSize = size;
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
|
|
|
const handleSubmit = async () => {
|
|
|
if (!validateForm(state.form.json5.cards)) {
|
|
|
showToast("商務卡片欄位錯誤,紅色錯誤欄位請重新檢查!!");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
let user_id = userid;
|
|
|
|
|
|
showLoadingToast({
|
|
|
duration: 0,
|
|
|
message: "名片上傳中...",
|
|
|
forbidClick: true,
|
|
|
});
|
|
|
|
|
|
let res = await updateCusCard({
|
|
|
user_id: user_id,
|
|
|
card_title: state.form.title,
|
|
|
show_cus: state.form.showNfc,
|
|
|
cus_card: JSON.stringify(state.form),
|
|
|
});
|
|
|
if (res.code === 200) {
|
|
|
store.commit("user/setCusCard", JSON.stringify(state.form));
|
|
|
showSuccessToast("建立成功");
|
|
|
} else {
|
|
|
showToast.fail("建立失敗");
|
|
|
}
|
|
|
router.push("/auth/getauth");
|
|
|
};
|
|
|
//檢查表單是否為空
|
|
|
function validateForm(data) {
|
|
|
let pattern = /(https?:\/\/|line:\/\/|tel:|mailto:)\S+/;
|
|
|
|
|
|
for (let [index, val] of data.entries()) {
|
|
|
// let rtn = Object.values(val).some((v) => {
|
|
|
// return v == "" || v == null;
|
|
|
// });
|
|
|
let rtn = false
|
|
|
|
|
|
for(let i in val){
|
|
|
if(i !=='link' && (val[i] == "" || val[i] == null)){
|
|
|
rtn = true
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (rtn === true) {
|
|
|
state.form.page = index + 1;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// if(!pattern.test(val.link)){
|
|
|
// state.form.page = index+1
|
|
|
// return false
|
|
|
// }
|
|
|
if(val.link){
|
|
|
val.link = val.link.trim()
|
|
|
}
|
|
|
|
|
|
if (val.btns && val.btns.length > 0) {
|
|
|
for (let btn of val.btns) {
|
|
|
let rtn = Object.values(btn).some((v) => {
|
|
|
return v == "" || v == null;
|
|
|
});
|
|
|
|
|
|
if (rtn === true) {
|
|
|
state.form.page = index + 1;
|
|
|
return false;
|
|
|
}
|
|
|
btn.link = btn.link.trim()
|
|
|
|
|
|
if (!pattern.test(btn.link)) {
|
|
|
state.form.page = index + 1;
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
function validateBtn(data) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
return {
|
|
|
...toRefs(state),
|
|
|
sizeArr,
|
|
|
showPreview,
|
|
|
flexRef,
|
|
|
crop,
|
|
|
myCrop,
|
|
|
addCard,
|
|
|
delCard,
|
|
|
moveCard,
|
|
|
addBtn,
|
|
|
addShareBtn,
|
|
|
delBtn,
|
|
|
moveBtn,
|
|
|
afterRead,
|
|
|
handlePreview,
|
|
|
handleDelete,
|
|
|
changeSize,
|
|
|
handleSubmit,
|
|
|
onCrop,
|
|
|
onClose,
|
|
|
};
|
|
|
},
|
|
|
});
|
|
|
</script>
|
|
|
|
|
|
<style lang="less" scoped>
|
|
|
.form-control.form-control-color,
|
|
|
.was-validated .form-control.form-control-color:valid {
|
|
|
-moz-appearance: none;
|
|
|
-webkit-appearance: none;
|
|
|
appearance: none;
|
|
|
background: 0 0;
|
|
|
border: 1px solid #ced4da;
|
|
|
height: auto;
|
|
|
padding: 0.375rem;
|
|
|
width: 3rem;
|
|
|
padding-right: 0.375rem !important;
|
|
|
}
|
|
|
|
|
|
.card-title {
|
|
|
display: flex;
|
|
|
justify-content: center;
|
|
|
align-items: center;
|
|
|
|
|
|
div:nth-child(1) {
|
|
|
flex: 1;
|
|
|
}
|
|
|
|
|
|
div:nth-child(2) {
|
|
|
width: 120px;
|
|
|
}
|
|
|
|
|
|
div:nth-child(3) {
|
|
|
width: 90px;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.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;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.flex-section {
|
|
|
width: 100%;
|
|
|
}
|
|
|
</style>
|