Browse Source

11.16

还差导出
daijiajun/feature-20251107115823-股票知识测评
chenzhen 2 months ago
parent
commit
7f36c66891
  1. 261
      src/components/Question/QuestionTable.vue
  2. 31
      src/components/UserStatistics/UserStatisticsSearch.vue
  3. 75
      src/components/UserStatistics/UserStatisticsTable.vue
  4. 22
      src/components/WrongQuestion/WrongQuestionSearch.vue
  5. 168
      src/components/WrongQuestion/WrongQuestionTable.vue
  6. 8
      src/views/UserStatistics.vue

261
src/components/Question/QuestionTable.vue

@ -1,78 +1,27 @@
<!-- src/components/Question/QuestionTable.vue -->
<template>
<div class="question-table-container">
<!-- 表格容器 -->
<div class="table-container">
<!-- 题目数据表格 -->
<table>
<!-- 表头部分 -->
<thead>
<tr>
<!-- ID列支持排序 -->
<th @click="sort('id')" class="sortable">
<div class="sort-header">
ID
<!-- 排序图标当按照ID排序时显示 -->
<span v-if="sortField === 'id'" class="sort-icon">
<svg :style="{ transform: sortDirection === 'desc' ? 'rotate(180deg)' : 'rotate(0deg)' }"
width="12" height="12" viewBox="0 0 24 24" fill="none">
<path d="M7 10L12 15L17 10" stroke="#e74c3c" stroke-width="2" />
<path d="M12 15V3" stroke="#e74c3c" stroke-width="2" />
</svg>
</span>
</div>
</th>
<!-- 题干列 -->
<th>ID</th>
<th>题干</th>
<!-- 题目类型列 -->
<th>题目类型</th>
<!-- 出错次数列支持排序 -->
<th @click="sort('errorCount')" class="sortable">
<div class="sort-header">
出错次数
<!-- 排序图标当按照出错次数排序时显示 -->
<span v-if="sortField === 'errorCount'" class="sort-icon">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7 10L12 15L17 10" stroke="#e74c3c" stroke-width="2" />
<path d="M12 15V3" stroke="#e74c3c" stroke-width="2" />
</svg>
</span>
</div>
</th>
<!-- 出错率列支持排序 -->
<th @click="sort('errorRate')" class="sortable">
<div class="sort-header">
出错率
<!-- 排序图标当按照出错率排序时显示 -->
<span v-if="sortField === 'errorRate'" class="sort-icon">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7 10L12 15L17 10" stroke="#e74c3c" stroke-width="2" />
<path d="M12 15V3" stroke="#e74c3c" stroke-width="2" />
</svg>
</span>
</div>
</th>
<!-- 推荐系列列 -->
<th>出错次数</th>
<th>出错率</th>
<th>推荐系列</th>
<!-- 操作列 -->
<th>操作</th>
</tr>
</thead>
<!-- 表格主体部分 -->
<tbody>
<!-- 数据行遍历sortedItems数组渲染每一条题目数据 -->
<tr v-for="item in sortedItems" :key="item.id" :data-id="item.id">
<td>{{ item.id }}</td>
<tr v-for="(item,index) in items" :key="item.id" :data-id="item.id">
<td>{{ (page- 1) * pageSize + index + 1 }}</td>
<td>{{ item.stem }}</td>
<td>{{ item.questionTypeName }}</td>
<td>{{ item.errorCount }}</td>
<td>{{ item.errorRate }}%</td>
<td>{{ item.CrName }}</td>
<!-- 操作按钮 -->
<td>
<button class="btn-red small" @click="viewQuestion(item)">查看</button>
<button class="btn-red small" @click="editQuestion(item)">修改</button>
@ -82,16 +31,11 @@
</tbody>
</table>
</div>
<!-- 分页控件 -->
<div class="pagination-container">
<!-- 分页信息显示 -->
<div class="pagination-info">
{{ total }} 条记录 {{ page }}
</div>
<!-- 分页操作按钮 -->
<div class="pagination-controls">
<!-- 首页按钮 -->
<button
class="btn-pagination"
:disabled="page <= 1"
@ -99,7 +43,6 @@
>
首页
</button>
<!-- 上一页按钮 -->
<button
class="btn-pagination"
:disabled="page <= 1"
@ -107,40 +50,17 @@
>
上一页
</button>
<!-- 页码输入框 -->
<input
type="number"
class="page-input"
:value="page"
@keyup.enter="jumpToPage"
min="1"
:max="totalPages"
/>
<!-- 总页数显示 -->
<input type="number" class="page-input" :value="page" @keyup.enter="jumpToPage" min="1" :max="totalPages"/>
<span class="page-info">/ {{ totalPages }}</span>
<!-- 下一页按钮 -->
<button
class="btn-pagination"
:disabled="page >= totalPages"
@click="changePage(page + 1)"
>
<button class="btn-pagination" :disabled="page >= totalPages" @click="changePage(page + 1)">
下一页
</button>
<!-- 末页按钮 -->
<button
class="btn-pagination"
:disabled="page >= totalPages"
@click="changePage(totalPages)"
>
<button class="btn-pagination" :disabled="page >= totalPages" @click="changePage(totalPages)">
末页
</button>
</div>
</div>
<!-- 查看题目详情弹窗 -->
<div v-if="showViewModal" class="modal-overlay" @click.self="closeViewModal">
<div class="view-modal-content" @click.stop>
<div class="modal-header">
@ -148,17 +68,9 @@
<button class="close-btn" @click="closeViewModal">×</button>
</div>
<div class="view-modal-body">
<!-- 题目文本 -->
<p class="question-text">{{ currentQuestion.stem }}</p>
<!-- 选项容器 -->
<div class="options-container">
<!-- 遍历ABCD四个选项 -->
<div
v-for="option in ['A', 'B', 'C', 'D']"
:key="option"
:class="[option === currentQuestion.correctAnswer ? 'option-item-correct' : 'option-item']"
>
<div v-for="option in ['A', 'B', 'C', 'D']" :key="option" :class="[option === currentQuestion.correctAnswer ? 'option-item-correct' : 'option-item']">
{{ `${option}. ${currentQuestion[`option${option}`]}` }}
</div>
</div>
@ -174,7 +86,7 @@
<div class="modal-content" @click.stop>
<div class="modal-header">
<h3>编辑题目</h3>
<!-- <button class="close-btn" @click="closeEditModal">×</button> -->
<button class="close-btn" @click="closeEditModal">×</button>
</div>
<div class="modal-body">
<div class="form-row">
@ -194,11 +106,7 @@
<div class="form-row-options">
<div class="option-group">
<label>选项A</label>
<input
type="text"
v-model="editingQuestion.optionA"
placeholder="请输入选项A" style="width: 280px; height: 40px;"
/>
<input type="text" v-model="editingQuestion.optionA" placeholder="请输入选项A" style="width: 280px; height: 40px;"/>
</div>
<div class="option-group">
<label>选项B</label>
@ -241,13 +149,11 @@
</div>
</div>
<!-- 删除确认对话框 -->
<div v-if="showDeleteModal" class="modal-overlay" @click.self="closeDeleteModal">
<div class="delete-modal-content" @click.stop>
<div class="modal-header">
<h3>您确定要删除吗</h3>
<!-- <button class="close-btn" @click="closeDeleteModal">×</button> -->
<button class="close-btn" @click="closeDeleteModal">×</button>
</div>
<div class="modal-footer">
<button class="btn-red" @click="confirmDelete">确定</button>
@ -268,19 +174,16 @@ export default {
name: 'QuestionTable',
data() {
return {
sortField: '', //
sortDirection: 'asc', // (/)
items: [], //
sortedItems: [], //
showViewModal: false, //
currentQuestion: {}, //
page: 1, //
pageSize: 20, //
total: 0 , //
showEditModal: false, //
editingQuestion: {}, //
showDeleteModal: false, //
deleteId: null, // ID
total: 0, //
showEditModal: false, //
editingQuestion: {}, //
showDeleteModal: false, //
deleteId: null, // ID
}
},
@ -296,30 +199,11 @@ export default {
await this.fetchQuestions()
},
watch: {
//
sortField: {
handler() {
this.updateSortedItems()
},
immediate: true
},
//
sortDirection: {
handler() {
this.updateSortedItems()
},
immediate: true
}
},
methods: {
//
// setData
setData(data) {
this.items = data.list || data;
this.total = data.total || (data.list ? data.list.length : data.length);
this.updateSortedItems();
},
@ -338,56 +222,13 @@ export default {
if (response.data.code === 200) {
this.items = response.data.data.list
this.total = response.data.data.total || 0
this.updateSortedItems()
}
} catch (error) {
console.error('获取题目数据失败:', error)
}
},
//
updateSortedItems() {
// ID
if (!this.sortField) {
this.sortedItems = [...this.items].sort((a, b) => a.id - b.id)
return
}
//
const sorted = [...this.items].sort((a, b) => {
const aValue = a[this.sortField]
const bValue = b[this.sortField]
//
if (typeof aValue === 'number' && typeof bValue === 'number') {
return this.sortDirection === 'asc' ? aValue - bValue : bValue - aValue
} else {
//
const strA = String(aValue).toLowerCase()
const strB = String(bValue).toLowerCase()
return this.sortDirection === 'asc'
? strA.localeCompare(strB)
: strB.localeCompare(strA)
}
})
this.sortedItems = sorted
},
//
sort(field) {
if (this.sortField === field) {
//
this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc'
} else {
//
this.sortField = field
this.sortDirection = 'asc'
}
},
//
// changePage
changePage(newPage) {
if (newPage >= 1 && newPage <= this.totalPages) {
this.page = newPage;
@ -397,7 +238,6 @@ export default {
},
//
// jumpToPage
jumpToPage(event) {
const targetPage = parseInt(event.target.value);
if (targetPage >= 1 && targetPage <= this.totalPages) {
@ -410,7 +250,7 @@ export default {
}
},
//
//
async viewQuestion(item) {
// 1.
const row = document.querySelector(`[data-id="${item.id}"]`);
@ -467,7 +307,7 @@ export default {
this.showViewModal = false;
},
//
//
editQuestion(item) {
//
this.editingQuestion = {
@ -512,19 +352,12 @@ export default {
this.editingQuestion.recommendedCourse === '价格破译' ? 2 : 3);
//
// const response = await axios.post('/admin/questions/update', params, {
// headers: {
// 'Content-Type': 'application/x-www-form-urlencoded'
// }
// });
console.log(params);
const response = await axios.post('http://192.168.40.41:8000/admin/questions/update',params,
{
headers: {
'Content-Type': 'application/json'
}
});
console.log(response.data);
if (response.data.code === 200) {
this.closeEditModal();
@ -546,7 +379,7 @@ export default {
this.editingQuestion = {};
},
//
//
async deleteQuestion(item) {
this.deleteId = item.id;
this.showDeleteModal = true;
@ -639,24 +472,6 @@ th {
}
}
/* sort-header 样式 */
.sort-header {
display: flex;
align-items: center;
gap: 6px;
}
/* 排序图标样式 */
.sort-icon svg {
width: 12px;
height: 12px;
fill: none;
stroke: #e74c3c;
stroke-width: 2;
transition: transform 0.2s;
}
/* 表格容器样式 */
.table-container {
width: 100%;
@ -684,30 +499,6 @@ th {
background-color: #f2f2f2;
font-weight: normal;
color: #333;
cursor: pointer; /* 添加鼠标指针 */
user-select: none; /* 防止文字选中 */
}
/* 可排序列样式 */
.sortable {
display: flex;
align-items: center;
gap: 6px;
}
/* 排序图标样式 */
.sortable svg {
width: 12px;
height: 12px;
fill: none;
stroke: #e74c3c;
stroke-width: 2;
transition: transform 0.2s;
}
/* 悬停效果 */
th:hover {
background-color: #e0e0e0;
}
/* 表格行悬停效果 */
@ -745,7 +536,6 @@ tr:hover {
overflow-y: auto;
}
/* 删除确认对话框样式 */
.delete-modal-content {
background-color: white;
@ -793,18 +583,16 @@ tr:hover {
gap: 16px;
}
.modal-content {
background-color: white;
border-radius: 8px;
width: 600px; /* 从500px改为620px */
height: 760px; /* 增加高度 */
width: 600px;
height: 760px;
max-width: 90%;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.modal-header {
padding: 20px;
border-bottom: 1px solid #eee;
@ -874,7 +662,6 @@ tr:hover {
font-weight: bold;
}
.modal-footer {
padding: 20px;
border-top: 1px solid #eee;
@ -901,7 +688,7 @@ tr:hover {
display: flex;
align-items: center;
gap: 10px;
margin-right: 20px; /* 明确设置右侧间距 */
margin-right: 20px;
}
.btn-pagination {
@ -937,4 +724,4 @@ tr:hover {
font-size: 14px;
color: #666;
}
</style>
</style>

31
src/components/UserStatistics/UserStatisticsSearch.vue

@ -7,6 +7,7 @@
<select v-model="filters.type">
<option value="">全部</option>
<option value="股票知识">股票知识</option>
<option value="企业文化">企业文化</option>
</select>
</div>
@ -39,7 +40,7 @@
<!-- 身份 -->
<div class="search-item">
<label>身份</label>
<select v-model="filters.role">
<select v-model="filters.user_identity">
<option value="">全部</option>
<option value="非网">非网</option>
<option value="半年">半年</option>
@ -67,34 +68,14 @@ export default {
endDate: '',
userName: '',
jingwangId: '',
role: '',
questionType: ''
user_identity: ''
}
}
},
methods: {
async searchUserStatistics() {
searchUserStatistics() {
//
try{
const params = new URLSearchParams();
const questionType = this.filters.questionType || '';
if(questionType){
console.log(questionType);
params.append('questionType', questionType);
}
const role = {
'非网':1,
'半年':2,
'终身':3
}
if(this.filters.role){
console.log(role[this.filters.role]);
params.append('role', role[this.filters.role]);
}
}catch (error) {
console.error('搜索用户统计失败:', error);
alert('搜索失败!');
}
this.$emit('search', { ...this.filters });
},
async exportToExcel() {
try{
@ -210,4 +191,4 @@ export default {
/* 防止文字换行 */
white-space: nowrap;
}
</style>
</style>

75
src/components/UserStatistics/UserStatisticsTable.vue

@ -14,20 +14,21 @@
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="user in users" :key="user.id">
<td>{{ user.id }}</td>
<td>{{ user.userName }}</td>
<tbody>
<tr v-for="(user, index) in users" :key="user.id">
<td>{{ (page - 1) * pageSize + index + 1 }}</td>
<td>{{ user.user_name }}</td>
<td>{{ user.user_identity }}</td>
<td>{{ user.jwcode }}</td>
<td>{{ user.questionTypeName }}</td>
<td>股票知识</td>
<td>{{ user.score }}</td>
<td>{{ user.createdAt }}</td>
<td>
<button class="btn-red small" @click="viewUser(user)">查看</button>
</td>
</tr>
</tbody>
</tbody>
</table>
<!-- 分页控件 -->
@ -197,8 +198,7 @@ export default {
} else {
throw new Error(response.message || '获取错题失败');
}
}
,
},
//
setRecommendationText() {
@ -225,24 +225,45 @@ export default {
//
async fetchUserStatistics(page = 1, filters = {}) {
try {
const params = {
page: page,
page_size: this.pageSize,
...filters
//
const params = new URLSearchParams();
params.append('page', page);
params.append('page_size', this.pageSize);
//
if (filters.type) {
params.append('question_type', filters.type);
}
//
if (filters.startDate) {
params.append('start_time', filters.startDate);
}
if (filters.endDate) {
params.append('end_time', filters.endDate);
}
//
if (filters.userName) {
params.append('user_name', filters.userName);
}
//
if (filters.jingwangId) {
params.append('jwcode', filters.jingwangId);
}
//
if (filters.user_identity) {
params.append('user_identity', filters.user_identity);
console.log(filters.user_identity);
}
const response = await getUserStatistics(params)
console.log(response);
if (response.code === 200) {
const formattedData = response.data.list.map(item => ({
id: item.id,
userName: item.user_name,
user_identity: item.user_identity,
jwcode: item.jwcode,
questionTypeName: item.question_type_name || '股票知识',
score: item.score,
createdAt: item.createdAt
}))
const formattedData = response.data.list
this.page = page;
this.total = response.data.total || response.data.list.length;
@ -254,9 +275,19 @@ export default {
});
} else {
console.error('接口返回错误:', response.message)
//
this.$emit('data-loaded', {
list: [],
total: 0
});
}
} catch (error) {
console.error('获取用户数据失败:', error)
//
this.$emit('data-loaded', {
list: [],
total: 0
});
}
},
@ -503,4 +534,4 @@ tr:hover {
.btn-red:hover {
background-color: #c82333;
}
</style>
</style>

22
src/components/WrongQuestion/WrongQuestionSearch.vue

@ -4,17 +4,17 @@
<!-- 题目类型筛选项 -->
<div class="search-item">
<label>题目类型</label>
<select v-model="filters.type">
<select v-model="filters.questionType">
<option value="">全部</option>
<option value="1">股票知识</option>
<option value="2">企业文化</option>
<option>股票知识</option>
<option>企业文化</option>
</select>
</div>
<!-- 题干关键词搜索项 -->
<div class="search-item">
<label>题干查找</label>
<input type="text" v-model="filters.questionText" placeholder="请输入题干关键词" />
<input type="text" v-model="filters.keyword" placeholder="请输入题干关键词" />
</div>
<!-- 推荐课程筛选项 -->
@ -22,9 +22,9 @@
<label>推荐课程</label>
<select v-model="filters.course">
<option value="">全部</option>
<option value="1">量能擒牛</option>
<option value="2">价格破译</option>
<option value="3">量价时空综合</option>
<option>量能擒牛</option>
<option>价格破译</option>
<option>量价时空综合</option>
</select>
</div>
@ -42,9 +42,9 @@ export default {
data() {
return {
filters: {
type: '', // ID
questionText: '', //
course: '' // ID
questionType: '', //
keyword: '', //
course: '' //
},
currentPage: 1, //
total: 0 //
@ -75,4 +75,4 @@ export default {
}
}
}
</script>
</script>

168
src/components/WrongQuestion/WrongQuestionTable.vue

@ -3,61 +3,29 @@
<div class="table-container">
<table>
<thead>
<tr>
<th @click="sort('id')" class="sortable">
<div class="sort-header">
ID
<span v-if="sortField === 'id'" class="sort-icon">
<svg :style="{ transform: sortDirection === 'desc' ? 'rotate(180deg)' : 'rotate(0deg)' }"
width="12" height="12" viewBox="0 0 24 24" fill="none">
<path d="M7 10L12 15L17 10" stroke="#e74c3c" stroke-width="2" />
<path d="M12 15V3" stroke="#e74c3c" stroke-width="2" />
</svg>
</span>
</div>
</th>
<th>题干</th>
<th>题目类型</th>
<th @click="sort('errorCount')" class="sortable">
<div class="sort-header">
出错次数
<span v-if="sortField === 'errorCount'" class="sort-icon">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7 10L12 15L17 10" stroke="#e74c3c" stroke-width="2" />
<path d="M12 15V3" stroke="#e74c3c" stroke-width="2" />
</svg>
</span>
</div>
</th>
<th @click="sort('errorRate')" class="sortable">
<div class="sort-header">
出错率
<span v-if="sortField === 'errorRate'" class="sort-icon">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7 10L12 15L17 10" stroke="#e74c3c" stroke-width="2" />
<path d="M12 15V3" stroke="#e74c3c" stroke-width="2" />
</svg>
</span>
</div>
</th>
<th>推荐课程</th>
<th>操作</th>
</tr>
<tr>
<th>ID</th>
<th>题干</th>
<th>题目类型</th>
<th>出错次数</th>
<th>出错率</th>
<th>推荐课程</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="item in sortedWrongQuestions" :key="item.id">
<td>{{ item.id }}</td>
<td>{{ item.stem }}</td>
<td>{{ item.questionTypeName }}</td>
<td>{{ item.errorCount }}</td>
<td>{{ item.errorRate }}</td>
<td>{{ item.CrName }}</td>
<td class="operation-cell">
<button class="btn-red small" @click="viewUser(item)">出错用户</button>
<button class="btn-red small" @click="viewQuestion(item)">查看题目</button>
</td>
</tr>
<tr v-for="(item,index) in wrongQuestions" :key="item.id">
<td>{{ (page- 1) * pageSize + index + 1 }}</td>
<td>{{ item.stem }}</td>
<td>{{ item.questionTypeName }}</td>
<td>{{ item.errorCount }}</td>
<td>{{ item.errorRate }}</td>
<td>{{ item.CrName }}</td>
<td class="operation-cell">
<button class="btn-red small" @click="viewUser(item)">出错用户</button>
<button class="btn-red small" @click="viewQuestion(item)">查看题目</button>
</td>
</tr>
</tbody>
</table>
@ -163,7 +131,6 @@
</template>
<script>
import { getQuestions } from '@/api/question.js';
export default {
@ -174,8 +141,6 @@ export default {
total: 0,
page: 1,
pageSize: 20,
sortField: '',
sortDirection: 'asc',
showUserModal: false,
errorUsers: [],
showViewModal: false,
@ -184,41 +149,15 @@ export default {
}
},
computed: {
sortedWrongQuestions() {
if (!this.sortField) {
return [...this.wrongQuestions].sort((a, b) => a.id - b.id)
}
return [...this.wrongQuestions].sort((a, b) => {
const aValue = a[this.sortField]
const bValue = b[this.sortField]
if (this.sortField === 'errorRate') {
const numA = parseFloat(String(aValue).replace('%', '')) || 0
const numB = parseFloat(String(bValue).replace('%', '')) || 0
return this.sortDirection === 'asc' ? numA - numB : numB - numA
}
if (typeof aValue === 'number' && typeof bValue === 'number') {
return this.sortDirection === 'asc' ? aValue - bValue : bValue - aValue
} else {
const strA = String(aValue).toLowerCase()
const strB = String(bValue).toLowerCase()
return this.sortDirection === 'asc'
? strA.localeCompare(strB)
: strB.localeCompare(strA)
}
})
},
totalPages() {
return Math.ceil(this.total / this.pageSize)
}
},
methods: {
setData(data) {
this.wrongQuestions = data.list || [];
this.total = data.total || 0;
this.page = data.page || 1;
setFilters(filters) {
this.currentFilters = filters;
this.page = 1;
this.fetchWrongQuestions();
},
async fetchWrongQuestions() {
@ -249,23 +188,10 @@ export default {
params.append('stem', this.currentFilters.keyword);
}
//
if (this.sortField) {
params.append('sort_field', this.sortField);
params.append('sort_direction', this.sortDirection);
}
const response = await getQuestions(params);
if (response.data.code === 200) {
this.wrongQuestions = response.data.data.list.map(item => ({
id: item.id,
stem: item.stem,
questionTypeName: item.questionTypeName,
errorCount: item.errorCount,
errorRate: item.errorRate, // %
CrName: item.CrName
}))
this.wrongQuestions = response.data.data.list
this.total = response.data.data.total || 0;
} else {
console.error('接口返回错误:', response.data.msg)
@ -346,16 +272,6 @@ export default {
this.showViewModal = false
},
sort(field) {
if (this.sortField === field) {
this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc'
} else {
this.sortField = field
this.sortDirection = 'asc'
}
this.fetchWrongQuestions();
},
changePage(newPage) {
if (newPage >= 1 && newPage <= this.totalPages) {
this.page = newPage;
@ -397,8 +313,7 @@ table {
background-color: white;
}
th,
td {
th,td {
padding: 12px;
text-align: left;
border-bottom: 1px solid #ddd;
@ -408,8 +323,6 @@ th {
background-color: #f2f2f2;
font-weight: normal;
color: #333;
cursor: pointer;
user-select: none;
display: table-cell !important;
vertical-align: middle !important;
}
@ -423,31 +336,6 @@ tr:hover {
gap: 16px;
}
.sort-header {
display: flex;
align-items: center;
gap: 6px;
}
.sortable {
display: flex;
align-items: center;
gap: 6px;
}
.sort-icon svg {
width: 12px;
height: 12px;
fill: none;
stroke: #e74c3c;
stroke-width: 2;
transition: transform 0.2s;
}
th:hover {
background-color: #e0e0e0;
}
/* 分页样式 */
.pagination-container {
display: flex;
@ -638,4 +526,4 @@ th:hover {
border-radius: 4px;
cursor: pointer;
}
</style>
</style>

8
src/views/UserStatistics.vue

@ -32,7 +32,7 @@ export default {
endDate: '',
userName: '',
jingwangId: '',
role: ''
user_identity: ''
},
page: 1,
pageSize: 10,
@ -42,8 +42,8 @@ export default {
methods: {
//
handleSearch(filters) {
this.filters = filters
this.page = 1
this.filters = { ...filters }; //
this.page = 1;
this.$refs.userStatisticsTable.fetchUserStatistics(1, filters);
},
//
@ -69,4 +69,4 @@ export default {
.user-statistics {
padding: 20px;
}
</style>
</style>
Loading…
Cancel
Save