疗休养模块优化整改
This commit is contained in:
+5
-2
@@ -83,7 +83,10 @@ public class TourGroupController {
|
|||||||
m.`year`,
|
m.`year`,
|
||||||
m.matterName,
|
m.matterName,
|
||||||
m.unionId,
|
m.unionId,
|
||||||
COALESCE(u.name, '校工会') AS unionName,
|
CASE
|
||||||
|
WHEN IFNULL(NULLIF(m.undertakeStatus, ''), 'unclaimed') = 'claimed' THEN COALESCE(u.name, '校工会')
|
||||||
|
ELSE ''
|
||||||
|
END AS unionName,
|
||||||
m.lineId,
|
m.lineId,
|
||||||
l.lineName,
|
l.lineName,
|
||||||
l.lineType,
|
l.lineType,
|
||||||
@@ -632,7 +635,7 @@ public class TourGroupController {
|
|||||||
return "m.matterName";
|
return "m.matterName";
|
||||||
}
|
}
|
||||||
if ("unionName".equals(orderName)) {
|
if ("unionName".equals(orderName)) {
|
||||||
return "u.name";
|
return "CASE WHEN IFNULL(NULLIF(m.undertakeStatus, ''), 'unclaimed') = 'claimed' THEN COALESCE(u.name, '校工会') ELSE '' END";
|
||||||
}
|
}
|
||||||
if ("lineType".equals(orderName)) {
|
if ("lineType".equals(orderName)) {
|
||||||
return "l.lineType";
|
return "l.lineType";
|
||||||
|
|||||||
+47
-5
@@ -36,6 +36,8 @@ import java.util.stream.Collectors;
|
|||||||
@At("/platform/tour/route")
|
@At("/platform/tour/route")
|
||||||
public class TourLineController {
|
public class TourLineController {
|
||||||
|
|
||||||
|
private static final String SORT_CODE_PATTERN = "^\\d+$";
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private TourLineService tourLineService;
|
private TourLineService tourLineService;
|
||||||
|
|
||||||
@@ -52,7 +54,7 @@ public class TourLineController {
|
|||||||
@SaCheckPermission("tour.route")
|
@SaCheckPermission("tour.route")
|
||||||
public Result pageData(PageForm pageForm, Integer year, String lineName, String lotId) {
|
public Result pageData(PageForm pageForm, Integer year, String lineName, String lotId) {
|
||||||
if (StrUtil.isBlank(pageForm.getPageOrderName())) {
|
if (StrUtil.isBlank(pageForm.getPageOrderName())) {
|
||||||
pageForm.defaultSortDesc("enabled");
|
pageForm.defaultSortAsc("lineCode");
|
||||||
}
|
}
|
||||||
|
|
||||||
Cnd cnd = Cnd.NEW();
|
Cnd cnd = Cnd.NEW();
|
||||||
@@ -91,7 +93,7 @@ public class TourLineController {
|
|||||||
LEFT JOIN tour_setting_lot lot ON lot.id = l.lotId
|
LEFT JOIN tour_setting_lot lot ON lot.id = l.lotId
|
||||||
$creatorJoin
|
$creatorJoin
|
||||||
$condition
|
$condition
|
||||||
ORDER BY $orderColumn $orderBy, l.`year` DESC, l.lineCode ASC, l.createdAt DESC
|
ORDER BY $orderColumn $orderBy, l.`year` DESC, CAST(l.lineCode AS UNSIGNED) ASC, l.createdAt DESC
|
||||||
""");
|
""");
|
||||||
listSql.setVar("creatorJoin", creatorJoin);
|
listSql.setVar("creatorJoin", creatorJoin);
|
||||||
listSql.setCondition(cnd);
|
listSql.setCondition(cnd);
|
||||||
@@ -168,7 +170,7 @@ public class TourLineController {
|
|||||||
sameCodeCnd.and(TourLine::getId, "<>", line.getId());
|
sameCodeCnd.and(TourLine::getId, "<>", line.getId());
|
||||||
}
|
}
|
||||||
if (tourLineService.count(sameCodeCnd) > 0) {
|
if (tourLineService.count(sameCodeCnd) > 0) {
|
||||||
return Result.error("同年度下线路编号已存在");
|
return Result.error("同年度下排序编号已存在");
|
||||||
}
|
}
|
||||||
if (line.getEnabled() == null) {
|
if (line.getEnabled() == null) {
|
||||||
line.setEnabled(true);
|
line.setEnabled(true);
|
||||||
@@ -197,10 +199,47 @@ public class TourLineController {
|
|||||||
if (StrUtil.isBlank(id)) {
|
if (StrUtil.isBlank(id)) {
|
||||||
return Result.error("参数错误");
|
return Result.error("参数错误");
|
||||||
}
|
}
|
||||||
|
TourLine line = tourLineService.fetch(id);
|
||||||
|
if (line == null) {
|
||||||
|
return Result.error("线路不存在");
|
||||||
|
}
|
||||||
|
if (countLineSignup(id) > 0) {
|
||||||
|
return Result.error("当前线路已有人员报名,不能删除");
|
||||||
|
}
|
||||||
|
if (countLineMatter(id) > 0) {
|
||||||
|
return Result.error("当前线路已关联事项,不能删除");
|
||||||
|
}
|
||||||
tourLineService.delete(id);
|
tourLineService.delete(id);
|
||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int countLineSignup(String lineId) {
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT COUNT(1)
|
||||||
|
FROM tour_ledger t
|
||||||
|
LEFT JOIN tour_matter m ON m.id = t.matterId
|
||||||
|
WHERE t.delFlag = 0
|
||||||
|
AND (t.lineId = @lineId OR m.lineId = @lineId)
|
||||||
|
""");
|
||||||
|
sql.setParam("lineId", lineId);
|
||||||
|
sql.setCallback(Sqls.callback.integer());
|
||||||
|
tourLineService.dao().execute(sql);
|
||||||
|
return sql.getInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int countLineMatter(String lineId) {
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT COUNT(1)
|
||||||
|
FROM tour_matter
|
||||||
|
WHERE delFlag = 0
|
||||||
|
AND lineId = @lineId
|
||||||
|
""");
|
||||||
|
sql.setParam("lineId", lineId);
|
||||||
|
sql.setCallback(Sqls.callback.integer());
|
||||||
|
tourLineService.dao().execute(sql);
|
||||||
|
return sql.getInt();
|
||||||
|
}
|
||||||
|
|
||||||
private Result check(TourLine line) {
|
private Result check(TourLine line) {
|
||||||
if (line == null) {
|
if (line == null) {
|
||||||
return Result.error("参数错误");
|
return Result.error("参数错误");
|
||||||
@@ -215,7 +254,10 @@ public class TourLineController {
|
|||||||
return Result.error("线路名称不能为空");
|
return Result.error("线路名称不能为空");
|
||||||
}
|
}
|
||||||
if (StrUtil.isBlank(line.getLineCode())) {
|
if (StrUtil.isBlank(line.getLineCode())) {
|
||||||
return Result.error("线路编号不能为空");
|
return Result.error("排序编号不能为空");
|
||||||
|
}
|
||||||
|
if (!line.getLineCode().matches(SORT_CODE_PATTERN)) {
|
||||||
|
return Result.error("排序编号必须为整数");
|
||||||
}
|
}
|
||||||
if (StrUtil.isBlank(line.getLineType())) {
|
if (StrUtil.isBlank(line.getLineType())) {
|
||||||
return Result.error("线路类型不能为空");
|
return Result.error("线路类型不能为空");
|
||||||
@@ -281,7 +323,7 @@ public class TourLineController {
|
|||||||
return "l.`year`";
|
return "l.`year`";
|
||||||
}
|
}
|
||||||
if ("lineCode".equals(orderName)) {
|
if ("lineCode".equals(orderName)) {
|
||||||
return "l.lineCode";
|
return "CAST(l.lineCode AS UNSIGNED)";
|
||||||
}
|
}
|
||||||
if ("lotName".equals(orderName)) {
|
if ("lotName".equals(orderName)) {
|
||||||
return "lot.lotName";
|
return "lot.lotName";
|
||||||
|
|||||||
+97
-12
@@ -76,7 +76,10 @@ public class TourMatterController {
|
|||||||
SELECT
|
SELECT
|
||||||
m.*,
|
m.*,
|
||||||
s.configName AS settingName,
|
s.configName AS settingName,
|
||||||
u.name AS unionName,
|
CASE
|
||||||
|
WHEN IFNULL(NULLIF(m.undertakeStatus, ''), 'unclaimed') = 'claimed' THEN COALESCE(u.name, '校工会')
|
||||||
|
ELSE ''
|
||||||
|
END AS unionName,
|
||||||
d.name AS organizationTypeName,
|
d.name AS organizationTypeName,
|
||||||
l.lineName AS lineName,
|
l.lineName AS lineName,
|
||||||
l.lineType AS lineType,
|
l.lineType AS lineType,
|
||||||
@@ -157,6 +160,35 @@ public class TourMatterController {
|
|||||||
return Result.success(sql.getList(NutMap.class));
|
return Result.success(sql.getList(NutMap.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckPermission("tour.matter")
|
||||||
|
public Result lineInfo(String lineId) {
|
||||||
|
if (StrUtil.isBlank(lineId)) {
|
||||||
|
return Result.error("参数错误");
|
||||||
|
}
|
||||||
|
Cnd cnd = Cnd.NEW();
|
||||||
|
cnd.and("l.delFlag", "=", false);
|
||||||
|
cnd.and("l.enabled", "=", true);
|
||||||
|
cnd.and("l.id", "=", lineId);
|
||||||
|
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
l.*,
|
||||||
|
lot.lotName AS lotName,
|
||||||
|
lot.lotValue AS lotValue,
|
||||||
|
lot.lotValue AS lotDays,
|
||||||
|
lot.activityCost AS activityCost
|
||||||
|
FROM tour_line l
|
||||||
|
LEFT JOIN tour_setting_lot lot ON lot.id = l.lotId
|
||||||
|
$condition
|
||||||
|
""");
|
||||||
|
sql.setCondition(cnd);
|
||||||
|
sql.setCallback(Sqls.callback.map());
|
||||||
|
tourMatterService.dao().execute(sql);
|
||||||
|
NutMap line = sql.getObject(NutMap.class);
|
||||||
|
return line == null || line.isEmpty() ? Result.error("线路不存在") : Result.success(line);
|
||||||
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission("tour.matter")
|
@SaCheckPermission("tour.matter")
|
||||||
public Result organizationTypeOptions() {
|
public Result organizationTypeOptions() {
|
||||||
@@ -194,7 +226,7 @@ public class TourMatterController {
|
|||||||
} else {
|
} else {
|
||||||
tourMatterService.updateIgnoreNull(matter);
|
tourMatterService.updateIgnoreNull(matter);
|
||||||
}
|
}
|
||||||
return Result.success();
|
return Result.success(NutMap.NEW().addv("id", matter.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@@ -246,21 +278,31 @@ public class TourMatterController {
|
|||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission("tour.matter")
|
@SaCheckPermission("tour.matter")
|
||||||
public Result settingPeople(String matterId) {
|
public Result settingPeople(String matterId, Integer year) {
|
||||||
if (StrUtil.isBlank(matterId)) {
|
if (StrUtil.isBlank(matterId) && year == null) {
|
||||||
return Result.error("参数错误");
|
return Result.error("参数错误");
|
||||||
}
|
}
|
||||||
TourMatter matter = tourMatterService.fetch(matterId);
|
return Result.success(settingDefaults(year, matterId));
|
||||||
if (matter == null || StrUtil.isBlank(matter.getSettingId())) {
|
}
|
||||||
return Result.success(NutMap.NEW());
|
|
||||||
|
private NutMap settingDefaults(Integer year, String matterId) {
|
||||||
|
TourMatter matter = null;
|
||||||
|
if (StrUtil.isNotBlank(matterId)) {
|
||||||
|
matter = tourMatterService.fetch(matterId);
|
||||||
|
}
|
||||||
|
Integer settingYear = year != null ? year : (matter == null ? null : matter.getYear());
|
||||||
|
TourSetting setting = fetchSettingByYear(settingYear);
|
||||||
|
if (setting == null && matter != null && StrUtil.isNotBlank(matter.getSettingId())) {
|
||||||
|
setting = tourMatterService.dao().fetch(TourSetting.class, matter.getSettingId());
|
||||||
}
|
}
|
||||||
TourSetting setting = tourMatterService.dao().fetch(TourSetting.class, matter.getSettingId());
|
|
||||||
if (setting == null) {
|
if (setting == null) {
|
||||||
return Result.success(NutMap.NEW());
|
return NutMap.NEW();
|
||||||
}
|
}
|
||||||
return Result.success(NutMap.NEW()
|
return NutMap.NEW()
|
||||||
.addv("minGroupPeople", setting.getMinGroupPeople())
|
.addv("minGroupPeople", setting.getMinGroupPeople())
|
||||||
.addv("maxGroupPeople", setting.getMaxGroupPeople()));
|
.addv("maxGroupPeople", setting.getMaxGroupPeople())
|
||||||
|
.addv("signupStartTime", setting.getSignupStartTime())
|
||||||
|
.addv("signupEndTime", setting.getSignupEndTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@@ -268,6 +310,7 @@ public class TourMatterController {
|
|||||||
@SaCheckPermission("tour.matter")
|
@SaCheckPermission("tour.matter")
|
||||||
@SLog(type = "tour", tag = "疗休养事项", msg = "保存事项线路配置")
|
@SLog(type = "tour", tag = "疗休养事项", msg = "保存事项线路配置")
|
||||||
public Result lineConfigDoSubmit(TourMatter matter) {
|
public Result lineConfigDoSubmit(TourMatter matter) {
|
||||||
|
fillLineConfigFromSetting(matter);
|
||||||
Result checkResult = checkLineConfig(matter);
|
Result checkResult = checkLineConfig(matter);
|
||||||
if (checkResult != null) {
|
if (checkResult != null) {
|
||||||
return checkResult;
|
return checkResult;
|
||||||
@@ -290,6 +333,48 @@ public class TourMatterController {
|
|||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void fillLineConfigFromSetting(TourMatter matter) {
|
||||||
|
if (matter == null || StrUtil.isBlank(matter.getId())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TourMatter oldMatter = tourMatterService.fetch(matter.getId());
|
||||||
|
if (oldMatter == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TourSetting setting = fetchSettingByYear(oldMatter.getYear());
|
||||||
|
if (setting == null && StrUtil.isNotBlank(oldMatter.getSettingId())) {
|
||||||
|
setting = tourMatterService.dao().fetch(TourSetting.class, oldMatter.getSettingId());
|
||||||
|
}
|
||||||
|
if (setting == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (setting.getMinGroupPeople() != null) {
|
||||||
|
matter.setMinGroupPeople(setting.getMinGroupPeople());
|
||||||
|
}
|
||||||
|
if (setting.getMaxGroupPeople() != null) {
|
||||||
|
matter.setMaxGroupPeople(setting.getMaxGroupPeople());
|
||||||
|
}
|
||||||
|
if (StrUtil.isNotBlank(setting.getSignupStartTime())) {
|
||||||
|
matter.setSignupStartTime(setting.getSignupStartTime());
|
||||||
|
}
|
||||||
|
if (StrUtil.isNotBlank(setting.getSignupEndTime())) {
|
||||||
|
matter.setSignupEndTime(setting.getSignupEndTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private TourSetting fetchSettingByYear(Integer year) {
|
||||||
|
if (year == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Cnd cnd = Cnd.where(TourSetting::getEnabled, "=", true);
|
||||||
|
cnd.and("delFlag", "=", false);
|
||||||
|
cnd.and(TourSetting::getYear, "=", year);
|
||||||
|
cnd.desc(TourSetting::getCreatedAt);
|
||||||
|
cnd.desc(TourSetting::getUpdatedAt);
|
||||||
|
cnd.asc(TourSetting::getConfigName);
|
||||||
|
return tourMatterService.dao().fetch(TourSetting.class, cnd);
|
||||||
|
}
|
||||||
|
|
||||||
private Result check(TourMatter matter) {
|
private Result check(TourMatter matter) {
|
||||||
if (matter == null) {
|
if (matter == null) {
|
||||||
return Result.error("参数错误");
|
return Result.error("参数错误");
|
||||||
@@ -422,7 +507,7 @@ public class TourMatterController {
|
|||||||
return "m.matterName";
|
return "m.matterName";
|
||||||
}
|
}
|
||||||
if ("unionName".equals(orderName)) {
|
if ("unionName".equals(orderName)) {
|
||||||
return "u.name";
|
return "CASE WHEN IFNULL(NULLIF(m.undertakeStatus, ''), 'unclaimed') = 'claimed' THEN COALESCE(u.name, '校工会') ELSE '' END";
|
||||||
}
|
}
|
||||||
if ("lineName".equals(orderName)) {
|
if ("lineName".equals(orderName)) {
|
||||||
return "l.lineName";
|
return "l.lineName";
|
||||||
|
|||||||
+45
-70
@@ -55,7 +55,6 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
@@ -146,6 +145,10 @@ public class TourMySignupController {
|
|||||||
IFNULL(GROUP_CONCAT(DISTINCT task.displayName), IF(ins.id IS NULL, '', '结束')) AS curTaskName,
|
IFNULL(GROUP_CONCAT(DISTINCT task.displayName), IF(ins.id IS NULL, '', '结束')) AS curTaskName,
|
||||||
IFNULL(f.familyCount, 0) AS familyCount,
|
IFNULL(f.familyCount, 0) AS familyCount,
|
||||||
COALESCE(m.travelEndTime, tp.travelEndTime) AS travelEndTime,
|
COALESCE(m.travelEndTime, tp.travelEndTime) AS travelEndTime,
|
||||||
|
CASE
|
||||||
|
WHEN IFNULL(NULLIF(m.undertakeStatus, ''), 'unclaimed') = 'claimed' THEN COALESCE(u.name, '校工会')
|
||||||
|
ELSE ''
|
||||||
|
END AS matterUnionName,
|
||||||
CASE
|
CASE
|
||||||
WHEN IFNULL(m.travelStartTime, '') <> '' AND IFNULL(m.travelEndTime, '') <> ''
|
WHEN IFNULL(m.travelStartTime, '') <> '' AND IFNULL(m.travelEndTime, '') <> ''
|
||||||
THEN CONCAT(m.travelStartTime, ' 至 ', m.travelEndTime)
|
THEN CONCAT(m.travelStartTime, ' 至 ', m.travelEndTime)
|
||||||
@@ -163,6 +166,7 @@ public class TourMySignupController {
|
|||||||
GROUP BY ledgerId
|
GROUP BY ledgerId
|
||||||
) f ON f.ledgerId = t.id
|
) f ON f.ledgerId = t.id
|
||||||
LEFT JOIN tour_matter m ON m.id = t.matterId AND m.delFlag = 0
|
LEFT JOIN tour_matter m ON m.id = t.matterId AND m.delFlag = 0
|
||||||
|
LEFT JOIN sys_union u ON u.id = m.unionId
|
||||||
LEFT JOIN (
|
LEFT JOIN (
|
||||||
SELECT
|
SELECT
|
||||||
`year`,
|
`year`,
|
||||||
@@ -213,7 +217,7 @@ public class TourMySignupController {
|
|||||||
.and(TourLedgerDirectRelative::getLedgerId, "=", ledger.getId()));
|
.and(TourLedgerDirectRelative::getLedgerId, "=", ledger.getId()));
|
||||||
NutMap signupConfig = getSignupConfig(ledger);
|
NutMap signupConfig = getSignupConfig(ledger);
|
||||||
return Result.success(NutMap.NEW()
|
return Result.success(NutMap.NEW()
|
||||||
.addv("ledger", ledger)
|
.addv("ledger", buildLedgerView(ledger))
|
||||||
.addv("travelPeriod", getTravelPeriod(ledger))
|
.addv("travelPeriod", getTravelPeriod(ledger))
|
||||||
.addv("families", tourLedgerFamilyService.query(familyCnd))
|
.addv("families", tourLedgerFamilyService.query(familyCnd))
|
||||||
.addv("directRelative", directRelative)
|
.addv("directRelative", directRelative)
|
||||||
@@ -326,11 +330,18 @@ public class TourMySignupController {
|
|||||||
.and(TourLedgerDirectRelative::getLedgerId, "=", ledger.getId()));
|
.and(TourLedgerDirectRelative::getLedgerId, "=", ledger.getId()));
|
||||||
return Result.success(NutMap.NEW()
|
return Result.success(NutMap.NEW()
|
||||||
.addv("matter", matter)
|
.addv("matter", matter)
|
||||||
.addv("ledger", ledger)
|
.addv("ledger", buildLedgerView(ledger))
|
||||||
.addv("families", tourLedgerFamilyService.query(familyCnd))
|
.addv("families", tourLedgerFamilyService.query(familyCnd))
|
||||||
.addv("directRelative", directRelative));
|
.addv("directRelative", directRelative));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private NutMap buildLedgerView(TourLedger ledger) {
|
||||||
|
NutMap map = Lang.obj2nutmap(ledger);
|
||||||
|
View_user user = tourLedgerService.dao().fetch(View_user.class, Cnd.where("loginname", "=", ledger.getJobNo()));
|
||||||
|
map.addv("mobile", defaultIfBlank(ledger.getMobile(), user == null ? "" : defaultIfBlank(user.getMobile(), "")));
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission(value = {"tour.mysignup", "h5.tour.mysignup"}, mode = SaMode.OR)
|
@SaCheckPermission(value = {"tour.mysignup", "h5.tour.mysignup"}, mode = SaMode.OR)
|
||||||
public Result directRelativeOptions() {
|
public Result directRelativeOptions() {
|
||||||
@@ -587,6 +598,9 @@ public class TourMySignupController {
|
|||||||
if (StrUtil.isBlank(ledger.getLineName())) {
|
if (StrUtil.isBlank(ledger.getLineName())) {
|
||||||
return Result.error("报名线路不能为空");
|
return Result.error("报名线路不能为空");
|
||||||
}
|
}
|
||||||
|
if (StrUtil.isBlank(ledger.getIdCard())) {
|
||||||
|
return Result.error("身份证号不能为空");
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,14 +626,16 @@ public class TourMySignupController {
|
|||||||
if (activityGroupId == null || !activityBasicScopeService.isUserInGroup(activityGroupId, SecurityUtil.getUserId())) {
|
if (activityGroupId == null || !activityBasicScopeService.isUserInGroup(activityGroupId, SecurityUtil.getUserId())) {
|
||||||
return Result.error("您不在本次疗休养报名范围内");
|
return Result.error("您不在本次疗休养报名范围内");
|
||||||
}
|
}
|
||||||
if (StrUtil.isBlank(matter.getSignupStartTime()) || StrUtil.isBlank(matter.getSignupEndTime())) {
|
String signupStartTime = defaultIfBlank(setting.getSignupStartTime(), matter.getSignupStartTime());
|
||||||
|
String signupEndTime = defaultIfBlank(setting.getSignupEndTime(), matter.getSignupEndTime());
|
||||||
|
if (StrUtil.isBlank(signupStartTime) || StrUtil.isBlank(signupEndTime)) {
|
||||||
return Result.error("报名时间未配置");
|
return Result.error("报名时间未配置");
|
||||||
}
|
}
|
||||||
String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||||
if (now.compareTo(normalizeDateTime(matter.getSignupStartTime(), false)) < 0) {
|
if (now.compareTo(normalizeDateTime(signupStartTime, false)) < 0) {
|
||||||
return Result.error("报名未开始");
|
return Result.error("报名未开始");
|
||||||
}
|
}
|
||||||
if (now.compareTo(normalizeDateTime(matter.getSignupEndTime(), true)) > 0) {
|
if (now.compareTo(normalizeDateTime(signupEndTime, true)) > 0) {
|
||||||
return Result.error("报名已结束");
|
return Result.error("报名已结束");
|
||||||
}
|
}
|
||||||
CycleAllowedTimes cycleAllowedTimes = calculateCycleAllowedTimes(matter, setting, oldLedger);
|
CycleAllowedTimes cycleAllowedTimes = calculateCycleAllowedTimes(matter, setting, oldLedger);
|
||||||
@@ -794,76 +810,35 @@ public class TourMySignupController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private OutProvinceQuota calculateOutProvinceQuota(TourMatter matter, TourSetting setting, TourLedger oldLedger) {
|
private OutProvinceQuota calculateOutProvinceQuota(TourMatter matter, TourSetting setting, TourLedger oldLedger) {
|
||||||
String ratioType = normalizeOutProvinceRatioType(setting == null ? null : setting.getOutProvinceRatioType());
|
|
||||||
BigDecimal originalRatio = setting == null ? null : setting.getOutProvinceRatio();
|
|
||||||
boolean oneThirdRatio = isOneThirdRatio(originalRatio);
|
|
||||||
BigDecimal ratio = oneThirdRatio ? BigDecimal.ONE.divide(BigDecimal.valueOf(3), 12, RoundingMode.HALF_UP)
|
|
||||||
: (originalRatio == null ? BigDecimal.ZERO : originalRatio);
|
|
||||||
int year = matter == null || matter.getYear() == null ? LocalDate.now().getYear() : matter.getYear();
|
int year = matter == null || matter.getYear() == null ? LocalDate.now().getYear() : matter.getYear();
|
||||||
String excludeLedgerId = oldLedger == null ? null : oldLedger.getId();
|
String excludeLedgerId = oldLedger == null ? null : oldLedger.getId();
|
||||||
int totalSignupPeople = countYearSignupPeople(year, excludeLedgerId);
|
int domesticSignupPeople = countYearDomesticSignupPeople(year, excludeLedgerId);
|
||||||
int outProvinceSignupPeople = countYearOutProvinceSignupPeople(year, excludeLedgerId);
|
int outProvinceSignupPeople = countYearOutProvinceSignupPeople(year, excludeLedgerId);
|
||||||
int basePeople;
|
int allowPeople = domesticSignupPeople / 2 - outProvinceSignupPeople;
|
||||||
if ("可参加教职工人数".equals(ratioType)) {
|
return new OutProvinceQuota("当年省内报名人数", domesticSignupPeople,
|
||||||
Integer groupId = parseInteger(setting == null ? null : setting.getActivityGroupId());
|
domesticSignupPeople + outProvinceSignupPeople, outProvinceSignupPeople, allowPeople);
|
||||||
basePeople = countActivityGroupPeople(groupId);
|
|
||||||
} else if ("固定人数".equals(ratioType)) {
|
|
||||||
basePeople = setting == null || setting.getOutProvinceFixedPeople() == null ? 0 : setting.getOutProvinceFixedPeople();
|
|
||||||
} else {
|
|
||||||
basePeople = totalSignupPeople;
|
|
||||||
}
|
|
||||||
int quotaPeople = oneThirdRatio
|
|
||||||
? basePeople / 3
|
|
||||||
: ratio.multiply(BigDecimal.valueOf(basePeople)).setScale(0, RoundingMode.FLOOR).intValue();
|
|
||||||
int allowPeople = quotaPeople - outProvinceSignupPeople;
|
|
||||||
return new OutProvinceQuota(ratioType, ratio, basePeople, totalSignupPeople, outProvinceSignupPeople, allowPeople);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isOneThirdRatio(BigDecimal ratio) {
|
|
||||||
if (ratio == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return ratio.compareTo(BigDecimal.valueOf(0.33)) >= 0 && ratio.compareTo(BigDecimal.valueOf(0.3333)) <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String normalizeOutProvinceRatioType(String ratioType) {
|
|
||||||
if ("当年参加人数".equals(ratioType) || StrUtil.isBlank(ratioType)) {
|
|
||||||
return "当年报名人数";
|
|
||||||
}
|
|
||||||
if ("可参加教职工人数".equals(ratioType) || "固定人数".equals(ratioType)) {
|
|
||||||
return ratioType;
|
|
||||||
}
|
|
||||||
return "当年报名人数";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildOutProvinceQuotaNotice(OutProvinceQuota quota) {
|
private String buildOutProvinceQuotaNotice(OutProvinceQuota quota) {
|
||||||
String suffix = quota.canApply() ? "您可以报名,或您稍后报名" : "请稍后报名";
|
String suffix = quota.canApply() ? "您可以报名,或您稍后报名" : "请稍后报名";
|
||||||
if ("当年报名人数".equals(quota.ratioType())) {
|
return "当前报省内线路教职工有效人数是" + quota.basePeople() + "人,已经报名省外线路教职工有效人数是"
|
||||||
return "当前报名人数是" + quota.totalSignupPeople() + "人,已经报名省外线路人数是"
|
+ quota.outProvinceSignupPeople() + "人,按照省外人数不超过出行人数的1/3规则"
|
||||||
+ quota.outProvinceSignupPeople() + "人,按照省外人数不超过" + quota.ratioText()
|
|
||||||
+ "的规则,当前时间允许报名人数是" + quota.allowPeople() + "人," + suffix;
|
|
||||||
}
|
|
||||||
if ("可参加教职工人数".equals(quota.ratioType())) {
|
|
||||||
return "今年有权限报名人数是" + quota.basePeople() + "人,已经报名省外线路人数是"
|
|
||||||
+ quota.outProvinceSignupPeople() + "人,按照省外人数不超过" + quota.ratioText()
|
|
||||||
+ "的规则,当前时间允许报名人数是" + quota.allowPeople() + "人," + suffix;
|
|
||||||
}
|
|
||||||
return "按照省外人数不超过" + quota.ratioText()
|
|
||||||
+ "的规则,当前时间允许报名人数是" + quota.allowPeople() + "人," + suffix;
|
+ "的规则,当前时间允许报名人数是" + quota.allowPeople() + "人," + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int countYearSignupPeople(int year, String excludeLedgerId) {
|
private int countYearDomesticSignupPeople(int year, String excludeLedgerId) {
|
||||||
String excludeSql = StrUtil.isBlank(excludeLedgerId) ? "" : " AND t.id <> @excludeLedgerId";
|
String excludeSql = StrUtil.isBlank(excludeLedgerId) ? "" : " AND t.id <> @excludeLedgerId";
|
||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
SELECT COUNT(1)
|
SELECT COUNT(DISTINCT t.id)
|
||||||
FROM tour_ledger t
|
FROM tour_ledger t
|
||||||
LEFT JOIN wf_process_instance ins ON ins.businessNo = t.id
|
LEFT JOIN wf_process_instance ins ON ins.businessNo = t.id
|
||||||
WHERE t.delFlag = 0
|
WHERE t.delFlag = 0
|
||||||
AND t.`year` = @year
|
AND t.`year` = @year
|
||||||
AND (ins.id IS NULL OR ins.state = @finishedState)
|
AND t.lineType IN ('省内线路', '省内', '国内线路', '国内')
|
||||||
|
AND (ins.id IS NULL OR ins.state <> @abandonState)
|
||||||
""" + excludeSql);
|
""" + excludeSql);
|
||||||
sql.setParam("year", year);
|
sql.setParam("year", year);
|
||||||
sql.setParam("finishedState", ProcessInstanceStateEnum.FINISHED.getCode());
|
sql.setParam("abandonState", ProcessInstanceStateEnum.ABANDON.getCode());
|
||||||
if (StrUtil.isNotBlank(excludeLedgerId)) {
|
if (StrUtil.isNotBlank(excludeLedgerId)) {
|
||||||
sql.setParam("excludeLedgerId", excludeLedgerId);
|
sql.setParam("excludeLedgerId", excludeLedgerId);
|
||||||
}
|
}
|
||||||
@@ -875,16 +850,16 @@ public class TourMySignupController {
|
|||||||
private int countYearOutProvinceSignupPeople(int year, String excludeLedgerId) {
|
private int countYearOutProvinceSignupPeople(int year, String excludeLedgerId) {
|
||||||
String excludeSql = StrUtil.isBlank(excludeLedgerId) ? "" : " AND t.id <> @excludeLedgerId";
|
String excludeSql = StrUtil.isBlank(excludeLedgerId) ? "" : " AND t.id <> @excludeLedgerId";
|
||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
SELECT COUNT(1)
|
SELECT COUNT(DISTINCT t.id)
|
||||||
FROM tour_ledger t
|
FROM tour_ledger t
|
||||||
LEFT JOIN wf_process_instance ins ON ins.businessNo = t.id
|
LEFT JOIN wf_process_instance ins ON ins.businessNo = t.id
|
||||||
WHERE t.delFlag = 0
|
WHERE t.delFlag = 0
|
||||||
AND t.`year` = @year
|
AND t.`year` = @year
|
||||||
AND t.lineType IN ('省外线路', '省外')
|
AND t.lineType IN ('省外线路', '省外')
|
||||||
AND (ins.id IS NULL OR ins.state = @finishedState)
|
AND (ins.id IS NULL OR ins.state <> @abandonState)
|
||||||
""" + excludeSql);
|
""" + excludeSql);
|
||||||
sql.setParam("year", year);
|
sql.setParam("year", year);
|
||||||
sql.setParam("finishedState", ProcessInstanceStateEnum.FINISHED.getCode());
|
sql.setParam("abandonState", ProcessInstanceStateEnum.ABANDON.getCode());
|
||||||
if (StrUtil.isNotBlank(excludeLedgerId)) {
|
if (StrUtil.isNotBlank(excludeLedgerId)) {
|
||||||
sql.setParam("excludeLedgerId", excludeLedgerId);
|
sql.setParam("excludeLedgerId", excludeLedgerId);
|
||||||
}
|
}
|
||||||
@@ -1089,7 +1064,6 @@ public class TourMySignupController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private record OutProvinceQuota(String ratioType,
|
private record OutProvinceQuota(String ratioType,
|
||||||
BigDecimal ratio,
|
|
||||||
int basePeople,
|
int basePeople,
|
||||||
int totalSignupPeople,
|
int totalSignupPeople,
|
||||||
int outProvinceSignupPeople,
|
int outProvinceSignupPeople,
|
||||||
@@ -1099,14 +1073,7 @@ public class TourMySignupController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String ratioText() {
|
String ratioText() {
|
||||||
if (ratio == null || BigDecimal.ZERO.compareTo(ratio) == 0) {
|
return "floor(省内有效人数/2)-省外有效人数";
|
||||||
return "0";
|
|
||||||
}
|
|
||||||
BigDecimal oneThird = BigDecimal.ONE.divide(BigDecimal.valueOf(3), 8, RoundingMode.HALF_UP);
|
|
||||||
if (ratio.subtract(oneThird).abs().compareTo(BigDecimal.valueOf(0.01)) <= 0) {
|
|
||||||
return "1/3";
|
|
||||||
}
|
|
||||||
return ratio.stripTrailingZeros().toPlainString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1338,6 +1305,7 @@ public class TourMySignupController {
|
|||||||
.addv("applyDate", firstNotBlank(approvalTimes.getString("applyDate", ""), ledger.getSignupTime()))
|
.addv("applyDate", firstNotBlank(approvalTimes.getString("applyDate", ""), ledger.getSignupTime()))
|
||||||
.addv("unionAuditorName", approvalTimes.getString("unionAuditorName", ""))
|
.addv("unionAuditorName", approvalTimes.getString("unionAuditorName", ""))
|
||||||
.addv("unionAuditDate", approvalTimes.getString("unionAuditDate", ""))
|
.addv("unionAuditDate", approvalTimes.getString("unionAuditDate", ""))
|
||||||
|
.addv("schoolUnionAuditorName", approvalTimes.getString("schoolUnionAuditorName", ""))
|
||||||
.addv("schoolUnionAuditDate", approvalTimes.getString("schoolUnionAuditDate", ""));
|
.addv("schoolUnionAuditDate", approvalTimes.getString("schoolUnionAuditDate", ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1389,6 +1357,7 @@ public class TourMySignupController {
|
|||||||
.addv("applyDate", firstNotBlank(approvalTimes.getString("applyDate", ""), ledger.getSignupTime()))
|
.addv("applyDate", firstNotBlank(approvalTimes.getString("applyDate", ""), ledger.getSignupTime()))
|
||||||
.addv("unionAuditorName", approvalTimes.getString("unionAuditorName", ""))
|
.addv("unionAuditorName", approvalTimes.getString("unionAuditorName", ""))
|
||||||
.addv("unionAuditDate", approvalTimes.getString("unionAuditDate", ""))
|
.addv("unionAuditDate", approvalTimes.getString("unionAuditDate", ""))
|
||||||
|
.addv("schoolUnionAuditorName", approvalTimes.getString("schoolUnionAuditorName", ""))
|
||||||
.addv("schoolUnionAuditDate", approvalTimes.getString("schoolUnionAuditDate", ""))
|
.addv("schoolUnionAuditDate", approvalTimes.getString("schoolUnionAuditDate", ""))
|
||||||
.addv("relativeUnitAuditDate", "");
|
.addv("relativeUnitAuditDate", "");
|
||||||
}
|
}
|
||||||
@@ -1444,6 +1413,7 @@ public class TourMySignupController {
|
|||||||
result.put("unionAuditorName", parseTaskUserName(item.getString("variable", "")));
|
result.put("unionAuditorName", parseTaskUserName(item.getString("variable", "")));
|
||||||
} else if ("校工会审核".equals(displayName)) {
|
} else if ("校工会审核".equals(displayName)) {
|
||||||
result.put("schoolUnionAuditDate", finishDate);
|
result.put("schoolUnionAuditDate", finishDate);
|
||||||
|
result.put("schoolUnionAuditorName", parseTaskUserName(item.getString("variable", "")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -1580,6 +1550,7 @@ public class TourMySignupController {
|
|||||||
drawPlainDateLine(writer, data.getString("unionAuditDate", ""), 330, paragraphEndY - 163, 18);
|
drawPlainDateLine(writer, data.getString("unionAuditDate", ""), 330, paragraphEndY - 163, 18);
|
||||||
|
|
||||||
writer.text("学校工会:盖章", 18, 300, paragraphEndY - 190, false);
|
writer.text("学校工会:盖章", 18, 300, paragraphEndY - 190, false);
|
||||||
|
writer.text(data.getString("schoolUnionAuditorName", ""), 18, 410, paragraphEndY - 190, false);
|
||||||
drawPlainDateLine(writer, data.getString("schoolUnionAuditDate", ""), 330, paragraphEndY - 217, 18);
|
drawPlainDateLine(writer, data.getString("schoolUnionAuditDate", ""), 330, paragraphEndY - 217, 18);
|
||||||
}
|
}
|
||||||
document.save(out);
|
document.save(out);
|
||||||
@@ -1644,6 +1615,7 @@ public class TourMySignupController {
|
|||||||
|
|
||||||
signY -= 78;
|
signY -= 78;
|
||||||
writer.text("学校工会:盖章", 15, signX + 20, signY, false);
|
writer.text("学校工会:盖章", 15, signX + 20, signY, false);
|
||||||
|
writer.text(data.getString("schoolUnionAuditorName", ""), 15, signX + 135, signY, false);
|
||||||
drawPlainDateLine(writer, data.getString("schoolUnionAuditDate", ""), signX + 45, signY - 31, 15);
|
drawPlainDateLine(writer, data.getString("schoolUnionAuditDate", ""), signX + 45, signY - 31, 15);
|
||||||
|
|
||||||
signY -= 78;
|
signY -= 78;
|
||||||
@@ -1823,6 +1795,9 @@ public class TourMySignupController {
|
|||||||
if ("travelPeriod".equals(orderName)) {
|
if ("travelPeriod".equals(orderName)) {
|
||||||
return "COALESCE(m.travelStartTime, tp.travelPeriod)";
|
return "COALESCE(m.travelStartTime, tp.travelPeriod)";
|
||||||
}
|
}
|
||||||
|
if ("matterUnionName".equals(orderName)) {
|
||||||
|
return "matterUnionName";
|
||||||
|
}
|
||||||
if ("lineType".equals(orderName)) {
|
if ("lineType".equals(orderName)) {
|
||||||
return "t.lineType";
|
return "t.lineType";
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-1
@@ -7,6 +7,7 @@ import com.budwk.app.base.page.Pagination;
|
|||||||
import com.budwk.app.base.param.PageForm;
|
import com.budwk.app.base.param.PageForm;
|
||||||
import com.budwk.app.base.result.Result;
|
import com.budwk.app.base.result.Result;
|
||||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||||
|
import com.budwk.app.sys.views.View_user;
|
||||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||||
import com.budwk.app.zhgh.dayofficework.tour.models.TourLedger;
|
import com.budwk.app.zhgh.dayofficework.tour.models.TourLedger;
|
||||||
import com.budwk.app.zhgh.dayofficework.tour.models.TourLedgerDirectRelative;
|
import com.budwk.app.zhgh.dayofficework.tour.models.TourLedgerDirectRelative;
|
||||||
@@ -20,6 +21,7 @@ import org.nutz.dao.sql.Sql;
|
|||||||
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||||
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.lang.Lang;
|
||||||
import org.nutz.lang.util.NutMap;
|
import org.nutz.lang.util.NutMap;
|
||||||
import org.nutz.mvc.annotation.At;
|
import org.nutz.mvc.annotation.At;
|
||||||
import org.nutz.mvc.annotation.Ok;
|
import org.nutz.mvc.annotation.Ok;
|
||||||
@@ -180,7 +182,7 @@ public class TourSchoolUnionApprovalController {
|
|||||||
.and(TourLedgerDirectRelative::getDelFlag, "=", false));
|
.and(TourLedgerDirectRelative::getDelFlag, "=", false));
|
||||||
NutMap signupConfig = getSignupConfig(ledger);
|
NutMap signupConfig = getSignupConfig(ledger);
|
||||||
return Result.success(NutMap.NEW()
|
return Result.success(NutMap.NEW()
|
||||||
.addv("ledger", ledger)
|
.addv("ledger", buildLedgerView(ledger))
|
||||||
.addv("travelPeriod", getTravelPeriod(ledger))
|
.addv("travelPeriod", getTravelPeriod(ledger))
|
||||||
.addv("families", tourLedgerFamilyService.query(familyCnd))
|
.addv("families", tourLedgerFamilyService.query(familyCnd))
|
||||||
.addv("directRelative", directRelative)
|
.addv("directRelative", directRelative)
|
||||||
@@ -189,6 +191,13 @@ public class TourSchoolUnionApprovalController {
|
|||||||
.addv("directFamilyUnitLine", signupConfig.getBoolean("directFamilyUnitLine", false)));
|
.addv("directFamilyUnitLine", signupConfig.getBoolean("directFamilyUnitLine", false)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private NutMap buildLedgerView(TourLedger ledger) {
|
||||||
|
NutMap map = Lang.obj2nutmap(ledger);
|
||||||
|
View_user user = tourLedgerService.dao().fetch(View_user.class, Cnd.where("loginname", "=", ledger.getJobNo()));
|
||||||
|
map.addv("mobile", StrUtil.blankToDefault(ledger.getMobile(), user == null ? "" : StrUtil.blankToDefault(user.getMobile(), "")));
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission(value = {"tour.schoolUnionApproval", "h5.tour.schoolUnionApproval"}, mode = SaMode.OR)
|
@SaCheckPermission(value = {"tour.schoolUnionApproval", "h5.tour.schoolUnionApproval"}, mode = SaMode.OR)
|
||||||
public Result unionOptions(Boolean audit, Integer startYear, Integer endYear, String keyword, String lineId, String travelPeriod, String lineType) {
|
public Result unionOptions(Boolean audit, Integer startYear, Integer endYear, String keyword, String lineId, String travelPeriod, String lineType) {
|
||||||
|
|||||||
+6
@@ -209,6 +209,12 @@ public class TourSettingController {
|
|||||||
&& tourSetting.getMinGroupPeople() > tourSetting.getMaxGroupPeople()) {
|
&& tourSetting.getMinGroupPeople() > tourSetting.getMaxGroupPeople()) {
|
||||||
return Result.error("最少成团人数不能大于最多成团人数");
|
return Result.error("最少成团人数不能大于最多成团人数");
|
||||||
}
|
}
|
||||||
|
if (StrUtil.isBlank(tourSetting.getSignupStartTime()) || StrUtil.isBlank(tourSetting.getSignupEndTime())) {
|
||||||
|
return Result.error("报名时间不能为空");
|
||||||
|
}
|
||||||
|
if (tourSetting.getSignupStartTime().compareTo(tourSetting.getSignupEndTime()) >= 0) {
|
||||||
|
return Result.error("开始报名时间必须小于结束报名时间");
|
||||||
|
}
|
||||||
if (tourSetting.getCycleStartYear() != null && tourSetting.getCycleEndYear() != null
|
if (tourSetting.getCycleStartYear() != null && tourSetting.getCycleEndYear() != null
|
||||||
&& tourSetting.getCycleStartYear() > tourSetting.getCycleEndYear()) {
|
&& tourSetting.getCycleStartYear() > tourSetting.getCycleEndYear()) {
|
||||||
return Result.error("周期开始年度不能大于周期结束年度");
|
return Result.error("周期开始年度不能大于周期结束年度");
|
||||||
|
|||||||
+163
-84
@@ -34,6 +34,7 @@ import org.nutz.aop.interceptor.ioc.TransAop;
|
|||||||
import org.nutz.dao.Cnd;
|
import org.nutz.dao.Cnd;
|
||||||
import org.nutz.dao.Sqls;
|
import org.nutz.dao.Sqls;
|
||||||
import org.nutz.dao.sql.Sql;
|
import org.nutz.dao.sql.Sql;
|
||||||
|
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||||
import org.nutz.ioc.aop.Aop;
|
import org.nutz.ioc.aop.Aop;
|
||||||
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;
|
||||||
@@ -44,8 +45,6 @@ import org.nutz.mvc.annotation.At;
|
|||||||
import org.nutz.mvc.annotation.Ok;
|
import org.nutz.mvc.annotation.Ok;
|
||||||
import org.nutz.mvc.annotation.Param;
|
import org.nutz.mvc.annotation.Param;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.RoundingMode;
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
@@ -368,6 +367,63 @@ public class TourSignupController {
|
|||||||
return Result.success(sql.getList(NutMap.class));
|
return Result.success(sql.getList(NutMap.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckPermission("tour.signup")
|
||||||
|
public Result signupPageData(PageForm pageForm, String matterId, String keyword, String unionId) {
|
||||||
|
return querySignupPageData(pageForm, matterId, keyword, unionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@At("/h5/signupPageData")
|
||||||
|
@SaCheckPermission(value = {"tour.signup", "h5.tour.signup"}, mode = SaMode.OR)
|
||||||
|
public Result h5SignupPageData(PageForm pageForm, String matterId, String keyword, String unionId) {
|
||||||
|
return querySignupPageData(pageForm, matterId, keyword, unionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Result querySignupPageData(PageForm pageForm, String matterId, String keyword, String unionId) {
|
||||||
|
if (StrUtil.isBlank(matterId)) {
|
||||||
|
return Result.error("参数错误");
|
||||||
|
}
|
||||||
|
if (StrUtil.isBlank(pageForm.getPageOrderName())) {
|
||||||
|
pageForm.defaultSortDesc("signupTime");
|
||||||
|
}
|
||||||
|
Cnd cnd = buildSignupQueryCnd(matterId, keyword, unionId);
|
||||||
|
Sql countSql = Sqls.create("""
|
||||||
|
SELECT COUNT(DISTINCT t.id)
|
||||||
|
FROM tour_ledger t
|
||||||
|
INNER JOIN tour_matter m ON m.id = t.matterId
|
||||||
|
INNER JOIN tour_line l ON l.id = m.lineId
|
||||||
|
$condition
|
||||||
|
""");
|
||||||
|
countSql.setCondition(cnd);
|
||||||
|
countSql.setCallback(Sqls.callback.integer());
|
||||||
|
tourLedgerService.dao().execute(countSql);
|
||||||
|
int count = countSql.getInt();
|
||||||
|
|
||||||
|
Sql listSql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
t.id,
|
||||||
|
t.jobNo,
|
||||||
|
t.userName,
|
||||||
|
t.unionId,
|
||||||
|
t.unionName,
|
||||||
|
t.signupTime
|
||||||
|
FROM tour_ledger t
|
||||||
|
INNER JOIN tour_matter m ON m.id = t.matterId
|
||||||
|
INNER JOIN tour_line l ON l.id = m.lineId
|
||||||
|
$condition
|
||||||
|
ORDER BY $orderColumn $orderBy, t.signupTime DESC, t.createdAt DESC
|
||||||
|
""");
|
||||||
|
listSql.setCondition(cnd);
|
||||||
|
listSql.setVar("orderColumn", getSignupOrderColumn(pageForm.getPageOrderName()));
|
||||||
|
listSql.setVar("orderBy", "ascending".equals(pageForm.getPageOrderBy()) ? "asc" : "desc");
|
||||||
|
listSql.setPager(tourLedgerService.dao().createPager(pageForm.getPageNumber(), pageForm.getPageSize()));
|
||||||
|
listSql.setCallback(Sqls.callback.maps());
|
||||||
|
tourLedgerService.dao().execute(listSql);
|
||||||
|
|
||||||
|
Pagination<NutMap> pagination = new Pagination<>(pageForm.getPageNumber(), pageForm.getPageSize(), count, listSql.getList(NutMap.class));
|
||||||
|
return Result.success(pagination);
|
||||||
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission(value = {"tour.signup", "h5.tour.signup"}, mode = SaMode.OR)
|
@SaCheckPermission(value = {"tour.signup", "h5.tour.signup"}, mode = SaMode.OR)
|
||||||
public Result lineDetail(String lineId) {
|
public Result lineDetail(String lineId) {
|
||||||
@@ -395,7 +451,7 @@ public class TourSignupController {
|
|||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission(value = {"tour.signup", "h5.tour.signup"}, mode = SaMode.OR)
|
@SaCheckPermission(value = {"tour.signup", "h5.tour.signup"}, mode = SaMode.OR)
|
||||||
public Result signupDetail(String matterId) {
|
public Result signupDetail(String matterId, Boolean noticeChecked) {
|
||||||
if (StrUtil.isBlank(matterId)) {
|
if (StrUtil.isBlank(matterId)) {
|
||||||
return Result.error("参数错误");
|
return Result.error("参数错误");
|
||||||
}
|
}
|
||||||
@@ -420,6 +476,8 @@ public class TourSignupController {
|
|||||||
l.travelAgencyId,
|
l.travelAgencyId,
|
||||||
a.agencyName AS travelAgencyName,
|
a.agencyName AS travelAgencyName,
|
||||||
IFNULL(lot.allowOverReimbursement, 0) AS allowOverReimbursement,
|
IFNULL(lot.allowOverReimbursement, 0) AS allowOverReimbursement,
|
||||||
|
IFNULL(sc.signupCount, 0) AS signupCount,
|
||||||
|
IFNULL(sc.familyCount, 0) AS familyCount,
|
||||||
s.allowFamily,
|
s.allowFamily,
|
||||||
IFNULL(s.fillBedInfo, 1) AS fillBedInfo
|
IFNULL(s.fillBedInfo, 1) AS fillBedInfo
|
||||||
FROM tour_matter m
|
FROM tour_matter m
|
||||||
@@ -427,6 +485,23 @@ public class TourSignupController {
|
|||||||
LEFT JOIN tour_travel_agency a ON a.id = l.travelAgencyId
|
LEFT JOIN tour_travel_agency a ON a.id = l.travelAgencyId
|
||||||
LEFT JOIN tour_setting_lot lot ON lot.id = l.lotId
|
LEFT JOIN tour_setting_lot lot ON lot.id = l.lotId
|
||||||
LEFT JOIN tour_setting s ON s.id = m.settingId
|
LEFT JOIN tour_setting s ON s.id = m.settingId
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT
|
||||||
|
t.matterId,
|
||||||
|
COUNT(1) + SUM(IFNULL(f.familyCount, 0)) AS signupCount,
|
||||||
|
SUM(IFNULL(f.familyCount, 0)) AS familyCount
|
||||||
|
FROM tour_ledger t
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT ledgerId, COUNT(1) AS familyCount
|
||||||
|
FROM tour_ledger_family
|
||||||
|
WHERE delFlag = 0
|
||||||
|
GROUP BY ledgerId
|
||||||
|
) f ON f.ledgerId = t.id
|
||||||
|
WHERE t.delFlag = 0
|
||||||
|
AND t.matterId IS NOT NULL
|
||||||
|
AND t.matterId <> ''
|
||||||
|
GROUP BY t.matterId
|
||||||
|
) sc ON sc.matterId = m.id
|
||||||
WHERE m.delFlag = 0
|
WHERE m.delFlag = 0
|
||||||
AND m.enabled = 1
|
AND m.enabled = 1
|
||||||
AND m.id = @matterId
|
AND m.id = @matterId
|
||||||
@@ -461,9 +536,11 @@ public class TourSignupController {
|
|||||||
ruleLedger.setMatterId(matter.getString("matterId"));
|
ruleLedger.setMatterId(matter.getString("matterId"));
|
||||||
ruleLedger.setLineId(matter.getString("lineId"));
|
ruleLedger.setLineId(matter.getString("lineId"));
|
||||||
ruleLedger.setLineName(matter.getString("lineName"));
|
ruleLedger.setLineName(matter.getString("lineName"));
|
||||||
Result ruleResult = checkSignupRule(ruleLedger, matterEntity, ledger);
|
if (!Boolean.TRUE.equals(noticeChecked)) {
|
||||||
if (ruleResult != null) {
|
Result ruleResult = checkSignupRule(ruleLedger, matterEntity, ledger);
|
||||||
return ruleResult;
|
if (ruleResult != null) {
|
||||||
|
return ruleResult;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
List<TourLedgerFamily> families = Collections.emptyList();
|
List<TourLedgerFamily> families = Collections.emptyList();
|
||||||
TourLedgerDirectRelative directRelative = null;
|
TourLedgerDirectRelative directRelative = null;
|
||||||
@@ -591,26 +668,39 @@ public class TourSignupController {
|
|||||||
@At
|
@At
|
||||||
@SaCheckPermission(value = {"tour.signup", "h5.tour.signup"}, mode = SaMode.OR)
|
@SaCheckPermission(value = {"tour.signup", "h5.tour.signup"}, mode = SaMode.OR)
|
||||||
public Result directRelativeOptions() {
|
public Result directRelativeOptions() {
|
||||||
List<Sys_dict> list = sysDictService.getSubListByCode("directRelative");
|
return Result.success(getEnabledDictOptions("directRelative"));
|
||||||
if (list == null) {
|
}
|
||||||
return Result.success(Collections.emptyList());
|
|
||||||
}
|
@At
|
||||||
return Result.success(list.stream().filter(item -> !item.isDisabled()).collect(Collectors.toList()));
|
@SaCheckPermission(value = {"tour.signup", "h5.tour.signup"}, mode = SaMode.OR)
|
||||||
|
public Result signupOptions() {
|
||||||
|
return Result.success(NutMap.NEW()
|
||||||
|
.addv("bedTypeOptions", getEnabledDictOptions("bedType"))
|
||||||
|
.addv("familyRelationshipOptions", getFamilyRelationshipOptions())
|
||||||
|
.addv("directRelativeOptions", getEnabledDictOptions("directRelative")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission(value = {"tour.signup", "h5.tour.signup"}, mode = SaMode.OR)
|
@SaCheckPermission(value = {"tour.signup", "h5.tour.signup"}, mode = SaMode.OR)
|
||||||
public Result bedTypeOptions() {
|
public Result bedTypeOptions() {
|
||||||
List<Sys_dict> list = sysDictService.getSubListByCode("bedType");
|
return Result.success(getEnabledDictOptions("bedType"));
|
||||||
if (list == null) {
|
|
||||||
return Result.success(Collections.emptyList());
|
|
||||||
}
|
|
||||||
return Result.success(list.stream().filter(item -> !item.isDisabled()).collect(Collectors.toList()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission(value = {"tour.signup", "h5.tour.signup"}, mode = SaMode.OR)
|
@SaCheckPermission(value = {"tour.signup", "h5.tour.signup"}, mode = SaMode.OR)
|
||||||
public Result familyRelationshipOptions() {
|
public Result familyRelationshipOptions() {
|
||||||
|
return Result.success(getFamilyRelationshipOptions());
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Sys_dict> getEnabledDictOptions(String code) {
|
||||||
|
List<Sys_dict> list = sysDictService.getSubListByCode(code);
|
||||||
|
if (list == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return list.stream().filter(item -> !item.isDisabled()).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Sys_dict> getFamilyRelationshipOptions() {
|
||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
SELECT d.*
|
SELECT d.*
|
||||||
FROM sys_dict p
|
FROM sys_dict p
|
||||||
@@ -624,7 +714,7 @@ public class TourSignupController {
|
|||||||
sql.setCallback(Sqls.callback.entities());
|
sql.setCallback(Sqls.callback.entities());
|
||||||
sql.setEntity(tourLedgerService.dao().getEntity(Sys_dict.class));
|
sql.setEntity(tourLedgerService.dao().getEntity(Sys_dict.class));
|
||||||
tourLedgerService.dao().execute(sql);
|
tourLedgerService.dao().execute(sql);
|
||||||
return Result.success(sql.getList(Sys_dict.class));
|
return sql.getList(Sys_dict.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@@ -772,6 +862,26 @@ public class TourSignupController {
|
|||||||
return cnd;
|
return cnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Cnd buildSignupQueryCnd(String matterId, String keyword, String unionId) {
|
||||||
|
Cnd cnd = Cnd.NEW();
|
||||||
|
cnd.and("t.delFlag", "=", false);
|
||||||
|
cnd.and("t.matterId", "=", matterId);
|
||||||
|
cnd.and("m.delFlag", "=", false);
|
||||||
|
cnd.and("m.enabled", "=", true);
|
||||||
|
cnd.and("m.lineId", "IS NOT", null);
|
||||||
|
cnd.and("m.lineId", "<>", "");
|
||||||
|
cnd.and("l.delFlag", "=", false);
|
||||||
|
cnd.and("l.enabled", "=", true);
|
||||||
|
if (StrUtil.isNotBlank(keyword)) {
|
||||||
|
SqlExpressionGroup keywordGroup = new SqlExpressionGroup();
|
||||||
|
keywordGroup.orLike("t.userName", keyword.trim());
|
||||||
|
keywordGroup.orLike("t.jobNo", keyword.trim());
|
||||||
|
cnd.and(keywordGroup);
|
||||||
|
}
|
||||||
|
cnd.andEX("t.unionId", "=", unionId);
|
||||||
|
return cnd;
|
||||||
|
}
|
||||||
|
|
||||||
private Result checkSignup(TourLedger ledger) {
|
private Result checkSignup(TourLedger ledger) {
|
||||||
if (ledger == null) {
|
if (ledger == null) {
|
||||||
return Result.error("参数错误");
|
return Result.error("参数错误");
|
||||||
@@ -788,6 +898,9 @@ public class TourSignupController {
|
|||||||
if (StrUtil.isBlank(ledger.getLineName())) {
|
if (StrUtil.isBlank(ledger.getLineName())) {
|
||||||
return Result.error("报名线路不能为空");
|
return Result.error("报名线路不能为空");
|
||||||
}
|
}
|
||||||
|
if (StrUtil.isBlank(ledger.getIdCard())) {
|
||||||
|
return Result.error("身份证号不能为空");
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -887,14 +1000,16 @@ public class TourSignupController {
|
|||||||
if (activityGroupId == null || !activityBasicScopeService.isUserInGroup(activityGroupId, SecurityUtil.getUserId())) {
|
if (activityGroupId == null || !activityBasicScopeService.isUserInGroup(activityGroupId, SecurityUtil.getUserId())) {
|
||||||
return Result.error("您不在本次疗休养报名范围内");
|
return Result.error("您不在本次疗休养报名范围内");
|
||||||
}
|
}
|
||||||
if (StrUtil.isBlank(matter.getSignupStartTime()) || StrUtil.isBlank(matter.getSignupEndTime())) {
|
String signupStartTime = defaultIfBlank(setting.getSignupStartTime(), matter.getSignupStartTime());
|
||||||
|
String signupEndTime = defaultIfBlank(setting.getSignupEndTime(), matter.getSignupEndTime());
|
||||||
|
if (StrUtil.isBlank(signupStartTime) || StrUtil.isBlank(signupEndTime)) {
|
||||||
return Result.error("报名时间未配置");
|
return Result.error("报名时间未配置");
|
||||||
}
|
}
|
||||||
String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||||
if (now.compareTo(normalizeDateTime(matter.getSignupStartTime(), false)) < 0) {
|
if (now.compareTo(normalizeDateTime(signupStartTime, false)) < 0) {
|
||||||
return Result.error("报名未开始");
|
return Result.error("报名未开始");
|
||||||
}
|
}
|
||||||
if (now.compareTo(normalizeDateTime(matter.getSignupEndTime(), true)) > 0) {
|
if (now.compareTo(normalizeDateTime(signupEndTime, true)) > 0) {
|
||||||
return Result.error("报名已结束");
|
return Result.error("报名已结束");
|
||||||
}
|
}
|
||||||
CycleAllowedTimes cycleAllowedTimes = calculateCycleAllowedTimes(matter, setting, oldLedger);
|
CycleAllowedTimes cycleAllowedTimes = calculateCycleAllowedTimes(matter, setting, oldLedger);
|
||||||
@@ -1069,76 +1184,35 @@ public class TourSignupController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private OutProvinceQuota calculateOutProvinceQuota(TourMatter matter, TourSetting setting, TourLedger oldLedger) {
|
private OutProvinceQuota calculateOutProvinceQuota(TourMatter matter, TourSetting setting, TourLedger oldLedger) {
|
||||||
String ratioType = normalizeOutProvinceRatioType(setting == null ? null : setting.getOutProvinceRatioType());
|
|
||||||
BigDecimal originalRatio = setting == null ? null : setting.getOutProvinceRatio();
|
|
||||||
boolean oneThirdRatio = isOneThirdRatio(originalRatio);
|
|
||||||
BigDecimal ratio = oneThirdRatio ? BigDecimal.ONE.divide(BigDecimal.valueOf(3), 12, RoundingMode.HALF_UP)
|
|
||||||
: (originalRatio == null ? BigDecimal.ZERO : originalRatio);
|
|
||||||
int year = matter == null || matter.getYear() == null ? LocalDate.now().getYear() : matter.getYear();
|
int year = matter == null || matter.getYear() == null ? LocalDate.now().getYear() : matter.getYear();
|
||||||
String excludeLedgerId = oldLedger == null ? null : oldLedger.getId();
|
String excludeLedgerId = oldLedger == null ? null : oldLedger.getId();
|
||||||
int totalSignupPeople = countYearSignupPeople(year, excludeLedgerId);
|
int domesticSignupPeople = countYearDomesticSignupPeople(year, excludeLedgerId);
|
||||||
int outProvinceSignupPeople = countYearOutProvinceSignupPeople(year, excludeLedgerId);
|
int outProvinceSignupPeople = countYearOutProvinceSignupPeople(year, excludeLedgerId);
|
||||||
int basePeople;
|
int allowPeople = domesticSignupPeople / 2 - outProvinceSignupPeople;
|
||||||
if ("可参加教职工人数".equals(ratioType)) {
|
return new OutProvinceQuota("当年省内报名人数", domesticSignupPeople,
|
||||||
Integer groupId = parseInteger(setting == null ? null : setting.getActivityGroupId());
|
domesticSignupPeople + outProvinceSignupPeople, outProvinceSignupPeople, allowPeople);
|
||||||
basePeople = countActivityGroupPeople(groupId);
|
|
||||||
} else if ("固定人数".equals(ratioType)) {
|
|
||||||
basePeople = setting == null || setting.getOutProvinceFixedPeople() == null ? 0 : setting.getOutProvinceFixedPeople();
|
|
||||||
} else {
|
|
||||||
basePeople = totalSignupPeople;
|
|
||||||
}
|
|
||||||
int quotaPeople = oneThirdRatio
|
|
||||||
? basePeople / 3
|
|
||||||
: ratio.multiply(BigDecimal.valueOf(basePeople)).setScale(0, RoundingMode.FLOOR).intValue();
|
|
||||||
int allowPeople = quotaPeople - outProvinceSignupPeople;
|
|
||||||
return new OutProvinceQuota(ratioType, ratio, basePeople, totalSignupPeople, outProvinceSignupPeople, allowPeople);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isOneThirdRatio(BigDecimal ratio) {
|
|
||||||
if (ratio == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return ratio.compareTo(BigDecimal.valueOf(0.33)) >= 0 && ratio.compareTo(BigDecimal.valueOf(0.3333)) <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String normalizeOutProvinceRatioType(String ratioType) {
|
|
||||||
if ("当年参加人数".equals(ratioType) || StrUtil.isBlank(ratioType)) {
|
|
||||||
return "当年报名人数";
|
|
||||||
}
|
|
||||||
if ("可参加教职工人数".equals(ratioType) || "固定人数".equals(ratioType)) {
|
|
||||||
return ratioType;
|
|
||||||
}
|
|
||||||
return "当年报名人数";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildOutProvinceQuotaNotice(OutProvinceQuota quota) {
|
private String buildOutProvinceQuotaNotice(OutProvinceQuota quota) {
|
||||||
String suffix = quota.canApply() ? "您可以报名,或您稍后报名" : "请稍后报名";
|
String suffix = quota.canApply() ? "您可以报名,或您稍后报名" : "请稍后报名";
|
||||||
if ("当年报名人数".equals(quota.ratioType())) {
|
return "当前报省内线路教职工有效人数是" + quota.basePeople() + "人,已经报名省外线路教职工有效人数是"
|
||||||
return "当前报名人数是" + quota.totalSignupPeople() + "人,已经报名省外线路人数是"
|
+ quota.outProvinceSignupPeople() + "人,按照省外人数不超过出行人数的1/3规则"
|
||||||
+ quota.outProvinceSignupPeople() + "人,按照省外人数不超过" + quota.ratioText()
|
|
||||||
+ "的规则,当前时间允许报名人数是" + quota.allowPeople() + "人," + suffix;
|
|
||||||
}
|
|
||||||
if ("可参加教职工人数".equals(quota.ratioType())) {
|
|
||||||
return "今年有权限报名人数是" + quota.basePeople() + "人,已经报名省外线路人数是"
|
|
||||||
+ quota.outProvinceSignupPeople() + "人,按照省外人数不超过" + quota.ratioText()
|
|
||||||
+ "的规则,当前时间允许报名人数是" + quota.allowPeople() + "人," + suffix;
|
|
||||||
}
|
|
||||||
return "按照省外人数不超过" + quota.ratioText()
|
|
||||||
+ "的规则,当前时间允许报名人数是" + quota.allowPeople() + "人," + suffix;
|
+ "的规则,当前时间允许报名人数是" + quota.allowPeople() + "人," + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int countYearSignupPeople(int year, String excludeLedgerId) {
|
private int countYearDomesticSignupPeople(int year, String excludeLedgerId) {
|
||||||
String excludeSql = StrUtil.isBlank(excludeLedgerId) ? "" : " AND t.id <> @excludeLedgerId";
|
String excludeSql = StrUtil.isBlank(excludeLedgerId) ? "" : " AND t.id <> @excludeLedgerId";
|
||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
SELECT COUNT(1)
|
SELECT COUNT(DISTINCT t.id)
|
||||||
FROM tour_ledger t
|
FROM tour_ledger t
|
||||||
LEFT JOIN wf_process_instance ins ON ins.businessNo = t.id
|
LEFT JOIN wf_process_instance ins ON ins.businessNo = t.id
|
||||||
WHERE t.delFlag = 0
|
WHERE t.delFlag = 0
|
||||||
AND t.`year` = @year
|
AND t.`year` = @year
|
||||||
AND (ins.id IS NULL OR ins.state = @finishedState)
|
AND t.lineType IN ('省内线路', '省内', '国内线路', '国内')
|
||||||
|
AND (ins.id IS NULL OR ins.state <> @abandonState)
|
||||||
""" + excludeSql);
|
""" + excludeSql);
|
||||||
sql.setParam("year", year);
|
sql.setParam("year", year);
|
||||||
sql.setParam("finishedState", ProcessInstanceStateEnum.FINISHED.getCode());
|
sql.setParam("abandonState", ProcessInstanceStateEnum.ABANDON.getCode());
|
||||||
if (StrUtil.isNotBlank(excludeLedgerId)) {
|
if (StrUtil.isNotBlank(excludeLedgerId)) {
|
||||||
sql.setParam("excludeLedgerId", excludeLedgerId);
|
sql.setParam("excludeLedgerId", excludeLedgerId);
|
||||||
}
|
}
|
||||||
@@ -1150,16 +1224,16 @@ public class TourSignupController {
|
|||||||
private int countYearOutProvinceSignupPeople(int year, String excludeLedgerId) {
|
private int countYearOutProvinceSignupPeople(int year, String excludeLedgerId) {
|
||||||
String excludeSql = StrUtil.isBlank(excludeLedgerId) ? "" : " AND t.id <> @excludeLedgerId";
|
String excludeSql = StrUtil.isBlank(excludeLedgerId) ? "" : " AND t.id <> @excludeLedgerId";
|
||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
SELECT COUNT(1)
|
SELECT COUNT(DISTINCT t.id)
|
||||||
FROM tour_ledger t
|
FROM tour_ledger t
|
||||||
LEFT JOIN wf_process_instance ins ON ins.businessNo = t.id
|
LEFT JOIN wf_process_instance ins ON ins.businessNo = t.id
|
||||||
WHERE t.delFlag = 0
|
WHERE t.delFlag = 0
|
||||||
AND t.`year` = @year
|
AND t.`year` = @year
|
||||||
AND t.lineType IN ('省外线路', '省外')
|
AND t.lineType IN ('省外线路', '省外')
|
||||||
AND (ins.id IS NULL OR ins.state = @finishedState)
|
AND (ins.id IS NULL OR ins.state <> @abandonState)
|
||||||
""" + excludeSql);
|
""" + excludeSql);
|
||||||
sql.setParam("year", year);
|
sql.setParam("year", year);
|
||||||
sql.setParam("finishedState", ProcessInstanceStateEnum.FINISHED.getCode());
|
sql.setParam("abandonState", ProcessInstanceStateEnum.ABANDON.getCode());
|
||||||
if (StrUtil.isNotBlank(excludeLedgerId)) {
|
if (StrUtil.isNotBlank(excludeLedgerId)) {
|
||||||
sql.setParam("excludeLedgerId", excludeLedgerId);
|
sql.setParam("excludeLedgerId", excludeLedgerId);
|
||||||
}
|
}
|
||||||
@@ -1267,7 +1341,6 @@ public class TourSignupController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private record OutProvinceQuota(String ratioType,
|
private record OutProvinceQuota(String ratioType,
|
||||||
BigDecimal ratio,
|
|
||||||
int basePeople,
|
int basePeople,
|
||||||
int totalSignupPeople,
|
int totalSignupPeople,
|
||||||
int outProvinceSignupPeople,
|
int outProvinceSignupPeople,
|
||||||
@@ -1277,14 +1350,7 @@ public class TourSignupController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String ratioText() {
|
String ratioText() {
|
||||||
if (ratio == null || BigDecimal.ZERO.compareTo(ratio) == 0) {
|
return "floor(省内有效人数/2)-省外有效人数";
|
||||||
return "0";
|
|
||||||
}
|
|
||||||
BigDecimal oneThird = BigDecimal.ONE.divide(BigDecimal.valueOf(3), 8, RoundingMode.HALF_UP);
|
|
||||||
if (ratio.subtract(oneThird).abs().compareTo(BigDecimal.valueOf(0.01)) <= 0) {
|
|
||||||
return "1/3";
|
|
||||||
}
|
|
||||||
return ratio.stripTrailingZeros().toPlainString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1457,6 +1523,19 @@ public class TourSignupController {
|
|||||||
return user == null ? SecurityUtil.getUserLoginname() : defaultIfBlank(user.getLoginname(), SecurityUtil.getUserLoginname());
|
return user == null ? SecurityUtil.getUserLoginname() : defaultIfBlank(user.getLoginname(), SecurityUtil.getUserLoginname());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getSignupOrderColumn(String orderName) {
|
||||||
|
if ("jobNo".equals(orderName)) {
|
||||||
|
return "t.jobNo";
|
||||||
|
}
|
||||||
|
if ("userName".equals(orderName)) {
|
||||||
|
return "t.userName";
|
||||||
|
}
|
||||||
|
if ("unionName".equals(orderName)) {
|
||||||
|
return "t.unionName";
|
||||||
|
}
|
||||||
|
return "t.signupTime";
|
||||||
|
}
|
||||||
|
|
||||||
private String getOrderColumn(String orderName) {
|
private String getOrderColumn(String orderName) {
|
||||||
if ("lineName".equals(orderName)) {
|
if ("lineName".equals(orderName)) {
|
||||||
return "l.lineName";
|
return "l.lineName";
|
||||||
|
|||||||
+6
-2
@@ -23,6 +23,7 @@ public class TourTravelAgencyController {
|
|||||||
|
|
||||||
private static final String MOBILE_PATTERN = "^1[3-9]\\d{9}$";
|
private static final String MOBILE_PATTERN = "^1[3-9]\\d{9}$";
|
||||||
private static final String EMAIL_PATTERN = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$";
|
private static final String EMAIL_PATTERN = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$";
|
||||||
|
private static final String SORT_CODE_PATTERN = "^\\d+$";
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private TourTravelAgencyService travelAgencyService;
|
private TourTravelAgencyService travelAgencyService;
|
||||||
@@ -77,7 +78,7 @@ public class TourTravelAgencyController {
|
|||||||
sameCodeCnd.and(TourTravelAgency::getId, "<>", agency.getId());
|
sameCodeCnd.and(TourTravelAgency::getId, "<>", agency.getId());
|
||||||
}
|
}
|
||||||
if (travelAgencyService.count(sameCodeCnd) > 0) {
|
if (travelAgencyService.count(sameCodeCnd) > 0) {
|
||||||
return Result.error("同年度下旅行社编号已存在");
|
return Result.error("同年度下排序编号已存在");
|
||||||
}
|
}
|
||||||
if (agency.getEnabled() == null) {
|
if (agency.getEnabled() == null) {
|
||||||
agency.setEnabled(true);
|
agency.setEnabled(true);
|
||||||
@@ -113,7 +114,10 @@ public class TourTravelAgencyController {
|
|||||||
return Result.error("旅行社名称不能为空");
|
return Result.error("旅行社名称不能为空");
|
||||||
}
|
}
|
||||||
if (StrUtil.isBlank(agency.getAgencyCode())) {
|
if (StrUtil.isBlank(agency.getAgencyCode())) {
|
||||||
return Result.error("旅行社编号不能为空");
|
return Result.error("排序编号不能为空");
|
||||||
|
}
|
||||||
|
if (!agency.getAgencyCode().matches(SORT_CODE_PATTERN)) {
|
||||||
|
return Result.error("排序编号必须为整数");
|
||||||
}
|
}
|
||||||
if (StrUtil.isBlank(agency.getContactName())) {
|
if (StrUtil.isBlank(agency.getContactName())) {
|
||||||
return Result.error("联系人不能为空");
|
return Result.error("联系人不能为空");
|
||||||
|
|||||||
+530
@@ -0,0 +1,530 @@
|
|||||||
|
package com.budwk.app.zhgh.dayofficework.tour.controller;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.budwk.app.base.constant.RoleConstant;
|
||||||
|
import com.budwk.app.base.page.Pagination;
|
||||||
|
import com.budwk.app.base.param.PageForm;
|
||||||
|
import com.budwk.app.base.result.Result;
|
||||||
|
import com.budwk.app.sys.models.Sys_union;
|
||||||
|
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||||
|
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||||
|
import com.budwk.app.zhgh.dayofficework.tour.models.TourMatter;
|
||||||
|
import com.budwk.app.zhgh.dayofficework.tour.service.TourLedgerService;
|
||||||
|
import com.budwk.app.zhgh.dayofficework.tour.service.TourMatterService;
|
||||||
|
import org.nutz.dao.Cnd;
|
||||||
|
import org.nutz.dao.Sqls;
|
||||||
|
import org.nutz.dao.sql.Sql;
|
||||||
|
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||||
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
|
import org.nutz.mvc.annotation.At;
|
||||||
|
import org.nutz.mvc.annotation.Ok;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@IocBean
|
||||||
|
@Ok("json:full")
|
||||||
|
@At("/platform/tour/undertake")
|
||||||
|
public class TourUndertakeController {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private TourMatterService tourMatterService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private TourLedgerService tourLedgerService;
|
||||||
|
|
||||||
|
@At("")
|
||||||
|
@Ok("beetl:/platform/zhgh/dayofficework/Tour/undertake/index.html")
|
||||||
|
@SaCheckPermission("tour.undertake")
|
||||||
|
public void index() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckPermission("tour.undertake")
|
||||||
|
public Result pageData(PageForm pageForm, Integer year, String lineName, String lineType, String unionId, String undertakeStatus) {
|
||||||
|
if (StrUtil.isBlank(pageForm.getPageOrderName())) {
|
||||||
|
pageForm.defaultSortAsc("lineName");
|
||||||
|
}
|
||||||
|
Cnd cnd = buildQueryCnd(year, lineName, lineType, unionId, undertakeStatus);
|
||||||
|
boolean sysAdmin = AuthUtil.hasRole(RoleConstant.SYSADMIN.name());
|
||||||
|
boolean showCurrentUnionSignupCount = !AuthUtil.hasRole(RoleConstant.SYSADMIN.name())
|
||||||
|
&& StrUtil.isNotBlank(SecurityUtil.getUnionId());
|
||||||
|
String currentUnionId = showCurrentUnionSignupCount ? SecurityUtil.getUnionId() : "";
|
||||||
|
|
||||||
|
Sql countSql = Sqls.create("""
|
||||||
|
SELECT COUNT(1)
|
||||||
|
FROM tour_matter m
|
||||||
|
INNER JOIN tour_line l ON l.id = m.lineId
|
||||||
|
LEFT JOIN sys_union u ON u.id = m.unionId
|
||||||
|
$condition
|
||||||
|
""");
|
||||||
|
countSql.setCondition(cnd);
|
||||||
|
countSql.setCallback(Sqls.callback.integer());
|
||||||
|
tourMatterService.dao().execute(countSql);
|
||||||
|
int count = countSql.getInt();
|
||||||
|
|
||||||
|
Sql listSql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
m.id AS matterId,
|
||||||
|
m.`year`,
|
||||||
|
m.matterName,
|
||||||
|
m.unionId,
|
||||||
|
CASE
|
||||||
|
WHEN IFNULL(NULLIF(m.undertakeStatus, ''), 'unclaimed') = 'claimed' THEN COALESCE(u.name, '校工会')
|
||||||
|
ELSE ''
|
||||||
|
END AS unionName,
|
||||||
|
IFNULL(NULLIF(m.undertakeStatus, ''), 'unclaimed') AS undertakeStatus,
|
||||||
|
CASE
|
||||||
|
WHEN IFNULL(NULLIF(m.undertakeStatus, ''), 'unclaimed') = 'claimed' THEN '已领'
|
||||||
|
ELSE '未领'
|
||||||
|
END AS undertakeStatusName,
|
||||||
|
m.lineId,
|
||||||
|
l.lineName,
|
||||||
|
l.lineType,
|
||||||
|
l.directFamilyUnitLine,
|
||||||
|
m.travelStartTime,
|
||||||
|
m.travelEndTime,
|
||||||
|
CASE
|
||||||
|
WHEN IFNULL(m.travelStartTime, '') <> '' AND IFNULL(m.travelEndTime, '') <> ''
|
||||||
|
THEN CONCAT(m.travelStartTime, ' 至 ', m.travelEndTime)
|
||||||
|
ELSE ''
|
||||||
|
END AS travelPeriod,
|
||||||
|
m.minGroupPeople,
|
||||||
|
m.maxGroupPeople,
|
||||||
|
IFNULL(sc.signupCount, 0) AS signupCount,
|
||||||
|
IFNULL(usc.currentUnionSignupCount, 0) AS currentUnionSignupCount,
|
||||||
|
CASE
|
||||||
|
WHEN m.maxGroupPeople IS NOT NULL AND m.maxGroupPeople > 0 AND IFNULL(sc.signupCount, 0) > m.maxGroupPeople THEN 'over'
|
||||||
|
WHEN m.minGroupPeople IS NOT NULL AND m.minGroupPeople > 0 AND IFNULL(sc.signupCount, 0) >= m.minGroupPeople THEN 'formed'
|
||||||
|
ELSE 'unformed'
|
||||||
|
END AS groupStatus,
|
||||||
|
CASE
|
||||||
|
WHEN m.maxGroupPeople IS NOT NULL AND m.maxGroupPeople > 0 AND IFNULL(sc.signupCount, 0) > m.maxGroupPeople THEN '超员'
|
||||||
|
WHEN m.minGroupPeople IS NOT NULL AND m.minGroupPeople > 0 AND IFNULL(sc.signupCount, 0) >= m.minGroupPeople THEN '已成团'
|
||||||
|
ELSE '未成团'
|
||||||
|
END AS groupStatusName
|
||||||
|
FROM tour_matter m
|
||||||
|
INNER JOIN tour_line l ON l.id = m.lineId
|
||||||
|
LEFT JOIN sys_union u ON u.id = m.unionId
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT t.matterId, SUM(1 + IFNULL(f.familyCount, 0)) AS signupCount
|
||||||
|
FROM tour_ledger t
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT ledgerId, COUNT(1) AS familyCount
|
||||||
|
FROM tour_ledger_family
|
||||||
|
WHERE delFlag = 0
|
||||||
|
GROUP BY ledgerId
|
||||||
|
) f ON f.ledgerId = t.id
|
||||||
|
WHERE t.delFlag = 0
|
||||||
|
AND t.matterId IS NOT NULL
|
||||||
|
AND t.matterId <> ''
|
||||||
|
GROUP BY t.matterId
|
||||||
|
) sc ON sc.matterId = m.id
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT t.matterId, SUM(1 + IFNULL(f.familyCount, 0)) AS currentUnionSignupCount
|
||||||
|
FROM tour_ledger t
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT ledgerId, COUNT(1) AS familyCount
|
||||||
|
FROM tour_ledger_family
|
||||||
|
WHERE delFlag = 0
|
||||||
|
GROUP BY ledgerId
|
||||||
|
) f ON f.ledgerId = t.id
|
||||||
|
WHERE t.delFlag = 0
|
||||||
|
AND t.matterId IS NOT NULL
|
||||||
|
AND t.matterId <> ''
|
||||||
|
AND t.unionId = @currentUnionId
|
||||||
|
GROUP BY t.matterId
|
||||||
|
) usc ON usc.matterId = m.id
|
||||||
|
$condition
|
||||||
|
ORDER BY $orderColumn $orderBy, m.`year` DESC, m.travelStartTime ASC, l.lineName ASC, m.createdAt DESC
|
||||||
|
""");
|
||||||
|
listSql.setCondition(cnd);
|
||||||
|
listSql.setParam("currentUnionId", currentUnionId);
|
||||||
|
listSql.setVar("orderColumn", getOrderColumn(pageForm.getPageOrderName()));
|
||||||
|
listSql.setVar("orderBy", "descending".equals(pageForm.getPageOrderBy()) ? "desc" : "asc");
|
||||||
|
listSql.setPager(tourMatterService.dao().createPager(pageForm.getPageNumber(), pageForm.getPageSize()));
|
||||||
|
listSql.setCallback(Sqls.callback.maps());
|
||||||
|
tourMatterService.dao().execute(listSql);
|
||||||
|
|
||||||
|
List<NutMap> list = listSql.getList(NutMap.class);
|
||||||
|
for (NutMap item : list) {
|
||||||
|
item.put("showCurrentUnionSignupCount", showCurrentUnionSignupCount);
|
||||||
|
item.put("canRelease", sysAdmin && "claimed".equals(item.getString("undertakeStatus", "")));
|
||||||
|
}
|
||||||
|
Pagination<NutMap> pagination = new Pagination<>(pageForm.getPageNumber(), pageForm.getPageSize(), count, list);
|
||||||
|
return Result.success(pagination);
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckPermission("tour.undertake")
|
||||||
|
public Result unionOptions() {
|
||||||
|
Cnd cnd = Cnd.NEW();
|
||||||
|
cnd.asc("unionCode");
|
||||||
|
cnd.asc("name");
|
||||||
|
return Result.success(tourMatterService.dao().query(Sys_union.class, cnd));
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckPermission("tour.undertake")
|
||||||
|
public Result currentUnion() {
|
||||||
|
NutMap unionInfo = currentUnionInfo();
|
||||||
|
if (unionInfo.isEmpty()) {
|
||||||
|
return Result.error("未获取到当前登录人工会");
|
||||||
|
}
|
||||||
|
return Result.success(unionInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckPermission("tour.undertake")
|
||||||
|
public Result undertakeLine(String matterId) {
|
||||||
|
if (StrUtil.isBlank(matterId)) {
|
||||||
|
return Result.error("参数错误");
|
||||||
|
}
|
||||||
|
NutMap unionInfo = currentUnionInfo();
|
||||||
|
if (unionInfo.isEmpty()) {
|
||||||
|
return Result.error("未获取到当前登录人工会");
|
||||||
|
}
|
||||||
|
TourMatter matter = tourMatterService.fetch(matterId);
|
||||||
|
if (matter == null || Boolean.TRUE.equals(matter.getDelFlag())) {
|
||||||
|
return Result.error("事项不存在");
|
||||||
|
}
|
||||||
|
if ("claimed".equals(matter.getUndertakeStatus())) {
|
||||||
|
return Result.error("当前线路已领办,不允许修改");
|
||||||
|
}
|
||||||
|
matter.setUnionId(unionInfo.getString("unionId"));
|
||||||
|
matter.setUndertakeStatus("claimed");
|
||||||
|
tourMatterService.update(matter);
|
||||||
|
return Result.success(unionInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckPermission("tour.undertake")
|
||||||
|
public Result releaseUndertakeLine(String matterId) {
|
||||||
|
if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) {
|
||||||
|
return Result.error("仅系统管理员可以解除领办");
|
||||||
|
}
|
||||||
|
if (StrUtil.isBlank(matterId)) {
|
||||||
|
return Result.error("参数错误");
|
||||||
|
}
|
||||||
|
TourMatter matter = tourMatterService.fetch(matterId);
|
||||||
|
if (matter == null || Boolean.TRUE.equals(matter.getDelFlag())) {
|
||||||
|
return Result.error("事项不存在");
|
||||||
|
}
|
||||||
|
if (!"claimed".equals(matter.getUndertakeStatus())) {
|
||||||
|
return Result.error("当前线路未领办,无需解除");
|
||||||
|
}
|
||||||
|
matter.setUnionId("");
|
||||||
|
matter.setUndertakeStatus("unclaimed");
|
||||||
|
tourMatterService.update(matter);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckPermission("tour.undertake")
|
||||||
|
public Result lineTypeOptions(Integer year) {
|
||||||
|
Cnd cnd = buildQueryCnd(year, null, null, null, null);
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT DISTINCT l.lineType
|
||||||
|
FROM tour_matter m
|
||||||
|
INNER JOIN tour_line l ON l.id = m.lineId
|
||||||
|
LEFT JOIN sys_union u ON u.id = m.unionId
|
||||||
|
$condition
|
||||||
|
ORDER BY l.lineType ASC
|
||||||
|
""");
|
||||||
|
sql.setCondition(cnd);
|
||||||
|
sql.setCallback(Sqls.callback.maps());
|
||||||
|
tourMatterService.dao().execute(sql);
|
||||||
|
return Result.success(sql.getList(NutMap.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
private NutMap currentUnionInfo() {
|
||||||
|
String unionId = SecurityUtil.getUnionId();
|
||||||
|
if (StrUtil.isBlank(unionId)) {
|
||||||
|
return NutMap.NEW();
|
||||||
|
}
|
||||||
|
Sys_union union = tourMatterService.dao().fetch(Sys_union.class, unionId);
|
||||||
|
if (union == null) {
|
||||||
|
return NutMap.NEW();
|
||||||
|
}
|
||||||
|
return NutMap.NEW()
|
||||||
|
.addv("unionId", union.getId())
|
||||||
|
.addv("unionName", union.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@SaCheckPermission("tour.undertake")
|
||||||
|
public Result signupPageData(PageForm pageForm, String matterId, String keyword, String unionId) {
|
||||||
|
if (StrUtil.isBlank(matterId)) {
|
||||||
|
return Result.error("参数错误");
|
||||||
|
}
|
||||||
|
if (StrUtil.isBlank(pageForm.getPageOrderName())) {
|
||||||
|
pageForm.defaultSortDesc("signupTime");
|
||||||
|
}
|
||||||
|
Cnd cnd = buildSignupQueryCnd(matterId, keyword, unionId);
|
||||||
|
Sql countSql = Sqls.create("""
|
||||||
|
SELECT COUNT(1)
|
||||||
|
FROM tour_ledger t
|
||||||
|
INNER JOIN tour_matter m ON m.id = t.matterId
|
||||||
|
INNER JOIN tour_line l ON l.id = m.lineId
|
||||||
|
$condition
|
||||||
|
""");
|
||||||
|
countSql.setCondition(cnd);
|
||||||
|
countSql.setCallback(Sqls.callback.integer());
|
||||||
|
tourLedgerService.dao().execute(countSql);
|
||||||
|
int count = countSql.getInt();
|
||||||
|
|
||||||
|
Sql listSql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
t.id,
|
||||||
|
t.jobNo,
|
||||||
|
t.userName,
|
||||||
|
'' AS mobile,
|
||||||
|
t.idCard,
|
||||||
|
t.unionId,
|
||||||
|
t.unionName,
|
||||||
|
t.signupTime
|
||||||
|
FROM tour_ledger t
|
||||||
|
INNER JOIN tour_matter m ON m.id = t.matterId
|
||||||
|
INNER JOIN tour_line l ON l.id = m.lineId
|
||||||
|
$condition
|
||||||
|
ORDER BY $orderColumn $orderBy, t.signupTime DESC, t.createdAt DESC
|
||||||
|
""");
|
||||||
|
listSql.setCondition(cnd);
|
||||||
|
listSql.setVar("orderColumn", getSignupOrderColumn(pageForm.getPageOrderName()));
|
||||||
|
listSql.setVar("orderBy", "ascending".equals(pageForm.getPageOrderBy()) ? "asc" : "desc");
|
||||||
|
listSql.setPager(tourLedgerService.dao().createPager(pageForm.getPageNumber(), pageForm.getPageSize()));
|
||||||
|
listSql.setCallback(Sqls.callback.maps());
|
||||||
|
tourLedgerService.dao().execute(listSql);
|
||||||
|
|
||||||
|
List<NutMap> list = listSql.getList(NutMap.class);
|
||||||
|
fillSignupMobile(list);
|
||||||
|
fillSignupFamilies(list);
|
||||||
|
Pagination<NutMap> pagination = new Pagination<>(pageForm.getPageNumber(), pageForm.getPageSize(), count, list);
|
||||||
|
return Result.success(pagination);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Cnd buildSignupQueryCnd(String matterId, String keyword, String unionId) {
|
||||||
|
Cnd cnd = Cnd.NEW();
|
||||||
|
cnd.and("t.delFlag", "=", false);
|
||||||
|
cnd.and("t.matterId", "=", matterId);
|
||||||
|
cnd.and("m.delFlag", "=", false);
|
||||||
|
cnd.and("m.enabled", "=", true);
|
||||||
|
cnd.and("m.lineId", "IS NOT", null);
|
||||||
|
cnd.and("m.lineId", "<>", "");
|
||||||
|
cnd.and("l.delFlag", "=", false);
|
||||||
|
cnd.and("l.enabled", "=", true);
|
||||||
|
if (StrUtil.isNotBlank(keyword)) {
|
||||||
|
SqlExpressionGroup keywordGroup = new SqlExpressionGroup();
|
||||||
|
keywordGroup.orLike("t.userName", keyword.trim());
|
||||||
|
keywordGroup.orLike("t.jobNo", keyword.trim());
|
||||||
|
cnd.and(keywordGroup);
|
||||||
|
}
|
||||||
|
cnd.andEX("t.unionId", "=", unionId);
|
||||||
|
applyMatterDataScope(cnd);
|
||||||
|
return cnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fillSignupMobile(List<NutMap> list) {
|
||||||
|
if (list == null || list.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<String> jobNos = new ArrayList<>();
|
||||||
|
for (NutMap item : list) {
|
||||||
|
String jobNo = item.getString("jobNo", "");
|
||||||
|
if (StrUtil.isNotBlank(jobNo) && !jobNos.contains(jobNo)) {
|
||||||
|
jobNos.add(jobNo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (jobNos.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sql sql = Sqls.create("SELECT loginname, mobile FROM vw_user WHERE loginname IN (@jobNos)");
|
||||||
|
sql.setParam("jobNos", jobNos.toArray(new String[0]));
|
||||||
|
sql.setCallback(Sqls.callback.maps());
|
||||||
|
tourLedgerService.dao().execute(sql);
|
||||||
|
|
||||||
|
Map<String, String> mobileMap = new HashMap<>();
|
||||||
|
for (NutMap user : sql.getList(NutMap.class)) {
|
||||||
|
mobileMap.put(user.getString("loginname", ""), user.getString("mobile", ""));
|
||||||
|
}
|
||||||
|
for (NutMap item : list) {
|
||||||
|
item.put("mobile", mobileMap.getOrDefault(item.getString("jobNo", ""), ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看成团报名人员时按台账ID带出家属子列表,避免前端逐行请求家属信息。
|
||||||
|
*/
|
||||||
|
private void fillSignupFamilies(List<NutMap> list) {
|
||||||
|
if (list == null || list.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<String> ledgerIds = new ArrayList<>();
|
||||||
|
for (NutMap item : list) {
|
||||||
|
String ledgerId = item.getString("id", "");
|
||||||
|
if (StrUtil.isNotBlank(ledgerId) && !ledgerIds.contains(ledgerId)) {
|
||||||
|
ledgerIds.add(ledgerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ledgerIds.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
ledgerId,
|
||||||
|
staffJobNo AS jobNo,
|
||||||
|
familyName AS userName,
|
||||||
|
'' AS mobile,
|
||||||
|
idCard,
|
||||||
|
relationship
|
||||||
|
FROM tour_ledger_family
|
||||||
|
WHERE delFlag = 0
|
||||||
|
AND ledgerId IN (@ledgerIds)
|
||||||
|
ORDER BY createdAt ASC
|
||||||
|
""");
|
||||||
|
sql.setParam("ledgerIds", ledgerIds.toArray(new String[0]));
|
||||||
|
sql.setCallback(Sqls.callback.maps());
|
||||||
|
tourLedgerService.dao().execute(sql);
|
||||||
|
|
||||||
|
Map<String, List<NutMap>> familyMap = new HashMap<>();
|
||||||
|
for (NutMap family : sql.getList(NutMap.class)) {
|
||||||
|
familyMap.computeIfAbsent(family.getString("ledgerId", ""), key -> new ArrayList<>()).add(family);
|
||||||
|
}
|
||||||
|
for (NutMap item : list) {
|
||||||
|
item.put("families", familyMap.getOrDefault(item.getString("id", ""), List.of()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Cnd buildQueryCnd(Integer year, String lineName, String lineType, String unionId, String undertakeStatus) {
|
||||||
|
Cnd cnd = Cnd.NEW();
|
||||||
|
cnd.and("m.delFlag", "=", false);
|
||||||
|
cnd.and("m.enabled", "=", true);
|
||||||
|
cnd.and("m.lineId", "IS NOT", null);
|
||||||
|
cnd.and("m.lineId", "<>", "");
|
||||||
|
cnd.and("l.delFlag", "=", false);
|
||||||
|
cnd.and("l.enabled", "=", true);
|
||||||
|
cnd.andEX("m.`year`", "=", year == null ? LocalDate.now().getYear() : year);
|
||||||
|
cnd.and(Cnd.likeEX("l.lineName", lineName));
|
||||||
|
cnd.andEX("l.lineType", "=", lineType);
|
||||||
|
cnd.andEX("m.unionId", "=", unionId);
|
||||||
|
if ("claimed".equals(undertakeStatus)) {
|
||||||
|
cnd.and("m.undertakeStatus", "=", "claimed");
|
||||||
|
} else if ("unclaimed".equals(undertakeStatus)) {
|
||||||
|
SqlExpressionGroup statusGroup = new SqlExpressionGroup();
|
||||||
|
statusGroup.or("m.undertakeStatus", "=", "unclaimed");
|
||||||
|
statusGroup.or("m.undertakeStatus", "IS", null);
|
||||||
|
statusGroup.or("m.undertakeStatus", "=", "");
|
||||||
|
cnd.and(statusGroup);
|
||||||
|
}
|
||||||
|
applyMatterDataScope(cnd);
|
||||||
|
return cnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线路成团按事项归属控制数据范围:校工会查看全部;分工会查看本工会事项;其它角色仅查看自己创建的事项。
|
||||||
|
*/
|
||||||
|
private void applyMatterDataScope(Cnd cnd) {
|
||||||
|
if (hasSchoolUnionScope() || AuthUtil.hasRole(RoleConstant.BRANCH_UNION_CHAIRMAN.name())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (hasBranchUnionScope()) {
|
||||||
|
cnd.and("m.unionId", "=", SecurityUtil.getUnionId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SqlExpressionGroup creatorGroup = new SqlExpressionGroup();
|
||||||
|
creatorGroup.or("m.creatorUserId", "=", SecurityUtil.getUserId());
|
||||||
|
creatorGroup.or("m.createdBy", "=", SecurityUtil.getUserId());
|
||||||
|
cnd.and(creatorGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasSchoolUnionScope() {
|
||||||
|
return AuthUtil.hasRole(RoleConstant.SYSADMIN.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.SCHOOL_UNION_ADMIN.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.SCHOOL_UNION_CHAIRMAN.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.SCHOOL_UNION_VICE_CHAIRMAN.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.SCHOOL_UNION_WELFARE_ADMIN.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.SCHOOL_UNION_MEMBER_ADMIN.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.SCHOOL_UNION_TC_ADMIN.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.SCHOOL_UNION_WC_ADMIN.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.SCHOOL_UNION_DC_ADMIN.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.SCHOOL_UNION_PROPOSAL_ADMIN.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.SCHOOL_UNION_CLUB_ADMIN.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.SCHOOL_UNION_ACTIVITY_ADMIN.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasBranchUnionScope() {
|
||||||
|
return AuthUtil.hasRole(RoleConstant.BRANCH_UNION_ADMIN.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.BRANCH_UNION_CHAIRMAN.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.BRANCH_UNION_VICE_CHAIRMAN.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.BRANCH_UNION_OPERATOR.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.BRANCH_UNION_GROUP_LEADER.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.BRANCH_UNION_ARTICLE_WRITER.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.BRANCH_UNION_WY.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.BRANCH_UNION_ZUZHI_WY.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.BRANCH_UNION_XUANCHUAN_WY.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.BRANCH_UNION_NVGONG_WY.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.BRANCH_UNION_QINGNIAN_WY.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.BRANCH_UNION_WENTI_WY.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.BRANCH_UNION_SHENGGHUO_WY.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.BRANCH_UNION_TIAOJIE_WY.name())
|
||||||
|
|| AuthUtil.hasRole(RoleConstant.BRANCH_UNION_WENTI_SPORTS.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getOrderColumn(String orderName) {
|
||||||
|
if ("lineName".equals(orderName)) {
|
||||||
|
return "l.lineName";
|
||||||
|
}
|
||||||
|
if ("travelPeriod".equals(orderName)) {
|
||||||
|
return "m.travelStartTime";
|
||||||
|
}
|
||||||
|
if ("matterName".equals(orderName)) {
|
||||||
|
return "m.matterName";
|
||||||
|
}
|
||||||
|
if ("unionName".equals(orderName)) {
|
||||||
|
return "u.name";
|
||||||
|
}
|
||||||
|
if ("undertakeStatusName".equals(orderName)) {
|
||||||
|
return "undertakeStatus";
|
||||||
|
}
|
||||||
|
if ("lineType".equals(orderName)) {
|
||||||
|
return "l.lineType";
|
||||||
|
}
|
||||||
|
if ("signupCount".equals(orderName)) {
|
||||||
|
return "signupCount";
|
||||||
|
}
|
||||||
|
if ("minGroupPeople".equals(orderName)) {
|
||||||
|
return "m.minGroupPeople";
|
||||||
|
}
|
||||||
|
if ("maxGroupPeople".equals(orderName)) {
|
||||||
|
return "m.maxGroupPeople";
|
||||||
|
}
|
||||||
|
if ("groupStatusName".equals(orderName)) {
|
||||||
|
return "groupStatus";
|
||||||
|
}
|
||||||
|
return "l.lineName";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getSignupOrderColumn(String orderName) {
|
||||||
|
if ("jobNo".equals(orderName)) {
|
||||||
|
return "t.jobNo";
|
||||||
|
}
|
||||||
|
if ("userName".equals(orderName)) {
|
||||||
|
return "t.userName";
|
||||||
|
}
|
||||||
|
if ("idCard".equals(orderName)) {
|
||||||
|
return "t.idCard";
|
||||||
|
}
|
||||||
|
if ("unionName".equals(orderName)) {
|
||||||
|
return "t.unionName";
|
||||||
|
}
|
||||||
|
return "t.signupTime";
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
-1
@@ -7,6 +7,7 @@ import com.budwk.app.base.page.Pagination;
|
|||||||
import com.budwk.app.base.param.PageForm;
|
import com.budwk.app.base.param.PageForm;
|
||||||
import com.budwk.app.base.result.Result;
|
import com.budwk.app.base.result.Result;
|
||||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||||
|
import com.budwk.app.sys.views.View_user;
|
||||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||||
import com.budwk.app.zhgh.dayofficework.tour.models.TourLedger;
|
import com.budwk.app.zhgh.dayofficework.tour.models.TourLedger;
|
||||||
import com.budwk.app.zhgh.dayofficework.tour.models.TourLedgerDirectRelative;
|
import com.budwk.app.zhgh.dayofficework.tour.models.TourLedgerDirectRelative;
|
||||||
@@ -20,6 +21,7 @@ import org.nutz.dao.sql.Sql;
|
|||||||
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||||
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.lang.Lang;
|
||||||
import org.nutz.lang.util.NutMap;
|
import org.nutz.lang.util.NutMap;
|
||||||
import org.nutz.mvc.annotation.At;
|
import org.nutz.mvc.annotation.At;
|
||||||
import org.nutz.mvc.annotation.Ok;
|
import org.nutz.mvc.annotation.Ok;
|
||||||
@@ -180,7 +182,7 @@ public class TourUnionApprovalController {
|
|||||||
.and(TourLedgerDirectRelative::getDelFlag, "=", false));
|
.and(TourLedgerDirectRelative::getDelFlag, "=", false));
|
||||||
NutMap signupConfig = getSignupConfig(ledger);
|
NutMap signupConfig = getSignupConfig(ledger);
|
||||||
return Result.success(NutMap.NEW()
|
return Result.success(NutMap.NEW()
|
||||||
.addv("ledger", ledger)
|
.addv("ledger", buildLedgerView(ledger))
|
||||||
.addv("travelPeriod", getTravelPeriod(ledger))
|
.addv("travelPeriod", getTravelPeriod(ledger))
|
||||||
.addv("families", tourLedgerFamilyService.query(familyCnd))
|
.addv("families", tourLedgerFamilyService.query(familyCnd))
|
||||||
.addv("directRelative", directRelative)
|
.addv("directRelative", directRelative)
|
||||||
@@ -189,6 +191,13 @@ public class TourUnionApprovalController {
|
|||||||
.addv("directFamilyUnitLine", signupConfig.getBoolean("directFamilyUnitLine", false)));
|
.addv("directFamilyUnitLine", signupConfig.getBoolean("directFamilyUnitLine", false)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private NutMap buildLedgerView(TourLedger ledger) {
|
||||||
|
NutMap map = Lang.obj2nutmap(ledger);
|
||||||
|
View_user user = tourLedgerService.dao().fetch(View_user.class, Cnd.where("loginname", "=", ledger.getJobNo()));
|
||||||
|
map.addv("mobile", StrUtil.blankToDefault(ledger.getMobile(), user == null ? "" : StrUtil.blankToDefault(user.getMobile(), "")));
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission(value = {"tour.unionApproval", "h5.tour.unionApproval"}, mode = SaMode.OR)
|
@SaCheckPermission(value = {"tour.unionApproval", "h5.tour.unionApproval"}, mode = SaMode.OR)
|
||||||
public Result unionOptions(Boolean audit, Integer startYear, Integer endYear, String keyword, String lineId, String travelPeriod, String lineType) {
|
public Result unionOptions(Boolean audit, Integer startYear, Integer endYear, String keyword, String lineId, String travelPeriod, String lineType) {
|
||||||
|
|||||||
@@ -51,6 +51,11 @@ public class TourLedger extends BaseModel implements Serializable {
|
|||||||
@ColDefine(type = ColType.VARCHAR, width = 30)
|
@ColDefine(type = ColType.VARCHAR, width = 30)
|
||||||
private String idCard;
|
private String idCard;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("手机号")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 30)
|
||||||
|
private String mobile;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("所在单位ID")
|
@Comment("所在单位ID")
|
||||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class TourLine extends BaseModel implements Serializable {
|
|||||||
private Integer year;
|
private Integer year;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("线路编号")
|
@Comment("排序编号")
|
||||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||||
private String lineCode;
|
private String lineCode;
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,12 @@ public class TourMatter extends BaseModel implements Serializable {
|
|||||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
private String unionId;
|
private String unionId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("领办状态")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||||
|
@Default("unclaimed")
|
||||||
|
private String undertakeStatus;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("组织形式")
|
@Comment("组织形式")
|
||||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||||
|
|||||||
@@ -63,6 +63,16 @@ public class TourSetting extends BaseModel implements Serializable {
|
|||||||
@ColDefine(type = ColType.INT)
|
@ColDefine(type = ColType.INT)
|
||||||
private Integer maxGroupPeople;
|
private Integer maxGroupPeople;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("报名开始时间")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||||
|
private String signupStartTime;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("报名结束时间")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||||
|
private String signupEndTime;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("省外几年去一次")
|
@Comment("省外几年去一次")
|
||||||
@ColDefine(type = ColType.INT)
|
@ColDefine(type = ColType.INT)
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class TourTravelAgency extends BaseModel implements Serializable {
|
|||||||
private Integer year;
|
private Integer year;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("旅行社编号")
|
@Comment("排序编号")
|
||||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||||
private String agencyCode;
|
private String agencyCode;
|
||||||
|
|
||||||
|
|||||||
@@ -99,6 +99,12 @@ FROM sys_menu p
|
|||||||
WHERE p.permission = 'tour'
|
WHERE p.permission = 'tour'
|
||||||
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.group') t);
|
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.group') t);
|
||||||
|
|
||||||
|
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
|
||||||
|
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10013', p.id, CONCAT(p.path, '0012'), '领办线路', 'Tour Undertake', 'menu', '/platform/tour/undertake', 'data-pjax', '', 1, 0, 'tour.undertake', NULL, 12, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'l', 0, 0
|
||||||
|
FROM sys_menu p
|
||||||
|
WHERE p.permission = 'tour'
|
||||||
|
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.undertake') t);
|
||||||
|
|
||||||
-- 给系统管理员默认授权,其他角色可在角色管理中按需分配。
|
-- 给系统管理员默认授权,其他角色可在角色管理中按需分配。
|
||||||
INSERT INTO sys_role_menu (roleId, menuId)
|
INSERT INTO sys_role_menu (roleId, menuId)
|
||||||
SELECT r.id, m.id
|
SELECT r.id, m.id
|
||||||
@@ -111,6 +117,7 @@ JOIN sys_menu m ON m.permission IN (
|
|||||||
'tour.matter',
|
'tour.matter',
|
||||||
'tour.signup',
|
'tour.signup',
|
||||||
'tour.group',
|
'tour.group',
|
||||||
|
'tour.undertake',
|
||||||
'tour.mysignup',
|
'tour.mysignup',
|
||||||
'tour.unionledger',
|
'tour.unionledger',
|
||||||
'tour.unionApproval',
|
'tour.unionApproval',
|
||||||
@@ -120,3 +127,14 @@ JOIN sys_menu m ON m.permission IN (
|
|||||||
LEFT JOIN sys_role_menu rm ON rm.roleId = r.id AND rm.menuId = m.id
|
LEFT JOIN sys_role_menu rm ON rm.roleId = r.id AND rm.menuId = m.id
|
||||||
WHERE r.code = 'SYSADMIN'
|
WHERE r.code = 'SYSADMIN'
|
||||||
AND rm.roleId IS NULL;
|
AND rm.roleId IS NULL;
|
||||||
|
|
||||||
|
INSERT INTO sys_role_menu (roleId, menuId)
|
||||||
|
SELECT r.id, m.id
|
||||||
|
FROM sys_role r
|
||||||
|
JOIN sys_menu m ON m.permission IN (
|
||||||
|
'tour',
|
||||||
|
'tour.undertake'
|
||||||
|
)
|
||||||
|
LEFT JOIN sys_role_menu rm ON rm.roleId = r.id AND rm.menuId = m.id
|
||||||
|
WHERE r.code = 'BRANCH_UNION_CHAIRMAN'
|
||||||
|
AND rm.roleId IS NULL;
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE `tour_ledger`
|
||||||
|
ADD COLUMN `mobile` varchar(30) DEFAULT NULL COMMENT '手机号' AFTER `idCard`;
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
ALTER TABLE `tour_matter`
|
||||||
|
ADD COLUMN `undertakeStatus` varchar(20) DEFAULT 'unclaimed' COMMENT '领办状态 claimed已领 unclaimed未领' AFTER `unionId`;
|
||||||
|
|
||||||
|
UPDATE `tour_matter`
|
||||||
|
SET `undertakeStatus` = 'unclaimed'
|
||||||
|
WHERE `undertakeStatus` IS NULL OR `undertakeStatus` = '';
|
||||||
@@ -7,6 +7,7 @@ CREATE TABLE IF NOT EXISTS `tour_matter` (
|
|||||||
`creatorUserId` varchar(32) DEFAULT NULL COMMENT '创建人ID',
|
`creatorUserId` varchar(32) DEFAULT NULL COMMENT '创建人ID',
|
||||||
`creatorName` varchar(100) DEFAULT NULL COMMENT '创建人',
|
`creatorName` varchar(100) DEFAULT NULL COMMENT '创建人',
|
||||||
`unionId` varchar(32) DEFAULT NULL COMMENT '所属工会ID',
|
`unionId` varchar(32) DEFAULT NULL COMMENT '所属工会ID',
|
||||||
|
`undertakeStatus` varchar(20) DEFAULT 'unclaimed' COMMENT '领办状态 claimed已领 unclaimed未领',
|
||||||
`organizationType` varchar(100) DEFAULT NULL COMMENT '组织形式',
|
`organizationType` varchar(100) DEFAULT NULL COMMENT '组织形式',
|
||||||
`mobileThumb` varchar(500) DEFAULT NULL COMMENT '移动端缩略图',
|
`mobileThumb` varchar(500) DEFAULT NULL COMMENT '移动端缩略图',
|
||||||
`enabled` tinyint(1) DEFAULT 1 COMMENT '事项状态',
|
`enabled` tinyint(1) DEFAULT 1 COMMENT '事项状态',
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- 疗休养配置增加全局报名时间字段。
|
||||||
|
ALTER TABLE `tour_setting`
|
||||||
|
ADD COLUMN `signupStartTime` varchar(20) DEFAULT NULL COMMENT '报名开始时间' AFTER `maxGroupPeople`,
|
||||||
|
ADD COLUMN `signupEndTime` varchar(20) DEFAULT NULL COMMENT '报名结束时间' AFTER `signupStartTime`;
|
||||||
@@ -9,6 +9,8 @@ CREATE TABLE IF NOT EXISTS `tour_setting` (
|
|||||||
`sortNo` int DEFAULT NULL COMMENT '排序编号',
|
`sortNo` int DEFAULT NULL COMMENT '排序编号',
|
||||||
`minGroupPeople` int DEFAULT NULL COMMENT '最少成团人数',
|
`minGroupPeople` int DEFAULT NULL COMMENT '最少成团人数',
|
||||||
`maxGroupPeople` int DEFAULT NULL COMMENT '最多成团人数',
|
`maxGroupPeople` int DEFAULT NULL COMMENT '最多成团人数',
|
||||||
|
`signupStartTime` varchar(20) DEFAULT NULL COMMENT '报名开始时间',
|
||||||
|
`signupEndTime` varchar(20) DEFAULT NULL COMMENT '报名结束时间',
|
||||||
`outProvinceYears` int DEFAULT NULL COMMENT '省外几年去一次',
|
`outProvinceYears` int DEFAULT NULL COMMENT '省外几年去一次',
|
||||||
`outProvinceRatio` decimal(10,2) DEFAULT NULL COMMENT '省外人数占比',
|
`outProvinceRatio` decimal(10,2) DEFAULT NULL COMMENT '省外人数占比',
|
||||||
`outProvinceRatioType` varchar(50) DEFAULT '当年报名人数' COMMENT '省外人数占比类型',
|
`outProvinceRatioType` varchar(50) DEFAULT '当年报名人数' COMMENT '省外人数占比类型',
|
||||||
@@ -116,6 +118,7 @@ CREATE TABLE IF NOT EXISTS `tour_matter` (
|
|||||||
`creatorUserId` varchar(32) DEFAULT NULL COMMENT '创建人ID',
|
`creatorUserId` varchar(32) DEFAULT NULL COMMENT '创建人ID',
|
||||||
`creatorName` varchar(100) DEFAULT NULL COMMENT '创建人',
|
`creatorName` varchar(100) DEFAULT NULL COMMENT '创建人',
|
||||||
`unionId` varchar(32) DEFAULT NULL COMMENT '所属工会ID',
|
`unionId` varchar(32) DEFAULT NULL COMMENT '所属工会ID',
|
||||||
|
`undertakeStatus` varchar(20) DEFAULT 'unclaimed' COMMENT '领办状态 claimed已领 unclaimed未领',
|
||||||
`organizationType` varchar(100) DEFAULT NULL COMMENT '组织形式',
|
`organizationType` varchar(100) DEFAULT NULL COMMENT '组织形式',
|
||||||
`mobileThumb` varchar(500) DEFAULT NULL COMMENT '移动端缩略图',
|
`mobileThumb` varchar(500) DEFAULT NULL COMMENT '移动端缩略图',
|
||||||
`enabled` tinyint(1) DEFAULT 1 COMMENT '事项状态',
|
`enabled` tinyint(1) DEFAULT 1 COMMENT '事项状态',
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
|
||||||
|
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10013', p.id, CONCAT(p.path, '0012'), '领办线路', 'Tour Undertake', 'menu', '/platform/tour/undertake', 'data-pjax', '', 1, 0, 'tour.undertake', NULL, 12, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'l', 0, 0
|
||||||
|
FROM sys_menu p
|
||||||
|
WHERE p.permission = 'tour'
|
||||||
|
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.undertake') t);
|
||||||
|
|
||||||
|
INSERT INTO sys_role_menu (roleId, menuId)
|
||||||
|
SELECT r.id, m.id
|
||||||
|
FROM sys_role r
|
||||||
|
JOIN sys_menu m ON m.permission IN (
|
||||||
|
'tour',
|
||||||
|
'tour.undertake'
|
||||||
|
)
|
||||||
|
LEFT JOIN sys_role_menu rm ON rm.roleId = r.id AND rm.menuId = m.id
|
||||||
|
WHERE r.code IN ('SYSADMIN', 'BRANCH_UNION_CHAIRMAN')
|
||||||
|
AND rm.roleId IS NULL;
|
||||||
@@ -173,8 +173,8 @@ layout("/layouts/platform.html"){
|
|||||||
<el-descriptions-item label="报名时间">{{ detail.signupTime || '' }}</el-descriptions-item>
|
<el-descriptions-item label="报名时间">{{ detail.signupTime || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="报名线路">{{ detail.lineName || '' }}</el-descriptions-item>
|
<el-descriptions-item label="报名线路">{{ detail.lineName || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="线路类型">{{ detail.lineType || '' }}</el-descriptions-item>
|
<el-descriptions-item label="线路类型">{{ detail.lineType || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="报名酒店">{{ detail.hotelName || '' }}</el-descriptions-item>
|
<el-descriptions-item v-if="false" label="报名酒店">{{ detail.hotelName || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="报名旅行社">{{ detail.travelAgencyName || '' }}</el-descriptions-item>
|
<el-descriptions-item v-if="false" label="报名旅行社">{{ detail.travelAgencyName || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="出行时间">{{ detail.travelPeriod || '' }}</el-descriptions-item>
|
<el-descriptions-item label="出行时间">{{ detail.travelPeriod || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item v-if="fillBedInfo" label="床型">{{ detail.bedType || '' }}</el-descriptions-item>
|
<el-descriptions-item v-if="fillBedInfo" label="床型">{{ detail.bedType || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item v-if="fillBedInfo" label="床位信息">{{ detail.bedInfo || '' }}</el-descriptions-item>
|
<el-descriptions-item v-if="fillBedInfo" label="床位信息">{{ detail.bedInfo || '' }}</el-descriptions-item>
|
||||||
|
|||||||
@@ -58,13 +58,13 @@ layout("/layouts/platform.html"){
|
|||||||
@sort-change="pageOrder">
|
@sort-change="pageOrder">
|
||||||
<el-table-column label="序号" type="index" :index="indexMethod" width="80" align="center" header-align="center"></el-table-column>
|
<el-table-column label="序号" type="index" :index="indexMethod" width="80" align="center" header-align="center"></el-table-column>
|
||||||
<el-table-column label="年度" prop="year" width="110" sortable="custom" align="center" header-align="center"></el-table-column>
|
<el-table-column label="年度" prop="year" width="110" sortable="custom" align="center" header-align="center"></el-table-column>
|
||||||
<el-table-column label="事项名称" prop="matterName" min-width="200" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="事项名称" prop="matterName" min-width="240" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="所属工会" prop="unionName" min-width="180" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="所属工会" prop="unionName" min-width="160" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="线路名称" prop="lineName" min-width="220" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="线路名称" prop="lineName" min-width="260" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="组织形式" prop="organizationTypeName" width="150" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="组织形式" prop="organizationTypeName" width="130" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="联系人" prop="contactName" width="130" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="联系人" prop="contactName" width="130" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="联系方式" prop="contactPhone" width="150" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="联系方式" prop="contactPhone" width="150" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="事项状态" prop="enabled" width="160" align="center" header-align="center">
|
<el-table-column label="事项状态" prop="enabled" width="140" align="center" header-align="center">
|
||||||
<template slot-scope="{row}">
|
<template slot-scope="{row}">
|
||||||
<el-switch
|
<el-switch
|
||||||
v-model="row.enabled"
|
v-model="row.enabled"
|
||||||
@@ -74,7 +74,7 @@ layout("/layouts/platform.html"){
|
|||||||
</el-switch>
|
</el-switch>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="260" align="center" header-align="center">
|
<el-table-column label="操作" width="260" fixed="right" align="center" header-align="center">
|
||||||
<template slot-scope="{row}">
|
<template slot-scope="{row}">
|
||||||
<el-button size="mini" type="primary" @click="openBatchForm(row)">选择线路</el-button>
|
<el-button size="mini" type="primary" @click="openBatchForm(row)">选择线路</el-button>
|
||||||
<el-button size="mini" type="primary" @click="openEdit(row)">编辑</el-button>
|
<el-button size="mini" type="primary" @click="openEdit(row)">编辑</el-button>
|
||||||
@@ -116,7 +116,7 @@ layout("/layouts/platform.html"){
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-form-item label="事项名称" prop="matterName">
|
<el-form-item label="事项名称" prop="matterName">
|
||||||
<el-input v-model="formData.matterName" maxlength="30" show-word-limit placeholder="请输入事项名称"></el-input>
|
<el-input v-model="formData.matterName" maxlength="30" show-word-limit placeholder="如恩施大峡谷五日第一批次"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="创建人">
|
<el-form-item label="创建人">
|
||||||
<el-input v-model="formData.creatorName" readonly placeholder="当前登录人"></el-input>
|
<el-input v-model="formData.creatorName" readonly placeholder="当前登录人"></el-input>
|
||||||
@@ -504,12 +504,10 @@ layout("/layouts/platform.html"){
|
|||||||
this.batchForm.travelStartTime = this.dateOnly(this.batchForm.travelStartTime)
|
this.batchForm.travelStartTime = this.dateOnly(this.batchForm.travelStartTime)
|
||||||
this.batchForm.travelEndTime = this.dateOnly(this.batchForm.travelEndTime)
|
this.batchForm.travelEndTime = this.dateOnly(this.batchForm.travelEndTime)
|
||||||
this.applySelectedLineDefaults(false)
|
this.applySelectedLineDefaults(false)
|
||||||
if (!this.batchForm.minGroupPeople || !this.batchForm.maxGroupPeople) {
|
this.loadSettingDefaults((data) => {
|
||||||
this.loadSettingPeople((data) => {
|
this.applySettingPeople(data)
|
||||||
this.batchForm.minGroupPeople = data.minGroupPeople || null
|
this.applySettingSignupTime(data)
|
||||||
this.batchForm.maxGroupPeople = data.maxGroupPeople || null
|
})
|
||||||
})
|
|
||||||
}
|
|
||||||
this.batchFormVisible = true
|
this.batchFormVisible = true
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.applySelectedLineDefaults(true)
|
this.applySelectedLineDefaults(true)
|
||||||
@@ -589,8 +587,39 @@ layout("/layouts/platform.html"){
|
|||||||
if (!value) return ""
|
if (!value) return ""
|
||||||
return String(value).substring(0, 10)
|
return String(value).substring(0, 10)
|
||||||
},
|
},
|
||||||
loadSettingPeople(callback) {
|
applySettingSignupTime(data) {
|
||||||
this.$axios.post(loc() + "/settingPeople", { matterId: this.currentMatter.id }).then((res) => {
|
if (!data) return
|
||||||
|
if (data.signupStartTime) {
|
||||||
|
this.$set(this.batchForm, "signupStartTime", data.signupStartTime)
|
||||||
|
}
|
||||||
|
if (data.signupEndTime) {
|
||||||
|
this.$set(this.batchForm, "signupEndTime", data.signupEndTime)
|
||||||
|
}
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.batchFormRef) {
|
||||||
|
this.$refs.batchFormRef.validateField(["signupStartTime", "signupEndTime"])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
applySettingPeople(data) {
|
||||||
|
if (!data) return
|
||||||
|
if (data.minGroupPeople !== null && data.minGroupPeople !== undefined && data.minGroupPeople !== "") {
|
||||||
|
this.$set(this.batchForm, "minGroupPeople", data.minGroupPeople)
|
||||||
|
}
|
||||||
|
if (data.maxGroupPeople !== null && data.maxGroupPeople !== undefined && data.maxGroupPeople !== "") {
|
||||||
|
this.$set(this.batchForm, "maxGroupPeople", data.maxGroupPeople)
|
||||||
|
}
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.batchFormRef) {
|
||||||
|
this.$refs.batchFormRef.validateField(["minGroupPeople", "maxGroupPeople"])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
loadSettingDefaults(callback) {
|
||||||
|
this.$axios.post(loc() + "/settingPeople", {
|
||||||
|
matterId: this.currentMatter.id,
|
||||||
|
year: this.currentMatter.year
|
||||||
|
}).then((res) => {
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
const data = res.data || {}
|
const data = res.data || {}
|
||||||
callback && callback(data)
|
callback && callback(data)
|
||||||
|
|||||||
@@ -50,7 +50,8 @@ layout("/layouts/platform.html"){
|
|||||||
<el-table-column v-if="false" label="所在单位" prop="unitName" min-width="180" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column v-if="false" label="所在单位" prop="unitName" min-width="180" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="报名线路" prop="lineName" min-width="220" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="报名线路" prop="lineName" min-width="220" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="出行时段" prop="travelPeriod" min-width="260" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="出行时段" prop="travelPeriod" min-width="260" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="线路类型" prop="lineType" width="130" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="所属工会" prop="matterUnionName" min-width="180" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column v-if="false" label="线路类型" prop="lineType" width="130" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="报名时间" prop="signupTime" width="170" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="报名时间" prop="signupTime" width="170" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="携带家属" prop="familyCount" width="120" sortable="custom" align="center" header-align="center">
|
<el-table-column label="携带家属" prop="familyCount" width="120" sortable="custom" align="center" header-align="center">
|
||||||
<template slot-scope="{row}">
|
<template slot-scope="{row}">
|
||||||
@@ -79,7 +80,7 @@ layout("/layouts/platform.html"){
|
|||||||
<el-button v-if="canModify(row) || isTravelEnded(row)" size="mini" type="primary" :disabled="isTravelEnded(row)" @click="openSignup(row)">修改</el-button>
|
<el-button v-if="canModify(row) || isTravelEnded(row)" size="mini" type="primary" :disabled="isTravelEnded(row)" @click="openSignup(row)">修改</el-button>
|
||||||
<el-button v-if="canRevoke(row)" size="mini" type="danger" @click="revokeSignup(row)">撤回</el-button>
|
<el-button v-if="canRevoke(row)" size="mini" type="danger" @click="revokeSignup(row)">撤回</el-button>
|
||||||
<el-button v-if="showExport(row)" size="mini" type="primary" :disabled="!canExport(row)" @click="exportSignup(row)">报销申请</el-button>
|
<el-button v-if="showExport(row)" size="mini" type="primary" :disabled="!canExport(row)" @click="exportSignup(row)">报销申请</el-button>
|
||||||
<el-button v-if="showDirectRelativeExport(row)" size="mini" type="primary" :disabled="!canDirectRelativeExport(row)" @click="exportDirectRelative(row)">亲属线路申请</el-button>
|
<el-button v-if="showDirectRelativeExport(row)" size="mini" type="primary" :disabled="!canDirectRelativeExport(row)" @click="exportDirectRelative(row)">下载亲属线路申请</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -113,8 +114,8 @@ layout("/layouts/platform.html"){
|
|||||||
<el-descriptions-item label="报名时间">{{ detail.signupTime || '' }}</el-descriptions-item>
|
<el-descriptions-item label="报名时间">{{ detail.signupTime || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="报名线路">{{ detail.lineName || '' }}</el-descriptions-item>
|
<el-descriptions-item label="报名线路">{{ detail.lineName || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="线路类型">{{ detail.lineType || '' }}</el-descriptions-item>
|
<el-descriptions-item label="线路类型">{{ detail.lineType || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="报名酒店">{{ detail.hotelName || '' }}</el-descriptions-item>
|
<el-descriptions-item v-if="false" label="报名酒店">{{ detail.hotelName || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="报名旅行社">{{ detail.travelAgencyName || '' }}</el-descriptions-item>
|
<el-descriptions-item v-if="false" label="报名旅行社">{{ detail.travelAgencyName || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="出行时间">{{ detail.travelPeriod || '' }}</el-descriptions-item>
|
<el-descriptions-item label="出行时间">{{ detail.travelPeriod || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item v-if="detailFillBedInfo" label="床型">{{ detail.bedType || '' }}</el-descriptions-item>
|
<el-descriptions-item v-if="detailFillBedInfo" label="床型">{{ detail.bedType || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item v-if="detailFillBedInfo" label="床位信息">{{ detail.bedInfo || '' }}</el-descriptions-item>
|
<el-descriptions-item v-if="detailFillBedInfo" label="床位信息">{{ detail.bedInfo || '' }}</el-descriptions-item>
|
||||||
@@ -249,12 +250,12 @@ layout("/layouts/platform.html"){
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="8">
|
<el-col v-if="false" :span="8">
|
||||||
<el-form-item label="报名酒店">
|
<el-form-item label="报名酒店">
|
||||||
<el-input v-model="signupForm.hotelName" :disabled="isDirectFamilyLine(signupForm)" maxlength="100" placeholder="请输入报名酒店"></el-input>
|
<el-input v-model="signupForm.hotelName" :disabled="isDirectFamilyLine(signupForm)" maxlength="100" placeholder="请输入报名酒店"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col v-if="false" :span="8">
|
||||||
<el-form-item label="报名旅行社">
|
<el-form-item label="报名旅行社">
|
||||||
<el-input v-model="signupForm.travelAgencyName" :disabled="isDirectFamilyLine(signupForm)" readonly></el-input>
|
<el-input v-model="signupForm.travelAgencyName" :disabled="isDirectFamilyLine(signupForm)" readonly></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -469,7 +470,7 @@ layout("/layouts/platform.html"){
|
|||||||
<div class="tour-export-date">时间:<span class="tour-export-sign-date">{{ formatDate(exportForm.unionAuditDate) }}</span></div>
|
<div class="tour-export-date">时间:<span class="tour-export-sign-date">{{ formatDate(exportForm.unionAuditDate) }}</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tour-export-sign school">
|
<div class="tour-export-sign school">
|
||||||
<div>学校工会:盖章</div>
|
<div>学校工会:盖章<span class="tour-export-sign-value">{{ exportForm.schoolUnionAuditorName }}</span></div>
|
||||||
<div class="tour-export-date">时间:<span class="tour-export-sign-date">{{ formatDate(exportForm.schoolUnionAuditDate) }}</span></div>
|
<div class="tour-export-date">时间:<span class="tour-export-sign-date">{{ formatDate(exportForm.schoolUnionAuditDate) }}</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -491,7 +492,7 @@ layout("/layouts/platform.html"){
|
|||||||
<div class="tour-export-date">时间:<span class="tour-export-sign-date">{{ formatDate(directRelativeExportForm.unionAuditDate) }}</span></div>
|
<div class="tour-export-date">时间:<span class="tour-export-sign-date">{{ formatDate(directRelativeExportForm.unionAuditDate) }}</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tour-export-sign tour-export-direct-sign">
|
<div class="tour-export-sign tour-export-direct-sign">
|
||||||
<div>学校工会:盖章</div>
|
<div>学校工会:盖章<span class="tour-export-sign-value">{{ directRelativeExportForm.schoolUnionAuditorName }}</span></div>
|
||||||
<div class="tour-export-date">时间:<span class="tour-export-sign-date">{{ formatDate(directRelativeExportForm.schoolUnionAuditDate) }}</span></div>
|
<div class="tour-export-date">时间:<span class="tour-export-sign-date">{{ formatDate(directRelativeExportForm.schoolUnionAuditDate) }}</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tour-export-sign tour-export-direct-sign">
|
<div class="tour-export-sign tour-export-direct-sign">
|
||||||
@@ -772,6 +773,7 @@ layout("/layouts/platform.html"){
|
|||||||
applyDate: "",
|
applyDate: "",
|
||||||
unionAuditorName: "",
|
unionAuditorName: "",
|
||||||
unionAuditDate: "",
|
unionAuditDate: "",
|
||||||
|
schoolUnionAuditorName: "",
|
||||||
schoolUnionAuditDate: ""
|
schoolUnionAuditDate: ""
|
||||||
},
|
},
|
||||||
directRelativeExportForm: {
|
directRelativeExportForm: {
|
||||||
@@ -790,6 +792,7 @@ layout("/layouts/platform.html"){
|
|||||||
applyDate: "",
|
applyDate: "",
|
||||||
unionAuditorName: "",
|
unionAuditorName: "",
|
||||||
unionAuditDate: "",
|
unionAuditDate: "",
|
||||||
|
schoolUnionAuditorName: "",
|
||||||
schoolUnionAuditDate: "",
|
schoolUnionAuditDate: "",
|
||||||
relativeUnitAuditDate: ""
|
relativeUnitAuditDate: ""
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -49,16 +49,16 @@ layout("/layouts/platform.html"){
|
|||||||
:data="tableData"
|
:data="tableData"
|
||||||
:size="tableSize"
|
:size="tableSize"
|
||||||
border
|
border
|
||||||
:default-sort="{prop: 'enabled', order: 'descending'}"
|
:default-sort="{prop: 'lineCode', order: 'ascending'}"
|
||||||
:row-class-name="tableRowClassName"
|
:row-class-name="tableRowClassName"
|
||||||
@sort-change="pageOrder">
|
@sort-change="pageOrder">
|
||||||
<el-table-column label="序号" type="index" :index="indexMethod" width="80" align="center" header-align="center"></el-table-column>
|
<el-table-column label="序号" type="index" :index="indexMethod" width="80" align="center" header-align="center"></el-table-column>
|
||||||
<el-table-column label="创建年度" prop="year" width="120" sortable="custom" align="center" header-align="center"></el-table-column>
|
<el-table-column label="创建年度" prop="year" width="120" sortable="custom" align="center" header-align="center"></el-table-column>
|
||||||
<el-table-column label="线路编号" prop="lineCode" width="140" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
|
||||||
<el-table-column label="线路名称" prop="lineName" min-width="220" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="线路名称" prop="lineName" min-width="220" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="时间标段" prop="lotName" width="140" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="时间标段" prop="lotName" width="140" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="线路类型" prop="lineType" width="140" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="线路类型" prop="lineType" width="140" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="创建人" prop="creatorName" width="140" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="创建人" prop="creatorName" width="140" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="排序编号" prop="lineCode" width="140" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="是否对外开放" prop="openFlag" width="160" align="center" header-align="center">
|
<el-table-column label="是否对外开放" prop="openFlag" width="160" align="center" header-align="center">
|
||||||
<template slot-scope="{row}">
|
<template slot-scope="{row}">
|
||||||
<el-switch
|
<el-switch
|
||||||
@@ -79,9 +79,10 @@ layout("/layouts/platform.html"){
|
|||||||
</el-switch>
|
</el-switch>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="260" align="center" header-align="center">
|
<el-table-column label="操作" width="340" align="center" header-align="center">
|
||||||
<template slot-scope="{row}">
|
<template slot-scope="{row}">
|
||||||
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
|
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
|
||||||
|
<el-button size="mini" type="primary" @click="createMatter(row)">新建事项</el-button>
|
||||||
<el-button size="mini" type="primary" @click="openEdit(row)">编辑</el-button>
|
<el-button size="mini" type="primary" @click="openEdit(row)">编辑</el-button>
|
||||||
<el-button size="mini" type="danger" @click="doDelete(row)">删除</el-button>
|
<el-button size="mini" type="danger" @click="doDelete(row)">删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
@@ -136,8 +137,8 @@ layout("/layouts/platform.html"){
|
|||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="线路编号" prop="lineCode">
|
<el-form-item label="排序编号" prop="lineCode">
|
||||||
<el-input v-model="formData.lineCode" maxlength="50" placeholder="建议年度加序号,如202601"></el-input>
|
<el-input-number v-model="formData.lineCode" :controls="false" :min="0" :precision="0" placeholder="请输入排序编号" style="width: 100%"></el-input-number>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
@@ -206,6 +207,132 @@ layout("/layouts/platform.html"){
|
|||||||
<el-button v-if="!viewMode" type="primary" :loading="submitLoading" @click="doSubmit">保存</el-button>
|
<el-button v-if="!viewMode" type="primary" :loading="submitLoading" @click="doSubmit">保存</el-button>
|
||||||
</span>
|
</span>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
title="新建事项"
|
||||||
|
:visible.sync="matterDialogVisible"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
width="64%">
|
||||||
|
<el-form :model="matterForm" :rules="matterFormRules" label-width="110px" ref="matterFormRef">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="年度" prop="year">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="matterForm.year"
|
||||||
|
type="year"
|
||||||
|
value-format="yyyy"
|
||||||
|
placeholder="请选择年度"
|
||||||
|
style="width: 100%"
|
||||||
|
@change="matterYearChange">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="事项状态" prop="enabled">
|
||||||
|
<el-radio-group v-model="matterForm.enabled">
|
||||||
|
<el-radio :label="true">启用</el-radio>
|
||||||
|
<el-radio :label="false">禁用</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-form-item label="事项名称" prop="matterName">
|
||||||
|
<el-input v-model="matterForm.matterName" maxlength="30" show-word-limit placeholder="请输入事项名称"></el-input>
|
||||||
|
<div class="tour-matter-name-tip">建议事项名称:{{ matterNameTip() }}</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建人">
|
||||||
|
<el-input v-model="matterForm.creatorName" readonly placeholder="当前登录人"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="疗休养配置" prop="settingId">
|
||||||
|
<el-select v-model="matterForm.settingId" clearable filterable placeholder="请选择配置" style="width: 100%">
|
||||||
|
<el-option v-for="item in matterSettingOptions" :key="item.id" :label="item.configName" :value="item.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="组织形式" prop="organizationType">
|
||||||
|
<el-select v-model="matterForm.organizationType" clearable filterable placeholder="请选择组织形式" style="width: 100%" @change="matterOrganizationTypeChange">
|
||||||
|
<el-option v-for="item in matterOrganizationTypeOptions" :key="item.code" :label="item.name" :value="item.code"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="所属工会" prop="unionId">
|
||||||
|
<el-select v-model="matterForm.unionId" clearable filterable placeholder="请选择所属工会" style="width: 100%" :disabled="isMatterUnionDisabled()">
|
||||||
|
<el-option v-for="item in matterUnionOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="matterDialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" :loading="matterSubDis" @click="submitMatterStep">下一步</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
title="选择线路"
|
||||||
|
:visible.sync="lineConfigDialogVisible"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
width="74%">
|
||||||
|
<el-form :model="batchForm" :rules="batchRules" label-width="110px" ref="batchFormRef">
|
||||||
|
<el-form-item label="线路" prop="lineId">
|
||||||
|
<el-select v-model="batchForm.lineId" disabled filterable placeholder="请选择线路" style="width: 100%">
|
||||||
|
<el-option v-for="item in matterLineOptions" :key="item.id" :label="matterLineOptionLabel(item)" :value="item.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="报名开始时间" prop="signupStartTime">
|
||||||
|
<el-date-picker v-model="batchForm.signupStartTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择时间" style="width: 100%"></el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="报名结束时间" prop="signupEndTime">
|
||||||
|
<el-date-picker v-model="batchForm.signupEndTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择时间" style="width: 100%"></el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="出行开始时间" prop="travelStartTime">
|
||||||
|
<el-date-picker v-model="batchForm.travelStartTime" type="date" value-format="yyyy-MM-dd" placeholder="选择日期" style="width: 100%" @change="matterTravelStartChange"></el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="出行结束时间" prop="travelEndTime">
|
||||||
|
<el-date-picker v-model="batchForm.travelEndTime" type="date" value-format="yyyy-MM-dd" placeholder="选择日期" style="width: 100%" @change="validateMatterTravelFields"></el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="联系人" prop="contactName">
|
||||||
|
<el-input v-model="batchForm.contactName" maxlength="10" placeholder="请输入联系人"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="联系方式" prop="contactPhone">
|
||||||
|
<el-input v-model="batchForm.contactPhone" maxlength="11" placeholder="请输入联系方式"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="预计费用" prop="estimatedCost">
|
||||||
|
<el-input v-model="batchForm.estimatedCost" maxlength="10" placeholder="请输入预计费用"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="最少成团人数" prop="minGroupPeople">
|
||||||
|
<el-input-number v-model="batchForm.minGroupPeople" :min="1" :precision="0" controls-position="right" style="width: 100%" @change="matterPeopleChange"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="最多成团人数" prop="maxGroupPeople">
|
||||||
|
<el-input-number v-model="batchForm.maxGroupPeople" :min="1" :precision="0" controls-position="right" style="width: 100%" @change="matterPeopleChange"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="backToMatterStep">上一步</el-button>
|
||||||
|
<el-button type="primary" :loading="batchSubDis" @click="submitMatterLineConfig">保存</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@@ -213,6 +340,13 @@ layout("/layouts/platform.html"){
|
|||||||
.el-table .direct-family-row > td .cell {
|
.el-table .direct-family-row > td .cell {
|
||||||
color: #f56c6c;
|
color: #f56c6c;
|
||||||
}
|
}
|
||||||
|
.tour-matter-name-tip {
|
||||||
|
margin-top: 6px;
|
||||||
|
color: #f56c6c;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 20px;
|
||||||
|
user-select: text;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script nonce="${cspNonce!}">
|
<script nonce="${cspNonce!}">
|
||||||
@@ -222,25 +356,93 @@ layout("/layouts/platform.html"){
|
|||||||
mixins: [initTableMixins],
|
mixins: [initTableMixins],
|
||||||
data() {
|
data() {
|
||||||
const currentYear = moment().format("YYYY")
|
const currentYear = moment().format("YYYY")
|
||||||
|
const validateMatterUnion = (rule, value, callback) => {
|
||||||
|
if (this.matterForm.organizationType === "schoolUnion" || value) {
|
||||||
|
callback()
|
||||||
|
} else {
|
||||||
|
callback(new Error("必填"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const validateMatterMobile = (rule, value, callback) => {
|
||||||
|
const mobileReg = /^1[3-9]\d{9}$/
|
||||||
|
if (!value) {
|
||||||
|
callback(new Error("必填"))
|
||||||
|
} else if (!mobileReg.test(value)) {
|
||||||
|
callback(new Error("手机号码格式不正确"))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const validateMatterMoney = (rule, value, callback) => {
|
||||||
|
const moneyReg = /^(0|[1-9]\d*)(\.\d{1,2})?$/
|
||||||
|
if (value === "" || value === null || value === undefined) {
|
||||||
|
callback(new Error("必填"))
|
||||||
|
} else if (!moneyReg.test(String(value))) {
|
||||||
|
callback(new Error("请输入非负金额,最多两位小数"))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const validateMatterPeople = (rule, value, callback) => {
|
||||||
|
if (!value || value <= 0) {
|
||||||
|
callback(new Error("人数必须大于0"))
|
||||||
|
} else if (this.batchForm.minGroupPeople && this.batchForm.maxGroupPeople
|
||||||
|
&& this.batchForm.minGroupPeople > this.batchForm.maxGroupPeople) {
|
||||||
|
callback(new Error("最少人数不能大于最多人数"))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const validateMatterTime = (rule, value, callback) => {
|
||||||
|
if (!value) {
|
||||||
|
callback(new Error("必填"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const form = this.batchForm
|
||||||
|
if (form.signupStartTime && form.signupEndTime && form.signupStartTime >= form.signupEndTime) {
|
||||||
|
callback(new Error("报名开始时间必须小于报名结束时间"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (form.travelStartTime && form.travelEndTime && form.travelStartTime > form.travelEndTime) {
|
||||||
|
callback(new Error("出行开始时间不能晚于出行结束时间"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (form.signupEndTime && form.travelStartTime && form.signupEndTime >= form.travelStartTime) {
|
||||||
|
callback(new Error("报名结束时间必须小于出行开始时间"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
title: "",
|
title: "",
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
viewMode: false,
|
viewMode: false,
|
||||||
submitLoading: false,
|
submitLoading: false,
|
||||||
|
matterDialogVisible: false,
|
||||||
|
matterSubDis: false,
|
||||||
|
lineConfigDialogVisible: false,
|
||||||
|
batchSubDis: false,
|
||||||
|
selectedMatterLine: {},
|
||||||
travelAgencyOptions: [],
|
travelAgencyOptions: [],
|
||||||
lotOptions: [],
|
lotOptions: [],
|
||||||
lineTypeOptions: [],
|
lineTypeOptions: [],
|
||||||
|
matterSettingOptions: [],
|
||||||
|
matterUnionOptions: [],
|
||||||
|
matterOrganizationTypeOptions: [],
|
||||||
|
matterLineOptions: [],
|
||||||
pageForm: {
|
pageForm: {
|
||||||
pageNumber: 1,
|
pageNumber: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
totalCount: 0,
|
totalCount: 0,
|
||||||
pageOrderName: "enabled",
|
pageOrderName: "lineCode",
|
||||||
pageOrderBy: "descending",
|
pageOrderBy: "ascending",
|
||||||
year: currentYear,
|
year: currentYear,
|
||||||
lineName: "",
|
lineName: "",
|
||||||
lotId: ""
|
lotId: ""
|
||||||
},
|
},
|
||||||
formData: {},
|
formData: {},
|
||||||
|
matterForm: {},
|
||||||
|
batchForm: {},
|
||||||
formRules: {
|
formRules: {
|
||||||
year: [{ required: true, message: "必填", trigger: ["blur", "change"] }],
|
year: [{ required: true, message: "必填", trigger: ["blur", "change"] }],
|
||||||
travelAgencyId: [{ required: true, message: "必填", trigger: ["blur", "change"] }],
|
travelAgencyId: [{ required: true, message: "必填", trigger: ["blur", "change"] }],
|
||||||
@@ -249,6 +451,25 @@ layout("/layouts/platform.html"){
|
|||||||
lineType: [{ required: true, message: "必填", trigger: ["blur", "change"] }],
|
lineType: [{ required: true, message: "必填", trigger: ["blur", "change"] }],
|
||||||
lotId: [{ required: true, message: "必填", trigger: ["blur", "change"] }],
|
lotId: [{ required: true, message: "必填", trigger: ["blur", "change"] }],
|
||||||
mobileThumb: [{ required: true, message: "请上传移动端缩略图", trigger: ["blur", "change"] }]
|
mobileThumb: [{ required: true, message: "请上传移动端缩略图", trigger: ["blur", "change"] }]
|
||||||
|
},
|
||||||
|
matterFormRules: {
|
||||||
|
year: [{ required: true, message: "必填", trigger: ["blur", "change"] }],
|
||||||
|
matterName: [{ required: true, message: "必填", trigger: ["blur", "change"] }],
|
||||||
|
settingId: [{ required: true, message: "必填", trigger: ["blur", "change"] }],
|
||||||
|
unionId: [{ validator: validateMatterUnion, trigger: ["blur", "change"] }],
|
||||||
|
organizationType: [{ required: true, message: "必填", trigger: ["blur", "change"] }]
|
||||||
|
},
|
||||||
|
batchRules: {
|
||||||
|
lineId: [{ required: true, message: "必填", trigger: ["blur", "change"] }],
|
||||||
|
signupStartTime: [{ validator: validateMatterTime, trigger: ["blur", "change"] }],
|
||||||
|
signupEndTime: [{ validator: validateMatterTime, trigger: ["blur", "change"] }],
|
||||||
|
travelStartTime: [{ validator: validateMatterTime, trigger: ["blur", "change"] }],
|
||||||
|
travelEndTime: [{ validator: validateMatterTime, trigger: ["blur", "change"] }],
|
||||||
|
contactName: [{ required: true, message: "必填", trigger: ["blur", "change"] }],
|
||||||
|
contactPhone: [{ validator: validateMatterMobile, trigger: ["blur", "change"] }],
|
||||||
|
minGroupPeople: [{ validator: validateMatterPeople, trigger: ["blur", "change"] }],
|
||||||
|
maxGroupPeople: [{ validator: validateMatterPeople, trigger: ["blur", "change"] }],
|
||||||
|
estimatedCost: [{ validator: validateMatterMoney, trigger: ["blur", "change"] }]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -307,6 +528,291 @@ layout("/layouts/platform.html"){
|
|||||||
this.viewMode = true
|
this.viewMode = true
|
||||||
this.loadDetail(row.id)
|
this.loadDetail(row.id)
|
||||||
},
|
},
|
||||||
|
createMatter(row) {
|
||||||
|
if (!row || !row.id) {
|
||||||
|
this.$message.warning("Line info is incomplete")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.selectedMatterLine = row
|
||||||
|
this.matterForm = this.emptyMatterForm()
|
||||||
|
this.batchForm = {}
|
||||||
|
this.matterLineOptions = []
|
||||||
|
this.loadMatterUnions()
|
||||||
|
this.loadMatterOrganizationTypes()
|
||||||
|
this.$axios.post(this.matterBasePath() + "/lineInfo", { lineId: row.id }).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.selectedMatterLine = Object.assign({}, row, res.data || {})
|
||||||
|
if (this.selectedMatterLine.year) {
|
||||||
|
this.matterForm.year = String(this.selectedMatterLine.year)
|
||||||
|
}
|
||||||
|
this.loadMatterSettings(this.matterForm.year, true)
|
||||||
|
} else {
|
||||||
|
this.$message.warning(res.msg || "线路信息查询失败")
|
||||||
|
this.loadMatterSettings(this.matterForm.year, true)
|
||||||
|
}
|
||||||
|
this.matterDialogVisible = true
|
||||||
|
this.$nextTick(() => this.$refs.matterFormRef && this.$refs.matterFormRef.clearValidate())
|
||||||
|
})
|
||||||
|
},
|
||||||
|
matterBasePath() {
|
||||||
|
return "/platform/tour/matter"
|
||||||
|
},
|
||||||
|
emptyMatterForm() {
|
||||||
|
const user = (this.$store && this.$store.state && this.$store.state.user) || {}
|
||||||
|
return {
|
||||||
|
year: moment().format("YYYY"),
|
||||||
|
matterName: "",
|
||||||
|
settingId: "",
|
||||||
|
creatorUserId: user.id || "",
|
||||||
|
creatorName: user.username || "",
|
||||||
|
unionId: "",
|
||||||
|
organizationType: "",
|
||||||
|
enabled: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
matterNameTip() {
|
||||||
|
const lineName = this.selectedMatterLine && this.selectedMatterLine.lineName ? this.selectedMatterLine.lineName : "线路名称"
|
||||||
|
return lineName + "第一批次"
|
||||||
|
},
|
||||||
|
emptyMatterBatchForm(matterId) {
|
||||||
|
return {
|
||||||
|
id: matterId || "",
|
||||||
|
lineId: this.selectedMatterLine.id || "",
|
||||||
|
signupStartTime: "",
|
||||||
|
signupEndTime: "",
|
||||||
|
travelStartTime: "",
|
||||||
|
travelEndTime: "",
|
||||||
|
contactName: "",
|
||||||
|
contactPhone: "",
|
||||||
|
minGroupPeople: null,
|
||||||
|
maxGroupPeople: null,
|
||||||
|
estimatedCost: ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
matterYearChange(year) {
|
||||||
|
this.matterForm.settingId = ""
|
||||||
|
this.loadMatterSettings(year, true)
|
||||||
|
},
|
||||||
|
matterOrganizationTypeChange() {
|
||||||
|
this.applyMatterOrganizationTypeRule()
|
||||||
|
this.$nextTick(() => this.$refs.matterFormRef && this.$refs.matterFormRef.validateField("unionId"))
|
||||||
|
},
|
||||||
|
applyMatterOrganizationTypeRule() {
|
||||||
|
if (this.matterForm.organizationType === "schoolUnion") {
|
||||||
|
this.matterForm.unionId = ""
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.matterForm.organizationType === "branchUnion" || this.matterForm.organizationType === "personal") {
|
||||||
|
const union = this.currentUserUnion()
|
||||||
|
this.matterForm.unionId = union.id || ""
|
||||||
|
this.ensureMatterUnionOption(union)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
currentUserUnion() {
|
||||||
|
const user = (this.$store && this.$store.state && this.$store.state.user) || {}
|
||||||
|
return user.union || {}
|
||||||
|
},
|
||||||
|
ensureMatterUnionOption(union) {
|
||||||
|
if (!union || !union.id) return
|
||||||
|
const exists = this.matterUnionOptions.some(item => item.id === union.id)
|
||||||
|
if (!exists) {
|
||||||
|
this.matterUnionOptions.push({ id: union.id, name: union.name || "" })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isMatterUnionDisabled() {
|
||||||
|
return ["schoolUnion", "branchUnion", "personal"].includes(this.matterForm.organizationType)
|
||||||
|
},
|
||||||
|
loadMatterSettings(year, autoSelectLatest) {
|
||||||
|
this.$axios.post(this.matterBasePath() + "/settingOptions", { year }).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.matterSettingOptions = res.data || []
|
||||||
|
if (autoSelectLatest && !this.matterForm.settingId && this.matterSettingOptions.length > 0) {
|
||||||
|
this.matterForm.settingId = this.matterSettingOptions[0].id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
loadMatterUnions() {
|
||||||
|
this.$axios.post(this.matterBasePath() + "/unionOptions").then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.matterUnionOptions = res.data || []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
loadMatterOrganizationTypes() {
|
||||||
|
this.$axios.post(this.matterBasePath() + "/organizationTypeOptions").then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.matterOrganizationTypeOptions = res.data || []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
submitMatterStep() {
|
||||||
|
this.$refs.matterFormRef.validate((valid) => {
|
||||||
|
if (!valid) return
|
||||||
|
this.matterSubDis = true
|
||||||
|
this.$axios.post(this.matterBasePath() + "/doSubmit", this.matterForm).then((res) => {
|
||||||
|
this.matterSubDis = false
|
||||||
|
if (res.code === 0) {
|
||||||
|
const data = res.data || {}
|
||||||
|
const matterId = data.id || this.matterForm.id || ""
|
||||||
|
this.matterForm.id = matterId
|
||||||
|
this.matterDialogVisible = false
|
||||||
|
this.openMatterLineConfig(matterId)
|
||||||
|
} else {
|
||||||
|
this.$message.warning(res.msg || "保存失败")
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
this.matterSubDis = false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
openMatterLineConfig(matterId) {
|
||||||
|
this.batchForm = this.emptyMatterBatchForm(matterId)
|
||||||
|
this.matterLineOptions = [this.selectedMatterLine]
|
||||||
|
this.$axios.post(this.matterBasePath() + "/lineConfig", { matterId }).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.batchForm = Object.assign(this.emptyMatterBatchForm(matterId), res.data || {})
|
||||||
|
this.batchForm.id = matterId
|
||||||
|
this.batchForm.lineId = this.selectedMatterLine.id || this.batchForm.lineId
|
||||||
|
this.batchForm.travelStartTime = this.dateOnly(this.batchForm.travelStartTime)
|
||||||
|
this.batchForm.travelEndTime = this.dateOnly(this.batchForm.travelEndTime)
|
||||||
|
this.applyMatterSelectedLineDefaults(false)
|
||||||
|
this.loadMatterSettingDefaults((data) => {
|
||||||
|
this.applyMatterSettingPeople(data)
|
||||||
|
this.applyMatterSettingSignupTime(data)
|
||||||
|
})
|
||||||
|
this.lineConfigDialogVisible = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.applyMatterSelectedLineDefaults(true)
|
||||||
|
this.$refs.batchFormRef && this.$refs.batchFormRef.clearValidate()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.$message.warning(res.msg || "事项信息查询失败")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
backToMatterStep() {
|
||||||
|
this.lineConfigDialogVisible = false
|
||||||
|
this.matterDialogVisible = true
|
||||||
|
this.$nextTick(() => this.$refs.matterFormRef && this.$refs.matterFormRef.clearValidate())
|
||||||
|
},
|
||||||
|
matterLineOptionLabel(item) {
|
||||||
|
if (!item) return ""
|
||||||
|
const lineName = this.matterLineField(item, "lineName") || ""
|
||||||
|
const lineType = this.matterLineField(item, "lineType") || ""
|
||||||
|
return lineType ? lineName + " (" + lineType + ")" : lineName
|
||||||
|
},
|
||||||
|
matterSelectedLine() {
|
||||||
|
return (this.matterLineOptions || []).find((item) => this.matterLineField(item, "id") === this.batchForm.lineId) || null
|
||||||
|
},
|
||||||
|
applyMatterSelectedLineDefaults(recalculateEnd) {
|
||||||
|
const line = this.matterSelectedLine()
|
||||||
|
if (!line) return
|
||||||
|
const activityCost = this.matterLineField(line, "activityCost")
|
||||||
|
if (activityCost !== null && activityCost !== undefined && activityCost !== "") {
|
||||||
|
this.batchForm.estimatedCost = activityCost
|
||||||
|
}
|
||||||
|
if (recalculateEnd) {
|
||||||
|
this.fillMatterTravelEndByLot()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
matterTravelStartChange() {
|
||||||
|
this.fillMatterTravelEndByLot()
|
||||||
|
},
|
||||||
|
fillMatterTravelEndByLot() {
|
||||||
|
const line = this.matterSelectedLine()
|
||||||
|
const days = this.matterLineLotDays(line)
|
||||||
|
if (!this.batchForm.travelStartTime || !days) return
|
||||||
|
this.$set(this.batchForm, "travelEndTime", moment(this.batchForm.travelStartTime).add(days - 1, "days").format("YYYY-MM-DD"))
|
||||||
|
this.validateMatterTravelFields()
|
||||||
|
},
|
||||||
|
matterLineLotDays(line) {
|
||||||
|
if (!line) return null
|
||||||
|
const lotDays = this.matterLineField(line, "lotDays") || this.matterLineField(line, "lotValue")
|
||||||
|
if (!/^\d+$/.test(String(lotDays || ""))) return null
|
||||||
|
const days = parseInt(lotDays, 10)
|
||||||
|
return days > 0 ? days : null
|
||||||
|
},
|
||||||
|
matterLineField(line, field) {
|
||||||
|
if (!line) return null
|
||||||
|
if (line[field] !== undefined) return line[field]
|
||||||
|
const lowerField = field.toLowerCase()
|
||||||
|
const matchedKey = Object.keys(line).find((key) => key.toLowerCase() === lowerField)
|
||||||
|
return matchedKey ? line[matchedKey] : null
|
||||||
|
},
|
||||||
|
validateMatterTravelFields() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.batchFormRef) {
|
||||||
|
this.$refs.batchFormRef.validateField(["travelStartTime", "travelEndTime"])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
dateOnly(value) {
|
||||||
|
if (!value) return ""
|
||||||
|
return String(value).substring(0, 10)
|
||||||
|
},
|
||||||
|
applyMatterSettingSignupTime(data) {
|
||||||
|
if (!data) return
|
||||||
|
if (data.signupStartTime) {
|
||||||
|
this.$set(this.batchForm, "signupStartTime", data.signupStartTime)
|
||||||
|
}
|
||||||
|
if (data.signupEndTime) {
|
||||||
|
this.$set(this.batchForm, "signupEndTime", data.signupEndTime)
|
||||||
|
}
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.batchFormRef) {
|
||||||
|
this.$refs.batchFormRef.validateField(["signupStartTime", "signupEndTime"])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
applyMatterSettingPeople(data) {
|
||||||
|
if (!data) return
|
||||||
|
if (data.minGroupPeople !== null && data.minGroupPeople !== undefined && data.minGroupPeople !== "") {
|
||||||
|
this.$set(this.batchForm, "minGroupPeople", data.minGroupPeople)
|
||||||
|
}
|
||||||
|
if (data.maxGroupPeople !== null && data.maxGroupPeople !== undefined && data.maxGroupPeople !== "") {
|
||||||
|
this.$set(this.batchForm, "maxGroupPeople", data.maxGroupPeople)
|
||||||
|
}
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.batchFormRef) {
|
||||||
|
this.$refs.batchFormRef.validateField(["minGroupPeople", "maxGroupPeople"])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
loadMatterSettingDefaults(callback) {
|
||||||
|
this.$axios.post(this.matterBasePath() + "/settingPeople", {
|
||||||
|
matterId: this.matterForm.id,
|
||||||
|
year: this.matterForm.year
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
callback && callback(res.data || {})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
matterPeopleChange() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.batchFormRef) {
|
||||||
|
this.$refs.batchFormRef.validateField(["minGroupPeople", "maxGroupPeople"])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
submitMatterLineConfig() {
|
||||||
|
this.$refs.batchFormRef.validate((valid) => {
|
||||||
|
if (!valid) return
|
||||||
|
this.batchSubDis = true
|
||||||
|
this.$axios.post(this.matterBasePath() + "/lineConfigDoSubmit", this.batchForm).then((res) => {
|
||||||
|
this.batchSubDis = false
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.$message.success("保存成功")
|
||||||
|
this.lineConfigDialogVisible = false
|
||||||
|
} else {
|
||||||
|
this.$message.warning(res.msg || "保存失败")
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
this.batchSubDis = false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
loadDetail(id) {
|
loadDetail(id) {
|
||||||
this.$axios.post(loc() + "/detail", { id }).then((res) => {
|
this.$axios.post(loc() + "/detail", { id }).then((res) => {
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
|
|||||||
+2
-2
@@ -190,8 +190,8 @@ layout("/layouts/platform.html"){
|
|||||||
<el-descriptions-item label="报名线路">{{ detail.lineName || '' }}</el-descriptions-item>
|
<el-descriptions-item label="报名线路">{{ detail.lineName || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="出行时段">{{ detail.travelPeriod || '' }}</el-descriptions-item>
|
<el-descriptions-item label="出行时段">{{ detail.travelPeriod || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="线路类型">{{ detail.lineType || '' }}</el-descriptions-item>
|
<el-descriptions-item label="线路类型">{{ detail.lineType || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="报名酒店">{{ detail.hotelName || '' }}</el-descriptions-item>
|
<el-descriptions-item v-if="false" label="报名酒店">{{ detail.hotelName || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="旅行社">{{ detail.travelAgencyName || '' }}</el-descriptions-item>
|
<el-descriptions-item v-if="false" label="旅行社">{{ detail.travelAgencyName || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="是否携带家属">
|
<el-descriptions-item label="是否携带家属">
|
||||||
{{ familyText() }}
|
{{ familyText() }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ layout("/layouts/platform.html"){
|
|||||||
<el-input v-model="formData.configName" maxlength="100" placeholder="请输入配置名称"></el-input>
|
<el-input v-model="formData.configName" maxlength="100" placeholder="请输入配置名称"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col v-if="false" :span="12">
|
||||||
<el-form-item label="疗休养类型" prop="tourType">
|
<el-form-item label="疗休养类型" prop="tourType">
|
||||||
<el-select v-model="formData.tourType" clearable allow-create filterable placeholder="请选择或输入类型" style="width: 100%">
|
<el-select v-model="formData.tourType" clearable allow-create filterable placeholder="请选择或输入类型" style="width: 100%">
|
||||||
<el-option label="省内疗休养" value="省内疗休养"></el-option>
|
<el-option label="省内疗休养" value="省内疗休养"></el-option>
|
||||||
@@ -145,6 +145,28 @@ layout("/layouts/platform.html"){
|
|||||||
<el-input-number v-model="formData.maxGroupPeople" :controls="false" :min="0" :precision="0" placeholder="请输入最多成团人数" style="width: 100%"></el-input-number>
|
<el-input-number v-model="formData.maxGroupPeople" :controls="false" :min="0" :precision="0" placeholder="请输入最多成团人数" style="width: 100%"></el-input-number>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="开始报名时间" prop="signupStartTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="formData.signupStartTime"
|
||||||
|
type="datetime"
|
||||||
|
value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
|
placeholder="请选择开始报名时间"
|
||||||
|
style="width: 100%">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="结束报名时间" prop="signupEndTime">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="formData.signupEndTime"
|
||||||
|
type="datetime"
|
||||||
|
value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
|
placeholder="请选择结束报名时间"
|
||||||
|
style="width: 100%">
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<div class="tour-setting-basic-divider"></div>
|
<div class="tour-setting-basic-divider"></div>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -155,7 +177,7 @@ layout("/layouts/platform.html"){
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="省外人数占比" prop="outProvinceRatio">
|
<el-form-item label="省外人数占比" prop="outProvinceRatio">
|
||||||
<el-input-number v-model="formData.outProvinceRatio" :controls="false" :min="0" :max="100" :precision="2" placeholder="请输入省外人数占比" style="width: 100%"></el-input-number>
|
<el-input-number v-model="formData.outProvinceRatio" :controls="false" :min="0" :max="100" :precision="2" disabled placeholder="请输入省外人数占比" style="width: 100%"></el-input-number>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
@@ -300,6 +322,18 @@ layout("/layouts/platform.html"){
|
|||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const checkSignupTime = (rule, value, callback) => {
|
||||||
|
if (!value) {
|
||||||
|
callback(new Error("必填"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.formData.signupStartTime && this.formData.signupEndTime
|
||||||
|
&& this.formData.signupStartTime >= this.formData.signupEndTime) {
|
||||||
|
callback(new Error("开始报名时间必须小于结束报名时间"))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
const checkCycleYear = (rule, value, callback) => {
|
const checkCycleYear = (rule, value, callback) => {
|
||||||
const startYear = parseInt(this.formData.cycleStartYear, 10)
|
const startYear = parseInt(this.formData.cycleStartYear, 10)
|
||||||
const endYear = parseInt(this.formData.cycleEndYear, 10)
|
const endYear = parseInt(this.formData.cycleEndYear, 10)
|
||||||
@@ -337,6 +371,8 @@ layout("/layouts/platform.html"){
|
|||||||
configName: [{required: true, message: "必填", trigger: ["blur", "change"]}],
|
configName: [{required: true, message: "必填", trigger: ["blur", "change"]}],
|
||||||
minGroupPeople: [{validator: checkGroupPeople, trigger: ["blur", "change"]}],
|
minGroupPeople: [{validator: checkGroupPeople, trigger: ["blur", "change"]}],
|
||||||
maxGroupPeople: [{validator: checkGroupPeople, trigger: ["blur", "change"]}],
|
maxGroupPeople: [{validator: checkGroupPeople, trigger: ["blur", "change"]}],
|
||||||
|
signupStartTime: [{validator: checkSignupTime, trigger: ["blur", "change"]}],
|
||||||
|
signupEndTime: [{validator: checkSignupTime, trigger: ["blur", "change"]}],
|
||||||
outProvinceRatioType: [{required: true, message: "必填", trigger: ["blur", "change"]}],
|
outProvinceRatioType: [{required: true, message: "必填", trigger: ["blur", "change"]}],
|
||||||
outProvinceFixedPeople: [{validator: checkOutProvinceFixedPeople, trigger: ["blur", "change"]}],
|
outProvinceFixedPeople: [{validator: checkOutProvinceFixedPeople, trigger: ["blur", "change"]}],
|
||||||
cycleStartYear: [{validator: checkCycleYear, trigger: ["blur", "change"]}],
|
cycleStartYear: [{validator: checkCycleYear, trigger: ["blur", "change"]}],
|
||||||
@@ -382,6 +418,8 @@ layout("/layouts/platform.html"){
|
|||||||
sortNo: 0,
|
sortNo: 0,
|
||||||
minGroupPeople: 0,
|
minGroupPeople: 0,
|
||||||
maxGroupPeople: 0,
|
maxGroupPeople: 0,
|
||||||
|
signupStartTime: "",
|
||||||
|
signupEndTime: "",
|
||||||
outProvinceYears: 0,
|
outProvinceYears: 0,
|
||||||
outProvinceRatio: 0,
|
outProvinceRatio: 0,
|
||||||
outProvinceRatioType: "当年报名人数",
|
outProvinceRatioType: "当年报名人数",
|
||||||
@@ -466,6 +504,8 @@ layout("/layouts/platform.html"){
|
|||||||
activityGroupId: "",
|
activityGroupId: "",
|
||||||
outProvinceRatioType: "当年报名人数",
|
outProvinceRatioType: "当年报名人数",
|
||||||
outProvinceFixedPeople: 0,
|
outProvinceFixedPeople: 0,
|
||||||
|
signupStartTime: "",
|
||||||
|
signupEndTime: "",
|
||||||
cycleStartYear: "",
|
cycleStartYear: "",
|
||||||
cycleEndYear: "",
|
cycleEndYear: "",
|
||||||
cycleTotalCost: null,
|
cycleTotalCost: null,
|
||||||
|
|||||||
@@ -54,11 +54,13 @@ layout("/layouts/platform.html"){
|
|||||||
@sort-change="pageOrder">
|
@sort-change="pageOrder">
|
||||||
<el-table-column label="序号" type="index" :index="indexMethod" width="80" align="center" header-align="center"></el-table-column>
|
<el-table-column label="序号" type="index" :index="indexMethod" width="80" align="center" header-align="center"></el-table-column>
|
||||||
<el-table-column label="线路名称" prop="lineName" min-width="220" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="线路名称" prop="lineName" min-width="220" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="出行时段" prop="travelPeriod" width="330" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="出行时段" prop="travelPeriod" width="240" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<!-- 临时屏蔽事项名称列,保留代码便于后续恢复
|
<!-- 临时屏蔽事项名称列,保留代码便于后续恢复
|
||||||
<el-table-column label="事项名称" prop="matterName" min-width="200" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="事项名称" prop="matterName" min-width="200" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
-->
|
-->
|
||||||
|
<!-- 临时屏蔽所属工会列,保留代码便于后续恢复
|
||||||
<el-table-column label="所属工会" prop="unionName" min-width="180" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="所属工会" prop="unionName" min-width="180" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
-->
|
||||||
<el-table-column label="线路类型" prop="lineType" width="140" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="线路类型" prop="lineType" width="140" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="最少成团人数" prop="minGroupPeople" width="140" sortable="custom" align="center" header-align="center">
|
<el-table-column label="最少成团人数" prop="minGroupPeople" width="140" sortable="custom" align="center" header-align="center">
|
||||||
<template slot-scope="{row}">
|
<template slot-scope="{row}">
|
||||||
@@ -75,10 +77,11 @@ layout("/layouts/platform.html"){
|
|||||||
<el-tag size="mini" :type="Number(row.signupCount || 0) > 0 ? 'success' : 'info'">{{ row.signupCount || 0 }}人</el-tag>
|
<el-tag size="mini" :type="Number(row.signupCount || 0) > 0 ? 'success' : 'info'">{{ row.signupCount || 0 }}人</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="260" align="center" header-align="center">
|
<el-table-column label="操作" width="300" align="center" header-align="center">
|
||||||
<template slot-scope="{row}">
|
<template slot-scope="{row}">
|
||||||
<el-button size="mini" type="primary" @click="openLineView(row)">查看线路</el-button>
|
|
||||||
<el-button size="mini" :type="signupActionType(row)" :disabled="signupActionDisabled(row)" @click="handleSignupAction(row)">{{ signupActionText(row) }}</el-button>
|
<el-button size="mini" :type="signupActionType(row)" :disabled="signupActionDisabled(row)" @click="handleSignupAction(row)">{{ signupActionText(row) }}</el-button>
|
||||||
|
<el-button size="mini" type="primary" @click="openLineView(row)">查看线路</el-button>
|
||||||
|
<el-button size="mini" type="primary" @click="openPeopleView(row)">查看人员</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -148,16 +151,22 @@ layout("/layouts/platform.html"){
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
|
<!-- 临时屏蔽报名酒店字段,保留代码便于后续恢复
|
||||||
|
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="报名酒店">
|
<el-form-item label="报名酒店">
|
||||||
<el-input v-model="signupForm.hotelName" :disabled="isDirectFamilyLine(signupForm)" maxlength="100" placeholder="请输入报名酒店"></el-input>
|
<el-input v-model="signupForm.hotelName" :disabled="isDirectFamilyLine(signupForm)" maxlength="100" placeholder="请输入报名酒店"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
-->
|
||||||
|
<!-- 临时屏蔽报名旅行社字段,保留代码便于后续恢复
|
||||||
|
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="报名旅行社">
|
<el-form-item label="报名旅行社">
|
||||||
<el-input v-model="signupForm.travelAgencyName" :disabled="isDirectFamilyLine(signupForm)" readonly></el-input>
|
<el-input v-model="signupForm.travelAgencyName" :disabled="isDirectFamilyLine(signupForm)" readonly></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
-->
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="出行时间">
|
<el-form-item label="出行时间">
|
||||||
<el-input v-model="signupForm.travelPeriod" :disabled="isDirectFamilyLine(signupForm)" readonly></el-input>
|
<el-input v-model="signupForm.travelPeriod" :disabled="isDirectFamilyLine(signupForm)" readonly></el-input>
|
||||||
@@ -369,11 +378,72 @@ layout("/layouts/platform.html"){
|
|||||||
|
|
||||||
<div class="tour-signup-section">
|
<div class="tour-signup-section">
|
||||||
<div class="tour-signup-title">线路内容</div>
|
<div class="tour-signup-title">线路内容</div>
|
||||||
<div ref="lineContent" class="tour-line-content" v-html="lineContentHtml" @click="handleLineContentClick"></div>
|
<div ref="lineContent" class="tour-line-content" v-html="lineContentHtml"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
|
|
||||||
|
<el-drawer
|
||||||
|
:title="peopleViewTitle"
|
||||||
|
:visible.sync="peopleViewVisible"
|
||||||
|
direction="rtl"
|
||||||
|
size="72%"
|
||||||
|
custom-class="tour-group-view-drawer"
|
||||||
|
:close-on-click-modal="false">
|
||||||
|
<div class="tour-group-view">
|
||||||
|
<el-card shadow="never">
|
||||||
|
<search :is-search-button="false">
|
||||||
|
<search-item label="姓名/工号">
|
||||||
|
<el-input
|
||||||
|
v-model="peopleViewForm.keyword"
|
||||||
|
clearable
|
||||||
|
placeholder="请输入姓名或工号"
|
||||||
|
style="width: 100%"
|
||||||
|
@keyup.enter.native="peopleViewSearch">
|
||||||
|
</el-input>
|
||||||
|
</search-item>
|
||||||
|
<search-item label="所属工会">
|
||||||
|
<el-select v-model="peopleViewForm.unionId" clearable filterable placeholder="请选择所属工会" style="width: 100%">
|
||||||
|
<el-option v-for="item in unionOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</search-item>
|
||||||
|
<div class="search-query" style="margin-left: auto;">
|
||||||
|
<el-button size="medium" type="primary" icon="el-icon-search" @click="peopleViewSearch">搜索</el-button>
|
||||||
|
<el-button size="medium" @click="peopleViewReset">重置</el-button>
|
||||||
|
</div>
|
||||||
|
</search>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<el-card class="mt10" shadow="never">
|
||||||
|
<div class="tour-group-view-title">报名人员列表</div>
|
||||||
|
<el-table
|
||||||
|
v-loading="peopleViewLoading"
|
||||||
|
:data="peopleViewTableData"
|
||||||
|
:size="tableSize"
|
||||||
|
border
|
||||||
|
@sort-change="peopleViewPageOrder">
|
||||||
|
<el-table-column label="序号" type="index" :index="peopleViewIndexMethod" width="80" align="center" header-align="center"></el-table-column>
|
||||||
|
<el-table-column label="工号" prop="jobNo" width="130" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="姓名" prop="userName" width="120" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="所属工会" prop="unionName" min-width="180" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="报名时间" prop="signupTime" width="170" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-row class="el-pagination-container tour-group-view-pagination">
|
||||||
|
<el-pagination
|
||||||
|
background
|
||||||
|
:current-page="peopleViewForm.pageNumber"
|
||||||
|
:page-size="peopleViewForm.pageSize"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
:total="peopleViewForm.totalCount"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
@size-change="peopleViewSizeChange"
|
||||||
|
@current-change="peopleViewCurrentChange">
|
||||||
|
</el-pagination>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</el-drawer>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@@ -416,21 +486,76 @@ layout("/layouts/platform.html"){
|
|||||||
.tour-line-content .tour-file-preview {
|
.tour-line-content .tour-file-preview {
|
||||||
border: 1px solid #dcdfe6;
|
border: 1px solid #dcdfe6;
|
||||||
display: block;
|
display: block;
|
||||||
min-height: 520px;
|
height: 620px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.tour-line-content .tour-pdf-preview {
|
.tour-line-content .tour-file-preview-box {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
.tour-line-content .tour-file-link {
|
.tour-line-content .tour-pdf-lazy-preview {
|
||||||
color: #0079c2;
|
border: 1px solid #dcdfe6;
|
||||||
text-decoration: underline;
|
background: #f5f7fa;
|
||||||
|
min-height: 180px;
|
||||||
|
margin-top: 10px;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.tour-line-content .tour-file-loading {
|
.tour-line-content .tour-pdf-lazy-toolbar {
|
||||||
|
background: #fff;
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
|
color: #606266;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 36px;
|
||||||
|
padding: 0 12px;
|
||||||
|
}
|
||||||
|
.tour-line-content .tour-pdf-page-placeholder {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
background: #f5f7fa;
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
color: #909399;
|
color: #909399;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
min-height: 220px;
|
||||||
|
}
|
||||||
|
.tour-line-content .tour-pdf-page-placeholder canvas {
|
||||||
|
background: #fff;
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
.tour-line-content .tour-image-preview {
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
display: block;
|
||||||
|
margin-top: 10px;
|
||||||
|
max-height: 680px;
|
||||||
|
object-fit: contain;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.tour-line-content .tour-file-unpreviewable {
|
||||||
|
align-items: center;
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
color: #909399;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 160px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.tour-group-view-drawer .el-drawer__body {
|
||||||
|
background: #f5f7fa;
|
||||||
|
padding: 12px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
.tour-group-view-pagination {
|
||||||
|
margin-top: 12px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.tour-group-view-title {
|
||||||
|
border-left: 4px solid #0079c2;
|
||||||
|
color: #0079c2;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 16px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding-left: 10px;
|
||||||
}
|
}
|
||||||
.el-table .direct-family-row > td,
|
.el-table .direct-family-row > td,
|
||||||
.el-table .direct-family-row > td .cell {
|
.el-table .direct-family-row > td .cell {
|
||||||
@@ -461,6 +586,9 @@ layout("/layouts/platform.html"){
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<script src="${base!}/assets/platform/plugins/pdfJs/h5/pdf.js" type="text/javascript" charset="utf-8"></script>
|
||||||
|
<script src="${base!}/assets/platform/plugins/pdfJs/h5/pdf.worker.js" type="text/javascript" charset="utf-8"></script>
|
||||||
|
|
||||||
<script nonce="${cspNonce!}">
|
<script nonce="${cspNonce!}">
|
||||||
new Vue({
|
new Vue({
|
||||||
el: "#app",
|
el: "#app",
|
||||||
@@ -484,6 +612,14 @@ layout("/layouts/platform.html"){
|
|||||||
lineVisible: false,
|
lineVisible: false,
|
||||||
lineDetail: {},
|
lineDetail: {},
|
||||||
lineContentHtml: "",
|
lineContentHtml: "",
|
||||||
|
linePdfPreviews: [],
|
||||||
|
linePdfObserver: null,
|
||||||
|
peopleViewVisible: false,
|
||||||
|
peopleViewLoading: false,
|
||||||
|
peopleViewRequestSeq: 0,
|
||||||
|
peopleViewTitle: "",
|
||||||
|
peopleViewRow: {},
|
||||||
|
peopleViewTableData: [],
|
||||||
pageForm: {
|
pageForm: {
|
||||||
pageNumber: 1,
|
pageNumber: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
@@ -494,6 +630,15 @@ layout("/layouts/platform.html"){
|
|||||||
lineName: "",
|
lineName: "",
|
||||||
lineType: "",
|
lineType: "",
|
||||||
unionId: ""
|
unionId: ""
|
||||||
|
},
|
||||||
|
peopleViewForm: {
|
||||||
|
pageNumber: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
totalCount: 0,
|
||||||
|
pageOrderName: "signupTime",
|
||||||
|
pageOrderBy: "descending",
|
||||||
|
keyword: "",
|
||||||
|
unionId: ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -535,6 +680,10 @@ layout("/layouts/platform.html"){
|
|||||||
this.revokeSignup(row)
|
this.revokeSignup(row)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (row && row.signed) {
|
||||||
|
this.loadSignupDetail(row)
|
||||||
|
return
|
||||||
|
}
|
||||||
this.openSignup(row)
|
this.openSignup(row)
|
||||||
},
|
},
|
||||||
isApprovalSignup(row) {
|
isApprovalSignup(row) {
|
||||||
@@ -570,6 +719,79 @@ layout("/layouts/platform.html"){
|
|||||||
|| row.directFamilyUnitLine === 1
|
|| row.directFamilyUnitLine === 1
|
||||||
|| row.directFamilyUnitLine === "1"
|
|| row.directFamilyUnitLine === "1"
|
||||||
},
|
},
|
||||||
|
openPeopleView(row) {
|
||||||
|
this.peopleViewRow = row || {}
|
||||||
|
this.peopleViewTitle = (this.peopleViewRow.lineName || "报名人员") + " - 报名人员"
|
||||||
|
this.peopleViewVisible = true
|
||||||
|
this.peopleViewForm.pageNumber = 1
|
||||||
|
this.peopleViewForm.pageSize = 10
|
||||||
|
this.peopleViewForm.totalCount = 0
|
||||||
|
this.peopleViewForm.pageOrderName = "signupTime"
|
||||||
|
this.peopleViewForm.pageOrderBy = "descending"
|
||||||
|
this.peopleViewForm.keyword = ""
|
||||||
|
this.peopleViewForm.unionId = ""
|
||||||
|
this.peopleViewTableData = []
|
||||||
|
this.loadPeopleViewData()
|
||||||
|
},
|
||||||
|
peopleViewSearch() {
|
||||||
|
this.peopleViewForm.pageNumber = 1
|
||||||
|
this.loadPeopleViewData()
|
||||||
|
},
|
||||||
|
peopleViewReset() {
|
||||||
|
this.peopleViewForm.keyword = ""
|
||||||
|
this.peopleViewForm.unionId = ""
|
||||||
|
this.peopleViewForm.pageNumber = 1
|
||||||
|
this.loadPeopleViewData()
|
||||||
|
},
|
||||||
|
peopleViewIndexMethod(index) {
|
||||||
|
return (this.peopleViewForm.pageNumber - 1) * this.peopleViewForm.pageSize + index + 1
|
||||||
|
},
|
||||||
|
peopleViewSizeChange(size) {
|
||||||
|
this.peopleViewForm.pageSize = size
|
||||||
|
this.peopleViewForm.pageNumber = 1
|
||||||
|
this.loadPeopleViewData()
|
||||||
|
},
|
||||||
|
peopleViewCurrentChange(page) {
|
||||||
|
this.peopleViewForm.pageNumber = page
|
||||||
|
this.loadPeopleViewData()
|
||||||
|
},
|
||||||
|
peopleViewPageOrder({ prop, order }) {
|
||||||
|
this.peopleViewForm.pageOrderName = prop || "signupTime"
|
||||||
|
this.peopleViewForm.pageOrderBy = order || "descending"
|
||||||
|
this.peopleViewForm.pageNumber = 1
|
||||||
|
this.loadPeopleViewData()
|
||||||
|
},
|
||||||
|
loadPeopleViewData() {
|
||||||
|
if (!this.peopleViewRow || !this.peopleViewRow.matterId) {
|
||||||
|
this.peopleViewTableData = []
|
||||||
|
this.peopleViewForm.totalCount = 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.peopleViewLoading = true
|
||||||
|
const requestSeq = ++this.peopleViewRequestSeq
|
||||||
|
this.$axios.post(loc() + "/signupPageData", {
|
||||||
|
matterId: this.peopleViewRow.matterId,
|
||||||
|
keyword: this.peopleViewForm.keyword,
|
||||||
|
unionId: this.peopleViewForm.unionId,
|
||||||
|
pageNumber: this.peopleViewForm.pageNumber,
|
||||||
|
pageSize: this.peopleViewForm.pageSize,
|
||||||
|
pageOrderName: this.peopleViewForm.pageOrderName,
|
||||||
|
pageOrderBy: this.peopleViewForm.pageOrderBy
|
||||||
|
}).then((res) => {
|
||||||
|
if (requestSeq !== this.peopleViewRequestSeq) return
|
||||||
|
if (res.code === 0) {
|
||||||
|
const data = res.data || {}
|
||||||
|
this.peopleViewTableData = data.list || []
|
||||||
|
this.peopleViewForm.totalCount = data.totalCount || 0
|
||||||
|
} else {
|
||||||
|
this.$message.warning(res.msg || "查询失败")
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
if (requestSeq === this.peopleViewRequestSeq) {
|
||||||
|
this.peopleViewLoading = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
canApplyOverReimbursement(row) {
|
canApplyOverReimbursement(row) {
|
||||||
if (!row) return false
|
if (!row) return false
|
||||||
return row.allowOverReimbursement === true
|
return row.allowOverReimbursement === true
|
||||||
@@ -580,15 +802,51 @@ layout("/layouts/platform.html"){
|
|||||||
this.$axios.post(loc() + "/lineDetail", { lineId: row.lineId }).then((res) => {
|
this.$axios.post(loc() + "/lineDetail", { lineId: row.lineId }).then((res) => {
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
this.lineDetail = res.data || {}
|
this.lineDetail = res.data || {}
|
||||||
this.lineContentHtml = this.buildLineContentHtml(this.lineDetail.lineContent)
|
this.lineContentHtml = ""
|
||||||
this.lineVisible = true
|
this.lineVisible = true
|
||||||
this.$nextTick(() => this.loadPdfPreviews())
|
this.buildLineContentHtmlAsync(this.lineDetail.lineContent).then((html) => {
|
||||||
|
this.lineContentHtml = html
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.initLinePdfPreviews()
|
||||||
|
})
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
this.$message.warning(res.msg || "查询失败")
|
this.$message.warning(res.msg || "查询失败")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
buildLineContentHtml(content) {
|
buildLineContentHtmlAsync(content) {
|
||||||
|
const ids = this.extractLineFileIds(content)
|
||||||
|
if (!ids.length) {
|
||||||
|
return Promise.resolve(this.buildLineContentHtml(content, {}))
|
||||||
|
}
|
||||||
|
return this.$axios.post("/platform/sys/file/previewFileData", {ids: JSON.stringify(ids)}).then((res) => {
|
||||||
|
const fileMap = {}
|
||||||
|
if (res.code === 0 && Array.isArray(res.data)) {
|
||||||
|
res.data.forEach((file) => {
|
||||||
|
if (file && file.id) {
|
||||||
|
file.suffix = (file.suffix || "").toLowerCase()
|
||||||
|
fileMap[file.id] = file
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return this.buildLineContentHtml(content, fileMap)
|
||||||
|
}).catch(() => this.buildLineContentHtml(content, {}))
|
||||||
|
},
|
||||||
|
extractLineFileIds(content) {
|
||||||
|
if (!content) return []
|
||||||
|
const wrap = document.createElement("div")
|
||||||
|
wrap.innerHTML = content
|
||||||
|
const ids = []
|
||||||
|
Array.prototype.slice.call(wrap.querySelectorAll("a[href]")).forEach((anchor) => {
|
||||||
|
const id = this.getFileIdFromUrl(anchor.getAttribute("href") || "")
|
||||||
|
if (id && !ids.includes(id)) {
|
||||||
|
ids.push(id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return ids
|
||||||
|
},
|
||||||
|
buildLineContentHtml(content, fileMap) {
|
||||||
if (!content) return "暂无线路内容"
|
if (!content) return "暂无线路内容"
|
||||||
const wrap = document.createElement("div")
|
const wrap = document.createElement("div")
|
||||||
wrap.innerHTML = content
|
wrap.innerHTML = content
|
||||||
@@ -596,63 +854,226 @@ layout("/layouts/platform.html"){
|
|||||||
anchors.forEach((anchor) => {
|
anchors.forEach((anchor) => {
|
||||||
const href = anchor.getAttribute("href") || ""
|
const href = anchor.getAttribute("href") || ""
|
||||||
const text = anchor.textContent || href
|
const text = anchor.textContent || href
|
||||||
const cleanHref = href.split("#")[0].split("?")[0]
|
const fileId = this.getFileIdFromUrl(href)
|
||||||
const lowerHref = cleanHref.toLowerCase()
|
const file = fileId && fileMap ? fileMap[fileId] : null
|
||||||
const lowerText = text.toLowerCase()
|
const fileType = this.detectPreviewFileType(href, text, file)
|
||||||
anchor.removeAttribute("download")
|
if (!fileType) {
|
||||||
anchor.setAttribute("target", "_blank")
|
return
|
||||||
anchor.setAttribute("rel", "noopener noreferrer")
|
}
|
||||||
anchor.classList.add("tour-file-link")
|
const preview = this.createLineFilePreview(href, fileType, file)
|
||||||
if (/\.pdf$/.test(lowerHref) || /\.pdf$/.test(lowerText) || lowerText.indexOf(".pdf") > -1) {
|
if (anchor.parentNode && preview) {
|
||||||
const box = document.createElement("div")
|
anchor.parentNode.replaceChild(preview, anchor)
|
||||||
box.className = "tour-pdf-preview"
|
|
||||||
box.setAttribute("data-pdf-url", encodeURIComponent(href))
|
|
||||||
box.innerHTML = '<div class="tour-file-preview tour-file-loading">PDF加载中...</div>'
|
|
||||||
anchor.parentNode.insertBefore(box, anchor.nextSibling)
|
|
||||||
} else if (/\.(jpg|jpeg|png|gif|bmp|webp)$/.test(lowerHref)) {
|
|
||||||
const img = document.createElement("img")
|
|
||||||
img.src = href
|
|
||||||
img.alt = text
|
|
||||||
img.style.display = "block"
|
|
||||||
img.style.marginTop = "10px"
|
|
||||||
anchor.parentNode.insertBefore(img, anchor.nextSibling)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return wrap.innerHTML
|
return wrap.innerHTML
|
||||||
},
|
},
|
||||||
isPdfLink(anchor) {
|
detectPreviewFileType(href, text, file) {
|
||||||
if (!anchor) return false
|
const suffix = file && file.suffix ? file.suffix.toLowerCase() : ""
|
||||||
const href = anchor.getAttribute("href") || ""
|
if (["jpg", "jpeg", "png", "gif", "bmp", "webp"].includes(suffix)) {
|
||||||
const text = anchor.textContent || href
|
return "image"
|
||||||
const lowerHref = href.split("#")[0].split("?")[0].toLowerCase()
|
}
|
||||||
const lowerText = text.toLowerCase()
|
if (suffix === "pdf") {
|
||||||
return /\.pdf$/.test(lowerHref) || /\.pdf$/.test(lowerText) || lowerText.indexOf(".pdf") > -1
|
return "pdf"
|
||||||
|
}
|
||||||
|
if (["doc", "docx", "xls", "xlsx"].includes(suffix)) {
|
||||||
|
return "office"
|
||||||
|
}
|
||||||
|
const lowerHref = (href || "").split("#")[0].split("?")[0].toLowerCase()
|
||||||
|
const lowerText = (text || "").toLowerCase()
|
||||||
|
const value = lowerHref + " " + lowerText
|
||||||
|
if (/\.(jpg|jpeg|png|gif|bmp|webp)(\s|$)/.test(value)) {
|
||||||
|
return "image"
|
||||||
|
}
|
||||||
|
if (/\.pdf(\s|$)/.test(value)) {
|
||||||
|
return "pdf"
|
||||||
|
}
|
||||||
|
if (/\.(doc|docx|xls|xlsx)(\s|$)/.test(value)) {
|
||||||
|
return "office"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
},
|
},
|
||||||
previewPdf(url, callback) {
|
createLineFilePreview(href, fileType, file) {
|
||||||
fetch(url, { credentials: "include" }).then((res) => {
|
if (fileType === "image") {
|
||||||
if (!res.ok) throw new Error("PDF加载失败")
|
const img = document.createElement("img")
|
||||||
return res.blob()
|
img.className = "tour-image-preview"
|
||||||
}).then((blob) => {
|
img.src = file && file.downloadPath ? file.downloadPath : href
|
||||||
const previewUrl = URL.createObjectURL(new Blob([blob], { type: "application/pdf" }))
|
img.alt = ""
|
||||||
callback(previewUrl)
|
return img
|
||||||
}).catch(() => {
|
}
|
||||||
callback(url)
|
const previewUrl = this.buildLinePreviewUrl(href, fileType, file)
|
||||||
})
|
if (!previewUrl) {
|
||||||
|
const tip = document.createElement("div")
|
||||||
|
tip.className = "tour-file-unpreviewable"
|
||||||
|
tip.textContent = "当前文件暂不支持预览"
|
||||||
|
return tip
|
||||||
|
}
|
||||||
|
const box = document.createElement("div")
|
||||||
|
box.className = "tour-file-preview-box"
|
||||||
|
const preview = document.createElement("div")
|
||||||
|
preview.className = "tour-pdf-lazy-preview"
|
||||||
|
preview.setAttribute("data-pdf-url", previewUrl)
|
||||||
|
preview.innerHTML = "<div class=\"tour-pdf-lazy-toolbar\">PDF预览加载中...</div>"
|
||||||
|
box.appendChild(preview)
|
||||||
|
return box
|
||||||
},
|
},
|
||||||
loadPdfPreviews() {
|
buildLinePreviewUrl(href, fileType, file) {
|
||||||
|
if (fileType === "office") {
|
||||||
|
const id = file && file.id ? file.id : this.getFileIdFromUrl(href)
|
||||||
|
return id ? "/platform/sys/file/convertPDF?id=" + id : ""
|
||||||
|
}
|
||||||
|
if (fileType === "pdf") {
|
||||||
|
return file && file.downloadPath ? file.downloadPath : href
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
},
|
||||||
|
getPdfLib() {
|
||||||
|
return window.pdfjsLib || window["pdfjs-dist/build/pdf"]
|
||||||
|
},
|
||||||
|
initLinePdfPreviews() {
|
||||||
|
this.cleanupLinePdfPreviews()
|
||||||
const root = this.$refs.lineContent
|
const root = this.$refs.lineContent
|
||||||
if (!root) return
|
const previews = root ? Array.prototype.slice.call(root.querySelectorAll(".tour-pdf-lazy-preview")) : []
|
||||||
const boxes = Array.prototype.slice.call(root.querySelectorAll(".tour-pdf-preview[data-pdf-url]"))
|
if (!previews.length) {
|
||||||
boxes.forEach((box) => {
|
return
|
||||||
const url = decodeURIComponent(box.getAttribute("data-pdf-url") || "")
|
}
|
||||||
if (!url) return
|
const pdfLib = this.getPdfLib()
|
||||||
this.previewPdf(url, (previewUrl) => {
|
if (!pdfLib || !pdfLib.getDocument) {
|
||||||
box.innerHTML = '<object class="tour-file-preview" data="' + previewUrl + '#toolbar=1&navpanes=0" type="application/pdf">'
|
previews.forEach((el) => {
|
||||||
+ '<embed class="tour-file-preview" src="' + previewUrl + '#toolbar=1&navpanes=0" type="application/pdf" />'
|
el.innerHTML = "<div class=\"tour-file-unpreviewable\">PDF预览组件加载失败</div>"
|
||||||
+ '</object>'
|
|
||||||
})
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (pdfLib.GlobalWorkerOptions) {
|
||||||
|
pdfLib.GlobalWorkerOptions.workerSrc = "/assets/platform/plugins/pdfJs/h5/pdf.worker.js"
|
||||||
|
}
|
||||||
|
if (window.IntersectionObserver) {
|
||||||
|
this.linePdfObserver = new IntersectionObserver((entries) => {
|
||||||
|
entries.forEach((entry) => {
|
||||||
|
if (!entry.isIntersecting) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.renderLazyPdfPage(entry.target)
|
||||||
|
this.linePdfObserver && this.linePdfObserver.unobserve(entry.target)
|
||||||
|
})
|
||||||
|
}, {
|
||||||
|
root: null,
|
||||||
|
rootMargin: "420px 0px",
|
||||||
|
threshold: 0.01
|
||||||
|
})
|
||||||
|
}
|
||||||
|
previews.forEach((el) => {
|
||||||
|
this.initLazyPdfPreview(el, pdfLib)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
initLazyPdfPreview(el, pdfLib) {
|
||||||
|
const url = el.getAttribute("data-pdf-url")
|
||||||
|
if (!url) {
|
||||||
|
el.innerHTML = "<div class=\"tour-file-unpreviewable\">当前文件暂不支持预览</div>"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const task = pdfLib.getDocument({
|
||||||
|
url: url,
|
||||||
|
disableAutoFetch: true,
|
||||||
|
disableStream: true,
|
||||||
|
disableRange: false
|
||||||
|
})
|
||||||
|
const state = {
|
||||||
|
el: el,
|
||||||
|
doc: null,
|
||||||
|
task: task,
|
||||||
|
rendered: {},
|
||||||
|
rendering: {}
|
||||||
|
}
|
||||||
|
this.linePdfPreviews.push(state)
|
||||||
|
task.promise.then((pdf) => {
|
||||||
|
state.doc = pdf
|
||||||
|
const count = pdf.numPages || 0
|
||||||
|
const toolbar = el.querySelector(".tour-pdf-lazy-toolbar")
|
||||||
|
if (toolbar) {
|
||||||
|
toolbar.textContent = "PDF预览:共 " + count + " 页,已优先加载第 1 页"
|
||||||
|
}
|
||||||
|
for (let i = 1; i <= count; i++) {
|
||||||
|
const page = document.createElement("div")
|
||||||
|
page.className = "tour-pdf-page-placeholder"
|
||||||
|
page.setAttribute("data-page-number", i)
|
||||||
|
page.textContent = i === 1 ? "正在加载第 1 页..." : "第 " + i + " 页,滚动到此处加载"
|
||||||
|
el.appendChild(page)
|
||||||
|
}
|
||||||
|
const firstPage = el.querySelector("[data-page-number='1']")
|
||||||
|
if (firstPage) {
|
||||||
|
this.renderLazyPdfPage(firstPage)
|
||||||
|
}
|
||||||
|
Array.prototype.slice.call(el.querySelectorAll(".tour-pdf-page-placeholder")).forEach((page) => {
|
||||||
|
if (page.getAttribute("data-page-number") !== "1" && this.linePdfObserver) {
|
||||||
|
this.linePdfObserver.observe(page)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).catch(() => {
|
||||||
|
el.innerHTML = "<div class=\"tour-file-unpreviewable\">PDF加载失败,请稍后重试</div>"
|
||||||
|
})
|
||||||
|
},
|
||||||
|
renderLazyPdfPage(pageEl) {
|
||||||
|
const previewEl = pageEl.closest(".tour-pdf-lazy-preview")
|
||||||
|
const state = this.linePdfPreviews.find((item) => item.el === previewEl)
|
||||||
|
if (!state || !state.doc) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const pageNumber = Number(pageEl.getAttribute("data-page-number") || 0)
|
||||||
|
if (!pageNumber || state.rendered[pageNumber] || state.rendering[pageNumber]) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
state.rendering[pageNumber] = true
|
||||||
|
pageEl.textContent = "正在加载第 " + pageNumber + " 页..."
|
||||||
|
state.doc.getPage(pageNumber).then((page) => {
|
||||||
|
const containerWidth = Math.max(previewEl.clientWidth - 24, 420)
|
||||||
|
const baseViewport = page.getViewport({scale: 1})
|
||||||
|
const cssScale = containerWidth / baseViewport.width
|
||||||
|
const outputScale = Math.min(window.devicePixelRatio || 1, 2)
|
||||||
|
const viewport = page.getViewport({scale: cssScale})
|
||||||
|
const canvas = document.createElement("canvas")
|
||||||
|
const context = canvas.getContext("2d")
|
||||||
|
canvas.width = Math.floor(viewport.width * outputScale)
|
||||||
|
canvas.height = Math.floor(viewport.height * outputScale)
|
||||||
|
canvas.style.width = Math.floor(viewport.width) + "px"
|
||||||
|
canvas.style.height = Math.floor(viewport.height) + "px"
|
||||||
|
pageEl.innerHTML = ""
|
||||||
|
pageEl.appendChild(canvas)
|
||||||
|
return page.render({
|
||||||
|
canvasContext: context,
|
||||||
|
viewport: viewport,
|
||||||
|
transform: outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null
|
||||||
|
}).promise.then(() => {
|
||||||
|
state.rendered[pageNumber] = true
|
||||||
|
state.rendering[pageNumber] = false
|
||||||
|
})
|
||||||
|
}).catch(() => {
|
||||||
|
state.rendering[pageNumber] = false
|
||||||
|
pageEl.textContent = "第 " + pageNumber + " 页加载失败"
|
||||||
|
})
|
||||||
|
},
|
||||||
|
cleanupLinePdfPreviews() {
|
||||||
|
if (this.linePdfObserver) {
|
||||||
|
this.linePdfObserver.disconnect()
|
||||||
|
this.linePdfObserver = null
|
||||||
|
}
|
||||||
|
this.linePdfPreviews.forEach((item) => {
|
||||||
|
if (item.task && item.task.destroy) {
|
||||||
|
try {
|
||||||
|
item.task.destroy()
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.linePdfPreviews = []
|
||||||
|
},
|
||||||
|
getFileIdFromUrl(href) {
|
||||||
|
if (!href) return ""
|
||||||
|
const idMatch = href.match(/[?&]id=([^&#]+)/)
|
||||||
|
if (idMatch) {
|
||||||
|
return decodeURIComponent(idMatch[1])
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
},
|
||||||
revokeSignup(row) {
|
revokeSignup(row) {
|
||||||
if (!this.canRevokeSignup(row)) {
|
if (!this.canRevokeSignup(row)) {
|
||||||
this.$message.warning("当前报名申请暂不支持撤回")
|
this.$message.warning("当前报名申请暂不支持撤回")
|
||||||
@@ -676,16 +1097,6 @@ layout("/layouts/platform.html"){
|
|||||||
})
|
})
|
||||||
}).catch(() => {})
|
}).catch(() => {})
|
||||||
},
|
},
|
||||||
handleLineContentClick(event) {
|
|
||||||
const anchor = event.target.closest && event.target.closest("a[href]")
|
|
||||||
if (!anchor || !this.$refs.lineContent || !this.$refs.lineContent.contains(anchor)) return
|
|
||||||
if (!this.isPdfLink(anchor)) return
|
|
||||||
event.preventDefault()
|
|
||||||
const href = anchor.getAttribute("href")
|
|
||||||
this.previewPdf(href, (previewUrl) => {
|
|
||||||
window.open(previewUrl, "_blank", "noopener,noreferrer")
|
|
||||||
})
|
|
||||||
},
|
|
||||||
openSignup(row) {
|
openSignup(row) {
|
||||||
this.$axios.post(loc() + "/signupEligibilityNotice", { matterId: row.matterId }).then((res) => {
|
this.$axios.post(loc() + "/signupEligibilityNotice", { matterId: row.matterId }).then((res) => {
|
||||||
if (res.code !== 0) {
|
if (res.code !== 0) {
|
||||||
@@ -769,10 +1180,7 @@ layout("/layouts/platform.html"){
|
|||||||
hasFamily: ledger.hasFamily === true || ledger.hasFamily === 1 || ledger.hasFamily === "1"
|
hasFamily: ledger.hasFamily === true || ledger.hasFamily === 1 || ledger.hasFamily === "1"
|
||||||
})
|
})
|
||||||
this.directRelativeForm = Object.assign(this.emptyDirectRelative(), {
|
this.directRelativeForm = Object.assign(this.emptyDirectRelative(), {
|
||||||
lineId: matter.lineId || "",
|
lineId: matter.lineId || ""
|
||||||
lineName: matter.lineName || "",
|
|
||||||
travelStartTime: matter.travelStartTime || "",
|
|
||||||
travelEndTime: matter.travelEndTime || ""
|
|
||||||
}, directRelative)
|
}, directRelative)
|
||||||
this.familyData = (data.families || []).map(item => Object.assign(this.emptyFamily(), item))
|
this.familyData = (data.families || []).map(item => Object.assign(this.emptyFamily(), item))
|
||||||
if (this.familyData.length > 0) {
|
if (this.familyData.length > 0) {
|
||||||
@@ -815,9 +1223,9 @@ layout("/layouts/platform.html"){
|
|||||||
relationshipCode: "",
|
relationshipCode: "",
|
||||||
relationshipName: "",
|
relationshipName: "",
|
||||||
lineId: this.signupForm.lineId || "",
|
lineId: this.signupForm.lineId || "",
|
||||||
lineName: this.signupForm.lineName || "",
|
lineName: "",
|
||||||
travelStartTime: this.signupForm.travelStartTime || "",
|
travelStartTime: "",
|
||||||
travelEndTime: this.signupForm.travelEndTime || ""
|
travelEndTime: ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
directRelativeChange(code) {
|
directRelativeChange(code) {
|
||||||
@@ -949,6 +1357,7 @@ layout("/layouts/platform.html"){
|
|||||||
this.cancelLoading = false
|
this.cancelLoading = false
|
||||||
},
|
},
|
||||||
destroyLineView() {
|
destroyLineView() {
|
||||||
|
this.cleanupLinePdfPreviews()
|
||||||
this.lineDetail = {}
|
this.lineDetail = {}
|
||||||
this.lineContentHtml = ""
|
this.lineContentHtml = ""
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -62,13 +62,14 @@ layout("/layouts/platform.html"){
|
|||||||
:data="tableData"
|
:data="tableData"
|
||||||
:size="tableSize"
|
:size="tableSize"
|
||||||
border
|
border
|
||||||
|
:default-sort="{prop: 'agencyCode', order: 'ascending'}"
|
||||||
@sort-change="pageOrder">
|
@sort-change="pageOrder">
|
||||||
<el-table-column label="序号" type="index" :index="indexMethod" width="80" align="center" header-align="center"></el-table-column>
|
<el-table-column label="序号" type="index" :index="indexMethod" width="80" align="center" header-align="center"></el-table-column>
|
||||||
<el-table-column label="年度" prop="year" width="110" sortable="custom" align="center" header-align="center"></el-table-column>
|
<el-table-column label="年度" prop="year" width="110" sortable="custom" align="center" header-align="center"></el-table-column>
|
||||||
<el-table-column label="旅行社编号" prop="agencyCode" width="120" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
|
||||||
<el-table-column label="旅行社名称" prop="agencyName" min-width="220" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="旅行社名称" prop="agencyName" min-width="220" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="联系人" prop="contactName" width="130" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="联系人" prop="contactName" width="130" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="联系电话" prop="contactPhone" width="150" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="联系电话" prop="contactPhone" width="150" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="排序编号" prop="agencyCode" width="120" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="激活状态" prop="enabled" width="160" align="center" header-align="center">
|
<el-table-column label="激活状态" prop="enabled" width="160" align="center" header-align="center">
|
||||||
<template slot-scope="{row}">
|
<template slot-scope="{row}">
|
||||||
<el-switch
|
<el-switch
|
||||||
@@ -117,11 +118,6 @@ layout("/layouts/platform.html"){
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="旅行社编号" prop="agencyCode">
|
|
||||||
<el-input v-model="formData.agencyCode" maxlength="50" placeholder="请输入旅行社编号"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="激活状态" prop="enabled">
|
<el-form-item label="激活状态" prop="enabled">
|
||||||
<el-radio-group v-model="formData.enabled">
|
<el-radio-group v-model="formData.enabled">
|
||||||
@@ -144,6 +140,11 @@ layout("/layouts/platform.html"){
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="排序编号" prop="agencyCode">
|
||||||
|
<el-input-number v-model="formData.agencyCode" :controls="false" :min="0" :precision="0" placeholder="请输入排序编号" style="width: 100%"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="邮箱" prop="email">
|
<el-form-item label="邮箱" prop="email">
|
||||||
<el-input v-model="formData.email" maxlength="100" placeholder="请输入邮箱"></el-input>
|
<el-input v-model="formData.email" maxlength="100" placeholder="请输入邮箱"></el-input>
|
||||||
@@ -213,7 +214,9 @@ layout("/layouts/platform.html"){
|
|||||||
year: currentYear,
|
year: currentYear,
|
||||||
agencyName: "",
|
agencyName: "",
|
||||||
contactName: "",
|
contactName: "",
|
||||||
contactPhone: ""
|
contactPhone: "",
|
||||||
|
pageOrderName: "agencyCode",
|
||||||
|
pageOrderBy: "ascending"
|
||||||
},
|
},
|
||||||
formData: {},
|
formData: {},
|
||||||
formRules: {
|
formRules: {
|
||||||
|
|||||||
@@ -0,0 +1,470 @@
|
|||||||
|
<!--#
|
||||||
|
layout("/layouts/platform.html"){
|
||||||
|
#-->
|
||||||
|
|
||||||
|
<div id="app" v-cloak>
|
||||||
|
<guava ref="guava">
|
||||||
|
<el-card shadow="never">
|
||||||
|
<search :is-search-button="false">
|
||||||
|
<search-item label="年度">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="pageForm.year"
|
||||||
|
type="year"
|
||||||
|
value-format="yyyy"
|
||||||
|
placeholder="请选择年度"
|
||||||
|
style="width: 100%">
|
||||||
|
</el-date-picker>
|
||||||
|
</search-item>
|
||||||
|
<search-item label="线路名称">
|
||||||
|
<el-input
|
||||||
|
v-model="pageForm.lineName"
|
||||||
|
clearable
|
||||||
|
placeholder="请输入线路名称"
|
||||||
|
style="width: 100%"
|
||||||
|
@keyup.enter.native="doSearch">
|
||||||
|
</el-input>
|
||||||
|
</search-item>
|
||||||
|
<search-item label="线路类型">
|
||||||
|
<el-select v-model="pageForm.lineType" clearable filterable placeholder="请选择线路类型" style="width: 100%">
|
||||||
|
<el-option v-for="item in lineTypeOptions" :key="item.lineType" :label="item.lineType" :value="item.lineType"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</search-item>
|
||||||
|
<search-item label="所属工会">
|
||||||
|
<el-select v-model="pageForm.unionId" clearable filterable placeholder="请选择所属工会" style="width: 100%">
|
||||||
|
<el-option v-for="item in unionOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</search-item>
|
||||||
|
<div class="search-query" style="margin-left: auto;">
|
||||||
|
<el-button size="medium" type="primary" icon="el-icon-search" @click="doSearch">搜索</el-button>
|
||||||
|
<el-button size="medium" @click="resetSearch">重置</el-button>
|
||||||
|
</div>
|
||||||
|
</search>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<el-card class="mt10" shadow="never">
|
||||||
|
<table-tool :app="this" label="领办线路列表">
|
||||||
|
<el-radio-group class="mr5" size="small" v-model="pageForm.undertakeStatus" @change="changeUndertakeStatus">
|
||||||
|
<el-radio-button label="claimed">已领</el-radio-button>
|
||||||
|
<el-radio-button label="unclaimed">未领</el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</table-tool>
|
||||||
|
|
||||||
|
<el-table
|
||||||
|
v-loading="tableLoading"
|
||||||
|
:data="tableData"
|
||||||
|
:size="tableSize"
|
||||||
|
border
|
||||||
|
:default-sort="{prop: 'lineName', order: 'ascending'}"
|
||||||
|
:row-class-name="tableRowClassName"
|
||||||
|
@sort-change="pageOrder">
|
||||||
|
<el-table-column label="序号" type="index" :index="indexMethod" width="80" align="center" header-align="center"></el-table-column>
|
||||||
|
<el-table-column label="线路名称" prop="lineName" min-width="220" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="出行时段" prop="travelPeriod" width="260" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column v-if="false" label="事项名称" prop="matterName" min-width="200" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="所属工会" prop="unionName" min-width="180" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="领办状态" prop="undertakeStatusName" width="150" sortable="custom" align="center" header-align="center">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<el-button size="mini" :type="isClaimed(row) ? 'info' : 'primary'" plain>{{ row.undertakeStatusName || '未领' }}</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="线路类型" prop="lineType" width="140" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="最少成团人数" prop="minGroupPeople" width="140" sortable="custom" align="center" header-align="center">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
{{ row.minGroupPeople || 0 }}人
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="最多成团人数" prop="maxGroupPeople" width="140" sortable="custom" align="center" header-align="center">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
{{ row.maxGroupPeople || 0 }}人
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="报名人数" prop="signupCount" width="160" sortable="custom" align="center" header-align="center">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<el-tag size="mini" :type="Number(row.signupCount || 0) > 0 ? 'success' : 'info'">
|
||||||
|
{{ row.signupCount || 0 }}人<span v-if="row.showCurrentUnionSignupCount">({{ row.currentUnionSignupCount || 0 }}人)</span>
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="成团状态" prop="groupStatusName" width="120" sortable="custom" align="center" header-align="center">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<el-tag size="mini" :type="groupStatusType(row.groupStatus)">{{ row.groupStatusName || '未成团' }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="220" align="center" header-align="center" fixed="right">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<el-button size="mini" type="primary" @click="openView(row)">查看</el-button>
|
||||||
|
<el-button size="mini" type="primary" :disabled="isClaimed(row)" @click="undertakeLine(row)">领办</el-button>
|
||||||
|
<el-button v-if="row.canRelease" size="mini" type="danger" plain @click="releaseUndertakeLine(row)">解除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!--#include("/layouts/pagination.html"){}#-->
|
||||||
|
<div class="tour-undertake-tip">温馨提醒:列表中报名人数字段括号内的数字是本工会所报其线路的人数。</div>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<el-drawer
|
||||||
|
:title="viewTitle"
|
||||||
|
:visible.sync="viewVisible"
|
||||||
|
direction="rtl"
|
||||||
|
size="72%"
|
||||||
|
custom-class="tour-group-view-drawer"
|
||||||
|
:close-on-click-modal="false">
|
||||||
|
<div class="tour-group-view">
|
||||||
|
<el-card shadow="never">
|
||||||
|
<search :is-search-button="false">
|
||||||
|
<search-item label="姓名/工号">
|
||||||
|
<el-input
|
||||||
|
v-model="viewForm.keyword"
|
||||||
|
clearable
|
||||||
|
placeholder="请输入姓名或工号"
|
||||||
|
style="width: 100%"
|
||||||
|
@keyup.enter.native="viewSearch">
|
||||||
|
</el-input>
|
||||||
|
</search-item>
|
||||||
|
<search-item label="所属工会">
|
||||||
|
<el-select v-model="viewForm.unionId" clearable filterable placeholder="请选择所属工会" style="width: 100%">
|
||||||
|
<el-option v-for="item in unionOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</search-item>
|
||||||
|
<div class="search-query" style="margin-left: auto;">
|
||||||
|
<el-button size="medium" type="primary" icon="el-icon-search" @click="viewSearch">搜索</el-button>
|
||||||
|
<el-button size="medium" @click="viewReset">重置</el-button>
|
||||||
|
</div>
|
||||||
|
</search>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<el-card class="mt10" shadow="never">
|
||||||
|
<div class="tour-group-view-title">报名人员列表</div>
|
||||||
|
<el-table
|
||||||
|
v-loading="viewLoading"
|
||||||
|
:data="viewTableData"
|
||||||
|
:size="tableSize"
|
||||||
|
border
|
||||||
|
@sort-change="viewPageOrder">
|
||||||
|
<el-table-column type="expand" width="50">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<div v-if="row.families && row.families.length > 0" class="tour-family-list">
|
||||||
|
<el-table :data="row.families" :size="tableSize" border>
|
||||||
|
<el-table-column label="工号" prop="jobNo" width="130" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="姓名" prop="userName" width="120" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="亲属关系" prop="relationship" width="120" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="手机号" prop="mobile" width="140" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="身份证号" prop="idCard" min-width="190" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<div v-else class="tour-family-empty">暂无亲属信息</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="序号" type="index" :index="viewIndexMethod" width="80" align="center" header-align="center"></el-table-column>
|
||||||
|
<el-table-column label="工号" prop="jobNo" width="130" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="姓名" prop="userName" width="120" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="手机号码" prop="mobile" width="140" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="身份证号" prop="idCard" min-width="190" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="所属工会" prop="unionName" min-width="180" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-row class="el-pagination-container tour-group-view-pagination">
|
||||||
|
<el-pagination
|
||||||
|
background
|
||||||
|
:current-page="viewForm.pageNumber"
|
||||||
|
:page-size="viewForm.pageSize"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
:total="viewForm.totalCount"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
@size-change="viewSizeChange"
|
||||||
|
@current-change="viewCurrentChange">
|
||||||
|
</el-pagination>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</el-drawer>
|
||||||
|
</guava>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script nonce="${cspNonce!}">
|
||||||
|
new Vue({
|
||||||
|
el: "#app",
|
||||||
|
mixins: [initTableMixins],
|
||||||
|
data() {
|
||||||
|
const currentYear = moment().format("YYYY")
|
||||||
|
return {
|
||||||
|
unionOptions: [],
|
||||||
|
lineTypeOptions: [],
|
||||||
|
viewVisible: false,
|
||||||
|
viewLoading: false,
|
||||||
|
viewRequestSeq: 0,
|
||||||
|
viewTitle: "",
|
||||||
|
viewRow: {},
|
||||||
|
viewTableData: [],
|
||||||
|
currentUnionInfo: null,
|
||||||
|
pageForm: {
|
||||||
|
pageNumber: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
totalCount: 0,
|
||||||
|
pageOrderName: "lineName",
|
||||||
|
pageOrderBy: "ascending",
|
||||||
|
year: currentYear,
|
||||||
|
lineName: "",
|
||||||
|
lineType: "",
|
||||||
|
unionId: "",
|
||||||
|
undertakeStatus: "unclaimed"
|
||||||
|
},
|
||||||
|
viewForm: {
|
||||||
|
pageNumber: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
totalCount: 0,
|
||||||
|
pageOrderName: "signupTime",
|
||||||
|
pageOrderBy: "descending",
|
||||||
|
keyword: "",
|
||||||
|
unionId: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
resetSearch() {
|
||||||
|
this.pageForm.year = moment().format("YYYY")
|
||||||
|
this.pageForm.lineName = ""
|
||||||
|
this.pageForm.lineType = ""
|
||||||
|
this.pageForm.unionId = ""
|
||||||
|
this.pageForm.undertakeStatus = "unclaimed"
|
||||||
|
this.loadLineTypeOptions()
|
||||||
|
this.doSearch()
|
||||||
|
},
|
||||||
|
changeUndertakeStatus() {
|
||||||
|
this.pageForm.pageNumber = 1
|
||||||
|
this.pageData()
|
||||||
|
},
|
||||||
|
groupStatusType(status) {
|
||||||
|
if (status === "formed") return "success"
|
||||||
|
if (status === "over") return "danger"
|
||||||
|
return "info"
|
||||||
|
},
|
||||||
|
tableRowClassName({ row }) {
|
||||||
|
return this.isDirectFamilyLine(row) ? "direct-family-row" : ""
|
||||||
|
},
|
||||||
|
isDirectFamilyLine(row) {
|
||||||
|
if (!row) return false
|
||||||
|
return row.directFamilyUnitLine === true
|
||||||
|
|| row.directFamilyUnitLine === 1
|
||||||
|
|| row.directFamilyUnitLine === "1"
|
||||||
|
},
|
||||||
|
isClaimed(row) {
|
||||||
|
return row && row.undertakeStatus === "claimed"
|
||||||
|
},
|
||||||
|
openView(row) {
|
||||||
|
this.viewRow = row || {}
|
||||||
|
this.viewTitle = this.viewRow.lineName || "报名人员"
|
||||||
|
this.viewVisible = true
|
||||||
|
this.viewForm.pageNumber = 1
|
||||||
|
this.viewForm.pageSize = 10
|
||||||
|
this.viewForm.totalCount = 0
|
||||||
|
this.viewForm.pageOrderName = "signupTime"
|
||||||
|
this.viewForm.pageOrderBy = "descending"
|
||||||
|
this.viewForm.keyword = ""
|
||||||
|
this.viewForm.unionId = ""
|
||||||
|
this.viewTableData = []
|
||||||
|
this.loadViewData()
|
||||||
|
},
|
||||||
|
loadCurrentUnion() {
|
||||||
|
if (this.currentUnionInfo) {
|
||||||
|
return Promise.resolve(this.currentUnionInfo)
|
||||||
|
}
|
||||||
|
return this.$axios.post(loc() + "/currentUnion").then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.currentUnionInfo = res.data || {}
|
||||||
|
return this.currentUnionInfo
|
||||||
|
}
|
||||||
|
this.$message.warning(res.msg || "未获取到当前登录人工会")
|
||||||
|
return Promise.reject(new Error(res.msg || "未获取到当前登录人工会"))
|
||||||
|
})
|
||||||
|
},
|
||||||
|
undertakeLine(row) {
|
||||||
|
if (!row || !row.matterId) {
|
||||||
|
this.$message.warning("线路信息不完整")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.isClaimed(row)) {
|
||||||
|
this.$message.warning("当前线路已领办,不允许修改")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.loadCurrentUnion().then((union) => {
|
||||||
|
const lineName = row.lineName || "当前线路"
|
||||||
|
const unionName = (union && union.unionName) || ""
|
||||||
|
return this.$confirm(lineName + "由" + unionName + "领办,领办后,系统不允许修改,请确认。", "提示", {
|
||||||
|
confirmButtonText: "确定",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "warning"
|
||||||
|
}).then(() => {
|
||||||
|
return this.$axios.post(loc() + "/undertakeLine", {
|
||||||
|
matterId: row.matterId
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}).then((res) => {
|
||||||
|
if (!res) return
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.$message.success("领办成功")
|
||||||
|
this.pageData()
|
||||||
|
} else {
|
||||||
|
this.$message.warning(res.msg || "领办失败")
|
||||||
|
}
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
releaseUndertakeLine(row) {
|
||||||
|
if (!row || !row.matterId) {
|
||||||
|
this.$message.warning("线路信息不完整")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!this.isClaimed(row)) {
|
||||||
|
this.$message.warning("当前线路未领办,无需解除")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const lineName = row.lineName || "当前线路"
|
||||||
|
this.$confirm("确认解除【" + lineName + "】的领办状态吗?解除后该线路将变为未领。", "提示", {
|
||||||
|
confirmButtonText: "确定",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "warning"
|
||||||
|
}).then(() => {
|
||||||
|
return this.$axios.post(loc() + "/releaseUndertakeLine", {
|
||||||
|
matterId: row.matterId
|
||||||
|
})
|
||||||
|
}).then((res) => {
|
||||||
|
if (!res) return
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.$message.success("解除成功")
|
||||||
|
this.pageData()
|
||||||
|
} else {
|
||||||
|
this.$message.warning(res.msg || "解除失败")
|
||||||
|
}
|
||||||
|
}).catch(() => {})
|
||||||
|
},
|
||||||
|
viewSearch() {
|
||||||
|
this.viewForm.pageNumber = 1
|
||||||
|
this.loadViewData()
|
||||||
|
},
|
||||||
|
viewReset() {
|
||||||
|
this.viewForm.keyword = ""
|
||||||
|
this.viewForm.unionId = ""
|
||||||
|
this.viewForm.pageNumber = 1
|
||||||
|
this.loadViewData()
|
||||||
|
},
|
||||||
|
viewIndexMethod(index) {
|
||||||
|
return (this.viewForm.pageNumber - 1) * this.viewForm.pageSize + index + 1
|
||||||
|
},
|
||||||
|
viewSizeChange(size) {
|
||||||
|
this.viewForm.pageSize = size
|
||||||
|
this.viewForm.pageNumber = 1
|
||||||
|
this.loadViewData()
|
||||||
|
},
|
||||||
|
viewCurrentChange(page) {
|
||||||
|
this.viewForm.pageNumber = page
|
||||||
|
this.loadViewData()
|
||||||
|
},
|
||||||
|
viewPageOrder({ prop, order }) {
|
||||||
|
this.viewForm.pageOrderName = prop || "signupTime"
|
||||||
|
this.viewForm.pageOrderBy = order || "descending"
|
||||||
|
this.viewForm.pageNumber = 1
|
||||||
|
this.loadViewData()
|
||||||
|
},
|
||||||
|
loadViewData() {
|
||||||
|
if (!this.viewRow || !this.viewRow.matterId) {
|
||||||
|
this.viewTableData = []
|
||||||
|
this.viewForm.totalCount = 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.viewLoading = true
|
||||||
|
const requestSeq = ++this.viewRequestSeq
|
||||||
|
this.$axios.post(loc() + "/signupPageData", {
|
||||||
|
matterId: this.viewRow.matterId,
|
||||||
|
keyword: this.viewForm.keyword,
|
||||||
|
unionId: this.viewForm.unionId,
|
||||||
|
pageNumber: this.viewForm.pageNumber,
|
||||||
|
pageSize: this.viewForm.pageSize,
|
||||||
|
pageOrderName: this.viewForm.pageOrderName,
|
||||||
|
pageOrderBy: this.viewForm.pageOrderBy
|
||||||
|
}).then((res) => {
|
||||||
|
if (requestSeq !== this.viewRequestSeq) return
|
||||||
|
if (res.code === 0) {
|
||||||
|
const data = res.data || {}
|
||||||
|
this.viewTableData = data.list || []
|
||||||
|
this.viewForm.totalCount = data.totalCount || 0
|
||||||
|
} else {
|
||||||
|
this.$message.warning(res.msg || "查询失败")
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
if (requestSeq === this.viewRequestSeq) {
|
||||||
|
this.viewLoading = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
loadUnionOptions() {
|
||||||
|
this.$axios.post(loc() + "/unionOptions").then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.unionOptions = res.data || []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
loadLineTypeOptions() {
|
||||||
|
this.$axios.post(loc() + "/lineTypeOptions", {
|
||||||
|
year: this.pageForm.year
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.lineTypeOptions = (res.data || []).filter(item => item.lineType)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.loadUnionOptions()
|
||||||
|
this.loadLineTypeOptions()
|
||||||
|
this.pageData()
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
"pageForm.year"() {
|
||||||
|
this.pageForm.lineType = ""
|
||||||
|
this.loadLineTypeOptions()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.tour-group-view-drawer .el-drawer__body {
|
||||||
|
background: #f5f7fa;
|
||||||
|
padding: 12px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
.tour-group-view-pagination {
|
||||||
|
margin-top: 12px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.tour-group-view-title {
|
||||||
|
border-left: 4px solid #0079c2;
|
||||||
|
color: #0079c2;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 16px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
.tour-family-list {
|
||||||
|
padding: 8px 32px;
|
||||||
|
}
|
||||||
|
.tour-family-empty {
|
||||||
|
color: #909399;
|
||||||
|
padding: 8px 32px;
|
||||||
|
}
|
||||||
|
.tour-undertake-tip {
|
||||||
|
margin-top: 8px;
|
||||||
|
color: #f56c6c;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.el-table .direct-family-row > td,
|
||||||
|
.el-table .direct-family-row > td .cell {
|
||||||
|
color: #f56c6c;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!--#
|
||||||
|
}
|
||||||
|
#-->
|
||||||
@@ -190,8 +190,8 @@ layout("/layouts/platform.html"){
|
|||||||
<el-descriptions-item label="报名线路">{{ detail.lineName || '' }}</el-descriptions-item>
|
<el-descriptions-item label="报名线路">{{ detail.lineName || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="出行时段">{{ detail.travelPeriod || '' }}</el-descriptions-item>
|
<el-descriptions-item label="出行时段">{{ detail.travelPeriod || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="线路类型">{{ detail.lineType || '' }}</el-descriptions-item>
|
<el-descriptions-item label="线路类型">{{ detail.lineType || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="报名酒店">{{ detail.hotelName || '' }}</el-descriptions-item>
|
<el-descriptions-item v-if="false" label="报名酒店">{{ detail.hotelName || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="旅行社">{{ detail.travelAgencyName || '' }}</el-descriptions-item>
|
<el-descriptions-item v-if="false" label="旅行社">{{ detail.travelAgencyName || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="是否携带家属">
|
<el-descriptions-item label="是否携带家属">
|
||||||
{{ familyText() }}
|
{{ familyText() }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
|||||||
@@ -163,8 +163,8 @@ layout("/layouts/platform.html"){
|
|||||||
<el-descriptions-item label="报名时间">{{ detail.signupTime || '' }}</el-descriptions-item>
|
<el-descriptions-item label="报名时间">{{ detail.signupTime || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="报名线路">{{ detail.lineName || '' }}</el-descriptions-item>
|
<el-descriptions-item label="报名线路">{{ detail.lineName || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="线路类型">{{ detail.lineType || '' }}</el-descriptions-item>
|
<el-descriptions-item label="线路类型">{{ detail.lineType || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="报名酒店">{{ detail.hotelName || '' }}</el-descriptions-item>
|
<el-descriptions-item v-if="false" label="报名酒店">{{ detail.hotelName || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="报名旅行社">{{ detail.travelAgencyName || '' }}</el-descriptions-item>
|
<el-descriptions-item v-if="false" label="报名旅行社">{{ detail.travelAgencyName || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="出行时间">{{ detail.travelPeriod || '' }}</el-descriptions-item>
|
<el-descriptions-item label="出行时间">{{ detail.travelPeriod || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item v-if="fillBedInfo" label="床型">{{ detail.bedType || '' }}</el-descriptions-item>
|
<el-descriptions-item v-if="fillBedInfo" label="床型">{{ detail.bedType || '' }}</el-descriptions-item>
|
||||||
<el-descriptions-item v-if="fillBedInfo" label="床位信息">{{ detail.bedInfo || '' }}</el-descriptions-item>
|
<el-descriptions-item v-if="fillBedInfo" label="床位信息">{{ detail.bedInfo || '' }}</el-descriptions-item>
|
||||||
|
|||||||
@@ -380,7 +380,7 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<van-button v-if="canRevoke(row)" size="small" type="danger" plain @click="revokeSignup(row)">撤回</van-button>
|
<van-button v-if="canRevoke(row)" size="small" type="danger" plain @click="revokeSignup(row)">撤回</van-button>
|
||||||
<van-button v-if="showCancel(row)" size="small" type="danger" plain :disabled="isTravelEnded(row)" @click="cancelByRow(row)">取消报名</van-button>
|
<van-button v-if="showCancel(row)" size="small" type="danger" plain :disabled="isTravelEnded(row)" @click="cancelByRow(row)">取消报名</van-button>
|
||||||
<van-button v-if="showExport(row)" size="small" type="info" plain :disabled="!canExport(row)" @click="downloadExport(row, 'cost')">报销申请</van-button>
|
<van-button v-if="showExport(row)" size="small" type="info" plain :disabled="!canExport(row)" @click="downloadExport(row, 'cost')">报销申请</van-button>
|
||||||
<van-button v-if="showDirectRelativeExport(row)" size="small" type="info" plain :disabled="!canDirectRelativeExport(row)" @click="downloadExport(row, 'direct')">亲属线路申请</van-button>
|
<van-button v-if="showDirectRelativeExport(row)" size="small" type="info" plain :disabled="!canDirectRelativeExport(row)" @click="downloadExport(row, 'direct')">下载亲属线路申请</van-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</van-list>
|
</van-list>
|
||||||
@@ -416,6 +416,7 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<van-cell title="姓名" :value="detail.userName || ''"></van-cell>
|
<van-cell title="姓名" :value="detail.userName || ''"></van-cell>
|
||||||
<van-cell title="性别" :value="detail.gender || ''"></van-cell>
|
<van-cell title="性别" :value="detail.gender || ''"></van-cell>
|
||||||
<van-cell title="身份证号" :value="detail.idCard || ''"></van-cell>
|
<van-cell title="身份证号" :value="detail.idCard || ''"></van-cell>
|
||||||
|
<van-cell title="手机号" :value="detail.mobile || ''"></van-cell>
|
||||||
<van-cell title="所在单位" :value="detail.unitName || ''"></van-cell>
|
<van-cell title="所在单位" :value="detail.unitName || ''"></van-cell>
|
||||||
<van-cell title="所在工会" :value="detail.unionName || ''"></van-cell>
|
<van-cell title="所在工会" :value="detail.unionName || ''"></van-cell>
|
||||||
</div>
|
</div>
|
||||||
@@ -424,8 +425,8 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<van-cell title="报名线路" :value="detail.lineName || ''"></van-cell>
|
<van-cell title="报名线路" :value="detail.lineName || ''"></van-cell>
|
||||||
<van-cell title="线路类型" :value="detail.lineType || ''"></van-cell>
|
<van-cell title="线路类型" :value="detail.lineType || ''"></van-cell>
|
||||||
<van-cell title="出行时间" :value="detail.travelPeriod || ''"></van-cell>
|
<van-cell title="出行时间" :value="detail.travelPeriod || ''"></van-cell>
|
||||||
<van-cell title="报名酒店" :value="detail.hotelName || ''"></van-cell>
|
<van-cell v-if="false" title="报名酒店" :value="detail.hotelName || ''"></van-cell>
|
||||||
<van-cell title="旅行社" :value="detail.travelAgencyName || ''"></van-cell>
|
<van-cell v-if="false" title="旅行社" :value="detail.travelAgencyName || ''"></van-cell>
|
||||||
<van-cell v-if="detailFillBedInfo" title="床型" :value="detail.bedType || ''"></van-cell>
|
<van-cell v-if="detailFillBedInfo" title="床型" :value="detail.bedType || ''"></van-cell>
|
||||||
<van-cell v-if="detailFillBedInfo" title="床位信息" :value="detail.bedInfo || ''"></van-cell>
|
<van-cell v-if="detailFillBedInfo" title="床位信息" :value="detail.bedInfo || ''"></van-cell>
|
||||||
<van-cell v-if="detailFillBedInfo" title="意向拼床人" :value="detail.intendedRoommate || ''"></van-cell>
|
<van-cell v-if="detailFillBedInfo" title="意向拼床人" :value="detail.intendedRoommate || ''"></van-cell>
|
||||||
@@ -469,7 +470,8 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<div class="tour-section-title">教职工信息</div>
|
<div class="tour-section-title">教职工信息</div>
|
||||||
<van-field label="姓名" readonly v-model="signupForm.userName"></van-field>
|
<van-field label="姓名" readonly v-model="signupForm.userName"></van-field>
|
||||||
<van-field label="工号" readonly v-model="signupForm.jobNo"></van-field>
|
<van-field label="工号" readonly v-model="signupForm.jobNo"></van-field>
|
||||||
<van-field label="身份证号" v-model="signupForm.idCard" maxlength="30" placeholder="请填写身份证号"></van-field>
|
<van-field required label="身份证号" v-model="signupForm.idCard" maxlength="30" placeholder="请填写身份证号"></van-field>
|
||||||
|
<van-field required label="手机号" v-model="signupForm.mobile" type="tel" maxlength="30" placeholder="请填写手机号"></van-field>
|
||||||
<van-field label="所在工会" readonly v-model="signupForm.unionName"></van-field>
|
<van-field label="所在工会" readonly v-model="signupForm.unionName"></van-field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -478,7 +480,7 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<van-field label="报名线路" readonly v-model="signupForm.lineName"></van-field>
|
<van-field label="报名线路" readonly v-model="signupForm.lineName"></van-field>
|
||||||
<van-field label="线路类型" readonly v-model="signupForm.lineType"></van-field>
|
<van-field label="线路类型" readonly v-model="signupForm.lineType"></van-field>
|
||||||
<van-field label="出行时间" readonly v-model="signupForm.travelPeriod"></van-field>
|
<van-field label="出行时间" readonly v-model="signupForm.travelPeriod"></van-field>
|
||||||
<van-field label="报名酒店" v-model="signupForm.hotelName" maxlength="100" placeholder="请输入报名酒店"></van-field>
|
<van-field v-if="false" label="报名酒店" v-model="signupForm.hotelName" maxlength="100" placeholder="请输入报名酒店"></van-field>
|
||||||
<van-field v-if="fillBedInfo" readonly clickable is-link label="床型" v-model="signupForm.bedType" placeholder="请选择床型" @click="openBedPicker('self')"></van-field>
|
<van-field v-if="fillBedInfo" readonly clickable is-link label="床型" v-model="signupForm.bedType" placeholder="请选择床型" @click="openBedPicker('self')"></van-field>
|
||||||
<van-field v-if="fillBedInfo" label="床位信息" v-model="signupForm.bedInfo" maxlength="100" placeholder="请输入床位信息"></van-field>
|
<van-field v-if="fillBedInfo" label="床位信息" v-model="signupForm.bedInfo" maxlength="100" placeholder="请输入床位信息"></van-field>
|
||||||
<van-field v-if="fillBedInfo" label="意向拼床人" v-model="signupForm.intendedRoommate" maxlength="100" placeholder="请输入意向拼床人"></van-field>
|
<van-field v-if="fillBedInfo" label="意向拼床人" v-model="signupForm.intendedRoommate" maxlength="100" placeholder="请输入意向拼床人"></van-field>
|
||||||
@@ -783,6 +785,7 @@ layout("/layouts/platform_h5.html"){
|
|||||||
userName: "",
|
userName: "",
|
||||||
gender: "",
|
gender: "",
|
||||||
idCard: "",
|
idCard: "",
|
||||||
|
mobile: "",
|
||||||
unitId: "",
|
unitId: "",
|
||||||
unitName: "",
|
unitName: "",
|
||||||
unionId: "",
|
unionId: "",
|
||||||
@@ -821,12 +824,9 @@ layout("/layouts/platform_h5.html"){
|
|||||||
overCostReimbursed: ledger.overCostReimbursed === true || ledger.overCostReimbursed === 1 || ledger.overCostReimbursed === "1",
|
overCostReimbursed: ledger.overCostReimbursed === true || ledger.overCostReimbursed === 1 || ledger.overCostReimbursed === "1",
|
||||||
hasFamily: ledger.hasFamily === true || ledger.hasFamily === 1 || ledger.hasFamily === "1"
|
hasFamily: ledger.hasFamily === true || ledger.hasFamily === 1 || ledger.hasFamily === "1"
|
||||||
})
|
})
|
||||||
this.directRelativeForm = Object.assign(this.emptyDirectRelative(), directRelative, {
|
this.directRelativeForm = Object.assign(this.emptyDirectRelative(), {
|
||||||
lineId: matter.lineId || "",
|
lineId: matter.lineId || ""
|
||||||
lineName: matter.lineName || "",
|
}, directRelative)
|
||||||
travelStartTime: matter.travelStartTime || "",
|
|
||||||
travelEndTime: matter.travelEndTime || ""
|
|
||||||
})
|
|
||||||
this.familyData = (data.families || []).map(item => Object.assign(this.emptyFamily(), item))
|
this.familyData = (data.families || []).map(item => Object.assign(this.emptyFamily(), item))
|
||||||
if (this.familyData.length > 0) {
|
if (this.familyData.length > 0) {
|
||||||
this.signupForm.hasFamily = true
|
this.signupForm.hasFamily = true
|
||||||
@@ -861,9 +861,9 @@ layout("/layouts/platform_h5.html"){
|
|||||||
relationshipCode: "",
|
relationshipCode: "",
|
||||||
relationshipName: "",
|
relationshipName: "",
|
||||||
lineId: this.signupForm.lineId || "",
|
lineId: this.signupForm.lineId || "",
|
||||||
lineName: this.signupForm.lineName || "",
|
lineName: "",
|
||||||
travelStartTime: this.signupForm.travelStartTime || "",
|
travelStartTime: "",
|
||||||
travelEndTime: this.signupForm.travelEndTime || ""
|
travelEndTime: ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addFamily() {
|
addFamily() {
|
||||||
@@ -956,8 +956,19 @@ layout("/layouts/platform_h5.html"){
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
|
validateSelfInfo() {
|
||||||
|
if (!String(this.signupForm.idCard || "").trim()) {
|
||||||
|
vant.Toast("请输入身份证号")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (!String(this.signupForm.mobile || "").trim()) {
|
||||||
|
vant.Toast("请输入手机号")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
},
|
||||||
submitSignup() {
|
submitSignup() {
|
||||||
if (!this.validateFamilies() || !this.validateDirectRelative()) return
|
if (!this.validateSelfInfo() || !this.validateFamilies() || !this.validateDirectRelative()) return
|
||||||
const families = this.allowFamily && this.signupForm.hasFamily ? this.familyData : []
|
const families = this.allowFamily && this.signupForm.hasFamily ? this.familyData : []
|
||||||
const form = Object.assign({}, this.signupForm, {
|
const form = Object.assign({}, this.signupForm, {
|
||||||
families: JSON.stringify(families),
|
families: JSON.stringify(families),
|
||||||
|
|||||||
+3
-2
@@ -205,6 +205,7 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<van-cell title="姓名" :value="detail.userName || ''"></van-cell>
|
<van-cell title="姓名" :value="detail.userName || ''"></van-cell>
|
||||||
<van-cell title="性别" :value="detail.gender || ''"></van-cell>
|
<van-cell title="性别" :value="detail.gender || ''"></van-cell>
|
||||||
<van-cell title="身份证号" :value="detail.idCard || ''"></van-cell>
|
<van-cell title="身份证号" :value="detail.idCard || ''"></van-cell>
|
||||||
|
<van-cell title="手机号" :value="detail.mobile || ''"></van-cell>
|
||||||
<van-cell title="所在单位" :value="detail.unitName || ''"></van-cell>
|
<van-cell title="所在单位" :value="detail.unitName || ''"></van-cell>
|
||||||
<van-cell title="所在工会" :value="detail.unionName || ''"></van-cell>
|
<van-cell title="所在工会" :value="detail.unionName || ''"></van-cell>
|
||||||
</div>
|
</div>
|
||||||
@@ -215,8 +216,8 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<van-cell title="线路类型" :value="detail.lineType || ''"></van-cell>
|
<van-cell title="线路类型" :value="detail.lineType || ''"></van-cell>
|
||||||
<van-cell title="出行时段" :value="detail.travelPeriod || ''"></van-cell>
|
<van-cell title="出行时段" :value="detail.travelPeriod || ''"></van-cell>
|
||||||
<van-cell title="报名时间" :value="detail.signupTime || ''"></van-cell>
|
<van-cell title="报名时间" :value="detail.signupTime || ''"></van-cell>
|
||||||
<van-cell title="报名酒店" :value="detail.hotelName || ''"></van-cell>
|
<van-cell v-if="false" title="报名酒店" :value="detail.hotelName || ''"></van-cell>
|
||||||
<van-cell title="旅行社" :value="detail.travelAgencyName || ''"></van-cell>
|
<van-cell v-if="false" title="旅行社" :value="detail.travelAgencyName || ''"></van-cell>
|
||||||
<van-cell v-if="fillBedInfo" title="床型" :value="detail.bedType || ''"></van-cell>
|
<van-cell v-if="fillBedInfo" title="床型" :value="detail.bedType || ''"></van-cell>
|
||||||
<van-cell v-if="fillBedInfo" title="床位信息" :value="detail.bedInfo || ''"></van-cell>
|
<van-cell v-if="fillBedInfo" title="床位信息" :value="detail.bedInfo || ''"></van-cell>
|
||||||
<van-cell v-if="fillBedInfo" title="意向拼床人" :value="detail.intendedRoommate || ''"></van-cell>
|
<van-cell v-if="fillBedInfo" title="意向拼床人" :value="detail.intendedRoommate || ''"></van-cell>
|
||||||
|
|||||||
@@ -109,8 +109,8 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<div class="tour-apply-title">教职工信息</div>
|
<div class="tour-apply-title">教职工信息</div>
|
||||||
<van-field label="姓名" readonly v-model="signupForm.userName"></van-field>
|
<van-field label="姓名" readonly v-model="signupForm.userName"></van-field>
|
||||||
<van-field label="工号" readonly v-model="signupForm.jobNo"></van-field>
|
<van-field label="工号" readonly v-model="signupForm.jobNo"></van-field>
|
||||||
<van-field label="身份证号码" v-model="signupForm.idCard" maxlength="30" placeholder="请填写身份证号码"></van-field>
|
<van-field required label="身份证号码" v-model="signupForm.idCard" maxlength="30" placeholder="请填写身份证号码"></van-field>
|
||||||
<van-field label="手机号" v-model="signupForm.mobile" type="tel" maxlength="30" placeholder="请填写手机号"></van-field>
|
<van-field required label="手机号" v-model="signupForm.mobile" type="tel" maxlength="30" placeholder="请填写手机号"></van-field>
|
||||||
<van-field label="所属工会" readonly v-model="signupForm.unionName"></van-field>
|
<van-field label="所属工会" readonly v-model="signupForm.unionName"></van-field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<van-field label="报名线路" readonly v-model="signupForm.lineName"></van-field>
|
<van-field label="报名线路" readonly v-model="signupForm.lineName"></van-field>
|
||||||
<van-field label="线路类型" readonly v-model="signupForm.lineType"></van-field>
|
<van-field label="线路类型" readonly v-model="signupForm.lineType"></van-field>
|
||||||
<van-field v-if="signupForm.travelPeriod" label="出行时间" readonly v-model="signupForm.travelPeriod"></van-field>
|
<van-field v-if="signupForm.travelPeriod" label="出行时间" readonly v-model="signupForm.travelPeriod"></van-field>
|
||||||
<van-field label="报名酒店" v-model="signupForm.hotelName" maxlength="100" placeholder="请输入报名酒店"></van-field>
|
<van-field v-if="false" label="报名酒店" v-model="signupForm.hotelName" maxlength="100" placeholder="请输入报名酒店"></van-field>
|
||||||
<van-field
|
<van-field
|
||||||
v-if="fillBedInfo"
|
v-if="fillBedInfo"
|
||||||
label="床型"
|
label="床型"
|
||||||
@@ -256,7 +256,8 @@ layout("/layouts/platform_h5.html"){
|
|||||||
relationshipPickerVisible: false,
|
relationshipPickerVisible: false,
|
||||||
directRelativePickerVisible: false,
|
directRelativePickerVisible: false,
|
||||||
bedPickerTarget: "self",
|
bedPickerTarget: "self",
|
||||||
matterId: GetQueryString("matterId") || ""
|
matterId: GetQueryString("matterId") || "",
|
||||||
|
noticeChecked: GetQueryString("noticeChecked") === "1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -280,25 +281,42 @@ layout("/layouts/platform_h5.html"){
|
|||||||
this.pageLoading = false
|
this.pageLoading = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Promise.all([this.loadOptions(), this.loadSignupDetail()]).finally(() => {
|
this.loadOptions().catch(() => {})
|
||||||
|
this.loadSignupDetail().finally(() => {
|
||||||
this.pageLoading = false
|
this.pageLoading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
loadOptions() {
|
loadOptions() {
|
||||||
return Promise.all([
|
const cacheKey = "tourSignupOptions"
|
||||||
this.$axios.post("/platform/tour/signup/bedTypeOptions").then(res => {
|
try {
|
||||||
if (res.code === 0) this.bedTypeOptions = res.data || []
|
const cached = JSON.parse(sessionStorage.getItem(cacheKey) || "null")
|
||||||
}),
|
if (cached && cached.data) {
|
||||||
this.$axios.post("/platform/tour/signup/familyRelationshipOptions").then(res => {
|
this.applyOptions(cached.data)
|
||||||
if (res.code === 0) this.familyRelationshipOptions = res.data || []
|
return Promise.resolve(cached.data)
|
||||||
}),
|
}
|
||||||
this.$axios.post("/platform/tour/signup/directRelativeOptions").then(res => {
|
} catch (e) {
|
||||||
if (res.code === 0) this.directRelativeOptions = res.data || []
|
}
|
||||||
})
|
return this.$axios.post("/platform/tour/signup/signupOptions").then(res => {
|
||||||
])
|
if (res.code === 0) {
|
||||||
|
const data = res.data || {}
|
||||||
|
this.applyOptions(data)
|
||||||
|
try {
|
||||||
|
sessionStorage.setItem(cacheKey, JSON.stringify({data: data}))
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
applyOptions(data) {
|
||||||
|
this.bedTypeOptions = data.bedTypeOptions || []
|
||||||
|
this.familyRelationshipOptions = data.familyRelationshipOptions || []
|
||||||
|
this.directRelativeOptions = data.directRelativeOptions || []
|
||||||
},
|
},
|
||||||
loadSignupDetail() {
|
loadSignupDetail() {
|
||||||
return this.$axios.post("/platform/tour/signup/signupDetail", { matterId: this.matterId }).then((res) => {
|
return this.$axios.post("/platform/tour/signup/signupDetail", {
|
||||||
|
matterId: this.matterId,
|
||||||
|
noticeChecked: this.noticeChecked
|
||||||
|
}).then((res) => {
|
||||||
if (res.code !== 0) {
|
if (res.code !== 0) {
|
||||||
vant.Dialog.alert({
|
vant.Dialog.alert({
|
||||||
title: "提示",
|
title: "提示",
|
||||||
@@ -361,10 +379,7 @@ layout("/layouts/platform_h5.html"){
|
|||||||
hasFamily: ledger.hasFamily === true || ledger.hasFamily === 1 || ledger.hasFamily === "1"
|
hasFamily: ledger.hasFamily === true || ledger.hasFamily === 1 || ledger.hasFamily === "1"
|
||||||
})
|
})
|
||||||
this.directRelativeForm = Object.assign(this.emptyDirectRelative(), {
|
this.directRelativeForm = Object.assign(this.emptyDirectRelative(), {
|
||||||
lineId: matter.lineId || "",
|
lineId: matter.lineId || ""
|
||||||
lineName: matter.lineName || "",
|
|
||||||
travelStartTime: matter.travelStartTime || "",
|
|
||||||
travelEndTime: matter.travelEndTime || ""
|
|
||||||
}, directRelative)
|
}, directRelative)
|
||||||
this.familyData = (data.families || []).map(item => Object.assign(this.emptyFamily(), item))
|
this.familyData = (data.families || []).map(item => Object.assign(this.emptyFamily(), item))
|
||||||
if (this.familyData.length > 0) {
|
if (this.familyData.length > 0) {
|
||||||
@@ -398,9 +413,9 @@ layout("/layouts/platform_h5.html"){
|
|||||||
relationshipCode: "",
|
relationshipCode: "",
|
||||||
relationshipName: "",
|
relationshipName: "",
|
||||||
lineId: this.signupForm.lineId || "",
|
lineId: this.signupForm.lineId || "",
|
||||||
lineName: this.signupForm.lineName || "",
|
lineName: "",
|
||||||
travelStartTime: this.signupForm.travelStartTime || "",
|
travelStartTime: "",
|
||||||
travelEndTime: this.signupForm.travelEndTime || ""
|
travelEndTime: ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
isDirectFamilyLine(row) {
|
isDirectFamilyLine(row) {
|
||||||
@@ -512,8 +527,20 @@ layout("/layouts/platform_h5.html"){
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
|
validateSelfInfo() {
|
||||||
|
if (!String(this.signupForm.idCard || "").trim()) {
|
||||||
|
vant.Toast("请输入身份证号码")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (!String(this.signupForm.mobile || "").trim()) {
|
||||||
|
vant.Toast("请输入手机号")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
},
|
||||||
submitSignup() {
|
submitSignup() {
|
||||||
if (this.pageLoading || this.submitLoading) return
|
if (this.pageLoading || this.submitLoading) return
|
||||||
|
if (!this.validateSelfInfo()) return
|
||||||
if (!this.validateFamilies()) return
|
if (!this.validateFamilies()) return
|
||||||
if (!this.validateDirectRelative()) return
|
if (!this.validateDirectRelative()) return
|
||||||
const families = this.allowFamily && this.signupForm.hasFamily ? this.familyData : []
|
const families = this.allowFamily && this.signupForm.hasFamily ? this.familyData : []
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ layout("/layouts/platform_h5.html"){
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tour-signup-footer">
|
<div class="tour-signup-footer">
|
||||||
<van-button block type="info" color="#0f74bc" round @click="confirmRead">我已阅读</van-button>
|
<van-button block type="info" color="#0f74bc" round :loading="readLoading" :disabled="readLoading" loading-text="进入中..." @click="confirmRead">我已阅读</van-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -167,6 +167,7 @@ layout("/layouts/platform_h5.html"){
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
|
readLoading: false,
|
||||||
currentYear: new Date().getFullYear(),
|
currentYear: new Date().getFullYear(),
|
||||||
serviceNoticeKey: "",
|
serviceNoticeKey: "",
|
||||||
bannerList: [
|
bannerList: [
|
||||||
@@ -196,7 +197,15 @@ layout("/layouts/platform_h5.html"){
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
confirmRead() {
|
confirmRead() {
|
||||||
window.location.href = "/platform/tour/signup/h5/signup"
|
if (this.readLoading) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.readLoading = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.href = "/platform/tour/signup/h5/signup"
|
||||||
|
}, 80)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
|||||||
+568
-147
@@ -81,6 +81,14 @@ layout("/layouts/platform_h5.html"){
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tour-signup-people-link {
|
||||||
|
margin-left: 4px;
|
||||||
|
color: #d40000;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
.tour-detail-section {
|
.tour-detail-section {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
@@ -105,9 +113,16 @@ layout("/layouts/platform_h5.html"){
|
|||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tour-detail-content /deep/ img {
|
.tour-detail-content {
|
||||||
|
color: #334155;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.75;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-detail-content /deep/ img,
|
||||||
|
.tour-detail-content /deep/ iframe {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
height: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tour-detail-section-scroll {
|
.tour-detail-section-scroll {
|
||||||
@@ -117,39 +132,73 @@ layout("/layouts/platform_h5.html"){
|
|||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tour-pdf-preview {
|
.tour-detail-content /deep/ .tour-line-file-preview-box {
|
||||||
min-height: 220px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tour-pdf-status {
|
.tour-detail-content /deep/ .tour-pdf-lazy-preview {
|
||||||
padding: 16px 0;
|
margin-top: 10px;
|
||||||
color: #64748b;
|
|
||||||
font-size: 13px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tour-pdf-toolbar {
|
|
||||||
margin-bottom: 8px;
|
|
||||||
color: #64748b;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tour-pdf-pages {
|
|
||||||
min-height: 180px;
|
min-height: 180px;
|
||||||
}
|
border: 1px solid #dcdfe6;
|
||||||
|
|
||||||
.tour-pdf-page {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
border-radius: 6px;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: #f8fafc;
|
background: #f8fafc;
|
||||||
box-shadow: 0 1px 4px rgba(15, 23, 42, 0.08);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tour-pdf-page canvas {
|
.tour-detail-content /deep/ .tour-pdf-lazy-toolbar {
|
||||||
width: 100%;
|
padding: 0 10px;
|
||||||
|
border-bottom: 1px solid #e5e7eb;
|
||||||
|
color: #64748b;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 32px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-detail-content /deep/ .tour-pdf-page-placeholder {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 180px;
|
||||||
|
border-bottom: 1px solid #e5e7eb;
|
||||||
|
color: #94a3b8;
|
||||||
|
font-size: 13px;
|
||||||
|
background: #f8fafc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-detail-content /deep/ .tour-pdf-page-placeholder canvas {
|
||||||
display: block;
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-detail-content /deep/ .tour-line-file-preview {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 70vh;
|
||||||
|
min-height: 420px;
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-detail-content /deep/ .tour-line-image-preview {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
max-height: 70vh;
|
||||||
|
height: auto;
|
||||||
|
margin-top: 10px;
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
object-fit: contain;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-detail-content /deep/ .tour-line-file-unpreviewable {
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 12px;
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
color: #94a3b8;
|
||||||
|
font-size: 13px;
|
||||||
|
text-align: center;
|
||||||
|
background: #f8fafc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tour-detail-empty {
|
.tour-detail-empty {
|
||||||
@@ -170,6 +219,99 @@ layout("/layouts/platform_h5.html"){
|
|||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tour-people-popup {
|
||||||
|
height: 72vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: #ffffff;
|
||||||
|
overflow: hidden;
|
||||||
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-people-popup-title {
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding: 14px 16px 8px;
|
||||||
|
color: #0f172a;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 22px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-people-search {
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding: 0 10px 8px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
border-bottom: 1px solid #edf0f4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-people-search /deep/ .van-search {
|
||||||
|
flex: 1;
|
||||||
|
padding: 0;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-people-search-btns {
|
||||||
|
flex-shrink: 0;
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-people-table {
|
||||||
|
min-height: 0;
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-people-table-head,
|
||||||
|
.tour-people-table-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 54px minmax(88px, 1fr) minmax(128px, 1.25fr);
|
||||||
|
align-items: center;
|
||||||
|
min-height: 42px;
|
||||||
|
border-bottom: 1px solid #edf0f4;
|
||||||
|
color: #0f172a;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-people-table-head {
|
||||||
|
flex-shrink: 0;
|
||||||
|
background: #f8fafc;
|
||||||
|
color: #334155;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-people-table-cell {
|
||||||
|
min-width: 0;
|
||||||
|
padding: 9px 8px;
|
||||||
|
text-align: center;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-people-sort {
|
||||||
|
color: #0b75bd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-people-table-body {
|
||||||
|
min-height: 0;
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tour-people-empty {
|
||||||
|
padding: 22px 0;
|
||||||
|
color: #94a3b8;
|
||||||
|
font-size: 13px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div id="app">
|
<div id="app">
|
||||||
@@ -192,7 +334,10 @@ layout("/layouts/platform_h5.html"){
|
|||||||
</div>
|
</div>
|
||||||
<div class="tour-detail-meta-row">
|
<div class="tour-detail-meta-row">
|
||||||
<span class="tour-detail-meta-label"><span>已报人数</span><span>:</span></span>
|
<span class="tour-detail-meta-label"><span>已报人数</span><span>:</span></span>
|
||||||
<span class="tour-detail-meta-value">{{ signupDetail.signupCount || 0 }}(家属{{ signupDetail.familyCount || 0 }}人)</span>
|
<span class="tour-detail-meta-value">
|
||||||
|
{{ signupDetail.signupCount || 0 }}(家属{{ signupDetail.familyCount || 0 }}人)
|
||||||
|
<span class="tour-signup-people-link" @click.stop="openPeoplePopup">查看</span>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="tour-detail-meta-row">
|
<div class="tour-detail-meta-row">
|
||||||
<span class="tour-detail-meta-label"><span>联系人</span><span>:</span></span>
|
<span class="tour-detail-meta-label"><span>联系人</span><span>:</span></span>
|
||||||
@@ -207,20 +352,7 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<div class="tour-detail-section">
|
<div class="tour-detail-section">
|
||||||
<div class="tour-detail-section-title">线路介绍</div>
|
<div class="tour-detail-section-title">线路介绍</div>
|
||||||
<div class="tour-detail-section-scroll">
|
<div class="tour-detail-section-scroll">
|
||||||
<div v-if="lineDetail.lineContent && lineContentHref" class="tour-pdf-preview">
|
<div v-if="lineDetail.lineContent" class="tour-detail-content" v-html="lineContentHtml">
|
||||||
<div v-if="pdfPageCount" class="tour-pdf-toolbar">
|
|
||||||
已加载 {{ pdfRenderedPages }} / {{ pdfPageCount }} 页
|
|
||||||
</div>
|
|
||||||
<div ref="pdfPreviewContainer" class="tour-pdf-pages"></div>
|
|
||||||
<div v-if="pdfLoading && pdfRenderedPages === 0" class="tour-pdf-status">
|
|
||||||
<van-loading size="22px" vertical>正在加载第一页...</van-loading>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="pdfLoading" class="tour-pdf-status">
|
|
||||||
正在继续加载后续页面...
|
|
||||||
</div>
|
|
||||||
<div v-if="pdfError" class="tour-pdf-status">{{ pdfError }}</div>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="lineDetail.lineContent" class="tour-detail-content" v-html="lineDetail.lineContent">
|
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="tour-detail-empty">暂无线路介绍</div>
|
<div v-else class="tour-detail-empty">暂无线路介绍</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -229,10 +361,51 @@ layout("/layouts/platform_h5.html"){
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tour-detail-footer">
|
<div class="tour-detail-footer">
|
||||||
<van-button :type="detailActionType()" block round :disabled="detailActionDisabled()" @click="handleDetailAction">
|
<van-button :type="detailActionType()" block round :loading="applyLoading" :disabled="detailActionDisabled() || applyLoading" @click="handleDetailAction">
|
||||||
{{ detailActionText() }}
|
{{ detailActionText() }}
|
||||||
</van-button>
|
</van-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<van-popup v-model="peopleVisible" position="bottom" round>
|
||||||
|
<div class="tour-people-popup">
|
||||||
|
<div class="tour-people-popup-title">报名人员</div>
|
||||||
|
<div class="tour-people-search">
|
||||||
|
<van-search
|
||||||
|
v-model="peopleForm.keyword"
|
||||||
|
shape="round"
|
||||||
|
placeholder="请输入姓名或工号"
|
||||||
|
@search="peopleSearch">
|
||||||
|
</van-search>
|
||||||
|
<div class="tour-people-search-btns">
|
||||||
|
<van-button size="small" type="info" @click="peopleSearch">搜索</van-button>
|
||||||
|
<van-button size="small" plain @click="peopleReset">重置</van-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tour-people-table">
|
||||||
|
<div class="tour-people-table-head">
|
||||||
|
<div class="tour-people-table-cell">序号</div>
|
||||||
|
<div class="tour-people-table-cell">姓名</div>
|
||||||
|
<div class="tour-people-table-cell tour-people-sort" @click="togglePeopleUnionSort">
|
||||||
|
所属工会{{ peopleSortText() }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tour-people-table-body">
|
||||||
|
<van-list
|
||||||
|
v-model="peopleLoading"
|
||||||
|
:finished="peopleFinished"
|
||||||
|
finished-text="没有更多了"
|
||||||
|
@load="loadPeople">
|
||||||
|
<div v-for="item in peopleList" :key="item.id" class="tour-people-table-row">
|
||||||
|
<div class="tour-people-table-cell">{{ item.displayIndex }}</div>
|
||||||
|
<div class="tour-people-table-cell">{{ item.userName || '' }}</div>
|
||||||
|
<div class="tour-people-table-cell">{{ item.unionName || '' }}</div>
|
||||||
|
</div>
|
||||||
|
</van-list>
|
||||||
|
<div v-if="!peopleLoading && peopleList.length === 0" class="tour-people-empty">暂无报名人员</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</van-popup>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script nonce="${cspNonce!}">
|
<script nonce="${cspNonce!}">
|
||||||
@@ -242,16 +415,25 @@ layout("/layouts/platform_h5.html"){
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
detailLoading: true,
|
detailLoading: true,
|
||||||
|
applyLoading: false,
|
||||||
lineDetail: {},
|
lineDetail: {},
|
||||||
signupDetail: {},
|
signupDetail: {},
|
||||||
lineContentHref: "",
|
lineContentHtml: "",
|
||||||
pdfDoc: null,
|
linePdfPreviews: [],
|
||||||
pdfLoadingTask: null,
|
linePdfObserver: null,
|
||||||
pdfLoading: false,
|
peopleVisible: false,
|
||||||
pdfError: "",
|
peopleLoading: false,
|
||||||
pdfPageCount: 0,
|
peopleFinished: true,
|
||||||
pdfRenderedPages: 0,
|
peopleList: [],
|
||||||
pdfRenderToken: 0,
|
peopleForm: {
|
||||||
|
pageNumber: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
totalCount: 0,
|
||||||
|
pageOrderName: "signupTime",
|
||||||
|
pageOrderBy: "descending",
|
||||||
|
keyword: "",
|
||||||
|
unionId: ""
|
||||||
|
},
|
||||||
matterId: GetQueryString("matterId") || "",
|
matterId: GetQueryString("matterId") || "",
|
||||||
lineId: GetQueryString("lineId") || ""
|
lineId: GetQueryString("lineId") || ""
|
||||||
}
|
}
|
||||||
@@ -314,6 +496,94 @@ layout("/layouts/platform_h5.html"){
|
|||||||
detailActionDisabled() {
|
detailActionDisabled() {
|
||||||
return this.isSigned() && this.isApprovalSignup() && (this.isFinishedSignup() || this.isRejectedSignup() || (!this.canRevokeSignup() && !this.canModifySignup()))
|
return this.isSigned() && this.isApprovalSignup() && (this.isFinishedSignup() || this.isRejectedSignup() || (!this.canRevokeSignup() && !this.canModifySignup()))
|
||||||
},
|
},
|
||||||
|
peopleSortText() {
|
||||||
|
if (this.peopleForm.pageOrderName !== "unionName") {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return this.peopleForm.pageOrderBy === "ascending" ? "↑" : "↓"
|
||||||
|
},
|
||||||
|
resetPeopleData() {
|
||||||
|
this.peopleForm.pageNumber = 1
|
||||||
|
this.peopleForm.totalCount = 0
|
||||||
|
this.peopleList = []
|
||||||
|
this.peopleFinished = false
|
||||||
|
},
|
||||||
|
openPeoplePopup() {
|
||||||
|
if (!this.matterId) {
|
||||||
|
vant.Toast("报名事项信息不完整")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.peopleVisible = true
|
||||||
|
this.peopleForm.keyword = ""
|
||||||
|
this.peopleForm.pageOrderName = "signupTime"
|
||||||
|
this.peopleForm.pageOrderBy = "descending"
|
||||||
|
this.resetPeopleData()
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.loadPeople()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
peopleSearch() {
|
||||||
|
this.resetPeopleData()
|
||||||
|
this.loadPeople()
|
||||||
|
},
|
||||||
|
peopleReset() {
|
||||||
|
this.peopleForm.keyword = ""
|
||||||
|
this.peopleForm.pageOrderName = "signupTime"
|
||||||
|
this.peopleForm.pageOrderBy = "descending"
|
||||||
|
this.resetPeopleData()
|
||||||
|
this.loadPeople()
|
||||||
|
},
|
||||||
|
togglePeopleUnionSort() {
|
||||||
|
if (this.peopleForm.pageOrderName === "unionName") {
|
||||||
|
this.peopleForm.pageOrderBy = this.peopleForm.pageOrderBy === "ascending" ? "descending" : "ascending"
|
||||||
|
} else {
|
||||||
|
this.peopleForm.pageOrderName = "unionName"
|
||||||
|
this.peopleForm.pageOrderBy = "ascending"
|
||||||
|
}
|
||||||
|
this.resetPeopleData()
|
||||||
|
this.loadPeople()
|
||||||
|
},
|
||||||
|
loadPeople() {
|
||||||
|
if (!this.matterId || this.peopleLoading || this.peopleFinished) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.peopleLoading = true
|
||||||
|
this.$axios.post("/platform/tour/signup/h5/signupPageData", {
|
||||||
|
matterId: this.matterId,
|
||||||
|
keyword: this.peopleForm.keyword,
|
||||||
|
unionId: this.peopleForm.unionId,
|
||||||
|
pageNumber: this.peopleForm.pageNumber,
|
||||||
|
pageSize: this.peopleForm.pageSize,
|
||||||
|
pageOrderName: this.peopleForm.pageOrderName,
|
||||||
|
pageOrderBy: this.peopleForm.pageOrderBy
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.code !== 0) {
|
||||||
|
vant.Toast(res.msg || "报名人员加载失败")
|
||||||
|
this.peopleFinished = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const data = res.data || {}
|
||||||
|
const rows = data.list || []
|
||||||
|
const startIndex = this.peopleList.length
|
||||||
|
const normalizedRows = rows.map((item, index) => {
|
||||||
|
return Object.assign({}, item, {
|
||||||
|
displayIndex: startIndex + index + 1
|
||||||
|
})
|
||||||
|
})
|
||||||
|
this.peopleForm.totalCount = data.totalCount || 0
|
||||||
|
this.peopleList = this.peopleList.concat(normalizedRows)
|
||||||
|
if (this.peopleList.length >= this.peopleForm.totalCount || rows.length < this.peopleForm.pageSize) {
|
||||||
|
this.peopleFinished = true
|
||||||
|
} else {
|
||||||
|
this.peopleForm.pageNumber += 1
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
vant.Toast("报名人员加载失败")
|
||||||
|
this.peopleFinished = true
|
||||||
|
}).finally(() => {
|
||||||
|
this.peopleLoading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
handleDetailAction() {
|
handleDetailAction() {
|
||||||
if (this.detailActionDisabled()) {
|
if (this.detailActionDisabled()) {
|
||||||
return
|
return
|
||||||
@@ -322,134 +592,269 @@ layout("/layouts/platform_h5.html"){
|
|||||||
this.revokeSignup()
|
this.revokeSignup()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (this.isSigned()) {
|
||||||
|
this.onApply(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
this.onApply()
|
this.onApply()
|
||||||
},
|
},
|
||||||
parseLineContentHref(content) {
|
buildLineContentHtmlAsync(content) {
|
||||||
if (!content) {
|
const ids = this.extractLineFileIds(content)
|
||||||
return ""
|
if (!ids.length) {
|
||||||
|
return Promise.resolve(this.buildLineContentHtml(content, {}))
|
||||||
}
|
}
|
||||||
try {
|
return this.$axios.post("/platform/sys/file/previewFileData", {ids: JSON.stringify(ids)}).then((res) => {
|
||||||
const parser = new DOMParser()
|
const fileMap = {}
|
||||||
const doc = parser.parseFromString(content, "text/html")
|
if (res.code === 0 && Array.isArray(res.data)) {
|
||||||
const link = doc.querySelector("a[href]")
|
res.data.forEach((file) => {
|
||||||
return link ? link.getAttribute("href") : ""
|
if (file && file.id) {
|
||||||
} catch (e) {
|
file.suffix = (file.suffix || "").toLowerCase()
|
||||||
return ""
|
fileMap[file.id] = file
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return this.buildLineContentHtml(content, fileMap)
|
||||||
|
}).catch(() => this.buildLineContentHtml(content, {}))
|
||||||
|
},
|
||||||
|
extractLineFileIds(content) {
|
||||||
|
if (!content) return []
|
||||||
|
const wrap = document.createElement("div")
|
||||||
|
wrap.innerHTML = content
|
||||||
|
const ids = []
|
||||||
|
Array.prototype.slice.call(wrap.querySelectorAll("a[href]")).forEach((anchor) => {
|
||||||
|
const id = this.getFileIdFromUrl(anchor.getAttribute("href") || "")
|
||||||
|
if (id && !ids.includes(id)) {
|
||||||
|
ids.push(id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return ids
|
||||||
|
},
|
||||||
|
buildLineContentHtml(content, fileMap) {
|
||||||
|
if (!content) return ""
|
||||||
|
const wrap = document.createElement("div")
|
||||||
|
wrap.innerHTML = content
|
||||||
|
const anchors = Array.prototype.slice.call(wrap.querySelectorAll("a[href]"))
|
||||||
|
anchors.forEach((anchor) => {
|
||||||
|
const href = anchor.getAttribute("href") || ""
|
||||||
|
const text = anchor.textContent || href
|
||||||
|
const fileId = this.getFileIdFromUrl(href)
|
||||||
|
const file = fileId && fileMap ? fileMap[fileId] : null
|
||||||
|
const fileType = this.detectPreviewFileType(href, text, file)
|
||||||
|
if (!fileType) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const preview = this.createLineFilePreview(href, fileType, file)
|
||||||
|
if (anchor.parentNode && preview) {
|
||||||
|
anchor.parentNode.replaceChild(preview, anchor)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return wrap.innerHTML
|
||||||
|
},
|
||||||
|
detectPreviewFileType(href, text, file) {
|
||||||
|
const suffix = file && file.suffix ? file.suffix.toLowerCase() : ""
|
||||||
|
if (["jpg", "jpeg", "png", "gif", "bmp", "webp"].includes(suffix)) {
|
||||||
|
return "image"
|
||||||
}
|
}
|
||||||
|
if (suffix === "pdf") {
|
||||||
|
return "pdf"
|
||||||
|
}
|
||||||
|
if (["doc", "docx", "xls", "xlsx"].includes(suffix)) {
|
||||||
|
return "office"
|
||||||
|
}
|
||||||
|
const lowerHref = (href || "").split("#")[0].split("?")[0].toLowerCase()
|
||||||
|
const lowerText = (text || "").toLowerCase()
|
||||||
|
const value = lowerHref + " " + lowerText
|
||||||
|
if (/\.(jpg|jpeg|png|gif|bmp|webp)(\s|$)/.test(value)) {
|
||||||
|
return "image"
|
||||||
|
}
|
||||||
|
if (/\.pdf(\s|$)/.test(value)) {
|
||||||
|
return "pdf"
|
||||||
|
}
|
||||||
|
if (/\.(doc|docx|xls|xlsx)(\s|$)/.test(value)) {
|
||||||
|
return "office"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
},
|
||||||
|
createLineFilePreview(href, fileType, file) {
|
||||||
|
if (fileType === "image") {
|
||||||
|
const img = document.createElement("img")
|
||||||
|
img.className = "tour-line-image-preview"
|
||||||
|
img.src = file && file.downloadPath ? file.downloadPath : href
|
||||||
|
img.alt = ""
|
||||||
|
return img
|
||||||
|
}
|
||||||
|
const previewUrl = this.buildLinePreviewUrl(href, fileType, file)
|
||||||
|
if (!previewUrl) {
|
||||||
|
const tip = document.createElement("div")
|
||||||
|
tip.className = "tour-line-file-unpreviewable"
|
||||||
|
tip.textContent = "当前文件暂不支持预览"
|
||||||
|
return tip
|
||||||
|
}
|
||||||
|
const box = document.createElement("div")
|
||||||
|
box.className = "tour-line-file-preview-box"
|
||||||
|
const preview = document.createElement("div")
|
||||||
|
preview.className = "tour-pdf-lazy-preview"
|
||||||
|
preview.setAttribute("data-pdf-url", previewUrl)
|
||||||
|
preview.innerHTML = "<div class=\"tour-pdf-lazy-toolbar\">PDF预览加载中...</div>"
|
||||||
|
box.appendChild(preview)
|
||||||
|
return box
|
||||||
|
},
|
||||||
|
buildLinePreviewUrl(href, fileType, file) {
|
||||||
|
if (fileType === "office") {
|
||||||
|
const id = file && file.id ? file.id : this.getFileIdFromUrl(href)
|
||||||
|
return id ? "/platform/sys/file/convertPDF?id=" + id : ""
|
||||||
|
}
|
||||||
|
if (fileType === "pdf") {
|
||||||
|
return file && file.downloadPath ? file.downloadPath : href
|
||||||
|
}
|
||||||
|
return ""
|
||||||
},
|
},
|
||||||
getPdfLib() {
|
getPdfLib() {
|
||||||
return window.pdfjsLib || window["pdfjs-dist/build/pdf"]
|
return window.pdfjsLib || window["pdfjs-dist/build/pdf"]
|
||||||
},
|
},
|
||||||
clearPdfPreview() {
|
initLinePdfPreviews() {
|
||||||
this.pdfRenderToken += 1
|
this.cleanupLinePdfPreviews()
|
||||||
this.pdfDoc = null
|
const pdfLib = this.getPdfLib()
|
||||||
this.pdfLoading = false
|
const previews = Array.prototype.slice.call(document.querySelectorAll(".tour-pdf-lazy-preview"))
|
||||||
this.pdfError = ""
|
if (!previews.length) {
|
||||||
this.pdfPageCount = 0
|
|
||||||
this.pdfRenderedPages = 0
|
|
||||||
if (this.pdfLoadingTask && this.pdfLoadingTask.destroy) {
|
|
||||||
try {
|
|
||||||
this.pdfLoadingTask.destroy()
|
|
||||||
} catch (e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.pdfLoadingTask = null
|
|
||||||
if (this.$refs.pdfPreviewContainer) {
|
|
||||||
this.$refs.pdfPreviewContainer.innerHTML = ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
renderLinePdf() {
|
|
||||||
this.clearPdfPreview()
|
|
||||||
if (!this.lineContentHref) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const pdfLib = this.getPdfLib()
|
|
||||||
if (!pdfLib || !pdfLib.getDocument) {
|
if (!pdfLib || !pdfLib.getDocument) {
|
||||||
this.pdfError = "PDF预览组件加载失败"
|
previews.forEach((el) => {
|
||||||
|
el.innerHTML = "<div class=\"tour-line-file-unpreviewable\">PDF预览组件加载失败</div>"
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (pdfLib.GlobalWorkerOptions) {
|
if (pdfLib.GlobalWorkerOptions) {
|
||||||
pdfLib.GlobalWorkerOptions.workerSrc = "/assets/platform/plugins/pdfJs/h5/pdf.worker.js"
|
pdfLib.GlobalWorkerOptions.workerSrc = "/assets/platform/plugins/pdfJs/h5/pdf.worker.js"
|
||||||
}
|
}
|
||||||
const token = this.pdfRenderToken
|
if (window.IntersectionObserver) {
|
||||||
this.pdfLoading = true
|
this.linePdfObserver = new IntersectionObserver((entries) => {
|
||||||
this.pdfLoadingTask = pdfLib.getDocument({
|
entries.forEach((entry) => {
|
||||||
url: this.lineContentHref,
|
if (!entry.isIntersecting) {
|
||||||
disableAutoFetch: false,
|
return
|
||||||
disableStream: false,
|
}
|
||||||
disableRange: false
|
this.renderLazyPdfPage(entry.target)
|
||||||
})
|
this.linePdfObserver && this.linePdfObserver.unobserve(entry.target)
|
||||||
this.pdfLoadingTask.promise.then((pdf) => {
|
})
|
||||||
if (token !== this.pdfRenderToken) {
|
}, {
|
||||||
return
|
root: null,
|
||||||
}
|
rootMargin: "360px 0px",
|
||||||
this.pdfDoc = pdf
|
threshold: 0.01
|
||||||
this.pdfPageCount = pdf.numPages || 0
|
})
|
||||||
return this.renderPdfPage(1, token)
|
}
|
||||||
}).then(() => {
|
previews.forEach((el) => {
|
||||||
if (token !== this.pdfRenderToken) {
|
this.initLazyPdfPreview(el, pdfLib)
|
||||||
return
|
|
||||||
}
|
|
||||||
this.renderRestPdfPages(2, token)
|
|
||||||
}).catch(() => {
|
|
||||||
if (token !== this.pdfRenderToken) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.pdfLoading = false
|
|
||||||
this.pdfError = "PDF加载失败,请稍后重试"
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
renderPdfPage(pageNumber, token) {
|
initLazyPdfPreview(el, pdfLib) {
|
||||||
if (!this.pdfDoc || token !== this.pdfRenderToken || pageNumber > this.pdfPageCount) {
|
const url = el.getAttribute("data-pdf-url")
|
||||||
return Promise.resolve()
|
if (!url) {
|
||||||
|
el.innerHTML = "<div class=\"tour-line-file-unpreviewable\">当前文件暂不支持预览</div>"
|
||||||
|
return
|
||||||
}
|
}
|
||||||
return this.pdfDoc.getPage(pageNumber).then((page) => {
|
const task = pdfLib.getDocument({
|
||||||
if (token !== this.pdfRenderToken || !this.$refs.pdfPreviewContainer) {
|
url: url,
|
||||||
return
|
disableAutoFetch: true,
|
||||||
|
disableStream: true,
|
||||||
|
disableRange: false
|
||||||
|
})
|
||||||
|
const state = {
|
||||||
|
el: el,
|
||||||
|
doc: null,
|
||||||
|
task: task,
|
||||||
|
rendered: {},
|
||||||
|
rendering: {}
|
||||||
|
}
|
||||||
|
this.linePdfPreviews.push(state)
|
||||||
|
task.promise.then((pdf) => {
|
||||||
|
state.doc = pdf
|
||||||
|
const count = pdf.numPages || 0
|
||||||
|
const toolbar = el.querySelector(".tour-pdf-lazy-toolbar")
|
||||||
|
if (toolbar) {
|
||||||
|
toolbar.textContent = "PDF预览:共 " + count + " 页,已优先加载第 1 页"
|
||||||
}
|
}
|
||||||
const container = this.$refs.pdfPreviewContainer
|
for (let i = 1; i <= count; i++) {
|
||||||
|
const page = document.createElement("div")
|
||||||
|
page.className = "tour-pdf-page-placeholder"
|
||||||
|
page.setAttribute("data-page-number", i)
|
||||||
|
page.textContent = i === 1 ? "正在加载第 1 页..." : "第 " + i + " 页,滚动到此处加载"
|
||||||
|
el.appendChild(page)
|
||||||
|
}
|
||||||
|
const firstPage = el.querySelector("[data-page-number='1']")
|
||||||
|
if (firstPage) {
|
||||||
|
this.renderLazyPdfPage(firstPage)
|
||||||
|
}
|
||||||
|
Array.prototype.slice.call(el.querySelectorAll(".tour-pdf-page-placeholder")).forEach((page) => {
|
||||||
|
if (page.getAttribute("data-page-number") !== "1" && this.linePdfObserver) {
|
||||||
|
this.linePdfObserver.observe(page)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).catch(() => {
|
||||||
|
el.innerHTML = "<div class=\"tour-line-file-unpreviewable\">PDF加载失败,请稍后重试</div>"
|
||||||
|
})
|
||||||
|
},
|
||||||
|
renderLazyPdfPage(pageEl) {
|
||||||
|
const previewEl = pageEl.closest(".tour-pdf-lazy-preview")
|
||||||
|
const state = this.linePdfPreviews.find((item) => item.el === previewEl)
|
||||||
|
if (!state || !state.doc) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const pageNumber = Number(pageEl.getAttribute("data-page-number") || 0)
|
||||||
|
if (!pageNumber || state.rendered[pageNumber] || state.rendering[pageNumber]) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
state.rendering[pageNumber] = true
|
||||||
|
pageEl.textContent = "正在加载第 " + pageNumber + " 页..."
|
||||||
|
state.doc.getPage(pageNumber).then((page) => {
|
||||||
|
const containerWidth = Math.max(previewEl.clientWidth - 16, 260)
|
||||||
const baseViewport = page.getViewport({scale: 1})
|
const baseViewport = page.getViewport({scale: 1})
|
||||||
const containerWidth = Math.max(container.clientWidth || 0, window.innerWidth - 44)
|
|
||||||
const cssScale = containerWidth / baseViewport.width
|
const cssScale = containerWidth / baseViewport.width
|
||||||
const outputScale = Math.min(window.devicePixelRatio || 1, 2)
|
const outputScale = Math.min(window.devicePixelRatio || 1, 2)
|
||||||
const viewport = page.getViewport({scale: cssScale})
|
const viewport = page.getViewport({scale: cssScale})
|
||||||
const pageEl = document.createElement("div")
|
|
||||||
pageEl.className = "tour-pdf-page"
|
|
||||||
const canvas = document.createElement("canvas")
|
const canvas = document.createElement("canvas")
|
||||||
const context = canvas.getContext("2d")
|
const context = canvas.getContext("2d")
|
||||||
canvas.width = Math.floor(viewport.width * outputScale)
|
canvas.width = Math.floor(viewport.width * outputScale)
|
||||||
canvas.height = Math.floor(viewport.height * outputScale)
|
canvas.height = Math.floor(viewport.height * outputScale)
|
||||||
canvas.style.width = Math.floor(viewport.width) + "px"
|
canvas.style.width = Math.floor(viewport.width) + "px"
|
||||||
canvas.style.height = Math.floor(viewport.height) + "px"
|
canvas.style.height = Math.floor(viewport.height) + "px"
|
||||||
|
pageEl.innerHTML = ""
|
||||||
pageEl.appendChild(canvas)
|
pageEl.appendChild(canvas)
|
||||||
container.appendChild(pageEl)
|
return page.render({
|
||||||
const renderContext = {
|
|
||||||
canvasContext: context,
|
canvasContext: context,
|
||||||
viewport: viewport,
|
viewport: viewport,
|
||||||
transform: outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null
|
transform: outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null
|
||||||
}
|
}).promise.then(() => {
|
||||||
return page.render(renderContext).promise.then(() => {
|
state.rendered[pageNumber] = true
|
||||||
if (token === this.pdfRenderToken) {
|
state.rendering[pageNumber] = false
|
||||||
this.pdfRenderedPages = Math.max(this.pdfRenderedPages, pageNumber)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
}).catch(() => {
|
||||||
|
state.rendering[pageNumber] = false
|
||||||
|
pageEl.textContent = "第 " + pageNumber + " 页加载失败"
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
renderRestPdfPages(pageNumber, token) {
|
cleanupLinePdfPreviews() {
|
||||||
if (token !== this.pdfRenderToken || !this.pdfDoc || pageNumber > this.pdfPageCount) {
|
if (this.linePdfObserver) {
|
||||||
this.pdfLoading = false
|
this.linePdfObserver.disconnect()
|
||||||
return
|
this.linePdfObserver = null
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
this.linePdfPreviews.forEach((item) => {
|
||||||
this.renderPdfPage(pageNumber, token).then(() => {
|
if (item.task && item.task.destroy) {
|
||||||
this.renderRestPdfPages(pageNumber + 1, token)
|
try {
|
||||||
}).catch(() => {
|
item.task.destroy()
|
||||||
if (token === this.pdfRenderToken) {
|
} catch (e) {
|
||||||
this.pdfLoading = false
|
|
||||||
this.pdfError = "部分页面加载失败"
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}, 120)
|
})
|
||||||
|
this.linePdfPreviews = []
|
||||||
|
},
|
||||||
|
getFileIdFromUrl(href) {
|
||||||
|
if (!href) return ""
|
||||||
|
const idMatch = href.match(/[?&]id=([^&#]+)/)
|
||||||
|
if (idMatch) {
|
||||||
|
return decodeURIComponent(idMatch[1])
|
||||||
|
}
|
||||||
|
return ""
|
||||||
},
|
},
|
||||||
loadDetail() {
|
loadDetail() {
|
||||||
if (!this.matterId || !this.lineId) {
|
if (!this.matterId || !this.lineId) {
|
||||||
@@ -470,9 +875,12 @@ layout("/layouts/platform_h5.html"){
|
|||||||
vant.Toast(lineRes.msg || "线路详情加载失败")
|
vant.Toast(lineRes.msg || "线路详情加载失败")
|
||||||
} else {
|
} else {
|
||||||
this.lineDetail = lineRes.data || {}
|
this.lineDetail = lineRes.data || {}
|
||||||
this.lineContentHref = this.parseLineContentHref(this.lineDetail.lineContent)
|
this.lineContentHtml = ""
|
||||||
this.$nextTick(() => {
|
this.buildLineContentHtmlAsync(this.lineDetail.lineContent).then((html) => {
|
||||||
this.renderLinePdf()
|
this.lineContentHtml = html
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.initLinePdfPreviews()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (signupRes.code !== 0) {
|
if (signupRes.code !== 0) {
|
||||||
@@ -489,20 +897,27 @@ layout("/layouts/platform_h5.html"){
|
|||||||
vant.Toast("线路详情加载失败")
|
vant.Toast("线路详情加载失败")
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
onApply() {
|
onApply(skipNotice) {
|
||||||
if (!this.matterId) {
|
if (!this.matterId) {
|
||||||
vant.Toast("报名事项信息不完整")
|
vant.Toast("报名事项信息不完整")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const goApply = () => {
|
const goApply = () => {
|
||||||
window.location.href = "/platform/tour/signup/h5/apply?matterId=" + encodeURIComponent(this.matterId)
|
window.location.href = "/platform/tour/signup/h5/apply?matterId=" + encodeURIComponent(this.matterId) + "¬iceChecked=1"
|
||||||
}
|
}
|
||||||
|
if (skipNotice) {
|
||||||
|
goApply()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.applyLoading = true
|
||||||
this.$axios.post("/platform/tour/signup/signupEligibilityNotice", { matterId: this.matterId }).then((res) => {
|
this.$axios.post("/platform/tour/signup/signupEligibilityNotice", { matterId: this.matterId }).then((res) => {
|
||||||
if (res.code !== 0) {
|
if (res.code !== 0) {
|
||||||
vant.Dialog.alert({
|
vant.Dialog.alert({
|
||||||
title: "温馨提醒",
|
title: "温馨提醒",
|
||||||
message: res.msg || "当前不能报名",
|
message: res.msg || "当前不能报名",
|
||||||
confirmButtonColor: "#1867b0"
|
confirmButtonColor: "#1867b0"
|
||||||
|
}).then(() => {
|
||||||
|
this.applyLoading = false
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -518,14 +933,20 @@ layout("/layouts/platform_h5.html"){
|
|||||||
confirmButtonText: "继续报名",
|
confirmButtonText: "继续报名",
|
||||||
cancelButtonText: "稍后报名",
|
cancelButtonText: "稍后报名",
|
||||||
confirmButtonColor: "#1867b0"
|
confirmButtonColor: "#1867b0"
|
||||||
}).then(goApply).catch(() => {})
|
}).then(goApply).catch(() => {
|
||||||
|
this.applyLoading = false
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
vant.Dialog.alert({
|
vant.Dialog.alert({
|
||||||
title: "温馨提醒",
|
title: "温馨提醒",
|
||||||
message: data.message || "当前不能报名",
|
message: data.message || "当前不能报名",
|
||||||
confirmButtonColor: "#1867b0"
|
confirmButtonColor: "#1867b0"
|
||||||
|
}).then(() => {
|
||||||
|
this.applyLoading = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
this.applyLoading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
revokeSignup() {
|
revokeSignup() {
|
||||||
@@ -549,7 +970,7 @@ layout("/layouts/platform_h5.html"){
|
|||||||
this.loadDetail()
|
this.loadDetail()
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.clearPdfPreview()
|
this.cleanupLinePdfPreviews()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -476,9 +476,9 @@ layout("/layouts/platform_h5.html"){
|
|||||||
'tour-line-action--danger': canRevokeSignup(row),
|
'tour-line-action--danger': canRevokeSignup(row),
|
||||||
'tour-line-action--disabled': signupActionDisabled(row)
|
'tour-line-action--disabled': signupActionDisabled(row)
|
||||||
}"
|
}"
|
||||||
:disabled="signupActionDisabled(row)"
|
:disabled="signupActionDisabled(row) || signupCheckingMatterId === row.matterId"
|
||||||
@click.stop="handleSignupAction(row)">
|
@click.stop="handleSignupAction(row)">
|
||||||
{{ signupActionText(row) }}
|
{{ signupCheckingMatterId === row.matterId ? '进入中...' : signupActionText(row) }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -520,17 +520,18 @@ layout("/layouts/platform_h5.html"){
|
|||||||
loading: false,
|
loading: false,
|
||||||
finished: false,
|
finished: false,
|
||||||
lineChecking: false,
|
lineChecking: false,
|
||||||
|
signupCheckingMatterId: "",
|
||||||
showUnionPopup: false,
|
showUnionPopup: false,
|
||||||
unionList: [
|
unionList: [
|
||||||
{id: "", name: "全部分工会"}
|
{id: "", name: "全部分工会"}
|
||||||
],
|
],
|
||||||
pageForm: {
|
pageForm: {
|
||||||
pageNumber: 1,
|
pageNumber: 1,
|
||||||
pageSize: 10,
|
pageSize: 5,
|
||||||
totalCount: 0,
|
totalCount: 0,
|
||||||
year: new Date().getFullYear(),
|
year: new Date().getFullYear(),
|
||||||
lineName: "",
|
lineName: "",
|
||||||
lineType: "",
|
lineType: "省内线路",
|
||||||
unionId: "",
|
unionId: "",
|
||||||
directFamilyUnitLine: null,
|
directFamilyUnitLine: null,
|
||||||
pageOrderName: "lineName",
|
pageOrderName: "lineName",
|
||||||
@@ -604,22 +605,34 @@ layout("/layouts/platform_h5.html"){
|
|||||||
this.revokeSignup(row)
|
this.revokeSignup(row)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (this.isSigned(row)) {
|
||||||
|
this.goApply(row, true)
|
||||||
|
return
|
||||||
|
}
|
||||||
this.goApply(row)
|
this.goApply(row)
|
||||||
},
|
},
|
||||||
goApply(row) {
|
goApply(row, skipNotice) {
|
||||||
if (!row || !row.matterId) {
|
if (!row || !row.matterId) {
|
||||||
vant.Toast("报名事项信息不完整")
|
vant.Toast("报名事项信息不完整")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const go = () => {
|
const go = () => {
|
||||||
window.location.href = "/platform/tour/signup/h5/apply?matterId=" + encodeURIComponent(row.matterId)
|
window.location.href = "/platform/tour/signup/h5/apply?matterId=" + encodeURIComponent(row.matterId) + "¬iceChecked=1"
|
||||||
}
|
}
|
||||||
|
if (skipNotice) {
|
||||||
|
this.signupCheckingMatterId = row.matterId
|
||||||
|
go()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.signupCheckingMatterId = row.matterId
|
||||||
this.$axios.post("/platform/tour/signup/signupEligibilityNotice", { matterId: row.matterId }).then((res) => {
|
this.$axios.post("/platform/tour/signup/signupEligibilityNotice", { matterId: row.matterId }).then((res) => {
|
||||||
if (res.code !== 0) {
|
if (res.code !== 0) {
|
||||||
vant.Dialog.alert({
|
vant.Dialog.alert({
|
||||||
title: "温馨提醒",
|
title: "温馨提醒",
|
||||||
message: res.msg || "当前不能报名",
|
message: res.msg || "当前不能报名",
|
||||||
confirmButtonColor: "#1867b0"
|
confirmButtonColor: "#1867b0"
|
||||||
|
}).then(() => {
|
||||||
|
this.signupCheckingMatterId = ""
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -635,14 +648,20 @@ layout("/layouts/platform_h5.html"){
|
|||||||
confirmButtonText: "继续报名",
|
confirmButtonText: "继续报名",
|
||||||
cancelButtonText: "稍后报名",
|
cancelButtonText: "稍后报名",
|
||||||
confirmButtonColor: "#1867b0"
|
confirmButtonColor: "#1867b0"
|
||||||
}).then(go).catch(() => {})
|
}).then(go).catch(() => {
|
||||||
|
this.signupCheckingMatterId = ""
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
vant.Dialog.alert({
|
vant.Dialog.alert({
|
||||||
title: "温馨提醒",
|
title: "温馨提醒",
|
||||||
message: data.message || "当前不能报名",
|
message: data.message || "当前不能报名",
|
||||||
confirmButtonColor: "#1867b0"
|
confirmButtonColor: "#1867b0"
|
||||||
|
}).then(() => {
|
||||||
|
this.signupCheckingMatterId = ""
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
this.signupCheckingMatterId = ""
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
revokeSignup(row) {
|
revokeSignup(row) {
|
||||||
|
|||||||
+3
-2
@@ -203,6 +203,7 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<van-cell title="姓名" :value="detail.userName || ''"></van-cell>
|
<van-cell title="姓名" :value="detail.userName || ''"></van-cell>
|
||||||
<van-cell title="性别" :value="detail.gender || ''"></van-cell>
|
<van-cell title="性别" :value="detail.gender || ''"></van-cell>
|
||||||
<van-cell title="身份证号" :value="detail.idCard || ''"></van-cell>
|
<van-cell title="身份证号" :value="detail.idCard || ''"></van-cell>
|
||||||
|
<van-cell title="手机号" :value="detail.mobile || ''"></van-cell>
|
||||||
<van-cell title="所在单位" :value="detail.unitName || ''"></van-cell>
|
<van-cell title="所在单位" :value="detail.unitName || ''"></van-cell>
|
||||||
<van-cell title="所在工会" :value="detail.unionName || ''"></van-cell>
|
<van-cell title="所在工会" :value="detail.unionName || ''"></van-cell>
|
||||||
</div>
|
</div>
|
||||||
@@ -213,8 +214,8 @@ layout("/layouts/platform_h5.html"){
|
|||||||
<van-cell title="线路类型" :value="detail.lineType || ''"></van-cell>
|
<van-cell title="线路类型" :value="detail.lineType || ''"></van-cell>
|
||||||
<van-cell title="出行时段" :value="detail.travelPeriod || ''"></van-cell>
|
<van-cell title="出行时段" :value="detail.travelPeriod || ''"></van-cell>
|
||||||
<van-cell title="报名时间" :value="detail.signupTime || ''"></van-cell>
|
<van-cell title="报名时间" :value="detail.signupTime || ''"></van-cell>
|
||||||
<van-cell title="报名酒店" :value="detail.hotelName || ''"></van-cell>
|
<van-cell v-if="false" title="报名酒店" :value="detail.hotelName || ''"></van-cell>
|
||||||
<van-cell title="旅行社" :value="detail.travelAgencyName || ''"></van-cell>
|
<van-cell v-if="false" title="旅行社" :value="detail.travelAgencyName || ''"></van-cell>
|
||||||
<van-cell v-if="fillBedInfo" title="床型" :value="detail.bedType || ''"></van-cell>
|
<van-cell v-if="fillBedInfo" title="床型" :value="detail.bedType || ''"></van-cell>
|
||||||
<van-cell v-if="fillBedInfo" title="床位信息" :value="detail.bedInfo || ''"></van-cell>
|
<van-cell v-if="fillBedInfo" title="床位信息" :value="detail.bedInfo || ''"></van-cell>
|
||||||
<van-cell v-if="fillBedInfo" title="意向拼床人" :value="detail.intendedRoommate || ''"></van-cell>
|
<van-cell v-if="fillBedInfo" title="意向拼床人" :value="detail.intendedRoommate || ''"></van-cell>
|
||||||
|
|||||||
Reference in New Issue
Block a user