-
Notifications
You must be signed in to change notification settings - Fork 2.6k
feat: add operate log #2626
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add operate log #2626
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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" | ||
|
|
@@ -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({ | ||
|
|
@@ -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: '', | ||
|
|
@@ -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') | ||
|
|
@@ -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() | ||
|
|
@@ -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> | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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:
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:
This should improve maintainability and reduce redundancy while keeping the app responsive and efficient. |
||
|
|
||
There was a problem hiding this comment.
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:
This will import
...getOperateLogfrom wherever it is defined, effectively including all properties of thegetOperateLogfunction 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.