This commit is contained in:
@jyuhsin
2025-06-09 16:13:00 +08:00
parent 49d3b4c8aa
commit b3f86d779a
10 changed files with 170 additions and 50 deletions
@@ -16,6 +16,7 @@ public enum ColumnFormTypeEnum {
INPUT("INPUT", "输入框"),
SELECT("SELECT", "选择框"),//选项数组,
STEPPER("STEPPER", "步进器"),
//RADIO("RADIO", "单选框"),//选项数组
FILE("FILE", "文件");//上传个数,格式
@@ -111,6 +111,14 @@ public class TrainSignUpActivityStatisticsController {
return trainSignUpActivityStatisticsService.registerUserList(courseId);
}
@At
@ViReturn
@Ok("json:full")
@RequiresPermissions("trainSingUp.statistics.activity")
public Object getTaleColumnInfo(@Param(value = "courseId") String courseId) {
return trainSignUpActivityStatisticsService.getTaleColumnInfo(courseId);
}
/**
* 培训班上课签到信息
*
@@ -177,7 +185,7 @@ public class TrainSignUpActivityStatisticsController {
excelCommonExportEntity.add(new ExcelExportEntity("性别", "sex", 20));
excelCommonExportEntity.add(new ExcelExportEntity("手机号", "mobile", 20));
excelCommonExportEntity.add(new ExcelExportEntity("报名时间", "signUpTime", 20));
excelCommonExportEntity.add(new ExcelExportEntity("报名时段", "courseTime", 20));
//excelCommonExportEntity.add(new ExcelExportEntity("报名时段", "courseTime", 20));
// excelCommonExportEntity.add(new ExcelExportEntity("生日", "birthday", 20));
excelCommonExportEntity.add(new ExcelExportEntity("报名状态", "stateName", 20));
@@ -198,7 +206,7 @@ public class TrainSignUpActivityStatisticsController {
TrainSignUpCourse course = courseMap.get(k);
//查询课程类型
TrainSignUpType trainSignUpType = dao.fetch(TrainSignUpType.class, Cnd.where("id", "=", course.getCourseType()));
dao.fetchLinks(trainSignUpType, "^trainMobileSignColumnList$");
dao.fetchLinks(trainSignUpType, "^trainMobileSignColumnList$", Cnd.NEW().asc("columnIndex"));
ExcelExportService service = new ExcelExportService();
ExportParams userExportParams = new ExportParams();
@@ -50,6 +50,12 @@ public class TrainSignUpType extends BaseModel implements Serializable {
@ColDefine(type = ColType.BOOLEAN)
private Boolean isAddFamily;
@Column
@Comment("本人纳入总人数")
@ColDefine(type = ColType.BOOLEAN)
@Default("1")
private Boolean selfAddFamily;
@Many(field = "typeId")
private List<TrainMobileSignColumn> trainMobileSignColumnList;
}
@@ -33,6 +33,8 @@ public interface TrainSignUpActivityStatisticsService extends ViService<TrainSig
*/
List<NutMap> registerUserList(String courseId);
List<NutMap> getTaleColumnInfo(String courseId);
/**
* 该课程下的报名人员信息
*
@@ -272,7 +272,9 @@ public class TrainSignUpActivityServiceImpl extends ViServiceImpl<TrainSignUpAct
AtomicInteger hasRegisterNum = new AtomicInteger();
List<TrainSignUpUser> signUpUsers = dao().query(TrainSignUpUser.class, Cnd.where("courseId", "=", c.getId()));
signUpUsers.forEach(item -> {
hasRegisterNum.getAndIncrement();
if(type.getSelfAddFamily()) {
hasRegisterNum.getAndIncrement();
}
if (type.getIsBringFamily() && type.getIsAddFamily()) {
List<NutMap> mapList = item.getMobileColumnsValue();
if (Lang.isNotEmpty(mapList)) {
@@ -449,7 +451,7 @@ public class TrainSignUpActivityServiceImpl extends ViServiceImpl<TrainSignUpAct
sql.setCondition(cnd);
//已经报名人数,这是教职工的
List<NutMap> signUpUsers = listMap(sql);
int hasRegisterNum = signUpUsers.size() + 1;//+1是算自己
int hasRegisterNum = signUpType.getSelfAddFamily() ? signUpUsers.size() + 1 : 0;//+1是算自己
//课程已报人数(携带的家属)
int hasFamilyNum = 0;
//如果携带家属,并且纳入人数,则mdzz
@@ -481,7 +483,8 @@ public class TrainSignUpActivityServiceImpl extends ViServiceImpl<TrainSignUpAct
int coursePeopleNumber = course.getCoursePeopleNumber();
//课程已报人数
List<TrainSignUpUser> signUpUsers = dao().query(TrainSignUpUser.class, Cnd.where("courseId", "=", courseId));
int hasRegisterNum = signUpUsers.size() + 1;//+1是算自己
//如果本人纳入总人数,则正常,但是如果不纳入,统计报名人数的时候就不算
int hasRegisterNum = type.getSelfAddFamily() ? signUpUsers.size() + 1 : 0;//+1是算自己
//课程已报人数(携带的家属)
int hasFamilyNum = 0;
//如果这个类型携带家属并且计入总人数
@@ -1,23 +1,31 @@
package io.v.nutz.zhgh.trainSignUp.service.impl;
import cn.hutool.core.util.StrUtil;
import cn.wizzer.framework.page.Pagination;
import io.v.nutz.base.dao.CndPlus;
import io.v.nutz.base.query.PageForm;
import io.v.nutz.base.service.impl.ViServiceImpl;
import io.v.nutz.base.utils.Vi;
import io.v.nutz.zhgh.trainSignUp.models.TrainMobileSignColumn;
import io.v.nutz.zhgh.trainSignUp.models.TrainSignUpCourse;
import io.v.nutz.zhgh.trainSignUp.models.TrainSignUpType;
import io.v.nutz.zhgh.trainSignUp.models.TrainSignUpUser;
import io.v.nutz.zhgh.trainSignUp.service.TrainSignUpActivityStatisticsService;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
/**
@@ -42,6 +50,9 @@ public class TrainSignUpActivityStatisticsServiceImpl extends ViServiceImpl<Trai
tsuc.coursePeopleNumber,
tsuc.courseReservedNumber,
type.lxname as courseType,
type.isBringFamily,
type.isAddFamily,
type.selfAddFamily,
tsuc.courseLocation,
tsuc.courseInstructor,
tsuc.reserveMode,
@@ -56,7 +67,31 @@ public class TrainSignUpActivityStatisticsServiceImpl extends ViServiceImpl<Trai
ORDER BY tsuc.orderNum
""");
sql.setParam("activityId", activityId);
return list(pageForm, sql);
Pagination list = list(pageForm, sql);
List<NutMap> listMap = list.getList(NutMap.class);
//找活动报的人
List<TrainSignUpUser> upUsers = dao().query(TrainSignUpUser.class, Cnd.where("activityId", "=", activityId));
Map<String, List<TrainSignUpUser>> signUsers = upUsers.stream().collect(Collectors.groupingBy(TrainSignUpUser::getCourseId));
for (NutMap item : listMap) {
AtomicReference<Integer> familyCount = new AtomicReference<>(0);
List<TrainSignUpUser> users = signUsers.get(item.getString("id"));
if (Lang.isNotEmpty(users)) {
users.forEach(u -> {
List<NutMap> mobileColumnsValue = u.getMobileColumnsValue();
if (Lang.isNotEmpty(mobileColumnsValue)) {
NutMap nutMap = mobileColumnsValue.stream().filter(o -> "xdqsrs".equals(o.getString("columnCode"))).findFirst().orElse(null);
if (nutMap != null) {
familyCount.updateAndGet(v -> v + (StrUtil.isNotBlank(nutMap.getString("columnValue")) ? nutMap.getInt("columnValue") : 0));
}
}
});
}
item.setv("familyCount", familyCount.get());
}
list.setList(listMap);
return list;
}
@Override
@@ -70,7 +105,8 @@ public class TrainSignUpActivityStatisticsServiceImpl extends ViServiceImpl<Trai
u.sex,
u.mobile,
tsuu.signUpTime,
tsuu.state
tsuu.state,
tsuu.mobileColumnsValue
FROM
train_sign_up_user tsuu
LEFT JOIN `user` u ON u.id = tsuu.userId
@@ -80,7 +116,27 @@ public class TrainSignUpActivityStatisticsServiceImpl extends ViServiceImpl<Trai
CndPlus cnd = new CndPlus();
cnd.andEx("tsuu.courseId", "=", courseId);
sql.setCondition(cnd);
return listMap(sql);
List<NutMap> list = listMap(sql);
list.forEach(o -> {
List<NutMap> mobileColumnsValue = Json.fromJsonAsList(NutMap.class, o.getString("mobileColumnsValue"));
if(Lang.isNotEmpty(mobileColumnsValue)) {
mobileColumnsValue.forEach(m -> {
o.put(m.getString("columnCode"), m.getString("columnValue"));
});
}
});
return list;
}
@Override
public List<NutMap> getTaleColumnInfo(String courseId) {
TrainSignUpCourse course = dao().fetch(TrainSignUpCourse.class, courseId);
TrainSignUpType upType = dao().fetch(TrainSignUpType.class, course.getCourseType());
dao().fetchLinks(upType, "trainMobileSignColumnList", Cnd.NEW().asc("columnIndex"));
List<TrainMobileSignColumn> columnList = upType.getTrainMobileSignColumnList();
List<NutMap> columnTableList = columnList.stream().map(o -> NutMap.NEW().setv("label", o.getColumnName()).setv("prop", o.getColumnCode())).collect(Collectors.toList());
return columnTableList;
}
@Override
@@ -8,42 +8,44 @@
<van-form @submit="onSubmit" ref="form">
<template v-for="column in dynamicData">
<!-- 文本数值时间 -->
<template v-if="['VARCHAR','TEXT','INT','DATE','DATETIME'].includes(column.columnType)">
<template v-if="['CHAR','VARCHAR','TEXT','INT','DATE','DATETIME'].includes(column.columnType)">
<van-field
class="field"
v-model="column.columnValue"
:clickable="['SELECT'].includes(column.columnFormType)"
:label="column.columnName"
:name="column.columnCode"
:type="['INT'].includes(column.columnType) ? 'digit' : ''"
:placeholder="(['SELECT'].includes(column.columnFormType) ? '请选择' : '请填写') + column.columnName"
:readonly="['SELECT'].includes(column.columnFormType)"
:rules="[{ required: column.isRequired, message: (['SELECT'].includes(column.columnFormType) ? '请选择' : '请填写') + column.columnName }]"
:required="column.isRequired"
:clearable="true"
clear-trigger="always"
@click="selectFieldClick(column)"
></van-field>
class="field"
v-model="column.columnValue"
:clickable="['SELECT'].includes(column.columnFormType)"
:label="column.columnName"
:name="column.columnCode"
:type="['INT'].includes(column.columnType) ? 'digit' : ''"
:placeholder="(['SELECT'].includes(column.columnFormType) ? '请选择' : '请填写') + column.columnName"
:readonly="['SELECT'].includes(column.columnFormType)"
:rules="[{ required: column.isRequired, message: (['SELECT'].includes(column.columnFormType) ? '请选择' : '请填写') + column.columnName }]"
:required="column.isRequired"
@click="selectFieldClick(column)"
>
<template v-if="['STEPPER'].includes(column.columnFormType)" #input>
<van-stepper v-model="column.columnValue" :max="3" :min="1"/>
</template>
</van-field>
<van-popup v-if="['SELECT'].includes(column.columnFormType)"
v-model="pickerStates[column.columnCode + 'Picker']"
position="bottom">
<template v-if="['DATETIME','DATE'].includes(column.columnType)">
<van-datetime-picker
:title="column.columnName"
:type="column.columnType.toLocaleLowerCase()"
show-toolbar
@cancel="pickerStates[column.columnCode + 'Picker'] = false; column.columnValue = ''"
@confirm="(time)=>{dateTimePickerConfirm(time,column)}"
:title="column.columnName"
:type="column.columnType.toLocaleLowerCase()"
show-toolbar
@cancel="pickerStates[column.columnCode + 'Picker'] = false; column.columnValue = ''"
@confirm="(time)=>{dateTimePickerConfirm(time,column)}"
/>
</template>
<template v-else>
<van-picker
:columns="column.selectValues"
:title="column.columnName"
show-toolbar
@cancel="pickerStates[column.columnCode + 'Picker'] = false; column.columnValue = ''"
@confirm="(value)=>{ordinaryPickerConfirm(value,column)}"
:columns="column.selectValues"
:title="column.columnName"
show-toolbar
@cancel="pickerStates[column.columnCode + 'Picker'] = false; column.columnValue = ''"
@confirm="(value)=>{ordinaryPickerConfirm(value,column)}"
/>
</template>
</van-popup>
@@ -94,6 +94,12 @@ layout("/layouts/platform.html"){
<el-radio :label="false" border>不纳入</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="formData.isBringFamily === true" prop="selfAddFamily" label="本人纳入总人数">
<el-radio-group v-model="formData.selfAddFamily">
<el-radio :label="true" border>纳入</el-radio>
<el-radio :label="false" border>不纳入</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<vi-title2 title="报名填写字段">
@@ -131,7 +137,7 @@ layout("/layouts/platform.html"){
<el-table-column label="控件类型" prop="columnFormType">
<template scope="{row, $index}">
<el-select filterable v-model="row.columnFormType" @change="(val) => {columnFormTypeChange(val, $index)}"
:disabled="formData.isBringFamily === true && row.columnCode === 'xdqsrs'" placeholder="请选择控件类型">
placeholder="请选择控件类型">
<el-option v-for="item in columnFormTypeList" :label="item.description" :value="item.code"></el-option>
</el-select>
</template>
@@ -139,8 +145,7 @@ layout("/layouts/platform.html"){
<el-table-column label="字段类型" prop="columnType">
<template scope="{row}">
<el-select filterable placeholder="请选择字段类型" v-model="row.columnType"
:disabled="row.isDisabled || (formData.isBringFamily === true && row.columnCode === 'xdqsrs')">
<el-select filterable placeholder="请选择字段类型" v-model="row.columnType">
<el-option v-for="item in columnTypeOptions" :label="item" :value="item"></el-option>
</el-select>
</template>
@@ -149,7 +154,6 @@ layout("/layouts/platform.html"){
<el-table-column label="是否必填" prop="isRequired" sortable>
<template scope="{row}">
<el-switch v-model="row.isRequired" active-color="#13ce66" inactive-color="#ff4949"
:disabled="formData.isBringFamily === true && row.columnCode === 'xdqsrs'"
:active-value="true" :inactive-value="false"
active-text="是" inactive-text="否"></el-switch>
</template>
@@ -202,7 +206,10 @@ layout("/layouts/platform.html"){
formData: {
trainMobileSignColumnList: [{isRequired: false}],
isBringFamily: false,
isAddFamily: null,
isAddFamily: false,
isTicket: false,
isWait: false,
selfAddFamily: true,
},
rules: {
lxname: [{required: true, message: '请输入类型名称', trigger: ['change', 'blur']}],
@@ -293,6 +300,7 @@ layout("/layouts/platform.html"){
this.formData = {
trainMobileSignColumnList: [{isRequired: false}],
isBringFamily: false,
selfAddFamily: true,
}
this.$refs.guava.edit()
if (this.$refs["addForm"])
@@ -89,12 +89,22 @@ layout("/layouts/platform.html"){
<el-table-column label="已报名人数" prop="registerNum" sortable align="center" header-align="center"
show-overflow-tooltip>
<template scope="{row}">
<el-link v-if="row.reserveMode === 1" @click="openView(row)" type="primary">
{{row.registerNum + row.courseReservedNumber}}
</el-link>
<el-link v-if="row.reserveMode === 2" @click="openView(row)" type="primary">
{{row.registerNum}}
</el-link>
<template v-if="row.isAddFamily && row.isBringFamily">
<el-link v-if="row.selfAddFamily" @click="openView(row)" type="primary">
{{row.registerNum + '家属(' + row.familyCount + ')'}}
</el-link>
<el-link v-else @click="openView(row)" type="primary">
{{row.familyCount}}
</el-link>
</template>
<template v-else>
<el-link v-if="row.reserveMode === 1" @click="openView(row)" type="primary">
{{row.registerNum + row.courseReservedNumber}}
</el-link>
<el-link v-if="row.reserveMode === 2" @click="openView(row)" type="primary">
{{row.registerNum}}
</el-link>
</template>
</template>
</el-table-column>
@@ -81,12 +81,22 @@ layout("/layouts/platform.html"){
<el-table-column label="已报名人数" prop="registerNum" sortable align="center" header-align="center"
show-overflow-tooltip>
<template scope="{row}">
<el-link v-if="row.reserveMode === 1" @click="openView(row)" type="primary">
{{row.registerNum + row.courseReservedNumber}}
</el-link>
<el-link v-if="row.reserveMode === 2" @click="openView(row)" type="primary">
{{row.registerNum}}
</el-link>
<template v-if="row.isAddFamily && row.isBringFamily">
<el-link v-if="row.selfAddFamily" @click="openView(row)" type="primary">
{{row.registerNum + '家属(' + row.familyCount + ')'}}
</el-link>
<el-link v-else @click="openView(row)" type="primary">
{{row.familyCount}}
</el-link>
</template>
<template v-else>
<el-link v-if="row.reserveMode === 1" @click="openView(row)" type="primary">
{{row.registerNum + row.courseReservedNumber}}
</el-link>
<el-link v-if="row.reserveMode === 2" @click="openView(row)" type="primary">
{{row.registerNum}}
</el-link>
</template>
</template>
</el-table-column>
<el-table-column label="操作" width="150px">
@@ -134,6 +144,15 @@ layout("/layouts/platform.html"){
{label: '报名时间', prop: 'signUpTime'},
{label: '报名状态', prop: 'state'},
],
cloneTableColumns: [
{label: '姓名', prop: 'username'},
{label: '工号', prop: 'loginname'},
{label: '单位', prop: 'unitname'},
{label: '分工会', prop: 'unionname'},
{label: '联系方式', prop: 'mobile'},
{label: '报名时间', prop: 'signUpTime'},
{label: '报名状态', prop: 'state'},
],
userSignInfo: {},
trainType: '培训班',
trainTypeList: [],
@@ -173,6 +192,11 @@ layout("/layouts/platform.html"){
this.registerUserTableData = resp_register.data
const resp_signInfo = await $.get(loc() + '/getSignInfo', {courseId: row.id})
this.userSignInfo = resp_signInfo.data
const resp_columnInfo = await $.get(loc() + '/getTaleColumnInfo', {courseId: row.id})
if(resp_columnInfo.data) {
this.registerUserTableColumns = []
this.registerUserTableColumns = this.cloneTableColumns.concat(resp_columnInfo.data)
}
}
},
async created() {