• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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}