web端职代会管理: 修复congress_materials职代会资料文件的fileType,fileSize字段为空的问题;

This commit is contained in:
2026-07-29 15:56:03 +08:00
parent 8bff6f8ce9
commit bff78c6ced
7 changed files with 185 additions and 20 deletions
@@ -134,7 +134,7 @@ public class CongressMaterialsManageController {
.add("sort_no", sortNo == null ? 0 : sortNo)
.add("file_name", StrUtil.blankToDefault(fileName, name.trim()))
.add("file_url", fileUrl)
.add("file_type", StrUtil.blankToDefault(fileType, null))
.add("file_type", congressManageService.normalizeFileType(fileType, fileName, fileUrl))
.add("file_size", StrUtil.blankToDefault(fileSize, null))
.add("update_time", now);
if (StrUtil.isBlank(id)) {
@@ -143,11 +143,11 @@ public class CongressMaterialsManageController {
.add("create_time", now)
.add("deleted", 0);
dao.insert("congress_materials", chain);
return Result.success(newId);
return Result.success().addData(newId);
}
dao.update("congress_materials", chain,
Cnd.where("id", "=", id).and("deleted", "=", 0));
return Result.success(id);
return Result.success().addData(id);
}
@At("/delete")
@@ -57,6 +57,60 @@ public class CongressVotingIssueController {
return Result.success(congressManageService.materialOptions(sessionId, typeId));
}
@At("/uploadMaterial")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("congress.vote.issue")
@SLog(tag = "职代会-投票管理", msg = "快捷上传投票资料")
public Result uploadMaterial(@Param("sessionId") String sessionId,
@Param("typeId") String typeId,
@Param("name") String name,
@Param("fileName") String fileName,
@Param("fileUrl") String fileUrl,
@Param("fileType") String fileType,
@Param("fileSize") String fileSize) {
if (StrUtil.hasBlank(sessionId, typeId, fileUrl)) {
return Result.error("届次、投票类型和文件不能为空");
}
if (congressManageService.count("""
SELECT COUNT(1)
FROM teacher_congress_session
WHERE id = @sessionId
AND delFlag = 0
""", NutMap.NEW().addv("sessionId", sessionId)) <= 0) {
return Result.error("所选届次不存在");
}
if (congressManageService.count("""
SELECT COUNT(1)
FROM congress_materials_type
WHERE id = @typeId
AND COALESCE(deleted, 0) = 0
AND COALESCE(is_vote, 0) = 1
""", NutMap.NEW().addv("typeId", typeId)) <= 0) {
return Result.error("所选投票类型不存在");
}
Date now = new Date();
String materialName = StrUtil.blankToDefault(name, StrUtil.blankToDefault(fileName, "资料")).trim();
String newId = R.UU32();
dao.insert("congress_materials", Chain.make("id", newId)
.add("name", materialName)
.add("session_id", sessionId)
.add("time_id", null)
.add("type_id", typeId)
.add("sort_no", 0)
.add("file_name", StrUtil.blankToDefault(fileName, materialName))
.add("file_url", fileUrl)
.add("file_type", congressManageService.normalizeFileType(fileType, fileName, fileUrl))
.add("file_size", StrUtil.blankToDefault(fileSize, null))
.add("create_time", now)
.add("update_time", now)
.add("deleted", 0));
return Result.success(NutMap.NEW()
.addv("id", newId)
.addv("name", materialName)
.addv("fileName", StrUtil.blankToDefault(fileName, materialName))
.addv("fileUrl", fileUrl));
}
@At("/pageData")
@SaCheckPermission("congress.vote.issue")
public Result issuePageData(PageForm pageForm,
@@ -17,6 +17,7 @@ import org.nutz.lang.util.NutMap;
import java.util.Date;
import java.util.List;
import java.util.Locale;
/**
* 职代会管理公共服务类。
@@ -148,4 +149,31 @@ public class CongressManageService {
sql.append(" AND ").append(column).append(" = @").append(paramName);
params.addv(paramName, value);
}
public String normalizeFileType(String fileType, String fileName, String fileUrl) {
if (StrUtil.isNotBlank(fileType) && !fileType.contains("/")) {
return fileType.replace(".", "").trim().toLowerCase(Locale.ROOT);
}
String suffix = extractFileExtension(fileName);
if (StrUtil.isBlank(suffix)) {
suffix = extractFileExtension(fileUrl);
}
return StrUtil.blankToDefault(suffix, null);
}
private String extractFileExtension(String name) {
if (StrUtil.isBlank(name)) {
return "";
}
String value = name.split("\\?", 2)[0];
int slashIndex = Math.max(value.lastIndexOf('/'), value.lastIndexOf('\\'));
if (slashIndex >= 0) {
value = value.substring(slashIndex + 1);
}
int dotIndex = value.lastIndexOf('.');
if (dotIndex < 0 || dotIndex == value.length() - 1) {
return "";
}
return value.substring(dotIndex + 1).toLowerCase(Locale.ROOT);
}
}
@@ -53,7 +53,7 @@ layout("/layouts/platform.html"){
</el-card>
<el-dialog :title="formData.id ? '编辑投票' : '新增投票'" :visible.sync="dialogFormVisible"
width="850px" :close-on-click-modal="false">
width="880px" :close-on-click-modal="false">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px">
<el-row :gutter="16">
<el-col :span="12">
@@ -77,11 +77,27 @@ layout("/layouts/platform.html"){
<el-input v-model.trim="formData.name" maxlength="255" show-word-limit></el-input>
</el-form-item>
<el-form-item label="资料" prop="materialsId">
<el-select v-model="formData.materialsId" filterable style="width:100%"
:disabled="!formData.sessionId || !formData.typeId">
<el-option v-for="item in materialOptions" :key="item.id"
:label="item.name" :value="item.id"></el-option>
</el-select>
<el-row :gutter="12">
<el-col :span="17">
<el-select v-model="formData.materialsId" filterable style="width:100%"
:disabled="materialUploadDisabled">
<el-option v-for="item in materialOptions" :key="item.id"
:label="item.name" :value="item.id"></el-option>
</el-select>
</el-col>
<el-col :span="7">
<el-upload action="/platform/sys/file/uploadDynamicReturnUrl" :show-file-list="false"
:disabled="materialUploadDisabled || materialUploadLoading"
:before-upload="beforeMaterialUpload"
:on-success="uploadMaterialSuccess"
:on-error="uploadMaterialError"
accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx">
<el-button type="primary" icon="el-icon-upload" style="width:100%"
:loading="materialUploadLoading"
:disabled="materialUploadDisabled || materialUploadLoading">上传资料</el-button>
</el-upload>
</el-col>
</el-row>
</el-form-item>
<el-row :gutter="16">
<el-col :span="12">
@@ -157,6 +173,8 @@ layout("/layouts/platform.html"){
sessionOptions: [],
typeOptions: [],
materialOptions: [],
materialUploadLoading: false,
materialLoadSeq: 0,
voteItems: [],
pageForm: {pageNumber: 1, pageSize: 10, totalCount: 0, sessionId: "", name: ""},
formData: {},
@@ -172,7 +190,10 @@ layout("/layouts/platform.html"){
},
computed: {
voteTypeOptions() {
return this.typeOptions.filter(v => !!v.isVote)
return this.typeOptions.filter(v => Number(v.isVote) === 1)
},
materialUploadDisabled() {
return !this.formData.sessionId || !this.formData.typeId
}
},
methods: {
@@ -188,20 +209,77 @@ layout("/layouts/platform.html"){
if (typesRes.code === 0) this.typeOptions = typesRes.data || []
},
async loadMaterials() {
const seq = ++this.materialLoadSeq
this.materialOptions = []
if (!this.formData.sessionId || !this.formData.typeId) return
const res = await this.$axios.post("/platform/congress/materials/issue/materials", {
sessionId: this.formData.sessionId,
typeId: this.formData.typeId
})
if (res.code === 0) this.materialOptions = res.data || []
if (seq === this.materialLoadSeq && res.code === 0) this.materialOptions = res.data || []
},
getUploadedUrl(res) {
if (!res) return ""
if (typeof res === "string") return res
return res.data || res.url || res.fileUrl || res.path || res.filePath || ""
},
fileNameWithoutExt(name) {
return name ? String(name).replace(/\.[^/.]+$/, "") : ""
},
fileExtension(name) {
const fileName = String(name || "")
const index = fileName.lastIndexOf(".")
return index >= 0 ? fileName.substring(index + 1).toLowerCase() : ""
},
beforeMaterialUpload(file) {
if (this.materialUploadDisabled) {
this.$message.warning("请先选择届次和投票类型")
return false
}
this.materialUploadLoading = true
return true
},
async uploadMaterialSuccess(response, file) {
const fileUrl = this.getUploadedUrl(response)
if (!fileUrl) {
this.materialUploadLoading = false
this.$message.error(response && response.msg ? response.msg : "上传资料失败")
return
}
const fileName = file.name || "附件"
try {
const res = await this.$axios.post("/platform/congress/materials/issue/uploadMaterial", {
sessionId: this.formData.sessionId,
typeId: this.formData.typeId,
name: this.fileNameWithoutExt(fileName),
fileName: fileName,
fileUrl: fileUrl,
fileType: this.fileExtension(fileName),
fileSize: file.raw && file.raw.size ? file.raw.size : ""
})
if (res.code === 0) {
await this.loadMaterials()
this.formData.materialsId = res.data && res.data.id ? res.data.id : res.data
this.$message.success("上传资料成功")
} else {
this.$message.error(res.msg)
}
} finally {
this.materialUploadLoading = false
}
},
uploadMaterialError() {
this.materialUploadLoading = false
this.$message.error("上传资料失败")
},
async sessionChanged() {
this.formData.materialsId = ""
this.materialOptions = []
await this.loadMaterials()
},
async typeChanged() {
this.formData.materialsId = ""
this.materialOptions = []
await this.loadMaterials()
},
addVoteItem() {
@@ -262,7 +340,7 @@ layout("/layouts/platform.html"){
const res = await this.$axios.post("/platform/congress/materials/issue/save", data)
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.$message.success("保存成功")
this.pageData()
} else {
this.$message.error(res.msg)
@@ -276,7 +354,7 @@ layout("/layouts/platform.html"){
this.$confirm("确认删除该投票议题吗?", "提示", {type: "warning"}).then(async () => {
const res = await this.$axios.post("/platform/congress/materials/issue/delete", {id})
if (res.code === 0) {
this.$message.success(res.msg)
this.$message.success("删除成功")
this.doSearch()
} else {
this.$message.error(res.msg)
@@ -160,6 +160,11 @@ layout("/layouts/platform.html"){
fileNameWithoutExt(name) {
return name ? String(name).replace(/\.[^/.]+$/, "") : ""
},
fileExtension(name) {
const fileName = String(name || "")
const index = fileName.lastIndexOf(".")
return index >= 0 ? fileName.substring(index + 1).toLowerCase() : ""
},
getUploadFileUrl(file) {
return file && file.response && file.response.data ? file.response.data : file && (file.url || file.data) || ""
},
@@ -175,7 +180,7 @@ layout("/layouts/platform.html"){
const fileName = file.name || this.fileNameFromUrl(this.getUploadFileUrl(file))
this.$set(this.formData, "fileName", fileName)
this.$set(this.formData, "fileUrl", this.getUploadFileUrl(file))
this.$set(this.formData, "fileType", file.raw && file.raw.type ? file.raw.type : file.type || "")
this.$set(this.formData, "fileType", this.fileExtension(fileName))
this.$set(this.formData, "fileSize", file.raw && file.raw.size ? file.raw.size : file.size || "")
if (!this.formData.name && fileName) {
this.$set(this.formData, "name", this.fileNameWithoutExt(fileName))
@@ -190,7 +195,7 @@ layout("/layouts/platform.html"){
const res = await this.$axios.post("/platform/congress/materials/manage/save", this.formData)
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.$message.success("保存成功")
this.pageData()
} else {
this.$message.error(res.msg)
@@ -204,7 +209,7 @@ layout("/layouts/platform.html"){
this.$confirm("确认删除该会议资料吗?", "提示", {type: "warning"}).then(async () => {
const res = await this.$axios.post("/platform/congress/materials/manage/delete", {id})
if (res.code === 0) {
this.$message.success(res.msg)
this.$message.success("删除成功")
this.doSearch()
} else {
this.$message.error(res.msg)
@@ -98,7 +98,7 @@ layout("/layouts/platform.html"){
const res = await this.$axios.post("/platform/congress/materials/type/save", this.formData)
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.$message.success("保存成功")
this.pageData()
} else {
this.$message.error(res.msg)
@@ -112,7 +112,7 @@ layout("/layouts/platform.html"){
this.$confirm("确认删除该资料类型吗?", "提示", {type: "warning"}).then(async () => {
const res = await this.$axios.post("/platform/congress/materials/type/delete", {id})
if (res.code === 0) {
this.$message.success(res.msg)
this.$message.success("删除成功")
this.doSearch()
} else {
this.$message.error(res.msg)
@@ -129,7 +129,7 @@ layout("/layouts/platform.html"){
const res = await this.$axios.post("/platform/congress/signIn/save", this.formData)
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.$message.success("保存成功")
this.pageData()
} else {
this.$message.error(res.msg)
@@ -143,7 +143,7 @@ layout("/layouts/platform.html"){
this.$confirm("确认删除该会议签到配置吗?", "提示", {type: "warning"}).then(async () => {
const res = await this.$axios.post("/platform/congress/signIn/delete", {id})
if (res.code === 0) {
this.$message.success(res.msg)
this.$message.success("删除成功")
this.doSearch()
} else {
this.$message.error(res.msg)