<style scoped lang="scss">
.system-container {

  :deep(.el-card__body) {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    flex: 1;
    overflow: auto;

    .el-table {
      flex: 1;
    }

  }
}

.page-content {
  margin-bottom: 20px;
}

.page-pager {
  background-color: var(--el-color-white);
  height: 24px;
}

.detail-section {
    margin-top: 15px;

    .section-title {
        font-weight: 500;
        margin-bottom: 10px;
        color: var(--el-text-color-primary);
    }

    :deep(.el-textarea__inner) {
        font-family: monospace;
        font-size: 13px;
        background: var(--el-fill-color-lighter);
    }
}
</style>
<template>
  <div class="system-container layout-padding">
    <el-card shadow="hover" class="layout-padding-auto">

      <el-form
          :model="queryParams"
          ref="queryRef"
          size="default" label-width="0px" class="mt5 mb5">
        <el-input
            v-model="queryParams.username"
            placeholder="操作用户"
            clearable
            @blur="handleQuery"
            class="wd150 mr10">
        </el-input>
        <el-date-picker
            v-model="dateRange"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            value-format="YYYY-MM-DD"
            @change="handleQuery"
            class="wd260 mr10">
        </el-date-picker>

        <el-button class="ml10" plain size="default" type="success" @click="handleQuery">
          <SvgIcon name="ele-Search"/>
          查询
        </el-button>
        <el-button plain size="default" type="warning" @click="resetQuery">
          <SvgIcon name="ele-Refresh"/>
          重置
        </el-button>
        <el-button plain size="default" type="danger" @click="handleClearLog">
          <SvgIcon name="ele-Delete"/>
          清空日志
        </el-button>
      </el-form>

      <el-table
          border
          stripe
          :height="state.tableHeight"
          :data="tableData"
          v-loading="loading">
        <el-table-column prop="id" label="ID" width="170" align="center" />
        <el-table-column prop="username" label="操作用户" width="130" align="center" />
        <el-table-column label="操作模块" align="center">
          <template #default="{ row }">
            <span style="white-space: nowrap">{{ getModule(row.method) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="操作类型" width="95" align="center">
          <template #default="{ row }">
            <el-tag :type="getOperationTypeColor(row.operation)" size="small">
              {{ getOperationTypeLabel(row.operation) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="operation" label="操作描述" min-width="200" show-overflow-tooltip />
        <el-table-column label="请求方式" width="100" align="center">
          <template #default="{ row }">
            <el-tag :type="getMethodColor(getHttpMethod(row.method))" size="small">{{ getHttpMethod(row.method) }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="请求URL" min-width="200" show-overflow-tooltip>
          <template #default="{ row }">{{ getRequestUrl(row.method) }}</template>
        </el-table-column>
        <el-table-column prop="ip" label="IP地址" width="150" align="center" />
        <el-table-column prop="executeTime" label="耗时(ms)" width="95" align="center" />
        <el-table-column prop="createTime" label="操作时间" width="175" align="center" />
        <el-table-column label="操作" width="75" align="center" fixed="right">
          <template #default="{ row }">
            <el-button type="primary" link size="small" @click="handleDetail(row)">详情</el-button>
          </template>
        </el-table-column>
      </el-table>

      <div class="page-pager">
        <el-pagination
            v-model:current-page="queryParams.pageNum"
            v-model:page-size="queryParams.pageSize"
            :page-sizes="[10, 20, 50, 100]"
            :total="total"
            layout="total, sizes, prev, pager, next, jumper"
            @size-change="handleQuery"
            @current-change="handleQuery"
            small
        />
      </div>
    </el-card>

    <!-- 详情对话框 -->
    <el-dialog v-model="detailVisible" title="日志详情" width="700px">
      <el-descriptions :column="2" border v-if="currentLog">
        <el-descriptions-item label="操作用户">{{ currentLog.username }}</el-descriptions-item>
        <el-descriptions-item label="操作模块">{{ getModule(currentLog.method) }}</el-descriptions-item>
        <el-descriptions-item label="操作类型">
          <el-tag :type="getOperationTypeColor(currentLog.operation)">
            {{ getOperationTypeLabel(currentLog.operation) }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="请求方式">
          <el-tag :type="getMethodColor(getHttpMethod(currentLog.method))" size="small">{{ getHttpMethod(currentLog.method) }}</el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="请求URL" :span="2">{{ getRequestUrl(currentLog.method) }}</el-descriptions-item>
        <el-descriptions-item label="IP地址">{{ currentLog.ip }}</el-descriptions-item>
        <el-descriptions-item label="耗时">{{ currentLog.executeTime }}ms</el-descriptions-item>
        <el-descriptions-item label="操作时间" :span="2">{{ currentLog.createTime }}</el-descriptions-item>
        <el-descriptions-item label="操作描述" :span="2">{{ currentLog.operation }}</el-descriptions-item>
      </el-descriptions>
      <div class="detail-section" v-if="currentLog">
        <div class="section-title">请求参数</div>
        <el-input type="textarea" :rows="4" :model-value="formatJson(currentLog.requestParam)" readonly />
      </div>
      <template #footer>
        <el-button @click="detailVisible = false">关闭</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts" name="SystemLog">
import { ref, reactive, onMounted, onBeforeUnmount, nextTick } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { $get, $body } from '/@/utils/request';

const queryRef = ref();
const queryParams = reactive({
    pageNum: 1,
    pageSize: 10,
    username: '',
    startDate: '',
    endDate: ''
});
const dateRange = ref<string[]>([]);

const state = reactive({
    tableHeight: 400,
});

const loading = ref(false);
const tableData = ref<any[]>([]);
const total = ref(0);

const detailVisible = ref(false);
const currentLog = ref<any>(null);

const getModule = (method: string) => {
    if (!method) return '-';
    const m = method.match(/com\.kym\.admin\.controller\.(\w+)Controller/);
    if (!m) return '-';
    const controllers: Record<string, string> = {
        'WashStation': '站点管理',
        'WashDevice': '设备管理',
        'WashOrder': '订单管理',
        'User': '用户管理',
        'Account': '账户管理',
        'AdminUser': '运维用户',
        'Role': '角色管理',
        'SystemLog': '系统日志',
        'Finance': '财务管理',
        'RechargeConfig': '充值配置',
        'Promotion': '优惠活动',
        'Activity': '活动管理',
        'Banner': '广告管理',
        'Faq': 'FAQ管理',
        'Feedback': '反馈管理',
        'DeviceConfig': '设备配置',
        'DeviceRelation': '设备关联',
        'InvestorInfo': '投资人',
        'DictData': '字典管理',
        'SystemNotice': '系统公告',
        'Wx': '微信管理',
        'Attachment': '附件管理',
        'Custom': '用户管理',
    };
    return controllers[m[1]] || m[1];
};

const getOperationTypeLabel = (operation: string) => {
    if (!operation) return '其他';
    if (operation.startsWith('新增')) return '新增';
    if (operation.startsWith('修改')) return '修改';
    if (operation.startsWith('删除')) return '删除';
    if (operation.startsWith('查询')) return '查询';
    if (operation.includes('登录')) return '登录';
    if (operation.includes('登出')) return '登出';
    if (operation.includes('清空')) return '删除';
    if (operation.includes('导入')) return '新增';
    if (operation.includes('导出')) return '查询';
    return '其他';
};

const getOperationTypeColor = (operation: string) => {
    const map: Record<string, string> = {
        '新增': 'success',
        '修改': 'warning',
        '删除': 'danger',
        '查询': 'info',
        '登录': 'primary',
        '登出': '',
        '其他': '',
    };
    return map[getOperationTypeLabel(operation)] || '';
};

const getHttpMethod = (method: string) => {
    if (!method) return '-';
    const m = method.match(/\.(\w+)\(\)$/);
    if (!m) return '-';
    const action = m[1].toLowerCase();
    if (action.startsWith('list') || action.startsWith('get') || action.startsWith('detail') || action.startsWith('query')) return 'GET';
    return 'POST';
};

const getMethodColor = (m: string) => {
    if (m === 'GET') return 'success';
    if (m === 'POST') return 'primary';
    return '';
};

const getRequestUrl = (method: string) => {
    if (!method) return '-';
    const m = method.match(/com\.kym\.admin\.controller\.(\w+)Controller\.(\w+)\(\)$/);
    if (!m) return method;
    const controller = m[1];
    const action = m[2];
    return `/${controller[0].toLowerCase() + controller.slice(1)}/${action}`;
};

const formatJson = (str: string) => {
    if (!str) return '';
    try {
        return JSON.stringify(JSON.parse(str), null, 2);
    } catch {
        return str;
    }
};

const handleQuery = async () => {
    if (dateRange.value && dateRange.value.length === 2) {
        queryParams.startDate = dateRange.value[0];
        queryParams.endDate = dateRange.value[1];
    } else {
        queryParams.startDate = '';
        queryParams.endDate = '';
    }

    loading.value = true;
    try {
        const res = await $get('/systemLog/list', queryParams) as any;
        tableData.value = res?.list || [];
        total.value = res?.total || 0;
    } catch {
        tableData.value = [];
        total.value = 0;
    } finally {
        loading.value = false;
    }
};

const resetQuery = () => {
    queryParams.username = '';
    dateRange.value = [];
    queryParams.pageNum = 1;
    handleQuery();
};

const handleDetail = (row: any) => {
    currentLog.value = row;
    detailVisible.value = true;
};

const handleClearLog = async () => {
    await ElMessageBox.confirm('确定要清空所有操作日志吗？此操作不可恢复！', '警告', { type: 'warning' });
    try {
        await $body('/systemLog/clear', {});
        ElMessage.success('清空成功');
        handleQuery();
    } catch {
        // ignore
    }
};

const calcTableHeight = () => {
    nextTick(() => {
        const bodyHeight = document.body.clientHeight;
        const queryHeight = queryRef.value?.$el?.clientHeight || 56;
        state.tableHeight = bodyHeight - queryHeight - 240;
    });
};

onMounted(() => {
    handleQuery();
    calcTableHeight();
    window.addEventListener('resize', calcTableHeight);
});

onBeforeUnmount(() => {
    window.removeEventListener('resize', calcTableHeight);
});
</script>
