This commit is contained in:
2025-10-29 15:50:03 +08:00
parent 3a8e58b558
commit c247c9a4d1
10 changed files with 370 additions and 19 deletions
@@ -137,7 +137,7 @@ public class ActivityCultureAuditActivityController {
public Result doReview(@Param("data") String param, String id) { public Result doReview(@Param("data") String param, String id) {
Dict args = Json.fromJson(Dict.class, param); Dict args = Json.fromJson(Dict.class, param);
ActivityTissue tissue = activityCultureService.dao().fetch(ActivityTissue.class, id); ActivityTissue tissue = activityCultureService.dao().fetch(ActivityTissue.class, id);
if (tissue.getIsUnseal()!=null &&tissue.getIsUnseal() && args.getInt("submitType") == 1) { if (args.getInt("submitType") == 1) {
Sys_home_activity sysHomeActivity = tissue.covertToSysHomeActivity(); Sys_home_activity sysHomeActivity = tissue.covertToSysHomeActivity();
activityCultureService.insertOrUpdate(sysHomeActivity); activityCultureService.insertOrUpdate(sysHomeActivity);
} }
@@ -183,9 +183,11 @@ public class ActivityCultureUserStatisticsController {
ActivityTissue tissue = dao.fetch(ActivityTissue.class, id); ActivityTissue tissue = dao.fetch(ActivityTissue.class, id);
Sql sql = Sqls.create(""" Sql sql = Sqls.create("""
SELECT SELECT
atp.* atp.*,
us.idcard idCard
FROM FROM
`activity_tissue_person` atp `activity_tissue_person` atp
left join sys_user us on us.id=atp.userId
$condition $condition
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
@@ -221,7 +223,7 @@ public class ActivityCultureUserStatisticsController {
entityList.add(new ExcelExportEntity("身份证号", "idCard", 20)); entityList.add(new ExcelExportEntity("身份证号", "idCard", 20));
entityList.add(new ExcelExportEntity("单位", "unitName", 20)); entityList.add(new ExcelExportEntity("单位", "unitName", 20));
entityList.add(new ExcelExportEntity("工会", "unionName", 20)); entityList.add(new ExcelExportEntity("工会", "unionName", 20));
if (tissue.getSignUpMethod() == 3) { if (List.of(2,3).contains(tissue.getSignUpMethod())) {
entityList.add(new ExcelExportEntity("报名人姓名", "applyUserUserName", 20)); entityList.add(new ExcelExportEntity("报名人姓名", "applyUserUserName", 20));
} }
entityList.add(new ExcelExportEntity("报名时间", "applyDateTime", 20)); entityList.add(new ExcelExportEntity("报名时间", "applyDateTime", 20));
@@ -231,7 +231,7 @@ public class ActivityTissue extends BaseModel implements Serializable, SysHomeCo
@Column @Column
@Comment("是否开启") @Comment("是否开启")
@Default("0") @Default("1")
@ColDefine(type = ColType.BOOLEAN) @ColDefine(type = ColType.BOOLEAN)
private Boolean isUnseal; private Boolean isUnseal;
@@ -240,6 +240,16 @@ public class ActivityTissue extends BaseModel implements Serializable, SysHomeCo
@ColDefine(type = ColType.MYSQL_JSON) @ColDefine(type = ColType.MYSQL_JSON)
private List<NutMap> goods; private List<NutMap> goods;
@Column
@Comment("主办单位")
@ColDefine(type = ColType.MYSQL_JSON)
private List<String> hostUnitIds;
@Column
@Comment("承办单位")
@ColDefine(type = ColType.MYSQL_JSON)
private List<String> undertakeUnitIds;
@Column @Column
@Comment("报名表单配置") @Comment("报名表单配置")
@ColDefine(type = ColType.MYSQL_JSON) @ColDefine(type = ColType.MYSQL_JSON)
@@ -159,15 +159,19 @@ public class ActivityCultureServiceImpl extends BaseServiceImpl<ActivityTissue>
club.clubName, club.clubName,
u.username, u.username,
u.loginname, u.loginname,
abs.`name` projectTypeName abs.`name` projectTypeName,
aus.groupName
FROM FROM
activity_tissue tissue activity_tissue tissue
LEFT JOIN sys_union uni ON uni.id = tissue.unionId LEFT JOIN sys_union uni ON uni.id = tissue.unionId
LEFT JOIN sys_club club ON club.id = tissue.clubId LEFT JOIN sys_club club ON club.id = tissue.clubId
LEFT JOIN `vw_user` u ON u.id=tissue.userId LEFT JOIN `vw_user` u ON u.id=tissue.userId
LEFT JOIN activity_basic_settings abs ON abs.`code`=tissue.projectTypeCode LEFT JOIN activity_basic_settings abs ON abs.`code`=tissue.projectTypeCode
LEFT JOIN activity_user_scope aus on aus.groupId=tissue.groupId
WHERE WHERE
tissue.id = @id tissue.id = @id
GROUP BY
tissue.id
""").setParam("id", id); """).setParam("id", id);
NutMap nutMap = (NutMap) dao().execute(sql.setCallback(Sqls.callback.map())).getResult(); NutMap nutMap = (NutMap) dao().execute(sql.setCallback(Sqls.callback.map())).getResult();
@@ -35,7 +35,7 @@ public class H5QsvSurveyController {
private QsvUserAnswerRecordService qsvUserAnswerRecordService; private QsvUserAnswerRecordService qsvUserAnswerRecordService;
@At("") @At("")
@Ok("beetl:/mobile/qsv/survey/index.html") @Ok("beetl:/platform/zhghh5/dayofficework/qsv/survey/index.html")
public void index() { public void index() {
} }
@@ -164,6 +164,34 @@ const ACTIVITY_CULTURE_APPLY_ACTIVITY = {
</div> </div>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12">
<el-form-item prop="hostUnitIds" label="主办单位">
<el-select v-model="formData.hostUnitIds" clearable filterable multiple
placeholder="请选择主办单位"
style="width: 100%">
<el-option
v-for="item in unitOptions"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="undertakeUnitIds" label="承办单位">
<el-select v-model="formData.undertakeUnitIds" clearable filterable multiple
placeholder="请选择主办单位"
style="width: 100%">
<el-option
v-for="item in unitOptions"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" <el-col :span="12"
v-if="formData.isEnrollSystem === true"> v-if="formData.isEnrollSystem === true">
@@ -571,7 +599,10 @@ const ACTIVITY_CULTURE_APPLY_ACTIVITY = {
{prop: "mobile", label: "联系方式"}, {prop: "mobile", label: "联系方式"},
{prop: "unitName", label: "所属单位"}, {prop: "unitName", label: "所属单位"},
{prop: "unionName", label: "所属工会"} {prop: "unionName", label: "所属工会"}
] ],
unitOptions: [],
clubOptions: [],
} }
}, },
components: { components: {
@@ -592,6 +623,10 @@ const ACTIVITY_CULTURE_APPLY_ACTIVITY = {
} }
}, },
methods: { methods: {
async getClubsByRole() {
const resp = await this.$axios.post("/platform/club/examine/apply/getClubsByRole")
return resp.data
},
// 保存 // 保存
onSave() { onSave() {
this.$confirm("您确定保存吗?", "提示", { this.$confirm("您确定保存吗?", "提示", {
@@ -869,7 +904,7 @@ const ACTIVITY_CULTURE_APPLY_ACTIVITY = {
}) })
return data return data
}, },
init(id) { async init(id) {
if (id) { if (id) {
this.activeName = "1" this.activeName = "1"
this.findOne(id) this.findOne(id)
@@ -897,6 +932,12 @@ const ACTIVITY_CULTURE_APPLY_ACTIVITY = {
this.$set(this.formData, "unionUserNumberLimit", data) this.$set(this.formData, "unionUserNumberLimit", data)
}) })
} }
this.clubOptions = await this.getClubsByRole()
this.clubOptions.map((v) => {
v.name = v.clubName
})
const units = await this.$businessTool.listUnit()
this.unitOptions = this.clubOptions.concat(units)
}, },
async queryUserByIds(ids) { async queryUserByIds(ids) {
const {data} = await this.$axios.post("/platform/activity/culture/applyActivity/queryUserByIds", {ids: JSON.stringify(ids)}) const {data} = await this.$axios.post("/platform/activity/culture/applyActivity/queryUserByIds", {ids: JSON.stringify(ids)})
@@ -918,6 +959,8 @@ const ACTIVITY_CULTURE_APPLY_ACTIVITY = {
if (data.startPlannedDate) data.plannedDate = [data.startPlannedDate, data.endPlannedDate] if (data.startPlannedDate) data.plannedDate = [data.startPlannedDate, data.endPlannedDate]
this.userData = clone(data.tissuePersonList) this.userData = clone(data.tissuePersonList)
data.unionUserNumberLimit = JSON.parse(data.unionUserNumberLimit) data.unionUserNumberLimit = JSON.parse(data.unionUserNumberLimit)
data.undertakeUnitIds = JSON.parse(data.undertakeUnitIds)
data.hostUnitIds = JSON.parse(data.hostUnitIds)
this.formData = data this.formData = data
if (!this.formData.unionUserNumberLimit) { if (!this.formData.unionUserNumberLimit) {
this.getUnionData().then((data) => { this.getUnionData().then((data) => {
@@ -41,6 +41,9 @@ const ACTIVITY_CULTURE_INFO_ACTIVITY = {
<el-descriptions-item label="活动人数"> <el-descriptions-item label="活动人数">
{{ viewData.peopleNum || '暂无' }} {{ viewData.peopleNum || '暂无' }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="活动报名范围">
{{ viewData.groupName || '暂无' }}
</el-descriptions-item>
<el-descriptions-item label="活动地点"> <el-descriptions-item label="活动地点">
{{ viewData.address }} {{ viewData.address }}
</el-descriptions-item> </el-descriptions-item>
@@ -326,14 +326,11 @@ layout("/layouts/platform.html"){
type: 'warning' type: 'warning'
}) })
if (confirm === "confirm") { if (confirm === "confirm") {
this.tableLoading = true const resp = await this.$axios.post(loc() + '/selectOptionByLastYear', {
const resp = await $.get(loc() + '/selectOptionByLastYear', {
projectId: this.pageForm.projectId projectId: this.pageForm.projectId
}) })
this.tableLoading = false
if (resp.code === 0) { if (resp.code === 0) {
this.doSearch() this.doSearch()
this.notifySuccess(resp.msg) this.notifySuccess(resp.msg)
} else { } else {
this.notifyWarning(resp.msg) this.notifyWarning(resp.msg)
@@ -345,7 +342,7 @@ layout("/layouts/platform.html"){
this.selectByAdminDialogVisible = true this.selectByAdminDialogVisible = true
}, },
async yearChange() { async yearChange() {
const resp = await $.get("/platform/healthCheckup/project/mange/getHealthCheckupProject", {year: this.pageForm.year}) const resp = await this.$axios.post("/platform/healthCheckup/project/mange/getHealthCheckupProject", {year: this.pageForm.year})
if (resp.code === 0) { if (resp.code === 0) {
this.projectOptions = resp.data this.projectOptions = resp.data
if (resp.data && resp.data.length > 0) { if (resp.data && resp.data.length > 0) {
@@ -360,7 +357,7 @@ layout("/layouts/platform.html"){
}, },
async getHealthCheckupSubject() { async getHealthCheckupSubject() {
this.projectSubjectOptions = [] this.projectSubjectOptions = []
const resp = await $.get("/platform/healthCheckup/project/mange/findOne", {id: this.pageForm.projectId}) const resp = await this.$axios.post("/platform/healthCheckup/project/mange/findOne", {id: this.pageForm.projectId})
if (resp.code === 0) { if (resp.code === 0) {
if (resp.data) { if (resp.data) {
this.projectInfo = resp.data this.projectInfo = resp.data
@@ -372,7 +369,7 @@ layout("/layouts/platform.html"){
this.doSearch() this.doSearch()
}, },
async queryCampus() { async queryCampus() {
const resp = await $.get("/platform/healthCheckup/campus/queryCampus") const resp = await this.$axios.post("/platform/healthCheckup/campus/queryCampus")
if (resp.code === 0) { if (resp.code === 0) {
this.campusOptions = resp.data this.campusOptions = resp.data
} else { } else {
@@ -406,7 +403,7 @@ layout("/layouts/platform.html"){
this.tableData = [] this.tableData = []
} }
const resp = await $.post(loc() + '/pageData', this.pageForm) const resp = await this.$axios.post(loc() + '/pageData', this.pageForm)
if (resp.code === 0) { if (resp.code === 0) {
this.tableData = resp.data.tableList this.tableData = resp.data.tableList
} }
@@ -454,7 +451,7 @@ layout("/layouts/platform.html"){
await this.pageUnionData(); await this.pageUnionData();
}, },
async pageUnionData() { async pageUnionData() {
const resp = await $.post(loc() + '/receivePageData', this.pageFormUnion) const resp = await this.$axios.post(loc() + '/receivePageData', this.pageFormUnion)
if (resp.code === 0) { if (resp.code === 0) {
this.$refs.guava.view() this.$refs.guava.view()
this.receive_tableColumns = resp.data.label this.receive_tableColumns = resp.data.label
@@ -195,9 +195,9 @@ const subjectForm = {
<div style="border-top: 1px solid var(--border-color-lighter);padding: 12px;text-align: right;"> <div style="border-top: 1px solid var(--border-color-lighter);padding: 12px;text-align: right;">
<!-- <el-button @click="visible = false">取消</el-button>--> <!-- <el-button @click="visible = false">取消</el-button>-->
<el-button type="primary" icon="el-icon-plus" @click="openBank"> <!--<el-button type="primary" icon="el-icon-plus" @click="openBank">
从题库选择 从题库选择
</el-button> </el-button>-->
<el-button type="primary" icon="el-icon-upload" @click="openTxtImport"> <el-button type="primary" icon="el-icon-upload" @click="openTxtImport">
从文本导入 从文本导入
@@ -0,0 +1,292 @@
<!--#
layout("/layouts/platform_h5.html"){
#-->
<style>
.container {
padding: 0;
}
.container .title {
text-align: center;
padding: 20px;
background: #ffffff;
margin: 0 0 10px 0;
}
.container .card {
padding: 10px;
background: #ffffff;
}
.subject {
background: #fff;
padding: 15px;
margin-bottom: 15px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
position: relative;
}
.subject p {
font-size: 16px;
margin: 20px 0 10px 0;
font-weight: bold;
}
.subject .tag {
position: absolute;
top: 0;
}
.button-control {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 20px;
display: flex;
column-gap: 20px;
background: #fff;
}
.van-checkbox__icon--checked .van-icon {
color: #fff !important;
background-color: var(--color-primary) !important;
border-color: var(--color-primary) !important;
}
.van-checkbox__icon--disabled .van-icon {
background-color: #fff;
}
.ui-input-box {
border: 1px solid #e3e3e3;
margin: 5px 0;
background-color: #fff;
padding: 0;
width: 100%;
display: flex;
}
.ui-input-box input {
background-color: #fff;
border: none !important;
padding: 10px;
font-size: 14px;
line-height: 18px;
display: inline-block;
margin: 0;
-webkit-appearance: none;
resize: none;
width: 100%;
}
</style>
<div id="app" v-cloak>
<van-nav-bar title="问卷调查" left-arrow @click-left="historyBack" placeholder fixed></van-nav-bar>
<div class="container" :style="{'padding-bottom': answerRecord.isFinish ? 0 : '84px'}">
<h2 class="title">{{ activity.title }}</h2>
<div v-if="!isFinished">
<div v-for="(subject, index) in subjects" :key="index" class="subject">
<p>{{index+1}}、{{ subject.title }}</p>
<div class="tag">
<van-tag v-if="subject.type === 'checkbox'" type="primary" size="large">多选</van-tag>
<van-tag v-if="subject.type === 'radio'" type="primary" size="large">单选</van-tag>
<van-tag v-if="subject.score" type="primary" size="large">{{subject.score}}分</van-tag>
</div>
<!--单选、多选-->
<van-checkbox-group
v-model="subject.userSelectOptionIds"
:ref="'subject'+subject.id"
v-if="['radio','checkbox'].includes(subject.type)"
>
<van-cell-group>
<van-cell
v-for="(option,index) in subject.options"
clickable
:key="option.id"
:title="option.text"
@click="cellToggle(subject,option.id)"
>
<template #icon>
<van-checkbox :name="option.id" :ref="'option'+option.id" style="margin-right: 10px"></van-checkbox>
</template>
<img
slot="right-icon"
v-if="option.imgUrl"
:src="option.imgUrl"
alt=""
style="width: 40px; height: 40px"
@click.stop="previewOptionImg(option.imgUrl)"
/>
</van-cell>
</van-cell-group>
</van-checkbox-group>
<!--填空题-->
<div class="ui-input-box" v-if="subject.type==='text'">
<input type="text" v-model="subject.userFillContent" :readonly="answerRecord.isFinish" />
</div>
</div>
<div class="button-control" v-if="!answerRecord.isFinish">
<van-button type="primary" @click="onSubmit" block :disabled="isEnd">{{isEnd ? '已结束' : '提交'}}</van-button>
</div>
</div>
</div>
</div>
<script>
const vue = new Vue({
el: "#app",
data() {
return {
list: [],
id: null,
subjects: [],
activity: {},
remainingTime: 0,
isFinished: false,
answerRecord: {},
answerRecordId: null
}
},
computed: {
isEnd() {
if (this.activity) {
return this.$moment().unix() > this.$moment(this.activity.endTime).unix()
}
return true
}
},
methods: {
//获取活动、题目
listSubjects() {
this.$axios.post("/platform/h5/qsv/survey/subjects", { activityId: this.id }).then((res) => {
if (res.code === 0) {
this.activity = res.data.activity
this.subjects = res.data.subjects
this.answerRecordId = res.data.answerRecordId
this.getAnswerRecord()
}
})
},
//获取回答记录
getAnswerRecord() {
this.$axios.post("/platform/h5/qsv/survey/answerRecord", { answerRecordId: this.answerRecordId }).then((res) => {
if (res.code === 0) {
this.answerRecord = res.data
if (this.answerRecord.isFinish) {
this.$toast.success("您已完成该调查")
}
this.initAnswer()
}
})
},
//答案回显
initAnswer() {
this.subjects.forEach((subject, subjectIndex) => {
const answer = this.answerRecord.extJson[subject.id]
if (["radio", "checkbox"].includes(subject.type)) {
this.$refs["subject" + subject.id][0].toggleAll(false)
answer?.optionIds.forEach((optionId) => {
this.$nextTick(() => {
this.$refs["option" + optionId][0].toggle()
})
})
} else if (subject.type === "text") {
subject.userFillContent = answer?.text
}
})
},
//选项点击
cellToggle(subject, optionId) {
if (this.answerRecord.isFinish) {
return
}
if (subject.type === "radio") {
this.$refs["subject" + subject.id][0].toggleAll(false)
}
this.$refs["option" + optionId][0].toggle()
},
//预览图片
previewOptionImg(img) {
vant.ImagePreview([img])
},
//手动提交
onSubmit() {
const endTime = this.activity.endTime
if (this.isEnd) {
this.$toast("调查已结束")
return
}
//提示那些题没有作答
for (let i = 0; i < this.subjects.length; i++) {
const subject = this.subjects[i]
if (["radio", "checkbox"].includes(subject.type)) {
if (!subject.userSelectOptionIds || subject.userSelectOptionIds.length === 0) {
this.$toast.fail("第" + (i + 1) + "题未做答")
return
}
} else if ("text" === subject.type) {
if (!subject.userFillContent) {
this.$toast.fail("第" + (i + 1) + "题未作答")
return
}
}
}
this.autoSubmit()
},
//自动提交
autoSubmit(loading = null) {
this.$axios
.post("/platform/h5/qsv/survey/submitAnswer", {
answer: JSON.stringify({
activityId: this.id,
answerRecordId: this.answerRecordId,
subjects: this.subjects.map((subject) => {
return {
id: subject.id,
userSelectOptionIds: ["checkbox", "radio"].includes(subject.type) ? subject.userSelectOptionIds : [],
userFillContent: subject.type === "text" ? subject.userFillContent : null
}
})
})
})
.then((res) => {
if (res.code === 0) {
this.$toast.success(res.msg)
this.getAnswerRecord()
}
})
.finally(() => {
if (loading) {
loading.clear()
}
})
}
},
created() {
const id = GetQueryString("id")
if (id) {
this.id = id
this.listSubjects()
}
}
})
</script>
<!--#
}
#-->