feat: 普惠疗休养优化4
This commit is contained in:
@@ -53,3 +53,4 @@ outputs
|
||||
|
||||
semgrep.json
|
||||
trivy.json
|
||||
.workbuddy
|
||||
+82
-13
@@ -1,5 +1,13 @@
|
||||
package com.budwk.app.zhgh.staffbenefit.therapyRecuperation.controller.statistics;
|
||||
|
||||
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
||||
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
||||
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||
import com.budwk.app.zhgh.staffbenefit.therapyRecuperation.support.TherapyDownload;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.result.Result;
|
||||
@@ -186,10 +194,27 @@ public class TheRapyRecuperationLineStatisticsController {
|
||||
@Param(value = "selectId") String selectId,
|
||||
@Param(value = "playMonth") String playMonth,
|
||||
@Param(value = "regionalNature") String regionalNature,
|
||||
@Param(value = "travelAgencyId") String travelAgencyId) {
|
||||
Sql sql = Sqls.create("""
|
||||
@Param(value = "travelAgencyId") String travelAgencyId,
|
||||
@Param(value = "groupStatus") Integer groupStatus) {
|
||||
List<Sql> queries = buildStatisticsQueries(startYear, endYear, unionId, takePartInLineId, lotId,
|
||||
signUpMode, selectId, playMonth, regionalNature, travelAgencyId, groupStatus);
|
||||
return enrollService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), queries.get(0), queries.get(1));
|
||||
}
|
||||
|
||||
private List<Sql> buildStatisticsQueries(Integer startYear, Integer endYear, String unionId,
|
||||
String takePartInLineId, String lotId, String signUpMode,
|
||||
String selectId, String playMonth, String regionalNature,
|
||||
String travelAgencyId, Integer groupStatus) {
|
||||
if (startYear != null && endYear != null && startYear > endYear) {
|
||||
throw new IllegalArgumentException("开始年度不能大于结束年度");
|
||||
}
|
||||
String groupedCondition = "IFNULL(lineu.estimatedFamilyNumbers, 0) > 0 AND "
|
||||
+ "IFNULL(enrollStats.lineNum, 0) + IFNULL(enrollStats.adultFamilyNum, 0) >= lineu.estimatedFamilyNumbers";
|
||||
String query = """
|
||||
SELECT
|
||||
line.id,
|
||||
$groupStatus AS groupStatusName,
|
||||
IFNULL(enrollStats.lineNum, 0) + IFNULL(enrollStats.adultFamilyNum, 0) AS groupCount,
|
||||
line.lineName,
|
||||
line.regionalNature,
|
||||
lineu.lineId,
|
||||
@@ -241,16 +266,12 @@ public class TheRapyRecuperationLineStatisticsController {
|
||||
) enrollStats ON enrollStats.takePartInLineId = lineu.id
|
||||
$condition
|
||||
ORDER BY line.serialNumber ASC, lineu.playStartTime ASC
|
||||
""");
|
||||
Sql countSql = Sqls.create("""
|
||||
SELECT
|
||||
COUNT(1)
|
||||
FROM
|
||||
inclusive_therapy_v3_line_union_select lineu
|
||||
LEFT JOIN inclusive_therapy_v3_line line ON line.id = lineu.lineId
|
||||
LEFT JOIN inclusive_therapy_v3_lot lot ON lot.id = line.lotId
|
||||
$condition
|
||||
""");
|
||||
""";
|
||||
Sql sql = Sqls.create(query);
|
||||
Sql countSql = Sqls.create("SELECT COUNT(1) FROM (" + query.substring(0, query.indexOf("ORDER BY")) + ") statistics");
|
||||
String groupStatusExpression = "CASE WHEN " + groupedCondition + " THEN '成团' ELSE '未成团' END";
|
||||
sql.setVar("groupStatus", groupStatusExpression);
|
||||
countSql.setVar("groupStatus", groupStatusExpression);
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if (startYear != null) {
|
||||
cnd.and("lineu.selectTime", ">=", startYear + "-01-01 00:00:00");
|
||||
@@ -260,9 +281,11 @@ public class TheRapyRecuperationLineStatisticsController {
|
||||
}
|
||||
cnd.andEX("lineu.signUpMode", "=", signUpMode);
|
||||
sql.setVar("unionCnd", "");
|
||||
countSql.setVar("unionCnd", "");
|
||||
if (!TherapyContext.hasAnyRoles("sysadmin,H06")) {
|
||||
String unionCndSql = "and (e.selfUnionId='%s' or e.takePartInUnionId = '%s')".formatted(TherapyContext.getUnionId(), TherapyContext.getUnionId());
|
||||
sql.setVar("unionCnd", unionCndSql);
|
||||
countSql.setVar("unionCnd", unionCndSql);
|
||||
cnd.and("lineu.unionId", "=", TherapyContext.getUnionId());
|
||||
} else {
|
||||
if (Strings.isNotBlank(unionId)) {
|
||||
@@ -282,9 +305,55 @@ public class TheRapyRecuperationLineStatisticsController {
|
||||
}
|
||||
cnd.andEX("line.regionalNature", "=", regionalNature);
|
||||
addTravelAgencyCondition(cnd, travelAgencyId);
|
||||
if (groupStatus != null && (groupStatus == 1 || groupStatus == 2)) {
|
||||
cnd.and("(" + groupedCondition + ")", "=", groupStatus == 1 ? 1 : 0);
|
||||
}
|
||||
sql.setCondition(cnd);
|
||||
countSql.setCondition(cnd);
|
||||
return enrollService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql, countSql);
|
||||
return Arrays.asList(sql, countSql);
|
||||
}
|
||||
|
||||
@At("/exportList")
|
||||
@Ok("void")
|
||||
@SaCheckPermission("inclusiveTherapyV3.statistics")
|
||||
public void exportList(@Param("startYear") Integer startYear,
|
||||
@Param("endYear") Integer endYear,
|
||||
@Param("unionId") String unionId,
|
||||
@Param("takePartInLineId") String takePartInLineId,
|
||||
@Param("lotId") String lotId,
|
||||
@Param("signUpMode") String signUpMode,
|
||||
@Param("selectId") String selectId,
|
||||
@Param("playMonth") String playMonth,
|
||||
@Param("regionalNature") String regionalNature,
|
||||
@Param("travelAgencyId") String travelAgencyId,
|
||||
@Param("groupStatus") Integer groupStatus,
|
||||
HttpServletResponse response) throws IOException {
|
||||
List<Sql> queries = buildStatisticsQueries(startYear, endYear, unionId, takePartInLineId, lotId,
|
||||
signUpMode, selectId, playMonth, regionalNature, travelAgencyId, groupStatus);
|
||||
List<NutMap> rows = enrollService.listMap(queries.get(0));
|
||||
List<ExcelExportEntity> columns = new ArrayList<>();
|
||||
columns.add(new ExcelExportEntity("年度", "year", 12));
|
||||
columns.add(new ExcelExportEntity("线路名称", "lineName", 35));
|
||||
columns.add(new ExcelExportEntity("选择线路工会", "unionname", 25));
|
||||
columns.add(new ExcelExportEntity("出行时间", "linePlayTime", 20));
|
||||
columns.add(new ExcelExportEntity("报名时间", "signUpTime", 20));
|
||||
columns.add(new ExcelExportEntity("调剂报名截止时间", "adjustSignUpEndTime", 22));
|
||||
columns.add(new ExcelExportEntity("承担旅行社", "travelAgencyName", 25));
|
||||
columns.add(new ExcelExportEntity("线路类型", "regionalNature", 12));
|
||||
columns.add(new ExcelExportEntity("联系人", "contact", 15));
|
||||
columns.add(new ExcelExportEntity("联系方式", "contactMobileNumber", 20));
|
||||
columns.add(new ExcelExportEntity("最少成团人数", "estimatedFamilyNumbers", 16));
|
||||
columns.add(new ExcelExportEntity("成团计入人数", "groupCount", 16));
|
||||
columns.add(new ExcelExportEntity("教职工报名人数", "lineNum", 18));
|
||||
columns.add(new ExcelExportEntity("家属总人数", "signUpUserFamilyNum", 16));
|
||||
columns.add(new ExcelExportEntity("成年家属人数", "adultFamilyNum", 16));
|
||||
columns.add(new ExcelExportEntity("成团状态", "groupStatusName", 12));
|
||||
TherapyDownload.excelResponse(response, "疗休养线路统计.xlsx");
|
||||
ExportParams params = new ExportParams();
|
||||
params.setType(ExcelType.XSSF);
|
||||
try (Workbook workbook = ExcelExportUtil.exportExcel(params, columns, rows)) {
|
||||
workbook.write(response.getOutputStream());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
-9
@@ -231,15 +231,6 @@ layout("/layouts/platform.html"){
|
||||
|
||||
</template>
|
||||
<el-button icon="el-icon-refresh" @click="doSearch" circle></el-button>
|
||||
<el-dropdown @command="tableSizeChange">
|
||||
<el-button icon="el-icon-c-scale-to-original" circle></el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="mini">Mini</el-dropdown-item>
|
||||
<el-dropdown-item command="small">Small</el-dropdown-item>
|
||||
<el-dropdown-item command="medium">Medium</el-dropdown-item>
|
||||
<el-dropdown-item command="">Large</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" style="width: 100%"
|
||||
row-key="id" @sort-change="pageOrder"
|
||||
|
||||
-9
@@ -159,15 +159,6 @@ layout("/layouts/platform.html"){
|
||||
|
||||
</template>
|
||||
<el-button icon="el-icon-refresh" @click="doSearch" circle></el-button>
|
||||
<el-dropdown @command="tableSizeChange">
|
||||
<el-button icon="el-icon-c-scale-to-original" circle></el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="mini">Mini</el-dropdown-item>
|
||||
<el-dropdown-item command="small">Small</el-dropdown-item>
|
||||
<el-dropdown-item command="medium">Medium</el-dropdown-item>
|
||||
<el-dropdown-item command="">Large</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" style="width: 100%"
|
||||
row-key="id" @sort-change="pageOrder"
|
||||
|
||||
-9
@@ -224,15 +224,6 @@ layout("/layouts/platform.html"){
|
||||
</el-radio-group>
|
||||
</template>
|
||||
<el-button icon="el-icon-refresh" @click="doSearch" circle></el-button>
|
||||
<el-dropdown @command="tableSizeChange">
|
||||
<el-button icon="el-icon-c-scale-to-original" circle></el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="mini">Mini</el-dropdown-item>
|
||||
<el-dropdown-item command="small">Small</el-dropdown-item>
|
||||
<el-dropdown-item command="medium">Medium</el-dropdown-item>
|
||||
<el-dropdown-item command="">Large</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" style="width: 100%"
|
||||
row-key="id" @sort-change="pageOrder"
|
||||
|
||||
-9
@@ -82,15 +82,6 @@ layout("/layouts/platform.html"){
|
||||
<el-button @click="openAdd" size="medium" type="primary">新建目的地</el-button>
|
||||
</template>
|
||||
<el-button icon="el-icon-refresh" @click="doSearch" circle></el-button>
|
||||
<el-dropdown @command="tableSizeChange">
|
||||
<el-button icon="el-icon-c-scale-to-original" circle></el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="mini">Mini</el-dropdown-item>
|
||||
<el-dropdown-item command="small">Small</el-dropdown-item>
|
||||
<el-dropdown-item command="medium">Medium</el-dropdown-item>
|
||||
<el-dropdown-item command="">Large</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder"
|
||||
align="center"
|
||||
|
||||
-9
@@ -172,15 +172,6 @@ layout("/layouts/platform.html"){
|
||||
<el-button @click="openAdd" size="medium" type="primary">新建线路</el-button>
|
||||
</template>
|
||||
<el-button icon="el-icon-refresh" @click="doSearch" circle></el-button>
|
||||
<el-dropdown @command="tableSizeChange">
|
||||
<el-button icon="el-icon-c-scale-to-original" circle></el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="mini">Mini</el-dropdown-item>
|
||||
<el-dropdown-item command="small">Small</el-dropdown-item>
|
||||
<el-dropdown-item command="medium">Medium</el-dropdown-item>
|
||||
<el-dropdown-item command="">Large</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder"
|
||||
align="center"
|
||||
|
||||
-9
@@ -54,15 +54,6 @@ layout("/layouts/platform.html"){
|
||||
<el-button @click="openAdd" size="medium" type="primary">新建旅行社</el-button>
|
||||
</template>
|
||||
<el-button icon="el-icon-refresh" @click="doSearch" circle></el-button>
|
||||
<el-dropdown @command="tableSizeChange">
|
||||
<el-button icon="el-icon-c-scale-to-original" circle></el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="mini">Mini</el-dropdown-item>
|
||||
<el-dropdown-item command="small">Small</el-dropdown-item>
|
||||
<el-dropdown-item command="medium">Medium</el-dropdown-item>
|
||||
<el-dropdown-item command="">Large</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" :size="tableSize">
|
||||
<el-table-column :index="indexMethod" align="center" header-align="center" label="序号" type="index"
|
||||
|
||||
-10
@@ -343,7 +343,6 @@ layout("/layouts/platform.html"){
|
||||
</el-select>
|
||||
<template slot="append">
|
||||
<el-button @click="doSearch">搜索</el-button>
|
||||
<el-button @click="resetSearch" icon="el-icon-refresh-left">重置</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-col>
|
||||
@@ -617,15 +616,6 @@ layout("/layouts/platform.html"){
|
||||
</el-radio-group>
|
||||
</template>
|
||||
<el-button icon="el-icon-refresh" @click="doSearch" circle></el-button>
|
||||
<el-dropdown @command="tableSizeChange">
|
||||
<el-button icon="el-icon-c-scale-to-original" circle></el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="mini">Mini</el-dropdown-item>
|
||||
<el-dropdown-item command="small">Small</el-dropdown-item>
|
||||
<el-dropdown-item command="medium">Medium</el-dropdown-item>
|
||||
<el-dropdown-item command="">Large</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</table-tool>
|
||||
|
||||
<el-table :key="pageForm.state + '-' + pageForm.lb" :data="tableData" style="width: 100%"
|
||||
|
||||
+16
-27
@@ -17,6 +17,13 @@ layout("/layouts/platform.html"){
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.query-row .query-row-content > .el-row > .el-col > span:first-child {
|
||||
display: inline-block;
|
||||
width: 5em;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.query-row:not(:last-child) {
|
||||
border-bottom: 1px dashed rgb(230, 230, 230);
|
||||
}
|
||||
@@ -42,23 +49,15 @@ layout("/layouts/platform.html"){
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<span>年  度:</span>
|
||||
<el-date-picker
|
||||
:clearable="false"
|
||||
v-model="pageForm.startYear"
|
||||
type="year"
|
||||
value-format="yyyy"
|
||||
placeholder="选择年"
|
||||
style="width: 38%" @change="yearChange">
|
||||
</el-date-picker>
|
||||
<span>至</span>
|
||||
<el-date-picker
|
||||
:clearable="false"
|
||||
v-model="pageForm.endYear"
|
||||
type="year"
|
||||
value-format="yyyy"
|
||||
placeholder="选择年"
|
||||
style="width: 38%" @change="yearChange">
|
||||
</el-date-picker>
|
||||
<div style="display: inline-flex; align-items: center; gap: 8px; vertical-align: middle; min-width: 0; width: 80%;">
|
||||
<el-date-picker v-model="pageForm.startYear" type="year" format="yyyy年" value-format="yyyy" :clearable="false"
|
||||
placeholder="开始年度" :picker-options="{disabledDate: date => !!pageForm.endYear && date.getFullYear() > Number(pageForm.endYear)}"
|
||||
@change="yearChange" style="flex: 1; width: 0; min-width: 0"></el-date-picker>
|
||||
<span>至</span>
|
||||
<el-date-picker v-model="pageForm.endYear" type="year" format="yyyy年" value-format="yyyy" :clearable="false"
|
||||
placeholder="结束年度" :picker-options="{disabledDate: date => !!pageForm.startYear && date.getFullYear() < Number(pageForm.startYear)}"
|
||||
@change="yearChange" style="flex: 1; width: 0; min-width: 0"></el-date-picker>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<span>查询类型:</span>
|
||||
@@ -73,7 +72,6 @@ layout("/layouts/platform.html"){
|
||||
</el-select>
|
||||
<template slot="append">
|
||||
<el-button @click="doSearch">搜索</el-button>
|
||||
<el-button @click="resetSearch" icon="el-icon-refresh-left">重置</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-col>
|
||||
@@ -246,15 +244,6 @@ layout("/layouts/platform.html"){
|
||||
|
||||
</template>
|
||||
<el-button icon="el-icon-refresh" @click="doSearch" circle></el-button>
|
||||
<el-dropdown @command="tableSizeChange">
|
||||
<el-button icon="el-icon-c-scale-to-original" circle></el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="mini">Mini</el-dropdown-item>
|
||||
<el-dropdown-item command="small">Small</el-dropdown-item>
|
||||
<el-dropdown-item command="medium">Medium</el-dropdown-item>
|
||||
<el-dropdown-item command="">Large</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</table-tool>
|
||||
|
||||
<el-table :data="tableData" style="width: 100%"
|
||||
|
||||
-9
@@ -115,15 +115,6 @@ layout("/layouts/platform.html"){
|
||||
|
||||
</template>
|
||||
<el-button icon="el-icon-refresh" @click="doSearch" circle></el-button>
|
||||
<el-dropdown @command="tableSizeChange">
|
||||
<el-button icon="el-icon-c-scale-to-original" circle></el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="mini">Mini</el-dropdown-item>
|
||||
<el-dropdown-item command="small">Small</el-dropdown-item>
|
||||
<el-dropdown-item command="medium">Medium</el-dropdown-item>
|
||||
<el-dropdown-item command="">Large</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder"
|
||||
align="center"
|
||||
|
||||
-9
@@ -100,15 +100,6 @@ layout("/layouts/platform.html"){
|
||||
|
||||
</template>
|
||||
<el-button icon="el-icon-refresh" @click="doSearch" circle></el-button>
|
||||
<el-dropdown @command="tableSizeChange">
|
||||
<el-button icon="el-icon-c-scale-to-original" circle></el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="mini">Mini</el-dropdown-item>
|
||||
<el-dropdown-item command="small">Small</el-dropdown-item>
|
||||
<el-dropdown-item command="medium">Medium</el-dropdown-item>
|
||||
<el-dropdown-item command="">Large</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder"
|
||||
align="center"
|
||||
|
||||
-9
@@ -110,15 +110,6 @@ layout("/layouts/platform.html"){
|
||||
<el-button @click="doExportExcel" icon="el-icon-download" size="small" type="primary">导出表格</el-button>
|
||||
</template>
|
||||
<el-button icon="el-icon-refresh" @click="doSearch" circle></el-button>
|
||||
<el-dropdown @command="tableSizeChange">
|
||||
<el-button icon="el-icon-c-scale-to-original" circle></el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="mini">Mini</el-dropdown-item>
|
||||
<el-dropdown-item command="small">Small</el-dropdown-item>
|
||||
<el-dropdown-item command="medium">Medium</el-dropdown-item>
|
||||
<el-dropdown-item command="">Large</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</table-tool>
|
||||
<el-table :data="tableData"
|
||||
:size="tableSize"
|
||||
|
||||
-9
@@ -203,15 +203,6 @@ layout("/layouts/platform.html"){
|
||||
</el-radio-group>
|
||||
</template>
|
||||
<el-button icon="el-icon-refresh" @click="doSearch" circle></el-button>
|
||||
<el-dropdown @command="tableSizeChange">
|
||||
<el-button icon="el-icon-c-scale-to-original" circle></el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="mini">Mini</el-dropdown-item>
|
||||
<el-dropdown-item command="small">Small</el-dropdown-item>
|
||||
<el-dropdown-item command="medium">Medium</el-dropdown-item>
|
||||
<el-dropdown-item command="">Large</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder"
|
||||
ref="table"
|
||||
|
||||
+153
-155
@@ -3,24 +3,15 @@ layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<!--#include("/platform/zhgh/staffbenefit/therapyRecuperation/common.html"){}#-->
|
||||
<style>
|
||||
.query-row {
|
||||
height: 70px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.query-row .el-col {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.query-row:not(:last-child) {
|
||||
border-bottom: 1px dashed rgb(230, 230, 230);
|
||||
}
|
||||
|
||||
.query-row-title {
|
||||
width: 120px;
|
||||
.statistics-filter-row + .statistics-filter-row { margin-top: 18px; }
|
||||
.statistics-filter-item { display: flex; align-items: center; min-width: 0; }
|
||||
.statistics-filter-label { flex: 0 0 80px; text-align: right; }
|
||||
.statistics-filter-item > .el-select,
|
||||
.statistics-filter-item > .el-date-editor { flex: 1; min-width: 0; }
|
||||
.statistics-filter-item .el-range-separator { width: 24px; }
|
||||
@media (max-width: 767px) {
|
||||
.statistics-filter-row + .statistics-filter-row { margin-top: 0; }
|
||||
.statistics-filter-item { margin-bottom: 14px; }
|
||||
}
|
||||
|
||||
.el-table-container {
|
||||
@@ -80,137 +71,104 @@ layout("/layouts/platform.html"){
|
||||
.therapy-statistics-time-dialog .el-dialog__body { padding: 16px; }
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<el-row align="middle" class="query-row" type="flex">
|
||||
<el-col class="query-row-title"></el-col>
|
||||
<el-col class="query-row-content">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<span>年  度:</span>
|
||||
<el-date-picker
|
||||
:clearable="false"
|
||||
v-model="pageForm.startYear"
|
||||
type="year"
|
||||
value-format="yyyy"
|
||||
placeholder="选择年"
|
||||
style="width: 38%" @change="yearChange">
|
||||
</el-date-picker>
|
||||
<span>至</span>
|
||||
<el-date-picker
|
||||
:clearable="false"
|
||||
v-model="pageForm.endYear"
|
||||
type="year"
|
||||
value-format="yyyy"
|
||||
placeholder="选择年"
|
||||
style="width: 38%" @change="yearChange">
|
||||
</el-date-picker>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<span>所属工会:</span>
|
||||
<el-select v-model="pageForm.unionId" placeholder="请选择所属工会"
|
||||
@change="doSearch()"
|
||||
filterable clearable style="width: 80%">
|
||||
<el-option
|
||||
v-for="item in unions"
|
||||
:key="item.id"
|
||||
:label="item.unionname"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-card shadow="never" class="statistics-filters">
|
||||
<el-row :gutter="24" class="statistics-filter-row">
|
||||
<el-col :span="8" :xs="24" class="statistics-filter-item">
|
||||
<span class="statistics-filter-label">年度:</span>
|
||||
<div style="display: inline-flex; align-items: center; gap: 8px; vertical-align: middle; min-width: 0; width: 100%; flex: 1;">
|
||||
<el-date-picker v-model="pageForm.startYear" type="year" format="yyyy年" value-format="yyyy"
|
||||
placeholder="开始年度" :picker-options="{disabledDate: date => !!pageForm.endYear && date.getFullYear() > Number(pageForm.endYear)}"
|
||||
@change="yearChange" style="flex: 1; width: 0; min-width: 0"></el-date-picker>
|
||||
<span>至</span>
|
||||
<el-date-picker v-model="pageForm.endYear" type="year" format="yyyy年" value-format="yyyy"
|
||||
placeholder="结束年度" :picker-options="{disabledDate: date => !!pageForm.startYear && date.getFullYear() < Number(pageForm.startYear)}"
|
||||
@change="yearChange" style="flex: 1; width: 0; min-width: 0"></el-date-picker>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8" :xs="24" class="statistics-filter-item">
|
||||
<span class="statistics-filter-label">所属工会:</span>
|
||||
<el-select v-model="pageForm.unionId" placeholder="请选择所属工会"
|
||||
filterable clearable style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in unions"
|
||||
:key="item.id"
|
||||
:label="item.unionname"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="8" :xs="24" class="statistics-filter-item">
|
||||
<span class="statistics-filter-label">旅行社:</span>
|
||||
<el-select v-model="pageForm.travelAgencyId" filterable clearable
|
||||
placeholder="请选择旅行社"
|
||||
style="width: 100%" @change="agencyChange">
|
||||
<el-option v-for="item in agencyLists"
|
||||
:key="item.id"
|
||||
:label="item.travelAgencyName"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
|
||||
<el-row align="middle" class="query-row" type="flex">
|
||||
<el-col class="query-row-title"></el-col>
|
||||
<el-col class="query-row-content">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<span>旅 行 社:</span>
|
||||
<el-select v-model="pageForm.travelAgencyId" filterable clearable
|
||||
placeholder="请选择旅行社"
|
||||
style="width: 80%" @change="agencyChange">
|
||||
<el-option v-for="item in agencyLists"
|
||||
:key="item.id"
|
||||
:label="item.travelAgencyName"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<span>路线类型:</span>
|
||||
<el-select v-model="pageForm.regionalNature" filterable
|
||||
placeholder="请选择线路"
|
||||
style="width: 80%"
|
||||
@change="lineTypeChange">
|
||||
<el-option label="全部" value=""></el-option>
|
||||
<el-option label="省内" value="省内"></el-option>
|
||||
<el-option label="省外" value="省外"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24" class="statistics-filter-row">
|
||||
<el-col :span="8" :xs="24" class="statistics-filter-item">
|
||||
<span class="statistics-filter-label">线路类型:</span>
|
||||
<el-select v-model="pageForm.regionalNature" filterable
|
||||
placeholder="请选择线路类型"
|
||||
style="width: 100%"
|
||||
@change="lineTypeChange">
|
||||
<el-option label="全部" value=""></el-option>
|
||||
<el-option label="省内" value="省内"></el-option>
|
||||
<el-option label="省外" value="省外"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="8" :xs="24" class="statistics-filter-item">
|
||||
<span class="statistics-filter-label">线路:</span>
|
||||
<el-select v-model="pageForm.takePartInLineId" filterable clearable
|
||||
placeholder="请选择线路"
|
||||
style="width: 100%">
|
||||
<el-option v-for="item in lineList"
|
||||
:key="item.id"
|
||||
:label="item.lineName + '-' + item.regionalNature + '【' + item.lotName + '】' + '(' + item.signUpMode + ')'"
|
||||
:value="item.lineId">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="8" :xs="24" class="statistics-filter-item">
|
||||
<span class="statistics-filter-label">标段:</span>
|
||||
<el-select v-model="pageForm.lotId" filterable clearable
|
||||
placeholder="请选择标段"
|
||||
style="width: 100%">
|
||||
<el-option v-for="item in modifyConfig.lots"
|
||||
:key="item.id"
|
||||
:label="item.lotName"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
|
||||
<el-row align="middle" class="query-row" type="flex">
|
||||
<el-col class="query-row-title"></el-col>
|
||||
<el-col class="query-row-content">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<span>线  路:</span>
|
||||
<el-select v-model="pageForm.takePartInLineId" filterable clearable
|
||||
placeholder="请选择线路"
|
||||
style="width: 80%" @change="lineChange">
|
||||
<el-option v-for="item in lineList"
|
||||
:key="item.id"
|
||||
:label="item.lineName + '-' + item.regionalNature + '【' + item.lotName + '】' + '(' + item.signUpMode + ')'"
|
||||
:value="item.lineId">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<span>标  段:</span>
|
||||
<el-select v-model="pageForm.lotId" filterable clearable
|
||||
placeholder="请选择标段"
|
||||
style="width: 80%" @change="doSearch()">
|
||||
<el-option v-for="item in modifyConfig.lots"
|
||||
:key="item.id"
|
||||
:label="item.lotName"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24" class="statistics-filter-row">
|
||||
<el-col :span="8" :xs="24" class="statistics-filter-item">
|
||||
<span class="statistics-filter-label">出行年月:</span>
|
||||
<el-date-picker v-model="pageForm.playMonth" type="month" value-format="yyyy-MM"
|
||||
placeholder="请选择出行年月" clearable style="width: 100%"></el-date-picker>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
|
||||
<el-row align="middle" class="query-row" type="flex">
|
||||
<el-col class="query-row-title"></el-col>
|
||||
<el-col class="query-row-content">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<span>出行年月:</span>
|
||||
<el-date-picker
|
||||
v-model="pageForm.playMonth"
|
||||
type="month"
|
||||
value-format="yyyy-MM"
|
||||
placeholder="请选择出行年月"
|
||||
style="width: 80%"
|
||||
clearable
|
||||
@change="doSearch">
|
||||
</el-date-picker>
|
||||
</el-col>
|
||||
<el-col :span="12"></el-col>
|
||||
</el-row>
|
||||
|
||||
<el-col :span="8" :xs="24" class="statistics-filter-item">
|
||||
<span class="statistics-filter-label">成团状态:</span>
|
||||
<el-select v-model="pageForm.groupStatus" style="width: 100%">
|
||||
<el-option label="全部" value=""></el-option>
|
||||
<el-option label="成团" :value="1"></el-option>
|
||||
<el-option label="未成团" :value="2"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="8" :xs="24" class="statistics-filter-item">
|
||||
<el-button icon="el-icon-search" type="primary" @click="doSearch" :loading="tableLoading">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh-left" @click="resetSearch">重置</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
@@ -219,6 +177,7 @@ layout("/layouts/platform.html"){
|
||||
<el-card shadow="never" class="mt10">
|
||||
<table-tool label="" :columns.sync="tableColumns" ref="table_tool">
|
||||
<template>
|
||||
<el-button icon="el-icon-download" size="small" type="primary" @click="exportCurrentList" :disabled="tableLoading || !exportQuery">导出当前查询列表</el-button>
|
||||
<el-button @click="showGiveTimes"
|
||||
size="small"
|
||||
style="margin-right: 10px"
|
||||
@@ -245,15 +204,6 @@ layout("/layouts/platform.html"){
|
||||
</el-button>-->
|
||||
</template>
|
||||
<el-button icon="el-icon-refresh" @click="doSearch" circle></el-button>
|
||||
<el-dropdown @command="tableSizeChange">
|
||||
<el-button icon="el-icon-c-scale-to-original" circle></el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="mini">Mini</el-dropdown-item>
|
||||
<el-dropdown-item command="small">Small</el-dropdown-item>
|
||||
<el-dropdown-item command="medium">Medium</el-dropdown-item>
|
||||
<el-dropdown-item command="">Large</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" style="width: 100%"
|
||||
ref="table"
|
||||
@@ -489,7 +439,10 @@ layout("/layouts/platform.html"){
|
||||
takePartInLineId: '',
|
||||
playMonth: '',
|
||||
travelAgencyId: '',
|
||||
groupStatus: '',
|
||||
},
|
||||
appliedQuery: null,
|
||||
exportQuery: null,
|
||||
tableColumns: [
|
||||
{prop: 'lineName', label: '线路名称', sortable: true, width: 300, fixed: 'left'},
|
||||
{prop: 'unionname', label: '选择线路工会', sortable: true, width: 220, fixed: 'left'},
|
||||
@@ -502,6 +455,7 @@ layout("/layouts/platform.html"){
|
||||
{prop: 'contactMobileNumber', label: '联系方式', visible: false},
|
||||
{prop: 'estimatedFamilyNumbers', label: '最少成团人数', width: 80},
|
||||
{prop: 'groupCount', label: '成团计入人数', width: 80},
|
||||
{prop: 'groupStatusName', label: '成团状态', width: 90},
|
||||
{prop: 'lineNum', label: '教职工报名人数', width: 80},
|
||||
{prop: 'signUpUserFamilyNum', label: '家属总人数', width: 80},
|
||||
{prop: 'adultFamilyNum', label: '成年家属人数', width: 80},
|
||||
@@ -643,6 +597,56 @@ layout("/layouts/platform.html"){
|
||||
})
|
||||
})
|
||||
},
|
||||
statisticsFilters() {
|
||||
const keys = ['startYear', 'endYear', 'unionId', 'regionalNature', 'signUpMode',
|
||||
'lotId', 'takePartInLineId', 'playMonth', 'travelAgencyId', 'groupStatus']
|
||||
return keys.reduce((filters, key) => {
|
||||
filters[key] = this.pageForm[key] == null ? '' : this.pageForm[key]
|
||||
return filters
|
||||
}, {})
|
||||
},
|
||||
doSearch() {
|
||||
if (this.pageForm.startYear && this.pageForm.endYear && Number(this.pageForm.startYear) > Number(this.pageForm.endYear)) {
|
||||
this.$message.warning('开始年度不能大于结束年度')
|
||||
return
|
||||
}
|
||||
this.appliedQuery = this.statisticsFilters()
|
||||
this.pageForm.pageNumber = 1
|
||||
this.$refs.table && this.$refs.table.clearSelection()
|
||||
return this.pageData()
|
||||
},
|
||||
async resetSearch() {
|
||||
Object.assign(this.pageForm, {
|
||||
startYear: moment().format('YYYY'), endYear: moment().format('YYYY'),
|
||||
unionId: '', regionalNature: '', signUpMode: '', lotId: '',
|
||||
takePartInLineId: '', playMonth: '', travelAgencyId: '', groupStatus: ''
|
||||
})
|
||||
this.getAgencyList()
|
||||
this.getUnionSelectLine()
|
||||
return this.doSearch()
|
||||
},
|
||||
pageData() {
|
||||
if (!this.appliedQuery) this.appliedQuery = this.statisticsFilters()
|
||||
const filters = {...this.appliedQuery}
|
||||
const request = this._statisticsRequest = (this._statisticsRequest || 0) + 1
|
||||
this.tableLoading = true
|
||||
return this.$axios.post(loc() + '/pageData', {...this.pageForm, ...filters}).then(res => {
|
||||
if (request !== this._statisticsRequest) return
|
||||
if (res.code === 0) {
|
||||
this.tableData = res.data.list
|
||||
this.pageForm.totalCount = res.data.totalCount
|
||||
this.exportQuery = filters
|
||||
} else {
|
||||
this.$message.error(res.msg || '查询失败')
|
||||
}
|
||||
}).finally(() => {
|
||||
if (request === this._statisticsRequest) this.tableLoading = false
|
||||
})
|
||||
},
|
||||
exportCurrentList() {
|
||||
if (!this.exportQuery || this.tableLoading) return
|
||||
this.downloadFile(loc() + '/exportList?' + $.param(this.exportQuery))
|
||||
},
|
||||
doExport() {
|
||||
const {
|
||||
startYear,
|
||||
@@ -666,25 +670,19 @@ layout("/layouts/platform.html"){
|
||||
"&types=" + JSON.stringify(['line']) +
|
||||
"&linePlayTime=" + linePlayTime)
|
||||
},
|
||||
lineChange() {
|
||||
this.doSearch()
|
||||
},
|
||||
lineTypeChange() {
|
||||
this.pageForm.takePartInLineId = ''
|
||||
this.getUnionSelectLine()
|
||||
this.doSearch()
|
||||
},
|
||||
yearChange() {
|
||||
this.$set(this.pageForm, 'travelAgencyId', '')
|
||||
this.$set(this.pageForm, 'takePartInLineId', '')
|
||||
this.getAgencyList()
|
||||
this.getUnionSelectLine()
|
||||
this.doSearch()
|
||||
},
|
||||
agencyChange() {
|
||||
this.$set(this.pageForm, 'takePartInLineId', '')
|
||||
this.getUnionSelectLine()
|
||||
this.doSearch()
|
||||
},
|
||||
async sendSuccess(row) {
|
||||
if (!this._therapyActions) this._therapyActions = new Set()
|
||||
|
||||
+95
-60
@@ -23,12 +23,13 @@ layout("/layouts/platform_h5.html"){
|
||||
}
|
||||
|
||||
.van-skeleton {
|
||||
padding: 20px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.van-skeleton__content {
|
||||
height: 600px;
|
||||
padding-top: 60px;
|
||||
height: auto;
|
||||
min-height: 60vh;
|
||||
padding: 16px 12px;
|
||||
}
|
||||
|
||||
.van-skeleton__row, .van-skeleton__title {
|
||||
@@ -131,7 +132,7 @@ layout("/layouts/platform_h5.html"){
|
||||
.top_icon {
|
||||
position: fixed;
|
||||
bottom: 80px;
|
||||
right: 20px;
|
||||
right: max(20px, calc(50vw - 300px));
|
||||
}
|
||||
|
||||
.van-field__control {
|
||||
@@ -183,8 +184,12 @@ layout("/layouts/platform_h5.html"){
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
/* 固定导航条改为页面显式让出高度:H5 布局的滚动容器是 .page-wrapper,
|
||||
van-sticky 无法在此生效,组件 placeholder 又在 v-cloak 期间测量为 0,会把首屏内容盖住。 */
|
||||
#app.therapy-line-detail { height: auto; min-height: 100%; padding-top: calc(46px + env(safe-area-inset-top)); }
|
||||
#app.therapy-line-detail > .van-nav-bar--fixed { z-index: 20; box-shadow: 0 1px 0 rgba(20, 37, 68, .06); }
|
||||
#app.therapy-line-detail .van-nav-bar__title { color: #142544; font-size: 18px; font-weight: 700; }
|
||||
#app.therapy-line-detail .container { padding: 16px 12px calc(90px + env(safe-area-inset-bottom)); }
|
||||
#app.therapy-line-detail .container { box-sizing: border-box; max-width: 640px; margin: 0 auto; padding: 16px 12px calc(90px + env(safe-area-inset-bottom)); }
|
||||
#app.therapy-line-detail .detail-card { margin-bottom: 14px; padding: 18px 16px; border: 1px solid #fff; border-radius: 18px; background: #fbfdff; color: #52627b; box-shadow: 0 7px 22px rgba(65, 115, 183, .06); }
|
||||
#app.therapy-line-detail .detail-title-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 10px; }
|
||||
#app.therapy-line-detail .detail-title-row h1 { flex: 1 1 180px; min-width: 0; margin: 0; color: #142544; font-size: 21px; font-weight: 700; line-height: 30px; overflow-wrap: anywhere; }
|
||||
@@ -207,7 +212,7 @@ layout("/layouts/platform_h5.html"){
|
||||
#app.therapy-line-detail .detail-time-label { grid-column: 1 / -1; color: #7d8da7; font-size: 13px; line-height: 20px; }
|
||||
#app.therapy-line-detail .detail-date { display: flex; flex-direction: column; min-width: 0; }
|
||||
#app.therapy-line-detail .detail-date strong { color: #243249; font-size: 24px; font-weight: 600; line-height: 32px; white-space: nowrap; }
|
||||
#app.therapy-line-detail .detail-date span { margin-top: 8px; color: #929fb4; font-size: 12px; line-height: 20px; }
|
||||
#app.therapy-line-detail .detail-date span { color: #929fb4; font-size: 12px; line-height: 20px; }
|
||||
#app.therapy-line-detail .detail-date-end { text-align: right; }
|
||||
#app.therapy-line-detail .detail-time-to { align-self: flex-start; margin: 0 8px; color: #b6c8e0; font-size: 28px; line-height: 32px; }
|
||||
#app.therapy-line-detail .detail-contact-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px; border-radius: 12px; background: #f2f7ff; overflow-wrap: anywhere; }
|
||||
@@ -242,25 +247,20 @@ layout("/layouts/platform_h5.html"){
|
||||
#app.therapy-line-detail .detail-time-to { margin: 0 4px; }
|
||||
}
|
||||
#app.therapy-line-detail .joinPopup { display: flex; flex-direction: column; background: #f6f7f9; }
|
||||
#app.therapy-line-detail .joinPopup .van-nav-bar__placeholder { flex-shrink: 0; }
|
||||
#app.therapy-line-detail .joinPopup .van-nav-bar { background: #fff; }
|
||||
#app.therapy-line-detail .joinPopup .van-nav-bar { flex-shrink: 0; background: #fff; }
|
||||
#app.therapy-line-detail .join_content { flex: 1; min-height: 0; height: auto; padding: 16px 12px calc(90px + env(safe-area-inset-bottom)); box-sizing: border-box; overflow-y: auto; }
|
||||
#app.therapy-line-detail .joinPopup .van-doc-card { margin: 0 0 16px; padding: 0 14px 8px; border: 1px solid #e1e6ee; border-radius: 12px; background: #fff; box-shadow: none; }
|
||||
#app.therapy-line-detail .joinPopup .van-doc-card > div:first-child { display: none; }
|
||||
#app.therapy-line-detail .joinPopup .van-card-header { display: flex; align-items: center; gap: 10px; padding: 14px 0; border-bottom: 1px solid #edf0f5; color: #006bff; font-size: 16px; line-height: 24px; }
|
||||
#app.therapy-line-detail .joinPopup .van-card-header::before { content: ''; flex: 0 0 4px; height: 18px; border-radius: 2px; background: #006bff; }
|
||||
#app.therapy-line-detail .joinPopup .van-card-body { padding: 0; }
|
||||
#app.therapy-line-detail .joinPopup .van-field { align-items: center; min-height: 44px; padding: 7px 0; background: transparent; font-size: 14px; }
|
||||
#app.therapy-line-detail .joinPopup .van-field { align-items: center; min-height: 44px; padding: 10px 0; background: transparent; font-size: 14px; }
|
||||
#app.therapy-line-detail .joinPopup .van-cell::after { right: 0; left: 0; border-color: #edf0f5; }
|
||||
#app.therapy-line-detail .joinPopup .van-field__label { width: 6.2em; margin-right: 12px; color: #58647a; line-height: 28px; }
|
||||
#app.therapy-line-detail .joinPopup .van-field__body { min-height: 28px; }
|
||||
#app.therapy-line-detail .joinPopup .van-field__control { color: #172033; line-height: 26px; }
|
||||
#app.therapy-line-detail .joinPopup .van-field__control::placeholder { color: #9aa2b2; }
|
||||
#app.therapy-line-detail .joinPopup .van-field__control:not([readonly]):not(.van-field__control--custom),
|
||||
#app.therapy-line-detail .joinPopup .van-cell--clickable .van-field__body { padding: 0 10px; border: 1px solid #dce1e9; border-radius: 6px; background: #f8f9fb; box-sizing: border-box; }
|
||||
#app.therapy-line-detail .joinPopup .van-cell--clickable { position: relative; }
|
||||
#app.therapy-line-detail .joinPopup .van-cell--clickable .van-field__body { padding-right: 26px; }
|
||||
#app.therapy-line-detail .joinPopup .van-cell__right-icon { position: absolute; right: 8px; top: 50%; margin: 0; transform: translateY(-50%); color: #7c899e; }
|
||||
#app.therapy-line-detail .joinPopup .van-field__label { width: 84px; margin-right: 12px; color: #596779; line-height: 24px; }
|
||||
#app.therapy-line-detail .joinPopup .van-field__body { min-height: 24px; }
|
||||
#app.therapy-line-detail .joinPopup .van-field__control { color: #4f5d70; font-size: 14px; line-height: 24px; }
|
||||
#app.therapy-line-detail .joinPopup .van-field__control::placeholder { color: #b1bac6; }
|
||||
#app.therapy-line-detail .joinPopup .van-cell__right-icon { color: #7c899e; }
|
||||
#app.therapy-line-detail .joinPopup .van-radio { margin-right: 20px; }
|
||||
#app.therapy-line-detail .joinPopup .van-radio__label { color: #172033; }
|
||||
#app.therapy-line-detail .joinPopup .van-radio__icon--checked .van-icon { border-color: #006bff; background: #006bff; }
|
||||
@@ -268,11 +268,10 @@ layout("/layouts/platform_h5.html"){
|
||||
#app.therapy-line-detail .joinPopup .companion-add .van-icon { font-size: 20px; }
|
||||
#app.therapy-line-detail .joinPopup .companion-heading { display: flex; align-items: center; justify-content: space-between; margin: 10px 0 4px; padding: 8px 10px; border-radius: 6px; background: #eef3fd; color: #172033; font-size: 14px; line-height: 20px; }
|
||||
#app.therapy-line-detail .joinPopup .companion-delete { padding: 0; border: 0; background: transparent; color: #ee3535; font: inherit; }
|
||||
#app.therapy-line-detail .joinPopup .van-tabs__wrap { margin: 10px 0 0; }
|
||||
#app.therapy-line-detail .joinPopup .single-companion .van-tabs__wrap { display: none; }
|
||||
#app.therapy-line-detail .joinPopup .van-tabs__nav--card { margin: 0; background: #f3f5f9; }
|
||||
#app.therapy-line-detail .joinPopup .van-tabs__nav--card .van-tab { color: #69768d; }
|
||||
#app.therapy-line-detail .joinPopup .van-tabs__nav--card .van-tab--active { background: #006bff; color: #fff; }
|
||||
#app.therapy-line-detail .joinPopup .companion-selector { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 12px; }
|
||||
#app.therapy-line-detail .joinPopup .companion-selector button { min-width: 0; padding: 8px 4px; border: 1px solid #e1e6ee; border-radius: 6px; background: #f3f5f9; color: #69768d; font: inherit; font-size: 13px; line-height: 20px; overflow-wrap: anywhere; }
|
||||
#app.therapy-line-detail .joinPopup .companion-selector button.is-active { border-color: #006bff; background: #006bff; color: #fff; }
|
||||
#app.therapy-line-detail .joinPopup .companion-tabs > .van-tabs__wrap { display: none; }
|
||||
#app.therapy-line-detail .joinPopup .companionList_empty_text { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; min-height: 138px; padding: 12px 0; color: #98a2b5; font-size: 13px; line-height: 22px; }
|
||||
#app.therapy-line-detail .joinPopup .companionList_empty_text .van-icon { color: #b0bacb; font-size: 36px; }
|
||||
#app.therapy-line-detail .joinPopup .companion-room-tip { display: flex; align-items: flex-start; gap: 8px; margin: 10px 0; padding: 10px; border-radius: 6px; background: #eef3fd; color: #7c899e; font-size: 12px; line-height: 20px; }
|
||||
@@ -283,10 +282,8 @@ layout("/layouts/platform_h5.html"){
|
||||
|
||||
<div id="app" class="therapy-mobile therapy-line-detail" v-cloak>
|
||||
|
||||
<van-sticky>
|
||||
<van-nav-bar @click-left="historyBack()" fixed left-arrow placeholder
|
||||
title="线路详情"></van-nav-bar>
|
||||
</van-sticky>
|
||||
<van-nav-bar @click-left="historyBack()" fixed left-arrow safe-area-inset-top
|
||||
title="线路详情"></van-nav-bar>
|
||||
|
||||
<template v-if="isLoad">
|
||||
<!--线路详情-->
|
||||
@@ -332,7 +329,7 @@ layout("/layouts/platform_h5.html"){
|
||||
<a v-if="lineData.contactMobileNumber" :href="'tel:' + lineData.contactMobileNumber" class="detail-call" aria-label="拨打旅行社电话"><van-icon name="phone-o"></van-icon></a>
|
||||
</div>
|
||||
<div class="detail-contact-row">
|
||||
<div><div class="detail-muted">联系人</div><div class="detail-contact-name">{{lineData.principal || '暂无信息'}} <span class="detail-contact-phone">{{lineData.principalContact}}</span></div></div>
|
||||
<div><div class="detail-muted">联系人</div><div class="detail-contact-name">{{lineData.principal || '暂无信息'}}</div><div class="detail-contact-phone">{{lineData.principalContact}}</div></div>
|
||||
<a v-if="lineData.principalContact" :href="'tel:' + lineData.principalContact" class="detail-call" aria-label="拨打联系人电话"><van-icon name="phone-o"></van-icon></a>
|
||||
</div>
|
||||
</section>
|
||||
@@ -373,10 +370,10 @@ layout("/layouts/platform_h5.html"){
|
||||
|
||||
<!--报名弹出框-->
|
||||
<van-popup v-model:show="joinPopup" position="right" class="joinPopup">
|
||||
<van-nav-bar @click-left="signType == '2' ? historyBack() : joinPopup = false" fixed left-arrow placeholder title="疗休养报名"></van-nav-bar>
|
||||
<van-nav-bar @click-left="signType == '2' ? historyBack() : joinPopup = false" left-arrow safe-area-inset-top title="疗休养报名"></van-nav-bar>
|
||||
<div class="join_content">
|
||||
|
||||
<van-form @submit="joinSubmit">
|
||||
<van-form @submit="joinSubmit" @failed="handleJoinValidationFailed" validate-first>
|
||||
|
||||
<!--基础信息-->
|
||||
<div class="van-doc-card" style="margin-bottom: 16px">
|
||||
@@ -387,9 +384,9 @@ layout("/layouts/platform_h5.html"){
|
||||
<div class="van-card-body">
|
||||
<van-field label="姓名" readonly v-model="formData.userName"></van-field>
|
||||
<van-field label="一卡通号" readonly v-model="formData.loginName"></van-field>
|
||||
<van-field label="身份证件" name="idCard" :rules="[{ required: true }]"
|
||||
<van-field label="身份证件" name="idCard" :rules="[{ required: true, message: '请填写身份证件' }, { validator: validateIdentityDocument, message: '证件号码格式不正确,请检查后填写' }]"
|
||||
placeholder="请填写身份证号、护照、台胞证等" v-model="formData.idCard"></van-field>
|
||||
<van-field label="手机号" name="mobile" :rules="[{ required: true }]"
|
||||
<van-field label="手机号" name="mobile" type="tel" :rules="[{ required: true, message: '请填写手机号' }, { validator: validateMobile, message: '请填写正确的11位手机号' }]"
|
||||
placeholder="请填写手机号" v-model="formData.mobile"></van-field>
|
||||
<van-field label="所属工会" readonly v-model="formData.unionName"></van-field>
|
||||
<van-field v-if="signType != '2'" label="报名线路" readonly v-model="formData.lineName"></van-field>
|
||||
@@ -411,8 +408,8 @@ layout("/layouts/platform_h5.html"){
|
||||
name="bedNum" placeholder="请选择床位" v-model="formData.bedInfo.bedNum"
|
||||
:rules="[{ required: true }]"></van-field>
|
||||
<van-field v-if="formData.bedInfo.bedType == '标准间'"
|
||||
:rules="[{ validator, message: '请选择是否拼房' }]"
|
||||
label="是否拼房" name="validator">
|
||||
:rules="[{ required: true, validator: validateBoolean, message: '请选择是否拼房' }]"
|
||||
label="是否拼房" name="isSleepTogether" :value="formData.bedInfo.isSleepTogether">
|
||||
<template #input>
|
||||
<van-radio-group direction="horizontal" v-model="formData.bedInfo.isSleepTogether">
|
||||
<van-radio :name="true" shape="square">是</van-radio>
|
||||
@@ -440,20 +437,25 @@ layout("/layouts/platform_h5.html"){
|
||||
</div>
|
||||
<template v-if="configData.familyInfo === 2">
|
||||
<div v-if="formData.companionList.length > 0" class="van-card-body">
|
||||
<van-tabs v-model="active" type="card" color="#006bff" :class="{'single-companion': formData.companionList.length === 1}" animated>
|
||||
<div v-if="formData.companionList.length > 1" class="companion-selector" role="group" aria-label="选择随行人">
|
||||
<button v-for="(item, companionIndex) in formData.companionList" :key="item.id || companionIndex"
|
||||
type="button" :class="{'is-active': active === companionIndex}"
|
||||
:aria-pressed="active === companionIndex" @click="active = companionIndex">随行人 {{companionIndex + 1}}</button>
|
||||
</div>
|
||||
<van-tabs v-model="active" class="companion-tabs" type="card" color="#006bff" :lazy-render="false" animated>
|
||||
<van-tab v-for="(item, index) in formData.companionList" :key="item.id || index" :title="'随行人' + (index + 1)">
|
||||
<div class="companion-heading">
|
||||
<span>随行人 {{index + 1}}</span>
|
||||
<button type="button" class="companion-delete" @click="delCompanion">删除</button>
|
||||
</div>
|
||||
<van-field label="姓名" name="userName" placeholder="请填写姓名"
|
||||
<van-field label="姓名" :name="'companion.' + index + '.userName'" placeholder="请填写姓名"
|
||||
v-model="item.userName"
|
||||
:rules="[{ required: true }]"></van-field>
|
||||
:rules="[{ required: true, validator: validateRequiredText, message: '请填写姓名' }]"></van-field>
|
||||
<!--<van-field label="一卡通号" name="loginName" placeholder="若没有工号,请忽略此项" v-model="item.loginName"></van-field>-->
|
||||
<van-field label="年龄" name="age" placeholder="请填写年龄" v-model="item.age"
|
||||
type="digit" :rules="[{ required: true }]"></van-field>
|
||||
<van-field label="年龄" :name="'companion.' + index + '.age'" placeholder="请填写年龄" v-model="item.age"
|
||||
type="digit" :rules="[{ required: true, message: '请填写年龄' }, { validator: validateAge, message: '年龄须为0至120之间的整数' }]"></van-field>
|
||||
<van-field :rules="[{ required: true, message: '请选择性别' }]" label="性别"
|
||||
name="validator">
|
||||
:name="'companion.' + index + '.sex'" :value="item.sex">
|
||||
<template #input>
|
||||
<van-radio-group direction="horizontal" v-model="item.sex">
|
||||
<van-radio name="男">男</van-radio>
|
||||
@@ -461,19 +463,19 @@ layout("/layouts/platform_h5.html"){
|
||||
</van-radio-group>
|
||||
</template>
|
||||
</van-field>
|
||||
<van-field label="身份证件" name="idCard" placeholder="请填写身份证号、护照、台胞证等"
|
||||
:rules="[{ required: true }]"
|
||||
<van-field label="身份证件" :name="'companion.' + index + '.idCard'" placeholder="请填写身份证号、护照、台胞证等"
|
||||
:rules="[{ required: true, message: '请填写身份证件' }, { validator: validateIdentityDocument, message: '证件号码格式不正确,请检查后填写' }]"
|
||||
v-model="item.idCard"></van-field>
|
||||
<van-field label="手机号" name="mobile" placeholder="请填写手机号"
|
||||
:rules="[{ required: true }]" type="digit"
|
||||
<van-field label="手机号" :name="'companion.' + index + '.mobile'" placeholder="请填写手机号"
|
||||
:rules="[{ required: true, message: '请填写手机号' }, { validator: validateMobile, message: '请填写正确的11位手机号' }]" type="tel"
|
||||
v-model="item.mobile"></van-field>
|
||||
<van-field @click="companionVisible = true" readonly is-link label="与本人关系"
|
||||
name="relation"
|
||||
:name="'companion.' + index + '.relation'"
|
||||
placeholder="随行人与本人关系" v-model="item.relation"
|
||||
:rules="[{ required: true }]"></van-field>
|
||||
:rules="[{ required: true, message: '请选择与本人关系' }]"></van-field>
|
||||
|
||||
<van-field @click="self = false; roomVisible = true" readonly is-link label="房间"
|
||||
name="bedType" placeholder="请选择房间"
|
||||
:name="'companion.' + index + '.bedType'" placeholder="请选择房间"
|
||||
v-model="item.bedInfo.bedType"></van-field>
|
||||
<div class="companion-room-tip">
|
||||
<van-icon name="info-o"></van-icon>
|
||||
@@ -482,10 +484,11 @@ layout("/layouts/platform_h5.html"){
|
||||
<van-field v-if="item.bedInfo.bedType == '标准间'"
|
||||
@click="self = false; bedVisible = true"
|
||||
readonly is-link label="床位"
|
||||
name="bedNum" placeholder="请选择床位"
|
||||
v-model="item.bedInfo.bedNum"></van-field>
|
||||
:name="'companion.' + index + '.bedNum'" placeholder="请选择床位"
|
||||
v-model="item.bedInfo.bedNum" :rules="[{ required: true, message: '请选择床位' }]"></van-field>
|
||||
<van-field v-if="item.bedInfo.bedType == '标准间'"
|
||||
:rules="[{ validator, message: '请选择是否拼房' }]" label="是否拼房">
|
||||
:rules="[{ required: true, validator: validateBoolean, message: '请选择是否拼房' }]" label="是否拼房"
|
||||
:name="'companion.' + index + '.isSleepTogether'" :value="item.bedInfo.isSleepTogether">
|
||||
<template #input>
|
||||
<van-radio-group direction="horizontal"
|
||||
v-model="item.bedInfo.isSleepTogether">
|
||||
@@ -496,8 +499,8 @@ layout("/layouts/platform_h5.html"){
|
||||
</van-field>
|
||||
<van-field
|
||||
v-if="item.bedInfo.bedType == '标准间' && item.bedInfo.isSleepTogether == true"
|
||||
label="意向拼房人" name="otherSleepUser" placeholder="多个拼房人请用,隔开"
|
||||
v-model="item.bedInfo.otherSleepUser"></van-field>
|
||||
label="意向拼房人" :name="'companion.' + index + '.otherSleepUser'" placeholder="多个拼房人请用,隔开"
|
||||
v-model="item.bedInfo.otherSleepUser" :rules="[{ required: true, validator: validateRequiredText, message: '请填写意向拼房人' }]"></van-field>
|
||||
</van-tab>
|
||||
</van-tabs>
|
||||
</div>
|
||||
@@ -510,7 +513,7 @@ layout("/layouts/platform_h5.html"){
|
||||
</template>
|
||||
<template v-else>
|
||||
<van-field label="家属数量" name="familyNumber" placeholder="请填写家属数量" v-model="formData.familyNumber"
|
||||
type="digit" :rules="[{ required: true }]"></van-field>
|
||||
type="digit" :rules="[{ required: true, message: '请填写家属数量' }, { validator: validateFamilyNumber, message: '家属数量须为非负整数' }]"></van-field>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
@@ -665,8 +668,45 @@ layout("/layouts/platform_h5.html"){
|
||||
}
|
||||
this.bedVisible = false
|
||||
},
|
||||
validator(value) {
|
||||
return value != null
|
||||
validateRequiredText(value) {
|
||||
return value != null && String(value).trim().length > 0
|
||||
},
|
||||
validateMobile(value) {
|
||||
return /^1[3-9]\d{9}$/.test(String(value == null ? '' : value).trim())
|
||||
},
|
||||
validateAge(value) {
|
||||
const age = String(value == null ? '' : value).trim()
|
||||
return /^(0|[1-9]\d{0,2})$/.test(age) && Number(age) <= 120
|
||||
},
|
||||
validateFamilyNumber(value) {
|
||||
const count = String(value == null ? '' : value).trim()
|
||||
return /^(0|[1-9]\d*)$/.test(count) && Number.isSafeInteger(Number(count)) && Number(count) <= 2147483647
|
||||
},
|
||||
validateBoolean(value) {
|
||||
return value === true || value === false
|
||||
},
|
||||
validateIdentityDocument(value) {
|
||||
const document = String(value == null ? '' : value).trim().toUpperCase()
|
||||
if (/^\d{15}$/.test(document) || /^\d{17}[0-9A-Z]$/.test(document)) {
|
||||
const legacy = document.length === 15
|
||||
const birthday = legacy ? '19' + document.slice(6, 12) : document.slice(6, 14)
|
||||
const date = moment(birthday, 'YYYYMMDD', true)
|
||||
const sequence = legacy ? document.slice(12, 15) : document.slice(14, 17)
|
||||
if (!/^[1-9]\d{5}/.test(document) || sequence === '000' || !date.isValid() || date.isAfter(moment(), 'day')) return false
|
||||
if (legacy) return true
|
||||
const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
|
||||
const sum = weights.reduce((total, weight, index) => total + Number(document[index]) * weight, 0)
|
||||
return '10X98765432'[sum % 11] === document[17]
|
||||
}
|
||||
// 未区分证件类型,保留护照、台胞证及港澳通行证的号码格式。
|
||||
return /^(?:\d{8,9}|(?=[A-Z0-9]{6,12}$)(?=.*[A-Z])(?=.*\d)[A-Z0-9]+)$/.test(document)
|
||||
},
|
||||
handleJoinValidationFailed({ errors }) {
|
||||
const error = errors[0]
|
||||
if (!error) return
|
||||
const companion = /^companion\.(\d+)\./.exec(error.name || '')
|
||||
if (companion) this.active = Number(companion[1])
|
||||
this.$toast(error.message)
|
||||
},
|
||||
async joinSubmit() {
|
||||
const toast = vant.Toast.loading({
|
||||
@@ -676,11 +716,6 @@ layout("/layouts/platform_h5.html"){
|
||||
message: '努力提交中',
|
||||
})
|
||||
const cloneData = clone(this.formData)
|
||||
cloneData.companionList.forEach((item, index) => {
|
||||
if (item.userName === '') {
|
||||
cloneData.companionList.splice(index, 1)
|
||||
}
|
||||
})
|
||||
let url = ''
|
||||
if(this.signType == '2') {
|
||||
cloneData.takePartInTravelAgencyId = this.takePartInTravelAgencyId
|
||||
|
||||
Reference in New Issue
Block a user