Merge remote-tracking branch 'origin/main'

This commit is contained in:
2026-08-20 17:26:55 +08:00
29 changed files with 508 additions and 126 deletions
@@ -7,12 +7,21 @@ layout("/layouts/platform.html"){
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<search-item label="申报开始年度">
<el-date-picker
placeholder="请选择年度"
placeholder="请选择申报开始年度"
type="year"
style="width: 100%"
v-model="pageForm.year"
v-model="pageForm.applyStartYear"
value-format="yyyy"
></el-date-picker>
</search-item>
<search-item label="申报结束年度">
<el-date-picker
placeholder="请选择申报结束年度"
type="year"
style="width: 100%"
v-model="pageForm.applyEndYear"
value-format="yyyy"
></el-date-picker>
</search-item>
@@ -41,11 +50,8 @@ layout("/layouts/platform.html"){
<span>{{ row.foundTime ? $moment(row.foundTime).format('YYYY-MM-DD') : '无' }}</span>
</template>
</el-table-column>
<el-table-column label="年度" prop="applyYear" sortable show-overflow-tooltip>
<template slot-scope="{row}">
<span>{{ $moment(row.applyTime).format('YYYY') }}</span>
</template>
</el-table-column>
<el-table-column label="申报开始年度" prop="applyStartYear" sortable show-overflow-tooltip></el-table-column>
<el-table-column label="申报结束年度" prop="applyEndYear" sortable show-overflow-tooltip></el-table-column>
<el-table-column label="申请时间" prop="applyTime" sortable show-overflow-tooltip></el-table-column>
<el-table-column label="当前节点" prop="curTaskName" show-overflow-tooltip></el-table-column>
<el-table-column label="审核时间" prop="finishTime" show-overflow-tooltip>
@@ -104,7 +110,8 @@ layout("/layouts/platform.html"){
return {
pageForm: {
clubId: "",
year: this.$moment().format("YYYY"),
applyStartYear: "",
applyEndYear: "",
audit: false
},
viewData: {},
@@ -8,12 +8,21 @@ layout("/layouts/platform.html"){
<template>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<search-item label="申报开始年度">
<el-date-picker
placeholder="请选择年度"
placeholder="请选择申报开始年度"
type="year"
style="width: 100%"
v-model="pageForm.year"
v-model="pageForm.applyStartYear"
value-format="yyyy"
></el-date-picker>
</search-item>
<search-item label="申报结束年度">
<el-date-picker
placeholder="请选择申报结束年度"
type="year"
style="width: 100%"
v-model="pageForm.applyEndYear"
value-format="yyyy"
></el-date-picker>
</search-item>
@@ -39,11 +48,8 @@ layout("/layouts/platform.html"){
<span>{{ row.foundTime ? $moment(row.foundTime).format('YYYY-MM-DD') : '' }}</span>
</template>
</el-table-column>
<el-table-column label="年度" prop="applyTime" sortable show-overflow-tooltip>
<template slot-scope="{row}">
<span>{{ $moment(row.applyTime).format('YYYY') }}</span>
</template>
</el-table-column>
<el-table-column label="申报开始年度" prop="applyStartYear" sortable show-overflow-tooltip></el-table-column>
<el-table-column label="申报结束年度" prop="applyEndYear" sortable show-overflow-tooltip></el-table-column>
<el-table-column label="申请时间" prop="applyTime" sortable show-overflow-tooltip></el-table-column>
<el-table-column label="当前节点" prop="taskName" show-overflow-tooltip></el-table-column>
<el-table-column label="流程状态" prop="instanceState" show-overflow-tooltip>
@@ -88,7 +94,8 @@ layout("/layouts/platform.html"){
return {
pageForm: {
clubId: "",
year: this.$moment().format("YYYY")
applyStartYear: "",
applyEndYear: ""
},
clubList: []
}
@@ -7,12 +7,21 @@ layout("/layouts/platform.html"){
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<search-item label="申报开始年度">
<el-date-picker
placeholder="请选择年度"
placeholder="请选择申报开始年度"
type="year"
style="width: 100%"
v-model="pageForm.year"
v-model="pageForm.applyStartYear"
value-format="yyyy"
></el-date-picker>
</search-item>
<search-item label="申报结束年度">
<el-date-picker
placeholder="请选择申报结束年度"
type="year"
style="width: 100%"
v-model="pageForm.applyEndYear"
value-format="yyyy"
></el-date-picker>
</search-item>
@@ -41,11 +50,8 @@ layout("/layouts/platform.html"){
<span>{{ row.foundTime ? $moment(row.foundTime).format('YYYY-MM-DD') : '无' }}</span>
</template>
</el-table-column>
<el-table-column label="年度" prop="applyYear" sortable show-overflow-tooltip>
<template slot-scope="{row}">
<span>{{ $moment(row.applyTime).format('YYYY') }}</span>
</template>
</el-table-column>
<el-table-column label="申报开始年度" prop="applyStartYear" sortable show-overflow-tooltip></el-table-column>
<el-table-column label="申报结束年度" prop="applyEndYear" sortable show-overflow-tooltip></el-table-column>
<el-table-column label="申请时间" prop="applyTime" sortable show-overflow-tooltip></el-table-column>
<el-table-column label="当前节点" prop="curTaskName" show-overflow-tooltip></el-table-column>
<el-table-column label="审核时间" prop="finishTime" show-overflow-tooltip>
@@ -104,7 +110,8 @@ layout("/layouts/platform.html"){
return {
pageForm: {
clubId: "",
year: this.$moment().format("YYYY"),
applyStartYear: "",
applyEndYear: "",
audit: false
},
viewData: {},
@@ -7,12 +7,21 @@ layout("/layouts/platform.html"){
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<search-item label="申报开始年度">
<el-date-picker
placeholder="请选择年度"
placeholder="请选择申报开始年度"
type="year"
style="width: 100%"
v-model="pageForm.year"
v-model="pageForm.applyStartYear"
value-format="yyyy"
></el-date-picker>
</search-item>
<search-item label="申报结束年度">
<el-date-picker
placeholder="请选择申报结束年度"
type="year"
style="width: 100%"
v-model="pageForm.applyEndYear"
value-format="yyyy"
></el-date-picker>
</search-item>
@@ -41,11 +50,8 @@ layout("/layouts/platform.html"){
<span>{{ row.foundTime ? $moment(row.foundTime).format('YYYY-MM-DD') : '无' }}</span>
</template>
</el-table-column>
<el-table-column label="年度" prop="applyYear" sortable show-overflow-tooltip>
<template slot-scope="{row}">
<span>{{ $moment(row.applyTime).format('YYYY') }}</span>
</template>
</el-table-column>
<el-table-column label="申报开始年度" prop="applyStartYear" sortable show-overflow-tooltip></el-table-column>
<el-table-column label="申报结束年度" prop="applyEndYear" sortable show-overflow-tooltip></el-table-column>
<el-table-column label="申请时间" prop="applyTime" sortable show-overflow-tooltip></el-table-column>
<el-table-column label="当前节点" prop="curTaskName" show-overflow-tooltip></el-table-column>
<el-table-column label="审核时间" prop="finishTime" show-overflow-tooltip>
@@ -104,7 +110,8 @@ layout("/layouts/platform.html"){
return {
pageForm: {
clubId: "",
year: this.$moment().format("YYYY"),
applyStartYear: "",
applyEndYear: "",
audit: false
},
viewData: {},
@@ -199,10 +199,10 @@
}
const viewData = resp.data || {}
this.$set(this, "viewData", viewData)
this.$set(this.viewData, "changeUserNum", viewData.changeUserNum || [])
this.$set(this, "legacyAuditRecords", viewData.legacyAuditRecords || [])
// 三类补充数据独立加载,成员变化统计失败不能阻断成员和审核记录显示
// 历史成员变化直接展示年审保存数据,成员和审核记录继续独立加载
await Promise.all([
this.getClubUserNum(viewData.clubId),
this.getJgUser(viewData.clubId),
this.getDoneTasks()
])
@@ -210,27 +210,6 @@
this.$message.error("查询年审详情失败")
}
},
async getClubUserNum(clubId) {
if (!clubId) {
this.$set(this.viewData, "changeUserNum", [])
return
}
try {
const resp = await this.$axios.post("/platform/club/examine/apply/getClubUserNum", {
clubId: clubId,
year: this.row.year
})
if (resp.code === 0) {
this.$set(this.viewData, "changeUserNum", resp.data || [])
} else {
this.$set(this.viewData, "changeUserNum", [])
this.$message.warning(resp.msg || "查询社团成员变化情况失败")
}
} catch (error) {
this.$set(this.viewData, "changeUserNum", [])
this.$message.warning("查询社团成员变化情况失败")
}
},
async getJgUser(clubId) {
if (!clubId) {
this.$set(this.viewData, "jgUser", [])
@@ -142,8 +142,13 @@ layout("/layouts/platform.html"){
></el-date-picker>
</el-form-item>
<el-form-item label="分工会">
<el-select :clearable="true" v-model="pageForm.department" placeholder="请选择分工会">
<el-option v-for="item in departments" :key="item.id" :label="item.name" :value="item.id"></el-option>
<el-select :clearable="true" v-model="pageForm.unionId" placeholder="请选择分工会">
<el-option v-for="item in unionOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="社团">
<el-select :clearable="true" v-model="pageForm.clubId" placeholder="请选择社团">
<el-option v-for="item in clubOptions" :key="item.id" :label="item.clubName" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item>
@@ -169,12 +174,15 @@ layout("/layouts/platform.html"){
<div class="chart-card">
<div class="chart-header">
<span class="chart-title">分工会投稿分布</span>
<el-tooltip content="数据更新时间:2024-02-24" placement="top">
<i class="el-icon-info"></i>
</el-tooltip>
</div>
<div id="pieChart" class="chart"></div>
</div>
<div class="chart-card">
<div class="chart-header">
<span class="chart-title">社团投稿分布</span>
</div>
<div id="clubPieChart" class="chart"></div>
</div>
</div>
<!-- 排行榜 -->
@@ -208,7 +216,8 @@ layout("/layouts/platform.html"){
<script nonce="${cspNonce!}">
let trendChart,
distributionChart = null
distributionChart,
clubDistributionChart = null
new Vue({
el: "#app",
@@ -216,10 +225,11 @@ layout("/layouts/platform.html"){
return {
statCards: [],
pageForm: {
dateRange: "",
department: ""
dateRange: [],
unionId: "",
clubId: ""
},
departments: [],
unionOptions: [],
clubOptions: [],
trendType: "month",
rankingTab: "person",
@@ -249,15 +259,27 @@ layout("/layouts/platform.html"){
}
},
methods: {
doSearch() {},
resetSearch() {},
doSearch() {
this.initTrendChart()
this.initDistributionChart()
this.initClubDistributionChart()
this.overview()
},
resetSearch() {
this.$set(this.pageForm, "dateRange", [])
this.$set(this.pageForm, "unionId", "")
this.$set(this.pageForm, "clubId", "")
this.doSearch()
},
initTrendChart() {
// 趋势图数据
this.$axios
.post("/platform/article/analysis/trend", {
type: this.trendType,
startDate: this.pageForm.dateRange[0],
endDate: this.pageForm.dateRange[1]
endDate: this.pageForm.dateRange[1],
unionId: this.pageForm.unionId,
clubId: this.pageForm.clubId
})
.then((res) => {
if (res.code === 0) {
@@ -312,7 +334,9 @@ layout("/layouts/platform.html"){
this.$axios
.post("/platform/article/analysis/distribution", {
startDate: this.pageForm.dateRange[0],
endDate: this.pageForm.dateRange[1]
endDate: this.pageForm.dateRange[1],
unionId: this.pageForm.unionId,
clubId: this.pageForm.clubId
})
.then((res) => {
if (res.code === 0) {
@@ -333,6 +357,32 @@ layout("/layouts/platform.html"){
})
},
initClubDistributionChart() {
this.$axios
.post("/platform/article/analysis/clubDistribution", {
startDate: this.pageForm.dateRange[0],
endDate: this.pageForm.dateRange[1],
unionId: this.pageForm.unionId,
clubId: this.pageForm.clubId
})
.then((res) => {
if (res.code === 0) {
clubDistributionChart && clubDistributionChart.destroy()
clubDistributionChart = new G2Plot.Pie("clubPieChart", {
data: res.data,
angleField: "value",
colorField: "type",
radius: 0.8,
label: {
type: "outer",
content: "{name} {percentage}"
}
})
clubDistributionChart.render()
}
})
},
loadRankingData() {
this.rankingData =
this.rankingTab === "person"
@@ -361,7 +411,12 @@ layout("/layouts/platform.html"){
},
overview() {
this.$axios.post("/platform/article/analysis/overview").then((res) => {
this.$axios.post("/platform/article/analysis/overview", {
startDate: this.pageForm.dateRange[0],
endDate: this.pageForm.dateRange[1],
unionId: this.pageForm.unionId,
clubId: this.pageForm.clubId
}).then((res) => {
if (res.code === 0) {
this.statCards = res.data
}
@@ -371,12 +426,13 @@ layout("/layouts/platform.html"){
mounted() {
this.initTrendChart()
this.initDistributionChart()
this.initClubDistributionChart()
this.loadRankingData()
this.overview()
},
created() {
this.$businessTool.listClub().then((res) => (this.clubOptions = res))
this.$businessTool.listUnit().then((res) => (this.departments = res))
this.$businessTool.listClub().then((res) => this.$set(this, "clubOptions", res))
this.$businessTool.listUnion().then((res) => this.$set(this, "unionOptions", res))
}
})
</script>
@@ -34,6 +34,159 @@ layout("/layouts/platform.html"){
<material-info ref="materialInfoRef"></material-info>
</div>
<style nonce="${cspNonce!}">
.material-write-dialog,
.material-view-dialog {
max-width: 1080px;
margin-top: 7vh !important;
border-radius: 4px;
}
.material-write-dialog .el-dialog__header,
.material-view-dialog .el-dialog__header {
padding: 14px 16px;
border-bottom: 1px solid #ebeef5;
}
.material-write-dialog .el-dialog__title,
.material-view-dialog .el-dialog__title {
font-size: 15px;
font-weight: 600;
color: #303133;
}
.material-write-dialog .el-dialog__body,
.material-view-dialog .el-dialog__body {
max-height: calc(86vh - 112px);
padding: 14px 16px 16px;
overflow-y: auto;
}
.material-write-dialog .time-warning {
margin: 0 0 12px;
padding: 10px 12px;
border: 1px solid #ffd8d8;
border-left: 3px solid #f56c6c;
border-radius: 3px;
background: #fff7f7;
color: #cf1322;
font-size: 13px;
line-height: 20px;
}
.material-write-dialog .upload-list,
.material-view-dialog .upload-list {
margin-bottom: 12px;
}
.material-write-dialog .upload-item,
.material-view-dialog .upload-item {
margin-bottom: 12px;
padding: 14px;
border: 1px solid #ebeef5;
border-radius: 6px;
background: #ffffff;
transition: border-color 0.2s, box-shadow 0.2s;
}
.material-write-dialog .upload-item:first-child,
.material-view-dialog .upload-item:first-child {
border-color: #5b9ef4;
}
.material-write-dialog .upload-item:hover,
.material-view-dialog .upload-item:hover {
border-color: #5b9ef4;
box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1);
}
.material-write-dialog .upload-item-title,
.material-view-dialog .upload-item-title {
display: flex;
align-items: center;
gap: 7px;
margin-bottom: 10px;
color: #303133;
font-size: 14px;
font-weight: 600;
line-height: 20px;
}
.material-write-dialog .upload-item-title i,
.material-view-dialog .upload-item-title i {
color: #1677c8;
}
.material-write-dialog .upload-hint {
margin-bottom: 10px;
padding: 8px 10px;
border-left: 2px solid #409eff;
border-radius: 2px;
background: #eff6ff;
color: #5f6b7a;
font-size: 13px;
line-height: 20px;
}
.material-write-dialog .upload-hint a {
color: #1677c8;
font-weight: 600;
text-decoration: none;
}
.material-write-dialog .upload-hint a:hover {
text-decoration: underline;
}
.material-write-dialog .el-upload__tip {
margin-top: 7px;
color: #909399;
font-size: 12px;
line-height: 18px;
}
.material-write-dialog .notice-box {
margin: 14px 0 0;
padding: 10px 12px;
border: 1px solid #ffe3a0;
border-left: 3px solid #e6a23c;
border-radius: 3px;
background: #fff9e8;
color: #7a5a17;
font-size: 13px;
line-height: 20px;
}
.material-write-dialog .notice-box i {
margin-right: 6px;
color: #e6a23c;
}
.material-write-dialog .el-dialog__footer {
padding: 10px 16px;
border-top: 1px solid #ebeef5;
}
@media screen and (max-width: 768px) {
.material-write-dialog,
.material-view-dialog {
width: calc(100% - 24px) !important;
margin-top: 12px !important;
}
.material-write-dialog .el-dialog__body,
.material-view-dialog .el-dialog__body {
max-height: calc(100vh - 118px);
padding: 12px;
}
.material-write-dialog .upload-item,
.material-view-dialog .upload-item {
padding: 12px;
}
}
</style>
<script nonce="${cspNonce!}">
<!--#include("write.js"){}#-->
<!--#include("./query/info.js"){}#-->
@@ -14,7 +14,7 @@ layout("/layouts/platform.html"){
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="数据列表">
<el-button size="small" type="primary" icon="el-icon-download" @click="exportZip">导出汇总表</el-button>
<el-button size="small" type="primary" icon="el-icon-download" @click="exportZip">导出汇总表Zip</el-button>
</table-tool>
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder" ref="table" row-key="id" style="width: 100%">
<el-table-column :index="indexMethod" align="center" header-align="center" label="序号" type="index" width="80px"></el-table-column>
@@ -71,6 +71,10 @@ layout("/layouts/platform.html"){
})
},
exportZip(){
if (!this.pageForm.actId) {
this.$message.warning("请先选择评比事项")
return
}
this.$downLoad('/platform/buildHome/material/query/exportZip', this.pageForm)
}
},
@@ -1,6 +1,6 @@
const info = {
template: /*language=HTML*/ `
<el-dialog title="查看详情" :visible.sync="visible" width="50%">
<el-dialog title="查看详情" :visible.sync="visible" width="80%" custom-class="material-view-dialog">
<div class="upload-list">
<div class="upload-item">
<div class="upload-item-title">
@@ -1,6 +1,6 @@
const write = {
template: /*language=HTML*/ `
<el-dialog :title="dialogTitle" :visible.sync="visible" width="70%">
<el-dialog :title="dialogTitle" :visible.sync="visible" width="80%" custom-class="material-write-dialog">
<div class="time-warning" v-if="activity && !isWithinTimeRange">
当前时间不在提交时间范围内,无法提交材料。提交时间:
@@ -94,8 +94,6 @@ const write = {
<strong>重要提示:</strong>
建家记录册、教职工之家建设考核评议自评表需由党委主要负责人签字盖章后扫描件上传
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="visible = false">取 消</el-button>
<el-button type="primary" @click="onSubmit" :disabled="!isWithinTimeRange">提交评比材料</el-button>
@@ -28,7 +28,7 @@ layout("/layouts/platform.html"){
<el-table-column prop="name" label="单位名称" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column prop="code" label="单位编码" sortable="custom" width="150px"></el-table-column>
<!-- <el-table-column prop="branchSchoolLeader" label="分管校领导及联系方式" width="180px"></el-table-column>-->
<el-table-column prop="unitLeader" label="单位领导及联系方式" sortable="custom" width="180px" show-overflow-tooltip></el-table-column>
<el-table-column prop="unitLeader" label="单位领导" sortable="custom" width="180px" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" width="350px">
<template slot-scope="{row}">
<!-- <el-button size="mini" type="primary" @click="$refs.userRef.onOpen(row.id,true)">设置分管校领导</el-button>-->
@@ -62,7 +62,10 @@ const pushAttendanceDialog = {
}
},
filterMethod(query, item) {
return item.userName.indexOf(query) > -1
// 代表预选支持按姓名或工号筛选,兼容人员信息字段为空的情况。
const userName = item.userName || ""
const loginName = item.loginName || ""
return userName.indexOf(query) > -1 || loginName.indexOf(query) > -1
},
async onConfirm() {
const loading = createLoading('正在提交中')
@@ -79,7 +79,10 @@ const pushFormalDialog = {
}
},
filterMethod(query, item) {
return item.userName.indexOf(query) > -1
// 代表预选支持按姓名或工号筛选,兼容人员信息字段为空的情况。
const userName = item.userName || ""
const loginName = item.loginName || ""
return userName.indexOf(query) > -1 || loginName.indexOf(query) > -1
},
async onConfirm() {
const loading = createLoading('正在提交中')