From 51b1a6cf279c3824bc9d9022d74ca8a32572297f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=8C=E5=85=88=E8=88=9C?= <2499071264@qq.com> Date: Fri, 13 Nov 2026 18:44:31 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E4=BD=9C=E5=93=81?= =?UTF-8?q?=E5=BE=81=E9=9B=86=E6=8A=95=E7=A8=BF=E5=92=8C=E6=94=B6=E8=B4=A7?= =?UTF-8?q?=E5=9C=B0=E5=9D=80=E7=AE=A1=E7=90=86=20-=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E7=AB=AF=E4=BD=9C=E5=93=81=E5=BE=81=E9=9B=86?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E3=80=81=E6=8A=95=E7=A8=BF=E5=92=8C=E6=88=91?= =?UTF-8?q?=E7=9A=84=E4=BD=9C=E5=93=81=E9=A1=B5=E9=9D=A2=20-=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20PC=20=E5=92=8C=E7=A7=BB=E5=8A=A8=E7=AB=AF=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E3=80=81=E6=96=B0=E5=A2=9E=E5=8F=8A=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=94=B6=E8=B4=A7=E5=9C=B0=E5=9D=80=20-=20=E9=99=90=E5=88=B6?= =?UTF-8?q?=E5=90=8C=E4=B8=80=E7=94=A8=E6=88=B7=E5=9C=A8=E5=90=8C=E4=B8=80?= =?UTF-8?q?=E6=B4=BB=E5=8A=A8=E3=80=81=E4=B8=BB=E9=A2=98=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E5=92=8C=E4=BD=9C=E5=93=81=E7=B1=BB=E5=9E=8B=E4=B8=8B=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E6=8A=95=E7=A8=BF=20-=20=E5=85=BC=E5=AE=B9=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0=E6=8E=A5=E5=8F=A3=E8=BF=94=E5=9B=9E=E7=9A=84=2026=20?= =?UTF-8?q?=E4=BD=8D=E9=99=84=E4=BB=B6=20ID=20-=20=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E7=AB=AF=E5=88=97=E8=A1=A8=E3=80=81=E8=A1=A8?= =?UTF-8?q?=E5=8D=95=E5=92=8C=E6=93=8D=E4=BD=9C=E6=8C=89=E9=92=AE=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/sys/services/SysFileService.java | 2 + .../sys/services/impl/SysFileServiceImpl.java | 22 + .../budwk/app/sys/utils/SysFileMinIoUtil.java | 9 + ...ivityWorksCollectionAddressController.java | 131 +++++ ...tivityWorksCollectionCommonController.java | 26 +- ...tivityWorksCollectionManageController.java | 28 + ...ActivityWorksCollectionReadController.java | 10 +- ...tivityWorksCollectionUploadController.java | 80 +-- .../H5ActivityWorksCollectionController.java | 200 ++++++- .../ActivityWorksCollectionUploadService.java | 265 ++++++++++ .../db/works_collection/works_collection.sql | 4 + .../components/plugins/sysUpload/index.vue | 15 +- .../activity/workscollection/common/info.js | 1 + .../workscollection/manage/index.html | 135 +++-- .../activity/workscollection/read/index.html | 3 + .../activity/workscollection/upload/auForm.js | 171 ++++-- .../workscollection/upload/index.html | 4 + .../workscollection/upload/shippingAddress.js | 98 ++++ .../welfare/addressManage/addressDialog.js | 13 +- .../zhgh/welfare/addressManage/index.html | 11 +- .../workscollection/activity/index.html | 230 ++++++++ .../workscollection/upload/address.html | 86 +++ .../workscollection/upload/addressEdit.html | 130 +++++ .../workscollection/upload/index.html | 490 +++++++++++++++++- .../activity/workscollection/upload/mine.html | 309 ++++++++++- 25 files changed, 2310 insertions(+), 163 deletions(-) create mode 100644 src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/ActivityWorksCollectionAddressController.java create mode 100644 src/main/java/com/budwk/app/zhgh/activity/workscollection/service/ActivityWorksCollectionUploadService.java create mode 100644 src/main/resources/db/works_collection/works_collection.sql create mode 100644 src/main/resources/views/platform/zhgh/activity/workscollection/upload/shippingAddress.js create mode 100644 src/main/resources/views/platform/zhghh5/activity/workscollection/upload/address.html create mode 100644 src/main/resources/views/platform/zhghh5/activity/workscollection/upload/addressEdit.html diff --git a/src/main/java/com/budwk/app/sys/services/SysFileService.java b/src/main/java/com/budwk/app/sys/services/SysFileService.java index 9976d46..b6b1ea0 100644 --- a/src/main/java/com/budwk/app/sys/services/SysFileService.java +++ b/src/main/java/com/budwk/app/sys/services/SysFileService.java @@ -25,6 +25,8 @@ public interface SysFileService extends BaseService { */ String uploadReturnUrl(String engine, TempFile file); + long sizeBytes(Sys_file file); + /** * 分页 */ diff --git a/src/main/java/com/budwk/app/sys/services/impl/SysFileServiceImpl.java b/src/main/java/com/budwk/app/sys/services/impl/SysFileServiceImpl.java index b610b45..864a15a 100644 --- a/src/main/java/com/budwk/app/sys/services/impl/SysFileServiceImpl.java +++ b/src/main/java/com/budwk/app/sys/services/impl/SysFileServiceImpl.java @@ -4,6 +4,7 @@ import cn.hutool.core.convert.Convert; import cn.hutool.core.date.DateUtil; import cn.hutool.core.img.ImgUtil; import cn.hutool.core.io.FileUtil; +import cn.hutool.json.JSONObject; import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.NumberUtil; @@ -65,6 +66,26 @@ public class SysFileServiceImpl extends BaseServiceImpl implements Sys return this.storageFile(engine, file, false); } + @Override + public long sizeBytes(Sys_file file) { + JSONObject metadata = file.getExtJson(); + if (metadata != null && metadata.getLong("sizeBytes") != null) { + return metadata.getLong("sizeBytes"); + } + if (SysFileEngineTypeEnum.LOCAL.getValue().equals(file.getEngine())) { + File storedFile = FileUtil.file(file.getStoragePath()); + if (!storedFile.isFile()) { + throw new BaseException("文件不存在"); + } + return storedFile.length(); + } + if (SysFileEngineTypeEnum.MINIO.getValue().equals(file.getEngine())) { + String objectKey = StrUtil.removePrefix(file.getStoragePath(), "/"); + return SysFileMinIoUtil.getFileSize(file.getBucket(), objectKey); + } + throw new BaseException("不支持的文件引擎"); + } + @Override public Pagination page(Sys_file file) { return null; @@ -250,6 +271,7 @@ public class SysFileServiceImpl extends BaseServiceImpl implements Sys sys_file.setSizeKb(Convert.toStr(NumberUtil.div(new BigDecimal(file.getSize()), BigDecimal.valueOf(1024)) .setScale(0, RoundingMode.HALF_UP))); sys_file.setSizeInfo(FileUtil.readableFileSize(file.getSize())); + sys_file.setExtJson(new JSONObject().set("sizeBytes", file.getSize())); sys_file.setObjName(ObjectUtil.isNotEmpty(sys_file.getSuffix()) ? fileId + StrUtil.DOT + sys_file.getSuffix() : null); // 如果是图片,则压缩生成缩略图 if (ObjectUtil.isNotEmpty(suffix)) { diff --git a/src/main/java/com/budwk/app/sys/utils/SysFileMinIoUtil.java b/src/main/java/com/budwk/app/sys/utils/SysFileMinIoUtil.java index 2b20a30..15a4889 100644 --- a/src/main/java/com/budwk/app/sys/utils/SysFileMinIoUtil.java +++ b/src/main/java/com/budwk/app/sys/utils/SysFileMinIoUtil.java @@ -103,6 +103,15 @@ public class SysFileMinIoUtil { return client; } + public static long getFileSize(String bucketName, String key) { + try { + initClient(); + return client.statObject(StatObjectArgs.builder().bucket(bucketName).object(key).build()).size(); + } catch (Exception e) { + throw new BaseException("文件大小读取失败"); + } + } + /** * 查询存储桶是否存在 * 例如:传入参数examplebucket-1250000000,返回true代表存在此桶 diff --git a/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/ActivityWorksCollectionAddressController.java b/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/ActivityWorksCollectionAddressController.java new file mode 100644 index 0000000..43f79cb --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/ActivityWorksCollectionAddressController.java @@ -0,0 +1,131 @@ +package com.budwk.app.zhgh.activity.workscollection.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.dev33.satoken.annotation.SaMode; +import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.result.Result; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.zhgh.welfare.model.WelfareMemberAddress; +import com.budwk.app.zhgh.welfare.service.WelfareAddressManageService; +import org.nutz.aop.interceptor.ioc.TransAop; +import org.nutz.dao.Chain; +import org.nutz.dao.Cnd; +import org.nutz.ioc.aop.Aop; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.POST; +import org.nutz.mvc.annotation.Param; + +import javax.servlet.http.HttpServletResponse; + +@IocBean +@At("/platform/activity/worksCollection/addressManage") +@Ok("json:full") +public class ActivityWorksCollectionAddressController { + + private static final String PERMISSION = "activity.workscollection.addressManage"; + + @Inject + private WelfareAddressManageService addressService; + + @At("") + @Ok("beetl:/platform/zhgh/welfare/addressManage/index.html") + @SaCheckPermission(PERMISSION) + public void index() { + } + + @At + @SaCheckPermission(value = {PERMISSION, "activity.workscollection.upload", "h5.activity.workscollection.upload"}, mode = SaMode.OR) + public Result selectUserAddress() { + return Result.success(addressService.query(currentUserAddresses().desc("isDefault"))); + } + + @At + @POST + @Aop(TransAop.READ_COMMITTED) + @SaCheckPermission(value = {PERMISSION, "activity.workscollection.upload", "h5.activity.workscollection.upload"}, mode = SaMode.OR) + public Result doSaveUserAddress(@Param("data") WelfareMemberAddress form) { + if (form == null || StrUtil.hasBlank(form.getUserName(), form.getTel(), form.getProvince(), + form.getCity(), form.getAreaCode(), form.getAddressDetail())) { + return Result.error("请填写完整的收货地址"); + } + + form.setTel(form.getTel().trim()); + if (!form.getTel().matches("1[3-9][0-9]{9}")) { + return Result.error("请输入正确的手机号码"); + } + + boolean editing = StrUtil.isNotBlank(form.getId()); + Cnd condition = currentUserAddresses().and("id", "=", form.getId()); + if (editing && addressService.count(condition) == 0) { + return Result.error("收货地址不存在"); + } + + if (form.isDefault()) { + addressService.dao().update(WelfareMemberAddress.class, Chain.make("isDefault", false), currentUserAddresses()); + } + + if (editing) { + Chain values = Chain.make("userName", form.getUserName()) + .add("tel", form.getTel()) + .add("province", form.getProvince()) + .add("city", form.getCity()) + .add("county", form.getCounty()) + .add("areaCode", form.getAreaCode()) + .add("addressDetail", form.getAddressDetail()) + .add("isDefault", form.isDefault()) + .add("updatedBy", SecurityUtil.getUserId()) + .add("updatedAt", System.currentTimeMillis()); + addressService.dao().update(WelfareMemberAddress.class, values, condition); + } else { + addressService.insert(new WelfareMemberAddress() + .setUserId(SecurityUtil.getUserId()) + .setUserName(form.getUserName()) + .setTel(form.getTel()) + .setProvince(form.getProvince()) + .setCity(form.getCity()) + .setCounty(form.getCounty()) + .setAreaCode(form.getAreaCode()) + .setAddressDetail(form.getAddressDetail()) + .setDefault(form.isDefault())); + } + return Result.success(); + } + + @At + @POST + @Aop(TransAop.READ_COMMITTED) + @SaCheckPermission(value = {PERMISSION, "activity.workscollection.upload", "h5.activity.workscollection.upload"}, mode = SaMode.OR) + public Result doDefault(@Param("id") String id) { + Cnd condition = currentUserAddresses().and("id", "=", id); + if (addressService.count(condition) == 0) { + return Result.error("收货地址不存在"); + } + addressService.dao().update(WelfareMemberAddress.class, Chain.make("isDefault", false), currentUserAddresses()); + addressService.dao().update(WelfareMemberAddress.class, Chain.make("isDefault", true), condition); + return Result.success(); + } + + @At + @POST + @SaCheckPermission(value = {PERMISSION, "h5.activity.workscollection.upload"}, mode = SaMode.OR) + public Result deleteAddress(@Param("id") String id) { + int deleted = addressService.dao().clear(WelfareMemberAddress.class, currentUserAddresses().and("id", "=", id)); + return deleted > 0 ? Result.success() : Result.error("收货地址不存在"); + } + + @At + @Ok("void") + @SaCheckPermission(PERMISSION) + public void exportAllAddress(HttpServletResponse response) { + StpUtil.checkRole("SYSADMIN"); + addressService.exportAllAddress(response); + } + + private Cnd currentUserAddresses() { + return Cnd.where("userId", "=", SecurityUtil.getUserId()); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/ActivityWorksCollectionCommonController.java b/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/ActivityWorksCollectionCommonController.java index bc83e37..68a05bc 100644 --- a/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/ActivityWorksCollectionCommonController.java +++ b/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/ActivityWorksCollectionCommonController.java @@ -1,6 +1,10 @@ package com.budwk.app.zhgh.activity.workscollection.controller; import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.dev33.satoken.stp.StpUtil; +import com.budwk.app.base.constant.RoleConstant; +import com.budwk.app.web.commons.auth.utils.AuthUtil; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.base.result.Result; import com.budwk.app.zhgh.activity.workscollection.models.Activity_works_collection; import com.budwk.app.zhgh.activity.workscollection.models.Activity_works_collection_upload; @@ -63,18 +67,36 @@ public class ActivityWorksCollectionCommonController { up.*, co.NAME AS activityName, su.typeName AS subjectName, - wo.worksTypeName AS worksName + wo.worksTypeName AS worksName, + CASE WHEN up.userId = @viewerId OR @readAll = 1 + OR (@readUnion = 1 AND up.unionId = @viewerUnionId) + THEN address.shippingAddress END AS shippingAddress FROM `activity_works_collection_upload` up LEFT JOIN activity_works_collection co ON up.activityId = co.id LEFT JOIN activity_works_subjecttype su ON up.subjectId = su.id LEFT JOIN activity_works_workstype wo ON up.worksId = wo.id + LEFT JOIN ( + SELECT userId, + CONCAT_WS(' ', CONCAT_WS('', province, city, county), addressDetail, userName, tel) AS shippingAddress, + ROW_NUMBER() OVER (PARTITION BY userId ORDER BY id) AS rn + FROM welfare_member_address + WHERE isDefault = 1 + ) address ON address.userId = up.userId AND address.rn = 1 $condition """); Cnd cnd = Cnd.NEW(); cnd.and("up.id", "=", id); sql.setCondition(cnd); - NutMap result = (NutMap) Daos.query(dao, sql.toString(), Sqls.callback.map()); + boolean canRead = StpUtil.hasPermission("activity.workscollection.read"); + boolean canReadAll = canRead && AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name()); + sql.setParam("viewerId", SecurityUtil.getUserId()); + sql.setParam("viewerUnionId", SecurityUtil.getUnionId()); + sql.setParam("readAll", canReadAll ? 1 : 0); + sql.setParam("readUnion", canRead ? 1 : 0); + sql.setCallback(Sqls.callback.map()); + dao.execute(sql); + NutMap result = sql.getObject(NutMap.class); return Result.success(result); } } diff --git a/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/ActivityWorksCollectionManageController.java b/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/ActivityWorksCollectionManageController.java index 6a7ba4a..d39b91f 100644 --- a/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/ActivityWorksCollectionManageController.java +++ b/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/ActivityWorksCollectionManageController.java @@ -80,6 +80,9 @@ public class ActivityWorksCollectionManageController { @At @SaCheckPermission("activity.workscollection.manage") public Result insert(@Param("data") @Valid Activity_works_collection worksCollection) { + if (!hasValidFileSizeLimits(worksCollection)) { + return Result.error("总文件大小必须大于或等于单个文件大小"); + } worksCollection.setIsSubmit(true); dao.insertWith(worksCollection, "subjectTypes"); worksCollection.getSubjectTypes().forEach(item -> { @@ -91,6 +94,9 @@ public class ActivityWorksCollectionManageController { @At @SaCheckPermission("activity.workscollection.manage") public Result save(@Param("data") @Valid Activity_works_collection worksCollection) { + if (!hasValidFileSizeLimits(worksCollection)) { + return Result.error("总文件大小必须大于或等于单个文件大小"); + } worksCollection.setIsSubmit(false); dao.insertWith(worksCollection, "subjectTypes"); worksCollection.getSubjectTypes().forEach(item -> { @@ -103,6 +109,9 @@ public class ActivityWorksCollectionManageController { @SaCheckPermission("activity.workscollection.manage") @Aop(TransAop.READ_COMMITTED) public Result update(@Param("data") @Valid Activity_works_collection worksCollection) { + if (!hasValidFileSizeLimits(worksCollection)) { + return Result.error("总文件大小必须大于或等于单个文件大小"); + } dao.update(worksCollection); dao.updateLinks(worksCollection, "subjectTypes"); dao.insertLinks(worksCollection, "subjectTypes"); @@ -123,6 +132,25 @@ public class ActivityWorksCollectionManageController { return Result.success(); } + private boolean hasValidFileSizeLimits(Activity_works_collection worksCollection) { + if (worksCollection.getSubjectTypes() == null) { + return true; + } + for (Activity_works_subjectType subjectType : worksCollection.getSubjectTypes()) { + if (subjectType.getWorksTypes() == null) { + continue; + } + for (Activity_works_worksType worksType : subjectType.getWorksTypes()) { + Integer single = worksType.getAllowSingleFileSize(); + Integer total = worksType.getAllowTotalFileSize(); + if (single != null && single > 0 && total != null && total > 0 && total < single) { + return false; + } + } + } + return true; + } + @At @SaCheckPermission("activity.workscollection.manage") @Aop(TransAop.READ_COMMITTED) diff --git a/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/ActivityWorksCollectionReadController.java b/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/ActivityWorksCollectionReadController.java index abe7d5f..c4a85ae 100644 --- a/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/ActivityWorksCollectionReadController.java +++ b/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/ActivityWorksCollectionReadController.java @@ -75,12 +75,20 @@ public class ActivityWorksCollectionReadController { up.*, co.NAME AS activityName, su.typeName AS subjectName, - wo.worksTypeName AS worksName + wo.worksTypeName AS worksName, + address.shippingAddress from activity_works_collection_upload up LEFT JOIN activity_works_collection co ON up.activityId = co.id LEFT JOIN activity_works_subjecttype su ON up.subjectId = su.id LEFT JOIN activity_works_workstype wo ON up.worksId = wo.id + LEFT JOIN ( + SELECT userId, + CONCAT_WS(' ', CONCAT_WS('', province, city, county), addressDetail, userName, tel) AS shippingAddress, + ROW_NUMBER() OVER (PARTITION BY userId ORDER BY id) AS rn + FROM welfare_member_address + WHERE isDefault = 1 + ) address ON address.userId = up.userId AND address.rn = 1 $condition """); Cnd cnd = Cnd.NEW(); diff --git a/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/ActivityWorksCollectionUploadController.java b/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/ActivityWorksCollectionUploadController.java index 4fad198..628b567 100644 --- a/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/ActivityWorksCollectionUploadController.java +++ b/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/ActivityWorksCollectionUploadController.java @@ -1,22 +1,20 @@ package com.budwk.app.zhgh.activity.workscollection.controller; import cn.dev33.satoken.annotation.SaCheckPermission; -import com.budwk.app.base.page.Pagination; import com.budwk.app.base.param.PageForm; import com.budwk.app.base.result.Result; -import com.budwk.app.base.service.BaseService; -import com.budwk.app.sys.models.Sys_user; -import com.budwk.app.sys.views.View_user; import com.budwk.app.web.commons.auth.utils.SecurityUtil; -import com.budwk.app.zhgh.activity.basic.models.ActivityUserScope; import com.budwk.app.zhgh.activity.workscollection.models.Activity_works_collection; import com.budwk.app.zhgh.activity.workscollection.models.Activity_works_collection_upload; +import com.budwk.app.zhgh.activity.workscollection.service.ActivityWorksCollectionUploadService; import io.swagger.annotations.ApiOperation; +import com.budwk.app.zhgh.welfare.model.WelfareMemberAddress; +import org.nutz.aop.interceptor.ioc.TransAop; +import org.nutz.ioc.aop.Aop; import org.nutz.dao.Cnd; import org.nutz.dao.Dao; import org.nutz.dao.FieldFilter; import org.nutz.dao.Sqls; -import org.nutz.dao.sql.Sql; import org.nutz.dao.util.Daos; import org.nutz.dao.util.cri.SqlExpressionGroup; import org.nutz.ioc.loader.annotation.Inject; @@ -40,7 +38,7 @@ public class ActivityWorksCollectionUploadController { private Dao dao; @Inject - private BaseService baseService; + private ActivityWorksCollectionUploadService uploadService; @At("") @Ok("beetl:/platform/zhgh/activity/workscollection/upload/index.html") @@ -57,27 +55,7 @@ public class ActivityWorksCollectionUploadController { @At @SaCheckPermission("activity.workscollection.upload") public Result pageData(@Valid PageForm pageForm, String activityId, String subjectId, String worksId) { - Sql sql = Sqls.create(""" - select - up.*, - co.NAME AS activityName, - su.typeName AS subjectName, - wo.worksTypeName AS worksName - from - activity_works_collection_upload up - LEFT JOIN activity_works_collection co ON up.activityId = co.id - LEFT JOIN activity_works_subjecttype su ON up.subjectId = su.id - LEFT JOIN activity_works_workstype wo ON up.worksId = wo.id - $condition - """); - Cnd cnd = Cnd.NEW(); - cnd.and("userId", "=", SecurityUtil.getUserId()); - cnd.andEX("up.activityId", "=", activityId); - cnd.andEX("up.subjectId", "=", subjectId); - cnd.andEX("up.worksId", "=", worksId); - sql.setCondition(cnd); - Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); - return Result.success(pagination); + return uploadService.pageData(pageForm, activityId, subjectId, worksId); } /** @@ -87,37 +65,33 @@ public class ActivityWorksCollectionUploadController { */ @At @SaCheckPermission("activity.workscollection.upload") - public Result insert(@Param("data") @Valid Activity_works_collection_upload upload) { - String activityId = upload.getActivityId(); - Activity_works_collection activity = dao.fetch(Activity_works_collection.class, activityId); - if (activity.getActivityGroupId() != null) { - int count = dao.count(ActivityUserScope.class, Cnd.where(ActivityUserScope::getGroupId, "=", activity.getActivityGroupId()) - .and(ActivityUserScope::getUserId, "=", SecurityUtil.getUserId())); - if (count == 0) { - return Result.error("您没有权限参与该活动"); - } + @Aop(TransAop.READ_COMMITTED) + public Result insert(@Param("data") @Valid Activity_works_collection_upload upload, @Param("addressId") String addressId) { + WelfareMemberAddress address = uploadService.shippingAddress(addressId); + if (address == null) { + return Result.error("请选择手机号有效的收货地址"); } - - View_user vwUser = dao.fetch(View_user.class, Cnd.where(View_user::getId, "=", SecurityUtil.getUserId())); - - upload.setUserId(SecurityUtil.getUserId()); - upload.setUserName(SecurityUtil.getUserUsername()); - upload.setLoginName(SecurityUtil.getUserLoginname()); - upload.setUnitId(SecurityUtil.getUnitId()); - upload.setUnitName(vwUser.getUnitName()); - upload.setUnionId(SecurityUtil.getUnionId()); - upload.setUnionName(vwUser.getUnionName()); - - dao.insert(upload); - return Result.success(); + Result result = uploadService.insert(upload); + if (result.isSuccess()) { + uploadService.confirmShippingAddress(address); + } + return result; } @At @SaCheckPermission("activity.workscollection.upload") - public Result update(@Param("data") @Valid Activity_works_collection_upload upload) { - dao.updateIgnoreNull(upload); - return Result.success(); + @Aop(TransAop.READ_COMMITTED) + public Result update(@Param("data") @Valid Activity_works_collection_upload upload, @Param("addressId") String addressId) { + WelfareMemberAddress address = uploadService.shippingAddress(addressId); + if (address == null) { + return Result.error("请选择手机号有效的收货地址"); + } + Result result = uploadService.update(upload); + if (result.isSuccess()) { + uploadService.confirmShippingAddress(address); + } + return result; } @At diff --git a/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/h5/H5ActivityWorksCollectionController.java b/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/h5/H5ActivityWorksCollectionController.java index 63ec2ba..8bbfbbe 100644 --- a/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/h5/H5ActivityWorksCollectionController.java +++ b/src/main/java/com/budwk/app/zhgh/activity/workscollection/controller/h5/H5ActivityWorksCollectionController.java @@ -1,9 +1,33 @@ package com.budwk.app.zhgh.activity.workscollection.controller.h5; import cn.dev33.satoken.annotation.SaCheckPermission; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.result.Result; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.zhgh.activity.workscollection.models.Activity_works_collection; +import com.budwk.app.zhgh.activity.workscollection.models.Activity_works_collection_upload; +import com.budwk.app.zhgh.activity.workscollection.models.Activity_works_subjectType; +import com.budwk.app.zhgh.activity.workscollection.models.Activity_works_worksType; +import com.budwk.app.zhgh.activity.workscollection.service.ActivityWorksCollectionUploadService; +import com.budwk.app.zhgh.welfare.model.WelfareMemberAddress; +import org.nutz.aop.interceptor.ioc.TransAop; +import org.nutz.ioc.aop.Aop; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.Strings; +import org.nutz.lang.util.NutMap; import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.POST; +import org.nutz.mvc.annotation.Param; + +import javax.validation.Valid; +import java.util.Date; +import java.util.List; /** * 手机端作品征集 @@ -13,12 +37,18 @@ import org.nutz.mvc.annotation.Ok; @Ok("json:full") public class H5ActivityWorksCollectionController { + @Inject + private Dao dao; + + @Inject + private ActivityWorksCollectionUploadService uploadService; + /** * 活动列表页面 */ - @At("/activity") + @At({"", "/activity"}) @Ok("beetl:/platform/zhghh5/activity/workscollection/activity/index.html") - @SaCheckPermission("activity.workscollection.upload") + @SaCheckPermission("h5.activity.workscollection.upload") public void activity() { } @@ -27,7 +57,7 @@ public class H5ActivityWorksCollectionController { */ @At("/upload") @Ok("beetl:/platform/zhghh5/activity/workscollection/upload/index.html") - @SaCheckPermission("activity.workscollection.upload") + @SaCheckPermission("h5.activity.workscollection.upload") public void upload() { } @@ -36,7 +66,169 @@ public class H5ActivityWorksCollectionController { */ @At("/upload/mine") @Ok("beetl:/platform/zhghh5/activity/workscollection/upload/mine.html") - @SaCheckPermission("activity.workscollection.upload") + @SaCheckPermission("h5.activity.workscollection.upload") public void uploadMine() { } + + @At("/upload/address") + @Ok("beetl:/platform/zhghh5/activity/workscollection/upload/address.html") + @SaCheckPermission("h5.activity.workscollection.upload") + public void uploadAddress() { + } + + @At("/upload/address/edit") + @Ok("beetl:/platform/zhghh5/activity/workscollection/upload/addressEdit.html") + @SaCheckPermission("h5.activity.workscollection.upload") + public void editUploadAddress() { + } + + @At("/activities") + @POST + @SaCheckPermission("h5.activity.workscollection.upload") + public Result activities() { + Date now = new Date(); + List activities = dao.query(Activity_works_collection.class, + visibleActivities().desc("startDateTime").desc("id")).stream() + .map(activity -> activityInfo(activity, now)) + .toList(); + return Result.success(activities); + } + + @At("/activityDetail") + @POST + @SaCheckPermission("h5.activity.workscollection.upload") + public Result activityDetail(@Param("activityId") String activityId) { + Activity_works_collection activity = findActivity(activityId); + if (activity == null) { + return Result.error("活动不存在或您没有权限参与该活动"); + } + List subjects = dao.query(Activity_works_subjectType.class, + Cnd.where("activityId", "=", activityId).asc("location")); + for (Activity_works_subjectType subject : subjects) { + subject.setWorksTypes(dao.query(Activity_works_worksType.class, + Cnd.where("subjectId", "=", subject.getId()).asc("location"))); + } + return Result.success(activityInfo(activity, new Date()) + .setv("content", activity.getContent()) + .setv("introduce", activity.getIntroduce()) + .setv("rewardMethod", activity.getRewardMethod()) + .setv("subjectTypes", subjects)); + } + + @At("/minePageData") + @POST + @SaCheckPermission("h5.activity.workscollection.upload") + public Result minePageData(@Valid PageForm pageForm) { + return uploadService.pageData(pageForm, null, null, null); + } + + @At("/myWork") + @POST + @SaCheckPermission("h5.activity.workscollection.upload") + public Result myWork(@Param("id") String id) { + Activity_works_collection_upload work = dao.fetch(Activity_works_collection_upload.class, myWorkCondition(id)); + return work == null ? Result.error("作品不存在") : Result.success(work); + } + + @At("/saveWork") + @POST + @SaCheckPermission("h5.activity.workscollection.upload") + @Aop(TransAop.READ_COMMITTED) + public Result saveWork(@Param("data") @Valid Activity_works_collection_upload form, @Param("addressId") String addressId) { + WelfareMemberAddress address = uploadService.shippingAddress(addressId); + if (address == null) { + return Result.error("请选择手机号有效的收货地址"); + } + String id = form.getId(); + Activity_works_collection_upload original = null; + if (Strings.isNotBlank(id)) { + original = dao.fetch(Activity_works_collection_upload.class, myWorkCondition(id)); + if (original == null) { + return Result.error("作品不存在"); + } + if (!original.getActivityId().equals(form.getActivityId())) { + return Result.error("无法变更作品所属活动"); + } + } + + Activity_works_collection activity = findActivity(form.getActivityId()); + if (activity == null) { + return Result.error("活动不存在或您没有权限参与该活动"); + } + if (!"open".equals(activityStatus(activity, new Date()))) { + return Result.error("当前活动不在作品提交时间内"); + } + + + Activity_works_collection_upload work = new Activity_works_collection_upload(); + work.setActivityId(activity.getId()); + work.setSubjectId(form.getSubjectId()); + work.setWorksId(form.getWorksId()); + work.setName(form.getName()); + work.setDescription(form.getDescription()); + work.setFiles(form.getFiles()); + Result result; + if (original == null) { + result = uploadService.insert(work); + } else { + work.setId(original.getId()); + result = uploadService.update(work); + } + if (result.isSuccess()) { + uploadService.confirmShippingAddress(address); + } + return result; + } + + @At("/deleteWork") + @POST + @SaCheckPermission("h5.activity.workscollection.upload") + public Result deleteWork(@Param("id") String id) { + Activity_works_collection_upload work = dao.fetch(Activity_works_collection_upload.class, myWorkCondition(id)); + if (work == null) { + return Result.error("作品不存在"); + } + Sql openActivity = Sqls.create(""" + SELECT id FROM activity_works_collection + WHERE id = @activityId AND enable = 1 AND (isSubmit = 1 OR isSubmit IS NULL) + AND startDateTime <= CURRENT_TIMESTAMP(3) AND endDateTime >= CURRENT_TIMESTAMP(3) + """).setParam("activityId", work.getActivityId()); + return dao.clear(Activity_works_collection_upload.class, myWorkCondition(id).and("activityId", "in", openActivity)) > 0 + ? Result.success() : Result.error("当前活动不在作品提交时间内,无法删除作品"); + } + + private Cnd visibleActivities() { + return Cnd.where("enable", "=", true) + .and(Cnd.exps("isSubmit", "=", true).or("isSubmit", "is", null)) + .and(Cnd.exps("activityGroupId", "is", null) + .or("activityGroupId", "in", Sqls.create("select groupId from activity_user_scope where userId = @userId") + .setParam("userId", SecurityUtil.getUserId()))); + } + + private Activity_works_collection findActivity(String activityId) { + return dao.fetch(Activity_works_collection.class, visibleActivities().and("id", "=", activityId)); + } + + private Cnd myWorkCondition(String id) { + return Cnd.where("id", "=", id).and("userId", "=", SecurityUtil.getUserId()); + } + + private NutMap activityInfo(Activity_works_collection activity, Date now) { + return NutMap.NEW() + .setv("id", activity.getId()) + .setv("name", activity.getName()) + .setv("cover", activity.getCover()) + .setv("startDateTime", activity.getStartDateTime() == null ? null : activity.getStartDateTime().getTime()) + .setv("endDateTime", activity.getEndDateTime() == null ? null : activity.getEndDateTime().getTime()) + .setv("status", activityStatus(activity, now)); + } + + private String activityStatus(Activity_works_collection activity, Date now) { + if (activity.getStartDateTime() == null || activity.getEndDateTime() == null || now.after(activity.getEndDateTime())) { + return "closed"; + } + return now.before(activity.getStartDateTime()) ? "upcoming" : "open"; + } + + } diff --git a/src/main/java/com/budwk/app/zhgh/activity/workscollection/service/ActivityWorksCollectionUploadService.java b/src/main/java/com/budwk/app/zhgh/activity/workscollection/service/ActivityWorksCollectionUploadService.java new file mode 100644 index 0000000..ece6daf --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/workscollection/service/ActivityWorksCollectionUploadService.java @@ -0,0 +1,265 @@ +package com.budwk.app.zhgh.activity.workscollection.service; + +import cn.hutool.json.JSONObject; +import com.budwk.app.base.page.Pagination; +import com.budwk.app.sys.models.Sys_file; +import com.budwk.app.sys.services.SysFileService; +import com.budwk.app.zhgh.activity.workscollection.models.Activity_works_subjectType; +import com.budwk.app.zhgh.activity.workscollection.models.Activity_works_worksType; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.result.Result; +import com.budwk.app.base.service.BaseService; +import com.budwk.app.sys.views.View_user; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.zhgh.activity.basic.models.ActivityUserScope; +import com.budwk.app.zhgh.activity.workscollection.models.Activity_works_collection; +import com.budwk.app.zhgh.activity.workscollection.models.Activity_works_collection_upload; +import com.budwk.app.zhgh.welfare.model.WelfareMemberAddress; +import org.nutz.dao.Chain; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +@IocBean +public class ActivityWorksCollectionUploadService { + + private static final String DUPLICATE_SUBMISSION = "您已提交过该活动下此主题类型和作品类型的作品,请在我的作品中编辑。"; + + @Inject + private Dao dao; + + @Inject + private SysFileService sysFileService; + + private static final String DOWNLOAD_PREFIX = "/platform/sys/file/download?id="; + + @Inject + private BaseService baseService; + + public Result pageData(PageForm pageForm, String activityId, String subjectId, String worksId) { + Sql sql = Sqls.create(""" + select + up.*, + co.NAME AS activityName, + co.cover AS activityCover, + CASE WHEN co.enable = 1 AND (co.isSubmit = 1 OR co.isSubmit IS NULL) + AND co.startDateTime <= CURRENT_TIMESTAMP(3) + AND co.endDateTime >= CURRENT_TIMESTAMP(3) + THEN 1 ELSE 0 END AS canModify, + su.typeName AS subjectName, + wo.worksTypeName AS worksName, + address.shippingAddress + from + activity_works_collection_upload up + LEFT JOIN activity_works_collection co ON up.activityId = co.id + LEFT JOIN activity_works_subjecttype su ON up.subjectId = su.id + LEFT JOIN activity_works_workstype wo ON up.worksId = wo.id + LEFT JOIN ( + SELECT userId, + CONCAT_WS(' ', CONCAT_WS('', province, city, county), addressDetail, userName, tel) AS shippingAddress, + ROW_NUMBER() OVER (PARTITION BY userId ORDER BY id) AS rn + FROM welfare_member_address + WHERE isDefault = 1 + ) address ON address.userId = up.userId AND address.rn = 1 + $condition + """); + Cnd cnd = Cnd.NEW(); + cnd.and("up.userId", "=", SecurityUtil.getUserId()); + cnd.andEX("up.activityId", "=", activityId); + cnd.andEX("up.subjectId", "=", subjectId); + cnd.andEX("up.worksId", "=", worksId); + cnd.desc("up.createdAt").desc("up.id"); + sql.setCondition(cnd); + Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + return Result.success(pagination); + } + + public WelfareMemberAddress shippingAddress(String addressId) { + if (addressId == null || addressId.isBlank()) { + return null; + } + WelfareMemberAddress address = dao.fetch(WelfareMemberAddress.class, + Cnd.where("userId", "=", SecurityUtil.getUserId()).and("id", "=", addressId)); + return address != null && address.getTel() != null && address.getTel().matches("1[3-9][0-9]{9}") + ? address : null; + } + + public void confirmShippingAddress(WelfareMemberAddress address) { + dao.update(WelfareMemberAddress.class, Chain.make("isDefault", false), + Cnd.where("userId", "=", address.getUserId()).and("id", "<>", address.getId())); + dao.update(WelfareMemberAddress.class, Chain.make("isDefault", true), + Cnd.where("userId", "=", address.getUserId()).and("id", "=", address.getId())); + } + + public Result insert(Activity_works_collection_upload upload) { + String userId = SecurityUtil.getUserId(); + String activityId = upload.getActivityId(); + Activity_works_collection activity = dao.fetch(Activity_works_collection.class, activityId); + if (activity == null) { + return Result.error("活动不存在"); + } + if (activity.getActivityGroupId() != null) { + int count = dao.count(ActivityUserScope.class, Cnd.where(ActivityUserScope::getGroupId, "=", activity.getActivityGroupId()) + .and(ActivityUserScope::getUserId, "=", userId)); + if (count == 0) { + return Result.error("您没有权限参与该活动"); + } + } + + if (!lockSubmitter(userId)) { + return Result.error("投稿用户不存在"); + } + if (dao.count(Activity_works_collection_upload.class, submissionCondition(userId, upload)) > 0) { + return Result.error(DUPLICATE_SUBMISSION); + } + + Result validation = validateWork(upload, null); + if (!validation.isSuccess()) { + return validation; + } + + View_user vwUser = dao.fetch(View_user.class, Cnd.where(View_user::getId, "=", userId)); + + upload.setUserId(userId); + upload.setUserName(SecurityUtil.getUserUsername()); + upload.setLoginName(SecurityUtil.getUserLoginname()); + upload.setUnitId(SecurityUtil.getUnitId()); + upload.setUnitName(vwUser.getUnitName()); + upload.setUnionId(SecurityUtil.getUnionId()); + upload.setUnionName(vwUser.getUnionName()); + + dao.insert(upload); + return Result.success(); + } + + public Result update(Activity_works_collection_upload upload) { + String userId = SecurityUtil.getUserId(); + if (!lockSubmitter(userId)) { + return Result.error("投稿用户不存在"); + } + Activity_works_collection_upload original = dao.fetch(Activity_works_collection_upload.class, + Cnd.where("id", "=", upload.getId()).and("userId", "=", userId)); + if (original == null) { + return Result.error("作品不存在"); + } + if (upload.getActivityId() == null) { + upload.setActivityId(original.getActivityId()); + } + boolean sameCategory = Objects.equals(original.getActivityId(), upload.getActivityId()) + && Objects.equals(original.getSubjectId(), upload.getSubjectId()) + && Objects.equals(original.getWorksId(), upload.getWorksId()); + if (!sameCategory && dao.count(Activity_works_collection_upload.class, + submissionCondition(userId, upload).and("id", "<>", original.getId())) > 0) { + return Result.error(DUPLICATE_SUBMISSION); + } + Result validation = validateWork(upload, original); + if (!validation.isSuccess()) { + return validation; + } + upload.setUserId(userId); + return dao.updateIgnoreNull(upload) > 0 ? Result.success() : Result.error("作品不存在"); + } + + private Result validateWork(Activity_works_collection_upload form, Activity_works_collection_upload original) { + Activity_works_subjectType subject = dao.fetch(Activity_works_subjectType.class, + Cnd.where("id", "=", form.getSubjectId()).and("activityId", "=", form.getActivityId())); + Activity_works_worksType worksType = dao.fetch(Activity_works_worksType.class, + Cnd.where("id", "=", form.getWorksId()).and("subjectId", "=", form.getSubjectId())); + if (subject == null || worksType == null) { + return Result.error("请选择该活动下有效的主题类型和作品类型"); + } + if (overLimit(worksType.getMaxWordCount(), form.getDescription().length())) { + return Result.error("作品描述超过该作品类型的字数限制"); + } + if (overLimit(worksType.getAllowFileNum(), form.getFiles().size())) { + return Result.error("附件数量超过该作品类型的限制"); + } + + Set existingUrls = new HashSet<>(); + if (original != null && original.getFiles() != null) { + for (JSONObject file : original.getFiles()) { + existingUrls.add(attachmentUrl(file)); + } + } + Set fileIds = new HashSet<>(); + List files = new ArrayList<>(); + long totalSizeBytes = 0; + for (JSONObject attachment : form.getFiles()) { + String url = attachmentUrl(attachment); + if (url == null || !url.startsWith(DOWNLOAD_PREFIX)) { + return Result.error("请上传有效的作品附件"); + } + String fileId = url.substring(DOWNLOAD_PREFIX.length()); + if (!fileId.matches("[a-zA-Z0-9]{26}(?:[a-zA-Z0-9]{6})?") || !fileIds.add(fileId)) { + return Result.error("作品附件无效或重复"); + } + Sys_file file = dao.fetch(Sys_file.class, fileId); + if (file == null || Boolean.TRUE.equals(file.getDelFlag()) + || !(SecurityUtil.getUserId().equals(file.getCreatedBy()) || existingUrls.contains(url))) { + return Result.error("请上传有效的作品附件"); + } + List allowedTypes = worksType.getAllowFileTypes(); + if (allowedTypes != null && !allowedTypes.isEmpty() + && allowedTypes.stream().noneMatch(type -> type.equalsIgnoreCase(file.getSuffix()))) { + return Result.error("附件格式不符合该作品类型的要求"); + } + long sizeBytes; + try { + sizeBytes = sysFileService.sizeBytes(file); + } catch (RuntimeException e) { + return Result.error("无法读取作品附件大小,请重新上传"); + } + if (sizeBytes < 0 || exceedsFileSize(worksType.getAllowSingleFileSize(), sizeBytes)) { + return Result.error("单个附件大小超过该作品类型的限制"); + } + totalSizeBytes += sizeBytes; + files.add(new JSONObject() + .set("name", file.getName()) + .set("url", url) + .set("size", sizeBytes) + .set("response", new JSONObject().set("code", 0).set("data", url))); + } + if (exceedsFileSize(worksType.getAllowTotalFileSize(), totalSizeBytes)) { + return Result.error("附件总大小超过该作品类型的限制"); + } + form.setFiles(files); + return Result.success(); + } + + private boolean exceedsFileSize(Integer limitKb, long sizeBytes) { + return limitKb != null && limitKb > 0 && sizeBytes > limitKb * 1024L; + } + + private boolean overLimit(Integer limit, long value) { + return limit != null && limit > 0 && value > limit; + } + + private String attachmentUrl(JSONObject file) { + JSONObject response = file == null ? null : file.getJSONObject("response"); + return response == null ? null : response.getStr("data"); + } + + private Cnd submissionCondition(String userId, Activity_works_collection_upload upload) { + return Cnd.where("userId", "=", userId) + .and("activityId", "=", upload.getActivityId()) + .and("subjectId", "=", upload.getSubjectId()) + .and("worksId", "=", upload.getWorksId()); + } + + private boolean lockSubmitter(String userId) { + // 在投稿事务中锁定账号行,串行处理同一用户从不同端发起的保存请求。 + Sql sql = Sqls.create("SELECT id FROM sys_user WHERE id = @userId FOR UPDATE"); + sql.setParam("userId", userId); + sql.setCallback(Sqls.callback.str()); + return dao.execute(sql).getResult() != null; + } +} diff --git a/src/main/resources/db/works_collection/works_collection.sql b/src/main/resources/db/works_collection/works_collection.sql new file mode 100644 index 0000000..d6ffcf0 --- /dev/null +++ b/src/main/resources/db/works_collection/works_collection.sql @@ -0,0 +1,4 @@ +INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, processKey, platform, moduleId, isQuickEntry) VALUES ('85bd177d04154c4c8eb57d6e6cd16893', '', '0172', '作品征集', null, 'menu', '/platform/h5/activity/worksCollection/activity', null, '/platform/sys/file/download?id=7hf45bajvmjg2on1tb6b6dhhl0', 1, 0, 'h5.activity.workscollection.upload', null, 17, 0, '17a7f8ad3ee947b4a26175049a9c253d', 1794556127700, '17a7f8ad3ee947b4a26175049a9c253d', 1794556139027, 0, null, 'H5', '543c7a3c6fde4a01a89570b4479c93f4', 0); +INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, processKey, platform, moduleId, isQuickEntry) VALUES ('9fcbf730b6a94b709b4cccec598b25a6', '91d79e0f4e464f298e7a6b37217386d3', '000900010004', '收货地址', null, 'menu', '/platform/activity/worksCollection/addressManage', null, null, 1, 0, 'activity.workscollection.addressManage', null, 22, 0, '17a7f8ad3ee947b4a26175049a9c253d', 1794557773073, '17a7f8ad3ee947b4a26175049a9c253d', 1794557773074, 0, null, 'PC', '889c6f60d1ca474494c4573f0b289c72', 0); +INSERT INTO sys_role_menu (roleId, menuId) VALUES ('7f4a820d5a394bb8a0a92d6699afe7c8', '85bd177d04154c4c8eb57d6e6cd16893'); +INSERT INTO sys_role_menu (roleId, menuId) VALUES ('7f4a820d5a394bb8a0a92d6699afe7c8', '9fcbf730b6a94b709b4cccec598b25a6'); diff --git a/src/main/resources/static/components/plugins/sysUpload/index.vue b/src/main/resources/static/components/plugins/sysUpload/index.vue index 8b32809..c5935ce 100644 --- a/src/main/resources/static/components/plugins/sysUpload/index.vue +++ b/src/main/resources/static/components/plugins/sysUpload/index.vue @@ -154,6 +154,10 @@ module.exports = { required: false }, // 接受上传的文件类型 + validate_file: { + type: Function, + default: null + }, accept: { type: String, default: "", @@ -290,6 +294,9 @@ module.exports = { // 这是兜底逻辑,保准只让这个image类型上传图片 beforeUpload(file) { + if (this.validate_file) { + return this.validate_file(file, this.fileList) + } return true // if (!this.fileAccept || typeof this.fileAccept !== "string") { @@ -546,9 +553,13 @@ module.exports = { } } - this.$message.success("获取手机文件成功") + const newFileList = [...originFileList] + for (const file of data.files) { + if (this.validate_file && !this.validate_file(file, newFileList)) return + newFileList.push(file) + } - const newFileList = originFileList.concat(data.files) + this.$message.success("获取手机文件成功") this.$emit("update:value", newFileList) }) } diff --git a/src/main/resources/views/platform/zhgh/activity/workscollection/common/info.js b/src/main/resources/views/platform/zhgh/activity/workscollection/common/info.js index 0cebe1d..ed657a9 100644 --- a/src/main/resources/views/platform/zhgh/activity/workscollection/common/info.js +++ b/src/main/resources/views/platform/zhgh/activity/workscollection/common/info.js @@ -11,6 +11,7 @@ const AU_INFO_TEMPLATE = { {{viewData.subjectName}} {{viewData.worksName}} {{viewData.description}} + {{viewData.shippingAddress || '—'}} diff --git a/src/main/resources/views/platform/zhgh/activity/workscollection/manage/index.html b/src/main/resources/views/platform/zhgh/activity/workscollection/manage/index.html index 3c79dba..814a0be 100644 --- a/src/main/resources/views/platform/zhgh/activity/workscollection/manage/index.html +++ b/src/main/resources/views/platform/zhgh/activity/workscollection/manage/index.html @@ -107,49 +107,46 @@ layout("/layouts/platform.html"){ - - - - - - - - - - - - - - - - 作品类型 -   - - - - - - - - - - - - - - - - - - +
@@ -213,7 +210,8 @@ layout("/layouts/platform.html"){ - @@ -233,17 +231,20 @@ layout("/layouts/platform.html"){ + placeholder="请输入允许上传的文件数量" + v-model="currentWorksType.allowFileNum" :precision="0"> + placeholder="请输入单个文件大小上限(KB)" + v-model="currentWorksType.allowSingleFileSize" :precision="0"> + placeholder="请输入文件总大小上限(KB)" + v-model="currentWorksType.allowTotalFileSize" :precision="0"> @@ -301,7 +302,7 @@ layout("/layouts/platform.html"){ 取消 - 确定 + 确定
@@ -325,6 +326,7 @@ layout("/layouts/platform.html"){ allowFileTypes: [], }, settingDialogVisible: false, + editingWorksType: null, colorList: ["#081776", "#31cab1", "#e54242", "#ff8939", "#ffb712", "#1dc47b", "#4495f7", "#ff5e8b", "#5d6e7f"], pageForm: { activityTime: [] @@ -354,9 +356,30 @@ layout("/layouts/platform.html"){ this.formData.subjectTypes.splice(index + 1, 0, {worksTypes: [item]}) }, openSetting(worksType) { - this.currentWorksType = worksType + this.editingWorksType = worksType + this.currentWorksType = { ...worksType, allowFileTypes: [...(worksType.allowFileTypes || [])] } this.settingDialogVisible = true }, + applyWorksTypeSettings() { + if (!this.validateFileSizeLimits(this.currentWorksType)) return + Object.keys(this.currentWorksType).forEach(key => { + this.$set(this.editingWorksType, key, this.currentWorksType[key]) + }) + this.settingDialogVisible = false + }, + validateFileSizeLimits(worksType) { + const { allowSingleFileSize, allowTotalFileSize } = worksType + if (allowSingleFileSize > 0 && allowTotalFileSize > 0 && allowTotalFileSize < allowSingleFileSize) { + const name = worksType.worksTypeName + this.$message.warning((name ? "「" + name + "」:" : "") + "总文件大小必须大于或等于单个文件大小") + return false + } + return true + }, + validateWorksTypeSettings() { + return (this.formData.subjectTypes || []).every(subject => + (subject.worksTypes || []).every(worksType => this.validateFileSizeLimits(worksType))) + }, addWorksType(type, worksIndex) { let item = {} this.initData(item) @@ -405,13 +428,16 @@ layout("/layouts/platform.html"){ this.$refs.guava.index() }, doSubmit() { + if (!this.validateWorksTypeSettings()) return this.$refs.formRef.validate((valid) => { if (valid) { this.formData.startDateTime = this.formData.activityTime[0] this.formData.endDateTime = this.formData.activityTime[1] - this.formData.nbStartDateTime = this.formData.nbTime[0] - this.formData.nbEndDateTime = this.formData.nbTime[1] + const [nbStartDateTime = null, nbEndDateTime = null] = this.formData.nbTime || [] + this.formData.nbStartDateTime = nbStartDateTime + this.formData.nbEndDateTime = nbEndDateTime this.formData.type = "1" + this.formData.isSubmit = true let loading = this.$loading({ lock: true, text: "数据正在提交中,请稍后...", @@ -432,11 +458,14 @@ layout("/layouts/platform.html"){ }) }, doSave() { + if (!this.validateWorksTypeSettings()) return this.formData.startDateTime = this.formData.activityTime[0] this.formData.endDateTime = this.formData.activityTime[1] - this.formData.nbStartDateTime = this.formData.nbTime[0] - this.formData.nbEndDateTime = this.formData.nbTime[1] + const [nbStartDateTime = null, nbEndDateTime = null] = this.formData.nbTime || [] + this.formData.nbStartDateTime = nbStartDateTime + this.formData.nbEndDateTime = nbEndDateTime this.formData.type = "1" + this.formData.isSubmit = false let loading = this.$loading({ lock: true, text: "数据正在保存中,请稍后...", diff --git a/src/main/resources/views/platform/zhgh/activity/workscollection/read/index.html b/src/main/resources/views/platform/zhgh/activity/workscollection/read/index.html index 004e805..af6aeeb 100644 --- a/src/main/resources/views/platform/zhgh/activity/workscollection/read/index.html +++ b/src/main/resources/views/platform/zhgh/activity/workscollection/read/index.html @@ -62,6 +62,9 @@ layout("/layouts/platform.html"){ + + +