<template>
    <div class="global-im">
        <!-- 悬浮按钮与角标 -->
        <div class="im-trigger" :class="{ active: visible }" @click="toggleChat">
            <el-icon :size="18"><el-icon-chat-round /></el-icon>
            <div class="unreadCount">
                <el-badge :value="unreadCount" :hidden="unreadCount === 0" :max="99">
                    <i class="el-icon-chat-dot-round" style="font-size: 24px"></i>
                </el-badge>
            </div>
        </div>
    </div>
    <el-drawer v-model="visible" title="在线客服" size="100%" destroy-on-close :close-on-click-modal="false" :with-header="false">
        <el-container class="flex-column">
            <div class="drawer-detail-main">
                <div class="drawer-detail-header">
                    <div class="drawer-detail-header-body">
                        <div class="drawer-detail-header-left">在线客服</div>
                        <div class="drawer-detail-header-left">
                            <el-button type="default" icon="el-icon-close" round @click="hideWindow"></el-button>
                        </div>
                    </div>
                </div>
            </div>
            <el-main class="nopadding">
                <el-container>
                    <el-aside width="300px" v-loading="loadMsg">
                        <el-container class="flex-column">
                            <!-- <div class="aside-tabs bg">
                                <div :class="orderData.tab=='user'?'aside-tab-items active':'aside-tab-items'" @click="handleClick('user')">当前咨询</div>
                                <div :class="orderData.tab=='order'?'aside-tab-items active':'aside-tab-items'" @click="handleClick('order')">历史咨询</div>
                            </div> -->
                            <el-main class="nopadding">
                                <div class="chat-contact">
                                    <div :class="checkChat==index?'contact-item active':'contact-item'" v-for="(item,index) in chatContact" :key="index" @click="checkChatItem(index)">
                                            <div class="img">
                                                <el-image :src="item.user.avatar" fit="contain" style="width: 40px; height: 40px"></el-image>
                                                <span class="last-num" v-if="item.last.num > 0">{{item.last.num}}</span>
                                            </div>
                                            <div class="kefu-store">
                                            <div class="name">{{item.user.nickname}}</div>
                                            <div class="desc" v-if="item.last.type=='text'">{{item.last.content}}</div>
                                            <div class="desc" v-if="item.last.type=='order'">[订单消息]</div>
                                            <div class="desc" v-if="item.last.type=='image'">[图片消息]</div>
                                            <div class="desc" v-if="item.last.type=='video'">[视频消息]</div>
                                            <div class="desc" v-if="item.last.type=='pay'">[支付消息]</div>
                                            <div class="desc" v-if="item.last.type=='address'">[收集地址]</div>
                                        </div>
                                        <div class="time">
                                            {{item.last.create_at}}
                                        </div>
                                    </div>
                                </div>
                            </el-main>
                        </el-container>
                    </el-aside>
                    <el-container v-if="chatItem">
                        <el-header><div class="msg-title">与{{ chatItem.user.nickname }}的对话</div></el-header>
                        <el-main class="nopadding" ref="main">
                            <div class="chat-container" v-if="chatItem">
                                <div class="loading-text" v-if="msgLoad">努力加载中...</div>
                                <div class="message-list" ref="messageListRef" @scroll="handleScroll">
                                    <template v-for="(item, index) in history.messages">
                                    <div class="z_index2" style="transform: rotate(-180deg)" :key="item.messageId" v-if="!item.isHide">
                                        <div class="icon_ text_26 color__ time">
                                            {{ renderMessageDate(item, index) }}
                                        </div>
                                        <div :key="item.messageIds" v-if="!item.recalled">
                                            <item :isMy="isSelf(item.senderId)" :myid="myid" :item="item" @onClick="onItem"
                                                @onLongpress="onLongpress" @mention="mention"></item>
                                        </div>
                                        <div class="icon_ text_26 recalled" v-else>
                                            <div class="">
                                                <span v-if="isSelf(item.senderId)">你</span>
                                                <span v-else>{{ item.senderData.name }}</span>
                                                撤回了一条消息
                                            </div>
                                            <div class="recalled-edit" v-if="item.type === 'text' && isSelf(item.senderId)"
                                                @click="recalledEdit(item)">重新编辑</div>
                                        </div>
                                    </div>
                                    </template>
                                </div>
                                <div class="input-area">
                                    <div class="quick-group">
                                        <div class="emoji-item">
                                            <el-popover placement="top" :width="400" trigger="click">
                                                <template #reference>
                                                    <div class="item-btn">
                                                        <el-image style="width:25px;height:25px;" src="https://jymini.oss-cn-guangzhou.aliyuncs.com/pc/face.svg"></el-image>
                                                        <div class="name">表情</div>
                                                    </div>
                                                </template>
                                                <div class="swiper-item-box">
                                                    <div class="flex_r swiper-item-box-l" v-for="(im, ix) in emojiList" :key="ix">
                                                        <div
                                                            class="icon_ emoji-item"
                                                            v-for="(item, index) in im"
                                                            :key="index"
                                                            :style="{ opacity: ix === opacityGroup && (index == 5 || index == 6 || index == 7) ? opacity : 1 }"
                                                        >
                                                            <el-image class="img" :src="emojiUrl + item.image" @click="chooseEmoji(item.text)"></el-image>
                                                        </div>
                                                    </div>
                                                </div>
                                            </el-popover>
                                        </div>
                                        <div class="emoji-item">
                                            <el-popover placement="top" :width="174">
                                                <template #reference>
                                                    <div class="item-btn">
                                                        <el-image style="width:25px;height:25px;" src="https://jymini.oss-cn-guangzhou.aliyuncs.com/pc/more.svg"></el-image>
                                                        <div class="name">图片</div>
                                                    </div>
                                                </template>
                                                <sc-upload v-model="uploadImg" :on-success="uploadSuccess"></sc-upload>
                                            </el-popover>
                                        </div>
                                        <div class="emoji-item" @click="showQuick">
                                            <el-popover placement="top" :width="400" trigger="click" @show="getQuick">
                                                <template #reference>
                                                    <div class="item-btn">
                                                        <el-image style="width:25px;height:25px;" src="https://jymini.oss-cn-guangzhou.aliyuncs.com/pc/quick.svg"></el-image>
                                                        <div class="name">快捷回复</div>
                                                    </div>
                                                </template>
                                                <div class="quick-table">
                                                    <div class="quick-search">
                                                        <div class="search-input">
                                                            <el-input placeholder="搜索一下..." style="width: 100%;" />
                                                            <el-button>搜索</el-button>
                                                        </div>
                                                        <div class="search-btn-txt"><el-button type="primary" @click="addQuick">添加</el-button></div>
                                                    </div>
                                                    <div class="quick-table-body">
                                                        <el-table :data="quickData.list" style="width: 100%" height="300" border>
                                                            <el-table-column prop="content" label="内容"></el-table-column>
                                                            <el-table-column prop="content" label="操作" width="80">
                                                                <template #default="scope">
                                                                    <el-button size="small" @click="sendQuick(scope.row.content)">发送</el-button>
                                                                </template>
                                                            </el-table-column>
                                                        </el-table>
                                                    </div>
                                                    <div class="quick-page">
                                                        <el-pagination
                                                            small
                                                            background
                                                            layout="prev, pager, next"
                                                            :total="quickData.total"
                                                            @size-change="quickPageChange" @current-change="quickPageChange"
                                                        />
                                                    </div>
                                                </div>
                                            </el-popover>
                                        </div>
                                    </div>
                                    <el-input
                                        type="textarea"
                                        :rows="3"
                                        v-model="inputMessage"
                                        placeholder="请输入消息..."
                                        @keyup.enter.native="handleKeyCode"
                                        @keydown.native="handleKeyCode"
                                    ></el-input>
                                    <div class="send-btn-group">
                                        <div class="send-btn-right">
                                            <el-button type="primary" @click="sendMessage">发送</el-button>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </el-main>
                    </el-container>
                    <el-container v-else>
                        <div class="empty-data">
                            请选择左侧的聊天列表
                        </div>
                    </el-container>
                    <el-aside width="400px" v-if="chatItem">
                        <el-container class="flex-column">
                            <div class="aside-tabs">
                                <div :class="orderData.tab=='user'?'aside-tab-items active':'aside-tab-items'" @click="handleClick('user')">用户信息</div>
                                <div :class="orderData.tab=='order'?'aside-tab-items active':'aside-tab-items'" @click="handleClick('order')">团购订单</div>
                                <!-- <div :class="orderData.tab=='price'?'aside-tab-items active':'aside-tab-items'" @click="handleClick('price')">差价订单</div> -->
                            </div>
                            <el-main class="nopadding">
                                <template v-if="orderData.tab == 'user'">
                                    <div class="order-info-user">
                                        <div class="info-item">
                                            <div class="name">昵称</div>
                                            <div class="right">{{ chatItem.user.nickname }} </div>
                                        </div>
                                        <div class="info-item">
                                            <div class="name">OpenId</div>
                                            <div class="right">{{ chatItem.user.openid }} </div>
                                        </div>
                                        <div class="info-item">
                                            <div class="name">手机号码</div>
                                            <div class="right">{{ chatItem.user.mobile }} </div>
                                        </div>
                                        <div class="info-item">
                                            <div class="name">注册时间</div>
                                            <div class="right">{{ chatItem.user.create_at }} </div>
                                        </div>
                                    </div>
                                    <div class="order-info-user" v-if="msgOrder">
                                        <div class="title">咨询订单</div>
                                        <div class="m-order-s" style="margin-top: 15px;">
                                            <div class="m-order-item" @click="viewOrder(msgOrder)">
                                                <div class="order-img"><el-image style="width: 80px;height: 80px;" :src="msgOrder.img" fit="fit"></el-image></div>
                                                <div class="order-info">
                                                    <div class="title" style="padding: 0;">{{msgOrder.product.product_name}}</div>
                                                    <div class="desc" v-if="msgOrder.sku_name">规格：{{msgOrder.sku_name}}</div>
                                                    <div class="desc">{{msgOrder.order_sn}}</div>
                                                    <div class="price">
                                                        {{$TOOL.money(msgOrder.price)}}
                                                        <text v-if="msgOrder.custom_price > 0">差价：{{$TOOL.money(msgOrder.custom_price)}}</text>
                                                    </div>
                                                </div>
                                                <div class="order-status-btn">
                                                    <div class="status info" v-if="msgOrder.status=='0'">未支付</div>
                                                    <div class="status primary" v-if="msgOrder.status=='1'">待使用</div>
                                                    <div class="status success" v-if="msgOrder.status=='2'">已完成</div>
                                                    <div class="status danger" v-if="msgOrder.status=='3'">已退款</div>
                                                    <div class="status warn" v-if="msgOrder.status=='4'">退款中</div>
                                                    <div class="status warn" v-if="msgOrder.status=='5'">已关闭</div>
                                                    <div class="status success" v-if="msgOrder.product.product_type==11 && msgOrder.custom_price > 0 && msgOrder.custom_status ==1">差价已付</div>
                                                    <div class="status danger" v-if="msgOrder.product.product_type==11 && msgOrder.custom_price > 0 && msgOrder.custom_status ==0">差价未付</div>
                                                </div>
                                            </div>
                                            <div class="order-btn-group">
                                                <div class="status primary cus" @click="sendAddress(msgOrder)" v-if="msgOrder.status=='1' && user.trade == '2'">发起预约</div>
                                                <div class="status info cus" @click="editAddress(msgOrder)" v-if="msgOrder.status=='1' && user.trade == '2'">代客预约</div>
                                                <!-- <div class="status warn cus" v-if="msgOrder.product.product_type==11 && msgOrder.custom_price > 0 && msgOrder.custom_status ==0" @click="submitPrice(msgOrder)">补差价</div> -->
                                                <!-- <div class="status danger cus" v-if="msgOrder.product.product_type==11 && msgOrder.custom_price > 0 && msgOrder.custom_status ==0" @click="submitPrice(msgOrder)">改差价</div> -->
                                                <div class="status danger cus" @click="sendOrder(msgOrder)">发送订单</div>
                                                <div class="status primary cus" @click="doneOrder(msgOrder)" v-if="msgOrder.status=='1' && user.trade == '1'">手动核销</div>
                                            </div>
                                        </div>
                                    </div>
                                </template>
                                <template v-if="orderData.tab == 'price'">
                                    <el-container>
                                        <el-header>
                                            <div class="order-search-input">
                                                <el-input v-model="priceData.order" placeholder="搜索订单编号..." style="width: 100%;" />
                                                <el-button @click="searchPrice">搜索</el-button>
                                            </div>
                                        </el-header>
                                        <el-main>
                                        </el-main>
                                        <el-footer style="text-align: right;">
                                            <div class="order-page">
                                                <el-pagination small background :default-page-size="priceData.size" layout="prev, pager, next" @size-change="orderPageChange" @current-change="orderPageChange" :total="priceData.total" />
                                            </div>
                                        </el-footer>
                                    </el-container>
                                </template>
                                <template v-if="orderData.tab == 'order'">
                                    <el-container v-loading="orderData.loading">
                                        <el-header>
                                            <div class="order-search-input">
                                                <el-input v-model="orderData.order" placeholder="搜索订单编号..." style="width: 100%;" />
                                                <el-button @click="searchOrder">搜索</el-button>
                                            </div>
                                        </el-header>
                                        <el-main>
                                            <div class="order-list-chat" v-if="orderData.list.length > 0">
                                                <div class="m-order-s" v-for="(item,index) in orderData.list" :key="index">
                                                    <div class="m-order-item" @click="viewOrder(item)">
                                                        <div class="order-img"><el-image style="width: 80px;height: 80px;" :src="item.img" fit="fit"></el-image></div>
                                                        <div class="order-info">
                                                            <div class="title">{{item.product.product_name}}</div>
                                                            <div class="desc" v-if="item.sku_name">规格：{{item.sku_name}}</div>
                                                            <div class="desc">{{item.order_sn}}</div>
                                                            <div class="price">
                                                                {{$TOOL.money(item.price)}}
                                                                <text v-if="item.custom_price > 0">差价：{{$TOOL.money(item.custom_price)}}</text>
                                                            </div>
                                                        </div>
                                                        <div class="order-status-btn">
                                                            <div class="status info" v-if="item.status=='0'">未支付</div>
                                                            <div class="status primary" v-if="item.status=='1'">待使用</div>
                                                            <div class="status success" v-if="item.status=='2'">已完成</div>
                                                            <div class="status danger" v-if="item.status=='3'">已退款</div>
                                                            <div class="status warn" v-if="item.status=='4'">退款中</div>
                                                            <div class="status warn" v-if="item.status=='5'">已关闭</div>
                                                            <div class="status success" v-if="item.product.product_type==11 && item.custom_price > 0 && item.custom_status ==1">差价已付</div>
                                                            <div class="status danger" v-if="item.product.product_type==11 && item.custom_price > 0 && item.custom_status ==0">差价未付</div>
                                                        </div>
                                                    </div>
                                                    <div class="order-btn-group">
                                                        <div class="status primary cus" @click="sendAddress(item)" v-if="item.status=='1' && user.trade == '2'">发起预约</div>
                                                        <div class="status info cus" @click="editAddress(item)" v-if="item.status=='1' && user.trade == '2'">代客预约</div>
                                                        <!-- <div class="status warn cus" v-if="item.product.product_type==11 && item.custom_price > 0 && item.custom_status ==0" @click="submitPrice(item)">补差价</div>
                                                        <div class="status danger cus" v-if="item.product.product_type==11 && item.custom_price > 0 && item.custom_status ==0" @click="submitPrice(item)">改差价</div> -->
                                                        <div class="status danger cus" @click="sendOrder(item)">发送订单</div>
                                                        <div class="status primary cus" @click="doneOrder(item)" v-if="item.status=='1' && user.trade == '1'">手动核销</div>
                                                    </div>
                                                </div>
                                            </div>
                                            <div class="order-list-chat" v-else>
                                                <el-empty description="没有订单" />
                                            </div>
                                        </el-main>
                                        <el-footer style="text-align: right;">
                                            <div class="order-page">
                                                <el-pagination small background :default-page-size="orderData.size" layout="prev, pager, next" @size-change="orderPageChange" @current-change="orderPageChange" :total="orderData.total" />
                                            </div>
                                        </el-footer>
                                    </el-container>
                                </template>
                            </el-main>
                        </el-container>
                    </el-aside>
                </el-container>
            </el-main>
        </el-container>
    </el-drawer>
    <orderDetail ref="orderDetail" @success="orderSuccess"></orderDetail>
    <quickTxt ref="quickTxt" @success="orderSuccess"></quickTxt>
    <addressMain ref="addressMain" @success="addressSuccess"></addressMain>
