Compare commits

...

2 Commits

Author SHA1 Message Date
632b37d5bd 【新增】完善后台首页面板 2025-11-21 18:39:51 +08:00
75ed266532 【新增】完善固件上传 2025-11-21 18:39:28 +08:00
8 changed files with 130 additions and 7 deletions

View File

@@ -43,7 +43,7 @@ dependencies {
annotationProcessor 'org.projectlombok:lombok' // Lombok 注解处理 annotationProcessor 'org.projectlombok:lombok' // Lombok 注解处理
testImplementation 'org.springframework.boot:spring-boot-starter-test' // 测试框架 testImplementation 'org.springframework.boot:spring-boot-starter-test' // 测试框架
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' // thymeleaf模版引擎 implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' // thymeleaf模版引擎
implementation 'com.aliyun.oss:aliyun-sdk-oss:3.17.4' // OSS SDK implementation 'com.aliyun.oss:aliyun-sdk-oss:3.18.1' // OSS SDK
} }
tasks.named('test') { tasks.named('test') {

View File

@@ -71,8 +71,8 @@ public class BizFirmwareController {
*/ */
@DeleteMapping("/delete") @DeleteMapping("/delete")
@ResponseBody @ResponseBody
public Result<Firmware> delete(String id) { public Result<Firmware> delete(Long id) {
return Result.isBool(firmwareService.removeById(id)); return Result.isBool(firmwareService.removeData(id));
} }
/** /**
@@ -97,4 +97,6 @@ public class BizFirmwareController {
return Result.isBool(firmwareService.uploadFile(file, id)); return Result.isBool(firmwareService.uploadFile(file, id));
} }
} }

View File

@@ -1,11 +1,26 @@
package com.corewing.app.modules.admin.sys; package com.corewing.app.modules.admin.sys;
import com.corewing.app.common.Result;
import com.corewing.app.service.FirmwareService;
import com.corewing.app.service.SysUserService;
import com.corewing.app.service.UserService;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
@Controller @Controller
public class SysMainController { public class SysMainController {
@Resource
private UserService userService;
@Resource
private FirmwareService firmwareService;
/** /**
* 加载页 * 加载页
* @return * @return
@@ -42,4 +57,17 @@ public class SysMainController {
return "admin/dashboard"; return "admin/dashboard";
} }
/**
* 统计
* @return
*/
@GetMapping("/main/statistics")
@ResponseBody
public Result<Map<String, Object>> statistics() {
Map<String, Object> result = new HashMap<>();
result.put("userCount", userService.count ());
result.put("firmwareCount", firmwareService.count());
return Result.success(result);
}
} }

View File

@@ -33,4 +33,11 @@ public interface FirmwareService extends IService<Firmware> {
* @return * @return
*/ */
boolean uploadFile(MultipartFile file, Long id); boolean uploadFile(MultipartFile file, Long id);
/**
* 根据id删除固件
* @param id
* @return
*/
boolean removeData(Long id);
} }

View File

@@ -9,6 +9,7 @@ import com.corewing.app.mapper.FirmwareMapper;
import com.corewing.app.service.FirmwareService; import com.corewing.app.service.FirmwareService;
import com.corewing.app.util.OSSUploadUtil; import com.corewing.app.util.OSSUploadUtil;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@@ -49,5 +50,62 @@ public class FirmwareServiceImpl extends ServiceImpl<FirmwareMapper, Firmware> i
} }
} }
@Transactional(rollbackFor = Exception.class)
@Override
public boolean removeData(Long id) {
Firmware firmware = getById(id);
if(firmware != null ){
if(firmware.getDownloadUrl() != null) {
OSSUploadUtil.deleteFile(getUrlLastSegment(firmware.getDownloadUrl()));
}
return removeById(id);
}
return false;
}
/**
* 获取 URL 路径的最后一节(忽略查询参数 ? 和锚点 #
* @param urlStr URL字符串
* @return 最后一节如文件名、资源ID异常/无路径时返回空字符串
*/
public static String getUrlLastSegment(String urlStr) {
// 1. 空值判断
if (urlStr == null || urlStr.trim().isEmpty()) {
return "";
}
// 2. 移除查询参数(? 及后面的内容)
int queryIndex = urlStr.indexOf('?');
if (queryIndex != -1) {
urlStr = urlStr.substring(0, queryIndex);
}
// 3. 移除锚点(# 及后面的内容)
int anchorIndex = urlStr.indexOf('#');
if (anchorIndex != -1) {
urlStr = urlStr.substring(0, anchorIndex);
}
// 4. 找到最后一个 "/" 的位置
int lastSlashIndex = urlStr.lastIndexOf('/');
// 5. 处理特殊情况:无 "/" 或 "/" 在末尾
if (lastSlashIndex == -1) {
// 无路径(如 "https://example.com" 或 "example.com"
return "";
}
if (lastSlashIndex == urlStr.length() - 1) {
// 路径以 "/" 结尾(如 "https://example.com/folder/"),需找倒数第二个 "/"
urlStr = urlStr.substring(0, lastSlashIndex);
lastSlashIndex = urlStr.lastIndexOf('/');
// 若倒数第二个 "/" 不存在(如 "https://example.com/"),返回空
if (lastSlashIndex == -1) {
return "";
}
}
// 6. 截取最后一个 "/" 后面的内容
return urlStr.substring(lastSlashIndex + 1);
}
} }

