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