commit
This commit is contained in:
+162
@@ -0,0 +1,162 @@
|
||||
package com.budwk.app.zhgh.democratic.teachercongress.delegate.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.sys.views.View_user;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegate.models.TeacherCongressDelegatePush;
|
||||
import com.budwk.app.zhgh.democratic.teachercongress.delegate.models.Teacher_congress_delegate;
|
||||
import io.swagger.annotations.Api;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
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.aop.Aop;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.Period;
|
||||
import java.time.ZoneId;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author zhf
|
||||
* @date 2025/9/22 20:41
|
||||
* @description
|
||||
*/
|
||||
@IocBean
|
||||
@At("/platform/teacherCongress/delegate/push")
|
||||
@Ok("json:full")
|
||||
@Api(value = "/platform/teacherCongress/delegate/push", tags = "教代会代表推选")
|
||||
public class TeacherCongressDelegatePushController {
|
||||
|
||||
@Inject
|
||||
private Dao dao;
|
||||
|
||||
@Inject
|
||||
private BaseService baseService;
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/zhgh/democratic/teachercongress/delegate/push/index.html")
|
||||
@SaCheckPermission("tc.delegate.push")
|
||||
public void index() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取本分工会下的非代表用户
|
||||
*
|
||||
* @param sessionId
|
||||
* @return
|
||||
*/
|
||||
@At
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@SaCheckPermission("tc.delegate.push")
|
||||
@SLog(tag = "民主管理-教代会代表推选", msg = "获取本分工会下的非代表用户")
|
||||
public Result getUnionUser(String sessionId, String unionId) {
|
||||
// 查询预选中的代表
|
||||
Cnd cndx = Cnd.where("sessionId", "=", sessionId);
|
||||
cndx.andEX("unionId", "=", SecurityUtil.getUnionId());
|
||||
List<Teacher_congress_delegate> delegateList = dao.query(Teacher_congress_delegate.class, cndx);
|
||||
// u.professionalTitle,
|
||||
// u.professionalLevel,
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
u.id AS userId,
|
||||
u.loginname as loginName,
|
||||
u.username as userName,
|
||||
|
||||
u.sex,
|
||||
u.birthday,
|
||||
u.nation,
|
||||
TIMESTAMPDIFF(YEAR, u.birthday, CURDATE()) AS age
|
||||
FROM
|
||||
`vw_user` u
|
||||
LEFT JOIN teacher_congress_delegate tcd ON tcd.userId = u.id
|
||||
AND tcd.sessionId = @sessionId
|
||||
LEFT JOIN teacher_congress_delegate_push tcdp ON tcdp.userId = tcdp.id
|
||||
AND tcdp.sessionId = @sessionId
|
||||
$condition
|
||||
""");
|
||||
sql.setParam("sessionId", sessionId);
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.and("u.member", "=", 1);
|
||||
cnd.and("tcd.userId", "is", null);
|
||||
cnd.and("tcdp.id", "is", null);
|
||||
cnd.and("u.unionId", "=", SecurityUtil.getUnionId());
|
||||
sql.setCondition(cnd);
|
||||
List userList = baseService.listMap(sql);
|
||||
return Result.success(Map.of("userData", userList, "userValue", delegateList));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 推选代表
|
||||
*/
|
||||
@At
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public Object addPreselectionDb(@Param("userValue") String[] userValue, String sessionId, String representativeType) {
|
||||
List<TeacherCongressDelegatePush> list = new ArrayList<>();
|
||||
for (String id : userValue) {
|
||||
View_user user = dao.fetch(View_user.class, Cnd.where("id", "=", id));
|
||||
|
||||
TeacherCongressDelegatePush tmd = new TeacherCongressDelegatePush();
|
||||
tmd.setUserId(user.getId());
|
||||
tmd.setSessionId(sessionId);
|
||||
tmd.setDelegationId(null);
|
||||
tmd.setUserName(user.getUsername());
|
||||
tmd.setLoginName(user.getLoginname());
|
||||
tmd.setSex(user.getSex());
|
||||
tmd.setNation(user.getNation());
|
||||
tmd.setEducation(user.getEducation());
|
||||
tmd.setAcademicDegree(user.getAcademicDegree());
|
||||
tmd.setPolitical(user.getPolitical());
|
||||
tmd.setProfessionalTitle(user.getProfessionalTitle());
|
||||
tmd.setProfessionalLevel(user.getProfessionalLevel());
|
||||
|
||||
tmd.setBirthday(user.getBirthday());
|
||||
tmd.setUnitId(user.getUnitId());
|
||||
tmd.setUnitName(user.getUnitName());
|
||||
tmd.setUnionId(user.getUnionId());
|
||||
tmd.setUnionName(user.getUnionName());
|
||||
|
||||
tmd.setOrdinaryTeacher(false);
|
||||
tmd.setSeniorTeacher(false);
|
||||
tmd.setSchoolLeader(false);
|
||||
tmd.setMiddleLevelLeader(false);
|
||||
|
||||
tmd.setMobile(user.getMobile());
|
||||
|
||||
tmd.setIsJdh(true);
|
||||
tmd.setIsGdh(false);
|
||||
tmd.setRepresentativeType(representativeType);
|
||||
if (ObjectUtil.isNotEmpty(user.getBirthday())) {
|
||||
Date birthdayDate = user.getBirthday();
|
||||
LocalDate birthday = birthdayDate.toInstant()
|
||||
.atZone(ZoneId.systemDefault())
|
||||
.toLocalDate();
|
||||
|
||||
LocalDate currentDate = LocalDate.now();
|
||||
int age = Period.between(birthday, currentDate).getYears();
|
||||
tmd.setAge(age);
|
||||
}
|
||||
tmd.setPushTime(new Date());
|
||||
list.add(tmd);
|
||||
}
|
||||
dao.insert(list);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
package com.budwk.app.zhgh.democratic.teachercongress.delegate.models;
|
||||
|
||||
import com.budwk.app.base.model.BaseModel;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author zhf
|
||||
* @date 2025/9/22 20:40
|
||||
* @description 代表推选表
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Table("teacher_congress_delegate_push")
|
||||
@TableMeta("{'mysql-charset':'utf8mb4'}")
|
||||
@Comment("代表推选表")
|
||||
public class TeacherCongressDelegatePush extends BaseModel {
|
||||
|
||||
@Name
|
||||
@Comment("ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@PrevInsert(uu32 = true)
|
||||
private String id;
|
||||
|
||||
@Column
|
||||
@Comment("代表用户ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String userId;
|
||||
|
||||
@Column
|
||||
@Comment("所属教代会ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String sessionId;
|
||||
|
||||
@Column
|
||||
@Comment("所属代表团 当用户为校领导是该字段不为空")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String delegationId;
|
||||
|
||||
@Column
|
||||
@Comment("姓名")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||
private String userName;
|
||||
|
||||
@Column
|
||||
@Comment("工号")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||
private String loginName;
|
||||
|
||||
@Column
|
||||
@Comment("性别")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 2)
|
||||
private String sex;
|
||||
|
||||
@Column
|
||||
@Comment("出生日期")
|
||||
@ColDefine(type = ColType.DATETIME)
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private Date birthday;
|
||||
|
||||
@Column
|
||||
@Comment("民族")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 10)
|
||||
private String nation;
|
||||
|
||||
@Column
|
||||
@Comment("政治面貌")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||
private String political;
|
||||
|
||||
@Column
|
||||
@Comment("学历")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||
private String education;
|
||||
|
||||
@Column
|
||||
@Comment("学位")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
private String academicDegree;
|
||||
|
||||
@Column
|
||||
@Comment("职称")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
private String professionalTitle;
|
||||
|
||||
@Column
|
||||
@Comment("职级")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
private String professionalLevel;
|
||||
|
||||
@Column
|
||||
@Comment("是否专任教师")
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
@Default("0")
|
||||
private Boolean ordinaryTeacher;
|
||||
|
||||
@Column
|
||||
@Comment("是否高级职称专任教师")
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
@Default("0")
|
||||
private Boolean seniorTeacher;
|
||||
|
||||
@Column
|
||||
@Comment("是否校领导")
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
@Default("0")
|
||||
private Boolean schoolLeader;
|
||||
|
||||
@Column
|
||||
@Comment("是否中层领导")
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
@Default("0")
|
||||
private Boolean middleLevelLeader;
|
||||
|
||||
@Column
|
||||
@Comment("行政职称===>position")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
private String administrativeTitle;
|
||||
|
||||
@Column
|
||||
@Comment("年龄")
|
||||
@ColDefine(type = ColType.INT)
|
||||
private Integer age;
|
||||
|
||||
@Column
|
||||
@Comment("单位ID")
|
||||
@ColDefine(type = ColType.VARCHAR)
|
||||
private String unitId;
|
||||
|
||||
@Column
|
||||
@Comment("单位名称")
|
||||
@ColDefine(type = ColType.VARCHAR)
|
||||
private String unitName;
|
||||
|
||||
@Column
|
||||
@Comment("分工会ID")
|
||||
@ColDefine(type = ColType.VARCHAR)
|
||||
private String unionId;
|
||||
|
||||
@Column
|
||||
@Comment("分工会名称")
|
||||
@ColDefine(type = ColType.VARCHAR)
|
||||
private String unionName;
|
||||
|
||||
@Column
|
||||
@Comment("手机号")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
private String mobile;
|
||||
|
||||
@Column
|
||||
@Comment("推送时间")
|
||||
@ColDefine(type = ColType.DATETIME)
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date pushTime;
|
||||
|
||||
|
||||
@Column
|
||||
@Comment("教代会代表类型")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String roleId;
|
||||
|
||||
@Column
|
||||
@Comment("教代会")
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
private Boolean isJdh;
|
||||
|
||||
@Column
|
||||
@Comment("工代会")
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
private Boolean isGdh;
|
||||
|
||||
@Column
|
||||
@Comment("备注")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||
private String bz;
|
||||
|
||||
@Column
|
||||
@Comment("代表类型(正式代表 列席代表)")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 4)
|
||||
private String representativeType;
|
||||
}
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<div id="app" v-cloak>
|
||||
<el-card shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="姓名/工号">
|
||||
<el-input placeholder="请输入内容" clearable v-model="pageForm.searchKeyword"></el-input>
|
||||
</search-item>
|
||||
<search-item label="教代会">
|
||||
<el-select v-model="pageForm.sessionId" @change="sessionChange">
|
||||
<el-option v-for="item in sessionOptions" :label="item.fullName" :value="item.id"
|
||||
:key="item.id"></el-option>
|
||||
</el-select>
|
||||
</search-item>
|
||||
<search-item label="分工会">
|
||||
<el-select v-model="pageForm.unionId" filterable @change="listUnit" clearable style="width: 100%">
|
||||
<el-option v-for="i in unionOptions" :label="i.name" :key="i.id" :value="i.id"></el-option>
|
||||
</el-select>
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never">
|
||||
<push-progress ref="pushProgressRef"></push-progress>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never">
|
||||
<table-tool>
|
||||
<el-button
|
||||
icon="el-icon-plus"
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="$refs.pushFormalRef.onOpen(pageForm.sessionId,pageForm.unionId)"
|
||||
>正式代表预选
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="el-icon-plus"
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="$refs.pushAttendanceRef.onOpen(pageForm.sessionId,pageForm.unionId)"
|
||||
>列席代表预选
|
||||
</el-button>
|
||||
<el-button icon="el-icon-download" size="small" type="primary" @click="doExport">导出</el-button>
|
||||
|
||||
<el-button icon="el-icon-check" size="small" type="primary" @click="onBatchSubmit">正式代表提交上报
|
||||
</el-button>
|
||||
|
||||
<el-radio-group v-model="pageForm.isFormalOrAttendance" size="small" class="ml10"
|
||||
@change="doSearch">
|
||||
<el-radio-button label="全部"></el-radio-button>
|
||||
<el-radio-button label="正式代表"></el-radio-button>
|
||||
<el-radio-button label="列席代表"></el-radio-button>
|
||||
</el-radio-group>
|
||||
</table-tool>
|
||||
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="tableData"
|
||||
row-key="id"
|
||||
@sort-change="pageOrder"
|
||||
>
|
||||
<el-table-column type="selection" width="55" reserve-selection fixed="left"></el-table-column>
|
||||
<el-table-column type="index" width="55" label="序号" :index="indexMethod" fixed="left"></el-table-column>
|
||||
<el-table-column label="姓名" prop="userName" width="100" fixed="left"></el-table-column>
|
||||
<el-table-column label="年龄" prop="age" width="100"></el-table-column>
|
||||
<el-table-column label="性别" prop="sex" width="100" fixed="left"></el-table-column>
|
||||
<el-table-column label="民族" prop="nation" min-width="100"></el-table-column>
|
||||
<el-table-column label="职称" prop="jobTitle" min-width="150"></el-table-column>
|
||||
<el-table-column label="职级" prop="jobTitleLevel" min-width="100"></el-table-column>
|
||||
<el-table-column label="校级领导" prop="schoolLeader" min-width="100">
|
||||
<template scope="{row}">
|
||||
<el-checkbox
|
||||
v-if="row"
|
||||
v-model="row.schoolLeader"
|
||||
:style="{'pointer-events':row.stateCode===0?'auto':'none'}"
|
||||
></el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="中层领导" prop="middleLevelLeader" min-width="100">
|
||||
<template scope="{row}">
|
||||
<el-checkbox
|
||||
v-if="row"
|
||||
v-model="row.middleLevelLeader"
|
||||
:style="{'pointer-events':row.stateCode===0?'auto':'none'}"
|
||||
></el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="专任教师" prop="ordinaryTeacher" min-width="100">
|
||||
<template scope="{row}">
|
||||
<el-checkbox
|
||||
v-if="row"
|
||||
v-model="row.ordinaryTeacher"
|
||||
:style="{'pointer-events':row.stateCode===0?'auto':'none'}"
|
||||
></el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="高级职称专任教师" prop="seniorTeacher" min-width="150">
|
||||
<template scope="{row}">
|
||||
<el-checkbox
|
||||
v-if="row"
|
||||
v-model="row.seniorTeacher"
|
||||
style="pointer-events:none"
|
||||
></el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="教代会代表" prop="isJdh" min-width="100">
|
||||
<template scope="{row}">
|
||||
<el-checkbox
|
||||
v-if="row"
|
||||
v-model="row.isJdh"
|
||||
:style="{'pointer-events':row.stateCode===0?'auto':'none'}"
|
||||
></el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="工代会代表" prop="isGdh" min-width="100">
|
||||
<template scope="{row}">
|
||||
<el-checkbox
|
||||
v-if="row"
|
||||
v-model="row.isGdh"
|
||||
:style="{'pointer-events':row.stateCode===0?'auto':'none'}"
|
||||
></el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="代表类型" prop="representativeType" show-overflow-tooltip width="100"
|
||||
fixed="right"></el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
|
||||
<push-formal-dialog ref="pushFormalRef" @refresh="doSearch"></push-formal-dialog>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
<!--#include('push-progress.js'){}#-->
|
||||
<!--#include('push-formal-dialog.js'){}#-->
|
||||
|
||||
new Vue({
|
||||
el: '#app',
|
||||
mixins: [initTableMixins],
|
||||
components: {
|
||||
'push-progress': pushProgress,
|
||||
'push-formal-dialog': pushFormalDialog,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
sessionOptions:[],
|
||||
unionOptions:[]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
listUnion() {
|
||||
this.$businessTool.listUnion().then((res) => {
|
||||
this.unionOptions = res
|
||||
})
|
||||
},
|
||||
listSession() {
|
||||
this.$axios.post("/platform/teacherCongress/common/listSession").then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.sessionOptions = res.data
|
||||
if (this.sessionOptions && this.sessionOptions.length > 0) {
|
||||
this.pageForm.sessionId = this.sessionOptions[0].id
|
||||
// this.pageData()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.listUnion()
|
||||
this.listSession()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
const pushFormalDialog = {
|
||||
template: /*language=HTML*/ `
|
||||
<el-dialog :close-on-click-modal="false"
|
||||
:visible.sync="dialogVisible"
|
||||
title="正式代表预选"
|
||||
class="push-formal-dialog"
|
||||
width="70%">
|
||||
<el-transfer
|
||||
ref="transfer"
|
||||
v-model="userValue"
|
||||
:data="userData"
|
||||
:filter-method="filterMethod"
|
||||
:props="{key: 'id',label: 'name'}"
|
||||
:titles="['可报人员名单', '当前选择']"
|
||||
filterable
|
||||
>
|
||||
<div slot-scope="{ option }">
|
||||
<div class="transfer-item">
|
||||
<div class="transfer-item-name">{{ option.userName }} - {{ option.loginName }}</div>
|
||||
<div class="transfer-item-details">
|
||||
<span class="detail-item">{{ option.sex}}</span>
|
||||
<span class="detail-item" v-if="option.age">{{ option.age }}岁</span>
|
||||
<span class="detail-item" v-if="option.jobTitle">{{ option.jobTitle }}</span>
|
||||
<span class="detail-item" v-if="option.jobTitleLevel">{{ option.jobTitleLevel }}</span>
|
||||
<span class="detail-item" v-if="option.nation">{{ option.nation }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-transfer>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="onConfirm">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
userValue: [],
|
||||
userData: [],
|
||||
rightChecked: [],
|
||||
attendanceRightChecked: [],
|
||||
sessionId: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onOpen(sessionId, unionId) {
|
||||
this.dialogVisible = true
|
||||
this.sessionId = sessionId
|
||||
this.userValue = []
|
||||
this.userData = []
|
||||
const {code, data} = await $.get('/platform/teacherCongress/delegate/push/getUnionUser', {
|
||||
sessionId: sessionId,
|
||||
unionId: unionId
|
||||
})
|
||||
if (code === 0) {
|
||||
data.userData.forEach(v => {
|
||||
this.userData.push({id: v.userId, ...v})
|
||||
})
|
||||
}
|
||||
},
|
||||
filterMethod(query, item) {
|
||||
return item.userName.indexOf(query) > -1
|
||||
},
|
||||
async onConfirm() {
|
||||
const {code, msg} = await $.post('/platform/teacherCongress/delegate/push/addPreselectionDb', {
|
||||
userValue: JSON.stringify(this.userValue),
|
||||
sessionId: this.sessionId,
|
||||
representativeType: '正式代表'
|
||||
})
|
||||
if (code === 0) {
|
||||
this.dialogVisible = false
|
||||
this.$message.success(msg)
|
||||
this.$emit('refresh')
|
||||
}
|
||||
}
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
.push-formal-dialog ::v-deep .el-transfer{
|
||||
text-align: center!important;
|
||||
}
|
||||
|
||||
.push-formal-dialog ::v-deep .el-transfer-panel__item.el-checkbox {
|
||||
height: auto;
|
||||
display: block;
|
||||
margin-right: 0;
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
.push-formal-dialog ::v-deep .el-checkbox__input {
|
||||
vertical-align: top;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.push-formal-dialog ::v-deep .transfer-item {
|
||||
padding: 5px;
|
||||
font-size: 12px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.push-formal-dialog ::v-deep .transfer-item-name {
|
||||
font-weight: bold;
|
||||
margin-bottom: 3px;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.push-formal-dialog ::v-deep .transfer-item-details {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.push-formal-dialog ::v-deep .detail-item {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.push-formal-dialog ::v-deep .el-transfer-panel{
|
||||
height: 60vh;
|
||||
text-align: left !important;
|
||||
width: 35% !important;
|
||||
}
|
||||
|
||||
.push-formal-dialog ::v-deep .el-transfer-panel__body {
|
||||
height: calc(100% - 40px) !important;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.push-formal-dialog ::v-deep .el-transfer-panel__list.is-filterable {
|
||||
flex: 1;
|
||||
}
|
||||
`
|
||||
}
|
||||
+575
@@ -0,0 +1,575 @@
|
||||
const pushProgress = {
|
||||
template: /*language=HTML*/ `
|
||||
<div class="representative-allocation">
|
||||
<div class="container-x">
|
||||
<!-- 主卡片 -->
|
||||
<div class="card">
|
||||
<div class="header-x">
|
||||
<div class="title">
|
||||
<h1>正式代表名额分配概况</h1>
|
||||
<p>{{teacherMeetName}}教职工代表大会代表名额分配情况</p>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<!-- <el-button type="primary" icon="el-icon-download">导出数据</el-button>-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid-cols-3" style="grid-template-columns: repeat(8,1fr)">
|
||||
<!-- 总代表数 -->
|
||||
<div class="metric-card">
|
||||
<div class="metric-header">
|
||||
<div>
|
||||
<div class="metric-title">总代表数</div>
|
||||
<div class="metric-value">
|
||||
{{ metrics.total.current }}
|
||||
<span class="metric-target">
|
||||
/ {{ metrics.total.target }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="metric-icon bg-primary-light">
|
||||
<i class="fas fa-users text-primary"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-bar-inner bg-success"
|
||||
:style="{width: metrics.total.progress * 100 + '%'}"></div>
|
||||
</div>
|
||||
<div class="progress-info">
|
||||
<span v-if="metrics.total.progress>1" class="text-danger">
|
||||
已超出
|
||||
</span>
|
||||
<span v-else-if="metrics.total.progress<1" class="text-primary">
|
||||
未达标
|
||||
</span>
|
||||
<span v-else class="text-success">
|
||||
已达标
|
||||
</span>
|
||||
<!-- <span class="text-gray-500" v-if="metrics.total.progress<1">剩余 {{ metrics.total.remaining }} 人</span>-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 高级职称专任教师代表数 -->
|
||||
<div class="metric-card">
|
||||
<div class="metric-header">
|
||||
<div>
|
||||
<div class="metric-title">高级职称专任教师</div>
|
||||
<div class="metric-value">{{ metrics.seniorTeacher.current }}<span
|
||||
class="metric-target"
|
||||
>/ {{ metrics.seniorTeacher.target }}</span></div>
|
||||
</div>
|
||||
<div class="metric-icon bg-primary-light">
|
||||
<i class="fas fa-user-tie text-primary"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-bar-inner bg-primary"
|
||||
:style="{width: metrics.seniorTeacher.progress * 100 + '%'}"></div>
|
||||
</div>
|
||||
<div class="progress-info">
|
||||
<span v-if="metrics.seniorTeacher.progress>=1 || metrics.seniorTeacher.target===0"
|
||||
class="text-success">
|
||||
已达标
|
||||
</span>
|
||||
<span v-else-if="metrics.seniorTeacher.progress<1" class="text-primary">
|
||||
未达标
|
||||
</span>
|
||||
<span
|
||||
v-if="metrics.seniorTeacher.remaining>0"
|
||||
class="text-gray-500"
|
||||
>剩余 {{ metrics.seniorTeacher.remaining }} 人</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 专任教师代表数 -->
|
||||
<div class="metric-card">
|
||||
<div class="metric-header">
|
||||
<div>
|
||||
<div class="metric-title">专任教师代表</div>
|
||||
<div class="metric-value">{{ metrics.ordinaryTeacher.current }}<span
|
||||
class="metric-target"
|
||||
>/ {{ metrics.ordinaryTeacher.target }}</span></div>
|
||||
</div>
|
||||
<div class="metric-icon bg-primary-light">
|
||||
<i class="fas fa-chalkboard-teacher text-primary"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress-bar">
|
||||
<div
|
||||
class="progress-bar-inner bg-primary"
|
||||
:style="{width: metrics.ordinaryTeacher.progress * 100 + '%'}"
|
||||
></div>
|
||||
</div>
|
||||
<div class="progress-info">
|
||||
<span v-if="metrics.ordinaryTeacher.progress>=1 || metrics.ordinaryTeacher.target===0"
|
||||
class="text-success">
|
||||
已达标
|
||||
</span>
|
||||
<span v-else-if="metrics.ordinaryTeacher.progress<1" class="text-primary">
|
||||
未达标
|
||||
</span>
|
||||
<span
|
||||
v-if="metrics.ordinaryTeacher.remaining>0"
|
||||
class="text-gray-500"
|
||||
>剩余 {{ metrics.ordinaryTeacher.remaining }} 人</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 女代表数 -->
|
||||
<div class="metric-card">
|
||||
<div class="metric-header">
|
||||
<div>
|
||||
<div class="metric-title">女代表数</div>
|
||||
<div class="metric-value">{{ metrics.female.current }}<span
|
||||
class="metric-target"
|
||||
>/ {{ metrics.female.target }}</span></div>
|
||||
</div>
|
||||
<div class="metric-icon bg-warning-light">
|
||||
<i class="fas fa-female text-warning"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress-bar">
|
||||
<div
|
||||
class="progress-bar-inner bg-primary"
|
||||
:style="{width: metrics.female.progress * 100 + '%'}"
|
||||
></div>
|
||||
</div>
|
||||
<div class="progress-info">
|
||||
<span v-if="metrics.female.progress>=1 || metrics.female.target===0"
|
||||
class="text-success">
|
||||
已达标
|
||||
</span>
|
||||
<span v-else-if="metrics.female.progress<1" class="text-primary">
|
||||
未达标
|
||||
</span>
|
||||
<span v-if="metrics.female.remaining>0" class="text-gray-500">剩余 {{
|
||||
metrics.female.remaining
|
||||
}} 人</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 45岁以下代表数 -->
|
||||
<div class="metric-card">
|
||||
<div class="metric-header">
|
||||
<div>
|
||||
<div class="metric-title">45岁以下代表</div>
|
||||
<div class="metric-value">{{ metrics.under45.current }}<span
|
||||
class="metric-target"
|
||||
>/ {{ metrics.under45.target }}</span></div>
|
||||
</div>
|
||||
<div class="metric-icon bg-primary-light">
|
||||
<i class="fas fa-user-graduate text-primary"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-bar-inner bg-primary"
|
||||
:style="{width: metrics.under45.progress * 100 + '%'}"></div>
|
||||
</div>
|
||||
<div class="progress-info">
|
||||
<span v-if="metrics.under45.progress>=1 || metrics.under45.target===0"
|
||||
class="text-success">
|
||||
已达标
|
||||
</span>
|
||||
<span v-else-if="metrics.under45.progress<1" class="text-primary">
|
||||
未达标
|
||||
</span>
|
||||
<span v-if="metrics.under45.remaining>0" class="text-gray-500">剩余 {{
|
||||
metrics.under45.remaining
|
||||
}} 人</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 少数民族数 -->
|
||||
<div class="metric-card">
|
||||
<div class="metric-header">
|
||||
<div>
|
||||
<div class="metric-title">少数民族代表</div>
|
||||
<div class="metric-value">{{ metrics.ethnicMinority.current }}<span
|
||||
class="metric-target"
|
||||
>/ {{ metrics.ethnicMinority.target }}</span></div>
|
||||
</div>
|
||||
<div class="metric-icon bg-primary-light">
|
||||
<i class="fas fa-user-graduate text-primary"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-bar-inner bg-primary"
|
||||
:style="{width: metrics.ethnicMinority.progress * 100 + '%'}"></div>
|
||||
</div>
|
||||
<div class="progress-info">
|
||||
<span v-if="metrics.ethnicMinority.progress>=1 || metrics.ethnicMinority.target===0"
|
||||
class="text-success">
|
||||
已达标
|
||||
</span>
|
||||
<span v-else-if="metrics.ethnicMinority.progress<1" class="text-primary">
|
||||
未达标
|
||||
</span>
|
||||
<span v-if="metrics.ethnicMinority.remaining>0" class="text-gray-500">剩余 {{
|
||||
metrics.ethnicMinority.remaining
|
||||
}} 人</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 校级领导 -->
|
||||
<div class="metric-card">
|
||||
<div class="metric-header">
|
||||
<div>
|
||||
<div class="metric-title">校级领导代表</div>
|
||||
<div class="metric-value">{{ metrics.schoolLeader.current }}<span
|
||||
class="metric-target"
|
||||
>/ {{ metrics.schoolLeader.target }}</span></div>
|
||||
</div>
|
||||
<div class="metric-icon bg-primary-light">
|
||||
<i class="fas fa-user-graduate text-primary"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-bar-inner bg-primary"
|
||||
:style="{width: metrics.schoolLeader.progress * 100 + '%'}"></div>
|
||||
</div>
|
||||
<div class="progress-info">
|
||||
<span v-if="metrics.schoolLeader.progress>=1 || metrics.schoolLeader.target===0"
|
||||
class="text-success">
|
||||
已达标
|
||||
</span>
|
||||
<span v-else-if="metrics.schoolLeader.progress<1" class="text-primary">
|
||||
未达标
|
||||
</span>
|
||||
<span v-if="metrics.schoolLeader.remaining>0" class="text-gray-500">剩余 {{
|
||||
metrics.schoolLeader.remaining
|
||||
}} 人</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 中层领导 -->
|
||||
<div class="metric-card">
|
||||
<div class="metric-header">
|
||||
<div>
|
||||
<div class="metric-title">中层领导</div>
|
||||
<div class="metric-value">{{ metrics.middleLevelLeader.current }}<span
|
||||
class="metric-target"
|
||||
>/ {{ metrics.middleLevelLeader.target }}</span></div>
|
||||
</div>
|
||||
<div class="metric-icon bg-primary-light">
|
||||
<i class="fas fa-user-graduate text-primary"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-bar-inner bg-primary"
|
||||
:style="{width: metrics.middleLevelLeader.progress * 100 + '%'}"></div>
|
||||
</div>
|
||||
<div class="progress-info">
|
||||
<span v-if="metrics.middleLevelLeader.progress>=1 || metrics.middleLevelLeader.target===0"
|
||||
class="text-success">
|
||||
已达标
|
||||
</span>
|
||||
<span v-else-if="metrics.middleLevelLeader.progress<1" class="text-primary">
|
||||
未达标
|
||||
</span>
|
||||
<span v-if="metrics.middleLevelLeader.remaining>0" class="text-gray-500">剩余 {{
|
||||
metrics.middleLevelLeader.remaining
|
||||
}} 人</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2 class="legend-title">指标说明</h2>
|
||||
<div class="legend-container">
|
||||
<div class="legend-item">
|
||||
<div class="legend-color bg-success"></div>
|
||||
<span class="legend-text">已达标:当前数量已达到或超过目标值</span>
|
||||
</div>
|
||||
<div class="legend-item">
|
||||
<div class="legend-color bg-primary"></div>
|
||||
<span class="legend-text">未达标:当前数量未达到目标值,但已有代表选派</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="update-time"></div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2 class="legend-title">上报说明</h2>
|
||||
<div class="legend-container">
|
||||
<div class="legend-item">
|
||||
<div class="legend-color bg-warning "></div>
|
||||
<span class="legend-text">正式代表完成信息填写后才能进行上报,列席代表可直接上报且不计入名额</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
props: {
|
||||
sessionId: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null
|
||||
},
|
||||
unionId: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
metrics: {
|
||||
total: {
|
||||
current: 15,
|
||||
target: 15,
|
||||
progress: 100,
|
||||
remaining: 0
|
||||
},
|
||||
female: {
|
||||
current: 3,
|
||||
target: 5,
|
||||
progress: 60,
|
||||
remaining: 2
|
||||
},
|
||||
seniorTeacher: {
|
||||
current: 4,
|
||||
target: 6,
|
||||
progress: 66.7,
|
||||
remaining: 2
|
||||
},
|
||||
ordinaryTeacher: {
|
||||
current: 8,
|
||||
target: 10,
|
||||
progress: 80,
|
||||
remaining: 2
|
||||
},
|
||||
under45: {
|
||||
current: 5,
|
||||
target: 7,
|
||||
progress: 71.4,
|
||||
remaining: 2
|
||||
},
|
||||
ethnicMinority:{
|
||||
current: 1,
|
||||
target: 2,
|
||||
progress: 50,
|
||||
remaining: 1
|
||||
},
|
||||
schoolLeader:{
|
||||
current: 2,
|
||||
target: 3,
|
||||
progress: 66.7,
|
||||
remaining: 1
|
||||
},
|
||||
middleLevelLeader:{
|
||||
current: 1,
|
||||
target: 2,
|
||||
progress: 33.3,
|
||||
remaining: 1
|
||||
}
|
||||
},
|
||||
teacherMeetName: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
sessionId(val) {
|
||||
this.refreshData()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async refreshData(sessionId, teacherMeetName, unionId) {
|
||||
this.teacherMeetName = teacherMeetName
|
||||
const {code, data} = await $.get('/platform/teacherCongress/delegate/push/selfUnionPushMetric', {
|
||||
teacherMeetId: sessionId,
|
||||
unionId: unionId
|
||||
})
|
||||
if (code === 0) {
|
||||
if (data) {
|
||||
this.metrics = data
|
||||
} else {
|
||||
this.$message.error('暂未分配名额')
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
.representative-allocation {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.representative-allocation .card {
|
||||
background-color: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.03);
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.representative-allocation .header-x {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.representative-allocation .header-x .title h1 {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.representative-allocation .header-x .title p {
|
||||
font-size: 14px;
|
||||
color: #6b7280;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.representative-allocation .buttons {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.representative-allocation .grid-cols-3 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(8, 1fr);
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.representative-allocation .metric-card {
|
||||
background-color: #f3f3f3;
|
||||
border-radius: 8px;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.representative-allocation .metric-card .metric-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.representative-allocation .metric-card .metric-header .metric-title {
|
||||
font-size: 14px;
|
||||
color: #6b7280;
|
||||
margin-bottom: 4px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.representative-allocation .metric-card .metric-header .metric-value {
|
||||
font-size: 30px;
|
||||
font-weight: 700;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.representative-allocation .metric-card .metric-header .metric-value .metric-target {
|
||||
font-size: 14px;
|
||||
color: #6b7280;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.representative-allocation .metric-card .metric-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.representative-allocation .progress-bar {
|
||||
height: 4px;
|
||||
border-radius: 2px;
|
||||
background-color: #f0f0f0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.representative-allocation .progress-bar .progress-bar-inner {
|
||||
height: 100%;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
.representative-allocation .progress-info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 8px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.representative-allocation .bg-primary {
|
||||
background-color: #1677ff;
|
||||
}
|
||||
|
||||
.representative-allocation .bg-primary-light {
|
||||
background-color: rgba(22, 119, 255, 0.1);
|
||||
}
|
||||
|
||||
.representative-allocation .text-primary {
|
||||
color: #1677ff;
|
||||
}
|
||||
|
||||
.representative-allocation .bg-secondary {
|
||||
background-color: #4096ff;
|
||||
}
|
||||
|
||||
.representative-allocation .bg-success {
|
||||
background-color: #52c41a;
|
||||
}
|
||||
|
||||
.representative-allocation .text-success {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
.representative-allocation .bg-warning {
|
||||
background-color: #faad14;
|
||||
}
|
||||
|
||||
.representative-allocation .text-warning {
|
||||
color: #faad14;
|
||||
}
|
||||
|
||||
.representative-allocation .bg-warning-light {
|
||||
background-color: rgba(250, 173, 20, 0.1);
|
||||
}
|
||||
|
||||
.representative-allocation .text-gray-500 {
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.representative-allocation .legend-title {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: #111827;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.representative-allocation .legend-container {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.representative-allocation .legend-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.representative-allocation .legend-item .legend-color {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.representative-allocation .legend-item .legend-text {
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.representative-allocation .update-time {
|
||||
font-size: 14px;
|
||||
color: #6b7280;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
`
|
||||
}
|
||||
Reference in New Issue
Block a user