1/** 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import ContactsModel from "../model/ContactsModel"; 17import ConversationModel from "../model/ConversationModel"; 18import common from "../data/commonData"; 19import HiLog from "../utils//HiLog"; 20import conversationListService from "./ConversationListService"; 21import telephoneUtils from "../utils/TelephoneUtil"; 22import contractService from "./ContractService"; 23import commonService from "./CommonService"; 24import LooseObject from "../data/LooseObject" 25import MmsPreferences from "../utils/MmsPreferences"; 26 27const TAG = "ConversationService"; 28 29let mConversationModel = new ConversationModel(); 30 31export default { 32 33 /** 34 * Check whether a contact exists. 35 * 36 * @param params contact phone number 37 * @callback Whether the contact exists 38 */ 39 judgeContactExists(actionData, callback) { 40 globalThis.DataWorker.sendRequest("queryContactDataByTelephone", { 41 actionData: actionData, 42 context: globalThis.mmsContext 43 }, result => { 44 let hasExitContract = false; 45 if (result.length >= 1) { 46 // Whether the contact exists 47 hasExitContract = true; 48 } 49 callback(hasExitContract); 50 }); 51 }, 52 53 /** 54 * Obtain information details. 55 * 56 * @param params phone number/session id 57 * @callback callback 58 */ 59 queryMessageDetail(actionData, callback) { 60 globalThis.DataWorker.sendRequest("queryMessageDetail", { 61 actionData: actionData, 62 context: globalThis.mmsContext 63 }, res => { 64 let result: LooseObject = {}; 65 result.code = res.code; 66 if (res.code == common.int.SUCCESS) { 67 this.groupDetailMessage(res.abilityResult, actionData, resultList => { 68 result.response = resultList; 69 callback(result); 70 }); 71 } else { 72 HiLog.w(TAG, "queryMessageDetail, failed"); 73 callback(result); 74 } 75 }); 76 }, 77 78 convertConversationList(mmsList) { 79 let resultList = []; 80 for (let item of mmsList) { 81 let result: LooseObject = {}; 82 result.id = item.msgId; 83 result.content = item.msgContent; 84 result.isLock = item.isLock == 0 ? false : true; 85 result.isStared = item.isCollect == 0 ? false : true; 86 // Fields related to MMS messages 87 result.msgType = 0; 88 result.isFullScreenImg = true; 89 result.read = item.isRead == 0 ? "0" : "1"; 90 if (item.msgState == 0) { 91 result.sendStatus = common.int.SEND_MESSAGE_SUCCESS; 92 } else if (item.msgState == 2) { 93 result.sendStatus = common.int.SEND_MESSAGE_FAILED; 94 } else if (item.msgState == 1) { 95 result.sendStatus = common.int.SEND_MESSAGE_SENDING; 96 } else { 97 result.sendStatus = common.int.SEND_DRAFT; 98 } 99 result.subId = item.slotId; 100 result.timeMillisecond = item.startTime; 101 result.isMsm = item.msgType == 0 ? false : true; 102 result.isCbChecked = false; 103 result.isDraft = false; 104 // Fields related to group-sending 105 result.groupId = item.groupId; 106 // Determine whether it is the receiver or sender. 107 result.isReceive = item.isSender == 0 ? false : true; 108 result.date = common.string.EMPTY_STR; 109 result.time = common.string.EMPTY_STR; 110 result.completeNumber = 0; 111 result.failuresNumber = 0; 112 result.hasReport = item.isSendReport == 0 ? false : true; 113 if (!result.isMsm) { 114 result.msgShowType = common.MESSAGE_SHOW_TYPE.NORMAL; 115 } 116 resultList.push(result); 117 } 118 return resultList; 119 }, 120 121 groupDetailMessage(mmsList, actionData, callback) { 122 let details = this.convertConversationList(mmsList); 123 let msgIds = []; 124 if (actionData.contactsNum == 1) { 125 for (let item of details) { 126 if (item.isMsm) { 127 msgIds.push(item.id); 128 } 129 } 130 this.dealMmsPartData(details, msgIds, actionData, res => { 131 callback(res); 132 }); 133 return; 134 } 135 let resultList = []; 136 // Group by groupId. 137 let detailMap = this.convertConversationMap(details); 138 // By group 139 let groupIds = detailMap.keys(); 140 for (let groupId of groupIds) { 141 let groups = detailMap.get(groupId); 142 let result = groups[0]; 143 let failuresNumber = 0; 144 let completeNumber = 0; 145 if (result.isMsm) { 146 msgIds.push(result.id); 147 } 148 for (let item of groups) { 149 if (item.sendStatus == common.int.SEND_MESSAGE_FAILED) { 150 failuresNumber++; 151 } 152 if (item.sendStatus == common.int.SEND_MESSAGE_FAILED || 153 item.sendStatus == common.int.SEND_MESSAGE_SUCCESS) { 154 completeNumber++; 155 } 156 } 157 result.completeNumber = completeNumber; 158 result.failuresNumber = failuresNumber; 159 resultList.push(result); 160 } 161 this.dealMmsPartData(resultList, msgIds, actionData, res => { 162 callback(res); 163 }); 164 }, 165 166 dealMmsPartData(resultList, msgIds, actionData, callback) { 167 if (msgIds.length == 0) { 168 callback(resultList); 169 return; 170 } 171 actionData.msgIds = msgIds; 172 this.queryMmsPartByIds(actionData, res => { 173 let mmsParts = res.response; 174 let mmsPartMap = new Map(); 175 for (let item of mmsParts) { 176 if (mmsPartMap.has(item.msgId)) { 177 let strings = mmsPartMap.get(item.msgId); 178 strings.push(item); 179 } else { 180 let strings = []; 181 strings.push(item); 182 mmsPartMap.set(item.msgId, strings); 183 } 184 } 185 for (let item of resultList) { 186 if (mmsPartMap.has(item.id)) { 187 let mmsParts = mmsPartMap.get(item.id); 188 // Determine whether to display 0 common style, 1 theme, and 2 slides, 189 item.mms = commonService.getMmsSource(mmsParts); 190 item.msgShowType = commonService.getDisplay(item.mms); 191 commonService.setItemMmsContent(item, item.mms); 192 } 193 } 194 callback(resultList); 195 }); 196 }, 197 198 convertConversationMap(details) { 199 let conversationMap = new Map(); 200 // grouping 201 for (let element of details) { 202 if (conversationMap.has(element.groupId)) { 203 let groups = conversationMap.get(element.groupId); 204 groups.push(element); 205 } else { 206 let groups = []; 207 groups.push(element); 208 conversationMap.set(element.groupId, groups); 209 } 210 } 211 return conversationMap; 212 }, 213 214 /** 215 * Inserting session details and sms details 216 * 217 * @param actionData 218 * @callback callback 219 */ 220 insertSessionAndDetail(actionData, callback): void { 221 let sendResults: Array<LooseObject> = actionData.sendResults; 222 let isReceive: boolean = actionData.isReceive; 223 if (sendResults.length == 0) { 224 HiLog.w(TAG, "insertSessionAndDetail, sendResults.length == 0"); 225 return; 226 } 227 let param: LooseObject = this.dealSendResults(sendResults); 228 // Check whether a session list has been created. 229 conversationListService.querySessionByTelephone(param.telephone, res => { 230 let response = res.response; 231 if (res.code == common.int.SUCCESS && response.id <= 0) { 232 this.dealNoExitingSession(isReceive, param, actionData, callback); 233 } else { 234 this.dealExitingSession(response, param, actionData, callback); 235 } 236 }); 237 }, 238 239 dealNoExitingSession(isReceive, param, actionData, callback) { 240 let unreadCount = 0; 241 if (isReceive) { 242 unreadCount = 1; 243 } 244 let valueBucket: LooseObject = { 245 "telephone": param.telephone, 246 "content": param.content, 247 "contacts_num": param.contractsNum, 248 "sms_type": param.smsType, 249 "unread_count": unreadCount, 250 "sending_status": param.sendStatus, 251 "has_draft": 0, 252 "time": param.timestamp, 253 "message_count": 1, 254 "has_mms": actionData.isMms ? 1 : 0, 255 "has_attachment": actionData.hasAttachment ? 1 : 0 256 } 257 conversationListService.insertSession(valueBucket, sessionResult => { 258 HiLog.i(TAG, "dealNoExitingSession, insertSession callback"); 259 // Invoke the SMS database to insert SMS messages. 260 this.dealInsertMessageDetail(param, actionData, sessionResult.rowId, res => { 261 let result = { 262 rowId: sessionResult.rowId, 263 initDatas: res.initDatas, 264 groupId: res.groupId 265 } 266 callback(result); 267 }); 268 }); 269 }, 270 271 dealExitingSession(response, param, actionData, callback): void { 272 let sessionId = response.id; 273 // Invoke the SMS database to insert SMS messages. 274 let threadIds = [sessionId]; 275 let time = new Date(); 276 let unreadCount: number = 0; 277 if (actionData.isReceive) { 278 unreadCount = response.unreadCount; 279 unreadCount = unreadCount + 1; 280 } 281 let hasDraft = response.hasDraft; 282 if (actionData.hasDraft && hasDraft == 1) { 283 hasDraft = 0; 284 } 285 let messageCount = response.messageCount; 286 messageCount = messageCount + 1; 287 let valueBucket: LooseObject = { 288 "content": param.content, 289 "unread_count": unreadCount, 290 "time": time.getTime(), 291 "sending_status": param.sendStatus, 292 "has_draft": hasDraft, 293 "message_count": messageCount, 294 "has_attachment": actionData.hasAttachment ? 1 : 0, 295 "has_mms": actionData.isMms ? 1 : 0, 296 } 297 conversationListService.updateById(threadIds, valueBucket); 298 // Invoke the SMS database to insert SMS messages. 299 this.dealInsertMessageDetail(param, actionData, sessionId, res => { 300 let result: LooseObject = { 301 rowId: sessionId, 302 initDatas: res.initDatas, 303 groupId: res.groupId 304 } 305 callback(result); 306 }); 307 }, 308 309 dealInsertMessageDetail(param, actionData, threadId, callback) { 310 this.queryMaxGroupId(actionData, res => { 311 let maxGroupId: number = 0; 312 if (res.code === common.int.SUCCESS) { 313 HiLog.i(TAG, "dealInsertMessageDetail, queryMaxGroupId maxGroupId=" + res.response.maxGroupId) 314 maxGroupId = res.response.maxGroupId == common.string.EMPTY_STR ? 0 : Number(res.response.maxGroupId); 315 maxGroupId = maxGroupId + 1; 316 } else { 317 HiLog.w(TAG, "dealInsertMessageDetail, queryMaxGroupId failed"); 318 callback(); 319 } 320 this.insertMessageDetailByMaxGroupId(param, actionData, threadId, maxGroupId, result => { 321 callback(result); 322 }); 323 }); 324 }, 325 326 insertMessageDetailByMaxGroupId(param, actionData, threadId, maxGroupId, callback) { 327 let count: number = 0; 328 let initDatas: Array<LooseObject> = []; 329 let result: LooseObject = {}; 330 result.groupId = maxGroupId; 331 let sendResults = actionData.sendResults; 332 sendResults.forEach(sendResult => { 333 let insertDetail: LooseObject = this.initInsertDetail(param, actionData, threadId, maxGroupId); 334 if (actionData.isReceive) { 335 insertDetail.receiverNumber = actionData.ownNumber; 336 insertDetail.senderNumber = sendResult.telephone; 337 insertDetail.isRead = 0; 338 } else { 339 insertDetail.receiverNumber = sendResult.telephone; 340 insertDetail.senderNumber = actionData.ownNumber; 341 insertDetail.isRead = 1; 342 } 343 insertDetail.sendStatus = sendResult.sendStatus; 344 if (sendResult.sendStatus == common.int.SEND_MESSAGE_FAILED) { 345 insertDetail.sendStatus = 2; 346 } else if (sendResult.sendStatus == common.int.SEND_MESSAGE_SUCCESS) { 347 insertDetail.sendStatus = 0; 348 } 349 if (sendResult.time != null) { 350 insertDetail.time = sendResult.time; 351 } 352 if (sendResult.slotId != null) { 353 insertDetail.slotId = sendResult.slotId; 354 } 355 this.insertMessageDetail(insertDetail, id => { 356 HiLog.d(TAG, "insertMessageDetailByMaxGroupId, insertMessageDetail id=" + id); 357 count++; 358 let initData: LooseObject = { 359 id: id, 360 telephone: sendResult.telephone 361 }; 362 initDatas.push(initData); 363 if (count == actionData.sendResults.length) { 364 result.initDatas = initDatas; 365 callback(result); 366 } 367 }); 368 }) 369 }, 370 371 initInsertDetail(param, actionData, threadId, maxGroupId) { 372 let insertDetail: LooseObject = { 373 slotId: common.int.SIM_ONE, 374 receiverNumber: common.string.EMPTY_STR, 375 senderNumber: common.string.EMPTY_STR, 376 smsType: param.smsType, 377 content: param.content, 378 sendStatus: common.int.SEND_MESSAGE_FAILED, 379 sessionType: 0, 380 threadId: threadId, 381 isSender: actionData.isSender, 382 groupId: maxGroupId, 383 time: common.string.EMPTY_STR, 384 hasReport: actionData.hasReport, 385 isMms: actionData.isMms, 386 mmsSource: actionData.mmsSource, 387 messageType: actionData.messageType 388 }; 389 return insertDetail; 390 }, 391 392 dealSendResults(sendResults: Array<LooseObject>): LooseObject { 393 let contractsNum: number = sendResults.length; 394 let telephone: string = common.string.EMPTY_STR; 395 let content: string = common.string.EMPTY_STR; 396 let sendStatus: number = common.int.SEND_MESSAGE_SUCCESS; 397 let failSum: number = 0; 398 let time = common.string.EMPTY_STR; 399 for (let sendResult of sendResults) { 400 telephone = telephone + sendResult.telephone + common.string.COMMA; 401 content = sendResult.content; 402 sendStatus = sendResult.sendStatus; 403 if (sendResult.sendStatus == common.int.SEND_MESSAGE_FAILED) { 404 failSum++; 405 } 406 if (sendResult.time != null) { 407 time = sendResult.time; 408 } 409 if (sendResult.isMessageSim != null && sendResult.isMessageSim) { 410 telephone = sendResult.telephone; 411 contractsNum = 1; 412 } 413 } 414 // If it fails, then the session list turns out to be a failure. 415 if (failSum > 0) { 416 sendStatus = common.int.SEND_MESSAGE_FAILED; 417 } 418 telephone = telephone.substring(0, telephone.length - 1); 419 let smsType: number = 0; 420 if (contractsNum == 1 && telephoneUtils.judgeIsInfoMsg(telephone)) { 421 smsType = 1; 422 } 423 let result: LooseObject = {}; 424 let timestamp = new Date().getTime(); 425 result.contractsNum = contractsNum; 426 result.content = content; 427 result.telephone = telephoneUtils.dealTelephoneSort(telephone); 428 result.sendStatus = sendStatus; 429 result.timestamp = time != common.string.EMPTY_STR ? time : timestamp; 430 result.smsType = smsType; 431 return result; 432 }, 433 434 /** 435 * Inserting sms messages 436 * 437 * @param actionData session ids 438 * @callback callback 439 */ 440 insertMessageDetail(param, callback) { 441 let actionData: LooseObject = {}; 442 let time = new Date(); 443 let timeStr = param.time != common.string.EMPTY_STR ? param.time : time.getTime() + common.string.EMPTY_STR; 444 let stringValue: LooseObject = { 445 "slot_id": common.int.SIM_ONE, 446 "receiver_number": param.receiverNumber, 447 "sender_number": param.senderNumber, 448 "start_time": timeStr, 449 "end_time": timeStr, 450 "msg_type": param.isMms ? "1" : "0", 451 "sms_type": param.smsType, 452 "msg_title": param.content, 453 "msg_content": param.content, 454 "msg_state": param.sendStatus, 455 "operator_service_number": common.string.EMPTY_STR, 456 "msg_code": common.string.EMPTY_STR, 457 "session_id": param.threadId, 458 "is_lock": "0", 459 "is_read": param.isRead, 460 "is_collect": "0", 461 "session_type": param.sessionType, 462 "is_sender": param.isSender, 463 "group_id": param.groupId, 464 "is_send_report": param.hasReport 465 }; 466 if (param.slotId != null) { 467 stringValue.slot_id = param.slotId; 468 } 469 actionData.stringValue = stringValue; 470 actionData.featureAbility = param.featureAbility; 471 globalThis.DataWorker.sendRequest("insertMessageDetail", { 472 actionData: actionData, 473 context: globalThis.mmsContext 474 }, result => { 475 if (result.code == common.int.SUCCESS) { 476 this.dealBatchInsertMmsPart(param, result, callback); 477 } else { 478 HiLog.w(TAG, "insertMessageDetail, fail"); 479 } 480 }); 481 }, 482 483 dealBatchInsertMmsPart(param, result, callback) { 484 if (param.isMms) { 485 param.msgId = result.abilityResult; 486 this.batchInsertMmsPart(param, res => { 487 callback(result.abilityResult); 488 }); 489 } else { 490 callback(result.abilityResult); 491 } 492 }, 493 494 batchInsertMmsPart(param, callback) { 495 let actionData: LooseObject = {}; 496 actionData.featureAbility = param.featureAbility; 497 let batchMmsParts: Array<LooseObject> = []; 498 for (let mms of param.mmsSource) { 499 let stringValue = { 500 "msg_id": param.msgId, 501 "group_id": param.groupId, 502 "type": mms.msgType, 503 "location_path": mms.msgUriPath, 504 "content": mms.content, 505 "recording_time": mms.time, 506 "part_size": (mms.fileSize + ''), 507 "state": param.messageType 508 }; 509 batchMmsParts.push(stringValue); 510 } 511 actionData.batchMmsParts = batchMmsParts; 512 globalThis.DataWorker.sendRequest("batchInsertMmsPart", { 513 actionData: actionData, 514 context: globalThis.mmsContext 515 }, result => { 516 callback(result); 517 }); 518 }, 519 520 updateSessionAndDetail(actionData) { 521 let sendResults = actionData.sendResults; 522 if (sendResults.length == 0) { 523 return; 524 } 525 let param = this.dealSendResults(sendResults); 526 // Update the status of the session list. 527 let threadIds = [actionData.threadId]; 528 let valueBucket = { 529 "sending_status": param.sendStatus, 530 "content": param.content 531 } 532 conversationListService.updateById(threadIds, valueBucket); 533 // Update the status of the information list. 534 for (let sendResult of sendResults) { 535 actionData.sendStatus = sendResult.sendStatus; 536 if (sendResult.sendStatus == common.int.SEND_MESSAGE_FAILED) { 537 actionData.sendStatus = 2; 538 } else if (sendResult.sendStatus == common.int.SEND_MESSAGE_SUCCESS) { 539 actionData.sendStatus = 0; 540 } else { 541 actionData.sendStatus = 1; 542 } 543 actionData.msgId = sendResult.id; 544 this.updateById(actionData, result => { 545 }); 546 } 547 }, 548 549 /** 550 * Deletes list data in batches based on session ids. 551 * 552 * @param actionData session ids 553 */ 554 deleteMessageBySessionIds(actionData) { 555 globalThis.DataWorker.sendRequest("queryGroupIdBySessionId", { 556 actionData: actionData, 557 context: globalThis.mmsContext 558 }, res => { 559 if (res.code == common.int.SUCCESS) { 560 globalThis.DataWorker.sendRequest("deleteMessageBySessionIds", { 561 actionData: actionData, 562 context: globalThis.mmsContext 563 }, res => { 564 // do nothing 565 }); 566 let groupIds = res.abilityResult; 567 actionData.groupIds = groupIds; 568 globalThis.DataWorker.sendRequest("deleteMmsPartByGroupIds", { 569 actionData: actionData, 570 context: globalThis.mmsContext 571 }, res => { 572 // do nothing 573 }); 574 } 575 }); 576 }, 577 578 /** 579 * Deletes list data in batches based on ids. 580 * 581 * @param actionData primary key id session ids 582 */ 583 deleteMessageByIds(actionData) { 584 mConversationModel.deleteMessageByIds(actionData); 585 }, 586 587 deleteMessageBySessionIdsAndLock(actionData) { 588 globalThis.DataWorker.sendRequest("deleteMessageBySessionIdsAndLock", { 589 actionData: actionData, 590 context: globalThis.mmsContext 591 }, res => { 592 // do nothing 593 }); 594 }, 595 596 /** 597 * Deletes list data in batches based on the group id. 598 * 599 * @param actionData session ids 600 */ 601 deleteMessageByGroupIds(actionData) { 602 globalThis.DataWorker.sendRequest("deleteMessageByGroupIds", { 603 actionData: actionData, 604 context: globalThis.mmsContext 605 }, res => { 606 // do nothing 607 }); 608 // Deleting mms data 609 globalThis.DataWorker.sendRequest("deleteMmsPartByGroupIds", { 610 actionData: actionData, 611 context: globalThis.mmsContext 612 }, res => { 613 // do nothing 614 }); 615 }, 616 617 /** 618 * Based on batch marking 619 * 620 * @param actionData 621 * @callback callback 622 */ 623 markAllAsRead(actionData, callback?) { 624 globalThis.DataWorker.sendRequest("markAllAsRead", { 625 actionData: actionData, 626 context: globalThis.mmsContext 627 }, res => { 628 if (callback) { 629 callback(res); 630 } 631 }); 632 }, 633 634 /** 635 * Based on batch marking 636 * 637 * @param actionData 638 * @callback callback 639 */ 640 markAllToRead(actionData, callback?) { 641 globalThis.DataWorker.sendRequest("markAllToRead", { 642 actionData: actionData, 643 context: globalThis.mmsContext 644 }, res => { 645 if (callback) { 646 callback(res); 647 } 648 }); 649 }, 650 651 /** 652 * Update based on a single id. 653 * 654 * @param actionData 655 * @callback callback 656 */ 657 updateById(actionData, callback) { 658 globalThis.DataWorker.sendRequest("updateById", { 659 actionData: actionData, 660 context: globalThis.mmsContext 661 }, res => { 662 callback(res); 663 }); 664 }, 665 666 /** 667 * Query the maximum group id. 668 * 669 * @param actionData 670 * @callBack callBack 671 */ 672 queryMaxGroupId(actionData, callBack) { 673 globalThis.DataWorker.sendRequest("queryMaxGroupId", { 674 actionData: actionData, 675 context: globalThis.mmsContext 676 }, res => { 677 let result: LooseObject = {}; 678 result.code = res.code; 679 if (res.code == common.int.SUCCESS) { 680 result.response = res.abilityResult; 681 } else { 682 HiLog.w(TAG, "queryMaxGroupId, failed"); 683 } 684 callBack(result); 685 }); 686 }, 687 688 /** 689 * Save picture 690 * 691 * @param params threadId, pduId 692 * @callback callback 693 */ 694 saveImage(params, callback) { 695 mConversationModel.saveImage(params, function (result) { 696 let message = ''; 697 if (result.code == common.int.SUCCESS) { 698 HiLog.i(TAG, "saveImage, success"); 699 message = this.$t("strings.attachment_saved_to") + result.abilityResult.filePath 700 + this.$t("strings.please_keep_it_secure"); 701 } else { 702 HiLog.w(TAG, "saveImage, error"); 703 message = this.$t("string.save_img_failed"); 704 } 705 callback(message); 706 }); 707 }, 708 709 /** 710 * Go to share 711 * 712 * @param actionData 713 * @callback callback 714 */ 715 gotoShare(actionData, callback) { 716 let result: LooseObject = {}; 717 mConversationModel.gotoShare(actionData, res => { 718 result.code = res.code; 719 }); 720 callback(result); 721 }, 722 723 /** 724 * Update the lock tag 725 * 726 * @param actionData 727 * @callback callback 728 */ 729 updateLock(actionData, callback) { 730 let result: LooseObject = {}; 731 mConversationModel.updateLock(actionData, res => { 732 result.code = res.code; 733 callback(result); 734 }); 735 }, 736 737 /** 738 * Update favorites 739 * 740 * @param actionData 741 * @callback callback 742 */ 743 updateCollect(actionData, callback) { 744 let result: LooseObject = {}; 745 mConversationModel.updateCollect(actionData, res => { 746 result.code = res.code; 747 callback(result); 748 }); 749 }, 750 751 /** 752 * Fuzzy search, by content 753 * 754 * @param actionData 755 * @callback callback 756 */ 757 searchMessageByContent(actionData, callback) { 758 let smsPromise = new Promise((resolve, reject) => { 759 this.searchSmsMessageByContent(actionData, res => { 760 if (res.code === common.int.SUCCESS) { 761 resolve(res.response); 762 } else { 763 reject(res.code); 764 } 765 }); 766 }); 767 // Information List Search Data 768 let mmsPartPromise = new Promise((resolve, reject) => { 769 this.searchMmsPartByContent(actionData, res => { 770 if (res.code === common.int.SUCCESS) { 771 resolve(res.response); 772 } else { 773 reject(res.code); 774 } 775 }); 776 }); 777 let result: LooseObject = {}; 778 Promise.all([smsPromise, mmsPartPromise]).then((res) => { 779 result.code = common.int.SUCCESS; 780 let resultList = []; 781 resultList = resultList.concat(res[0]); 782 resultList = resultList.concat(res[1]); 783 result.response = this.dealMessageSort(resultList); 784 callback(result); 785 }).catch((err) => { 786 HiLog.e(TAG, "searchMessageByContent, error: " + JSON.stringify(err.message)); 787 result.code = common.int.FAILURE; 788 callback(result); 789 }); 790 }, 791 792 dealMessageSort(resultList) { 793 let favoriteList = []; 794 let messageList = []; 795 for (let item of resultList) { 796 if (item.isFavorite) { 797 favoriteList.push(item); 798 } else { 799 messageList.push(item); 800 } 801 } 802 let response = []; 803 // Favorites list in reverse order 804 if (favoriteList.length > 0) { 805 // inverted 806 favoriteList.sort((a, b) => { 807 return b.timeMillisecond - a.timeMillisecond 808 }); 809 response = response.concat(favoriteList); 810 } 811 // List of common SMs in reverse order 812 if (messageList.length > 0) { 813 // inverted 814 messageList.sort((a, b) => { 815 return b.timeMillisecond - a.timeMillisecond 816 }) 817 response = response.concat(messageList); 818 } 819 return response; 820 }, 821 822 /** 823 * Fuzzy search, by content 824 * 825 * @param actionData 826 * @callback callback 827 */ 828 searchSmsMessageByContent(actionData, callback) { 829 let searchText = actionData.inputValue; 830 actionData.content = searchText; 831 let result: LooseObject = {}; 832 // The query details need to be disabled. 833 mConversationModel.searchSmsMessageByContent(actionData, res => { 834 result.code = res.code; 835 if (res.code == common.int.SUCCESS) { 836 let telephones = []; 837 let resultList = this.convertLikeConversation(res.abilityResult, searchText, telephones, new Map()); 838 this.dealContactsName(telephones, actionData, resultList, sessionList => { 839 result.response = sessionList; 840 callback(result); 841 }); 842 } else { 843 callback(result); 844 } 845 }); 846 }, 847 848 convertLikeConversation(mmsList, searchText, telephones, mmsPartMap) { 849 let resultList = []; 850 for (let item of mmsList) { 851 let map: LooseObject = {}; 852 map.content = item.msgContent; 853 if (mmsPartMap.has(item.msgId)) { 854 map.content = mmsPartMap.get(item.msgId).content; 855 } 856 map.name = common.string.EMPTY_STR; 857 map.telephone = item.receiverNumber; 858 map.telephoneFormat = item.receiverNumber; 859 if (item.isSender == 1) { 860 map.telephone = item.senderNumber; 861 map.telephoneFormat = item.senderNumber; 862 } 863 telephones.push(map.telephone); 864 map.nameFormatter = map.name + "<" + map.telephoneFormat + ">"; 865 map.date = common.string.EMPTY_STR; 866 map.time = common.string.EMPTY_STR; 867 map.timeMillisecond = item.startTime; 868 map.isFavorite = item.isCollect == 0 ? false : true; 869 map.threadId = item.sessionId; 870 if (item.smsType == 0) { 871 map.icon = "icon/user_avatar_full_fill.svg"; 872 } else { 873 map.icon = "icon/entrance_icon01.svg"; 874 } 875 map.groupId = item.groupId; 876 resultList.push(map); 877 } 878 return resultList; 879 }, 880 881 dealContactsName(telephones, actionData, resultList, callback) { 882 actionData.telephones = telephones; 883 if (telephones.length == 0) { 884 callback(resultList); 885 } 886 contractService.queryContactDataByTelephone(actionData, contacts => { 887 let groupIdMap: LooseObject = {}; 888 if (contacts.length == 0) { 889 groupIdMap = this.convertingMessageByGroup(resultList); 890 } else { 891 // Convert the result to Map, key: mobile number, value: name 892 let telephoneMap = new Map(); 893 for (let item of contacts) { 894 if (item.displayName == common.string.EMPTY_STR) { 895 telephoneMap.set(item.detailInfo, item.detailInfo); 896 } else { 897 telephoneMap.set(item.detailInfo, item.displayName); 898 } 899 } 900 // Match the result based on the mobile number. 901 groupIdMap = this.getGroupIdMap(resultList, telephoneMap); 902 } 903 let lists = []; 904 let favoriteList = []; 905 for (let key of Object.keys(groupIdMap)) { 906 let value = groupIdMap[key]; 907 let contactsNums = value.telephone.split(common.string.COMMA); 908 value.contactsNum = contactsNums.length; 909 if (value.isFavorite) { 910 let temp = JSON.parse(JSON.stringify(value)); 911 temp.icon = "/common/icon/icon_favorite.svg"; 912 favoriteList.push(temp); 913 value.isFavorite = false; 914 } 915 lists.push(value); 916 } 917 // Add favorite data to the search list. 918 if (favoriteList.length > 0) { 919 lists = lists.concat(favoriteList); 920 } 921 callback(lists); 922 }); 923 }, 924 925 getGroupIdMap(resultList, telephoneMap) { 926 let groupIdMap: LooseObject = {}; 927 for (let map of resultList) { 928 // Indicates the combination of multiple names. The names need to be displayed in combination. 929 if (telephoneMap.has(map.telephone)) { 930 map.name = telephoneMap.get(map.telephone); 931 map.nameFormatter = map.name + "<" + map.telephoneFormat + ">"; 932 } else { 933 map.nameFormatter = map.telephoneFormat; 934 } 935 if (Object.keys(groupIdMap).indexOf(map.groupId) > -1) { 936 let list = groupIdMap[map.groupId]; 937 list.name = list.name + common.string.COMMA + map.name; 938 list.nameFormatter = list.nameFormatter + common.string.COMMA + map.nameFormatter; 939 list.telephone = list.telephone + common.string.COMMA + map.telephone; 940 list.telephoneFormat = list.telephoneFormat + common.string.COMMA + map.telephoneFormat; 941 } else { 942 groupIdMap[map.groupId] = map; 943 } 944 } 945 return groupIdMap; 946 }, 947 948 convertingMessageByGroup(resultList) { 949 let groupIdMap: LooseObject = {}; 950 for (let element of resultList) { 951 if (Object.keys(groupIdMap).indexOf(element.groupId) == -1) { 952 groupIdMap[element.groupId] = element; 953 } 954 } 955 return groupIdMap; 956 }, 957 958 /** 959 * Fuzzy search for mms messages by content 960 * 961 * @param actionData 962 * @callback callback 963 */ 964 searchMmsPartByContent(actionData, callback) { 965 let searchText = actionData.inputValue; 966 actionData.content = searchText; 967 // The query details need to be disabled. 968 let result: LooseObject = {}; 969 mConversationModel.searchMmsPartByContent(actionData, res => { 970 result.code = res.code; 971 if (res.code == common.int.SUCCESS) { 972 let mmsPartMap = this.getMmsPartMap(res.abilityResult); 973 actionData.msgIds = this.getMsgIds(mmsPartMap); 974 if (actionData.msgIds.length == 0) { 975 result.response = []; 976 callback(result); 977 return; 978 } 979 this.buildMmsPartContacts(actionData, searchText, mmsPartMap, sessionList => { 980 result.response = sessionList; 981 callback(result); 982 }); 983 } else { 984 HiLog.w(TAG, "searchMmsPartByContent, failed"); 985 callback(result); 986 } 987 }); 988 }, 989 990 buildMmsPartContacts(actionData, searchText, mmsPartMap, callback) { 991 mConversationModel.queryMessageDetail(actionData, messageDetails => { 992 let telephones = []; 993 let mmsParts = messageDetails.abilityResult; 994 let resultList = this.convertLikeConversation(mmsParts, searchText, telephones, mmsPartMap); 995 this.dealContactsName(telephones, actionData, resultList, sessionList => { 996 callback(sessionList); 997 }); 998 }); 999 }, 1000 1001 getMmsPartMap(mmsParts) { 1002 let mmsPartMap = new Map(); 1003 // grouping 1004 for (let element of mmsParts) { 1005 if (!mmsPartMap.has(element.msgId)) { 1006 mmsPartMap.set(element.msgId, element); 1007 } 1008 } 1009 return mmsPartMap; 1010 }, 1011 1012 getMsgIds(mmsPartMap) { 1013 let msgIds = []; 1014 for (let msgId of mmsPartMap.keys()) { 1015 msgIds.push(msgId); 1016 } 1017 return msgIds; 1018 }, 1019 1020 /** 1021 * Get pictures and videos from gallery 1022 * 1023 * @param actionData 1024 * @callback callback 1025 */ 1026 queryFromGallery(actionData, callback) { 1027 let result: LooseObject = {}; 1028 mConversationModel.queryFromGallery(actionData, res => { 1029 result.code = res.code; 1030 result.pictureListFromGallery = res.abilityResult; 1031 }); 1032 callback(result); 1033 }, 1034 1035 /** 1036 * Querying sms messages in the last 30 days 1037 * 1038 * @param actionData 1039 * @callback callback 1040 */ 1041 queryMessageThirty(actionData, callBack) { 1042 let result: LooseObject = {}; 1043 mConversationModel.queryMessageThirty(actionData, res => { 1044 result.code = res.code; 1045 if (res.code == common.int.SUCCESS) { 1046 result.response = res.abilityResult; 1047 } else { 1048 HiLog.w(TAG, "queryMessageThirty, failed"); 1049 } 1050 callBack(result); 1051 }); 1052 }, 1053 1054 /** 1055 * Inserting data into the sim card 1056 * 1057 * @param actionData 1058 * @callback callback 1059 */ 1060 insertManageSimData(actionData, callback) { 1061 HiLog.i(TAG, "insertManageSimData") 1062 let sendResults = actionData.sendResults; 1063 let value = this.dealSendResults(sendResults); 1064 // Check whether a session list has been created. 1065 conversationListService.querySessionByTelephone(value.telephone, res => { 1066 let response = res.response; 1067 if (res.code == common.int.SUCCESS && response.id < 0) { 1068 this.insertManageSimNoExiting(value, actionData, callback); 1069 } else { 1070 let sessionId = response.id; 1071 this.dealInsertMessageDetail(value, actionData, sessionId, res => { 1072 let result = { 1073 rowId: sessionId, 1074 initDatas: res.initDatas, 1075 groupId: res.groupId 1076 } 1077 callback(result); 1078 }); 1079 } 1080 }); 1081 }, 1082 1083 insertManageSimNoExiting(value, actionData, callback) { 1084 let valueBucket = { 1085 "telephone": value.telephone, 1086 "content": value.content, 1087 "contacts_num": value.contractsNum, 1088 "sms_type": value.smsType, 1089 "unread_count": 0, 1090 "sending_status": value.sendStatus, 1091 "has_draft": 0, 1092 "time": value.timestamp, 1093 "message_count": 1 1094 } 1095 conversationListService.insertSession(valueBucket, sessionResult => { 1096 // Invoke the SMS database to insert SMS messages. 1097 this.dealInsertMessageDetail(value, actionData, sessionResult.rowId, res => { 1098 let result = { 1099 rowId: sessionResult.rowId, 1100 initDatas: res.initDatas, 1101 groupId: res.groupId 1102 } 1103 callback(result); 1104 }); 1105 }); 1106 }, 1107 1108 /** 1109 * Counting the number of unread notifications 1110 * 1111 * @param actionData 1112 * @callback callback 1113 */ 1114 statisticsUnreadNotify(actionData, callback) { 1115 mConversationModel.statisticsUnreadNotify(actionData, res => { 1116 if (res.code == common.int.SUCCESS) { 1117 callback(res.abilityResult); 1118 } else { 1119 HiLog.w(TAG, "statisticsUnreadNotify, failed"); 1120 callback(0); 1121 } 1122 }); 1123 }, 1124 1125 /** 1126 * This interface is used to query MMS information based on groupId. 1127 * 1128 * @param actionData 1129 * @callback callback 1130 */ 1131 queryMmsPartByIds(actionData, callback) { 1132 globalThis.DataWorker.sendRequest("queryMmsPart", { 1133 actionData: actionData, 1134 context: globalThis.mmsContext 1135 }, res => { 1136 let result: LooseObject = {}; 1137 result.code = res.code; 1138 if (res.code == common.int.SUCCESS) { 1139 result.response = res.abilityResult; 1140 } else { 1141 HiLog.w(TAG, "queryMmsPartByIds, failed"); 1142 } 1143 callback(result); 1144 }); 1145 }, 1146 1147 /** 1148 * Obtains the lock status based on sessionId. 1149 * 1150 * @param actionData 1151 * @callback callback 1152 */ 1153 queryMessageLockBySessionId(actionData, callback) { 1154 let result: LooseObject = {}; 1155 HiLog.i(TAG, "queryMessageLockBySessionId"); 1156 mConversationModel.queryMessageLockBySessionId(actionData, res => { 1157 result.code = res.code; 1158 if (res.code == common.int.SUCCESS) { 1159 callback(res.abilityResult); 1160 } else { 1161 HiLog.w(TAG, "queryMessageLockBySessionId, failed"); 1162 callback(result); 1163 } 1164 }); 1165 }, 1166}