1、新加功能:建议意见讨论组

2、代表团管理:设置联络人(面向全校)
This commit is contained in:
2026-04-20 15:21:27 +08:00
parent 8553e1063b
commit 377dbafc18
10 changed files with 785 additions and 4 deletions
@@ -36,7 +36,6 @@ const HEAD_FORM_TEMPLATE = {
<user-select v-model="formData.contactUserId"
v-if="headDialogFormVisible"
api="/platform/teacherCongress/delegation/notHeadUser"
:api_params="{sessionId:formData.sessionId,delegationId:formData.delegationId}"
api_input_key_name="keyWord"
:option_list="contactOptions"
option_value="userId"
@@ -0,0 +1,241 @@
const AU_FORM_TEMPLATE = {
template: /*language=HTML*/ `
<el-dialog :title="formData.id ? '编辑' : '新增'" :visible.sync="dialogFormVisible" width="760px" :close-on-click-modal="false">
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="110px" size="small">
<el-form-item label="教代会届次" prop="sessionId">
<el-select v-model="formData.sessionId" filterable style="width: 100%" @change="onSessionChange">
<el-option v-for="item in sessionOptions" :key="item.id" :label="item.fullName" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="讨论组编码" prop="code">
<el-input v-model="formData.code" maxlength="50" placeholder="请输入讨论组编码"></el-input>
</el-form-item>
<el-form-item label="讨论组名称" prop="name">
<el-input v-model="formData.name" maxlength="100" placeholder="请输入讨论组名称"></el-input>
</el-form-item>
<el-form-item label="记录人" prop="recorderUserId">
<user-select
v-model="formData.recorderUserId"
v-if="dialogFormVisible"
ref="recorderUserSelect"
api="/platform/teacherCongress/discussionGroup/recorderOptions"
api_input_key_name="keyword"
:option_list="recorderOptions"
option_value="id"
:option_label_func="(item) => item.username + ' (' + item.loginname + ')'"
placeholder="请输入姓名或编码搜索"
style="width: 100%"
@change="onRecorderChange"
></user-select>
</el-form-item>
<el-form-item label="手机号">
<el-input :value="selectedRecorder && selectedRecorder.mobile ? selectedRecorder.mobile : ''" disabled></el-input>
</el-form-item>
<el-form-item label="代表团" prop="delegationCodes">
<el-select
v-model="selectedDelegations"
value-key="code"
multiple
filterable
remote
reserve-keyword
style="width: 100%"
placeholder="请输入代表团名称或编码搜索"
:remote-method="remoteSearchDelegation"
:loading="delegationLoading"
>
<el-option
v-for="item in delegationOptions"
:key="item.code"
:label="item.name + ' (' + item.code + ')'"
:value="item"
></el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取消</el-button>
<el-button type="primary" @click="doSubmit">确定</el-button>
</div>
</el-dialog>
`,
data() {
return {
dialogFormVisible: false,
delegationLoading: false,
formData: {},
selectedRecorder: null,
selectedDelegations: [],
recorderOptions: [],
delegationOptions: [],
sessionOptions: [],
formRules: {
sessionId: [{ required: true, message: "教代会届次不能为空", trigger: ["change", "blur"] }],
code: [{ required: true, message: "讨论组编码不能为空", trigger: ["change", "blur"] }],
name: [{ required: true, message: "讨论组名称不能为空", trigger: ["change", "blur"] }],
recorderUserId: [{ required: true, message: "记录人不能为空", trigger: ["change", "blur"] }],
delegationCodes: [{ required: true, message: "代表团不能为空", trigger: ["change", "blur"] }]
}
}
},
methods: {
onOpen(id, sessionId) {
this.dialogFormVisible = true
this.formData = {}
this.selectedRecorder = null
this.selectedDelegations = []
this.recorderOptions = []
this.delegationOptions = []
this.listSession(() => {
if (id) {
this.loadDetail(id)
} else {
this.formData = {
sessionId: sessionId || "",
code: "",
name: "",
recorderUserId: "",
recorderUserCode: "",
recorderUserName: "",
delegationCodes: "",
delegationNames: ""
}
this.$nextTick(() => {
this.$refs.formRef && this.$refs.formRef.clearValidate()
})
if (this.formData.sessionId) {
this.remoteSearchDelegation("")
}
}
})
},
loadDetail(id) {
this.$axios.post("/platform/teacherCongress/discussionGroup/findOne", { id }).then((res) => {
if (res.code === 0) {
const data = res.data || {}
this.formData = {
id: data.id || "",
sessionId: data.sessionid || "",
code: data.code || "",
name: data.name || "",
recorderUserId: data.recorderuserid || "",
recorderUserCode: data.recorderusercode || "",
recorderUserName: data.recorderusername || "",
delegationCodes: data.delegationcodes || "",
delegationNames: data.delegationnames || ""
}
if (this.formData.sessionid && data.sessionname) {
const hasSession = this.sessionOptions.some((item) => item.id === this.formData.sessionid)
if (!hasSession) {
this.sessionOptions = this.sessionOptions.concat([{
id: this.formData.sessionid,
fullName: data.sessionname
}])
}
}
this.selectedRecorder = {
id: this.formData.recorderUserId,
loginname: this.formData.recorderUserCode,
username: this.formData.recorderUserName,
mobile: data.recorderusermobile || ""
}
this.recorderOptions = this.formData.recorderUserId ? [this.selectedRecorder] : []
const codes = Array.isArray(data.delegationCodeList) ? data.delegationCodeList : this.parseJsonArray(this.formData.delegationCodes)
const names = Array.isArray(data.delegationNameList) ? data.delegationNameList : this.parseJsonArray(this.formData.delegationNames)
this.selectedDelegations = codes.map((code, index) => ({
code,
name: names[index] || ""
}))
this.delegationOptions = this.selectedDelegations.slice()
if (data.sessionid) {
this.remoteSearchDelegation("")
}
this.$nextTick(() => {
this.$refs.formRef && this.$refs.formRef.clearValidate()
})
}
})
},
listSession(callback) {
this.$axios.post("/platform/teacherCongress/common/listOpenSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data || []
callback && callback()
}
})
},
onSessionChange() {
this.selectedDelegations = []
this.delegationOptions = []
this.formData.delegationCodes = ""
this.formData.delegationNames = ""
this.remoteSearchDelegation("")
},
remoteSearchDelegation(keyword) {
if (!this.formData.sessionId) {
this.delegationOptions = this.selectedDelegations.slice()
return
}
this.delegationLoading = true
this.$axios.post("/platform/teacherCongress/discussionGroup/delegationOptions", {
sessionId: this.formData.sessionId,
keyword
}).then((res) => {
if (res.code === 0) {
this.delegationOptions = this.mergeOptions(this.selectedDelegations, res.data || [], "code")
}
}).finally(() => {
this.delegationLoading = false
})
},
mergeOptions(current, incoming, key) {
const map = new Map()
;(incoming || []).concat(current || []).forEach((item) => {
if (item && item[key]) {
if (!map.has(item[key])) {
map.set(item[key], item)
}
}
})
return Array.from(map.values())
},
onRecorderChange(userId) {
const componentOptions = this.$refs.recorderUserSelect && this.$refs.recorderUserSelect.options ? this.$refs.recorderUserSelect.options : []
this.recorderOptions = this.mergeOptions(this.recorderOptions, componentOptions, "id")
const user = this.recorderOptions.find((item) => item.id === userId)
this.selectedRecorder = user || null
this.formData.recorderUserId = user ? user.id : ""
this.formData.recorderUserCode = user ? user.loginname : ""
this.formData.recorderUserName = user ? user.username : ""
},
parseJsonArray(value) {
if (!value) {
return []
}
try {
const result = JSON.parse(value)
return Array.isArray(result) ? result : []
} catch (e) {
return []
}
},
doSubmit() {
this.formData.delegationCodes = JSON.stringify(this.selectedDelegations.map((item) => item.code))
this.formData.delegationNames = JSON.stringify(this.selectedDelegations.map((item) => item.name))
this.$refs.formRef.validate((valid) => {
if (valid) {
this.$axios.post(
"/platform/teacherCongress/discussionGroup" + (this.formData.id ? "/update" : "/insert"),
this.formData
).then((res) => {
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.$emit("refresh")
}
})
}
})
}
}
}
@@ -0,0 +1,155 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会届次">
<el-select clearable filterable style="width: 100%" v-model="pageForm.sessionId" @change="doSearch">
<el-option v-for="item in sessionOptions" :key="item.id" :label="item.fullName" :value="item.id"></el-option>
</el-select>
</search-item>
<search-item>
<el-input placeholder="请输入查询内容" v-model="pageForm.searchKeyword" @keyup.enter.native="doSearch">
<el-select v-model="pageForm.searchName" slot="prepend" style="width: 130px">
<el-option label="讨论组编码" value="code"></el-option>
<el-option label="讨论组名称" value="name"></el-option>
</el-select>
<el-button slot="append" icon="el-icon-search" @click="doSearch"></el-button>
</el-input>
</search-item>
<search-item label="记录人">
<el-input clearable placeholder="请输入记录人姓名或编码" v-model="pageForm.recorderUserName" @keyup.enter.native="doSearch"></el-input>
</search-item>
<search-item label="代表团编码">
<el-input clearable placeholder="请输入代表团编码" v-model="pageForm.delegationCode" @keyup.enter.native="doSearch"></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool label="建议意见讨论组">
<el-button size="small" type="primary" @click="$refs.auFormRef.onOpen(null, pageForm.sessionId)">
<i class="ti-plus"></i>
新增
</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%">
<el-table-column type="index" :index="indexMethod" label="序号" width="70"></el-table-column>
<el-table-column prop="code" label="讨论组编码" min-width="140"></el-table-column>
<el-table-column prop="name" label="讨论组名称" min-width="180"></el-table-column>
<el-table-column prop="recorderUserName" label="记录人" min-width="140">
<template slot-scope="{row}">
{{ row.recorderUserName }}<span v-if="row.recorderUserCode">({{ row.recorderUserCode }})</span>
</template>
</el-table-column>
<el-table-column prop="recorderUserMobile" label="手机号" width="140"></el-table-column>
<el-table-column prop="delegationNames" label="代表团" min-width="260" :show-overflow-tooltip="true">
<template slot-scope="{row}">
{{ formatDelegations(row) }}
</template>
</el-table-column>
<el-table-column prop="createdByName" label="创建人" width="120"></el-table-column>
<el-table-column prop="createdAt" label="创建时间" width="180">
<template slot-scope="{row}">
{{ formatDate(row.createdAt) }}
</template>
</el-table-column>
<el-table-column label="操作" width="160" fixed="right">
<template slot-scope="{row}">
<el-button size="mini" type="primary" @click="$refs.auFormRef.onOpen(row.id, row.sessionId)">编辑</el-button>
<el-button size="mini" type="danger" @click="doDelete(row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<au-form @refresh="pageData" ref="auFormRef"></au-form>
</div>
<script>
<!--#include("auForm.js"){}#-->
new Vue({
el: "#app",
mixins: [initTableMixins],
components: {
"au-form": AU_FORM_TEMPLATE
},
data() {
return {
sessionOptions: []
}
},
methods: {
listSession() {
this.$axios.post("/platform/teacherCongress/common/listOpenSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data || []
if (!this.pageForm.sessionId && this.sessionOptions.length) {
this.pageForm.sessionId = this.sessionOptions[0].id
this.pageData()
}
}
})
},
formatDelegations(row) {
const codes = this.parseJsonArray(row.delegationCodes)
const names = this.parseJsonArray(row.delegationNames)
return codes.map((code, index) => (names[index] || "") + "(" + code + ")").filter((item) => item !== "()").join(", ")
},
formatDate(value) {
if (!value) {
return ""
}
const date = new Date(Number(value))
const pad = (num) => String(num).padStart(2, "0")
return [
date.getFullYear(),
pad(date.getMonth() + 1),
pad(date.getDate())
].join("-") + " " + [pad(date.getHours()), pad(date.getMinutes()), pad(date.getSeconds())].join(":")
},
parseJsonArray(value) {
if (!value) {
return []
}
try {
const result = JSON.parse(value)
return Array.isArray(result) ? result : []
} catch (e) {
return []
}
},
doDelete(id) {
this.$confirm("确认删除这条记录吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/teacherCongress/discussionGroup/delete", { id }).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.pageData()
}
})
})
},
pageData() {
this.$axios.post("/platform/teacherCongress/discussionGroup/pageData", this.pageForm).then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
}
})
}
},
created() {
this.pageForm.searchName = "code"
this.listSession()
}
})
</script>
<!--#
}
#-->