123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683 |
- <template>
- <view class="content">
- <view v-if="searchActive" class="navbar" style="padding-bottom: 20px;">
- <image @click="showBar()" class="icon" src="../../static/pics/search.png"></image>
- <image @click="navigateToPage('add')" class="icon" src="../../static/pics/add.png"></image>
- <image @click="navigateToPage('setting')" class="icon" src="../../static/pics/setting.png"></image>
-
- </view>
- <view class="navbar" v-else>
- <view class="uni-column">
- <view class="search-input">
- <input type="text" focus confirm-type="search" v-model="searchText" placeholder="输入号码或名字" @input="filterContacts" />
- </view>
- <view class="search-img" @click="showBar()">
- 取消
- </view>
- </view>
- </view>
- <view class="text-area">
- <view v-if="filteredContacts.length" v-for="(item, id) in filteredContacts" :key="id">
- <view class="name-btn">
-
- <view v-if="switchStatus" style="display: flex;flex-direction: row; ">
- <view class="loud" @click="play(item.displayName || item.phoneNumbers[0].value)">
- <image style="width: 80%;height: 40%; margin-left: 35rpx;" src="../../static/pics/laba.png"></image>
- </view>
- <view class="con-mes" @click="goToDetails(item)">
- <text v-if="!item.displayName">{{ formatPhoneNumber(item.phoneNumbers[0].value) }}</text>
- <text v-else>{{ truncate(item.displayName) }}</text>
- </view>
- </view>
-
- <view v-else>
- <view class="con-mes-null" @click="goToDetails(item)">
- <text v-if="!item.displayName">{{ formatPhoneNumber(item.phoneNumbers[0].value) }}</text>
- <text v-else>{{ truncate(item.displayName) }}</text>
- </view>
- </view>
-
- <NumbersChoose class="phonenumber-choose-component"
- :visible="isChooseNumberVisible[item.id] || false"
- :title="item.displayName"
- @update:visible="(visible) => this.$set(isChooseNumberVisible, item.id, visible)">
- <template #default>
- <div class="scrollable-box">
- <view v-for="(number, index) in item.phoneNumbers" :key="index" @click="CallPhone(item,number.value)">
- <text class="choose-phonenumber">
- {{formatPhoneNumber1(number.value) }}
- </text>
- </view>
- </div>
- </template>
- </NumbersChoose>
-
- <view class="btn" @click="showChooseNumber(item,item.phoneNumbers[0].value)">
- <image class="Call" src="../../static/pics/call-out.png"></image>
- </view>
- </view>
- </view>
- <view v-else class="notFind">
- 该号码或联系人不存在
- </view>
- </view>
- </view>
- </template>
- <script>
-
- function getInitials(str) {
-
- const initialsArray = pinyin(str, {
- style: pinyin.STYLE_FIRST_LETTER
- });
-
-
- const firstLettersOnly = initialsArray.map(initial => initial[0]);
-
-
- return firstLettersOnly.join('');
- }
- const FvvUniTTS=uni.requireNativePlugin('Fvv-UniTTS');
- import pinyin from "pinyin";
- import CustomModal from '@/components/customModal.vue';
- import NumbersChoose from '@/components/oppositePhonenumberChoose.vue'
-
- export default {
-
- components:{
- CustomModal,
- NumbersChoose,
-
- } ,
- data() {
- return {
- searchText: '',
- list: [],
- filteredContacts: [],
- num: '',
- isLoudVisible: true,
- searchActive: true,
- showModal:false,
- phoneNumbersCount:'',
- switchStatus:false,
- isChooseNumberVisible:{},
- isActive: false,
- };
- },
- onShow() {
-
- this.ToGetMessage();
-
- this.setLanguage();
- this.init();
- this.getM();
- },
- beforeCreate() {
- const domModule = uni.requireNativePlugin('dom')
- domModule.addRule('fontFace', {
- 'fontFamily': "myIconfont",
- 'src': "url('../assets/typeface/almmdfdk.ttf')"
- });
- },
- mounted() {
- this.filteredContacts.forEach(item => {
- this.$set(this.isChooseNumberVisible, item.id, false);
- });
- },
- methods: {
- showChooseNumber(item,phoneNumber){
- console.log("showChooseNumber called");
- console.log(new Error().stack);
- if(item.phoneNumbers.length>1){
- this.$set(this.isChooseNumberVisible,item.id,true)
- console.log("isChooseNumberVisible",this.isChooseNumberVisible)
- }
- else{
- console.log("这里对方只有一个电话号码")
- this.CallPhone(item,phoneNumber)
- }
- },
- toggleActive() {
- this.isActive = !this.isActive;
- },
- handleTouchedStart(){
- this.isActive=true;
- },
- handleTouchedEnd(){
- this.isActive=false;
- },
- toNum(e){
- console.log("num",e);
- this.num=e;
- },
-
- formatPhoneNumber(value) {
-
- value = value.replace(/\D/g, '');
-
- if (value.length === 11) {
-
- return value.replace(/(\d{3})(\d{4})(\d{4})/, '$1 $2 $3');
- } else {
-
- return value.replace(/(\d{4})(?=\d)/g, '$1 ');
- }
- },
- formatPhoneNumber1(value) {
-
- value = value.replace(/\D/g, '');
-
- if (value.length === 11) {
-
- return value.replace(/(\d{3})(\d{4})(\d{4})/, '$1\n$2 $3');
- } else if (value.length > 11) {
-
- return value.replace(/(\d{3})(\d{4})(\d{4})/, '$1\n$2 $3') + '...';
- } else {
-
-
- return value.replace(/(\d{4})(\d{3})/, '$1\n$2').replace(/(\d{4})(?=\d)/g, '$1 ');
- }
- },
- truncate(value) {
- if (value.length > 9) {
- return value.slice(0, 5) + '\n' + value.substring(5, 9) + '...';
- }
- else{
- return value.slice(0, 5) + '\n' + value.substring(5, 9)
- }
- return value;
- },
-
-
- init(){
-
- FvvUniTTS.init((callback) => {
- console.log(callback);
- },"com.iflytek.speechcloud");
-
- FvvUniTTS.onStart((res) => {
- console.log("onStart:" + res)
- });
-
- FvvUniTTS.onDone((res) => {
- console.log("onDone:" + res)
- });
-
- FvvUniTTS.onError((res) => {
- console.log("onError:" + res)
- });
- FvvUniTTS.getInstallTTS(res => {
- console.log(res+"11")
- })
- },
- play(e){
- console.log("xinxi",e)
- FvvUniTTS.speak({
- text:e,
- id:2,
- });
-
- FvvUniTTS.getInstallTTS(res => {
- console.log(res+"11")
- })
- },
- setLanguage(){
- console.log("set lang : " + FvvUniTTS.setLanguage("CHINESE"));
- },
- setEngines(){
- let setEngine = "com.iflytek.speechcloud"
-
-
- FvvUniTTS.getInstallTTS(res => {
- if(res == null || res.length <= 0){
- return
- }
- console.log(res)
- if(JSON.stringify(res).indexOf(setEngine) < 0){
- console.log("未安装该语音引擎")
- return
- }
- console.log("set engine : " + FvvUniTTS.setEngine(setEngine));
- FvvUniTTS.speak({
- text:"设置成功",
- id:2,
- });
- })
- },
- saveFile(){
- FvvUniTTS.saveAudioFile({
- text:"hello",
- id:3,
- path:"/sdcard/test/1.wav"
- })
- },
- setVoice(){
- FvvUniTTS.setPitch(100)
- FvvUniTTS.setSpeechRate(100)
- },
- navigateToPage(page) {
- switch (page) {
- case 'add':
-
- uni.navigateTo({
- url: '/pages/add/add'
- });
- break;
- case 'setting':
-
- uni.navigateTo({
- url: '/pages/setting/setting'
- });
- break;
- default:
- break;
- }
- },
-
- showBar() {
- this.searchActive = !this.searchActive;
- this.ToGetMessage();
- },
-
- ToGetMessage() {
- var that = this;
-
- plus.contacts.getAddressBook(plus.contacts.ADDRESSBOOK_PHONE, function(addressbook) {
- addressbook.find(["displayName", "phoneNumbers"], function(contacts) {
- that.list = contacts;
- console.log(that.list)
-
-
- that.list.sort(function(a, b) {
-
- const isChinese = (str) => /^[\u4e00-\u9fa5]+$/.test(str);
- const isEnglish = (str) => /^[A-Za-z]+$/.test(str);
- const isNumber = (str) => /^[0-9]+$/.test(str);
-
-
- let firstCharA = a.displayName ? a.displayName.trim()[0] : a.phoneNumbers[0].value;
- let firstCharB = b.displayName ? b.displayName.trim()[0] : b.phoneNumbers[0].value;
-
-
- if (isChinese(firstCharA)) {
- firstCharA = pinyin(firstCharA, { style: pinyin.STYLE_FIRST_LETTER })[0][0];
- }
- if (isChinese(firstCharB)) {
- firstCharB = pinyin(firstCharB, { style: pinyin.STYLE_FIRST_LETTER })[0][0];
- }
-
-
- if (isEnglish(firstCharA) && isEnglish(firstCharB)) {
-
- return firstCharA.localeCompare(firstCharB);
- } else if (isChinese(firstCharA) && isChinese(firstCharB)) {
-
- return firstCharA.localeCompare(firstCharB);
- } else if ((isEnglish(firstCharA) || isChinese(firstCharA)) && (isNumber(firstCharB) || !isEnglish(firstCharB))) {
-
- return -1;
- } else if ((isNumber(firstCharA) || !isEnglish(firstCharA)) && (isEnglish(firstCharB) || isChinese(firstCharB))) {
-
- return 1;
- } else {
-
- return firstCharA.localeCompare(firstCharB);
- }
- });
-
-
- console.log("list",that.list);
- that.filteredContacts = that.list;
- console.error("更新过滤后的联系人列表",that.filteredContacts)
- }, function() {
- uni.showToast({
- title: '获取联系人失败',
- duration: 2000
- });
- }, { multiple: true });
- }, function(e) {
- uni.showToast({
- title: '获取通讯录对象失败:' + e.message,
- duration: 2000
- });
- });
- },
-
- CallPhone(item,e) {
-
- Object.keys(this.isChooseNumberVisible).forEach(key=>{
- this.$set(this.isChooseNumberVisible,key,false);
- });
- console.log("ischooseNumber",this.isChooseNumberVisible)
- // 调用HTML5 Plus框架提供的接口
- plus.device.dial(e, false);
- Object.keys(this.isChooseNumberVisible).forEach(key=>{
- this.$set(this.isChooseNumberVisible,key,false);
- });
- },
- filterContacts() {
-
- const searchText = this.searchText.toLowerCase();
- console.log("输入内容",searchText)
- if (!searchText) {
-
- console.log("kong")
- this.filteredContacts = this.list;
-
- } else {
-
- this.filteredContacts = this.list.filter(contact => {
-
- const isFuzzyMatch = (contact.displayName || '').toLowerCase().includes(searchText) ||
- contact.phoneNumbers.some(phone => phone.value.toLowerCase().includes(searchText));
-
-
- const displayNameFirstLetters = getInitials(contact.displayName || '');
- const isInitialsMatch = displayNameFirstLetters.includes(searchText);
-
-
- return isFuzzyMatch || isInitialsMatch;
- });
- }
- },
-
- search() {
-
- this.filterContacts();
- },
-
- goToDetails(item){
- console.error('item',item)
- const phoneNumbers=item.phoneNumbers
- const phoneNumbersString=JSON.stringify(phoneNumbers)
- const phoenNumberCount=item.phoneNumbers.length;
- console.error("phonenumber",phoneNumbers)
- console.error("phoenNumberCount",phoenNumberCount)
- uni.navigateTo({
- url: `/pages/ContactDetails/ContactDetails?name=${encodeURIComponent(item.displayName)}&phoneNumbers=${encodeURIComponent(phoneNumbersString)}&count=${phoenNumberCount}`
- });
- },
- getM(){
-
- const storedSwitchStatus = uni.getStorageSync('voiceBroadcastSwitch');
- console.log("读取的本地存储状态1:", storedSwitchStatus);
-
- if (typeof storedSwitchStatus === 'boolean') {
- this.switchStatus = storedSwitchStatus;
- }
- }
- },
- mounted() {
- this.getM();
- }
- }
- </script>
- <style>
- .floating-button {
- width: 50px;
- height: 300px;
- border-radius: 25px;
- background-color: rgba(0, 0, 0, 0.5);
- position: fixed;
- right: 20px;
- bottom: 20px;
- overflow: hidden;
- z-index: 1000;
- }
- .alphabet-scroll {
- width: 100%;
- height: 100%;
- background-color: #fff;
- }
- .alphabet-item {
- padding: 5px 10px;
- text-align: center;
- cursor: pointer;
- }
- .alphabet-item.active {
- background-color: #007AFF;
- color: #fff;
- }
-
- .notFind{
- font-size: 50rpx;
- }
-
- .null {}
- .uni-column {
- width: 690rpx;
- height: 140rpx;
- border: 1px solid black;
- margin-top: 18rpx;
- border-radius: 20rpx;
- font-size: 50rpx;
- display: flex;
- justify-content: space-between;
-
- }
- .search-input {
- width: 75%;
-
- display: flex;
- align-items: center;
- }
- .search-img {
- width: 25%;
-
- display: flex;
- border-left: 1px solid black;
- justify-content: center;
- align-items: center;
- }
- .search-input input {
-
- width: 90%;
- height: 90%;
- font-size: 50rpx;
- padding: 10px;
- }
- .search-img image {
- width: 50%;
- height: 50%;
- font-size: 50rpx;
- }
- .content {
- min-height: 100%;
- display: flex;
- flex-direction: column;
- justify-content: center;
- background-color: #f0efef;
- }
- .con-mes,.con-mes-null {
- font-family: 'FangSong', '仿宋_GB2312', serif;
- font-size: 35px;
- font-weight: 700;
- display: flex;
- align-items: center;
- justify-content: center;
- text-align: center;
- white-space: pre-line;
- word-wrap: break-word;
- width: 410rpx;
- height: 200rpx;
- border: none;
- background-color: white;
- }
- .con-mes-null{
- border-radius: 20rpx 0rpx 0rpx 20rpx;
- width: 510rpx;
- height: 200rpx;
- }
- .name-btn {
- display: flex;
- align-items: center;
- justify-content: space-between;
- width: 690rpx;
- height: 200rpx;
- border: 0.5px solid black;
- margin-top: 8rpx;
- margin-bottom: 10rpx;
- border-radius: 20rpx;
- font-size: 50rpx;
- }
- .text-area {
- padding-top: 145px;
- display: flex;
- flex-direction: column;
- align-items: center;
- }
- .loud {
- display: flex;
- justify-content: center;
- align-items: center;
- width: 100rpx;
- height: 200rpx;
- border-radius: 20rpx 0rpx 0rpx 20rpx;
- background-color: white;
- }
- .btn {
- display: flex;
- justify-content: center;
- align-items: center;
- width: 180rpx;
- height: 200rpx;
- background-color: #ecfff3;
- border-radius: 0rpx 20rpx 20rpx 0rpx;
- }
- .Call {
- width: 100rpx;
- height: 100rpx;
- object-fit: contain;
- }
- .navbar {
- display: flex;
- justify-content: space-around;
- align-items: flex-end;
- width: 100%;
- background-color: #f0efef;
- min-height: 120px;
- padding-bottom: 20px;
- position: fixed;
- top: 0;
- z-index: 999;
- }
- .icon {
- justify-content: space-around;
- width: 100rpx;
- height: 100rpx;
- }
- .uni-tabbar__iconfont {
- font-size: 50px;
- width: 80px;
- height: 80px;
- }
- .numbers{
- }
- .choose-phonenumber1{
- display: flex;
- align-items: center;
- text-align: center;
- justify-content: center;
- font-size: 80rpx;
- border-left: 5px solid #9ee493;
- border-radius: 6px;
- background-color: white;
- padding: 10px;
- margin-top: 10px;
- margin-bottom: 10px;
-
- }
-
- .scrollable-box {
- height: 700rpx;
- overflow-y: auto;
- scrollbar-width: thin;
- }
- .choose-phonenumber{
- display: flex;
- text-align: center;
- width: 90%;
- align-items: center;
- justify-content: center;
- font-size: 100rpx;
- border-radius: 10px;
- background-color: #c6ffcf;
- padding: 10px;
- margin-top: 10px;
- margin-bottom: 10px;
- }
- .choose-phonenumber.active {
- background-color: #b0b0b0;
- }
- .line{
-
- width: 100%;
- height: 2rpx;
- background-color: #dbdbdb;
- margin: 9rpx 0;
- }
- movable-view {
- display: flex;
- align-items: center;
- justify-content: center;
- height: 150rpx;
- width: 150rpx;
- background-color: #007AFF;
- color: #fff;
- }
- movable-area {
- height: 300rpx;
- width: 100%;
- background-color: #D8D8D8;
- overflow: hidden;
- }
- .max {
- width:500rpx;
- height: 500rpx;
- }
- </style>
|