Compare commits

...

2 Commits

Author SHA1 Message Date
44f817eced 【优化】优化用户管理界面 2025-11-03 11:43:37 +08:00
0f2cc6a33c 【新增】完善固件管理 2025-11-03 11:43:11 +08:00
7 changed files with 392 additions and 152 deletions

View File

@@ -0,0 +1,10 @@
package com.corewing.app.dto.biz.firmware;
import lombok.Data;
import java.util.List;
@Data
public class FirmwareBatchDeleteRequest {
private List<Long> ids;
}

View File

@@ -61,4 +61,20 @@ public class Firmware implements Serializable {
*/ */
@TableField(fill = FieldFill.INSERT_UPDATE) @TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime; private LocalDateTime updateTime;
@TableField(exist = false)
private String firmwareTypeName;
public String getFirmwareTypeName() {
switch (firmwareType) {
case 1:
return "调参固件";
case 2:
return "AP固件";
case 3:
return "INAV固件";
default:
return "";
}
}
} }

View File

@@ -0,0 +1,103 @@
package com.corewing.app.modules.admin.biz;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.corewing.app.common.Result;
import com.corewing.app.dto.biz.firmware.FirmwareBatchDeleteRequest;
import com.corewing.app.entity.Firmware;
import com.corewing.app.service.FirmwareService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 固件管理
*/
@Controller
@RequestMapping("/biz/firmware")
public class BizFirmwareController {
@Resource
private FirmwareService firmwareService;
/**
* 固件管理首页
* @return
*/
@GetMapping("/index")
public String index() {
return "admin/biz/firmware/index";
}
/**
* 分页查询
* @param firmware
* @return
*/
@GetMapping("/page")
@ResponseBody
public Result<Page<Firmware>> page(Firmware firmware) {
return Result.success(firmwareService.page(firmware));
}
/**
* 保存
* @param firmware
* @return
*/
@PostMapping("/save")
@ResponseBody
public Result<String> save(@RequestBody Firmware firmware) {
return Result.isBool(firmwareService.save(firmware));
}
/**
* 更新
* @param firmware
* @return
*/
@PostMapping("/update")
@ResponseBody
public Result<String> update(@RequestBody Firmware firmware) {
return Result.isBool(firmwareService.updateById(firmware));
}
/**
* 删除
* @param id
* @return
*/
@DeleteMapping("/delete")
@ResponseBody
public Result<Firmware> delete(String id) {
return Result.isBool(firmwareService.removeById(id));
}
/**
* 批量删除
* @param firmwareBatchDeleteRequest
* @return
*/
@PostMapping("/batchDelete")
@ResponseBody
public Result<Firmware> batchDelete(@RequestBody FirmwareBatchDeleteRequest firmwareBatchDeleteRequest) {
return Result.isBool(firmwareService.removeBatchByIds(firmwareBatchDeleteRequest.getIds()));
}
/**
* 上传固件
* @param file
* @return
*/
@PostMapping("/uploadFile")
@ResponseBody
public Result<String> uploadFile(MultipartFile file) {
return Result.success();
}
}

View File

