Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion ui/src/api/operate-log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ const getOperateLog: (
return get(`${prefix}/${page.current_page}/${page.page_size}`, param, loading)
}

const getMenuList: () => Promise<Result<any>> = () => {
return get(`${prefix}/menu_operate_option/`, undefined, undefined)
}

export default {
getOperateLog
getOperateLog,
getMenuList
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The provided code looks clean and well-structured. However, there is one minor suggestion to make it more concise:

@@ -22,7 +22,6 @@ const getOperateLog: (
 export default {
-  getOperateLog,
+  ...getOperateLog,
 } 

This will import ...getOperateLog from wherever it is defined, effectively including all properties of the getOperateLog function object into the exported module. This can be useful if you want to avoid listing each property individually.

For other checks, such as type checking or security considerations, I would need additional context about how these functions are used and what kind of operations they perform with their parameters. If the endpoint requires specific types or handles sensitive data properly, ensure that this is accounted for in your environment. Additionally, consider adding input validation before making API calls to prevent common errors like missing or incorrect parameters.

85 changes: 72 additions & 13 deletions ui/src/views/operate-log/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,49 @@
@changePage="getList"
v-loading="loading"
>
<el-table-column prop="menu" :label="$t('views.operateLog.table.menu.label')" width="160" />
<el-table-column prop="menu" :label="$t('views.operateLog.table.menu.label')" width="160">
<template #header>
<div>
<span>{{ $t('views.operateLog.table.menu.label') }}</span>
<el-popover :width="200" trigger="click" :visible="popoverVisible">
<template #reference>
<el-button
style="margin-top: -2px"
:type="operateTypeArr && operateTypeArr.length > 0 ? 'primary' : ''"
link
@click="popoverVisible = !popoverVisible"
>
<el-icon>
<Filter />
</el-icon>
</el-button>
</template>
<div class="filter">
<div class="form-item mb-16">
<div @click.stop>
<el-scrollbar height="300" style="margin: 0 0 0 10px;">
<el-checkbox-group v-model="operateTypeArr" style="display: flex; flex-direction: column;">
<el-checkbox v-for="item in operateOptions"
:key="item.value"
:label="item.label"
:value="item.value" />
</el-checkbox-group>
</el-scrollbar>
</div>
</div>
</div>
<div class="text-right">
<el-button size="small" @click="filterChange('clear')">{{
$t('common.clear')
}}</el-button>
<el-button type="primary" @click="filterChange" size="small">{{
$t('common.confirm')
}}</el-button>
</div>
</el-popover>
</div>
</template>
</el-table-column>
<el-table-column prop="operate" :label="$t('views.operateLog.table.operate.label')" />
<el-table-column
width="120"
Expand Down Expand Up @@ -119,11 +161,13 @@
</template>
<script setup lang="ts">
import { ref, onMounted, reactive } from 'vue'
import getOperateLog from '@/api/operate-log'
import operateLog from '@/api/operate-log'
import DetailDialog from './component/DetailDialog.vue'
import { t } from '@/locales'
import { beforeDay, datetimeFormat, nowDate } from '@/utils/time'

const popoverVisible = ref(false)
const operateTypeArr = ref<any[]>([])
const DetailDialogRef = ref()
const loading = ref(false)
const paginationConfig = reactive({
Expand All @@ -134,7 +178,7 @@ const paginationConfig = reactive({
const searchValue = ref('')
const tableData = ref<any[]>([])
const history_day = ref<number | string>(7)
const filter_type = ref<string>('menu')
const filter_type = ref<string>('user')
const filter_status = ref<string>('')
const daterange = ref({
start_time: '',
Expand Down Expand Up @@ -165,14 +209,6 @@ const dayOptions = [
}
]
const filterOptions = [
{
value: 'menu',
label: t('views.operateLog.table.menu.label')
},
{
value: 'operate',
label: t('views.operateLog.table.operate.label')
},
{
value: 'user',
label: t('views.operateLog.table.user.label')
Expand All @@ -196,6 +232,15 @@ const statusOptions = [
label: t('views.operateLog.table.status.fail')
}
]
const operateOptions = ref<any[]>([])

function filterChange(val: string) {
if (val === 'clear') {
operateTypeArr.value = []
}
getList()
popoverVisible.value = false
}

function changeStatusHandle(val: string) {
getList()
Expand Down Expand Up @@ -241,15 +286,29 @@ function getList() {
if (filter_type.value === 'status') {
obj['status'] = filter_status.value
}
return getOperateLog.getOperateLog(paginationConfig, obj, loading).then((res) => {
if(operateTypeArr.value.length > 0) {
obj['menu'] = JSON.stringify(operateTypeArr.value)
}
return operateLog.getOperateLog(paginationConfig, obj, loading).then((res) => {
tableData.value = res.data.records
paginationConfig.total = res.data.total
})
}

function getMenuList() {
return operateLog.getMenuList().then((res) => {
let arr: any[] = res.data
arr.filter((item, index, self) =>
index === self.findIndex((i) => i['menu'] === item['menu'])
).forEach(ele => {
operateOptions.value.push({label:ele.menu_label, value:ele.menu})
})
})
}

onMounted(() => {
getMenuList()
changeDayHandle(history_day.value)
getList()
})
</script>
<style lang="scss" scoped>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks good overall, but there are a few areas that could be optimized or improved:

  1. Code Duplication: The filter logic is repeated for both menu and operate. Consider refactoring this into a separate function to make it cleaner.

  2. Empty Check in Filter Change: Ensure that when val is 'clear', the checkbox array is properly cleared before resetting the list of options.

  3. API Call Optimization: If fetching menu data from /api/operate-log/getMenuList is expensive or frequently needed, consider caching the results locally.

  4. Loading State Handling: It might be beneficial to introduce more granular loading states based on different API requests.

Here's an updated version of the code with some optimizations:

<template>
  <!-- Table component remains mostly unchanged -->
</template>

<script setup lang="ts">
import { ref, onMounted, reactive } from 'vue'
import getOperateLog from '@/api/operate-log'
import DetailDialog from './component/DetailDialog.vue'
import { t } from '@/locales'
import { beforeDay, datetimeFormat, nowDate } from '@/utils/time'

const popoverVisible = ref(false)
const operateTypeArr = ref<any[]>([])
const DetailDialogRef = ref()
const loading = ref(false)

// Other variables remain mostly unchanged

onMounted(() => {
  getMenuList()
  changeDayHandle(history_day.value)
  getList()
})

async function fetchData(params: any): Promise<void> {
  try {
    const response = await getOperateLog.getOperateLog(paginationConfig, params, loading);
    tableData.value = response.data.records;
    paginationConfig.total = response.data.total;
  } catch (error) {
    // Handle error appropriately
  }
}

function filterChange(val: string) {
  if (val === 'clear') {
    operateTypeArr.value = [];
  } else {
    const filteredParams: Record<string, any> = {};
    
    if (filter_type.value === 'status') {
      filteredParams['status'] = filter_status.value;
    }

    if (operateTypeArr.value.length > 0 && filter_type.value === 'menu') {
      filteredParams['menu'] = JSON.stringify(operateTypeArr.value);
    }

    fetchData(filteredParams);
  }
  popoverVisible.value = false;
}

// ...

Explanation of Changes:

  1. Moved Fetch Logic to Separate Function: Created fetchData to encapsulate the API call logic, making it reusable and clean.

  2. Updated Filter Functionality: The filter function no longer needs checks for each property separately; they all use the same pattern now.

This should improve maintainability and reduce redundancy while keeping the app responsive and efficient.

Expand Down