You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

605 lines
16 KiB

<script setup>
import _ from 'lodash';
import { onMounted, onBeforeMount, ref } from 'vue'
import { toClipboard } from "@soerenmartius/vue3-clipboard";
import { showToast, showSuccessToast, showConfirmDialog } from 'vant';
import { useRoute } from 'vue-router';
import {
getUserFaviList
, getUserCateList
, updateUserCate
, setUserFaviCate
, addUserFavi
, deleteUserFavi
} from '@/api'
import { getAreaList } from '@/api/system';
const route = useRoute();
const setShowPicker = ref(false);
const selectVal1 = ref('all');
const selectVal2 = ref('普通');
const selectOpt1 = ref([{ text: '全部', value: 'all' }]);
const selectOpt2 = ref([{ text: '重要', value: '重要' }, { text: '普通', value: '普通' }]);
const addressList = ref([]);
onMounted(async () => {
if (route.query.act === 'add') {
let res = await addUserFavi({ uf_user_id: route.query.cardid });
}
initData();
getCateList();
});
const initData = async () => {
let res = await getUserFaviList(search.value);
if (res.code === 200) {
addressList.value = res.data;
}
};
const getCateList = async () => {
let res = await getUserCateList();
if (res.code === 200) {
columns.value = [columns.value[0], ...res.data];
columns2.value = [columns2.value[0], ...res.data];
if (res.data.length > 0) {
modalForm.value.sort = res.data;
} else {
modalForm.value.sort = [_.cloneDeep(defaultCate)];
}
}
}
// 複製連結
const doCopy = (text) => {
toClipboard(text);
showToast("已放入剪貼簿");
};
const handleDeleteFavi = async (id) => {
// vant 詢問是否刪除
showConfirmDialog({
title: '確認刪除',
message:
'是否確認刪除好友?',
cancelButtonText: '取消',
confirmButtonText: '確認',
})
.then(async () => {
let res = await deleteUserFavi(id);
if (res.code === 200) {
initData();
showSuccessToast('刪除成功')
} else {
showToast('刪除失敗')
}
})
.catch(() => {
});
};
const handleGoNfc = (item) => {
window.open(item.nfcurl, '_blank');
};
// START: 通訊錄類別
const fieldValue = ref('全部-全部');
const showCatePicker = ref(false);
const customFieldName = {
text: 'name',
value: 'id',
children: 'children',
};
const columns = ref([
{
id: 0,
name: '全部',
children: [
{
id: 0,
name: '全部'
}
]
},
]);
const onCateConfirm = async (value) => {
search.value.cate = value.selectedValues[1]
showCatePicker.value = false
};
const onCateChange = (value) => {
fieldValue.value = value.selectedOptions.map((item) => item.name).join('-');
};
// END: 通訊錄類別
// START: 更改好友類別
const columns2 = ref([
{
id: 0,
name: '未分類',
children: [
{
id: 0,
name: '未分類'
}
]
},
]);
const showChangeCatePicker = ref(false);
const changeUserId = ref('');
const handleChangeCate = (userId) => {
changeUserId.value = userId;
showChangeCatePicker.value = true;
};
const onChangeCateConfirm = async (value) => {
let res = await setUserFaviCate({ uf_user_id: changeUserId.value, cate_id: value.selectedValues[1] });
if (res.code === 200) {
getCateList();
showSuccessToast('更新成功')
} else {
showToast('更新失敗')
}
showChangeCatePicker.value = false;
};
const onChangeCateChange = (value) => {
console.log('Change Category');
};
// END: 更改好友類別
// START: 編輯通訊錄
const defaultCate = {
"id": 0,
"name": ""
};
const modalForm = ref({
page: 1,
sort: [_.cloneDeep(defaultCate)]
});
const sel1Change = (value) => {
if (value != 'all') {
let child = modalForm.value.sort[value].children;
let ary = [];
child.forEach((item, i) => {
ary.push({
text: item.name,
value: item.name
})
});
selectOpt2.value = ary;
selectVal2.value = child[0].name;
} else {
selectOpt2.value = [];
selectVal2.value = '';
}
};
const addCard = () => {
modalForm.value.sort.push(_.cloneDeep(defaultCate));
modalForm.value.page = modalForm.value.sort.length;
};
const delCard = (page) => {
if (page > 1) {
modalForm.value.page = page - 1;
}
modalForm.value.sort.splice(page - 1, 1);
};
const addBtn = (page) => {
if (!modalForm.value.sort[page - 1].children) {
modalForm.value.sort[page - 1].children = [];
}
modalForm.value.sort[page - 1].children.push(_.cloneDeep(defaultCate));
};
const moveCard = (type, page) => {
if (type === 0) {
if (page !== 1) {
[modalForm.value.sort[page - 1], modalForm.value.sort[page - 2]] = [
modalForm.value.sort[page - 2],
modalForm.value.sort[page - 1],
];
modalForm.value.page = page - 1;
}
} else {
if (page !== modalForm.value.sort.length) {
[modalForm.value.sort[page], modalForm.value.sort[page - 1]] = [
modalForm.value.sort[page - 1],
modalForm.value.sort[page],
];
modalForm.value.page = page + 1;
}
}
};
const delBtn = (index) => {
modalForm.value.sort[modalForm.value.page - 1].children.splice(index, 1);
if (modalForm.value.sort[modalForm.value.page - 1].children.length === 0) {
delete modalForm.value.sort[modalForm.value.page - 1].children;
}
};
const moveBtn = (type, index) => {
if (type === 0) {
if (index !== 0) {
[
modalForm.value.sort[modalForm.value.page - 1].children[index],
modalForm.value.sort[modalForm.value.page - 1].children[index - 1],
] = [
modalForm.value.sort[modalForm.value.page - 1].children[index - 1],
modalForm.value.sort[modalForm.value.page - 1].children[index],
];
}
} else {
if (index + 1 !== modalForm.value.sort[modalForm.value.page - 1].children.length) {
[
modalForm.value.sort[modalForm.value.page - 1].children[index + 1],
modalForm.value.sort[modalForm.value.page - 1].children[index],
] = [
modalForm.value.sort[modalForm.value.page - 1].children[index],
modalForm.value.sort[modalForm.value.page - 1].children[index + 1],
];
}
}
};
const onSubmit = async () => {
let res = await updateUserCate({ category: modalForm.value.sort })
if (res.code === 200) {
getCateList();
showSuccessToast('更新成功')
// router.push('/member')
} else {
console.log(res.code);
showToast('更新失敗')
}
};
const search = ref({
cate: 0,
area: 0,
sex: 2,
keyword: ''
});
const tab2showPicker = ref(false);
const tab3showPicker = ref(false)
const tab3columns = ref([])
const areaName = ref('')
//取得區域資料
let areaRes = await getAreaList()
if (areaRes.code === 200) {
tab3columns.value = areaRes.data
// tab3columns加上第一項為全部
tab3columns.value.unshift({
text: '全部',
value: 0
})
//取得區域名稱
// if (areaRes.data.length > 0) {
// const findRes = _.find(areaRes.data, { value: form.value.area })
// if (findRes) {
// areaName.value = findRes.text
// }
// }
}
const tab3OnConfirm = (value) => {
areaName.value = value.selectedOptions[0].text
search.value.area = value.selectedOptions[0].value
tab3showPicker.value = false
}
const tab4showPicker = ref(false);
const tab4columns = ref([
{
text: '全部',
value: 2
},
{
text: '男',
value: 1
},
{
text: '女',
value: 0
}
]);
const sexName = ref('')
const tab4OnConfirm = (value) => {
sexName.value = value.selectedOptions[0].text
search.value.sex = value.selectedOptions[0].value
tab4showPicker.value = false
}
const handleSearch = async () => {
let res = await getUserFaviList(search.value);
if (res.code === 200) {
addressList.value = res.data;
}
}
</script>
<template>
<div class="address page">
<van-nav-bar class="bg-skyBlue py-1" left-arrow right-arrow @click-left="$router.push('/')"
@click-right="setShowPicker = true">
<template #title>
<h5 class="text-white mb-1"><strong>通訊錄</strong></h5>
</template>
<template #left>
<h4><i class="fa-solid fa-angle-left text-white" :style="{ opacity: 0.5 }"></i></h4>
</template>
<template #right>
<h4><i class="fa-solid fa-gear text-white" :style="{ opacity: 0.5 }"></i></h4>
</template>
</van-nav-bar>
<div class="content">
<!-- START: 通訊錄類別 -->
<van-cell-group inset>
<van-field v-model="fieldValue" is-link readonly label="類別" placeholder="通訊錄類別" @click="showCatePicker = true" />
<van-popup v-model:show="showCatePicker" round position="bottom">
<van-picker :columns="columns" :columns-field-names="customFieldName" confirm-button-text="確認"
cancel-button-text="取消" @cancel="showCatePicker = false" @confirm="onCateConfirm" @change="onCateChange" />
</van-popup>
</van-cell-group>
<van-cell-group inset>
<van-row gutter="0" align="center">
<van-col span="5">
<van-field v-model="areaName" is-link readonly name="picker"
:border="false"
placeholder="縣市"
@click="tab3showPicker = true" />
<van-popup v-model:show="tab3showPicker" position="bottom">
<van-picker confirm-button-text="確認" cancel-button-text="取消" :columns="tab3columns" @confirm="tab3OnConfirm"
@cancel="tab3showPicker = false" />
</van-popup>
</van-col>
<van-col span="5">
<van-field v-model="sexName"
is-link
readonly
name="picker"
:border="false"
placeholder="性別"
@click="tab4showPicker = true" />
<van-popup v-model:show="tab4showPicker" position="bottom">
<van-picker confirm-button-text="確認" cancel-button-text="取消" :columns="tab4columns" @confirm="tab4OnConfirm"
@cancel="tab4showPicker = false" />
</van-popup>
</van-col>
<van-col span="14">
<van-search v-model="search.keyword" show-action placeholder="請輸入搜尋關鍵字" @search="handleSearch">
<template #action>
<van-button class="btn-darkBlue" @click="handleSearch">
搜索
</van-button>
</template>
</van-search>
</van-col>
</van-row>
</van-cell-group>
<!-- END: 通訊錄類別 -->
<van-cell-group inset>
<van-list>
<div class="list-item" v-for="(item, index) in addressList" :data-cateid="item.user_cate_id" :key="index">
<div class="left" @click="handleGoNfc(item)">
<div class="avatar"><img :src="item.avatar"></div>
<div class="text">
<h5 class="name ellipsis">{{ item.real_name }}</h5>
<div class="desc ellipsis">@{{ item.line }}</div>
</div>
</div>
<div class="right">
<van-button size="small" class="border-0" @click="handleChangeCate(item.user_id)">
<h5><i class="fa-solid fa-heart text-darkBlue"></i></h5>
</van-button>
<van-button size="small" class="border-0" @click="doCopy(item.nfcurl)">
<h5><i class="fa-solid fa-share-nodes text-darkBlue"></i></h5>
</van-button>
<van-button size="small" class="border-0" @click="handleDeleteFavi(item.uf_id)">
<h5><i class="fa-solid fa-trash text-darkBlue"></i></h5>
</van-button>
</div>
</div>
</van-list>
</van-cell-group>
</div>
<!-- START: 編輯通訊錄 -->
<van-dialog v-model:show="setShowPicker" width="400" showCancelButton confirm-button-text="確認修改" @confirm="onSubmit">
<van-form @submit="onSubmit">
<div id="app" class="address-block">
<div class="bg-lightPink px-2 pt-3">
<ul class="nav nav-tabs">
<li class="nav-item" v-for="(card, index) in modalForm.sort" :key="index"
@click="modalForm.page = index + 1">
<button type="button" class="nav-link" :class="{ active: modalForm.page === index + 1 }">
{{ index + 1 }}
</button>
</li>
<li class="nav-item" @click="addCard" v-if="modalForm.sort.length < 10">
<button type="button" class="nav-link">
<i class="fa fa-plus-circle"></i>
</button>
</li>
</ul>
</div>
<van-cell-group class="m-0 pt-2">
<van-field label="調整卡片順序" :border="false" v-if="modalForm.sort.length > 1">
<template #button>
<van-button size="small" class="ml-1 btn-skyBlue" icon="arrow-left"
@click="moveCard(0, modalForm.page)">前移</van-button>
<van-button size="small" class="ml-1 btn-skyBlue" icon="arrow"
@click="moveCard(1, modalForm.page)">後移</van-button>
<van-button size="small" class="ml-1 btn-tomatoRed" icon="delete-o"
@click="delCard(modalForm.page)"></van-button>
</template>
</van-field>
<van-field v-model="modalForm.sort[modalForm.page - 1].name" label="分類名稱" id="vcard-title" input-align="right"
placeholder="請輸入分類名稱" />
<div class="listCnt">
<div class="item" v-for="(btn, index) in modalForm.sort[modalForm.page - 1].children" :key="index">
<van-field v-model="btn.name" id="cardbtn-text-0" placeholder="請輸入子項目名稱" class="bg-transparent">
<template #button>
<van-button size="small" class="bg-transparent border-0" icon="arrow-up" @click="moveBtn(0, index)"
v-if="modalForm.sort[modalForm.page - 1].children.length > 1"></van-button>
<van-button size="small" class="bg-transparent border-0" icon="arrow-down" @click="moveBtn(1, index)"
v-if="modalForm.sort[modalForm.page - 1].children.length > 1"></van-button>
<van-button size="small" class="bg-transparent border-0" icon="delete-o"
@click="delBtn(index)"></van-button>
</template>
</van-field>
</div>
<van-button block class="btn-tomatoRed" icon="add-o" @click="addBtn(modalForm.page)">
<h6>新增按鈕</h6>
</van-button>
</div>
</van-cell-group>
</div>
</van-form>
</van-dialog>
<!-- END: 編輯通訊錄 -->
<van-popup v-model:show="showChangeCatePicker" round position="bottom">
<van-picker :columns="columns2" :columns-field-names="customFieldName" confirm-button-text=""
cancel-button-text="" @cancel="showChangeCatePicker = false" @confirm="onChangeCateConfirm"
@change="onChangeCateChange" />
</van-popup>
</div>
</template>
<style lang="less" scoped>
.address {
.content {
min-height: calc(100vh - 54px);
}
.van-list {
.list-item {
display: flex;
align-items: center;
flex-wrap: wrap;
padding: 15px 0;
margin: 0 15px;
border-bottom: 1px #e3e3e3 solid;
.left {
flex: 1 0 0%;
display: flex;
align-items: center;
.avatar {
width: 55px;
min-width: 55px;
aspect-ratio: 1/1;
border-radius: 50%;
margin-right: 10px;
overflow: hidden;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.name {
font-weight: bold;
}
}
.right {
flex: 0 0 auto;
}
.bottom {
flex: 1 0 100%;
border: 1px #e3e3e3 solid;
border-radius: 10px;
padding: 0 10px;
margin: 0;
transition: all .2s;
&.show {
padding: 10px;
margin: 5px 0;
}
}
}
}
.nav-tabs {
.nav-link {
color: #4a677d;
background-color: #fff;
border-color: transparent;
margin-right: 4px;
}
.nav-item.show .nav-link,
.nav-link.active {
color: #fff;
background-color: #4a677d;
border-color: #4a677d #4a677d #4a677d;
}
}
.listCnt {
padding: 15px;
.item {
margin-bottom: 15px;
border: 1px #ddd solid;
border-radius: 5px;
}
}
}
.address-block {
max-height: 80vh;
overflow-y: auto;
}
</style>