@@ -1,6 +1,8 @@
package com.corewing.app.service; package com.corewing.app.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.corewing.app.common.Result;
import com.corewing.app.entity.Firmware; import com.corewing.app.entity.Firmware;
/** /**
@@ -8,6 +10,13 @@ import com.corewing.app.entity.Firmware;
*/ */
public interface FirmwareService extends IService<Firmware> { public interface FirmwareService extends IService<Firmware> {
/**
* 查询固件分页数据
* @param firmware
* @return
*/
Page<Firmware> page(Firmware firmware);
/** /**
* 根据固件名称查询固件 * 根据固件名称查询固件
* *

View File

@@ -1,11 +1,14 @@
package com.corewing.app.service.impl; package com.corewing.app.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.corewing.app.common.page.PageContext;
import com.corewing.app.entity.Firmware; import com.corewing.app.entity.Firmware;
import com.corewing.app.mapper.FirmwareMapper; import com.corewing.app.mapper.FirmwareMapper;
import com.corewing.app.service.FirmwareService; import com.corewing.app.service.FirmwareService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
/** /**
* 固件 Service 实现类 * 固件 Service 实现类
@@ -13,10 +16,21 @@ import org.springframework.stereotype.Service;
@Service @Service
public class FirmwareServiceImpl extends ServiceImpl<FirmwareMapper, Firmware> implements FirmwareService { public class FirmwareServiceImpl extends ServiceImpl<FirmwareMapper, Firmware> implements FirmwareService {
@Override
public Page<Firmware> page(Firmware firmware) {
Page<Firmware> page = PageContext.getPage(Firmware.class);
LambdaQueryWrapper<Firmware> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.like(StringUtils.hasText(firmware.getFirmwareName()), Firmware::getFirmwareName, firmware.getFirmwareName());
queryWrapper.eq(firmware.getFirmwareType() != null, Firmware::getFirmwareType, firmware.getFirmwareType());
return page(page, queryWrapper);
}
@Override @Override
public Firmware getByFirmwareName(String firmwareName) { public Firmware getByFirmwareName(String firmwareName) {
LambdaQueryWrapper<Firmware> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<Firmware> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Firmware::getFirmwareName, firmwareName); wrapper.eq(Firmware::getFirmwareName, firmwareName);
return this.getOne(wrapper); return this.getOne(wrapper);
} }
} }

View File

@@ -3,9 +3,9 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用户管理系统</title> <title>固件管理</title>
<!-- 外部引入库文件 --> <!-- 外部引入库文件 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css" rel="stylesheet">
<!-- 外部引入自定义样式 --> <!-- 外部引入自定义样式 -->
<link rel="stylesheet" href="/assets/css/table.css"> <link rel="stylesheet" href="/assets/css/table.css">
@@ -13,46 +13,42 @@
<body id="app"> <body id="app">
<div class="main-container"> <div class="main-container">
<div class="table-container"> <div class="table-container">
<!-- 页面标题 --> <h4 class="mb-3">固件管理</h4>
<h3 class="mb-4">固件管理</h3>
<!-- 多参数搜索栏 -->
<div class="search-bar"> <div class="search-bar">
<!-- 搜索参数1关键词 -->
<div class="search-item"> <div class="search-item">
<div class="input-group"> <div class="input-group">
<span class="input-group-text"> <span class="input-group-text">
用户 固件
</span> </span>
<input <input
v-model="searchParams.keyword" v-model="searchParams.firmwareName"
type="text" type="text"
class="form-control" class="form-control"
placeholder="关键词搜索(名称/ID" placeholder="请输入固件名称"
@keyup.enter="fetchData()" @keyup.enter="fetchData()"
> >
</div> </div>
</div> </div>
<!-- 搜索参数2状态筛选 -->
<div class="search-item"> <div class="search-item">
<div class="input-group"> <div class="input-group">
<span class="input-group-text"> <span class="input-group-text">
状态 类型
</span> </span>
<select <select
v-model="searchParams.status" v-model="searchParams.firmwareType"
class="form-select" class="form-select"
@change="fetchData()" @change="fetchData()"
> >
<option value="">全部状态</option> <option value="">全部状态</option>
<option value="1">启用</option> <option value="1">调参固件</option>
<option value="0">禁用</option> <option value="2">AP固件</option>
<option value="3">INAV固件</option>
</select> </select>
</div> </div>
</div> </div>
<!-- 搜索和重置按钮 -->
<div class="d-flex gap-2"> <div class="d-flex gap-2">
<button class="btn btn-primary" @click="fetchData()"> <button class="btn btn-primary" @click="fetchData()">
<i class="bi bi-search me-1"></i> 搜索 <i class="bi bi-search me-1"></i> 搜索
@@ -63,16 +59,14 @@
</div> </div>
</div> </div>
<!-- 新增按钮 --> <div class="mb-2">
<div class="mb-3">
<button class="btn btn-info" @click="openAddModal()"> <button class="btn btn-info" @click="openAddModal()">
<i class="bi bi-plus-circle me-1"></i> 新增 <i class="bi bi-plus-circle me-1"></i> 新增
</button> </button>
</div> </div>
<!-- 表格 -->
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-striped table-hover table-bordered"> <table class="table table-sm table-striped table-hover table-bordered ">
<thead class="table-light"> <thead class="table-light">
<tr> <tr>
<!-- 全选复选框 --> <!-- 全选复选框 -->
@@ -84,11 +78,10 @@
@change="toggleSelectAll()" @change="toggleSelectAll()"
> >
</th> </th>
<th>ID</th> <th>固件名</th>
<th>名称</th> <th>大小(字节)</th>
<th>状态</th> <th>描述</th>
<th>用户类型</th> <th>类型</th>
<th>所属部门</th>
<th>创建时间</th> <th>创建时间</th>
<th style="width: 120px;">操作</th> <th style="width: 120px;">操作</th>
</tr> </tr>
@@ -118,7 +111,8 @@
</tr> </tr>
<!-- 数据列表 --> <!-- 数据列表 -->
<tr v-else v-for="(item, index) in tableData" :key="item.id" :class="{ selected: selectedIds.includes(item.id) }"> <tr v-else v-for="(item, index) in tableData" :key="item.id"
:class="{ selected: selectedIds.includes(item.id) }">
<td> <td>
<input <input
type="checkbox" type="checkbox"
@@ -128,26 +122,16 @@
@change="toggleSelectItem(item.id)" @change="toggleSelectItem(item.id)"
> >
</td> </td>
<td>{{ item.id }}</td> <td>{{ item.firmwareName }}</td>
<td>{{ item.name }}</td> <td>{{ item.firmwareSize }}</td>
<td> <td>{{ item.firmwareDescription }}</td>
<span class="badge" :class="item.status === 1 ? 'bg-success' : 'bg-danger'"> <td>{{ item.firmwareTypeName }}</td>
{{ item.status === 1 ? '启用' : '禁用' }}
</span>
</td>
<td>
<span class="badge bg-primary">
{{ item.userType === 'admin' ? '管理员' : item.userType === 'editor' ? '编辑' : '查看者' }}
</span>
</td>
<td>
<span class="badge bg-secondary">
{{ item.deptId === '1' ? '技术部' : item.deptId === '2' ? '运营部' : item.deptId === '3' ? '市场部' : '人事部' }}
</span>
</td>
<td>{{ formatTime(item.createTime) }}</td> <td>{{ formatTime(item.createTime) }}</td>
<td> <td>
<div class="d-flex gap-1"> <div class="d-flex gap-1">
<button class="btn btn-sm btn-primary" @click="openUploadModal(item)" title="上传固件">
<i class="bi bi-cloud-upload-fill"></i>
</button>
<button class="btn btn-sm btn-primary" @click="openEditModal(item)"> <button class="btn btn-sm btn-primary" @click="openEditModal(item)">
<i class="bi bi-pencil"></i> <i class="bi bi-pencil"></i>
</button> </button>
@@ -161,12 +145,9 @@
</table> </table>
</div> </div>
<!-- 批量操作(表格下方左侧) -->
<div class="batch-actions mt-3"> <div class="batch-actions mt-3">
<div class="d-flex align-items-center gap-2"> <div class="d-flex align-items-center gap-2">
<span class="text-muted">已选中 {{ selectedIds.length }} 条数据</span> <span class="text-muted">已选中 {{ selectedIds.length }} 条数据</span>
<!-- 使用select标签实现批量操作选择 -->
<select <select
class="form-select" class="form-select"
v-model="batchAction" v-model="batchAction"
@@ -176,8 +157,6 @@
> >
<option value="">-- 批量操作 --</option> <option value="">-- 批量操作 --</option>
<option value="delete">批量删除</option> <option value="delete">批量删除</option>
<option value="enable">批量启用</option>
<option value="disable">批量禁用</option>
</select> </select>
<button <button
@@ -190,7 +169,6 @@
</div> </div>
</div> </div>
<!-- 分页控件 -->
<div class="d-flex justify-content-between align-items-center mt-3"> <div class="d-flex justify-content-between align-items-center mt-3">
<div class="page-info"> <div class="page-info">
共 {{ total }} 条数据,当前第 {{ pageNum }}/{{ totalPages }} 页 共 {{ total }} 条数据,当前第 {{ pageNum }}/{{ totalPages }} 页
@@ -203,7 +181,8 @@
<li class="page-item" :class="{ disabled: pageNum === 1 }"> <li class="page-item" :class="{ disabled: pageNum === 1 }">
<a class="page-link" href="#" @click.prevent="changePage(pageNum - 1)">上一页</a> <a class="page-link" href="#" @click.prevent="changePage(pageNum - 1)">上一页</a>
</li> </li>
<li class="page-item active" v-for="page in pageList" :key="page"> <li class="page-item" :class="page === pageNum ? 'active' : ''" v-for="page in pageList"
:key="page">
<a class="page-link" href="#" @click.prevent="changePage(page)">{{ page }}</a> <a class="page-link" href="#" @click.prevent="changePage(page)">{{ page }}</a>
</li> </li>
<li class="page-item" :class="{ disabled: pageNum === totalPages }"> <li class="page-item" :class="{ disabled: pageNum === totalPages }">
@@ -216,6 +195,94 @@
</nav> </nav>
</div> </div>
</div> </div>
</div>
<!-- 上传文件 -->
<div class="modal fade" id="uploadFileModal" tabindex="-1" aria-labelledby="uploadFileModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="uploadFileModalLabel">上传固件</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form>
<div class="mb-3 row">
<label class="col-sm-3 col-form-label">选择固件</label>
<div class="col-sm-9">
<input
type="file"
class="form-control"
id="firmwareFile"
name="file"
accept=".bin"
>
<div class="form-text text-muted mt-1">支持 .bin 格式,单个文件不超过 100MB</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" @click.prevent="uploadFile">上传</button>
</div>
</div>
</div>
</div>
<!-- 新增 or 编辑 -->
<div class="modal fade" id="addOrEditModel" tabindex="-1" aria-labelledby="addOrEditModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="addOrEditModalLabel">{{ addOrEditTitle }}</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form>
<div class="mb-3 row">
<label class="col-sm-3 col-form-label">固件名称</label>
<div class="col-sm-9">
<input type="text" class="form-control" v-model="addOrEditDto.firmwareName"
placeholder="请输入固件名称">
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-3 col-form-label">固件描述</label>
<div class="col-sm-9">
<input type="text" class="form-control" v-model="addOrEditDto.firmwareDescription"
placeholder="请输入固件描述">
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-3 col-form-label">固件类型</label>
<div class="col-sm-9">
<select class="form-control" v-model="addOrEditDto.firmwareType">
<option value=1>调参固件</option>
<option value=2>AP固件</option>
<option value=3>INAV固件</option>
</select>
</div>
</div>
<div class="mb-3 row">
<label class="col-sm-3 col-form-label">固件地址</label>
<div class="col-sm-9">
<input type="text" class="form-control" v-model="addOrEditDto.downloadUrl"
placeholder="请输入固件地址">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary" @click.prevent="saveEntity">保存</button>
</div>
</div>
</div>
</div> </div>
<!-- 外部引入库文件 --> <!-- 外部引入库文件 -->
@@ -223,7 +290,9 @@
<script src="https://cdn.jsdelivr.net/npm/axios@1.4.0/dist/axios.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/axios@1.4.0/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<!-- 外部引入模拟请求文件 --> <!-- 外部引入模拟请求文件 -->
<script src="js/axiosRequest.js"></script> <script src="/assets/js/axiosRequest.js"></script>
<script src="/assets/js/message.js"></script>
<script src="/assets/js/confirmModal.js"></script>
<!-- 页面核心逻辑 --> <!-- 页面核心逻辑 -->
<script> <script>
@@ -234,14 +303,9 @@
return { return {
tableData: [], // 表格数据源 tableData: [], // 表格数据源
loading: false, // 加载状态 loading: false, // 加载状态
// 多搜索参数绑定(与搜索栏对应)
searchParams: { searchParams: {
keyword: '', firmwareName: '',
status: '', firmwareType: '',
createTimeStart: '',
createTimeEnd: '',
userType: '',
deptId: ''
}, },
// 分页参数 // 分页参数
pageNum: 1, // 当前页码 pageNum: 1, // 当前页码
@@ -252,8 +316,22 @@
selectedIds: [], // 选中的ID集合 selectedIds: [], // 选中的ID集合
selectAll: false, // 全选状态 selectAll: false, // 全选状态
batchAction: '', // 批量操作选择 batchAction: '', // 批量操作选择
// 分页显示范围最多显示5个页码 pageRange: 5,
pageRange: 5 modalInstances: {},
resetPasswordDto: {
userId: null,
nickName: null,
username: null,
password: null,
},
addOrEditTitle: '',
addOrEditDto: {
id: null,
firmwareName: null,
firmwareDescription: null,
firmwareType: 1,
downloadUrl: ''
}
} }
}, },
computed: { computed: {
@@ -289,7 +367,6 @@
} }
}, },
methods: { methods: {
// 格式化时间(毫秒转字符串)
formatTime(time) { formatTime(time) {
if (!time) return '-'; if (!time) return '-';
const date = new Date(time); const date = new Date(time);
@@ -303,23 +380,20 @@
}); });
}, },
// 获取表格数据(核心方法)
async fetchData() { async fetchData() {
this.loading = true; this.loading = true;
try { try {
// 调用模拟接口获取数据 const response = await request.get('/biz/firmware/page', {
const response = await request.get('/sys/data/list', { ...this.searchParams,
params: { current: this.pageNum,
...this.searchParams, // 传递所有搜索参数 size: this.pageSize
pageNum: this.pageNum,
pageSize: this.pageSize
}
}); });
console.log(response)
if (response.code === 200) { if (response.code === 200) {
this.tableData = response.data.list; // 列表数据 this.tableData = response.data.records; // 列表数据
this.total = response.data.total; // 总条数 this.total = response.data.total; // 总条数
this.totalPages = Math.ceil(this.total / this.pageSize); // 总页数 this.totalPages = response.data.pages; // 总页数
} }
} catch (error) { } catch (error) {
console.error('获取数据失败:', error); console.error('获取数据失败:', error);
@@ -328,47 +402,39 @@
this.totalPages = 0; this.totalPages = 0;
} finally { } finally {
this.loading = false; this.loading = false;
this.clearSelected(); // 每次加载数据清空选中状态 this.clearSelected();
} }
}, },
// 切换页码 // 切换页码
changePage(page) { changePage(page) {
// 边界判断
if (page < 1 || page > this.totalPages || page === this.pageNum) return; if (page < 1 || page > this.totalPages || page === this.pageNum) return;
this.pageNum = page; this.pageNum = page;
this.fetchData(); // 切换页码后重新加载数据 this.fetchData();
}, },
// 重置搜索 // 重置搜索
resetSearch() { resetSearch() {
// 重置所有搜索参数
this.searchParams = { this.searchParams = {
keyword: '', firmwareName: '',
status: '', firmwareType: '',
createTimeStart: '',
createTimeEnd: '',
userType: '',
deptId: ''
}; };
this.pageNum = 1; // 重置到第一页 this.pageNum = 1;
this.fetchData(); this.fetchData();
}, },
// 全选/取消全选 // 全选/取消全选
toggleSelectAll() { toggleSelectAll() {
if (this.selectAll) { if (this.selectAll) {
// 全选收集所有数据的ID
this.selectedIds = this.tableData.map(item => item.id); this.selectedIds = this.tableData.map(item => item.id);
} else { } else {
// 取消全选清空选中ID
this.selectedIds = []; this.selectedIds = [];
} }
}, },
// 单个选中/取消选中 // 单个选中/取消选中
toggleSelectItem(id) { toggleSelectItem(id) {
// 当选中状态变化时,更新全选状态
this.selectAll = this.selectedIds.length === this.tableData.length && this.tableData.length > 0; this.selectAll = this.selectedIds.length === this.tableData.length && this.tableData.length > 0;
}, },
@@ -376,7 +442,7 @@
clearSelected() { clearSelected() {
this.selectedIds = []; this.selectedIds = [];
this.selectAll = false; this.selectAll = false;
this.batchAction = ''; // 重置批量操作选择 this.batchAction = '';
}, },
// 处理批量操作 // 处理批量操作
@@ -387,86 +453,119 @@
case 'delete': case 'delete':
this.handleBatchDelete(); this.handleBatchDelete();
break; break;
case 'enable':
this.handleBatchStatus(1);
break;
case 'disable':
this.handleBatchStatus(0);
break;
} }
// 执行操作后重置选择
this.batchAction = ''; this.batchAction = '';
}, },
// 批量删除 // 批量删除
async handleBatchDelete() { async handleBatchDelete() {
if (!confirm(`确定要删除选中的 ${this.selectedIds.length} 条数据吗?`)) return; showConfirmModal({
title: '删除确认',
try { content: `确定要删除选中的 ${this.selectedIds.length} 条数据吗?`,
const response = await request.post('/sys/data/batchDelete', { onConfirm: async () => {
ids: this.selectedIds try {
}); const response = await request.post('/biz/firmware/batchDelete', {ids: this.selectedIds});
if (response.code === 200) {
if (response.code === 200) { $message.success("删除成功");
alert('删除成功!'); this.fetchData();
this.fetchData(); // 重新加载数据 }
} catch (error) {
console.error('删除失败:', error);
$message.error('删除失败,请重试!');
}
} }
} catch (error) { });
console.error('批量删除失败:', error);
alert('删除失败,请重试!');
}
},
// 批量修改状态(启用/禁用)
async handleBatchStatus(status) {
try {
const response = await request.post('/sys/data/batchUpdateStatus', {
ids: this.selectedIds,
status: status
});
if (response.code === 200) {
alert(`已${status === 1 ? '启用' : '禁用'}选中数据!`);
this.fetchData(); // 重新加载数据
}
} catch (error) {
console.error('批量更新状态失败:', error);
alert('操作失败,请重试!');
}
}, },
// 单个删除 // 单个删除
async handleDelete(id) { async handleDelete(id) {
if (!confirm('确定要删除这条数据吗?')) return; showConfirmModal({
title: '删除确认',
try { content: '确定要删除这条数据吗?',
const response = await request.post('/sys/data/delete', {id}); onConfirm: async () => {
if (response.code === 200) { try {
alert('删除成功!'); const response = await request.delete('/biz/firmware/delete', {id});
this.fetchData(); // 重新加载数据 if (response.code === 200) {
$message.success("删除成功");
this.fetchData(); // 重新加载数据
}
} catch (error) {
console.error('删除失败:', error);
$message.error('删除失败,请重试!');
}
} }
} catch (error) { });
console.error('删除失败:', error);
alert('删除失败,请重试!');
}
}, },
// 打开文件上传模态框
openUploadModal(item) {
this.modalInstances['uploadFileModal'].show();
},
uploadFile() {
request.put("/biz/user/resetPasswordRequest", this.resetPasswordDto)
.then((res) => {
if (res.code === 200) {
$message.success('修改成功!', 500);
this.modalInstances['resetPwdModal'].hide();
} else {
alert('修改失败!');
}
this.resetPasswordDto = {};
});
},
// 打开新增模态框 // 打开新增模态框
openAddModal() { openAddModal() {
alert('打开新增模态框'); this.addOrEditTitle = '新增';
// 实际项目中添加模态框显示逻辑 this.modalInstances['addOrEditModel'].show();
}, },
// 打开编辑模态框 // 打开编辑模态框
openEditModal(item) { openEditModal(item) {
alert(`打开编辑模态框编辑ID: ${item.id}`); this.addOrEditTitle = '编辑';
// 实际项目中添加模态框显示和数据回显逻辑 this.addOrEditDto = item;
this.modalInstances['addOrEditModel'].show();
},
saveEntity() {
let url = (this.addOrEditDto === null || this.addOrEditDto.id === null) ? '/biz/firmware/save' : '/biz/firmware/update';
request.post(url, this.addOrEditDto)
.then((res) => {
if (res.code === 200) {
$message.success('保存成功!', 500);
this.fetchData();
this.modalInstances['addOrEditModel'].hide();
} else {
$message.error('保存失败!', 500);
}
this.clearForm();
}).catch(() => {
})
},
// 清空表单数据
clearForm() {
this.addOrEditDto = {
id: null,
firmwareName: null,
firmwareDescription: null,
firmwareType: 1,
downloadUrl: ''
};
} }
}, },
mounted() { mounted() {
// 页面加载完成后初始化数据
this.fetchData(); this.fetchData();
const modalIds = ['uploadFileModal', 'addOrEditModel'];
modalIds.forEach(id => {
const modalElement = document.getElementById(id);
if (modalElement) {
this.modalInstances[id] = new bootstrap.Modal(modalElement, {
backdrop: 'static',
keyboard: true
});
}
});
} }
}).mount('#app'); }).mount('#app');
</script> </script>

View File

@@ -13,12 +13,9 @@
<body id="app"> <body id="app">
<div class="main-container"> <div class="main-container">
<div class="table-container"> <div class="table-container">
<!-- 页面标题 -->
<h4 class="mb-3">用户管理</h4> <h4 class="mb-3">用户管理</h4>
<!-- 多参数搜索栏 -->
<div class="search-bar"> <div class="search-bar">
<!-- 搜索参数1关键词 -->
<div class="search-item"> <div class="search-item">
<div class="input-group"> <div class="input-group">
<span class="input-group-text"> <span class="input-group-text">
@@ -49,7 +46,6 @@
</div> </div>
</div> </div>
<!-- 搜索参数2状态筛选 -->
<div class="search-item"> <div class="search-item">
<div class="input-group"> <div class="input-group">
<span class="input-group-text"> <span class="input-group-text">
@@ -67,7 +63,6 @@
</div> </div>
</div> </div>
<!-- 搜索和重置按钮 -->
<div class="d-flex gap-2"> <div class="d-flex gap-2">
<button class="btn btn-primary" @click="fetchData()"> <button class="btn btn-primary" @click="fetchData()">
<i class="bi bi-search me-1"></i> 搜索 <i class="bi bi-search me-1"></i> 搜索
@@ -78,19 +73,16 @@
</div> </div>
</div> </div>
<!-- 新增按钮 -->
<div class="mb-2"> <div class="mb-2">
<button class="btn btn-info" @click="openAddModal()"> <button class="btn btn-info" @click="openAddModal()">
<i class="bi bi-plus-circle me-1"></i> 新增 <i class="bi bi-plus-circle me-1"></i> 新增
</button> </button>
</div> </div>
<!-- 表格 -->
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-sm table-striped table-hover table-bordered "> <table class="table table-sm table-striped table-hover table-bordered ">
<thead class="table-light"> <thead class="table-light">
<tr> <tr>
<!-- 全选复选框 -->
<th style="width: 50px;"> <th style="width: 50px;">
<input <input
type="checkbox" type="checkbox"
@@ -172,12 +164,10 @@
</table> </table>
</div> </div>
<!-- 批量操作(表格下方左侧) -->
<div class="batch-actions mt-3"> <div class="batch-actions mt-3">
<div class="d-flex align-items-center gap-2"> <div class="d-flex align-items-center gap-2">
<span class="text-muted">已选中 {{ selectedIds.length }} 条数据</span> <span class="text-muted">已选中 {{ selectedIds.length }} 条数据</span>
<!-- 使用select标签实现批量操作选择 -->
<select <select
class="form-select" class="form-select"
v-model="batchAction" v-model="batchAction"
@@ -201,7 +191,6 @@
</div> </div>
</div> </div>
<!-- 分页控件 -->
<div class="d-flex justify-content-between align-items-center mt-3"> <div class="d-flex justify-content-between align-items-center mt-3">
<div class="page-info"> <div class="page-info">
共 {{ total }} 条数据,当前第 {{ pageNum }}/{{ totalPages }} 页 共 {{ total }} 条数据,当前第 {{ pageNum }}/{{ totalPages }} 页
@@ -530,7 +519,7 @@
} }
} catch (error) { } catch (error) {
console.error('删除失败:', error); console.error('删除失败:', error);
alert('删除失败,请重试!'); $message.error('删除失败,请重试!');
} }
} }
}); });