Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ceec8eb095 | ||
|
|
2a305a3f23 |
@@ -19,7 +19,6 @@ RoleConstant {
|
|||||||
SCHOOL_UNION_ADMIN("校工会管理员"),
|
SCHOOL_UNION_ADMIN("校工会管理员"),
|
||||||
SCHOOL_UNION_CHAIRMAN("校工会主席"),
|
SCHOOL_UNION_CHAIRMAN("校工会主席"),
|
||||||
SCHOOL_UNION_VICE_CHAIRMAN("校工会副主席"),
|
SCHOOL_UNION_VICE_CHAIRMAN("校工会副主席"),
|
||||||
SCHOOL_UNION_FINANCE("校工会财务"),
|
|
||||||
SCHOOL_OFFICE_DIRECTOR("校工会办公室主任"),
|
SCHOOL_OFFICE_DIRECTOR("校工会办公室主任"),
|
||||||
SCHOOL_UNION_WELFARE_ADMIN("校工会福利管理员"),
|
SCHOOL_UNION_WELFARE_ADMIN("校工会福利管理员"),
|
||||||
SCHOOL_UNION_MEMBER_ADMIN("校工会会员管理员"),
|
SCHOOL_UNION_MEMBER_ADMIN("校工会会员管理员"),
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
package com.budwk.app.base.utils;
|
package com.budwk.app.base.utils;
|
||||||
|
|
||||||
import cn.hutool.core.io.FileUtil;
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import com.aspose.cells.FontConfigs;
|
||||||
import com.aspose.cells.PdfSaveOptions;
|
import com.aspose.cells.PdfSaveOptions;
|
||||||
import com.aspose.cells.Workbook;
|
import com.aspose.cells.Workbook;
|
||||||
|
import com.aspose.slides.FontsLoader;
|
||||||
|
import com.aspose.slides.LoadOptions;
|
||||||
import com.aspose.slides.Presentation;
|
import com.aspose.slides.Presentation;
|
||||||
import com.aspose.words.Document;
|
import com.aspose.words.Document;
|
||||||
|
import com.aspose.words.FontSettings;
|
||||||
|
import com.aspose.words.FontSourceBase;
|
||||||
|
import com.aspose.words.MemoryFontSource;
|
||||||
import com.aspose.words.SaveFormat;
|
import com.aspose.words.SaveFormat;
|
||||||
import com.budwk.app.base.exception.BaseException;
|
import com.budwk.app.base.exception.BaseException;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -12,6 +18,8 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文档转换
|
* 文档转换
|
||||||
@@ -19,6 +27,81 @@ import java.io.IOException;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class OfficePlusUtil {
|
public class OfficePlusUtil {
|
||||||
|
|
||||||
|
private static final String DEFAULT_FONT_NAME = "Noto Sans SC";
|
||||||
|
private static final String DEFAULT_FONT_RESOURCE = "/fonts/NotoSansSC-VF.ttf";
|
||||||
|
private static final Object FONT_CONFIG_LOCK = new Object();
|
||||||
|
private static volatile boolean fontConfigured;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册系统内置字体,并将其作为 Office 文档缺失字体或缺失字形时的默认回退字体。
|
||||||
|
* 原文档字体在服务器可用时仍优先使用,只有找不到原字体时才使用内置字体。
|
||||||
|
*/
|
||||||
|
private static void configureDefaultFont() {
|
||||||
|
if (fontConfigured) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
synchronized (FONT_CONFIG_LOCK) {
|
||||||
|
if (fontConfigured) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
byte[] fontData = loadDefaultFontData();
|
||||||
|
configureWordFont(fontData);
|
||||||
|
configureExcelFont(fontData);
|
||||||
|
FontsLoader.loadExternalFont(fontData);
|
||||||
|
fontConfigured = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从 classpath 读取随应用打包的字体,避免依赖线上服务器安装字体。
|
||||||
|
*
|
||||||
|
* @return 默认字体的二进制数据
|
||||||
|
*/
|
||||||
|
private static byte[] loadDefaultFontData() {
|
||||||
|
try (InputStream inputStream = OfficePlusUtil.class.getResourceAsStream(DEFAULT_FONT_RESOURCE)) {
|
||||||
|
if (inputStream == null) {
|
||||||
|
throw new BaseException("系统内置默认字体不存在");
|
||||||
|
}
|
||||||
|
return inputStream.readAllBytes();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("读取系统内置默认字体失败", e);
|
||||||
|
throw new BaseException("读取系统内置默认字体失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为 Word 转换保留已有字体源并追加内置字体,同时配置缺失字体和缺失字形回退。
|
||||||
|
*
|
||||||
|
* @param fontData 默认字体的二进制数据
|
||||||
|
*/
|
||||||
|
private static void configureWordFont(byte[] fontData) {
|
||||||
|
FontSettings fontSettings = FontSettings.getDefaultInstance();
|
||||||
|
FontSourceBase[] currentSources = fontSettings.getFontsSources();
|
||||||
|
FontSourceBase[] fontSources = Arrays.copyOf(currentSources, currentSources.length + 1);
|
||||||
|
fontSources[currentSources.length] = new MemoryFontSource(fontData);
|
||||||
|
fontSettings.setFontsSources(fontSources);
|
||||||
|
fontSettings.getSubstitutionSettings().getDefaultFontSubstitution().setDefaultFontName(DEFAULT_FONT_NAME);
|
||||||
|
try {
|
||||||
|
fontSettings.getFallbackSettings().loadNotoFallbackSettings();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("配置 Word 默认字体回退规则失败", e);
|
||||||
|
throw new BaseException("配置 Word 默认字体失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为 Excel 转换追加内置字体,并将其设置为找不到原字体时的默认字体。
|
||||||
|
*
|
||||||
|
* @param fontData 默认字体的二进制数据
|
||||||
|
*/
|
||||||
|
private static void configureExcelFont(byte[] fontData) {
|
||||||
|
com.aspose.cells.FontSourceBase[] currentSources = FontConfigs.getFontSources();
|
||||||
|
com.aspose.cells.FontSourceBase[] fontSources = Arrays.copyOf(currentSources, currentSources.length + 1);
|
||||||
|
fontSources[currentSources.length] = new com.aspose.cells.MemoryFontSource(fontData);
|
||||||
|
FontConfigs.setFontSources(fontSources);
|
||||||
|
FontConfigs.setDefaultFontName(DEFAULT_FONT_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换
|
* 转换
|
||||||
*
|
*
|
||||||
@@ -47,7 +130,11 @@ public class OfficePlusUtil {
|
|||||||
public static void presentationConvertPdf(String sourcePath, String targetPath) {
|
public static void presentationConvertPdf(String sourcePath, String targetPath) {
|
||||||
Presentation presentation = null;
|
Presentation presentation = null;
|
||||||
try {
|
try {
|
||||||
presentation = new Presentation(sourcePath);
|
configureDefaultFont();
|
||||||
|
LoadOptions loadOptions = new LoadOptions();
|
||||||
|
loadOptions.setDefaultRegularFont(DEFAULT_FONT_NAME);
|
||||||
|
loadOptions.setDefaultAsianFont(DEFAULT_FONT_NAME);
|
||||||
|
presentation = new Presentation(sourcePath, loadOptions);
|
||||||
presentation.save(targetPath, com.aspose.slides.SaveFormat.Pdf);
|
presentation.save(targetPath, com.aspose.slides.SaveFormat.Pdf);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.info("转换pdf报错", e);
|
log.info("转换pdf报错", e);
|
||||||
@@ -68,10 +155,12 @@ public class OfficePlusUtil {
|
|||||||
public static void excelConvertPdf(String sourcePath, String targetPath) {
|
public static void excelConvertPdf(String sourcePath, String targetPath) {
|
||||||
FileOutputStream fileOS = null;
|
FileOutputStream fileOS = null;
|
||||||
try {
|
try {
|
||||||
|
configureDefaultFont();
|
||||||
Workbook wb = new Workbook(sourcePath);
|
Workbook wb = new Workbook(sourcePath);
|
||||||
fileOS = new FileOutputStream(targetPath);
|
fileOS = new FileOutputStream(targetPath);
|
||||||
PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();
|
PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();
|
||||||
pdfSaveOptions.setOnePagePerSheet(true);
|
pdfSaveOptions.setOnePagePerSheet(true);
|
||||||
|
pdfSaveOptions.setDefaultFont(DEFAULT_FONT_NAME);
|
||||||
// for (int i = 0; i < 3; i++) {
|
// for (int i = 0; i < 3; i++) {
|
||||||
// wb.getWorksheets().get(i).getHorizontalPageBreaks().clear();
|
// wb.getWorksheets().get(i).getHorizontalPageBreaks().clear();
|
||||||
// wb.getWorksheets().get(i).getVerticalPageBreaks().clear();
|
// wb.getWorksheets().get(i).getVerticalPageBreaks().clear();
|
||||||
@@ -105,6 +194,7 @@ public class OfficePlusUtil {
|
|||||||
public static void wordConvertPdf(String sourcePath, String targetPath) {
|
public static void wordConvertPdf(String sourcePath, String targetPath) {
|
||||||
FileOutputStream os = null;
|
FileOutputStream os = null;
|
||||||
try {
|
try {
|
||||||
|
configureDefaultFont();
|
||||||
File file = new File(targetPath);
|
File file = new File(targetPath);
|
||||||
os = new FileOutputStream(file);
|
os = new FileOutputStream(file);
|
||||||
Document doc = new Document(sourcePath);
|
Document doc = new Document(sourcePath);
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
package com.budwk.app.flow.handler;
|
|
||||||
|
|
||||||
import com.budwk.app.base.constant.RoleConstant;
|
|
||||||
import com.budwk.app.flow.engine.AssignmentHandler;
|
|
||||||
import com.budwk.app.flow.engine.core.Execution;
|
|
||||||
import com.budwk.app.flow.engine.core.ServiceContext;
|
|
||||||
import com.budwk.app.flow.engine.model.TaskModel;
|
|
||||||
import org.nutz.dao.Dao;
|
|
||||||
import org.nutz.dao.Sqls;
|
|
||||||
import org.nutz.dao.sql.Sql;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 为流程任务分配拥有校工会财务角色的用户。
|
|
||||||
*/
|
|
||||||
public class FlowSchoolUnionFinanceHandler implements AssignmentHandler {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按校工会财务角色查询参与者,并去除重复的用户 ID。
|
|
||||||
*
|
|
||||||
* @param model 当前流程任务模型,无需额外传入人员参数
|
|
||||||
* @param execution 当前流程执行上下文,无需额外传入业务参数
|
|
||||||
* @return 用户 ID 列表;未配置角色或角色用户时返回空列表
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<String> assign(TaskModel model, Execution execution) {
|
|
||||||
Dao dao = ServiceContext.find(Dao.class);
|
|
||||||
Sql sql = Sqls.create("""
|
|
||||||
SELECT
|
|
||||||
userRole.userId
|
|
||||||
FROM
|
|
||||||
`sys_user_role` userRole
|
|
||||||
LEFT JOIN sys_role role ON role.id = userRole.roleId
|
|
||||||
WHERE
|
|
||||||
role.`code` = @roleCode
|
|
||||||
GROUP BY
|
|
||||||
userRole.userId
|
|
||||||
""").setParam("roleCode", RoleConstant.SCHOOL_UNION_FINANCE.name());
|
|
||||||
sql.setCallback(Sqls.callback.strList());
|
|
||||||
dao.execute(sql);
|
|
||||||
return sql.getList(String.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回流程设计器中展示的参与者处理类名称。
|
|
||||||
*
|
|
||||||
* @return 流程设计器下拉选项名称
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getMessage() {
|
|
||||||
return "获取校工会财务";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+94
-21
@@ -4,12 +4,14 @@ package com.budwk.app.zhgh.activity.sports.service.impl;
|
|||||||
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
||||||
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||||
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
||||||
|
import com.budwk.app.base.exception.BaseException;
|
||||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||||
import com.budwk.app.base.utils.CommonDownloadUtil;
|
import com.budwk.app.base.utils.CommonDownloadUtil;
|
||||||
import com.budwk.app.base.utils.DateUtil;
|
import com.budwk.app.base.utils.DateUtil;
|
||||||
import com.budwk.app.sys.models.Sys_home_activity;
|
import com.budwk.app.sys.models.Sys_home_activity;
|
||||||
import com.budwk.app.sys.models.Sys_home_template;
|
import com.budwk.app.sys.models.Sys_home_template;
|
||||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||||
|
import com.budwk.app.zhgh.activity.basic.models.ActivityEvent;
|
||||||
import com.budwk.app.zhgh.activity.basic.models.ActivityBasicUnit;
|
import com.budwk.app.zhgh.activity.basic.models.ActivityBasicUnit;
|
||||||
import com.budwk.app.zhgh.activity.basic.models.ActivityBasicUnion;
|
import com.budwk.app.zhgh.activity.basic.models.ActivityBasicUnion;
|
||||||
import com.budwk.app.zhgh.activity.culture.models.ActivityTissue;
|
import com.budwk.app.zhgh.activity.culture.models.ActivityTissue;
|
||||||
@@ -28,6 +30,7 @@ import org.nutz.dao.entity.Record;
|
|||||||
import org.nutz.dao.sql.Sql;
|
import org.nutz.dao.sql.Sql;
|
||||||
import org.nutz.ioc.aop.Aop;
|
import org.nutz.ioc.aop.Aop;
|
||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.json.Json;
|
||||||
import org.nutz.lang.Lang;
|
import org.nutz.lang.Lang;
|
||||||
import org.nutz.lang.Strings;
|
import org.nutz.lang.Strings;
|
||||||
|
|
||||||
@@ -55,6 +58,7 @@ public class ActivitySportsServiceImpl extends BaseServiceImpl<ActivitySchool> i
|
|||||||
@Override
|
@Override
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public String doAdd(ActivitySchool activitySchool, ActivitySchoolEvent[] events) {
|
public String doAdd(ActivitySchool activitySchool, ActivitySchoolEvent[] events) {
|
||||||
|
events = validateAndApplySingleEventLimits(events);
|
||||||
ActivityBasicUnit activityBasicUnit = dao().fetch(ActivityBasicUnit.class, Cnd.where("id", "=", SecurityUtil.getUserId()));
|
ActivityBasicUnit activityBasicUnit = dao().fetch(ActivityBasicUnit.class, Cnd.where("id", "=", SecurityUtil.getUserId()));
|
||||||
|
|
||||||
if (activitySchool.getActivityLevel() == 40002) {
|
if (activitySchool.getActivityLevel() == 40002) {
|
||||||
@@ -101,6 +105,7 @@ public class ActivitySportsServiceImpl extends BaseServiceImpl<ActivitySchool> i
|
|||||||
@Override
|
@Override
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public void doEdit(ActivitySchool activitySchool, ActivitySchoolEvent[] events) {
|
public void doEdit(ActivitySchool activitySchool, ActivitySchoolEvent[] events) {
|
||||||
|
events = validateAndApplySingleEventLimits(events);
|
||||||
ActivitySchool school = dao().fetch(ActivitySchool.class, activitySchool.getId());
|
ActivitySchool school = dao().fetch(ActivitySchool.class, activitySchool.getId());
|
||||||
if (school.getActivityLevel() == 40002) {
|
if (school.getActivityLevel() == 40002) {
|
||||||
school.setBelongUnionId(SecurityUtil.getUnionId());
|
school.setBelongUnionId(SecurityUtil.getUnionId());
|
||||||
@@ -161,6 +166,56 @@ public class ActivitySportsServiceImpl extends BaseServiceImpl<ActivitySchool> i
|
|||||||
dao().insertOrUpdate(sysHomeActivity);
|
dao().insertOrUpdate(sysHomeActivity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验单项人数限制,并在具体单项未设置限制时应用“所有单项”的默认值。
|
||||||
|
*
|
||||||
|
* @param events 页面提交的项目配置,允许包含 eventId 为 allItems 的默认配置
|
||||||
|
* @return 已移除 allItems 临时配置、可直接持久化的项目配置数组
|
||||||
|
*/
|
||||||
|
private ActivitySchoolEvent[] validateAndApplySingleEventLimits(ActivitySchoolEvent[] events) {
|
||||||
|
if (events == null || events.length == 0) {
|
||||||
|
return new ActivitySchoolEvent[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
ActivitySchoolEvent allItems = Arrays.stream(events)
|
||||||
|
.filter(event -> event != null && "allItems".equals(event.getEventId()))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
List<ActivitySchoolEvent> result = new ArrayList<>();
|
||||||
|
for (ActivitySchoolEvent event : events) {
|
||||||
|
if (event == null || "allItems".equals(event.getEventId())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ActivityEvent activityEvent = dao().fetch(ActivityEvent.class, event.getEventId());
|
||||||
|
if (activityEvent != null && "1".equals(activityEvent.getProjectType())) {
|
||||||
|
applySingleEventDefaultLimit(event, allItems);
|
||||||
|
}
|
||||||
|
result.add(event);
|
||||||
|
}
|
||||||
|
return result.toArray(new ActivitySchoolEvent[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单项的两个限制必须同时设置;均未设置或均为0时继承“所有单项”的对应值。
|
||||||
|
*/
|
||||||
|
private void applySingleEventDefaultLimit(ActivitySchoolEvent event, ActivitySchoolEvent allItems) {
|
||||||
|
Integer athletesMaxNum = event.getAthletesMaxNum();
|
||||||
|
Integer restrictRegNumber = event.getRestrictRegNumber();
|
||||||
|
if ((athletesMaxNum == null) != (restrictRegNumber == null)) {
|
||||||
|
throw new BaseException("每队(项)运动员最多人数和每人限报项目必须同时设置");
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean useDefault = athletesMaxNum == null || (athletesMaxNum == 0 && restrictRegNumber == 0);
|
||||||
|
if (!useDefault) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (allItems == null || allItems.getAthletesMaxNum() == null || allItems.getRestrictRegNumber() == null) {
|
||||||
|
throw new BaseException("请先设置所有单项的运动员最多人数和每人限报项目");
|
||||||
|
}
|
||||||
|
event.setAthletesMaxNum(allItems.getAthletesMaxNum());
|
||||||
|
event.setRestrictRegNumber(allItems.getRestrictRegNumber());
|
||||||
|
}
|
||||||
|
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
private void addTeam(String schoolId, ActivitySchoolEvent[] events) {
|
private void addTeam(String schoolId, ActivitySchoolEvent[] events) {
|
||||||
if (events.length > 0) {
|
if (events.length > 0) {
|
||||||
@@ -271,33 +326,19 @@ public class ActivitySportsServiceImpl extends BaseServiceImpl<ActivitySchool> i
|
|||||||
WHERE
|
WHERE
|
||||||
app.activityId = @id
|
app.activityId = @id
|
||||||
and app.status = 2
|
and app.status = 2
|
||||||
$cnd
|
and (@filterUnion = 0 or app.activityUnionId = @unionId)
|
||||||
ORDER BY
|
ORDER BY
|
||||||
ev.allName DESC,
|
ev.allName DESC,
|
||||||
u.unionname DESC,
|
u.unionname DESC,
|
||||||
app.`team` asc
|
app.`team` asc
|
||||||
""").setParam("id", id)
|
""").setParam("id", id);
|
||||||
.setVar("cnd", "");
|
// 参数必须声明在原始SQL中;setVar追加的字符串不会再次解析其中的@参数。
|
||||||
if (Strings.isNotBlank(unionId)) {
|
// 未选择分工会时导出整个活动,选择时按报名记录中的活动分工会过滤。
|
||||||
sql.setVar("cnd", "and u.unionid = @unionId");
|
sql.setParam("filterUnion", Strings.isNotBlank(unionId) ? 1 : 0);
|
||||||
sql.setParam("unionId", unionId);
|
sql.setParam("unionId", Strings.isNotBlank(unionId) ? unionId : "");
|
||||||
}
|
|
||||||
List<Record> list = list(sql);
|
List<Record> list = list(sql);
|
||||||
String activityName;
|
|
||||||
if (Lang.isNotEmpty(list)) {
|
|
||||||
activityName = list.get(0).getString("activityName");
|
|
||||||
} else {
|
|
||||||
activityName = "暂无人员";
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ActivitySchoolApply> excels = new ArrayList<>();
|
List<ActivitySchoolApply> excels = new ArrayList<>();
|
||||||
|
list.forEach(record -> excels.add(toActivitySchoolApplyExport(record)));
|
||||||
list.forEach(z -> {
|
|
||||||
ActivitySchoolApply schoolApply = z.toPojo(ActivitySchoolApply.class);
|
|
||||||
String s = schoolApply.getIdentity().stream().map(personType::getName).toList().toString();
|
|
||||||
schoolApply.setSf(s);
|
|
||||||
excels.add(schoolApply);
|
|
||||||
});
|
|
||||||
|
|
||||||
ExportParams exportParams = new ExportParams();
|
ExportParams exportParams = new ExportParams();
|
||||||
exportParams.setType(ExcelType.XSSF);
|
exportParams.setType(ExcelType.XSSF);
|
||||||
@@ -305,10 +346,42 @@ public class ActivitySportsServiceImpl extends BaseServiceImpl<ActivitySchool> i
|
|||||||
CommonDownloadUtil.download(getUnionApplyExportFileName(unionId), workbook, response);
|
CommonDownloadUtil.download(getUnionApplyExportFileName(unionId), workbook, response);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
throw new BaseException("导出报名信息失败:" + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将原生SQL查询结果转换为报名信息导出对象。
|
||||||
|
* identity 是数据库JSON文本,需要显式转换为身份编码集合,避免 Record.toPojo 自动转换失败导致整表无数据。
|
||||||
|
*
|
||||||
|
* @param record 导出SQL返回的一行报名数据
|
||||||
|
* @return EasyPoi 使用的 ActivitySchoolApply 导出对象
|
||||||
|
*/
|
||||||
|
private ActivitySchoolApply toActivitySchoolApplyExport(Record record) {
|
||||||
|
ActivitySchoolApply schoolApply = new ActivitySchoolApply();
|
||||||
|
schoolApply.setUnionname(record.getString("unionname"));
|
||||||
|
schoolApply.setTeam(record.getString("team"));
|
||||||
|
schoolApply.setAllName(record.getString("allName"));
|
||||||
|
schoolApply.setLoginname(record.getString("loginname"));
|
||||||
|
schoolApply.setUsername(record.getString("username"));
|
||||||
|
schoolApply.setMobile(record.getString("mobile"));
|
||||||
|
schoolApply.setIdCard(record.getString("idCard"));
|
||||||
|
schoolApply.setProfessionalLevel(record.getString("professionalLevel"));
|
||||||
|
schoolApply.setSex(record.getString("sex"));
|
||||||
|
|
||||||
|
String identityJson = record.getString("identity");
|
||||||
|
List<String> identities = Strings.isBlank(identityJson)
|
||||||
|
? new ArrayList<>()
|
||||||
|
: Json.fromJsonAsList(String.class, identityJson);
|
||||||
|
String identityName = identities.stream()
|
||||||
|
.map(personType::getName)
|
||||||
|
.filter(Strings::isNotBlank)
|
||||||
|
.collect(Collectors.joining("、"));
|
||||||
|
schoolApply.setSf(identityName);
|
||||||
|
return schoolApply;
|
||||||
|
}
|
||||||
|
|
||||||
private String getUnionApplyExportFileName(String unionId) {
|
private String getUnionApplyExportFileName(String unionId) {
|
||||||
String unionName = "分工会";
|
String unionName = "分工会";
|
||||||
if (Strings.isNotBlank(unionId)) {
|
if (Strings.isNotBlank(unionId)) {
|
||||||
|
|||||||
+13
-5
@@ -17,7 +17,6 @@ import com.budwk.app.flow.enums.ProcessInstanceStateEnum;
|
|||||||
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
|
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
|
||||||
import com.budwk.app.flow.service.FlowCommonService;
|
import com.budwk.app.flow.service.FlowCommonService;
|
||||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||||
import com.budwk.app.zhgh.club.model.ClubUser;
|
|
||||||
import com.budwk.app.zhgh.club.model.SysClub;
|
import com.budwk.app.zhgh.club.model.SysClub;
|
||||||
import com.budwk.app.zhgh.club.model.SysClubExamineRegister;
|
import com.budwk.app.zhgh.club.model.SysClubExamineRegister;
|
||||||
import com.budwk.app.zhgh.club.service.SysClubExamineService;
|
import com.budwk.app.zhgh.club.service.SysClubExamineService;
|
||||||
@@ -119,10 +118,7 @@ public class ClubExamineApplyController {
|
|||||||
if(StrUtil.isBlank(clubId)) {
|
if(StrUtil.isBlank(clubId)) {
|
||||||
return Result.error("社团信息为空,请核查");
|
return Result.error("社团信息为空,请核查");
|
||||||
}
|
}
|
||||||
int count = dao.count(ClubUser.class, Cnd.where("clubId", "=", clubId));
|
return Result.success(sysClubExamineService.getClubMemberMoney(clubId));
|
||||||
SysClub club = dao.fetch(SysClub.class, clubId);
|
|
||||||
int money = count * (club.getDue() != null ? Integer.parseInt(club.getDue()) : 0);
|
|
||||||
return Result.success(money);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@@ -175,6 +171,10 @@ public class ClubExamineApplyController {
|
|||||||
public Result save(@Param("data") SysClubExamineRegister examineRegister,
|
public Result save(@Param("data") SysClubExamineRegister examineRegister,
|
||||||
@Param("incomeDetailed") String incomeDetailed,
|
@Param("incomeDetailed") String incomeDetailed,
|
||||||
@Param("incomeCensus") String incomeCensus) {
|
@Param("incomeCensus") String incomeCensus) {
|
||||||
|
String validateMessage = sysClubExamineService.validateActivityRequired(examineRegister);
|
||||||
|
if (validateMessage != null) {
|
||||||
|
return Result.error(validateMessage);
|
||||||
|
}
|
||||||
if (StrUtil.isBlank(examineRegister.getId())) {
|
if (StrUtil.isBlank(examineRegister.getId())) {
|
||||||
sysClubExamineService.doAdd(examineRegister, incomeDetailed, incomeCensus);
|
sysClubExamineService.doAdd(examineRegister, incomeDetailed, incomeCensus);
|
||||||
} else {
|
} else {
|
||||||
@@ -190,6 +190,10 @@ public class ClubExamineApplyController {
|
|||||||
public Result submit(@Param("data") SysClubExamineRegister examineRegister,
|
public Result submit(@Param("data") SysClubExamineRegister examineRegister,
|
||||||
@Param("incomeDetailed") String incomeDetailed,
|
@Param("incomeDetailed") String incomeDetailed,
|
||||||
@Param("incomeCensus") String incomeCensus) {
|
@Param("incomeCensus") String incomeCensus) {
|
||||||
|
String validateMessage = sysClubExamineService.validateActivityRequired(examineRegister);
|
||||||
|
if (validateMessage != null) {
|
||||||
|
return Result.error(validateMessage);
|
||||||
|
}
|
||||||
SysClubExamineRegister reg;
|
SysClubExamineRegister reg;
|
||||||
if (StrUtil.isBlank(examineRegister.getId())) {
|
if (StrUtil.isBlank(examineRegister.getId())) {
|
||||||
reg = sysClubExamineService.doAdd(examineRegister, incomeDetailed, incomeCensus);
|
reg = sysClubExamineService.doAdd(examineRegister, incomeDetailed, incomeCensus);
|
||||||
@@ -221,6 +225,10 @@ public class ClubExamineApplyController {
|
|||||||
@Param("incomeDetailed") String incomeDetailed,
|
@Param("incomeDetailed") String incomeDetailed,
|
||||||
@Param("incomeCensus") String incomeCensus,
|
@Param("incomeCensus") String incomeCensus,
|
||||||
@Param("taskId") Long taskId) {
|
@Param("taskId") Long taskId) {
|
||||||
|
String validateMessage = sysClubExamineService.validateActivityRequired(examineRegister);
|
||||||
|
if (validateMessage != null) {
|
||||||
|
return Result.error(validateMessage);
|
||||||
|
}
|
||||||
if (StrUtil.isBlank(examineRegister.getId())) {
|
if (StrUtil.isBlank(examineRegister.getId())) {
|
||||||
sysClubExamineService.doAdd(examineRegister, incomeDetailed, incomeCensus);
|
sysClubExamineService.doAdd(examineRegister, incomeDetailed, incomeCensus);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+1
-1
@@ -86,7 +86,7 @@ public class ClubExamineMineController {
|
|||||||
//nutMap.setv("schoolName", Globals.MyConfig.getString("AppName"));
|
//nutMap.setv("schoolName", Globals.MyConfig.getString("AppName"));
|
||||||
nutMap.setv("clubName", register.getClubName());
|
nutMap.setv("clubName", register.getClubName());
|
||||||
nutMap.setv("create_time", register.getFoundTime());
|
nutMap.setv("create_time", register.getFoundTime());
|
||||||
nutMap.setv("dues_standard", register.getDue());
|
nutMap.setv("dues_standard", register.getDue() == null ? "--" : register.getDue() + "元/年");
|
||||||
// 生成材料中的年度与列表展示的登记年度保持一致。
|
// 生成材料中的年度与列表展示的登记年度保持一致。
|
||||||
nutMap.setv("year", register.getYear());
|
nutMap.setv("year", register.getYear());
|
||||||
nutMap.setv("registerDate", register.getRegisterDate());
|
nutMap.setv("registerDate", register.getRegisterDate());
|
||||||
|
|||||||
@@ -91,8 +91,8 @@ public class SysClub extends BaseModel {
|
|||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("会费标准")
|
@Comment("会费标准")
|
||||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
@ColDefine(type = ColType.DOUBLE, width = 10, precision = 2)
|
||||||
private String due;
|
private Double due;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("附件")
|
@Comment("附件")
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ public class SysClubExamineRegister extends BaseModel {
|
|||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("会费标准")
|
@Comment("会费标准")
|
||||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
@ColDefine(type = ColType.DOUBLE, width = 10, precision = 2)
|
||||||
private String due;
|
private Double due;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("年度活动情况")
|
@Comment("年度活动情况")
|
||||||
|
|||||||
@@ -24,6 +24,21 @@ public interface SysClubExamineService extends BaseService<SysClubExamineRegiste
|
|||||||
|
|
||||||
List<NutMap> getJgUser(@Valid String clubId);
|
List<NutMap> getJgUser(@Valid String clubId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算指定社团的年度会费收入。
|
||||||
|
*
|
||||||
|
* @param clubId 社团ID,用于查询当前会员数量和社团会费标准
|
||||||
|
* @return 会员数量乘以会费标准后的金额;社团或会费标准为空时返回0
|
||||||
|
*/
|
||||||
|
Double getClubMemberMoney(@Valid String clubId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验考核登记的两组活动明细。
|
||||||
|
* @param examineRegister 页面data参数对应的登记实体,yearActivityList为本年度活动,plans为下一年度计划
|
||||||
|
* @return String类型;通过返回null,否则返回缺失的明细行号及字段提示
|
||||||
|
*/
|
||||||
|
String validateActivityRequired(SysClubExamineRegister examineRegister);
|
||||||
|
|
||||||
SysClubExamineRegister doAdd(SysClubExamineRegister examineRegister, String incomeDetailed, String incomeCensus);
|
SysClubExamineRegister doAdd(SysClubExamineRegister examineRegister, String incomeDetailed, String incomeCensus);
|
||||||
|
|
||||||
SysClubExamineRegister doEdit(SysClubExamineRegister examineRegister, String incomeDetailed, String incomeCensus);
|
SysClubExamineRegister doEdit(SysClubExamineRegister examineRegister, String incomeDetailed, String incomeCensus);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import com.budwk.app.flow.enums.ProcessInstanceStateEnum;
|
|||||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||||
|
import com.budwk.app.zhgh.club.model.ClubUser;
|
||||||
import com.budwk.app.zhgh.club.model.SysClub;
|
import com.budwk.app.zhgh.club.model.SysClub;
|
||||||
import com.budwk.app.zhgh.club.model.SysClubExamineRegister;
|
import com.budwk.app.zhgh.club.model.SysClubExamineRegister;
|
||||||
import com.budwk.app.zhgh.club.model.SysClubExamineRegisterDetailed;
|
import com.budwk.app.zhgh.club.model.SysClubExamineRegisterDetailed;
|
||||||
@@ -50,6 +51,15 @@ public class SysClubExamineServiceImpl extends BaseServiceImpl<SysClubExamineReg
|
|||||||
super(dao);
|
super(dao);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Double getClubMemberMoney(String clubId) {
|
||||||
|
int memberCount = dao().count(ClubUser.class, Cnd.where(ClubUser::getClubId, "=", clubId));
|
||||||
|
SysClub club = dao().fetch(SysClub.class, clubId);
|
||||||
|
// 社团或会费标准为空时按0计算,保证考核登记初始化能够正常完成。
|
||||||
|
Double due = club == null || club.getDue() == null ? 0D : club.getDue();
|
||||||
|
return memberCount * due;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<NutMap> getClubUserNum(String clubId, Integer year) {
|
public List<NutMap> getClubUserNum(String clubId, Integer year) {
|
||||||
Date yearStart = DateUtil.parse(year + "-01-01 00:00:00");
|
Date yearStart = DateUtil.parse(year + "-01-01 00:00:00");
|
||||||
@@ -345,6 +355,40 @@ public class SysClubExamineServiceImpl extends BaseServiceImpl<SysClubExamineReg
|
|||||||
return listMap;
|
return listMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 两组明细均至少填写一条;本年度主办单位和获奖情况保持选填。
|
||||||
|
* @param examineRegister data参数绑定的登记实体,包含yearActivityList和plans两组JSON明细
|
||||||
|
* @return 校验通过返回null,否则返回首个缺失字段的行号和名称
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String validateActivityRequired(SysClubExamineRegister examineRegister) {
|
||||||
|
if (examineRegister == null) {
|
||||||
|
return "考核登记信息不能为空";
|
||||||
|
}
|
||||||
|
String message = validateActivityRows(examineRegister.getYearActivityList(), "本年度活动开展情况",
|
||||||
|
new String[]{"activityTime", "activityName", "activityAddress", "joinNum"},
|
||||||
|
new String[]{"活动时间", "活动主题/赛事名称", "活动地点", "参加人数"});
|
||||||
|
return message != null ? message : validateActivityRows(examineRegister.getPlans(), "下一年度活动计划",
|
||||||
|
new String[]{"activityName", "activityUnit", "activityAddress"},
|
||||||
|
new String[]{"活动主题/赛事名称", "活动/赛事主办单位", "活动地点"});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 检查空列表、空行及纯空白字段;数值0按已填写处理,不扩大为人数范围校验。 */
|
||||||
|
private String validateActivityRows(List<JSONObject> rows, String label, String[] fields, String[] names) {
|
||||||
|
if (rows == null || rows.isEmpty()) {
|
||||||
|
return label + "至少填写一条";
|
||||||
|
}
|
||||||
|
for (int i = 0; i < rows.size(); i++) {
|
||||||
|
JSONObject row = rows.get(i);
|
||||||
|
for (int j = 0; j < fields.length; j++) {
|
||||||
|
if (row == null || StrUtil.isBlank(row.getStr(fields[j]))) {
|
||||||
|
return label + "第" + (i + 1) + "条:" + names[j] + "不能为空";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SysClubExamineRegister doAdd(SysClubExamineRegister examineRegister, String incomeDetailed, String incomeCensus) {
|
public SysClubExamineRegister doAdd(SysClubExamineRegister examineRegister, String incomeDetailed, String incomeCensus) {
|
||||||
// JSON转换为实体列表(空值判断避免转换异常)
|
// JSON转换为实体列表(空值判断避免转换异常)
|
||||||
|
|||||||
+3
-7
@@ -229,18 +229,14 @@ public class ProposalMineController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除当前用户可删除的提案。
|
|
||||||
*
|
|
||||||
* @param id 提案 ID;仅允许删除本人未发起流程或退回发起节点的提案
|
|
||||||
* @return Result,成功时返回成功结果,不满足删除条件时返回原因
|
|
||||||
*/
|
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission("proposal.mine")
|
@SaCheckPermission("proposal.mine")
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
@SLog(tag = "提案管理系统-我的提案", msg = "删除提案")
|
@SLog(tag = "提案管理系统-我的提案", msg = "删除提案")
|
||||||
public Result delete(@Valid String id) {
|
public Result delete(@Valid String id) {
|
||||||
return proposalCommonService.deleteMine(id, SecurityUtil.getUserId());
|
dao.delete(ProposalInfo.class, id);
|
||||||
|
flowEngine.processInstanceService().deleteProcessInstanceByBusinessKey(id);
|
||||||
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
|
|||||||
-10
@@ -3,7 +3,6 @@ package com.budwk.app.zhgh.democratic.proposal.service.common;
|
|||||||
import com.budwk.app.base.service.BaseService;
|
import com.budwk.app.base.service.BaseService;
|
||||||
import com.budwk.app.base.param.PageForm;
|
import com.budwk.app.base.param.PageForm;
|
||||||
import com.budwk.app.base.param.ExportTableColumns;
|
import com.budwk.app.base.param.ExportTableColumns;
|
||||||
import com.budwk.app.base.result.Result;
|
|
||||||
import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo;
|
import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo;
|
||||||
import com.budwk.app.zhgh.democratic.proposal.models.ProposalUndertake;
|
import com.budwk.app.zhgh.democratic.proposal.models.ProposalUndertake;
|
||||||
import com.budwk.app.zhgh.democratic.proposal.param.ProposalQueryComprehensiveParam;
|
import com.budwk.app.zhgh.democratic.proposal.param.ProposalQueryComprehensiveParam;
|
||||||
@@ -20,15 +19,6 @@ import java.util.Set;
|
|||||||
|
|
||||||
public interface ProposalCommonService extends BaseService<ProposalInfo> {
|
public interface ProposalCommonService extends BaseService<ProposalInfo> {
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除当前用户尚未发起流程或已退回发起节点的提案。
|
|
||||||
*
|
|
||||||
* @param id 待删除的提案 ID
|
|
||||||
* @param userId 当前登录用户 ID,用于核对提案创建人
|
|
||||||
* @return Result,删除成功返回 success;提案不存在、非本人或流程不允许删除时返回错误信息
|
|
||||||
*/
|
|
||||||
Result deleteMine(String id, String userId);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按页面允许的字段白名单添加排序条件,避免前端字段直接进入SQL。
|
* 按页面允许的字段白名单添加排序条件,避免前端字段直接进入SQL。
|
||||||
*
|
*
|
||||||
|
|||||||
-42
@@ -17,7 +17,6 @@ import com.budwk.app.base.exception.BaseException;
|
|||||||
import com.budwk.app.base.param.ExportTableColumns;
|
import com.budwk.app.base.param.ExportTableColumns;
|
||||||
import com.budwk.app.base.param.PageForm;
|
import com.budwk.app.base.param.PageForm;
|
||||||
import com.budwk.app.base.page.Pagination;
|
import com.budwk.app.base.page.Pagination;
|
||||||
import com.budwk.app.base.result.Result;
|
|
||||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||||
import com.budwk.app.base.utils.CommonDownloadUtil;
|
import com.budwk.app.base.utils.CommonDownloadUtil;
|
||||||
import com.budwk.app.base.utils.PageUtil;
|
import com.budwk.app.base.utils.PageUtil;
|
||||||
@@ -53,7 +52,6 @@ import com.deepoove.poi.config.Configure;
|
|||||||
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
|
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.ddr.poi.html.HtmlRenderPolicy;
|
import org.ddr.poi.html.HtmlRenderPolicy;
|
||||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
|
||||||
import org.nutz.dao.Cnd;
|
import org.nutz.dao.Cnd;
|
||||||
import org.nutz.dao.Dao;
|
import org.nutz.dao.Dao;
|
||||||
import org.nutz.dao.FieldFilter;
|
import org.nutz.dao.FieldFilter;
|
||||||
@@ -64,7 +62,6 @@ import org.nutz.dao.util.cri.SqlExpressionGroup;
|
|||||||
import org.nutz.dao.util.cri.Static;
|
import org.nutz.dao.util.cri.Static;
|
||||||
import org.nutz.ioc.loader.annotation.Inject;
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
import org.nutz.ioc.aop.Aop;
|
|
||||||
import org.nutz.json.Json;
|
import org.nutz.json.Json;
|
||||||
import org.nutz.lang.Lang;
|
import org.nutz.lang.Lang;
|
||||||
import org.nutz.lang.Strings;
|
import org.nutz.lang.Strings;
|
||||||
@@ -187,45 +184,6 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl<ProposalInfo> imp
|
|||||||
super(dao);
|
super(dao);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 仅允许创建人删除草稿或退回发起节点的提案,并清理其 WF 流程。
|
|
||||||
*
|
|
||||||
* @param id 待删除的提案 ID
|
|
||||||
* @param userId 当前登录用户 ID,用于核对提案创建人
|
|
||||||
* @return Result,删除成功返回 success;提案不存在、非本人或流程不允许删除时返回错误信息
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
|
||||||
public Result deleteMine(String id, String userId) {
|
|
||||||
if (StrUtil.isBlank(id) || StrUtil.isBlank(userId)) {
|
|
||||||
return Result.error("提案不存在或无权删除");
|
|
||||||
}
|
|
||||||
ProposalInfo proposal = dao().fetch(ProposalInfo.class, id);
|
|
||||||
if (proposal == null || !Objects.equals(proposal.getCreatedBy(), userId)) {
|
|
||||||
return Result.error("提案不存在或无权删除");
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ProcessInstance> instances = dao().query(ProcessInstance.class,
|
|
||||||
Cnd.where(ProcessInstance::getBusinessNo, "=", id));
|
|
||||||
// 一个提案出现多个流程实例时无法安全判断当前节点,拒绝删除并保留数据。
|
|
||||||
if (instances.size() > 1) {
|
|
||||||
return Result.error("提案流程数据异常,无法删除");
|
|
||||||
}
|
|
||||||
if (!instances.isEmpty()) {
|
|
||||||
ProcessInstance instance = instances.get(0);
|
|
||||||
List<ProcessTask> tasks = flowEngine.processTaskService().getDoingTaskList(instance.getId(), null);
|
|
||||||
// 存在并行任务时,只有所有活动任务均位于发起节点才允许删除。
|
|
||||||
if (!Objects.equals(instance.getState(), ProcessInstanceStateEnum.DOING.getCode())
|
|
||||||
|| tasks.isEmpty() || tasks.stream().anyMatch(task -> !Objects.equals(task.getTaskName(), "startTask"))) {
|
|
||||||
return Result.error("仅未提交或退回发起节点的提案可以删除");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dao().delete(ProposalInfo.class, id);
|
|
||||||
flowEngine.processInstanceService().deleteProcessInstanceByBusinessKey(id);
|
|
||||||
return Result.success();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页查询提案综合列表。
|
* 分页查询提案综合列表。
|
||||||
* 普通查询不关联历史任务表;仅在 origins 包含 answer 且 commonKeyword 非空时,
|
* 普通查询不关联历史任务表;仅在 origins 包含 answer 且 commonKeyword 非空时,
|
||||||
|
|||||||
+2
-2
@@ -101,7 +101,7 @@ public class TeacherCongressInstitutionUserServiceImpl extends BaseServiceImpl<T
|
|||||||
if (identity.equals("主任")) {
|
if (identity.equals("主任")) {
|
||||||
sysRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_PREPARATION_LEADERSHIP_GROUP_DIRECTOR);
|
sysRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_PREPARATION_LEADERSHIP_GROUP_DIRECTOR);
|
||||||
|
|
||||||
} else if (identity.equals("委员")) {
|
} else if (identity.equals("成员")) {
|
||||||
sysRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_PREPARATION_LEADERSHIP_GROUP_MEMBER);
|
sysRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_PREPARATION_LEADERSHIP_GROUP_MEMBER);
|
||||||
}
|
}
|
||||||
if (sysRole == null) {
|
if (sysRole == null) {
|
||||||
@@ -148,7 +148,7 @@ public class TeacherCongressInstitutionUserServiceImpl extends BaseServiceImpl<T
|
|||||||
if (institutionUser.getIdentity().equals("主任")) {
|
if (institutionUser.getIdentity().equals("主任")) {
|
||||||
sysRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_PREPARATION_LEADERSHIP_GROUP_DIRECTOR);
|
sysRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_PREPARATION_LEADERSHIP_GROUP_DIRECTOR);
|
||||||
|
|
||||||
} else if (institutionUser.getIdentity().equals("委员")) {
|
} else if (institutionUser.getIdentity().equals("成员")) {
|
||||||
sysRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_PREPARATION_LEADERSHIP_GROUP_MEMBER);
|
sysRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_PREPARATION_LEADERSHIP_GROUP_MEMBER);
|
||||||
}
|
}
|
||||||
if (sysRole == null) {
|
if (sysRole == null) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ nutz:
|
|||||||
ignore: ^(.+[.])(jsp|png|gif|jpg|js|css|jspx|jpeg|html|mp3|mp4|ico|svg|vue)$
|
ignore: ^(.+[.])(jsp|png|gif|jpg|js|css|jspx|jpeg|html|mp3|mp4|ico|svg|vue)$
|
||||||
exclusions: /favicon/*,/assets/*,/druid/*,/upload/*,/components/*
|
exclusions: /favicon/*,/assets/*,/druid/*,/upload/*,/components/*
|
||||||
server:
|
server:
|
||||||
port: 80
|
port: 8081
|
||||||
host: 0.0.0.0
|
host: 0.0.0.0
|
||||||
|
|
||||||
jetty:
|
jetty:
|
||||||
@@ -21,7 +21,7 @@ jetty:
|
|||||||
#结合ftp使用,或用nginx代理ftp路径
|
#结合ftp使用,或用nginx代理ftp路径
|
||||||
#staticPath: /Users/wizzer/temp/files
|
#staticPath: /Users/wizzer/temp/files
|
||||||
#开发模式静态资源
|
#开发模式静态资源
|
||||||
staticPathLocal: E:/projects/zhgh_cqgmy/src/main/resources/static
|
staticPathLocal: D:/myProject/zhgh_cqgmy/src/main/resources/static
|
||||||
|
|
||||||
security:
|
security:
|
||||||
tokenName: saToken
|
tokenName: saToken
|
||||||
@@ -87,7 +87,7 @@ xsssql:
|
|||||||
beetl:
|
beetl:
|
||||||
RESOURCE:
|
RESOURCE:
|
||||||
#本地路径,开发时设置本地路径,便于调试
|
#本地路径,开发时设置本地路径,便于调试
|
||||||
rootLocal: E:/projects/zhgh_cqgmy/src/main/resources/views/
|
rootLocal: D:/myProject/zhgh_cqgmy/src/main/resources/views/
|
||||||
root: views/
|
root: views/
|
||||||
DELIMITER_STATEMENT_START: "<!--#"
|
DELIMITER_STATEMENT_START: "<!--#"
|
||||||
DELIMITER_STATEMENT_END: "#-->"
|
DELIMITER_STATEMENT_END: "#-->"
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
This Font Software is licensed under the SIL Open Font License,
|
||||||
|
Version 1.1.
|
||||||
|
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font
|
||||||
|
creation efforts of academic and linguistic communities, and to
|
||||||
|
provide a free and open framework in which fonts may be shared and
|
||||||
|
improved in partnership with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply to
|
||||||
|
any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software
|
||||||
|
components as distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to,
|
||||||
|
deleting, or substituting -- in part or in whole -- any of the
|
||||||
|
components of the Original Version, by changing formats or by porting
|
||||||
|
the Font Software to a new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed,
|
||||||
|
modify, redistribute, and sell modified and unmodified copies of the
|
||||||
|
Font Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components, in
|
||||||
|
Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the
|
||||||
|
corresponding Copyright Holder. This restriction only applies to the
|
||||||
|
primary font name as presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created using
|
||||||
|
the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -380,7 +380,7 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
<span slot="footer" class="dialog-footer">
|
<span slot="footer" class="dialog-footer">
|
||||||
<el-button @click="setDialogVisible = false">取消</el-button>
|
<el-button @click="setDialogVisible = false">取消</el-button>
|
||||||
<el-button type="primary" @click="doSetActivityUser" v-loading="settingLoading">确定</el-button>
|
<el-button type="primary" :disabled="settingLoading" @click="doSetActivityUser">确定</el-button>
|
||||||
</span>
|
</span>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
@@ -646,7 +646,7 @@ module.exports = {
|
|||||||
doSearch(showFullLoading = false) {
|
doSearch(showFullLoading = false) {
|
||||||
this.tableKey = new Date().getTime()
|
this.tableKey = new Date().getTime()
|
||||||
this.pageForm.pageNumber = 1
|
this.pageForm.pageNumber = 1
|
||||||
this.pageData(showFullLoading === true)
|
return this.pageData(showFullLoading === true)
|
||||||
},
|
},
|
||||||
async pageData(showFullLoading = false) {
|
async pageData(showFullLoading = false) {
|
||||||
this.tableLoading = true
|
this.tableLoading = true
|
||||||
@@ -679,43 +679,74 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async doSetActivityUser() {
|
doSetActivityUser() {
|
||||||
const valid = await this.$refs.setForm.validate()
|
// 方法级状态保护与整页遮罩共同阻止慢请求期间的重复确认。
|
||||||
if (!valid) {
|
if (this.settingLoading) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.formData.groupType !== 2 && this.tableData.length === 0) {
|
this.$refs.setForm.validate((valid) => {
|
||||||
this.$message.warning("请先指定筛选条件!")
|
if (!valid) {
|
||||||
return
|
return
|
||||||
}
|
|
||||||
|
|
||||||
const confirm = await this.$confirm("是否将符合搜索条件的用户设为活动人员?", "提示", {
|
|
||||||
confirmButtonText: "确定",
|
|
||||||
cancelButtonText: "取消",
|
|
||||||
type: "warning"
|
|
||||||
})
|
|
||||||
|
|
||||||
if (confirm === "confirm") {
|
|
||||||
this.settingLoading = true
|
|
||||||
const pageForm = this.normalizePageForm(this.pageForm)
|
|
||||||
Object.assign(pageForm, this.formData)
|
|
||||||
const resp = await $.post("/platform/activity/basic/scope/doSetActivityUser", {
|
|
||||||
data: JSON.stringify(pageForm)
|
|
||||||
})
|
|
||||||
if (resp.code === 0) {
|
|
||||||
this.setDialogVisible = false
|
|
||||||
await this.getActivityGroup()
|
|
||||||
this.doSearch()
|
|
||||||
this.$message.success(resp.msg)
|
|
||||||
this.formData = this.getDefaultFormData()
|
|
||||||
} else {
|
|
||||||
this.$message.error(resp.msg)
|
|
||||||
}
|
}
|
||||||
this.settingLoading = false
|
|
||||||
this.$emit("update:group_id", resp.data)
|
if (this.formData.groupType !== 2 && this.tableData.length === 0) {
|
||||||
this.$emit("group_change")
|
this.$message.warning("请先指定筛选条件!")
|
||||||
}
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$confirm("是否将符合搜索条件的用户设为活动人员?", "提示", {
|
||||||
|
confirmButtonText: "确定",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "warning"
|
||||||
|
}).then(() => {
|
||||||
|
if (this.settingLoading) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.settingLoading = true
|
||||||
|
const loading = this.$loading({
|
||||||
|
lock: true,
|
||||||
|
text: "正在设置活动人员,请稍候...",
|
||||||
|
spinner: "el-icon-loading",
|
||||||
|
background: "rgba(255, 255, 255, 0.65)"
|
||||||
|
})
|
||||||
|
const pageForm = this.normalizePageForm(this.pageForm)
|
||||||
|
Object.assign(pageForm, this.formData)
|
||||||
|
|
||||||
|
$.post("/platform/activity/basic/scope/doSetActivityUser", {
|
||||||
|
data: JSON.stringify(pageForm)
|
||||||
|
}).then((resp) => {
|
||||||
|
if (resp.code !== 0) {
|
||||||
|
// 将后端业务错误转入统一失败分支,直接展示接口返回的真实原因。
|
||||||
|
throw new Error(resp.msg || "设置活动人员失败")
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setDialogVisible = false
|
||||||
|
// 设置成功后等待分组和人员列表刷新完成,再解除整页操作锁定。
|
||||||
|
return this.getActivityGroup()
|
||||||
|
.then(() => this.doSearch())
|
||||||
|
.then(() => {
|
||||||
|
this.$message.success(resp.msg)
|
||||||
|
this.formData = this.getDefaultFormData()
|
||||||
|
this.$emit("update:group_id", resp.data)
|
||||||
|
this.$emit("group_change")
|
||||||
|
})
|
||||||
|
}).then(null, (error) => {
|
||||||
|
// 兼容业务错误、权限异常和网络异常,避免请求失败后页面持续加载。
|
||||||
|
const response = error && error.responseJSON ? error.responseJSON : null
|
||||||
|
const errorMessage = response && response.msg
|
||||||
|
? response.msg
|
||||||
|
: error && error.message
|
||||||
|
? error.message
|
||||||
|
: "设置活动人员失败"
|
||||||
|
this.$message.error(errorMessage)
|
||||||
|
}).always(() => {
|
||||||
|
this.settingLoading = false
|
||||||
|
loading.close()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
async getActivityGroup() {
|
async getActivityGroup() {
|
||||||
const resp = await $.get("/platform/activity/basic/scope/getActivityUserScopeGroup")
|
const resp = await $.get("/platform/activity/basic/scope/getActivityUserScopeGroup")
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
:finished="tableFinished"
|
:finished="tableFinished"
|
||||||
finished-text="没有更多了"
|
finished-text="没有更多了"
|
||||||
@load="onLoad">
|
@load="onLoad">
|
||||||
<div class="table-list-container" @click="showOverflowText">
|
<div class="table-list-container">
|
||||||
<div v-for="(row, index) in tableData" :key="index" class="table-list-item"
|
<div v-for="(row, index) in tableData" :key="index" class="table-list-item"
|
||||||
:data-row-id="row && row.id ? row.id : ''">
|
:data-row-id="row && row.id ? row.id : ''">
|
||||||
<slot name="header" :index="index" :row="row">
|
<slot name="header" :index="index" :row="row">
|
||||||
@@ -36,12 +36,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</van-list>
|
</van-list>
|
||||||
<van-popover ref="overflowPopover" :value="overflowVisible" :style="overflowAnchorStyle"
|
|
||||||
:placement="overflowPlacement" get-container="body" @input="onOverflowInput"
|
|
||||||
@opened="positionOverflow">
|
|
||||||
<div class="table-list-overflow-content">{{ overflowText }}</div>
|
|
||||||
<template #reference><span></span></template>
|
|
||||||
</van-popover>
|
|
||||||
</van-pull-refresh>
|
</van-pull-refresh>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
@@ -96,138 +90,10 @@ module.exports = {
|
|||||||
tableLoading: false,
|
tableLoading: false,
|
||||||
tableFinished: false,
|
tableFinished: false,
|
||||||
tableRefreshing: false,
|
tableRefreshing: false,
|
||||||
localPageForm: {...this.page_form},
|
localPageForm: {...this.page_form}
|
||||||
overflowVisible: false,
|
|
||||||
overflowText: "",
|
|
||||||
overflowTarget: null,
|
|
||||||
overflowPlacement: "top",
|
|
||||||
overflowAnchorStyle: {}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 只响应真正被截断的纯文字,保留卡片内按钮和业务插槽原有的点击行为。
|
|
||||||
showOverflowText(event) {
|
|
||||||
const target = event.target
|
|
||||||
if (!target || !target.closest) return
|
|
||||||
const card = target.closest(".table-list-item")
|
|
||||||
if (!card || target.closest(".item-actions, a, button, input, textarea, select, [role=button], [tabindex], [onclick]")) return
|
|
||||||
if (target.children.length || !target.textContent.trim() || this.hasOverflowClickHandler(target, card)) return
|
|
||||||
const style = window.getComputedStyle(target)
|
|
||||||
if (style.textOverflow !== "ellipsis" || (target.scrollWidth <= target.clientWidth && target.scrollHeight <= target.clientHeight)) return
|
|
||||||
|
|
||||||
const rect = target.getBoundingClientRect()
|
|
||||||
this.overflowTarget = target
|
|
||||||
this.overflowText = target.textContent.trim()
|
|
||||||
this.overflowPlacement = rect.top < 180 ? "bottom" : "top"
|
|
||||||
this.overflowAnchorStyle = {
|
|
||||||
position: "fixed",
|
|
||||||
display: "block",
|
|
||||||
pointerEvents: "none",
|
|
||||||
left: rect.left + "px",
|
|
||||||
top: rect.top + "px",
|
|
||||||
width: rect.width + "px",
|
|
||||||
height: rect.height + "px"
|
|
||||||
}
|
|
||||||
if (!this.overflowVisible) this.bindOverflowListeners()
|
|
||||||
this.overflowVisible = true
|
|
||||||
this.$nextTick(() => {
|
|
||||||
const instance = this.$refs.overflowPopover
|
|
||||||
if (instance) instance.updateLocation()
|
|
||||||
setTimeout(() => this.positionOverflow(), 50)
|
|
||||||
setTimeout(() => this.positionOverflow(), 350)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
// 检查文字及其卡片内的祖先节点,避免干扰已有 Vue 点击事件。
|
|
||||||
hasOverflowClickHandler(target, card) {
|
|
||||||
const ancestors = []
|
|
||||||
let element = target
|
|
||||||
while (element && element !== card.parentElement) {
|
|
||||||
ancestors.push(element)
|
|
||||||
element = element.parentElement
|
|
||||||
}
|
|
||||||
const visit = (node) => {
|
|
||||||
if (!node) return false
|
|
||||||
const events = node.data ? [node.data.on, node.data.nativeOn] : []
|
|
||||||
if (ancestors.includes(node.elm) && events.some((handlers) => handlers &&
|
|
||||||
Object.keys(handlers).some((key) => /^[~!&]*(click|touchstart|pointerdown|mousedown)$/.test(key)))) return true
|
|
||||||
if (node.componentInstance && visit(node.componentInstance._vnode)) return true
|
|
||||||
return Array.isArray(node.children) && node.children.some((child) => visit(child))
|
|
||||||
}
|
|
||||||
return visit(this._vnode)
|
|
||||||
},
|
|
||||||
|
|
||||||
// Vant 的弹层挂在 body;校正窗口边缘的位置,避免完整文字被屏幕裁掉。
|
|
||||||
positionOverflow() {
|
|
||||||
const instance = this.$refs.overflowPopover
|
|
||||||
const popup = instance && instance.$refs.popover && instance.$refs.popover.$el
|
|
||||||
if (!this.overflowVisible || !this.overflowTarget || !popup) return
|
|
||||||
const rect = popup.getBoundingClientRect()
|
|
||||||
const anchor = this.overflowTarget.getBoundingClientRect()
|
|
||||||
if (!rect.width || !rect.height) return
|
|
||||||
const margin = 8
|
|
||||||
const left = Math.max(margin, Math.min(rect.left, window.innerWidth - rect.width - margin))
|
|
||||||
let top = rect.top
|
|
||||||
if (top < margin) top = anchor.bottom + 8
|
|
||||||
if (top + rect.height > window.innerHeight - margin) top = anchor.top - rect.height - 8
|
|
||||||
top = Math.max(margin, Math.min(top, window.innerHeight - rect.height - margin))
|
|
||||||
popup.style.left = (parseFloat(popup.style.left) || 0) + left - rect.left + "px"
|
|
||||||
popup.style.top = (parseFloat(popup.style.top) || 0) + top - rect.top + "px"
|
|
||||||
const arrow = popup.querySelector(".van-popover__arrow")
|
|
||||||
if (arrow) {
|
|
||||||
arrow.style.left = Math.max(12, Math.min(anchor.left + anchor.width / 2 - left, rect.width - 12)) + "px"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onOverflowInput(visible) {
|
|
||||||
this.overflowVisible = visible
|
|
||||||
if (!visible) {
|
|
||||||
this.overflowTarget = null
|
|
||||||
this.unbindOverflowListeners()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// 监听只在气泡打开时存在,PJAX 替换页面前也会关闭气泡并注销。
|
|
||||||
bindOverflowListeners() {
|
|
||||||
document.addEventListener("click", this.closeOverflowOnClick)
|
|
||||||
window.addEventListener("scroll", this.closeOverflowOnMove, true)
|
|
||||||
window.addEventListener("resize", this.closeOverflowOnMove)
|
|
||||||
window.addEventListener("transitionend", this.onOverflowAnimationEnd)
|
|
||||||
window.addEventListener("animationend", this.onOverflowAnimationEnd)
|
|
||||||
$(document).on("pjax:send", this.closeOverflowForNavigation)
|
|
||||||
},
|
|
||||||
|
|
||||||
unbindOverflowListeners() {
|
|
||||||
document.removeEventListener("click", this.closeOverflowOnClick)
|
|
||||||
window.removeEventListener("scroll", this.closeOverflowOnMove, true)
|
|
||||||
window.removeEventListener("resize", this.closeOverflowOnMove)
|
|
||||||
window.removeEventListener("transitionend", this.onOverflowAnimationEnd)
|
|
||||||
window.removeEventListener("animationend", this.onOverflowAnimationEnd)
|
|
||||||
$(document).off("pjax:send", this.closeOverflowForNavigation)
|
|
||||||
},
|
|
||||||
|
|
||||||
closeOverflowForNavigation() {
|
|
||||||
this.onOverflowInput(false)
|
|
||||||
},
|
|
||||||
|
|
||||||
// Vant 会在动画结束时重新计算定位,随后再次限制气泡的屏幕边界。
|
|
||||||
onOverflowAnimationEnd() {
|
|
||||||
if (this.overflowVisible) setTimeout(() => this.positionOverflow(), 0)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 滚动或改变屏幕尺寸时关闭气泡,避免气泡脱离原文字位置。
|
|
||||||
closeOverflowOnMove(event) {
|
|
||||||
if (event && event.target && event.target.closest && event.target.closest(".table-list-overflow-content")) return
|
|
||||||
this.onOverflowInput(false)
|
|
||||||
},
|
|
||||||
|
|
||||||
closeOverflowOnClick(event) {
|
|
||||||
if (!this.overflowVisible) return
|
|
||||||
if (this.overflowTarget && this.overflowTarget.contains(event.target)) return
|
|
||||||
if (event.target.closest && event.target.closest(".table-list-overflow-content")) return
|
|
||||||
this.onOverflowInput(false)
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前列表快照。
|
* 获取当前列表快照。
|
||||||
* 返回值包含已加载记录、分页参数和加载完成状态,供业务页面在进入详情前暂存列表现场。
|
* 返回值包含已加载记录、分页参数和加载完成状态,供业务页面在进入详情前暂存列表现场。
|
||||||
@@ -320,28 +186,10 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$emit("ready")
|
this.$emit("ready")
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
this.unbindOverflowListeners()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
|
||||||
/* Vant 将气泡挂到 body,控制宽高并允许长文本在气泡内滚动。 */
|
|
||||||
.table-list-overflow-content {
|
|
||||||
max-width: min(240px, calc(100vw - 48px));
|
|
||||||
max-height: 160px;
|
|
||||||
padding: 10px 12px;
|
|
||||||
overflow-y: auto;
|
|
||||||
color: #253247;
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 1.55;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
overflow-wrap: anywhere;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.table-list-container {
|
.table-list-container {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ module.exports = {
|
|||||||
*/
|
*/
|
||||||
init() {
|
init() {
|
||||||
this.signatureAddress = origin + "/platform/signature/scanPcCode?id=" + this.id
|
this.signatureAddress = origin + "/platform/signature/scanPcCode?id=" + this.id
|
||||||
|
console.log(this.signatureAddress)
|
||||||
return this.$axios.post("/platform/signature/get")
|
return this.$axios.post("/platform/signature/get")
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (this._isBeingDestroyed || this._isDestroyed) {
|
if (this._isBeingDestroyed || this._isDestroyed) {
|
||||||
|
|||||||
@@ -706,7 +706,7 @@
|
|||||||
Vue.component("year-van-dropdown-item", httpVueLoader("/components/plugins/vantMore/yearVanDropDownItem.vue?v=" + h5ComponentVersion))
|
Vue.component("year-van-dropdown-item", httpVueLoader("/components/plugins/vantMore/yearVanDropDownItem.vue?v=" + h5ComponentVersion))
|
||||||
Vue.component("van-text-dialog", httpVueLoader("/components/plugins/vantMore/vantTextDialog.vue?v=" + h5ComponentVersion))
|
Vue.component("van-text-dialog", httpVueLoader("/components/plugins/vantMore/vantTextDialog.vue?v=" + h5ComponentVersion))
|
||||||
Vue.component("enum-tag", httpVueLoader("/components/plugins/sysEnum/EnumTag.vue?v=" + h5ComponentVersion))
|
Vue.component("enum-tag", httpVueLoader("/components/plugins/sysEnum/EnumTag.vue?v=" + h5ComponentVersion))
|
||||||
Vue.component("table-list", httpVueLoader("/components/plugins/h5/TableList.vue?v=" + h5ComponentVersion + "_overflow1"))
|
Vue.component("table-list", httpVueLoader("/components/plugins/h5/TableList.vue?v=" + h5ComponentVersion))
|
||||||
Vue.component("table-column", httpVueLoader("/components/plugins/h5/TableColumn.vue?v=" + h5ComponentVersion))
|
Vue.component("table-column", httpVueLoader("/components/plugins/h5/TableColumn.vue?v=" + h5ComponentVersion))
|
||||||
Vue.component("file-preview", httpVueLoader("/components/plugins/sysFilePreview/H5Index.vue?v=" + h5ComponentVersion))
|
Vue.component("file-preview", httpVueLoader("/components/plugins/sysFilePreview/H5Index.vue?v=" + h5ComponentVersion))
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -75,7 +75,7 @@
|
|||||||
|
|
||||||
<!-- 引入 form-create 和 designer -->
|
<!-- 引入 form-create 和 designer -->
|
||||||
<script src="${base!}/assets/platform/plugins/form-create/form-create.min.js"></script>
|
<script src="${base!}/assets/platform/plugins/form-create/form-create.min.js"></script>
|
||||||
<script src="${base!}/assets/platform/plugins/form-create/index.umd.js"></script>
|
<script src="${base!}/assets/platform/plugins/form-create/index.umd.js?v=20261030"></script>
|
||||||
|
|
||||||
<!-- swiper -->
|
<!-- swiper -->
|
||||||
<script src="${base!}/assets/platform/plugins/swiper/swiper-bundle.js"></script>
|
<script src="${base!}/assets/platform/plugins/swiper/swiper-bundle.js"></script>
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ const act = {
|
|||||||
}
|
}
|
||||||
if (act.url === "/platform/activity/apply"
|
if (act.url === "/platform/activity/apply"
|
||||||
&& !this.$auth.hasRoleOr(["SYSADMIN", "SCHOOL_UNION_ADMIN", "BRANCH_UNION_CHAIRMAN", "BRANCH_UNION_WENTI_SPORTS"])) {
|
&& !this.$auth.hasRoleOr(["SYSADMIN", "SCHOOL_UNION_ADMIN", "BRANCH_UNION_CHAIRMAN", "BRANCH_UNION_WENTI_SPORTS"])) {
|
||||||
return this.$message.warning("PC端暂未开放报名,请前往移动端报名!")
|
return this.$message.warning("温馨提示:您没有参加该活动的权限!")
|
||||||
|
|
||||||
}
|
}
|
||||||
window.open(act.url)
|
window.open(act.url)
|
||||||
|
|||||||
@@ -116,6 +116,69 @@ layout("/layouts/v4/baseLayout.html"){
|
|||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 最新活动的作用域样式会在组件挂载后注入,首屏先固定布局和图片尺寸,避免刷新时放大闪烁。 */
|
||||||
|
#v4-home-app .act-card .activity-section-wrapper,
|
||||||
|
#v4-home-app .act-card .section-act,
|
||||||
|
#v4-home-app .act-card .activity-swiper {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
max-width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#v4-home-app .act-card .activity-swiper-container {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
max-width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 9px 54px 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#v4-home-app .act-card .activity-swiper .swiper-slide {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
min-width: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-right: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#v4-home-app .act-card .activity-swiper .img-box {
|
||||||
|
width: 100%;
|
||||||
|
height: 128px;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#v4-home-app .act-card .activity-swiper .img-box img {
|
||||||
|
display: block;
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
max-height: 128px !important;
|
||||||
|
object-fit: fill !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
#v4-home-app .act-card .activity-swiper .swiper-slide {
|
||||||
|
width: calc((100% - 18px) / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
#v4-home-app .act-card .activity-swiper .swiper-slide {
|
||||||
|
width: calc((100% - 54px) / 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1200px) {
|
||||||
|
#v4-home-app .act-card .activity-swiper .swiper-slide {
|
||||||
|
width: calc((100% - 72px) / 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="v4-container" id="v4-home-app">
|
<div class="v4-container" id="v4-home-app">
|
||||||
|
|||||||
+1
-1
@@ -100,7 +100,7 @@ layout("/layouts/platform.html"){
|
|||||||
size="mini" type="danger">删除
|
size="mini" type="danger">删除
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
<el-button v-if="row.instanceState === 20" @click="doExportDeclare(row)" size="mini" type="primary">申请表导出</el-button>
|
<el-button @click="doExportDeclare(row)" size="mini" type="primary">申请表导出</el-button>
|
||||||
<el-button v-if="row.instanceState === 20" @click="doExportReimbursement(row)" size="mini"
|
<el-button v-if="row.instanceState === 20" @click="doExportReimbursement(row)" size="mini"
|
||||||
type="primary">报销凭证导出
|
type="primary">报销凭证导出
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|||||||
@@ -221,8 +221,7 @@ layout("/layouts/platform.html"){
|
|||||||
placeholder="请输入姓名" filterable clearable
|
placeholder="请输入姓名" filterable clearable
|
||||||
style="width: 100%" size="small" v-if="awardsMode==1">
|
style="width: 100%" size="small" v-if="awardsMode==1">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in userList"
|
v-for="item in getSelectableUserList(row)"
|
||||||
:disabled="item.disabled"
|
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
:label="item.username+'('+item.loginname+')'+item.sex"
|
:label="item.username+'('+item.loginname+')'+item.sex"
|
||||||
:value="item.id">
|
:value="item.id">
|
||||||
@@ -721,10 +720,15 @@ layout("/layouts/platform.html"){
|
|||||||
}
|
}
|
||||||
return score;
|
return score;
|
||||||
},
|
},
|
||||||
|
getSelectableUserList(row) {
|
||||||
|
// 其他行已经选择的人员不再显示,当前行人员保留用于姓名正常回显。
|
||||||
|
const selectedUserIds = this.userData
|
||||||
|
.map(item => item.userId)
|
||||||
|
.filter(userId => userId)
|
||||||
|
return this.userList.filter(item => item.id === row.userId || !selectedUserIds.includes(item.id))
|
||||||
|
},
|
||||||
userDetailsChange(val, row) {
|
userDetailsChange(val, row) {
|
||||||
const useridArr = this.userData.map(v => v.userId)
|
|
||||||
this.userList.forEach(v => {
|
this.userList.forEach(v => {
|
||||||
v.disabled = useridArr.includes(v.id)
|
|
||||||
if (row && row.userId === v.id) {
|
if (row && row.userId === v.id) {
|
||||||
const o = {
|
const o = {
|
||||||
unionId: v.unionId,
|
unionId: v.unionId,
|
||||||
|
|||||||
@@ -601,6 +601,8 @@
|
|||||||
eventForm: {
|
eventForm: {
|
||||||
isLeader: false
|
isLeader: false
|
||||||
},
|
},
|
||||||
|
// 独立记录当前编辑项目,避免下拉框切换后丢失切换前项目标识。
|
||||||
|
currentEventId: "",
|
||||||
eventsIds: [],
|
eventsIds: [],
|
||||||
rightChecked: [],
|
rightChecked: [],
|
||||||
checkedEventInfo: [],
|
checkedEventInfo: [],
|
||||||
@@ -778,8 +780,10 @@
|
|||||||
this.checkedEventInfo = this.checkedEvents.map((v) => {
|
this.checkedEventInfo = this.checkedEvents.map((v) => {
|
||||||
v.eventId = v.id
|
v.eventId = v.id
|
||||||
if (v.projectType === "1") {
|
if (v.projectType === "1") {
|
||||||
v.athletesMaxNum = 3
|
// “所有单项”保存默认值,具体单项以0表示尚未个性化设置。
|
||||||
v.restrictRegNumber = 2
|
const isAllItems = v.eventId === "allItems"
|
||||||
|
v.athletesMaxNum = isAllItems ? 3 : 0
|
||||||
|
v.restrictRegNumber = isAllItems ? 2 : 0
|
||||||
v.leanderNum = 0
|
v.leanderNum = 0
|
||||||
v.coachNum = 0
|
v.coachNum = 0
|
||||||
v.applyUserModel = 1
|
v.applyUserModel = 1
|
||||||
@@ -791,7 +795,23 @@
|
|||||||
return v
|
return v
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
cacheCurrentEventForm() {
|
||||||
|
if (!this.currentEventId || !this.eventForm) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const current = clone(this.eventForm)
|
||||||
|
current.checkedEventId = this.currentEventId
|
||||||
|
current.eventId = this.currentEventId
|
||||||
|
|
||||||
|
const index = this.checkedEventInfo.findIndex((item) => item.eventId === this.currentEventId)
|
||||||
|
if (index >= 0) {
|
||||||
|
this.checkedEventInfo.splice(index, 1, current)
|
||||||
|
} else {
|
||||||
|
this.checkedEventInfo.push(current)
|
||||||
|
}
|
||||||
|
},
|
||||||
async eventChange(val) {
|
async eventChange(val) {
|
||||||
|
this.cacheCurrentEventForm()
|
||||||
const data = this.checkedEventInfo.find((v) => v.eventId === val)
|
const data = this.checkedEventInfo.find((v) => v.eventId === val)
|
||||||
const resp = await $.get("/platform/activity/sports/common/getEventData", { id: val })
|
const resp = await $.get("/platform/activity/sports/common/getEventData", { id: val })
|
||||||
await this.$nextTick()
|
await this.$nextTick()
|
||||||
@@ -804,10 +824,10 @@
|
|||||||
projectType: resp.data.projectType,
|
projectType: resp.data.projectType,
|
||||||
leanderNum: 0,
|
leanderNum: 0,
|
||||||
coachNum: 0,
|
coachNum: 0,
|
||||||
athletesMaxNum: resp.data.projectType === 1 ? 3 : null,
|
athletesMaxNum: resp.data.projectType === 1 ? 0 : null,
|
||||||
restrictTotalTeam: 1,
|
restrictTotalTeam: 1,
|
||||||
substituteNum: 0,
|
substituteNum: 0,
|
||||||
restrictRegNumber: resp.data.projectType === 1 ? 2 : null,
|
restrictRegNumber: resp.data.projectType === 1 ? 0 : null,
|
||||||
isLeader: false,
|
isLeader: false,
|
||||||
applyUserModel: 1
|
applyUserModel: 1
|
||||||
}
|
}
|
||||||
@@ -815,33 +835,27 @@
|
|||||||
this.projectType = resp.data.projectType
|
this.projectType = resp.data.projectType
|
||||||
}
|
}
|
||||||
this.$set(this.eventForm, "checkedEventId", val)
|
this.$set(this.eventForm, "checkedEventId", val)
|
||||||
|
this.currentEventId = val
|
||||||
},
|
},
|
||||||
async saveEvent() {
|
saveEvent() {
|
||||||
const data = clone(this.eventForm)
|
const data = clone(this.eventForm)
|
||||||
if (data.checkedEventId === "allItems") {
|
if (data.checkedEventId === "allItems") {
|
||||||
this.checkedEventInfo.forEach((v) => {
|
const allItemsIndex = this.checkedEventInfo.findIndex((v) => v.eventId === "allItems")
|
||||||
if (v.projectType === "1") {
|
if (allItemsIndex >= 0) {
|
||||||
v.applyUserModel = this.eventForm.applyUserModel
|
this.checkedEventInfo.splice(allItemsIndex, 1, data)
|
||||||
v.athletesMaxNum = data.athletesMaxNum
|
}
|
||||||
v.restrictRegNumber = data.restrictRegNumber
|
|
||||||
v.unionLimit = data.unionLimit
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
const info = this.checkedEventInfo.find((v) => v.eventId === data.checkedEventId)
|
const info = this.checkedEventInfo.find((v) => v.eventId === data.checkedEventId)
|
||||||
if (info != null) {
|
if (info != null) {
|
||||||
const index = this.checkedEventInfo.findIndex((v) => v.eventId === data.checkedEventId)
|
const index = this.checkedEventInfo.findIndex((v) => v.eventId === data.checkedEventId)
|
||||||
this.checkedEventInfo.splice(index, 1)
|
this.checkedEventInfo.splice(index, 1)
|
||||||
if (info.projectType === "1") {
|
|
||||||
this.$set(this.eventForm, "athletesMaxNum", data.athletesMaxNum)
|
|
||||||
this.$set(this.eventForm, "restrictRegNumber", data.restrictRegNumber)
|
|
||||||
}
|
|
||||||
this.$set(this.eventForm, "checkedEventId", info.eventId)
|
|
||||||
}
|
}
|
||||||
data.eventId = data.checkedEventId
|
data.eventId = data.checkedEventId
|
||||||
this.checkedEventInfo.push(data)
|
this.checkedEventInfo.push(data)
|
||||||
}
|
}
|
||||||
await this.doSave()
|
this.eventForm = clone(data)
|
||||||
|
this.currentEventId = data.checkedEventId
|
||||||
|
return this.doSave()
|
||||||
},
|
},
|
||||||
prev() {
|
prev() {
|
||||||
this.active--
|
this.active--
|
||||||
@@ -949,6 +963,7 @@
|
|||||||
this.copyTemplateMode = false
|
this.copyTemplateMode = false
|
||||||
this.copyTemplateName = ""
|
this.copyTemplateName = ""
|
||||||
this.pushTodoFlag = false
|
this.pushTodoFlag = false
|
||||||
|
this.currentEventId = ""
|
||||||
this.events = await this.getEvents(2)
|
this.events = await this.getEvents(2)
|
||||||
await this.getActivityGroup()
|
await this.getActivityGroup()
|
||||||
this.active = 0
|
this.active = 0
|
||||||
@@ -1028,6 +1043,7 @@
|
|||||||
async openEdit(row, flag, copyTemplateMode = false) {
|
async openEdit(row, flag, copyTemplateMode = false) {
|
||||||
this.copyTemplateMode = !!copyTemplateMode
|
this.copyTemplateMode = !!copyTemplateMode
|
||||||
this.pushTodoFlag = false
|
this.pushTodoFlag = false
|
||||||
|
this.currentEventId = ""
|
||||||
this.active = flag ? 0 : this.active
|
this.active = flag ? 0 : this.active
|
||||||
await this.getActivityGroup()
|
await this.getActivityGroup()
|
||||||
const { id } = row
|
const { id } = row
|
||||||
@@ -1184,7 +1200,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.eventForm.checkedEventId == "allItems") {
|
if (this.eventForm.checkedEventId == "allItems") {
|
||||||
events = events.filter((v) => v.projectType == 1 && v.id != "allItems")
|
// “所有单项”配置随具体单项提交,由后端统一校验并补齐继承值。
|
||||||
|
events = events.filter((v) => v.projectType == 1)
|
||||||
} else {
|
} else {
|
||||||
this.$set(this.eventForm, "activityId", this.formData.id)
|
this.$set(this.eventForm, "activityId", this.formData.id)
|
||||||
this.$set(this.eventForm, "eventId", this.eventForm.checkedEventId)
|
this.$set(this.eventForm, "eventId", this.eventForm.checkedEventId)
|
||||||
@@ -1192,9 +1209,10 @@
|
|||||||
this.$set(this.eventForm, "startAgeDate", this.eventForm.ageDate[0])
|
this.$set(this.eventForm, "startAgeDate", this.eventForm.ageDate[0])
|
||||||
this.$set(this.eventForm, "endAgeDate", this.eventForm.ageDate[1])
|
this.$set(this.eventForm, "endAgeDate", this.eventForm.ageDate[1])
|
||||||
}
|
}
|
||||||
events = this.eventForm
|
const allItems = this.checkedEventInfo.find((v) => v.eventId === "allItems")
|
||||||
|
events = allItems ? [clone(allItems), this.eventForm] : [this.eventForm]
|
||||||
if (this.copyTemplateMode) {
|
if (this.copyTemplateMode) {
|
||||||
this.cleanCopyTemplateData(null, [events])
|
this.cleanCopyTemplateData(null, events)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const loading = this.$loading({
|
const loading = this.$loading({
|
||||||
@@ -1215,6 +1233,7 @@
|
|||||||
this.copyTemplateMode = false
|
this.copyTemplateMode = false
|
||||||
}
|
}
|
||||||
await this.openEdit(formData, false)
|
await this.openEdit(formData, false)
|
||||||
|
this.currentEventId = this.eventForm.checkedEventId || ""
|
||||||
this.$message.success(resp.msg)
|
this.$message.success(resp.msg)
|
||||||
} else {
|
} else {
|
||||||
this.$message.error(resp.msg)
|
this.$message.error(resp.msg)
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
const REGISTER_INFO_COMPONENT = {
|
const REGISTER_INFO_COMPONENT = {
|
||||||
|
// 默认展示换届报告,仅由不需要查看该字段的业务页面显式关闭。
|
||||||
|
props: {
|
||||||
|
hideReplaceReport: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
template: `
|
template: `
|
||||||
<div>
|
<div>
|
||||||
<el-tabs tab-position="top" v-model="activeName">
|
<el-tabs tab-position="top" v-model="activeName">
|
||||||
@@ -36,7 +43,7 @@ const REGISTER_INFO_COMPONENT = {
|
|||||||
{{viewData.createTime}}
|
{{viewData.createTime}}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="会费标准" :span="4">
|
<el-descriptions-item label="会费标准" :span="4">
|
||||||
{{viewData.due}}
|
{{ viewData.due === null || viewData.due === undefined ? "--" : viewData.due + " 元/年" }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item :span="4">
|
<el-descriptions-item :span="4">
|
||||||
<template slot="label">社团介绍</template>
|
<template slot="label">社团介绍</template>
|
||||||
@@ -66,7 +73,7 @@ const REGISTER_INFO_COMPONENT = {
|
|||||||
<template slot="label">其他附件</template>
|
<template slot="label">其他附件</template>
|
||||||
<file-preview :files="viewData.files" complete_result></file-preview>
|
<file-preview :files="viewData.files" complete_result></file-preview>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item :span="2">
|
<el-descriptions-item :span="2" v-if="!hideReplaceReport">
|
||||||
<template slot="label">换届报告</template>
|
<template slot="label">换届报告</template>
|
||||||
<file-preview :files="viewData.replaceReport" complete_result></file-preview>
|
<file-preview :files="viewData.replaceReport" complete_result></file-preview>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
|||||||
@@ -68,10 +68,12 @@ layout("/layouts/platform.html"){
|
|||||||
</el-steps>
|
</el-steps>
|
||||||
|
|
||||||
<!-- 第一步:基础信息表单 -->
|
<!-- 第一步:基础信息表单 -->
|
||||||
|
<!-- 本表单自行提示首个必填错误,关闭全局校验弹窗增强以免重复提示。 -->
|
||||||
<el-form
|
<el-form
|
||||||
v-show="step === 0"
|
v-show="step === 0"
|
||||||
:model="formData"
|
:model="formData"
|
||||||
ref="baseForm"
|
ref="baseForm"
|
||||||
|
no-auto-enhance
|
||||||
:rules="baseRules"
|
:rules="baseRules"
|
||||||
label-width="150px"
|
label-width="150px"
|
||||||
class="main-form"
|
class="main-form"
|
||||||
@@ -135,7 +137,9 @@ layout("/layouts/platform.html"){
|
|||||||
v-model="formData.due"
|
v-model="formData.due"
|
||||||
placeholder="请输入会费标准"
|
placeholder="请输入会费标准"
|
||||||
readonly
|
readonly
|
||||||
></el-input>
|
>
|
||||||
|
<template slot="append">元/年</template>
|
||||||
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -146,7 +150,7 @@ layout("/layouts/platform.html"){
|
|||||||
<el-form-item
|
<el-form-item
|
||||||
class="is-required"
|
class="is-required"
|
||||||
label="本年度活动开展情况"
|
label="本年度活动开展情况"
|
||||||
prop="yearActivity"
|
prop="yearActivityList"
|
||||||
>
|
>
|
||||||
<span class="tip-text">说明:非赛事活动无需填写赛事举办单位、获奖情况。</span>
|
<span class="tip-text">说明:非赛事活动无需填写赛事举办单位、获奖情况。</span>
|
||||||
<el-table
|
<el-table
|
||||||
@@ -638,6 +642,7 @@ layout("/layouts/platform.html"){
|
|||||||
id: GetQueryString("bizId"),
|
id: GetQueryString("bizId"),
|
||||||
taskId: GetQueryString("taskId"),
|
taskId: GetQueryString("taskId"),
|
||||||
step: 0, // 当前步骤(0-基础信息,1-财务收支,2-成员名单)
|
step: 0, // 当前步骤(0-基础信息,1-财务收支,2-成员名单)
|
||||||
|
formLoading: false,
|
||||||
isRegistered: false, // 是否已登记
|
isRegistered: false, // 是否已登记
|
||||||
currentClubId: "", // 当前选中社团ID
|
currentClubId: "", // 当前选中社团ID
|
||||||
|
|
||||||
@@ -656,7 +661,7 @@ layout("/layouts/platform.html"){
|
|||||||
year: new Date().getFullYear() + "", // 默认当前年度
|
year: new Date().getFullYear() + "", // 默认当前年度
|
||||||
clubId: "",
|
clubId: "",
|
||||||
foundTime: "",
|
foundTime: "",
|
||||||
due: "",
|
due: null,
|
||||||
clubName: "",
|
clubName: "",
|
||||||
yearActivityList: [{}], // 本年度活动列表
|
yearActivityList: [{}], // 本年度活动列表
|
||||||
plans: [{}], // 下年度计划列表
|
plans: [{}], // 下年度计划列表
|
||||||
@@ -671,7 +676,10 @@ layout("/layouts/platform.html"){
|
|||||||
},
|
},
|
||||||
|
|
||||||
// 表单校验规则
|
// 表单校验规则
|
||||||
baseRules: {},
|
baseRules: {
|
||||||
|
yearActivityList: [{validator: this.validateActivityRows, trigger: ['change', 'blur']}],
|
||||||
|
plans: [{validator: this.validateActivityRows, trigger: ['change', 'blur']}]
|
||||||
|
},
|
||||||
financeRules: {},
|
financeRules: {},
|
||||||
memberRules: {}
|
memberRules: {}
|
||||||
};
|
};
|
||||||
@@ -724,6 +732,28 @@ layout("/layouts/platform.html"){
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 在列表级逐行校验,避免嵌套表单项未注册、空数组或纯空白文本绕过必填。
|
||||||
|
validateActivityRows(rule, value, callback) {
|
||||||
|
const currentYear = rule.field === 'yearActivityList';
|
||||||
|
const label = currentYear ? '本年度活动开展情况' : '下一年度活动计划';
|
||||||
|
const fields = currentYear
|
||||||
|
? [['activityTime', '活动时间'], ['activityName', '活动主题/赛事名称'], ['activityAddress', '活动地点'], ['joinNum', '参加人数']]
|
||||||
|
: [['activityName', '活动主题/赛事名称'], ['activityUnit', '活动/赛事主办单位'], ['activityAddress', '活动地点']];
|
||||||
|
if (!Array.isArray(value) || value.length === 0) {
|
||||||
|
callback(new Error(label + '至少填写一条'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (let i = 0; i < value.length; i++) {
|
||||||
|
for (const field of fields) {
|
||||||
|
const content = value[i] && value[i][field[0]];
|
||||||
|
if (content === null || content === undefined || String(content).trim() === '') {
|
||||||
|
callback(new Error(label + '第' + (i + 1) + '条:' + field[1] + '不能为空'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
},
|
||||||
/************************ 通用工具方法 ************************/
|
/************************ 通用工具方法 ************************/
|
||||||
// 格式化数字(保留2位小数,空值显示0)
|
// 格式化数字(保留2位小数,空值显示0)
|
||||||
formatNumber(num) {
|
formatNumber(num) {
|
||||||
@@ -1110,7 +1140,7 @@ layout("/layouts/platform.html"){
|
|||||||
if (!val) return;
|
if (!val) return;
|
||||||
const club = this.clubOptions.find(item => item.id === val);
|
const club = this.clubOptions.find(item => item.id === val);
|
||||||
// 更新社团基础信息
|
// 更新社团基础信息
|
||||||
this.formData.due = club?.due || "";
|
this.formData.due = club && club.due !== null && club.due !== undefined ? club.due : null;
|
||||||
this.formData.foundTime = club?.foundTime
|
this.formData.foundTime = club?.foundTime
|
||||||
? this.$moment(club.foundTime).format("YYYY-MM-DD")
|
? this.$moment(club.foundTime).format("YYYY-MM-DD")
|
||||||
: this.$moment().format("YYYY-MM-DD");
|
: this.$moment().format("YYYY-MM-DD");
|
||||||
@@ -1161,73 +1191,63 @@ layout("/layouts/platform.html"){
|
|||||||
// 步骤前进
|
// 步骤前进
|
||||||
this.step++;
|
this.step++;
|
||||||
},
|
},
|
||||||
// 保存
|
// 三个操作共用基础信息校验,失败时返回第一步展示行号和必填字段。
|
||||||
async handleSave() {
|
validateBaseBeforeAction(action) {
|
||||||
try {
|
if (this.formLoading) return;
|
||||||
this.recalculateCensus();
|
this.$refs.baseForm.validate((valid, fields) => {
|
||||||
const resp = await this.$axios.post("/platform/club/examine/apply/save", {
|
if (!valid) {
|
||||||
data: JSON.stringify(this.formData),
|
this.step = 0;
|
||||||
incomeDetailed: JSON.stringify(this.financeData.incomeDetailed),
|
const firstError = Object.values(fields || {}).flat()[0];
|
||||||
incomeCensus: JSON.stringify(this.financeData.incomeCensus)
|
this.$message.warning('温馨提示:' + (firstError ? firstError.message : '请补全基础信息必填项'));
|
||||||
});
|
return;
|
||||||
if (resp.code === 0) {
|
|
||||||
this.$message.success(resp.msg);
|
|
||||||
commonUtil.pjaxPush('/platform/club/examine/mine');
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
action();
|
||||||
this.handleError(error, "保存失败");
|
});
|
||||||
}
|
|
||||||
},
|
},
|
||||||
// 提交(新增)
|
// 仅接收本页三个固定操作的接口后缀;data为登记实体JSON,另两项为财务数组JSON。
|
||||||
async handleSubmit() {
|
// 接口返回{code,msg,data},code为0时保存成功,否则展示后端校验提示。
|
||||||
try {
|
requestExamineAction(action) {
|
||||||
this.recalculateCensus();
|
if (this.formLoading) return;
|
||||||
await this.$confirm("确定要提交此申请吗?", "提示", {
|
this.recalculateCensus();
|
||||||
confirmButtonText: "确定",
|
const params = {
|
||||||
cancelButtonText: "取消",
|
data: JSON.stringify(this.formData),
|
||||||
type: "info"
|
incomeDetailed: JSON.stringify(this.financeData.incomeDetailed),
|
||||||
|
incomeCensus: JSON.stringify(this.financeData.incomeCensus)
|
||||||
|
};
|
||||||
|
if (action === 'submitAgain') params.taskId = this.taskId;
|
||||||
|
this.formLoading = true;
|
||||||
|
return this.$axios.post('/platform/club/examine/apply/' + action, params)
|
||||||
|
.then((resp) => {
|
||||||
|
if (resp.code === 0) {
|
||||||
|
this.$message.success(resp.msg);
|
||||||
|
commonUtil.pjaxPush('/platform/club/examine/mine');
|
||||||
|
} else {
|
||||||
|
this.$message.warning(resp.msg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
// 后端校验和网络异常已由全局axios拦截器提示,此处仅结束失败请求,避免再次弹窗。
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.formLoading = false;
|
||||||
});
|
});
|
||||||
const resp = await this.$axios.post("/platform/club/examine/apply/submit", {
|
|
||||||
data: JSON.stringify(this.formData),
|
|
||||||
incomeDetailed: JSON.stringify(this.financeData.incomeDetailed),
|
|
||||||
incomeCensus: JSON.stringify(this.financeData.incomeCensus)
|
|
||||||
});
|
|
||||||
if (resp.code === 0) {
|
|
||||||
this.$message.success(resp.msg);
|
|
||||||
commonUtil.pjaxPush('/platform/club/examine/mine');
|
|
||||||
} else {
|
|
||||||
this.$message.warning(resp.msg);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
if (error !== "cancel") {
|
|
||||||
this.handleError(error, "提交失败");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
// 提交(任务处理)
|
handleSave() {
|
||||||
async handleFinishTask() {
|
this.validateBaseBeforeAction(() => this.requestExamineAction('save'));
|
||||||
try {
|
},
|
||||||
this.recalculateCensus();
|
handleSubmit() {
|
||||||
await this.$confirm("您确定要提交吗?", "提示", {
|
this.validateBaseBeforeAction(() => {
|
||||||
confirmButtonText: "确定",
|
this.$confirm('确定要提交此申请吗?', '提示', {
|
||||||
cancelButtonText: "取消",
|
confirmButtonText: '确定', cancelButtonText: '取消', type: 'info'
|
||||||
type: "warning"
|
}).then(() => this.requestExamineAction('submit')).catch(() => {});
|
||||||
});
|
});
|
||||||
const resp = await this.$axios.post('/platform/club/examine/apply/submitAgain', {
|
},
|
||||||
data: JSON.stringify(this.formData),
|
handleFinishTask() {
|
||||||
incomeDetailed: JSON.stringify(this.financeData.incomeDetailed),
|
this.validateBaseBeforeAction(() => {
|
||||||
incomeCensus: JSON.stringify(this.financeData.incomeCensus),
|
this.$confirm('您确定要提交吗?', '提示', {
|
||||||
taskId: this.taskId
|
confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning'
|
||||||
});
|
}).then(() => this.requestExamineAction('submitAgain')).catch(() => {});
|
||||||
if (resp.code === 0) {
|
});
|
||||||
this.$message.success(resp.msg);
|
|
||||||
commonUtil.pjaxPush('/platform/club/examine/mine');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
if (error !== "cancel") {
|
|
||||||
this.handleError(error, "提交失败");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<el-descriptions v-if="viewData" :column="3" border class="table_fixed">
|
<el-descriptions v-if="viewData" :column="3" border class="table_fixed">
|
||||||
<el-descriptions-item label="社团名称">{{ viewData.clubName }}</el-descriptions-item>
|
<el-descriptions-item label="社团名称">{{ viewData.clubName }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="成立时间">{{ viewData.foundTime }} </el-descriptions-item>
|
<el-descriptions-item label="成立时间">{{ viewData.foundTime }} </el-descriptions-item>
|
||||||
<el-descriptions-item label="会费标准">{{ viewData.due }}</el-descriptions-item>
|
<el-descriptions-item label="会费标准">{{ viewData.due === null || viewData.due === undefined ? "--" : viewData.due + " 元/年" }}</el-descriptions-item>
|
||||||
<el-descriptions-item span="3">
|
<el-descriptions-item span="3">
|
||||||
<template slot="label">工作总结</template>
|
<template slot="label">工作总结</template>
|
||||||
<file-preview :files="viewData.summaryFiles" complete_result></file-preview>
|
<file-preview :files="viewData.summaryFiles" complete_result></file-preview>
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ layout("/layouts/platform.html"){
|
|||||||
<el-descriptions-item label="联系人邮箱">{{viewData.concatPersonEmail}}</el-descriptions-item>
|
<el-descriptions-item label="联系人邮箱">{{viewData.concatPersonEmail}}</el-descriptions-item>
|
||||||
<el-descriptions-item>
|
<el-descriptions-item>
|
||||||
<template slot="label">会费标准</template>
|
<template slot="label">会费标准</template>
|
||||||
{{viewData.due}}
|
{{ viewData.due === null || viewData.due === undefined ? "--" : viewData.due + " 元/年" }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item :span="2">
|
<el-descriptions-item :span="2">
|
||||||
<template slot="label">当前人数</template>
|
<template slot="label">当前人数</template>
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ layout("/layouts/platform.html"){
|
|||||||
<el-descriptions-item label="社团编码">{{viewData.clubCode}}</el-descriptions-item>
|
<el-descriptions-item label="社团编码">{{viewData.clubCode}}</el-descriptions-item>
|
||||||
<el-descriptions-item label="社团类型">{{viewData.typeName}}</el-descriptions-item>
|
<el-descriptions-item label="社团类型">{{viewData.typeName}}</el-descriptions-item>
|
||||||
<el-descriptions-item label="发起人">{{viewData.sponsorName}}</el-descriptions-item>
|
<el-descriptions-item label="发起人">{{viewData.sponsorName}}</el-descriptions-item>
|
||||||
<el-descriptions-item label="会费标准">{{viewData.due}}</el-descriptions-item>
|
<el-descriptions-item label="会费标准">{{ viewData.due === null || viewData.due === undefined ? "--" : viewData.due + " 元/年" }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="当前人数">{{viewData.currentPeopleNum}}</el-descriptions-item>
|
<el-descriptions-item label="当前人数">{{viewData.currentPeopleNum}}</el-descriptions-item>
|
||||||
<el-descriptions-item span="2">
|
<el-descriptions-item span="2">
|
||||||
<template slot="label">社团介绍</template>
|
<template slot="label">社团介绍</template>
|
||||||
|
|||||||
@@ -24,7 +24,13 @@ const CLUB_FORM_TEMPLATE = {
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="会费标准" prop="due">
|
<el-form-item label="会费标准" prop="due">
|
||||||
<el-input placeholder="请填写会费标准" v-model="formData.due">
|
<el-input
|
||||||
|
min="0"
|
||||||
|
placeholder="请填写会费标准"
|
||||||
|
step="0.01"
|
||||||
|
type="number"
|
||||||
|
v-model.number="formData.due"
|
||||||
|
>
|
||||||
<template slot="append">元/年</template>
|
<template slot="append">元/年</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -156,12 +162,15 @@ const CLUB_FORM_TEMPLATE = {
|
|||||||
return {
|
return {
|
||||||
formData: {
|
formData: {
|
||||||
clubName: "",
|
clubName: "",
|
||||||
clubType: ""
|
clubType: "",
|
||||||
|
due: null
|
||||||
},
|
},
|
||||||
formRules: {
|
formRules: {
|
||||||
clubName: [{ required: true, message: "请填写社团名称", trigger: ["blur", "change"] }],
|
clubName: [{ required: true, message: "请填写社团名称", trigger: ["blur", "change"] }],
|
||||||
clubCode: [{ required: false, message: "请填写社团编码", trigger: ["blur", "change"] }],
|
clubCode: [{ required: false, message: "请填写社团编码", trigger: ["blur", "change"] }],
|
||||||
clubType: [{ required: true, message: "请选择社团类型", trigger: ["blur", "change"] }],
|
clubType: [{ required: true, message: "请选择社团类型", trigger: ["blur", "change"] }],
|
||||||
|
// 会费标准只保存数字,单位“元/年”由页面统一展示。
|
||||||
|
due: [{ type: "number", min: 0, message: "会费标准必须为不小于0的数字", trigger: ["blur", "change"] }],
|
||||||
//concatPerson: [{ required: true, message: "请选择社团联系人", trigger: ["blur", "change"] }],
|
//concatPerson: [{ required: true, message: "请选择社团联系人", trigger: ["blur", "change"] }],
|
||||||
foundTime: [{ required: true, message: "请选择成立时间", trigger: ["blur", "change"] }]
|
foundTime: [{ required: true, message: "请选择成立时间", trigger: ["blur", "change"] }]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ layout("/layouts/platform.html"){
|
|||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<template #public>
|
<template #public>
|
||||||
<register-info ref="registerInfoRef">
|
<register-info ref="registerInfoRef" :hide-replace-report="true">
|
||||||
<div v-if="showApprovalForm">
|
<div v-if="showApprovalForm">
|
||||||
<div class="process-title">
|
<div class="process-title">
|
||||||
{{formData.taskName}}
|
{{formData.taskName}}
|
||||||
|
|||||||
@@ -21,29 +21,14 @@ const PROPOSAL_INFO = {
|
|||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="提案类别">
|
<el-descriptions-item label="提案类别">
|
||||||
{{viewData.typeName}}
|
{{viewData.typeName}}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item><!--
|
||||||
<!-- 提案方式和联系电话来自提案详情,未填写时显示占位符。 -->
|
|
||||||
<el-descriptions-item label="提案方式">
|
|
||||||
<dict-tag v-if="viewData.source" :options="dict.type.PROPOSAL_SOURCE"
|
|
||||||
:value="viewData.source"></dict-tag>
|
|
||||||
<span v-else>--</span>
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="联系电话">{{ viewData.mobile || '--' }}</el-descriptions-item><!--
|
|
||||||
<el-descriptions-item label="建议承办单位">
|
<el-descriptions-item label="建议承办单位">
|
||||||
{{viewData.suggestUnits}}
|
{{viewData.suggestUnits}}
|
||||||
</el-descriptions-item>-->
|
</el-descriptions-item>-->
|
||||||
<!-- 立案结果和类型尚未填写时仍显示字段,并以双横线表示空值。 -->
|
<el-descriptions-item label="立案结果" :span="2">
|
||||||
<el-descriptions-item label="立案结果">
|
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
|
||||||
<dict-tag v-if="viewData.caseFilingResult" :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
|
|
||||||
:value="viewData.caseFilingResult"></dict-tag>
|
:value="viewData.caseFilingResult"></dict-tag>
|
||||||
<span v-else>--</span>
|
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="立案类型">
|
|
||||||
<dict-tag v-if="viewData.caseFilingType" :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
|
|
||||||
:value="viewData.caseFilingType"></dict-tag>
|
|
||||||
<span v-else>--</span>
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item></el-descriptions-item>
|
|
||||||
<!--<el-descriptions-item label="调研情况" :span="3">
|
<!--<el-descriptions-item label="调研情况" :span="3">
|
||||||
<div class="text-left">{{viewData.researchFindings}}</div>
|
<div class="text-left">{{viewData.researchFindings}}</div>
|
||||||
</el-descriptions-item>-->
|
</el-descriptions-item>-->
|
||||||
@@ -97,22 +82,18 @@ const PROPOSAL_INFO = {
|
|||||||
{{row.commissionerName}}({{row.commissionerLoginName}})
|
{{row.commissionerName}}({{row.commissionerLoginName}})
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<!-- 委员意见分别展示立案结果和类型,未填写时显示双横线。 -->
|
<el-table-column label="立案结果" prop="caseFilingType">
|
||||||
<el-table-column label="立案结果" prop="caseFilingResult">
|
|
||||||
<template slot-scope="{row}">
|
<template slot-scope="{row}">
|
||||||
<div style="display: flex;justify-content: center">
|
<div style="display: flex;justify-content: center">
|
||||||
<dict-tag v-if="row.caseFilingResult" :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
|
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
|
||||||
:value="row.caseFilingResult"></dict-tag>
|
:value="row.caseFilingResult"></dict-tag>
|
||||||
<span v-else>--</span>
|
<!-- 普通提案/重点提案暂不展示,历史数据仍保留。 -->
|
||||||
</div>
|
<template v-if="false">
|
||||||
</template>
|
(
|
||||||
</el-table-column>
|
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
|
||||||
<el-table-column label="立案类型" prop="caseFilingType">
|
:value="row.caseFilingType"></dict-tag>
|
||||||
<template slot-scope="{row}">
|
)
|
||||||
<div style="display: flex;justify-content: center">
|
</template>
|
||||||
<dict-tag v-if="row.caseFilingType" :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
|
|
||||||
:value="row.caseFilingType"></dict-tag>
|
|
||||||
<span v-else>--</span>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -143,125 +124,117 @@ const PROPOSAL_INFO = {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<!--同一提案可能存在多个承办单位答复任务,查看时合并为一个流程节点,节点内保留每条答复。-->
|
<!--同一提案可能存在多个承办单位答复任务,查看时合并为一个流程节点,节点内保留每条答复。-->
|
||||||
<template v-if="task.replyTasks">
|
<template v-if="task.replyTasks">
|
||||||
<el-descriptions v-for="replyTask in task.replyTasks" border class="flow-task-form"
|
<el-descriptions v-for="replyTask in task.replyTasks" border class="flow-task-form"
|
||||||
:column="3" :key="replyTask.id">
|
:column="3" :key="replyTask.id">
|
||||||
<el-descriptions-item label="承办单位" :span="3">
|
<el-descriptions-item label="承办单位" :span="3">
|
||||||
{{replyTask.ext.underTakeName}}
|
{{replyTask.ext.underTakeName}}
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="办理用户">
|
|
||||||
{{replyTask.taskFormData.userName}}({{replyTask.taskFormData.loginName}})
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="办理时间">{{replyTask.finishTime}}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="办理结果">
|
|
||||||
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
|
|
||||||
:value="replyTask.ext.submitType"></dict-tag>
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="办理意见" :span="3">
|
|
||||||
<div v-html="replyTask.taskFormData.tf_opinion"></div>
|
|
||||||
</el-descriptions-item>
|
|
||||||
</el-descriptions>
|
|
||||||
</template>
|
|
||||||
<el-descriptions border class="flow-task-form" :column="3" :key="task.id"
|
|
||||||
v-else-if="task.ext.isFirstTaskNode">
|
|
||||||
<el-descriptions-item label="申请用户">{{ task.ext.initiatorName
|
|
||||||
}}({{task.ext.initiatorAccount}})
|
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="申请时间">{{ task.finishTime }}</el-descriptions-item>
|
<el-descriptions-item label="办理用户">
|
||||||
|
{{replyTask.taskFormData.userName}}({{replyTask.taskFormData.loginName}})
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="办理时间">{{replyTask.finishTime}}</el-descriptions-item>
|
||||||
<el-descriptions-item label="办理结果">
|
<el-descriptions-item label="办理结果">
|
||||||
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
|
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
|
||||||
:value="task.ext.submitType"></dict-tag>
|
:value="replyTask.ext.submitType"></dict-tag>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
|
||||||
|
|
||||||
<!--邀请附议人-->
|
|
||||||
<el-descriptions border class="flow-task-form" :column="3" :key="task.id"
|
|
||||||
v-else-if="task.taskName === 'invite'">
|
|
||||||
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName
|
|
||||||
}}({{task.taskFormData.loginName}})
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="办理时间" :span="2">{{ task.finishTime }}
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="附议人" :span="3" v-if="task.taskName === 'invite'">
|
|
||||||
<el-table v-loading="tableLoading" :data="task?.taskFormData?.seconder">
|
|
||||||
<el-table-column label="姓名" prop="userName"></el-table-column>
|
|
||||||
<el-table-column label="工号" prop="loginName"></el-table-column>
|
|
||||||
<el-table-column label="性别" prop="sex"></el-table-column>
|
|
||||||
<el-table-column label="联系方式" prop="mobile"></el-table-column>
|
|
||||||
<el-table-column label="单位" prop="unitName"></el-table-column>
|
|
||||||
<el-table-column label="分工会" prop="unionName"></el-table-column>
|
|
||||||
<el-table-column label="代表团" prop="delegationName"></el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</el-descriptions-item>
|
|
||||||
</el-descriptions>
|
|
||||||
|
|
||||||
<!--提案委员会立案-->
|
|
||||||
<el-descriptions border class="flow-task-form" :column="3" :key="task.id"
|
|
||||||
v-else-if="task.taskName === 'committee'||task.taskName === 'committeeFilingUnit'">
|
|
||||||
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName
|
|
||||||
}}({{task.taskFormData.loginName}})
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>
|
|
||||||
<!-- 立案节点分别展示流程记录中的结果与类型,空值显示双横线。 -->
|
|
||||||
<el-descriptions-item label="立案结果">
|
|
||||||
<div style="display: flex;justify-content: center">
|
|
||||||
<dict-tag v-if="task.ext.tf_caseFilingResult"
|
|
||||||
:options="dict.type.PROPOSAL_CASE_FILING_RESULT"
|
|
||||||
:value="task.ext.tf_caseFilingResult"></dict-tag>
|
|
||||||
<span v-else>--</span>
|
|
||||||
</div>
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="立案类型">
|
|
||||||
<div style="display: flex;justify-content: center">
|
|
||||||
<dict-tag v-if="task.ext.tf_caseFilingType"
|
|
||||||
:options="dict.type.PROPOSAL_CASE_FILING_TYPE"
|
|
||||||
:value="task.ext.tf_caseFilingType"></dict-tag>
|
|
||||||
<span v-else>--</span>
|
|
||||||
</div>
|
|
||||||
</el-descriptions-item>
|
|
||||||
<template v-if="['CONFIRM_FILING','SUGGESTION'].includes(task.ext.tf_caseFilingResult)">
|
|
||||||
<el-descriptions-item v-if="task.ext.tf_caseFilingResult === 'SUGGESTION'"
|
|
||||||
label="承办单位" :span="3">{{task?.ext?.tf_masterUnitNameStr ||
|
|
||||||
task?.ext?.tf_slaveUnitNameStr}}
|
|
||||||
</el-descriptions-item>
|
|
||||||
<template v-else>
|
|
||||||
<el-descriptions-item label="主办单位" :span="3">{{task?.ext?.tf_masterUnitNameStr}}
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="协办单位" :span="3">{{task?.ext?.tf_slaveUnitNameStr}}
|
|
||||||
</el-descriptions-item>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
<el-descriptions-item label="办理意见" :span="3">
|
<el-descriptions-item label="办理意见" :span="3">
|
||||||
<div v-html="task.taskFormData.tf_opinion"></div>
|
<div v-html="replyTask.taskFormData.tf_opinion"></div>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
|
</template>
|
||||||
|
<el-descriptions border class="flow-task-form" :column="3" :key="task.id"
|
||||||
|
v-else-if="task.ext.isFirstTaskNode">
|
||||||
|
<el-descriptions-item label="申请用户">{{ task.ext.initiatorName
|
||||||
|
}}({{task.ext.initiatorAccount}})
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="申请时间">{{ task.finishTime }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="办理结果">
|
||||||
|
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
|
||||||
|
:value="task.ext.submitType"></dict-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
|
||||||
<el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-else>
|
<!--邀请附议人-->
|
||||||
<el-descriptions-item label="承办单位"
|
<el-descriptions border class="flow-task-form" :column="3" :key="task.id"
|
||||||
v-if="['opinion_unit_reply','unit_reply','two_unit_reply','opinion_master_reply','master_reply','slave_reply'].includes(task.taskName)"
|
v-else-if="task.taskName === 'invite'">
|
||||||
:span="3">
|
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName
|
||||||
{{task.ext.underTakeName}}
|
}}({{task.taskFormData.loginName}})
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="办理时间" :span="2">{{ task.finishTime }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="附议人" :span="3" v-if="task.taskName === 'invite'">
|
||||||
|
<el-table v-loading="tableLoading" :data="task?.taskFormData?.seconder">
|
||||||
|
<el-table-column label="姓名" prop="userName"></el-table-column>
|
||||||
|
<el-table-column label="工号" prop="loginName"></el-table-column>
|
||||||
|
<el-table-column label="性别" prop="sex"></el-table-column>
|
||||||
|
<el-table-column label="联系方式" prop="mobile"></el-table-column>
|
||||||
|
<el-table-column label="单位" prop="unitName"></el-table-column>
|
||||||
|
<el-table-column label="分工会" prop="unionName"></el-table-column>
|
||||||
|
<el-table-column label="代表团" prop="delegationName"></el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
|
||||||
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName
|
<!--提案委员会立案-->
|
||||||
}}({{task.taskFormData.loginName}})
|
<el-descriptions border class="flow-task-form" :column="3" :key="task.id"
|
||||||
</el-descriptions-item>
|
v-else-if="task.taskName === 'committee'||task.taskName === 'committeeFilingUnit'">
|
||||||
<el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>
|
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName
|
||||||
|
}}({{task.taskFormData.loginName}})
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="立案结果">
|
||||||
|
<div style="display: flex;justify-content: center">
|
||||||
|
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
|
||||||
|
:value="task.ext.tf_caseFilingResult"></dict-tag>
|
||||||
|
|
||||||
<el-descriptions-item label="办理评价" v-if="['feedback'].includes(task.taskName)"
|
<!-- 普通提案/重点提案暂不展示,历史流程变量仍保留。 -->
|
||||||
:span="3">
|
<template v-if="false">
|
||||||
<dict-tag :options="dict.type.PROPOSAL_FEEDBACK"
|
(
|
||||||
:value="task.ext.tf_feedback"></dict-tag>
|
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
|
||||||
|
:value="task.ext.tf_caseFilingType"></dict-tag>
|
||||||
|
)
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<template v-if="['CONFIRM_FILING','SUGGESTION'].includes(task.ext.tf_caseFilingResult)">
|
||||||
|
<el-descriptions-item v-if="task.ext.tf_caseFilingResult === 'SUGGESTION'" label="承办单位" :span="3">{{task?.ext?.tf_masterUnitNameStr || task?.ext?.tf_slaveUnitNameStr}}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="办理结果" v-else>
|
<template v-else>
|
||||||
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
|
<el-descriptions-item label="主办单位" :span="3">{{task?.ext?.tf_masterUnitNameStr}}
|
||||||
:value="task.ext.submitType"></dict-tag>
|
</el-descriptions-item>
|
||||||
</el-descriptions-item>
|
<el-descriptions-item label="协办单位" :span="3">{{task?.ext?.tf_slaveUnitNameStr}}
|
||||||
<el-descriptions-item label="办理意见" :span="3" v-if="!task.ext.isFirstTaskNode">
|
</el-descriptions-item>
|
||||||
<div v-html="task.taskFormData.tf_opinion"></div>
|
</template>
|
||||||
</el-descriptions-item>
|
</template>
|
||||||
</el-descriptions>
|
<el-descriptions-item label="办理意见" :span="3">
|
||||||
|
<div v-html="task.taskFormData.tf_opinion"></div>
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
|
||||||
|
<el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-else>
|
||||||
|
<el-descriptions-item label="承办单位"
|
||||||
|
v-if="['opinion_unit_reply','unit_reply','two_unit_reply','opinion_master_reply','master_reply','slave_reply'].includes(task.taskName)" :span="3">
|
||||||
|
{{task.ext.underTakeName}}
|
||||||
|
</el-descriptions-item>
|
||||||
|
|
||||||
|
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName
|
||||||
|
}}({{task.taskFormData.loginName}})
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>
|
||||||
|
|
||||||
|
<el-descriptions-item label="办理评价" v-if="['feedback'].includes(task.taskName)" :span="3">
|
||||||
|
<dict-tag :options="dict.type.PROPOSAL_FEEDBACK"
|
||||||
|
:value="task.ext.tf_feedback"></dict-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="办理结果" v-else>
|
||||||
|
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
|
||||||
|
:value="task.ext.submitType"></dict-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="办理意见" :span="3" v-if="!task.ext.isFirstTaskNode">
|
||||||
|
<div v-html="task.taskFormData.tf_opinion"></div>
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
</el-collapse>
|
</el-collapse>
|
||||||
</template>
|
</template>
|
||||||
@@ -270,7 +243,7 @@ const PROPOSAL_INFO = {
|
|||||||
<snaker-chart ref="snakerChartRef"></snaker-chart>
|
<snaker-chart ref="snakerChartRef"></snaker-chart>
|
||||||
</div>
|
</div>
|
||||||
`,
|
`,
|
||||||
dicts: ["PROPOSAL_TYPE", "PROPOSAL_SOURCE", "PROPOSAL_CASE_FILING_RESULT", "PROPOSAL_CASE_FILING_TYPE", "PROCESS_TASK_SUBMIT_TYPE", "PROPOSAL_FEEDBACK"],
|
dicts: ["PROPOSAL_TYPE", "PROPOSAL_CASE_FILING_RESULT", "PROPOSAL_CASE_FILING_TYPE", "PROCESS_TASK_SUBMIT_TYPE", "PROPOSAL_FEEDBACK"],
|
||||||
props: {
|
props: {
|
||||||
hide_slave: false
|
hide_slave: false
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -60,10 +60,7 @@ const USER_COMPONENT = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
filterUnit(query, item) {
|
filterUnit(query, item) {
|
||||||
// 按姓名或工号筛选人员,字段为空时按空字符串处理。
|
return item.username.indexOf(query) > -1
|
||||||
const username = item.username || ""
|
|
||||||
const loginname = item.loginname || ""
|
|
||||||
return username.indexOf(query) > -1 || loginname.indexOf(query) > -1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ layout("/layouts/platform.html"){
|
|||||||
</el-card>
|
</el-card>
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
<table-tool :columns.sync="tableColumns">
|
<table-tool :columns.sync="tableColumns">
|
||||||
<!-- <el-button class="ml5" icon="el-icon-upload2" type="primary" size="small"
|
<el-button class="ml5" icon="el-icon-upload2" type="primary" size="small"
|
||||||
@click="openImport">导入提案
|
@click="openImport">导入提案
|
||||||
</el-button>-->
|
</el-button>
|
||||||
</table-tool>
|
</table-tool>
|
||||||
<el-table v-loading="tableLoading" :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%" row-key="id">
|
<el-table v-loading="tableLoading" :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%" row-key="id">
|
||||||
<el-table-column label="序号" width="50" type="index" :index="indexMethod" fixed="left"></el-table-column>
|
<el-table-column label="序号" width="50" type="index" :index="indexMethod" fixed="left"></el-table-column>
|
||||||
@@ -76,7 +76,8 @@ layout("/layouts/platform.html"){
|
|||||||
<el-button v-if="row.canRevoke" size="mini" type="danger" @click="openRevoke(row)">
|
<el-button v-if="row.canRevoke" size="mini" type="danger" @click="openRevoke(row)">
|
||||||
撤回
|
撤回
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button v-if="row.taskKey === 'startTask' || !row.instanceId" size="mini" type="danger" @click="del(row.id)">
|
<!-- v-if="row.taskKey === 'startTask' || !row.instanceId"-->
|
||||||
|
<el-button size="mini" type="danger" @click="del(row.id)">
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ layout("/layouts/platform.html"){
|
|||||||
<custom-card>
|
<custom-card>
|
||||||
<snaker-start slot="header" label="撰写提案" define_key="JDHTA_NC">
|
<snaker-start slot="header" label="撰写提案" define_key="JDHTA_NC">
|
||||||
<template slot="header-right-label">
|
<template slot="header-right-label">
|
||||||
<!-- <el-link type="primary" @click="openImport" v-if="!formData.id" style="margin-right: 15px">导入提案</el-link>-->
|
<el-link type="primary" @click="openImport" v-if="!formData.id" style="margin-right: 15px">导入提案</el-link>
|
||||||
</template>
|
</template>
|
||||||
</snaker-start>
|
</snaker-start>
|
||||||
<el-form :model="formData" :rules="formRules" label-width="120px" ref="addForm">
|
<el-form :model="formData" :rules="formRules" label-width="120px" ref="addForm">
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<van-cell title="会长">{{ clubDetail.clubLeader || '--' }}</van-cell>
|
<van-cell title="会长">{{ clubDetail.clubLeader || '--' }}</van-cell>
|
||||||
<van-cell title="秘书长">{{ clubDetail.clubSecretary || '--' }}</van-cell>
|
<van-cell title="秘书长">{{ clubDetail.clubSecretary || '--' }}</van-cell>
|
||||||
<van-cell title="当前人数">{{ clubDetail.currentPeopleNum || 0 }} 人</van-cell>
|
<van-cell title="当前人数">{{ clubDetail.currentPeopleNum || 0 }} 人</van-cell>
|
||||||
<van-cell title="会费标准">{{ clubDetail.due || '--' }}</van-cell>
|
<van-cell title="会费标准">{{ clubDetail.due === null || clubDetail.due === undefined ? '--' : clubDetail.due + ' 元/年' }}</van-cell>
|
||||||
<van-cell title="社团介绍" class="club-user-join-info-long-cell"><div v-if="hasClubContent(clubDetail.introduce)" v-html="clubDetail.introduce"></div><span v-else>暂无</span></van-cell>
|
<van-cell title="社团介绍" class="club-user-join-info-long-cell"><div v-if="hasClubContent(clubDetail.introduce)" v-html="clubDetail.introduce"></div><span v-else>暂无</span></van-cell>
|
||||||
<van-cell title="社团宗旨" class="club-user-join-info-long-cell"><div v-if="hasClubContent(clubDetail.purpose)" v-html="clubDetail.purpose"></div><span v-else>暂无</span></van-cell>
|
<van-cell title="社团宗旨" class="club-user-join-info-long-cell"><div v-if="hasClubContent(clubDetail.purpose)" v-html="clubDetail.purpose"></div><span v-else>暂无</span></van-cell>
|
||||||
<van-cell title="社团章程" class="club-user-join-info-long-cell"><file-preview v-if="clubDetail.rulesFile && clubDetail.rulesFile.length" :files="clubDetail.rulesFile" complete_result></file-preview><span v-else>暂无</span></van-cell>
|
<van-cell title="社团章程" class="club-user-join-info-long-cell"><file-preview v-if="clubDetail.rulesFile && clubDetail.rulesFile.length" :files="clubDetail.rulesFile" complete_result></file-preview><span v-else>暂无</span></van-cell>
|
||||||
|
|||||||
@@ -9,30 +9,26 @@ const PROPOSAL_INFO = {
|
|||||||
<van-cell-group :border="false">
|
<van-cell-group :border="false">
|
||||||
<van-cell title="提案编号">{{ viewData.code || '--' }}</van-cell>
|
<van-cell title="提案编号">{{ viewData.code || '--' }}</van-cell>
|
||||||
<van-cell title="提案名称">{{ viewData.name || '--' }}</van-cell>
|
<van-cell title="提案名称">{{ viewData.name || '--' }}</van-cell>
|
||||||
|
<van-cell title="立案结果" v-if="viewData.caseFilingResult">
|
||||||
<van-cell title="提案类别">{{ viewData.typeName || '--' }}</van-cell>
|
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
|
||||||
|
:value="viewData.caseFilingResult"></dict-tag>
|
||||||
|
</van-cell>
|
||||||
|
<van-cell title="立案类型" v-if="viewData.caseFilingType">
|
||||||
|
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
|
||||||
|
:value="viewData.caseFilingType"></dict-tag>
|
||||||
|
</van-cell>
|
||||||
|
<van-cell title="提案类型">{{ viewData.typeName || '--' }}</van-cell>
|
||||||
<van-cell title="提案方式">{{ getDictText(dict.type.PROPOSAL_SOURCE, viewData.source) }}
|
<van-cell title="提案方式">{{ getDictText(dict.type.PROPOSAL_SOURCE, viewData.source) }}
|
||||||
</van-cell>
|
</van-cell>
|
||||||
<van-cell title="提案人">{{ viewData.createUserName || '--' }}</van-cell>
|
<van-cell title="代表姓名">{{ viewData.createUserName || '--' }}</van-cell>
|
||||||
<van-cell title="教代会届次">{{ viewData.sessionName || viewData.fullName || '--' }}</van-cell>
|
<van-cell title="所属教代会">{{ viewData.sessionName || viewData.fullName || '--' }}</van-cell>
|
||||||
<van-cell :title="viewData.committeeName ? '委员会名称' : '代表团名称'">
|
<van-cell :title="viewData.committeeName ? '所属委员会' : '所属代表团'">
|
||||||
{{ viewData.committeeName || viewData.delegationName || '--' }}
|
{{ viewData.committeeName || viewData.delegationName || '--' }}
|
||||||
</van-cell>
|
</van-cell>
|
||||||
<van-cell title="提案人单位">{{ viewData.unitName || '--' }}</van-cell>
|
<van-cell title="单位">{{ viewData.unitName || '--' }}</van-cell>
|
||||||
<van-cell title="联系电话">{{ viewData.mobile || '--' }}</van-cell>
|
<van-cell title="联系电话">{{ viewData.mobile || '--' }}</van-cell>
|
||||||
<van-cell title="提案时间">{{ viewData.createTime || '--' }}</van-cell>
|
<van-cell title="提案时间">{{ viewData.createTime || '--' }}</van-cell>
|
||||||
<!-- 立案结果和类型尚未填写时仍显示字段,并以双横线表示空值。 -->
|
<van-cell title="案由" class="proposal-view-long-cell">
|
||||||
<van-cell title="立案结果">
|
|
||||||
<dict-tag v-if="viewData.caseFilingResult" :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
|
|
||||||
:value="viewData.caseFilingResult"></dict-tag>
|
|
||||||
<span v-else>--</span>
|
|
||||||
</van-cell>
|
|
||||||
<van-cell title="立案类型">
|
|
||||||
<dict-tag v-if="viewData.caseFilingType" :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
|
|
||||||
:value="viewData.caseFilingType"></dict-tag>
|
|
||||||
<span v-else>--</span>
|
|
||||||
</van-cell>
|
|
||||||
<van-cell title="提案案由" class="proposal-view-long-cell">
|
|
||||||
<div class="proposal-view-rich-value" v-html="viewData.brief || '--'"></div>
|
<div class="proposal-view-rich-value" v-html="viewData.brief || '--'"></div>
|
||||||
</van-cell>
|
</van-cell>
|
||||||
<van-cell title="建议措施" class="proposal-view-long-cell">
|
<van-cell title="建议措施" class="proposal-view-long-cell">
|
||||||
@@ -52,7 +48,7 @@ const PROPOSAL_INFO = {
|
|||||||
:key="merge.id"
|
:key="merge.id"
|
||||||
class="proposal-view-merge-cell"
|
class="proposal-view-merge-cell"
|
||||||
:title="(index + 1) + '. ' + merge.name"
|
:title="(index + 1) + '. ' + merge.name"
|
||||||
:label="'提案编号:' + merge.code + '|提案人:' + merge.createUserName + '|提案类别:' + merge.typeName + '|代表团:' + merge.delegationName"
|
:label="'提案编号:' + merge.code + '|提案人:' + merge.createUserName + '|类别:' + merge.typeName + '|代表团:' + merge.delegationName"
|
||||||
is-link
|
is-link
|
||||||
@click="openView(merge)">
|
@click="openView(merge)">
|
||||||
</van-cell>
|
</van-cell>
|
||||||
@@ -70,16 +66,13 @@ const PROPOSAL_INFO = {
|
|||||||
<template v-if="opinion.commissionerLoginName">({{ opinion.commissionerLoginName }})
|
<template v-if="opinion.commissionerLoginName">({{ opinion.commissionerLoginName }})
|
||||||
</template>
|
</template>
|
||||||
</van-cell>
|
</van-cell>
|
||||||
<!-- 委员意见分别展示立案结果和类型,未填写时显示双横线。 -->
|
|
||||||
<van-cell title="立案结果">
|
<van-cell title="立案结果">
|
||||||
<dict-tag v-if="opinion.caseFilingResult" :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
|
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
|
||||||
:value="opinion.caseFilingResult"></dict-tag>
|
:value="opinion.caseFilingResult"></dict-tag>
|
||||||
<span v-else>--</span>
|
|
||||||
</van-cell>
|
</van-cell>
|
||||||
<van-cell title="立案类型">
|
<van-cell title="立案类型" v-if="opinion.caseFilingType">
|
||||||
<dict-tag v-if="opinion.caseFilingType" :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
|
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
|
||||||
:value="opinion.caseFilingType"></dict-tag>
|
:value="opinion.caseFilingType"></dict-tag>
|
||||||
<span v-else>--</span>
|
|
||||||
</van-cell>
|
</van-cell>
|
||||||
<van-cell title="意见" v-if="opinion.opinionText" class="proposal-view-long-cell">
|
<van-cell title="意见" v-if="opinion.opinionText" class="proposal-view-long-cell">
|
||||||
<div class="proposal-view-rich-value">{{ opinion.opinionText }}</div>
|
<div class="proposal-view-rich-value">{{ opinion.opinionText }}</div>
|
||||||
@@ -165,18 +158,13 @@ const PROPOSAL_INFO = {
|
|||||||
|| '--' }})
|
|| '--' }})
|
||||||
</van-cell>
|
</van-cell>
|
||||||
<van-cell title="办理时间">{{ selectedTask.finishTime || '--' }}</van-cell>
|
<van-cell title="办理时间">{{ selectedTask.finishTime || '--' }}</van-cell>
|
||||||
<!-- 立案节点分别展示流程记录中的结果与类型,空值显示双横线。 -->
|
|
||||||
<van-cell title="立案结果">
|
<van-cell title="立案结果">
|
||||||
<dict-tag v-if="selectedTask.ext.tf_caseFilingResult"
|
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
|
||||||
:options="dict.type.PROPOSAL_CASE_FILING_RESULT"
|
|
||||||
:value="selectedTask.ext.tf_caseFilingResult"></dict-tag>
|
:value="selectedTask.ext.tf_caseFilingResult"></dict-tag>
|
||||||
<span v-else>--</span>
|
|
||||||
</van-cell>
|
</van-cell>
|
||||||
<van-cell title="立案类型">
|
<van-cell title="立案类型" v-if="selectedTask.ext.tf_caseFilingType">
|
||||||
<dict-tag v-if="selectedTask.ext.tf_caseFilingType"
|
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
|
||||||
:options="dict.type.PROPOSAL_CASE_FILING_TYPE"
|
|
||||||
:value="selectedTask.ext.tf_caseFilingType"></dict-tag>
|
:value="selectedTask.ext.tf_caseFilingType"></dict-tag>
|
||||||
<span v-else>--</span>
|
|
||||||
</van-cell>
|
</van-cell>
|
||||||
<template
|
<template
|
||||||
v-if="['CONFIRM_FILING', 'SUGGESTION'].includes(selectedTask.ext.tf_caseFilingResult)">
|
v-if="['CONFIRM_FILING', 'SUGGESTION'].includes(selectedTask.ext.tf_caseFilingResult)">
|
||||||
@@ -199,7 +187,7 @@ const PROPOSAL_INFO = {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<van-cell title="承办单位"
|
<van-cell title="办理单位"
|
||||||
v-if="['opinion_unit_reply', 'unit_reply', 'two_unit_reply', 'opinion_master_reply', 'master_reply', 'slave_reply'].includes(selectedTask.taskName)">
|
v-if="['opinion_unit_reply', 'unit_reply', 'two_unit_reply', 'opinion_master_reply', 'master_reply', 'slave_reply'].includes(selectedTask.taskName)">
|
||||||
{{ selectedTask.ext.underTakeName || '--' }}
|
{{ selectedTask.ext.underTakeName || '--' }}
|
||||||
</van-cell>
|
</van-cell>
|
||||||
|
|||||||
Reference in New Issue
Block a user