</template>

<script>
import {
	mapState
} from 'vuex';
import { Push } from "@/utils/push";
import { emojiMap } from "@/utils/emoji";
import item from '@/components/chat/index';
var pushObj = null;
let height2 = null;
const emojiUrl = 'https://imgcache.qq.com/open/qcloud/tim/assets/emoji/';
import {
	formatDate,
	to as tofn
} from '@/util/index.js';
import orderDetail from '@/components/imFloat/order';
import quickTxt from '@/components/imFloat/quickTxt';
import addressMain from '@/components/imFloat/address';
let imageList = [];
export default {
    name: 'GlobalIM',
    components:{
        item,
        orderDetail,
        quickTxt,
        addressMain
    },
    props: {
        user: { type: Object, default: () => {} }
    },
    data() {
        return {
            activeName:"user",
            rules:{
                name: [
                    {required: true, message: '请输入'}
                ],
                price: [
                    {required: true, message: '请输入'}
                ],
            },
            priceForm:{
                name:"补差价"
            },
            uploadImg:"",
            loadMsg:false,
            history: {
				messages: [],
				allLoaded: false
			},
            msgLoad:false,
            emojiUrl,
            loading:false,
            visible: false,           // 聊天窗口可见性
            unreadCount: 0,          // 未读消息数量
            inputMessage: '',        // 输入的消息
            timer: null,             // 定时器
            messages: [],
            wsAuth:"https://tran.jsshuita.cn/plugin/webman/push/auth",
            wsUrl: 'wss://tran.jsshuita.cn/ws',
            // wsAuth:"http://127.0.0.1:9981/plugin/webman/push/auth",
            // wsUrl: 'ws://127.0.0.1:3131',
            page:1,
            size:10,
            msgPage:1,
            msgSize:20,
            orderSize:10,
            chatContact:[],
            checkChat:null,
            chatItem:null,
            emojiList:[],
			sendId:null,
			myid: this.user.userId,
            userId:null,
            isSaveing:false,
            quickData:{
                page:1,
                size:10,
                list:[],
                popState:false,
                total:0
            },
            msgOrder:null, // 咨询订单
            orderData:{
                page:1,
                size:10,
                list:[],
                loading:false,
                total:0,
                tab:"user",
                order:""
            },
            priceData:{
                page:1,
                size:10,
                list:[],
                loading:false,
                total:0,
                order:""
            }
        }
    },
    watch: {
        chatItem(val){
            if (val) {
                this.$nextTick(() => {
                    this.$refs.messageListRef?.addEventListener('scroll', this.handleScroll)
                })
            }
        }
    },
	computed: mapState({
		//显示时间
		renderMessageDate() {
			return (message, index) => {
				if (message.timestamp - this.history.messages[index + 1]?.timestamp > 3 * 60 * 1000) {
					return formatDate(message.timestamp, 'timestamp');
				}
				return '';
			};
		},
		// 是否本人isMy
		isSelf() {
			return (senderId) => {
				const {
					member_id = this.myid
				} = {"member_id":this.myid};
				return senderId === `${member_id}`;
			};
		}
	}),
    mounted() {
        // console.log("pushObj")
        this.initEmoji()
        this.initPush();
        // this.simulateNewMessage()
    },
    beforeDestroy() {
        // if (this.timer) {
        //     clearInterval(this.timer)
        // }
        this.$refs.messageListRef.removeEventListener('scroll', this.handleScroll)
    },
    methods: {
        editAddress(item){
            this.$nextTick(() => {
                this.$refs.addressMain.open("edit").setData(item);
            })
        },
        addressSuccess(){
            this.getOrderList();
        },
        handleClick(event){
            this.orderData.tab = event;
            switch (event) {
                case "user":
                    break;
                case "order":
                    this.orderData.page = 1;
                    this.orderData.list = [];
                    this.getOrderList();
                    break;
                case "price":
                    this.priceData.page = 1;
                    this.priceData.list = [];
                    this.getOrderPrice();
                    break;
            }
        },
        searchOrder(){
            this.orderData.page = 1;
            this.orderData.list = [];
            this.getOrderList();
        },
        searchPrice(){
            this.priceData.page = 1;
            this.priceData.list = [];
            this.getOrderPrice();
        },
        getOrderPrice(){

        },
        viewOrder(data){
            data.order = data.out_order_no;
            this.$refs.orderDetail.open("add").setData(data)
        },
        quickPageChange(e){
            this.quickData.page = e;
            this.getQuick()
        },
        async getQuick(){
            var resp = await this.$API.merQuick.list.get({"page":this.quickData.page,"pageSize":this.quickData.size});
            if (resp.code == 0) {
                return this.$message.error(resp.msg)
            }
            this.quickData.total = resp.data.total;
            this.quickData.list = resp.data.rows;
        },
        addQuick(){
            this.$nextTick(() => {
                this.$refs.quickTxt.open("add")
            })
        },
        sendQuick(text){
            this.inputMessage = text;
            this.sendMessage()
        },
        orderSuccess(type,data){
            switch(type) {
                case "address":
                    this.sendAddress(data)
                    break;
            }
        },
        async submitPrice(data){
            var { priceForm,$message } = this;
            if (data.custom_status == 1) return $message.error("该订单差价已完成支付")
            // var validate = await this.$refs.priceForm.validate().catch(()=>{});
            // if(!validate){ return false }
            this.isSaveing = true;
            priceForm.name = "订单差额补款";
            priceForm.price = parseInt(data.custom_price) / 100;
            priceForm.type = "pay";
            priceForm.groupId = this.chatItem.poi_id
            priceForm.openid = this.chatItem.openid
            var resp = await this.$API.chat.price.post(priceForm);
            this.isSaveing = false;
            if (resp.code == 0) {
                return $message.error(resp.msg)
            }
            this.sendMessageData({
                payload: {
                    pay: resp.data,
                },
                type: 'pay'
            });
            this.uploadImg = "";
        },
        orderPageChange(e){
            this.orderData.page = e;
            this.getOrderList()
        },
        hideWindow(){
            this.chatItem = null;
            this.msgPage = 1;
            this.unreadCount = 0;
            this.checkChat = null;
            this.visible = false;
        },
        handleScroll(e){
            const { scrollTop, clientHeight, scrollHeight } = e.target
            const isBottom = scrollTop + clientHeight >= scrollHeight - 5   // 5px 缓冲区
            const isTop = scrollTop <= 5
            // console.log("滚动",this.history.allLoaded)
            if (isBottom && !this.history.allLoaded) {
                console.log('到达底部')
                // 加载更多等操作
                this.getMsgMore()
            }
            if (isTop && this.history.allLoaded) {
                // console.log('到达顶部')
            }
        },
        playAudio(){
            const audio = new Audio('/img/msn.mp3');
            audio.play().catch(error => {
                console.error("播放音频时出错:", error);
            });
        },
        onLongpress(){},
        onItem(data){
            switch(data.type)
            {
                case "order":
                    this.$nextTick(() => {
                        this.$refs.orderDetail.open("add").setData(data.payload.order)
                    })
                    break;
                case "address":
                    this.$nextTick(() => {
                        this.$refs.orderDetail.open("add").setData(data.payload.address)
                    })
                    break;
            }
        },
        chooseEmoji(data){
            this.inputMessage += data;
        },
        initEmoji() {
			let newList = [];
			let i = 1;
			for (let key in emojiMap) {
				let obj = {};
				obj['index'] = i;
				obj['text'] = key;
				obj['image'] = emojiMap[key];
				i++;
				newList.push(obj);
			}
			var list = [];
			let A = newList.filter((item, index) => {
				return (index + 1) % 8 === 0;
			});
			A.unshift({ index: 0 });
			A.push({ index: newList.length });
			this.emojiList = A.map((item, index) => {
				return newList.slice(A[index].index, A[index + 1]?.index || newList.length);
			});
			// this.scroll({ detail: { scrollTop: 10 } });
		},
        /**
         * 发送订单消息
         * @param data 
         */
        async sendOrder(data){
            var orderData = {"img":data.img,"name":data.product.product_name,"goods_id":data.life_goods_id,"order":data.out_order_no,"price":this.$TOOL.disMoney(data.pay_money),"status":data.status};
            var resp = await this.sendMessageApi("order",orderData);
            if (!resp) {
                return ;
            }
            this.sendMessageData({
                payload: {
                    order: orderData
                },
                type: 'order'
            });
        },
        /**
         * 收集地址消息
         * @param data 
         */
        async sendAddress(data){
            var orderData = {"img":data.img,"name":"完善会员信息","order":data.out_order_no,"status":0};
            var resp = await this.sendMessageApi("address",orderData);
            if (!resp) {
                return ;
            }
            this.sendMessageData({
                payload: {
                    address: orderData
                },
                type: 'address'
            });
        },
        async sendMessage(){
            if (!this.inputMessage) return ;
            var resp = await this.sendMessageApi("text",this.inputMessage);
            if (!resp) {
                this.inputMessage = "";
                return ;
            }
            this.sendMessageData({
                payload: {
                    text: this.inputMessage
                },
                type: 'text'
            });
            this.inputMessage = ""
        },
        sendMessageData({payload,type}){
			const message = {
				groupId: this.chatItem.poi_id,
				senderData: {
                    avatar:this.chatItem.avatar
                },
				senderId: this.myid,
				messageId: Date.now(),
				payload: payload,
				timestamp: Date.now(),
				type: type,
				recalled: false,
				status: 'success',
				isHide: 0
			};
			this.pushList(message);
        },
        handleKeyCode(event){
            if (event.keyCode == 13) {
                if (!event.ctrlKey) {
                    this.sendMessage()
                    event.preventDefault();
                } else {
                    this.inputMessage += "\n";
                }
            } else {
                return ;
            }
        },
        checkChatItem(index){
            this.checkChat = index;
            this.chatItem = this.chatContact[index]
            this.chatContact[index].last.num = 0;
            this.msgPage = 1;
            this.history.messages = []
            this.history.allLoaded = false
            this.orderData.list = [];
            this.orderData.page = 1;
            this.orderData.tab = "user";
            this.getMsgData();
            this.getMsgOrder();
            this.getOrderList();
        },
        async getMsgOrder(){
            var resp = await this.$API.chat.msgOrder.get({"msgId":this.chatItem.id})
            if (resp.code == 0) return ;
            this.msgOrder = resp.data.order;
        },
        initPush(){
            var _this = this;
            if (!this.pushObj) {
                this.pushObj = new Push({
                    "url":this.wsUrl,
                    "app_key":"265c33b73d5c04f918978577df2c48d2",
                    "auth":this.wsAuth
                });
            }
            var user_channel = this.pushObj.subscribe('service-' + this.myid);
            user_channel.on('message', function (data) {
                _this.playAudio()
                _this.unreadCount ++;
                _this.sortItemData(data.item)
                if (_this.chatItem && _this.chatItem.openid == data.openid) { // 当前窗口实时推送
                    _this.formatMsg(data);
                }
                // 给消息标红并更新最后一条消息
                var msgData = _this.chatContact;
                for (var i=0; i <= msgData.length;i ++) {
                    var item = msgData[i];
                    if (item && item.openid == data.openid) {
                        item.last.type = data.type;
                        item.last.content = data.content;
                        item.last.create_at = data.create_at
                        item.last.last_at = data.last_at
                        // item.last.num ++;
                    }
                }
            })
        },
        truncateByBytes(str, maxBytes) {
            let count = 0;
            let result = '';
            for (const char of str) {
                // 中文、全角符号算 2 字节，其他算 1 字节
                const byteLen = char.match(/[^\x00-\xff]/) ? 2 : 1;
                if (count + byteLen > maxBytes) break;
                result += char;
                count += byteLen;
            }
            return result + (count < str.length ? '...' : '');
        },
        sortItemData(data){
            const existIdx = this.chatContact.findIndex(item => item.id === data.id);
            if (existIdx !== -1) { // 若已存在，按更新处理
                this.handleNewMessage(data);
                return;
            }
            // 新增数据到最顶部
            this.chatContact.unshift(data);
        },
        handleNewMessage(updateData) {
            const idx = this.chatContact.findIndex(item => item.id === updateData.id);
            this.chatContact.splice(idx, 1, updateData);
            this.sortSessions();
        },
        sortSessions() {
            this.chatContact.sort((a, b) => {
                const timeA = a.last_at && a.last_at !== '-' ? new Date(a.last_at).getTime() : 0;
                const timeB = b.last_at && b.last_at !== '-' ? new Date(b.last_at).getTime() : 0;
                return timeB - timeA;
            });
        },
        sortBooks() {
            this.chatContact.sort((a, b) => b.last_at - a.last_at)
        },
        formatMsg(item){
			var payload = {};
			if (item.type == 'text') {
				payload.text = item.content
			}
			if (item.type == 'order') {
				var order = JSON.parse(item.content)
				payload.order = order
			}
			if (item.type == 'pay') {
				var order = JSON.parse(item.content)
				payload.pay = order
			}
			if (item.type == 'address') {
				var order = JSON.parse(item.content)
				payload.address = order
			}
			if (item.type == 'image') {
				payload = {
					contentType: 'image/png',
					name: 'uni-image.png',
					size: 82942,
					url: item.content,
					width: 2732,
					height: 2732,
					thumbnail: item.content
				};
			}
			const message = {
				groupId: item.poi_id,
				senderData: {
					avatar:item.source==2?item.avatar:item.user.avatar,
					name:item.source==2?item.nick.truename:item.user.nickname
				},
				senderId: (item.source==1?item.openid:item.service_id),
				messageId: item.msgId,
				payload: payload,
				timestamp: item.time,
				type: item.type,
				recalled: false,
				status: 'success',
				isHide: 0
			};
			this.pushList(message);
		},
        async pushList(message) {
			this.initMessageItem(message);
			this.history.messages.unshift(message);
			// 是否触发文字动效果
			if (message.type === 'text' || message.type === 'text_quote') {
				this.onSetText(message.payload.text);
			}
			// 缓存照片地址，
			if (message.type === 'image' || message.type === 'image_transmit') {
				imageList.push(message.payload.url);
			}
		},
		// 组装item
		initMessageItem(message, index) {
			message['isHide'] = 0;
			if (index === 0 && (message.type === 'text' || message.type === 'text_quote')) {
				this.onSetText(message.payload.text);
			}
		},
		// 文本触发效果相关========
		onSetText(text) {},
        // 切换聊天窗口
        async toggleChat() {
            this.visible = !this.visible
            if (this.visible) {
                // 打开窗口时清除未读角标
                this.unreadCount = 0
            }
            if (this.chatContact.length == 0) {
                this.loadMsg = true;
                var resp = await this.$API.chat.list.get({page:this.page,pageSize:this.size})
                this.loadMsg = false;
                if (resp.code == 0) {
                    return this.$message.error(resp.msg)
                }
                this.chatContact = this.chatContact.concat(resp.data.rows)
            }
            // this.chatItem = this.chatContact[0]
            // this.userId = this.chatItem.openid;
            // this.getMsgData();
        },
        /**
         * 加载更多
         */
        async getMsgMore(){
            this.history.allLoaded = true;
            this.msgLoad = true;
            var resp = await this.$API.chat.msg.get({"page":this.msgPage,"size":this.msgSize,"openid":this.chatItem.openid})
            this.msgLoad = false;
            if (resp.data.rows.length > 0) {
                this.msgPage ++;
                var msgData = []
				var list = resp.data.rows
                // 同步混入数据
                list.forEach((item, ix) => {
                    var payload = {};
                    if (item.type == 'text') {
                        payload.text = item.content
                    }
                    if (item.type == 'order') {
                        var order = JSON.parse(item.content)
                        payload.order = order
                    }
                    if (item.type == 'pay') {
                        var order = JSON.parse(item.content)
                        payload.pay = order
                    }
                    if (item.type == 'address') {
                        var order = JSON.parse(item.content)
                        payload.address = order
                    }
                    if (item.type == 'image') {
                        payload = {
                            contentType: 'image/png',
                            name: 'uni-image.png',
                            size: 82942,
                            url: item.content,
                            width: 2732,
                            height: 2732,
                            thumbnail: item.content
                        };
                    }
                    const message = {
                        groupId: item.poi_id,
                        senderData: {
                            avatar:item.avatar
                        },
                        senderId: (item.source==1?item.openid:item.service_id),
                        messageId: item.msgId,
                        payload: payload,
                        timestamp: item.time,
                        type: item.type,
                        recalled: false,
                        status: 'success',
                        isHide: 0
                    };
                    msgData[ix] = message
                });
                this.history.messages = [...this.history.messages, ...msgData];
                this.history.allLoaded = false;
            } else {
                this.history.allLoaded = true;
            }
        },
        /**
         * 首次加载
         */
        async getMsgData(){
            var resp = await this.$API.chat.msg.get({"page":this.msgPage,"size":this.msgSize,"openid":this.chatItem.openid})
            if (resp.data.rows.length > 0) {
                var msgData = resp.data.rows
                msgData.forEach((item,index)=>{
                    this.formatMsg(item);
                })
                this.msgPage ++;
            }
        },
        async uploadSuccess(data){
            var resp = await this.sendMessageApi("image",data.data.src);
            if (!resp) {
                return ;
            }
            this.sendMessageData({
                payload: {
                    contentType: 'image/png',
                    name: data.data.fileName,
                    size: 0,
                    url: data.data.src,
                    width: 2732,
                    height: 2732,
                    thumbnail: data.data.src
                },
                type: 'image'
            });
            this.uploadImg = "";
        },
        async sendMessageApi(type,content){
            this.chatContact[this.checkChat].last.num = 0;
            var resp = await this.$API.chat.send.post({type:type,content: content,groupId: this.chatItem.poi_id,openid:this.chatItem.openid})
            if (resp.code == 0) return false;
            this.chatContact[this.checkChat].last.type = type;
            this.chatContact[this.checkChat].last.content = (type=='text'?this.truncateByBytes(content,18):content);
            this.chatContact[this.checkChat].last.create_at = resp.data.time;
            return true;
        },
        doneOrder(data){
            this.$confirm(`手动核销订单后,该订单不支持线上退款，如需退款需与客户线下进行处理❗️如商家原因拒绝退款，平台会代替商家先行垫付且店铺无法正常经营`, '注意事项', {
                type: 'warning'
            }).then(async ()=>{
                this.isDoneing = true;
                var resp = await this.$API.merOrder.done.post({"id":data.order_sn});
                this.isDoneing = false;
                if (resp.code == 0) {
                    return this.$message.error(resp.msg);
                }
                this.$message.success(resp.msg);
                this.getOrderList()
            }).catch(()=>{})
        },
        async getOrderList(){
            this.orderData.loading = true;
            var resp = await this.$API.order.list.get({"page":this.orderData.page,"pageSize":this.orderData.size,"order":this.orderData.order,"openid":this.chatItem.openid});
            this.orderData.loading = false;
            if (resp.code == 0) {
                return ;
            }
            this.orderData.list = resp.data.rows;
            this.orderData.total = resp.data.total;
        }
    }
}
</script>

