PageSourceSearch

https://www.migliohome.com/assets/js/widget/ai-faq.js

js migliohome.com collected 2026-10-07 22:02:52 UTC 4,852 bytes, 157 lines download raw bytes

1class WidgetAiFaq extends Script {
2    constructor(params) {
3        super(params)
4        this.iframe_url = params.iframe_url
5        this.$dom = document.querySelector(`#${this.attrId}`)
6        this.$iframe = document.querySelector('#widget_ai_faq_iframe')
7        this.msgChannel = new MessageChannel()
8        this.chatOptions = {
9            greeting: params.greeting,
10            assistant_avatar: params.assistant_avatar
11        }
12    }
13
14    init() {
15        this.initPlugin()
16    }
17
18    initPlugin() {
19        /**
20         * @type {HTMLIFrameElement} iframe
21         */
22        const iframe = this.$iframe
23        const that = this
24        window.addEventListener('message', function (evt) {
25            if (evt && evt.data && evt.data._topic === 'chatView:ready') {
26                const contentWindow = iframe.contentWindow
27                if (evt.source.window === contentWindow) {
28                    contentWindow.postMessage({
29                        _topic: 'init:messagePort',
30                        data: {
31                            chatOptions: that.chatOptions
32                        }
33                    }, iframe.src, [that.msgChannel.port2])
34                }
35            }
36        })
37        this.msgChannel.port1.onmessage = function (evt) {
38            if (evt && evt.data && evt.data._topic === 'localStorage:setItem') {
39                const msgData = evt.data.data
40                localStorage.setItem(msgData.key, msgData.value)
41            }
42        }
43
44        this.getSiteData().then(function (config) {
45            if (config) {
46                that.setChatOptions(config)
47            }
48            that.loadChatFrame()
49        })
50
51    }
52
53    /**
54     *
55     * @param { { knowledge: {website_hc_message, kefu_message}, site: {site_logo} } } config
56     */
57    setChatOptions(config) {
58        if (config && config.site) {
59            this.chatOptions.assistant_avatar = config.site.site_logo || ''
60        }
61        if (config && config.knowledge) {
62            this.chatOptions.greeting = config.knowledge.website_hc_message || ''
63        }
64    }
65
66    /**
67     *
68     * @param conversation_type
69     * @param site_id
70     * @returns {string}
71     */
72    generateStoreKey(conversation_type, site_id) {
73        /**
74         * 对话类型
75         * @type {{AI_CUSTOMER_SUPPORT: number, AI_FAQ: number}}
76         */
77        const CONVERSATION_TYPES = WidgetAiFaq.CONVERSATION_TYPES
78        /**
79         * @type {{}}
80         */
81        const CONVERSATION_TYPES_KEY = {
82            [CONVERSATION_TYPES.AI_CUSTOMER_SUPPORT]: 'chat', // ai 客服
83            [CONVERSATION_TYPES.AI_FAQ]: 'faq' // ai 帮助中心
84        }
85        const CONVERSATION_STORE_KEY_PREFIX = 'lf_open_'
86        const type = CONVERSATION_TYPES_KEY[conversation_type] || ''
87        return `${CONVERSATION_STORE_KEY_PREFIX}_${type}_${site_id}`
88    }
89
90    /**
91     * 加载iframe
92     */
93    loadChatFrame() {
94        const referrer = btoa(location.href)
95            .replace(/[+]/g, '-')
96            .replace(/\//g, '_')
97            .replace(/=/g, '')
98        const iframe_url = new URL(this.iframe_url)
99        iframe_url.searchParams.set('_lf_referrer', referrer)
100        if (this.greeting) {
101            iframe_url.searchParams.set('greeting', this.greeting)
102        }
103        const conversationKey = this.generateStoreKey(WidgetAiFaq.CONVERSATION_TYPES.AI_FAQ, window.app.info.site.site_id)
104        try {
105            const stored = localStorage.getItem(conversationKey)
106            /**
107             *
108             * @type {{conversation_id: string, list: array}|null}
109             */
110            const conversation = JSON.parse(stored) || null
111            if (conversation && conversation.conversation_id) {
112                iframe_url.searchParams.set('conversation_id', conversation.conversation_id)
113            }
114        } catch (e) {
115            console.error(e)
116        }
117        if (!this.$iframe.getAttribute('src')) {
118            this.$iframe.setAttribute('src', iframe_url.href)
119        }
120    }
121
122  /**
123   * 迁移到 Utilts.getSiteData
124   * @deprecated
125   * @returns {*|Promise<Awaited<unknown>>}
126   */
127  getSiteData() {
128        const that = this
129        if (this.siteConfig) {
130            return Promise.resolve(this.siteConfig)
131        } else {
132            return this.fetSiteData().then(function (res) {
133                if (res && res.code === 0) {
134                    that.siteConfig = res.data
135                }
136                return res.data
137            })
138        }
139    }
140
141    fetSiteData() {
142        const params = {
143            site_id: window.app.info.site.site_id
144        }
145        return this.utilts.request({
146            url: '/site/info',
147            method: 'get',
148            params
149        })
150    }
151
152}
153
154WidgetAiFaq.CONVERSATION_TYPES = {
155    AI_CUSTOMER_SUPPORT: 2, // ai 客服
156    AI_FAQ: 3 // ai 帮助中心
157}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.