﻿<template>
    <div class="store-page">
        <Breadcrumb />

        <a-card title="请求日志">
            <AppQueryFilter>
            <a-row class="query-row app-query-form">
                <a-col :flex="1">
                    <a-form :model="queryData" :label-col-props="{ span: 6 }" :wrapper-col-props="{ span: 18 }"
                        label-align="left">
                        <a-row :gutter="16">
                            <a-col :span="8">
                                <a-form-item field="begin_time" label="开始时间">
                                    <a-date-picker show-time format="YYYY-MM-DD HH:mm:ss"
                                        v-model="queryData.begin_time" />
                                </a-form-item>
                            </a-col>
                            <a-col :span="8">
                                <a-form-item field="end_time" label="结束时间">
                                    <a-date-picker show-time format="YYYY-MM-DD HH:mm:ss"
                                        v-model="queryData.end_time" />
                                </a-form-item>
                            </a-col>
                            <a-col :span="8">
                                <a-form-item field="create_user" label="用户UUID">
                                    <a-input v-model="queryData.create_user" />
                                </a-form-item>
                            </a-col>
                            <a-col :span="8">
                                <a-form-item field="url" label="请求URL">
                                    <a-input v-model="queryData.url" />
                                </a-form-item>
                            </a-col>
                            <a-col :span="8">
                                <a-form-item field="ip" label="请求IP">
                                    <a-input v-model="queryData.ip" />
                                </a-form-item>
                            </a-col>
                        </a-row>
                    </a-form>
                </a-col>
                <a-divider style="height: 84px" direction="vertical" />
                <a-col :flex="'86px'" style="text-align: right">
                    <a-space direction="vertical" :size="18">
                        <a-button type="primary" @click="search">
                            <template #icon>
                                <icon-search />
                            </template>
                            搜索
                        </a-button>
                        <a-button @click="reset">
                            <template #icon>
                                <icon-refresh />
                            </template>
                            重置
                        </a-button>
                    </a-space>
                </a-col>
            </a-row>
            </AppQueryFilter>

            <a-table :bordered="false" :data="data" stripe hoverable column-resizable class="table" :loading="loading" :columns="columns"
                :pagination="{
                    showPageSize: true,
                    showJumper: true,
                    showTotal: true,
                    pageSize: pagination.pagesize,
                    current: pagination.current,
                    total: pagination.total
                }" @page-change="handlePageChange" @page-size-change="handlePageSizeChange">
                <template #username="{ record }">
                    <a-avatar :size="30">
                        <img :alt="record.username ?? ''"
                            :src="record.avatar ?? 'https://lepao-cloud.xxoo365.top/view.php/25aa126dc406974ff3579a99a2c6501a.png'" />
                    </a-avatar>
                    {{ record.username }}
                </template>
                <template #time="{ record }">
                    {{ stramptoTime(record.create_time) }}
                </template>
                <template #optional="{ record }">
                    <a-button @click="showDetail(record)">查看详情</a-button>
                </template>
            </a-table>
        </a-card>
    </div>

    <a-modal v-model:visible="showModal" hide-cancel width="auto" style="min-width: 500px;" draggable>
        <template #title>
            日志详情
        </template>
        <div>
            <a-descriptions :data="modalData" :column="1" />
        </div>
    </a-modal>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { adminGetReqLog, adminGetReqLogDetail } from '@/api/user'
import { Notification } from '@arco-design/web-vue'

const showModal = ref(false)
const modalData = ref([])

const queryData = reactive({
    create_user: '',
    url: '',
    ip: '',
    begin_time: null,
    end_time: null
})

const pagination = reactive({
    total: 0,
    current: 1, // 默认从第1页开始
    pagesize: 20
})

const loading = ref(false)
const data = ref([])

const columns = [{
    title: 'ID',
    dataIndex: 'id',
}, {
    title: '操作人',
    slotName: 'username'
}, {
    title: '请求路径',
    dataIndex: 'url',
}, {
    title: '请求方法',
    dataIndex: 'method',
}, {
    title: '请求IP',
    dataIndex: 'ip',
}, {
    title: 'IP属地',
    dataIndex: 'location',
}, {
    title: '客户端类型',
    dataIndex: 'deviceType'
}, {
    title: '操作时间',
    slotName: 'time',
}, {
    title: '状态码',
    dataIndex: 'code'
}, {
    title: '操作',
    slotName: 'optional'
}
]

const search = () => {
    pagination.current = 1
    getLogList()
}

const reset = () => {
    queryData.create_user = ''
    queryData.url = ''
    queryData.ip = ''
    queryData.begin_time = null
    queryData.end_time = null
    getLogList()
}

const showDetail = async (record) => {
    try {
        loading.value = true
        showModal.value = false
        const res = await adminGetReqLogDetail({ id: record.id })
        if (!res || res.code !== 0)
            return Notification.error({
                title: '获取日志数据失败！',
                content: res?.msg ?? '请稍后再试'
            })

        const data = [{
            label: '操作人',
            value: res.data.username,
        }, {
            label: '操作人UUID',
            value: res.data.create_user,
        }, {
            label: '请求方式',
            value: res.data.method.toUpperCase()
        }, {
            label: '请求路径',
            value: res.data.url,
        }, {
            label: '请求IP',
            value: res.data.ip
        }, {
            label: 'IP属地',
            value: res.data.location
        }, {
            label: 'UA',
            value: res.data.ua
        },
        {
            label: '客户端类型',
            value: res.data.deviceType
        }, {
            label: '请求数据',
            value: JSON.stringify(res.data.reqData, null, 4)
        }, {
            label: '响应数据',
            value: JSON.stringify(res.data.resData, null, 4)
        },
        {
            label: '状态码',
            value: res.data.code
        },
        {
            label: '操作时间',
            value: stramptoTime(res.data.create_time)
        },
        ]

        modalData.value = data
        showModal.value = true
    } catch (error) {
        Notification.error({
            title: '获取日志数据失败！',
            content: error.message || '请稍后再试'
        })
    } finally {
        loading.value = false
    }
}

const getLogList = async () => {
    try {
        loading.value = true
        const reqData = {
            create_user: queryData.create_user,
            begin_time: new Date(queryData.begin_time).getTime(),
            end_time: new Date(queryData.end_time).getTime(),
            url: queryData.url,
            ip: queryData.ip,
            pagesize: pagination.pagesize,
            current: pagination.current
        }
        const res = await adminGetReqLog(reqData)
        if (!res || res.code !== 0)
            return Notification.error({
                title: '获取日志数据失败！',
                content: res?.msg ?? '请稍后再试'
            })

        data.value = res.data
        pagination.total = res.pagination.total
    } catch (error) {
        Notification.error({
            title: '获取日志数据失败！',
            content: error.message || '请稍后再试'
        })
    } finally {
        loading.value = false
    }
}

// 分页 - 页码变化
const handlePageChange = (page) => {
    pagination.current = page
    getLogList()
}

// 分页 - 每页条数变化
const handlePageSizeChange = (size) => {
    pagination.pagesize = size
    pagination.current = 1 // 页大小变化后回到第一页
    getLogList()
}

onMounted(() => {
    getLogList()
})

const stramptoTime = (time) => {
    return new Date(time).toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' })
}
</script>

<style scoped>
.table {
    margin-top: 15px;
}
</style>