<style scoped lang="scss">
@import '@/style/index.scss';

.order-info-user{background-color: #fff;padding: 10px;margin-top: 10px;}
.order-info-user .title{font-size: 16px;color: #333;font-weight: bold;padding-bottom: 10px;border-bottom: 1px solid #f8f8f8;}
.order-info-user .info-item{height: 40px;line-height: 40px;font-size: 12px;display: flex;align-items: center;border-bottom: 1px solid #f8f8f8;}
.order-info-user .info-item .right{color: #666;margin-left: auto;margin-right: 0;}
.order-info-user .info-item .right text{border: 1px solid #ccc;color: #333;font-size: 12px;padding: 0 15upx;margin-left: 10px;border-radius: 5px;}

.aside-tabs{display: flex;height: 65px;align-items: center;gap: 10px;border-bottom: 1px solid var(--el-border-color-light);padding: 13px 15px;}
.aside-tabs .aside-tab-items{font-size: 14px;cursor: pointer;padding: 0 20px;}
.aside-tabs .aside-tab-items.active{color: var(--el-color-primary);}
.quick-search{display: flex;align-items: center;justify-content: space-between;gap: 10px;}
.quick-search .search-input{flex: 1;display: flex;align-items: center;gap: 5px;}
.quick-search .search-btn-txt{font-size: 14px;color: #409eff;cursor: pointer;}
.quick-table .quick-table-body{margin: 10px 0;}
.border-none{border: 0;}
.msg-title{font-size: 18px;font-weight: bold;}
.loading-text{background-color: #f8f8f8;text-align: center;font-size: 12px;}
.order-list-chat{height: 100%;flex-direction: column;flex: 1;display: flex;}
.m-order-s{background-color: #fff;border-radius: 5px;margin-bottom: 10px;border: 1px solid #f8f8f8;}
.m-order-s .m-order-item{display: flex;font-size: 14px;position: relative;background-color: #f8f8f8;}
.m-order-s .order-btn-group{display: flex;align-items: center;padding: 10px;gap: 10px;}
.order-search-input{display: flex;align-items: center;gap: 10px;flex: 1;}
.m-order-s .order-img{display: flex;}
.m-order-s .order-img image{width: 80px;height: 80px;}
.m-order-s .order-info {padding: 5px 10px 10px;flex: 1;}
.m-order-s .order-info .title{font-size: 14px;overflow: hidden;text-overflow: ellipsis;display: -webkit-box;-webkit-line-clamp: 2;-webkit-box-orient: vertical;}
.m-order-s .order-info .desc{font-size: 12px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;color: #999;}
.m-order-s .order-info .price{font-size: 14px;color: #f00;}
.m-order-s .order-status-btn{position: absolute;right: 0;bottom: 0;display: flex;align-items: center;gap: 5px;}
.m-order-s .status{border-radius: 5px 0 5px 0;background-color: #909399;font-size: 12px;color: #fff;padding: 5px;}
.m-order-s .status.cus{cursor: pointer;}
.m-order-s .status.info{background-color: #909399;}
.m-order-s .status.primary{background-color: #409eff;}
.m-order-s .status.success{background-color: #67c23a;}
.m-order-s .status.danger{background-color: #f56c6c;}
.m-order-s .status.warn{background-color: #e6a23c;}

.hideStr{overflow: hidden;width: 80%;}
.contact-item{display: flex;align-items: center;background-color: #fff;padding: 10px;border-bottom: 1px solid #f8f8f8;cursor: pointer;}
.contact-item.active{background-color: #f8f8f8;}
.contact-item .img{position: relative;border: 1px solid #f8f8f8;border-radius: 5px;display: flex;align-items: center;justify-content: center;}
.contact-item span.last-num{background-color: #f00;color: #fff;width: 20px;height: 20px;display: flex;align-items: center;justify-content: center;border-radius: 20px;font-size: 12px;margin-left: 10px;position: absolute;right: 0;top: 0;}

.contact-item .kefu-store{margin-left: 10px;}
.contact-item .kefu-store .name{font-size: 14px;color: #333;display: flex;align-items: center;}


.contact-item .kefu-store .desc{font-size: 12px;color: #666;margin-top: 5px;}
.contact-item .time{margin-left: auto;margin-right: 0;font-size: 12px;color: #666;}
.send-btn-group{margin-top: 10px;display: flex;align-items: center;justify-content: space-between;}
.send-btn-group .send-emoji{display: flex;align-items: center;gap: 15px;cursor: pointer;}
.quick-group{display: flex;align-items: center;gap: 10px;padding: 15px 0;}
.quick-group .item-btn{background-color: #f8f8f8;padding: 5px;border-radius: 3px;display: flex;align-items: center;gap: 5px;cursor: pointer;}
.z_index2{position: relative;z-index: 2;}
.empty-data{display: flex;width: 100%;text-align: center;justify-content: center;font-size: 18px;background-color: #f8f8f8;align-items: center;}
.swiper-item-box {
    position: relative;
    z-index: 1;
    box-sizing: border-box;
    width: 100%;
    height: 100%;
    max-height: 300px;
    overflow: auto;
    flex-wrap: wrap;
    align-items: flex-start;

    .swiper-item-box-l {
        // width: calc(62.5vw);
        width: calc(100%);
        flex-wrap: wrap;
        align-items: flex-start;
    }
    .swiper-item-box-r {
        width: calc(37.5%);
        flex-wrap: wrap;
        align-items: flex-start;
    }

    .emoji-item {
        width: calc(12.5%);
        height: calc(12.5%);
        flex-shrink: 0;
        transition: all 0.1s;
        padding: 10px 0;
        
        .img {
            width: 55%;
            height: 55%;
            cursor: pointer;
        }
        &:hover {
            background-color: #f8f8f8;
        }
    }
}
.flex_r {
    display: flex;
    flex-direction: row;
}
.swiper-item-box-b {
    width: calc(38%);
    position: absolute;
    z-index: 99;
    right: 0rpx;
    bottom: 0px;
    padding: 0 0 40rpx 0;
    // background-color: #000;
    background-image: linear-gradient(to top, #ececec, #ececec, #ececec, #ececec, #ececec, rgba(0, 0, 0, 0));
}
.swiper-item-box-delete {
    width: 116rpx;
    height: calc(12.5%);
    border-radius: 10rpx;
    margin-right: 20rpx;
    background-color: #fff;
    .img {
        width: 45%;
        height: 45%;
        margin-right: 4rpx;
    }
}
.swiper-item-box-button {
    width: 116rpx;
    height: calc(12.5vw);
    border-radius: 10rpx;
    margin-right: 10rpx;
    background-color: #05c160;
}
.page {
	position: fixed;
	z-index: 1;
	top: 0;
	left: 0;
	bottom: 0;
	right: 0;
	background-color: #ededed;
}
.scroll-Y {
	width: 100%;
	height: 0;
	transition: all 0.2s;
	transform: rotate(180deg);
	background-color: #ededed;
	::-webkit-scrollbar {
		display: none;
	}
}
.scroll-view-str {
	width: 100%;
}

.message-list .time {
	width: 100%;
	color: #a3a3a3;
	line-height: 50px;
}

.message-list .recalled {
	width: 100%;
	height: 50rpx;
	margin: 20rpx 0;
	color: #a3a3a3;

	.recalled-edit {
		color: #5a6693;
		margin-left: 14rpx;
	}
}
@keyframes simple-blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}
.global-im {
    .unreadCount{
        position: fixed;
        right: 42px;
        bottom: 162px;
        animation: simple-blink 2s ease-in-out infinite;
    }
  .im-trigger {
    position: fixed;
    right: 24px;
    bottom: 124px;
    width: 48px;
    height: 48px;
    background: #409eff;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);
    z-index: 2000;
    transition: all 0.3s;
    color: white;
    &:hover {
      background: #66b1ff;
    }
    &.active {
      background: #909399;
    }
  }
}
.chat-container {
  display: flex;
  flex-direction: column;
  height: 100%;
  .message-list {
    flex: 1;
    overflow-y: auto;
    background-color: #f8f8f8;
    transition: all 0.2s;
    transform: rotate(180deg);
    .message-item {
      display: flex;
      margin-bottom: 16px;
      &.self {
        flex-direction: row-reverse;
        .content {
          margin-right: 12px;
          align-items: flex-end;
          .text {
            background: #95ec69;
          }
        }
      }
      &.other {
        .content {
          margin-left: 12px;
        }
      }
      .content {
        display: flex;
        flex-direction: column;
        max-width: 70%;
        .name {
          font-size: 12px;
          color: #999;
          margin-bottom: 4px;
        }
        .text {
          padding: 8px 12px;
          background: #f0f0f0;
          border-radius: 12px;
          word-break: break-all;
        }
        .time {
          font-size: 10px;
          color: #ccc;
          margin-top: 4px;
        }
      }
    }
  }
  .input-area {
    padding: 0 16px 16px 16px;
    border-top: 1px solid #eee;
  }
}
</style>