View File

@@ -47,7 +47,11 @@ public class OSSUploadUtil {
// 上传文件 // 上传文件
PutObjectRequest request = new PutObjectRequest(BUCKET_NAME, objectName, inputStream, metadata); PutObjectRequest request = new PutObjectRequest(BUCKET_NAME, objectName, inputStream, metadata);
PutObjectResult result = ossClient.putObject(request); PutObjectResult result = ossClient.putObject(request);
ossClient.setObjectAcl(
BUCKET_NAME, // Bucket 名称
objectName, // 刚上传的文件路径
CannedAccessControlList.PublicRead // 公共可读权限
);
// 生成文件访问 URL公网访问需 Bucket 设为公共读) // 生成文件访问 URL公网访问需 Bucket 设为公共读)
return String.format("https://%s.%s/%s", BUCKET_NAME, ENDPOINT, objectName); return String.format("https://%s.%s/%s", BUCKET_NAME, ENDPOINT, objectName);
} finally { } finally {
@@ -69,6 +73,11 @@ public class OSSUploadUtil {
try { try {
File file = new File(localFilePath); File file = new File(localFilePath);
ossClient.putObject(BUCKET_NAME, objectName, file); ossClient.putObject(BUCKET_NAME, objectName, file);
ossClient.setObjectAcl(
BUCKET_NAME, // Bucket 名称
objectName, // 刚上传的文件路径
CannedAccessControlList.PublicRead // 公共可读权限
);
return String.format("https://%s.%s/%s", BUCKET_NAME, ENDPOINT, objectName); return String.format("https://%s.%s/%s", BUCKET_NAME, ENDPOINT, objectName);
} finally { } finally {
if (ossClient != null) { if (ossClient != null) {

View File

@@ -269,7 +269,7 @@
</select> </select>
</div> </div>
</div> </div>
<div class="mb-3 row"> <div class="mb-3 row" v-if="addOrEditDto.id != null">
<label class="col-sm-3 col-form-label">固件地址</label> <label class="col-sm-3 col-form-label">固件地址</label>
<div class="col-sm-9"> <div class="col-sm-9">
<input type="text" class="form-control" v-model="addOrEditDto.downloadUrl" <input type="text" class="form-control" v-model="addOrEditDto.downloadUrl"
@@ -557,12 +557,14 @@
}, },
// 打开新增模态框 // 打开新增模态框
openAddModal() { openAddModal() {
this.clearForm();
this.addOrEditTitle = '新增'; this.addOrEditTitle = '新增';
this.modalInstances['addOrEditModel'].show(); this.modalInstances['addOrEditModel'].show();
}, },
// 打开编辑模态框 // 打开编辑模态框
openEditModal(item) { openEditModal(item) {
this.clearForm();
this.addOrEditTitle = '编辑'; this.addOrEditTitle = '编辑';
this.addOrEditDto = item; this.addOrEditDto = item;
this.modalInstances['addOrEditModel'].show(); this.modalInstances['addOrEditModel'].show();

View File

@@ -25,7 +25,7 @@
<div class="col-md-4 mb-4"> <div class="col-md-4 mb-4">
<div class="stat-card primary"> <div class="stat-card primary">
<i class="bi bi-people-fill"></i> <i class="bi bi-people-fill"></i>
<h3>1,234</h3> <h3>{{statistics.userCount}}</h3>
<p>用户数</p> <p>用户数</p>
</div> </div>
</div> </div>
@@ -39,7 +39,7 @@
<div class="col-md-4 mb-4"> <div class="col-md-4 mb-4">
<div class="stat-card warning"> <div class="stat-card warning">
<i class="bi bi-graph-up"></i> <i class="bi bi-graph-up"></i>
<h3>89%</h3> <h3>{{statistics.firmwareCount}}</h3>
<p>固件数</p> <p>固件数</p>
</div> </div>
</div> </div>
@@ -66,6 +66,10 @@
username: '', username: '',
realName: '', realName: '',
userId: '' userId: ''
},
statistics: {
userCount: 0,
firmwareCount: 0,
} }
} }
}, },
@@ -90,10 +94,23 @@
} }
} }
}, },
async loadStatistics() {
try {
const response = await request.get('/main/statistics');
if (response.code === 200) {
this.statistics = response.data;
}
} catch (error) {
console.error('获取用户信息失败:', error);
}
}
}, },
mounted() { mounted() {
// 加载用户信息 // 加载用户信息
this.loadUserInfo(); this.loadUserInfo();
// 加载统计信息
this.loadStatistics();
} }
}).mount('#app'); }).mount('#app');
</script> </script>