# Conflicts:
#	src/test/java/com/budwk/app/WelfareTest.java
This commit is contained in:
那些花儿
2025-06-30 14:57:45 +08:00
33 changed files with 1697 additions and 297 deletions
@@ -173,10 +173,6 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
cnd = ConditionGroupUtil.applyConditionGroup(cnd, updateParam.getConditionGroup()); cnd = ConditionGroupUtil.applyConditionGroup(cnd, updateParam.getConditionGroup());
} }
// List<Map<String, String>> allList = ExcelImportUtil.importExcel(new File("C:\\Users\\jug\\Desktop\\南京师范蛋糕卡\\匹配上生日.xlsx"), Map.class, new ImportParams());
// List<String> loginNames = allList.stream().map(v -> v.get("工号")).toList();
// cnd.and("loginname", "in", loginNames);
List<Sys_user_source> sources = dao.query(Sys_user_source.class, cnd.groupBy("loginname")); List<Sys_user_source> sources = dao.query(Sys_user_source.class, cnd.groupBy("loginname"));
log.info("符合条件的数据源记录数: {}", sources.size()); log.info("符合条件的数据源记录数: {}", sources.size());
@@ -57,6 +57,6 @@ public class SysUserAllRenewJob implements Job {
param.setUpdateMode(SysDataUpdateMode.ALL.name()); param.setUpdateMode(SysDataUpdateMode.ALL.name());
param.setConditionGroup(conditionGroup); param.setConditionGroup(conditionGroup);
sysDataUserUpdateService.update(param); // sysDataUserUpdateService.update(param);
} }
} }
@@ -78,7 +78,8 @@ public class MemberInfoServiceImpl extends BaseServiceImpl<Sys_user> implements
unitId, unitId,
unitName, unitName,
education, education,
nation nation,
postDoctoralJoinDate
FROM FROM
vw_user vw_user
$condition $condition
@@ -142,7 +142,8 @@ public class MemberStatisticsServiceImpl extends BaseServiceImpl<Sys_user> imple
u.userState, u.userState,
u.unionName, u.unionName,
u.unitName, u.unitName,
u.member u.member,
u.postDoctoralJoinDate
FROM FROM
$table $table
$hisUser $hisUser
@@ -8,6 +8,7 @@ import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result; import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil; import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.welfare.model.WelfareList;
import com.budwk.app.zhgh.welfare.model.WelfareUserSelection; import com.budwk.app.zhgh.welfare.model.WelfareUserSelection;
import com.budwk.app.zhgh.welfare.param.WelfareSelectionSituationPageForm; import com.budwk.app.zhgh.welfare.param.WelfareSelectionSituationPageForm;
import com.budwk.app.zhgh.welfare.service.WelfareListService; import com.budwk.app.zhgh.welfare.service.WelfareListService;
@@ -84,6 +85,11 @@ public class WelfareSelectionSituationController {
@SLog(type = "welfare", tag = "选择福利", msg = "代选福利") @SLog(type = "welfare", tag = "选择福利", msg = "代选福利")
@SaCheckPermission("welfare.selection.situation") @SaCheckPermission("welfare.selection.situation")
public Result confirmSelect(@Param("selections") WelfareUserSelection[] selections, String projectId, String userId) { public Result confirmSelect(@Param("selections") WelfareUserSelection[] selections, String projectId, String userId) {
int count = dao.count(WelfareList.class, Cnd.where(WelfareList::getProjectId, "=", projectId).and(WelfareList::getUserId, "=", userId));
if(count==0){
return Result.error("此用户没有选择的权限");
}
//删除上次选择的 //删除上次选择的
dao.clear(WelfareUserSelection.class, Cnd.where(WelfareUserSelection::getWelfareId, "=", projectId).and(WelfareUserSelection::getSelectUserId, "=", userId)); dao.clear(WelfareUserSelection.class, Cnd.where(WelfareUserSelection::getWelfareId, "=", projectId).and(WelfareUserSelection::getSelectUserId, "=", userId));
for (WelfareUserSelection welfareUserSelection : selections) { for (WelfareUserSelection welfareUserSelection : selections) {
@@ -81,6 +81,11 @@ public class WelfareUserSelectController {
@SLog(type = "welfare", tag = "选择福利", msg = "福利") @SLog(type = "welfare", tag = "选择福利", msg = "福利")
@SaCheckPermission("welfare.user.select") @SaCheckPermission("welfare.user.select")
public Result confirmSelect(@Param("selections") WelfareUserSelection[] selections, String projectId) { public Result confirmSelect(@Param("selections") WelfareUserSelection[] selections, String projectId) {
int count = dao.count(WelfareList.class, Cnd.where(WelfareList::getProjectId, "=", projectId).and(WelfareList::getUserId, "=", SecurityUtil.getUserId()));
if(count==0){
return Result.error("您没有选择的权限");
}
//删除上次选择的 //删除上次选择的
dao.clear(WelfareUserSelection.class, Cnd.where(WelfareUserSelection::getWelfareId, "=", projectId).and(WelfareUserSelection::getSelectUserId, "=", SecurityUtil.getUserId())); dao.clear(WelfareUserSelection.class, Cnd.where(WelfareUserSelection::getWelfareId, "=", projectId).and(WelfareUserSelection::getSelectUserId, "=", SecurityUtil.getUserId()));
for (WelfareUserSelection welfareUserSelection : selections) { for (WelfareUserSelection welfareUserSelection : selections) {
@@ -536,7 +536,7 @@ public class WelfareListServiceImpl extends BaseServiceImpl<WelfareList> impleme
WelfareList wl = new WelfareList(); WelfareList wl = new WelfareList();
wl.setProjectId(pageForm.getProjectId()); wl.setProjectId(pageForm.getProjectId());
wl.setUserId(user.getString("id")); wl.setUserId(user.getString("id"));
wl.setWelfareUnitId(user.getString("unionId")); wl.setWelfareUnitId(user.getString("unitId"));
wl.setWelfareUnitName(user.getString("unitName")); wl.setWelfareUnitName(user.getString("unitName"));
wl.setWelfareUnionId(user.getString("unionId")); wl.setWelfareUnionId(user.getString("unionId"));
wl.setWelfareUnionName(user.getString("unionName")); wl.setWelfareUnionName(user.getString("unionName"));
@@ -60,7 +60,7 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
if (AuthUtil.hasRole(RoleConstant.BRANCH_UNION_CHAIRMAN.name())) { if (AuthUtil.hasRole(RoleConstant.BRANCH_UNION_CHAIRMAN.name()) || AuthUtil.hasRole(RoleConstant.BRANCH_UNION_OPERATOR.name())) {
cnd.and("t1.welfareUnionId", "=", SecurityUtil.getUnionId()); cnd.and("t1.welfareUnionId", "=", SecurityUtil.getUnionId());
} }
@@ -117,7 +117,7 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
if (AuthUtil.hasRole(RoleConstant.BRANCH_UNION_CHAIRMAN.name())) { if (AuthUtil.hasRole(RoleConstant.BRANCH_UNION_CHAIRMAN.name()) || AuthUtil.hasRole(RoleConstant.BRANCH_UNION_OPERATOR.name())) {
cnd.and("t1.welfareUnionId", "=", SecurityUtil.getUnionId()); cnd.and("t1.welfareUnionId", "=", SecurityUtil.getUnionId());
} }
@@ -122,8 +122,13 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
SELECT SELECT
u.loginname AS loginName, u.loginname AS loginName,
u.username AS userName, u.username AS userName,
wl.userState,
wl.personType,
wl.preparedBy,
wl.welfareUnitName, wl.welfareUnitName,
wl.welfareUnionName, wl.welfareUnionName,
u.postDoctoralJoinDate,
DATE_FORMAT(u.birthday, '%Y-%m-%d') AS birthday,
wpus.mobile, wpus.mobile,
GROUP_CONCAT(DISTINCT wpso.optionName, '', wpus.selectNum, '份)') selectOptionName GROUP_CONCAT(DISTINCT wpso.optionName, '', wpus.selectNum, '份)') selectOptionName
FROM FROM
@@ -155,8 +160,13 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
SELECT SELECT
u.loginname AS loginName, u.loginname AS loginName,
u.username AS userName, u.username AS userName,
wl.userState,
wl.personType,
wl.preparedBy,
wl.welfareUnitName, wl.welfareUnitName,
wl.welfareUnionName, wl.welfareUnionName,
u.postDoctoralJoinDate,
DATE_FORMAT(u.birthday, '%Y-%m-%d') AS birthday,
wpus.mobile, wpus.mobile,
GROUP_CONCAT(DISTINCT wpso.optionName, '', wpus.selectNum, '份)') selectOptionName GROUP_CONCAT(DISTINCT wpso.optionName, '', wpus.selectNum, '份)') selectOptionName
FROM FROM
@@ -188,6 +198,11 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
List<ExcelExportEntity> entities = new ArrayList<>(); List<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("工号", "loginName", 20)); entities.add(new ExcelExportEntity("工号", "loginName", 20));
entities.add(new ExcelExportEntity("姓名", "userName", 20)); entities.add(new ExcelExportEntity("姓名", "userName", 20));
entities.add(new ExcelExportEntity("生日", "birthday", 20));
entities.add(new ExcelExportEntity("在职状态", "userState", 20));
entities.add(new ExcelExportEntity("教职工类别", "personType", 20));
entities.add(new ExcelExportEntity("聘用方式", "preparedBy", 20));
entities.add(new ExcelExportEntity("进站时间", "postDoctoralJoinDate", 20));
entities.add(new ExcelExportEntity("单位", "welfareUnitName", 20)); entities.add(new ExcelExportEntity("单位", "welfareUnitName", 20));
entities.add(new ExcelExportEntity("工会", "welfareUnionName", 20)); entities.add(new ExcelExportEntity("工会", "welfareUnionName", 20));
entities.add(new ExcelExportEntity("手机号", "mobile", 20)); entities.add(new ExcelExportEntity("手机号", "mobile", 20));
@@ -210,8 +225,13 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
SELECT SELECT
u.loginname AS loginName, u.loginname AS loginName,
u.username AS userName, u.username AS userName,
wl.userState,
wl.personType,
wl.preparedBy,
wl.welfareUnitName, wl.welfareUnitName,
wl.welfareUnionName wl.welfareUnionName,
u.postDoctoralJoinDate,
DATE_FORMAT(u.birthday, '%Y-%m-%d') AS birthday
FROM FROM
`welfare_list` wl `welfare_list` wl
LEFT JOIN welfare_project_user_selection wpus ON wl.userId = wpus.selectUserId LEFT JOIN welfare_project_user_selection wpus ON wl.userId = wpus.selectUserId
@@ -245,8 +265,13 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
SELECT SELECT
u.loginname AS loginName, u.loginname AS loginName,
u.username AS userName, u.username AS userName,
wl.userState,
wl.personType,
wl.preparedBy,
wl.welfareUnitName, wl.welfareUnitName,
wl.welfareUnionName wl.welfareUnionName,
u.postDoctoralJoinDate,
DATE_FORMAT(u.birthday, '%Y-%m-%d') AS birthday
FROM FROM
`welfare_list` wl `welfare_list` wl
LEFT JOIN welfare_project_user_selection wpus ON wl.userId = wpus.selectUserId LEFT JOIN welfare_project_user_selection wpus ON wl.userId = wpus.selectUserId
@@ -279,6 +304,7 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
List<ExcelExportEntity> entities = new ArrayList<>(); List<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("工号", "loginName", 20)); entities.add(new ExcelExportEntity("工号", "loginName", 20));
entities.add(new ExcelExportEntity("姓名", "userName", 20)); entities.add(new ExcelExportEntity("姓名", "userName", 20));
entities.add(new ExcelExportEntity("姓名", "userName", 20));
entities.add(new ExcelExportEntity("单位", "welfareUnitName", 20)); entities.add(new ExcelExportEntity("单位", "welfareUnitName", 20));
entities.add(new ExcelExportEntity("工会", "welfareUnionName", 20)); entities.add(new ExcelExportEntity("工会", "welfareUnionName", 20));
@@ -446,17 +446,29 @@
:root { :root {
/*--color-primary: #1890ff;*/ /*--color-primary: #1890ff;*/
--color-primary: #1867b0; /*--color-primary-1: #e6f7ff;*/
--color-primary-1: #e6f7ff; /*--color-primary-2: #bae7ff;*/
--color-primary-2: #bae7ff; /*--color-primary-3: #91d5ff;*/
--color-primary-3: #91d5ff; /*--color-primary-4: #69c0ff;*/
--color-primary-4: #69c0ff; /*--color-primary-5: #73d13d;*/
--color-primary-5: #096dd9; /*--color-primary-6: #1890ff;*/
--color-primary-6: #1890ff; /*--color-primary-7: #096dd9;*/
--color-primary-7: #096dd9; /*--color-primary-8: #0050b3;*/
--color-primary-8: #0050b3; /*--color-primary-9: #003a8c;*/
--color-primary-9: #003a8c; /*--color-primary-10: #002766;*/
--color-primary-10: #002766;
--color-primary: #217050;
--color-primary-1: #e8f5eb;
--color-primary-2: #c3e6d1;
--color-primary-3: #9dd7b7;
--color-primary-4: #78c89d;
--color-primary-5: #53b983;
--color-primary-6: #217050; /* 主色 */
--color-primary-7: #1a5a40;
--color-primary-8: #134330;
--color-primary-9: #0d2d20;
--color-primary-10: #061610;
--color-success: #52c41a; --color-success: #52c41a;
--color-success-1: #f6ffed; --color-success-1: #f6ffed;
--color-success-2: #d9f7be; --color-success-2: #d9f7be;
@@ -2807,7 +2819,7 @@
} }
.el-menu-item.is-active { .el-menu-item.is-active {
color: var(--color-primary); color: #FFFFFF!important;
} }
.el-menu-item.is-active i { .el-menu-item.is-active i {
@@ -5547,7 +5559,7 @@
.el-breadcrumb__inner a:hover, .el-breadcrumb__inner a:hover,
.el-breadcrumb__inner.is-link:hover { .el-breadcrumb__inner.is-link:hover {
color: var(--color-primary); /*color: var(--color-primary);*/
cursor: pointer; cursor: pointer;
} }
@@ -18669,7 +18681,8 @@ body [class^="el-icon-_"] {
.el-breadcrumb__inner, .el-breadcrumb__inner,
.el-breadcrumb__inner a, .el-breadcrumb__inner a,
.el-breadcrumb__inner.is-link { .el-breadcrumb__inner.is-link {
color: var(--color-text-secondary); /*color: var(--color-text-secondary);*/
color: var(--color-white);
font-weight: 400; font-weight: 400;
} }
@@ -18677,7 +18690,7 @@ body [class^="el-icon-_"] {
.el-breadcrumb__item:last-child .el-breadcrumb__inner a, .el-breadcrumb__item:last-child .el-breadcrumb__inner a,
.el-breadcrumb__item:last-child .el-breadcrumb__inner a:hover, .el-breadcrumb__item:last-child .el-breadcrumb__inner a:hover,
.el-breadcrumb__item:last-child .el-breadcrumb__inner:hover { .el-breadcrumb__item:last-child .el-breadcrumb__inner:hover {
color: var(--color-text-regular); /*color: var(--color-text-regular);*/
} }
.el-tabs .el-tabs__header, .el-tabs .el-tabs__header,
@@ -18931,7 +18944,8 @@ body [class^="el-icon-_"] {
.el-menu .el-menu-item, .el-menu .el-menu-item,
.el-menu .el-submenu > .el-submenu__title { .el-menu .el-submenu > .el-submenu__title {
color: var(--color-text-dark-regular); /*color: var(--color-text-dark-regular);*/
color: #000000;
background: none; background: none;
} }
@@ -18948,7 +18962,8 @@ body [class^="el-icon-_"] {
.el-menu .el-menu-item.is-active, .el-menu .el-menu-item.is-active,
.el-menu .el-submenu.is-active > .el-submenu__title { .el-menu .el-submenu.is-active > .el-submenu__title {
color: var(--color-text-dark-primary); /*color: var(--color-text-dark-primary);*/
color: #000000;
background: none; background: none;
} }
@@ -21071,6 +21086,7 @@ body.ele-transition-disabled .ele-modal-mask-inner {
align-items: center; align-items: center;
height: 56px; height: 56px;
background: var(--header-light-background); background: var(--header-light-background);
background: var(--color-primary);
position: relative; position: relative;
} }
@@ -21669,8 +21685,8 @@ span {
/*}*/ /*}*/
.ele-admin-show-tabs:not(.ele-admin-tab-card):not(.ele-admin-head-dark) .ele-admin-header { .ele-admin-show-tabs:not(.ele-admin-tab-card):not(.ele-admin-head-dark) .ele-admin-header {
-webkit-box-shadow: 240px -1px 0 var(--border-color-extra-light) inset; /*-webkit-box-shadow: 240px -1px 0 var(--border-color-extra-light) inset;*/
box-shadow: 240px -1px 0 var(--border-color-extra-light) inset; /*box-shadow: 240px -1px 0 var(--border-color-extra-light) inset;*/
-webkit-transition: padding-left 0.3s cubic-bezier(0.2, 0, 0, 1) 0s, -webkit-transition: padding-left 0.3s cubic-bezier(0.2, 0, 0, 1) 0s,
-webkit-box-shadow 0.3s cubic-bezier(0.2, 0, 0, 1) 0s; -webkit-box-shadow 0.3s cubic-bezier(0.2, 0, 0, 1) 0s;
transition: padding-left 0.3s cubic-bezier(0.2, 0, 0, 1) 0s, transition: padding-left 0.3s cubic-bezier(0.2, 0, 0, 1) 0s,
@@ -22174,15 +22190,15 @@ span {
.ele-admin-side-dark .ele-admin-logo { .ele-admin-side-dark .ele-admin-logo {
color: var(--color-text-dark-primary); color: var(--color-text-dark-primary);
-webkit-box-shadow: var(--logo-dark-shadow); /*-webkit-box-shadow: var(--logo-dark-shadow);*/
box-shadow: var(--logo-dark-shadow); /*box-shadow: var(--logo-dark-shadow);*/
background: var(--sidebar-background-dark); background: var(--color-primary);
} }
.ele-admin-side-dark .ele-admin-sidebar { .ele-admin-side-dark .ele-admin-sidebar {
-webkit-box-shadow: var(--sidebar-dark-shadow); /*-webkit-box-shadow: var(--sidebar-dark-shadow);*/
box-shadow: var(--sidebar-dark-shadow); /*box-shadow: var(--sidebar-dark-shadow);*/
background: var(--sidebar-background-dark); background: #FFFFFF;
} }
.ele-admin-side-dark.ele-admin-side-mix:not(.ele-admin-collapse) .ele-admin-logo, .ele-admin-side-dark.ele-admin-side-mix:not(.ele-admin-collapse) .ele-admin-logo,
@@ -126,12 +126,12 @@
*/ */
.text-primary, .text-primary,
.text-primary a { .text-primary a {
color: #1582dc; color: var(--color-primary);
} }
.text-primary:focus, .text-primary:focus,
.text-primary a:focus { .text-primary a:focus {
color: #0e5996; color: var(--color-primary-6);
} }
.text-default, .text-default,
@@ -67,6 +67,11 @@ module.exports = {
<style scoped> <style scoped>
.appCenterPopover { .appCenterPopover {
padding: 0 !important; padding: 0 !important;
color: var(--color-white);
}
.el-popover__reference{
font-weight: normal!important;
} }
.appCenterCard .el-card__header { .appCenterCard .el-card__header {
@@ -26,7 +26,7 @@
<a @click.prevent="viewMore" class="ele-cell-content">查看更多</a> <a @click.prevent="viewMore" class="ele-cell-content">查看更多</a>
</div> </div>
<el-badge :value="messages.length" slot="reference" :style="{ animation: messages.length > 0 ? 'bell-shake 0.5s infinite' : '' }"> <el-badge :value="messages.length" slot="reference" :style="{ animation: messages.length > 0 ? 'bell-shake 0.5s infinite' : '' }">
<i class="el-icon-bell"></i> <i class="el-icon-bell" style="color: var(--color-white)"></i>
</el-badge> </el-badge>
</el-popover> </el-popover>
</div> </div>
@@ -10,10 +10,10 @@
/> />
<img v-else alt="" src="/assets/platform/img/home/avatar_girl.png" /> <img v-else alt="" src="/assets/platform/img/home/avatar_girl.png" />
</span> </span>
<span class="hidden-xs-only"> <span class="hidden-xs-only" style="color: var(--color-white)">
{{ $store.state.user.username }} {{ $store.state.user.username }}
</span> </span>
<i class="el-icon-arrow-down"></i> <i class="el-icon-arrow-down" style="color: var(--color-white)"></i>
</div> </div>
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown">
<el-dropdown-item command="userInfo">个人信息</el-dropdown-item> <el-dropdown-item command="userInfo">个人信息</el-dropdown-item>
@@ -10,7 +10,7 @@
<link rel="stylesheet" href="${base!}/assets/platform/fonts/themify-icons.css" /> <link rel="stylesheet" href="${base!}/assets/platform/fonts/themify-icons.css" />
<link rel="stylesheet" href="${base!}/assets/platform/fonts/font-awesome.min.css" /> <link rel="stylesheet" href="${base!}/assets/platform/fonts/font-awesome.min.css" />
<link rel="stylesheet" href="${base!}/assets/platform/css/common.css?v=1.0.1" /> <link rel="stylesheet" href="${base!}/assets/platform/css/common.css?v=1.0.1" />
<link rel="stylesheet" href="${base!}/assets/platform/css/a.css" /> <link rel="stylesheet" href="${base!}/assets/platform/css/a.css?v=1.0.0" />
<!-- import Vue before Element --> <!-- import Vue before Element -->
<script src="${base!}/assets/platform/plugins/vue/vue.js"></script> <script src="${base!}/assets/platform/plugins/vue/vue.js"></script>
@@ -36,7 +36,7 @@ const appModule = {
width: 110px; width: 110px;
height: 110px; height: 110px;
border: 1px solid #f3efef; border: 1px solid #f3efef;
/ / background-color: rgb(248, 248, 248); /*/ / background-color: rgb(248, 248, 248);*/
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@@ -63,20 +63,36 @@ const quickEntry = {
padding: 10px; padding: 10px;
transition: transform 0.3s ease-in-out, transition: transform 0.3s ease-in-out,
box-shadow 0.3s ease-in-out; box-shadow 0.3s ease-in-out;
background: #f3f3f3;
border-radius: 10px;
} }
.home-quick-entry .quickEntries .quickEntryItem span { .home-quick-entry .quickEntries .quickEntryItem span {
margin-top: auto; margin-top: auto;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
} }
.home-quick-entry .quickEntries .quickEntryItem:hover { .home-quick-entry .quickEntries .quickEntryItem:hover {
cursor: pointer; cursor: pointer;
background: #f3f3f3; background: #f3f3f3;
border-radius: 10px; border-radius: 10px;
border: 1px solid var(--color-primary);
box-shadow:
0 0 12px rgba(33, 112, 80, 0.4), /* 外发光 */
inset 0 0 8px rgba(33, 112, 80, 0.2); /* 内发光 */
background: rgba(33, 112, 80, 0.05); /* 悬浮背景微透主题色 */
} }
.home-quick-entry .quickEntries .quickEntryItem:hover { .home-quick-entry .quickEntries .quickEntryItem:hover .svg-icon {
animation: shake 0.3s; transform: scale(1.1); /* 图标放大10% */
transition: transform 0.3s ease;
}
.home-quick-entry .quickEntries .quickEntryItem:hover span {
color: var(--color-primary); /* 使用主题色或自定义颜色 */
} }
@keyframes shake { @keyframes shake {
@@ -9,7 +9,7 @@ layout("/layouts/platform.html"){
.alert { .alert {
padding: 15px; padding: 15px;
background-color: #e8f4ff; background-color: #e8f4ff;
border-left: 4px solid #1890ff; border-left: 4px solid var(--color-primary);
margin-bottom: 25px; margin-bottom: 25px;
border-radius: 4px; border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
@@ -29,7 +29,7 @@ layout("/layouts/platform.html"){
} }
.alert i { .alert i {
color: #1890ff; color: var(--color-primary);
margin-right: 8px; margin-right: 8px;
} }
@@ -54,7 +54,7 @@ layout("/layouts/platform.html"){
} }
.book-header { .book-header {
background: linear-gradient(120deg, #1e3c72, #2a5298); background: linear-gradient(120deg, var(--color-primary), var(--color-primary-8));
color: white; color: white;
padding: 30px; padding: 30px;
text-align: center; text-align: center;
@@ -107,7 +107,7 @@ layout("/layouts/platform.html"){
font-size: 18px; font-size: 18px;
font-weight: bold; font-weight: bold;
margin-bottom: 20px; margin-bottom: 20px;
color: #1867b0; color: var(--color-primary);
position: relative; position: relative;
padding-left: 15px; padding-left: 15px;
} }
@@ -5,7 +5,7 @@ layout("/layouts/platform.html"){
<guava ref="guava"> <guava ref="guava">
<el-card shadow="never"> <el-card shadow="never">
<template #header> <template #header>
<h3 style="color: #1867b0">{{isEdit?'修改登记':'荣誉登记'}}</h3> <h3 style="color: var(--color-primary)">{{isEdit?'修改登记':'荣誉登记'}}</h3>
</template> </template>
<el-form :model="formData" label-width="120px"> <el-form :model="formData" label-width="120px">
<el-row type="flex" :gutter="20"> <el-row type="flex" :gutter="20">
@@ -61,7 +61,7 @@ const MEMBER_RECORD = {
<el-table-column align="center" header-align="center" label="异动类型" <el-table-column align="center" header-align="center" label="异动类型"
prop="changeType" show-overflow-tooltip sortable> prop="changeType" show-overflow-tooltip sortable>
<template scope="{row}"> <template scope="{row}">
<span style="color: #0e78c5;cursor: pointer" @click="openUserChangeInfo(row)"> <span style="color: var(--color-primary);cursor: pointer" @click="openUserChangeInfo(row)">
{{getChangeTypes(row.changeTypes)}} {{getChangeTypes(row.changeTypes)}}
</span> </span>
</template> </template>
@@ -2,152 +2,346 @@
layout("/layouts/platform.html"){ layout("/layouts/platform.html"){
#--> #-->
<style> <style>
.top-col { /* 主网格布局 */
background-color: white; .dashboard {
position: relative; display: grid;
box-sizing: border-box; grid-template-columns: repeat(4, 1fr);
padding: 20px; grid-template-rows: 200px 1fr;
width: calc((100% - (20px * 3)) / 4); gap: 20px;
}
.top-col:not(:last-child),
.center-col:not(:last-child) {
margin-right: 20px;
}
.col-title {
color: rgba(0, 0, 0, 0.45);
font-size: 14px;
margin-bottom: 10px;
}
.top-col-member-number {
font-size: 30px;
color: rgba(0, 0, 0, 0.85);
}
.top-col-chart {
height: 80px;
width: 100%; width: 100%;
position: relative; height: calc(100vh - 126px);
}
.center-col {
background-color: white;
position: relative;
box-sizing: border-box; box-sizing: border-box;
padding: 20px;
width: calc((100% - (20px * 1)) / 2);
} }
.idx { /* 卡片基础样式 */
.card {
background-color: white;
border-radius: 8px;
overflow: hidden;
display: flex; display: flex;
justify-content: center; flex-direction: column;
align-items: center; }
color: rgba(0, 0, 0, 0.85);
width: 20px; /* 卡片标题样式 */
height: 20px; .card-title {
border-radius: 50%; padding: 16px 20px 8px;
background-color: #f0f0f0; font-size: 16px;
font-weight: 600;
color: #333;
border-bottom: 1px solid #f0f0f0;
flex-shrink: 0;
}
/* 顶部统计卡片 */
.stats-card {
height: 200px;
padding: 20px;
box-sizing: border-box;
}
.stats-card .card-title {
padding: 0 0 8px 0;
border: none;
font-size: 14px;
color: #666;
margin-bottom: 8px;
}
.stat-value {
font-size: 32px;
font-weight: bold;
color: #217050;
margin: 10px 0;
line-height: 1.2;
}
.stat-meta {
font-size: 12px; font-size: 12px;
color: #999;
margin-top: auto;
}
.trend-up {
color: #52c41a;
}
.trend-down {
color: #ff4d4f;
}
/* 图表容器 */
.chart-container {
flex: 1;
min-height: 0;
padding: 10px;
}
/* 统计卡片中的图表容器 */
.stats-card .chart-container {
height: 120px;
min-height: 120px;
flex: none;
margin: 8px 0;
padding: 0;
}
/* 内容区域 - 左右布局 */
.content-left {
grid-column: 1 / 4;
display: grid;
grid-template-rows: 1fr 1fr;
gap: 20px;
min-height: 0;
}
.content-right {
grid-column: 4 / 5;
min-height: 0;
}
/* 左侧图表卡片 */
.content-left .card {
min-height: 0;
}
.content-left .card .chart-container {
flex: 1;
min-height: 200px;
}
/* 右侧表格样式 */
.content-right {
display: flex;
flex-direction: column;
}
.content-right .el-table {
flex: 1;
height: auto !important;
}
.content-right .card-title {
flex-shrink: 0;
}
/* 表格序号样式 */
.idx {
width: 24px;
height: 24px;
line-height: 24px;
text-align: center;
border-radius: 4px;
font-weight: bold;
margin: 0 auto; margin: 0 auto;
} }
.idx-rank { .idx-rank {
color: white !important; background: linear-gradient(135deg, #217050, #2d8a5f);
background-color: #314659 !important; color: white;
} }
.el-table__body-wrapper::-webkit-scrollbar { /* 响应式设计 */
display: none; /* Chrome Safari */ @media (max-width: 1400px) {
.dashboard {
grid-template-columns: repeat(2, 1fr);
grid-template-rows: 200px 200px 1fr;
}
.stats-card:nth-child(1),
.stats-card:nth-child(2) {
grid-row: 1;
}
.stats-card:nth-child(3),
.stats-card:nth-child(4) {
grid-row: 2;
}
.content-left {
grid-column: 1 / 3;
grid-row: 3;
grid-template-columns: 2fr 1fr;
grid-template-rows: 1fr;
}
.content-right {
grid-column: 1 / 3;
grid-row: 4;
}
} }
.el-table__body-wrapper { @media (max-width: 768px) {
scrollbar-width: none; /* firefox */ .dashboard {
-ms-overflow-style: none; /* IE 10+ */ grid-template-columns: 1fr;
overflow-x: hidden; grid-template-rows: repeat(4, 180px) 1fr 300px;
gap: 15px;
}
.stats-card {
height: 180px;
padding: 15px;
}
.stats-card .chart-container {
height: 100px;
min-height: 100px;
}
.content-left {
grid-column: 1;
grid-row: 5;
grid-template-columns: 1fr;
grid-template-rows: 1fr 1fr;
}
.content-right {
grid-column: 1;
grid-row: 6;
min-height: 300px;
}
.stat-value {
font-size: 24px;
}
}
/* Element UI 表格样式重写 */
.el-table {
font-size: 14px;
}
.el-table .el-table__header-wrapper {
background-color: #fafafa;
}
.el-table .el-table__body-wrapper {
max-height: calc(100% - 48px);
overflow-y: auto; overflow-y: auto;
} }
.el-table th {
background-color: #fafafa !important;
color: #333;
font-weight: 600;
}
.el-table td {
border-bottom: 1px solid #f0f0f0;
}
.el-table--border .el-table__inner-wrapper::after {
display: none;
}
/* Loading 样式优化 */
.el-loading-mask {
background-color: rgba(255, 255, 255, 0.8);
}
.el-loading-spinner .circular {
width: 32px;
height: 32px;
}
@media (max-width: 768px) {
.dashboard {
grid-template-columns: 1fr; /* 单列布局 */
grid-template-rows: repeat(6, auto); /* 自动高度,6行 */
gap: 15px;
}
/* 所有卡片独占一行 */
.stats-card,
.content-left,
.content-right {
grid-column: 1 !important; /* 强制占满整行 */
grid-row: auto !important; /* 自动行位置 */
height: auto; /* 高度自适应 */
min-height: 180px; /* 最小高度保障 */
}
/* 调整左侧内容区域为垂直堆叠 */
.content-left {
display: flex;
flex-direction: column;
gap: 15px;
}
/* 调整图表容器高度 */
.chart-container {
min-height: 200px;
}
/* 统计卡片调整 */
.stats-card {
padding: 15px;
}
.stats-card .chart-container {
height: 120px;
min-height: 120px;
}
}
</style> </style>
<div id="app" v-cloak> <div id="app" v-cloak>
<guava ref="guava"> <guava ref="guava">
<el-row style="background-color: #f0f2f5" type="flex"> <div class="dashboard">
<el-col class="top-col" v-loading="loading.memberNumber"> <!-- 顶部四个统计卡片 - 高度固定200px -->
<div class="col-title">会员数</div> <div class="card stats-card">
<div class="top-col-member-number"> <div class="card-title">会员数</div>
<div class="stat-value" v-loading="loading.memberNumber">
{{memberNumberData.memberNum}} {{memberNumberData.memberNum}}
<span style="font-size: 14px">&ensp;</span> <span style="font-size: 14px">&ensp;</span>
</div> </div>
<div <!-- <div class="stat-meta" v-loading="loading.memberNumber">-->
style=" <!-- 年同比 {{memberNumberData.ratio}}&ensp;-->
color: rgba(0, 0, 0, 0.85); <!-- <i :class="memberNumberData.diff >= 0 ? 'el-icon-top trend-up' : 'el-icon-bottom trend-down'"></i>-->
margin-top: 20px; <!-- </div>-->
font-size: 14px; </div>
display: flex;
align-items: center;
justify-content: flex-end;
"
>
年同比 {{memberNumberData.ratio}}&ensp;
<svg
aria-hidden="true"
data-icon="caret-up"
fill="currentColor"
focusable="false"
height="1em"
style="color: #67c23a"
v-if="memberNumberData.diff>=0"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M858.9 689L530.5 308.2c-9.4-10.9-27.5-10.9-37 0L165.1 689c-12.2 14.2-1.2 35 18.5 35h656.8c19.7 0 30.7-20.8 18.5-35z"
></path>
</svg>
<svg <div class="card stats-card">
aria-hidden="true" <div class="card-title">增长趋势</div>
data-icon="caret-up" <div class="chart-container" id="growthTrendChart" v-loading="loading.growthTrend"></div>
fill="currentColor" </div>
focusable="false"
height="1em" <div class="card stats-card">
style="color: #f56c6c" <div class="card-title">会员占比</div>
v-else <div class="chart-container" id="memberPercentageChart" v-loading="loading.memberPercentage"></div>
viewBox="0 0 1024 1024" </div>
width="1em"
> <div class="card stats-card">
<path <div class="card-title">男女占比</div>
d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z" <div class="chart-container" id="memberSexPercentageChart" v-loading="loading.memberSexPercentage"></div>
></path> </div>
</svg>
<!-- 左侧内容区域 -->
<div class="content-left">
<!-- 工会会员数图表 -->
<div class="card">
<div class="card-title">工会会员数</div>
<div class="chart-container" id="unionMemberChart" v-loading="loading.unionMember"></div>
</div> </div>
</el-col>
<el-col class="top-col" v-loading="loading.growthTrend">
<div class="col-title">增长趋势</div>
<div class="top-col-chart" id="growthTrendChart"></div>
</el-col>
<el-col class="top-col" v-loading="loading.memberPercentage">
<div class="col-title">会员占比</div>
<div class="top-col-chart" id="memberPercentageChart" style="position: absolute; height: 120px; right: -10%; bottom: 20px"></div>
</el-col>
<el-col class="top-col" v-loading="loading.memberSexPercentageChart">
<div class="col-title">男女占比</div>
<div class="top-col-chart" id="memberSexPercentageChart" style="position: absolute; height: 120px; right: -10%; bottom: 20px"></div>
</el-col>
</el-row>
<el-row style="background-color: #f0f2f5; margin-top: 20px" type="flex"> <!-- 人员类型图表 -->
<el-col class="center-col" v-loading="loading.unionMember"> <div class="card">
<div class="col-title">工会会员数</div> <div class="card-title">人员类型统计</div>
<div class="chart-container" id="personTypeMemberChart" v-loading="loading.personTypeMember"></div>
<div id="unionMemberChart" style="width: 100%; height: 100px"></div> </div>
</div>
<!-- 右侧表格区域 -->
<div class="card content-right">
<div class="card-title">工会会员明细</div>
<el-table <el-table
:data="unionMember" :data="unionMember"
:header-cell-style="{background:'#FAFAFA'}" :header-cell-style="{background:'#FAFAFA'}"
height="calc(100vh - 160px - 300px)" style="width: 100%; height: calc(100% - 40px)"
row-key="id" row-key="id"
style="width: 100%; margin-top: 20px" v-loading="loading.unionMember"
> >
<el-table-column label="序号" width="100px" align="center"> <el-table-column label="序号" width="100px" align="center">
<template scope="{$index}"> <template scope="{$index}">
@@ -159,34 +353,20 @@ layout("/layouts/platform.html"){
<template scope="{row}">{{row.unionname}}</template> <template scope="{row}">{{row.unionname}}</template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
align="center" align="center"
header-align="center" header-align="center"
label="会员人数" label="会员人数"
prop="value" prop="value"
show-overflow-tooltip show-overflow-tooltip
sortable sortable
width="120px" width="120px"
></el-table-column> ></el-table-column>
</el-table> </el-table>
</el-col> </div>
<el-col class="center-col"> </div>
<div class="col-title">在职状态</div>
<div
id="userStateMemberChart"
style="width: 100%; height: calc(50% - 35px); box-sizing: border-box; padding: 30px 10px"
v-loading="loading.userStateMember"
></div>
<div class="col-title">人员类型</div>
<div
id="personTypeMemberChart"
style="width: 100%; height: calc(50% - 35px); box-sizing: border-box; padding: 30px 10px"
v-loading="loading.personTypeMember"
></div>
</el-col>
</el-row>
</guava> </guava>
</div> </div>
<script> <script>
const chart = { const chart = {
growthTrendChart: undefined, growthTrendChart: undefined,
@@ -197,26 +377,29 @@ layout("/layouts/platform.html"){
userStateMemberChart: undefined userStateMemberChart: undefined
} }
new Vue({ const vue = new Vue({
el: "#app", el: "#app",
data: { data(){
loading: { return{
memberNumber: false, loading: {
growthTrend: false, memberNumber: false,
memberPercentage: false, growthTrend: false,
memberSexPercentage: false, memberPercentage: false,
unionMember: false, memberSexPercentage: false,
personTypeMember: false, unionMember: false,
userStateMember: false personTypeMember: false,
}, userStateMember: false
memberNumberData: { },
memberNum: "--", memberNumberData: {
lastYearMemberNum: "--", memberNum: "--",
ratio: "0.0%", lastYearMemberNum: "--",
diff: 0 ratio: "0.0%",
}, diff: 0
memberPercentage: "--", },
unionMember: [] memberPercentage: "--",
unionMember: []
}
}, },
methods: { methods: {
/** /**
@@ -261,10 +444,30 @@ layout("/layouts/platform.html"){
autoFit: true, autoFit: true,
data: values, data: values,
smooth: true, smooth: true,
showContent: true,
// 核心配色方案
color: '#217050', // 主色线
areaStyle: { areaStyle: {
fill: "#d6e3fd" fill: 'l(270) 0:#e8f5eb 1:#217050', // 线性渐变填充
opacity: 0.8
}, },
line: {
color: '#134330', // 深绿色线条
size: 2
},
// 数据点样式
point: {
size: 3,
style: {
fill: '#fff',
stroke: '#217050',
lineWidth: 2
}
},
showContent: true,
tooltip: { tooltip: {
customContent: function (i, data) { customContent: function (i, data) {
if (labels[i]) { if (labels[i]) {
@@ -305,10 +508,12 @@ layout("/layouts/platform.html"){
}, },
autoFit: true, autoFit: true,
percent: data, percent: data,
color: '#217050',
statistic: { statistic: {
content: { content: {
style: { style: {
fontSize: 16 fontSize: 16,
fill: '#fff', // 白色文字
} }
} }
} }
@@ -340,10 +545,21 @@ layout("/layouts/platform.html"){
colorField: "type", colorField: "type",
legend: false, legend: false,
label: { label: {
formatter: () => "" type: 'inner',
offset: '-30%',
style: {
fontSize: 14,
fontWeight: 'bold',
fill: '#fff', // 白色文字
textShadow: '0 1px 2px rgba(0,0,0,0.5)' // 增强可读性
},
formatter: (datum) => (datum.percent * 100).toFixed(1)
}, },
interactions: [{ type: "element-active" }], // 交互效果
color: ["#409EFF", "#F56C6C"] interactions: [
{ type: 'element-active' },
],
color: ['#217050', '#f0a35c']
}) })
chart.memberSexPercentageChart.render() chart.memberSexPercentageChart.render()
} else { } else {
@@ -377,19 +593,66 @@ layout("/layouts/platform.html"){
autoFit: true, autoFit: true,
xField: "unionname", xField: "unionname",
yField: "value", yField: "value",
label: { color: '#217050', // 主色柱体
// 可手动配置 label 数据标签位置 // 柱体样式
position: "middle", // 'top', 'bottom', 'middle', columnStyle: {
// 配置样式 fill: '#217050',
style: { stroke: '#134330',
fill: "#FFFFFF", lineWidth: 1,
opacity: 0.6 shadowColor: 'rgba(33, 112, 80, 0.5)', // 主色阴影
} shadowBlur: 6,
radius: [4, 4, 0, 0] // 顶部圆角
}, },
label: {
position: "top",
style: {
fill: "#217050", // 白色文字
fontSize: 12,
fontWeight: 'bold',
textShadow: '0 1px 2px rgba(0,0,0,0.5)',
opacity: 0.9
},
formatter: (datum) => datum.value // 显示原始值
},
// X轴配置
xAxis: { xAxis: {
label: { label: {
autoHide: true, autoHide: true,
autoRotate: false autoRotate: false,
style: {
fill: '#666',
fontSize: 12
}
},
line: {
style: {
stroke: '#e8f5eb' // 浅绿色轴线
}
},
grid: {
line: {
style: {
stroke: '#f0f0f0',
lineDash: [4, 2]
}
}
}
},
// Y轴配置
yAxis: {
label: {
style: {
fill: '#666'
},
formatter: (val) => val
},
grid: {
line: {
style: {
stroke: '#e8f5eb',
lineDash: [4, 2]
}
}
} }
}, },
meta: { meta: {
@@ -429,19 +692,72 @@ layout("/layouts/platform.html"){
autoFit: true, autoFit: true,
xField: "label", xField: "label",
yField: "value", yField: "value",
label: { // 核心配色方案
// 可手动配置 label 数据标签位置 color: '#217050', // 主色柱体
position: "middle", // 'top', 'bottom', 'middle', // 柱体样式
// 配置样式 columnStyle: {
style: { fill: '#217050',
fill: "#FFFFFF", stroke: '#134330',
opacity: 0.6 lineWidth: 1,
} shadowColor: 'rgba(33, 112, 80, 0.5)', // 主色阴影
shadowBlur: 6,
radius: [4, 4, 0, 0] // 顶部圆角
}, },
// 数据标签
label: {
position: "top",
style: {
fill: "#217050", // 白色文字
fontSize: 12,
fontWeight: 'bold',
textShadow: '0 1px 2px rgba(0,0,0,0.5)',
opacity: 0.9
},
formatter: (datum) => datum.value // 显示原始值
// 如需千分位格式化:.toLocaleString()
},
// X轴配置
xAxis: { xAxis: {
label: { label: {
autoHide: true, autoHide: true,
autoRotate: false autoRotate: false,
style: {
fill: '#666',
fontSize: 12
}
},
line: {
style: {
stroke: '#e8f5eb' // 浅绿色轴线
}
},
grid: {
line: {
style: {
stroke: '#f0f0f0',
lineDash: [4, 2]
}
}
}
},
// Y轴配置
yAxis: {
label: {
style: {
fill: '#666'
},
formatter: (val) => val
},
grid: {
line: {
style: {
stroke: '#e8f5eb',
lineDash: [4, 2]
}
}
} }
}, },
meta: { meta: {
@@ -476,33 +792,87 @@ layout("/layouts/platform.html"){
return return
} }
chart.userStateMemberChart = new G2Plot.Radar("userStateMemberChart", { chart.userStateMemberChart = new G2Plot.Column("userStateMemberChart", {
data, data,
autoFit: true,
xField: "label", xField: "label",
yField: "value", yField: "value",
appendPadding: [0, 10, 0, 10], // 核心配色方案
meta: { color: '#217050', // 主色柱体
value: { // 柱体样式
alias: "会员数量", columnStyle: {
min: 0, fill: '#217050',
nice: true, stroke: '#134330',
formatter: (v) => parseInt(v) lineWidth: 1,
} shadowColor: 'rgba(33, 112, 80, 0.5)', // 主色阴影
shadowBlur: 6,
radius: [4, 4, 0, 0] // 顶部圆角
}, },
// 数据标签
label: {
position: "top",
style: {
fill: "#217050", // 白色文字
fontSize: 12,
fontWeight: 'bold',
textShadow: '0 1px 2px rgba(0,0,0,0.5)',
opacity: 0.9
},
formatter: (datum) => datum.value // 显示原始值
// 如需千分位格式化:.toLocaleString()
},
// X轴配置
xAxis: { xAxis: {
tickLine: null label: {
}, autoHide: true,
yAxis: { autoRotate: false,
label: false, style: {
fill: '#666',
fontSize: 12
}
},
line: {
style: {
stroke: '#e8f5eb' // 浅绿色轴线
}
},
grid: { grid: {
alternateColor: "rgba(0, 0, 0, 0.04)" line: {
style: {
stroke: '#f0f0f0',
lineDash: [4, 2]
}
}
} }
}, },
// 开启辅助点
point: { // Y轴配置
size: 2 yAxis: {
label: {
style: {
fill: '#666'
},
formatter: (val) => val
},
grid: {
line: {
style: {
stroke: '#e8f5eb',
lineDash: [4, 2]
}
}
}
}, },
area: {} meta: {
label: {
alias: "类型"
},
value: {
alias: "会员数"
}
}
}) })
chart.userStateMemberChart.render() chart.userStateMemberChart.render()
} else { } else {
@@ -518,7 +888,7 @@ layout("/layouts/platform.html"){
this.getMemberSexPercentage() this.getMemberSexPercentage()
this.getUnionMember() this.getUnionMember()
this.getPersonTypeMember() this.getPersonTypeMember()
this.getUserStateMember() // this.getUserStateMember()
} }
}, },
mounted() { mounted() {
@@ -0,0 +1,718 @@
<!--#
layout("/layouts/platform.html"){
#-->
<style>
.top-col {
background-color: white;
position: relative;
box-sizing: border-box;
padding: 20px;
width: calc((100% - (20px * 3)) / 4);
}
.top-col:not(:last-child),
.center-col:not(:last-child) {
margin-right: 20px;
}
.col-title {
color: rgba(0, 0, 0, 0.45);
font-size: 14px;
margin-bottom: 10px;
}
.top-col-member-number {
font-size: 30px;
color: rgba(0, 0, 0, 0.85);
}
.top-col-chart {
height: 80px;
width: 100%;
position: relative;
}
.center-col {
background-color: white;
position: relative;
box-sizing: border-box;
padding: 20px;
width: calc((100% - (20px * 1)) / 2);
}
.idx {
display: flex;
justify-content: center;
align-items: center;
color: rgba(0, 0, 0, 0.85);
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #f0f0f0;
font-size: 12px;
margin: 0 auto;
}
.idx-rank {
color: white !important;
background-color: #314659 !important;
}
.el-table__body-wrapper::-webkit-scrollbar {
display: none; /* Chrome Safari */
}
.el-table__body-wrapper {
scrollbar-width: none; /* firefox */
-ms-overflow-style: none; /* IE 10+ */
overflow-x: hidden;
overflow-y: auto;
}
</style>
<div id="app" v-cloak>
<guava ref="guava">
<el-row style="background-color: #f0f2f5" type="flex">
<el-col class="top-col" v-loading="loading.memberNumber">
<div class="col-title">会员数</div>
<div class="top-col-member-number">
{{memberNumberData.memberNum}}
<span style="font-size: 14px">&ensp;</span>
</div>
<div
style="
color: rgba(0, 0, 0, 0.85);
margin-top: 20px;
font-size: 14px;
display: flex;
align-items: center;
justify-content: flex-end;
"
>
年同比 {{memberNumberData.ratio}}&ensp;
<svg
aria-hidden="true"
data-icon="caret-up"
fill="currentColor"
focusable="false"
height="1em"
style="color: #67c23a"
v-if="memberNumberData.diff>=0"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M858.9 689L530.5 308.2c-9.4-10.9-27.5-10.9-37 0L165.1 689c-12.2 14.2-1.2 35 18.5 35h656.8c19.7 0 30.7-20.8 18.5-35z"
></path>
</svg>
<svg
aria-hidden="true"
data-icon="caret-up"
fill="currentColor"
focusable="false"
height="1em"
style="color: #f56c6c"
v-else
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"
></path>
</svg>
</div>
</el-col>
<el-col class="top-col" v-loading="loading.growthTrend">
<div class="col-title">增长趋势</div>
<div class="top-col-chart" id="growthTrendChart"></div>
</el-col>
<el-col class="top-col" v-loading="loading.memberPercentage">
<div class="col-title">会员占比</div>
<div class="top-col-chart" id="memberPercentageChart" style="position: absolute; height: 120px; right: -10%; bottom: 20px"></div>
</el-col>
<el-col class="top-col" v-loading="loading.memberSexPercentageChart">
<div class="col-title">男女占比</div>
<div class="top-col-chart" id="memberSexPercentageChart" style="position: absolute; height: 120px; right: -10%; bottom: 20px"></div>
</el-col>
</el-row>
<el-row style="background-color: #f0f2f5; margin-top: 20px" type="flex">
<el-col class="center-col" v-loading="loading.unionMember">
<div class="col-title">工会会员数</div>
<div id="unionMemberChart" style="width: 100%; height: 200px"></div>
<el-table
:data="unionMember"
:header-cell-style="{background:'#FAFAFA'}"
height="calc(100vh - 190px - 400px)"
row-key="id"
style="width: 100%; margin-top: 20px"
>
<el-table-column label="序号" width="100px" align="center">
<template scope="{$index}">
<div class="idx idx-rank" v-if="$index<3">{{$index+1}}</div>
<div class="idx" v-else>{{$index+1}}</div>
</template>
</el-table-column>
<el-table-column align="center" header-align="center" label="分工会" prop="unioncode" show-overflow-tooltip sortable>
<template scope="{row}">{{row.unionname}}</template>
</el-table-column>
<el-table-column
align="center"
header-align="center"
label="会员人数"
prop="value"
show-overflow-tooltip
sortable
width="120px"
></el-table-column>
</el-table>
</el-col>
<el-col class="center-col">
<div class="col-title">在职状态</div>
<div
id="userStateMemberChart"
style="width: 100%; height: calc(50% - 35px); box-sizing: border-box; padding: 30px 10px"
v-loading="loading.userStateMember"
></div>
<div class="col-title">人员类型</div>
<div
id="personTypeMemberChart"
style="width: 100%; height: calc(50% - 35px); box-sizing: border-box; padding: 30px 10px"
v-loading="loading.personTypeMember"
></div>
</el-col>
</el-row>
</guava>
</div>
<script>
const chart = {
growthTrendChart: undefined,
memberPercentageChart: undefined,
memberSexPercentageChart: undefined,
unionMemberChart: undefined,
personTypeMemberChart: undefined,
userStateMemberChart: undefined
}
new Vue({
el: "#app",
data: {
loading: {
memberNumber: false,
growthTrend: false,
memberPercentage: false,
memberSexPercentage: false,
unionMember: false,
personTypeMember: false,
userStateMember: false
},
memberNumberData: {
memberNum: "--",
lastYearMemberNum: "--",
ratio: "0.0%",
diff: 0
},
memberPercentage: "--",
unionMember: []
},
methods: {
/**
* 会员数
* @returns {Promise<void>}
*/
async getMemberNumber() {
this.loading.memberNumber = true
this.$axios.post("/platform/member/info/board/memberNumber").then((resp) => {
if (resp.code === 0) {
const {
data: { memberNum, lastYearMemberNum }
} = resp
const diff = memberNum - lastYearMemberNum
const ratio = (lastYearMemberNum ? (Math.abs(diff) / lastYearMemberNum) * 100 : (diff / 1) * 10).toFixed(2) + " %"
this.memberNumberData = { memberNum, lastYearMemberNum, diff, ratio }
this.loading.memberNumber = false
} else {
this.$message.warning(resp.msg)
}
})
},
/**
* 增长趋势
* @returns {Promise<void>}
*/
async getGrowthTrend() {
this.loading.growthTrend = true
this.$axios.post("/platform/member/info/board/growthTrend").then((resp) => {
this.loading.growthTrend = false
if (resp.code === 0) {
const { data } = resp
const labels = data.map((v) => v.label)
const values = data.map((v) => v.value)
if (chart.growthTrendChart) {
chart.growthTrendChart.changeData(values)
return
}
chart.growthTrendChart = new G2Plot.TinyArea("growthTrendChart", {
autoFit: true,
data: values,
smooth: true,
// 核心配色方案
color: '#217050', // 主色线
areaStyle: {
fill: 'l(270) 0:#e8f5eb 1:#217050', // 线性渐变填充
opacity: 0.8
},
line: {
color: '#134330', // 深绿色线条
size: 2
},
// 数据点样式
point: {
size: 3,
style: {
fill: '#fff',
stroke: '#217050',
lineWidth: 2
}
},
showContent: true,
tooltip: {
customContent: function (i, data) {
if (labels[i]) {
return labels[i] + "-" + data[0]?.data?.y + "人"
}
return ""
}
}
})
chart.growthTrendChart.render()
} else {
this.$message.warning(resp.msg)
}
})
},
/**
* 会员占比
* @returns {Promise<void>}
*/
async getMemberPercentage() {
this.loading.memberPercentage = true
this.$axios.post("/platform/member/info/board/memberPercentage").then((resp) => {
this.loading.memberPercentage = false
if (resp.code === 0) {
const { data } = resp
this.memberPercentage = data.toFixed(2)
if (chart.memberPercentageChart) {
chart.memberPercentageChart.changeData(data)
return
}
chart.memberPercentageChart = new G2Plot.Liquid("memberPercentageChart", {
outline: {
border: 4,
distance: 8
},
wave: {
length: 128
},
autoFit: true,
percent: data,
color: '#217050',
statistic: {
content: {
style: {
fontSize: 16,
fill: '#fff', // 白色文字
}
}
}
})
chart.memberPercentageChart.render()
} else {
this.$message.warning(resp.msg)
}
})
},
/**
* 男女占比
* @returns {Promise<void>}
*/
async getMemberSexPercentage() {
this.loading.memberSexPercentage = true
this.$axios.post("/platform/member/info/board/memberSexPercentage").then((resp) => {
this.loading.memberSexPercentage = false
if (resp.code === 0) {
const { data } = resp
if (chart.memberSexPercentageChart) {
chart.memberSexPercentageChart.changeData(data)
return
}
chart.memberSexPercentageChart = new G2Plot.Pie("memberSexPercentageChart", {
data,
angleField: "value",
colorField: "type",
legend: false,
label: {
type: 'inner',
offset: '-30%',
style: {
fontSize: 14,
fontWeight: 'bold',
fill: '#fff', // 白色文字
textShadow: '0 1px 2px rgba(0,0,0,0.5)' // 增强可读性
},
formatter: (datum) => (datum.percent * 100).toFixed(1)
},
// 交互效果
interactions: [
{ type: 'element-active' },
],
color: ['#217050', '#f0a35c']
})
chart.memberSexPercentageChart.render()
} else {
this.$message.warning(resp.msg)
}
})
},
/**
* 各工会会员数
* @returns {Promise<void>}
*/
async getUnionMember() {
this.loading.unionMember = true
this.$axios.post("/platform/member/info/board/unionMember").then((resp) => {
this.loading.unionMember = false
if (resp.code === 0) {
const { chartData, tableData } = resp.data
this.unionMember = tableData
const labels = chartData.map((v) => v.unionname)
const values = chartData.map((v) => v.value)
if (chart.unionMemberChart) {
chart.unionMemberChart.changeData(values)
return
}
chart.unionMemberChart = new G2Plot.Column("unionMemberChart", {
data: chartData,
autoFit: true,
xField: "unionname",
yField: "value",
color: '#217050', // 主色柱体
// 柱体样式
columnStyle: {
fill: '#217050',
stroke: '#134330',
lineWidth: 1,
shadowColor: 'rgba(33, 112, 80, 0.5)', // 主色阴影
shadowBlur: 6,
radius: [4, 4, 0, 0] // 顶部圆角
},
label: {
position: "top",
style: {
fill: "#217050", // 白色文字
fontSize: 12,
fontWeight: 'bold',
textShadow: '0 1px 2px rgba(0,0,0,0.5)',
opacity: 0.9
},
formatter: (datum) => datum.value // 显示原始值
},
// X轴配置
xAxis: {
label: {
autoHide: true,
autoRotate: false,
style: {
fill: '#666',
fontSize: 12
}
},
line: {
style: {
stroke: '#e8f5eb' // 浅绿色轴线
}
},
grid: {
line: {
style: {
stroke: '#f0f0f0',
lineDash: [4, 2]
}
}
}
},
// Y轴配置
yAxis: {
label: {
style: {
fill: '#666'
},
formatter: (val) => val
},
grid: {
line: {
style: {
stroke: '#e8f5eb',
lineDash: [4, 2]
}
}
}
},
meta: {
label: {
alias: "类型"
},
value: {
alias: "会员数"
}
}
})
chart.unionMemberChart.render()
} else {
this.$message.warning(resp.msg)
}
})
},
/**
* 根据人员类型查找会员数
* @returns {Promise<void>}
*/
async getPersonTypeMember() {
this.loading.personTypeMember = true
this.$axios.post("/platform/member/info/board/personTypeMember").then((resp) => {
this.loading.personTypeMember = false
if (resp.code === 0) {
const { data } = resp
if (chart.personTypeMemberChart) {
chart.personTypeMemberChart.changeData(data)
return
}
chart.personTypeMemberChart = new G2Plot.Column("personTypeMemberChart", {
data,
autoFit: true,
xField: "label",
yField: "value",
// 核心配色方案
color: '#217050', // 主色柱体
// 柱体样式
columnStyle: {
fill: '#217050',
stroke: '#134330',
lineWidth: 1,
shadowColor: 'rgba(33, 112, 80, 0.5)', // 主色阴影
shadowBlur: 6,
radius: [4, 4, 0, 0] // 顶部圆角
},
// 数据标签
label: {
position: "top",
style: {
fill: "#217050", // 白色文字
fontSize: 12,
fontWeight: 'bold',
textShadow: '0 1px 2px rgba(0,0,0,0.5)',
opacity: 0.9
},
formatter: (datum) => datum.value // 显示原始值
// 如需千分位格式化:.toLocaleString()
},
// X轴配置
xAxis: {
label: {
autoHide: true,
autoRotate: false,
style: {
fill: '#666',
fontSize: 12
}
},
line: {
style: {
stroke: '#e8f5eb' // 浅绿色轴线
}
},
grid: {
line: {
style: {
stroke: '#f0f0f0',
lineDash: [4, 2]
}
}
}
},
// Y轴配置
yAxis: {
label: {
style: {
fill: '#666'
},
formatter: (val) => val
},
grid: {
line: {
style: {
stroke: '#e8f5eb',
lineDash: [4, 2]
}
}
}
},
meta: {
label: {
alias: "类型"
},
value: {
alias: "会员数"
}
}
})
chart.personTypeMemberChart.render()
} else {
this.$message.warning(resp.msg)
}
})
},
/**
* 根据在职状态查找会员数
* @returns {Promise<void>}
*/
async getUserStateMember() {
this.loading.userStateMember = true
this.$axios.post("/platform/member/info/board/userStateMember").then((resp) => {
this.loading.userStateMember = false
if (resp.code === 0) {
const { data } = resp
if (chart.userStateMemberChart) {
chart.userStateMemberChart.changeData(data)
return
}
chart.userStateMemberChart = new G2Plot.Column("userStateMemberChart", {
data,
autoFit: true,
xField: "label",
yField: "value",
// 核心配色方案
color: '#217050', // 主色柱体
// 柱体样式
columnStyle: {
fill: '#217050',
stroke: '#134330',
lineWidth: 1,
shadowColor: 'rgba(33, 112, 80, 0.5)', // 主色阴影
shadowBlur: 6,
radius: [4, 4, 0, 0] // 顶部圆角
},
// 数据标签
label: {
position: "top",
style: {
fill: "#217050", // 白色文字
fontSize: 12,
fontWeight: 'bold',
textShadow: '0 1px 2px rgba(0,0,0,0.5)',
opacity: 0.9
},
formatter: (datum) => datum.value // 显示原始值
// 如需千分位格式化:.toLocaleString()
},
// X轴配置
xAxis: {
label: {
autoHide: true,
autoRotate: false,
style: {
fill: '#666',
fontSize: 12
}
},
line: {
style: {
stroke: '#e8f5eb' // 浅绿色轴线
}
},
grid: {
line: {
style: {
stroke: '#f0f0f0',
lineDash: [4, 2]
}
}
}
},
// Y轴配置
yAxis: {
label: {
style: {
fill: '#666'
},
formatter: (val) => val
},
grid: {
line: {
style: {
stroke: '#e8f5eb',
lineDash: [4, 2]
}
}
}
},
meta: {
label: {
alias: "类型"
},
value: {
alias: "会员数"
}
}
})
chart.userStateMemberChart.render()
} else {
this.$message.warning(resp.msg)
}
})
},
initData() {
this.getMemberNumber()
this.getGrowthTrend()
this.getMemberPercentage()
this.getMemberSexPercentage()
this.getUnionMember()
this.getPersonTypeMember()
this.getUserStateMember()
}
},
mounted() {
this.initData()
}
})
</script>
<!--#
}
#-->
@@ -210,6 +210,7 @@ layout("/layouts/platform.html"){
{ prop: "mobile", label: "联系电话" }, { prop: "mobile", label: "联系电话" },
{ prop: "userState", label: "在职状态", sortable: true }, { prop: "userState", label: "在职状态", sortable: true },
{ prop: "preparedBy", label: "聘用方式", sortable: true }, { prop: "preparedBy", label: "聘用方式", sortable: true },
{ prop: "postDoctoralJoinDate", label: "进站时间", sortable: true },
{ prop: "personType", label: "人员类型", sortable: true }, { prop: "personType", label: "人员类型", sortable: true },
{ prop: "unionName", label: "所属工会", sortable: true }, { prop: "unionName", label: "所属工会", sortable: true },
{ prop: "unitName", label: "所属单位", sortable: true } { prop: "unitName", label: "所属单位", sortable: true }
@@ -123,6 +123,7 @@ layout("/layouts/platform.html"){
{ prop: "userState", label: "在职状态", width: 120, sortable: true }, { prop: "userState", label: "在职状态", width: 120, sortable: true },
{ prop: "personType", label: "教职工类别", width: 120, sortable: true }, { prop: "personType", label: "教职工类别", width: 120, sortable: true },
{ prop: "preparedBy", label: "聘用方式", width: 120, sortable: true }, { prop: "preparedBy", label: "聘用方式", width: 120, sortable: true },
{ prop: "postDoctoralJoinDate", label: "进站时间", sortable: true },
{ prop: "identityType", label: "身份类型", width: 120, sortable: true }, { prop: "identityType", label: "身份类型", width: 120, sortable: true },
{ prop: "unionName", label: "所属工会", width: 120, sortable: true }, { prop: "unionName", label: "所属工会", width: 120, sortable: true },
{ prop: "unitName", label: "所属单位", width: 120, sortable: true }, { prop: "unitName", label: "所属单位", width: 120, sortable: true },
@@ -114,19 +114,19 @@ layout("/layouts/platform.html"){
></el-date-picker> ></el-date-picker>
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- <el-col span="12"> <el-col span="12">
<el-form-item prop="provideTime" label="发放时间"> <el-form-item prop="provideTime" label="发放时间">
<el-date-picker <el-date-picker
style="width: 100%" style="width: 100%"
v-model="formData.provideTime" v-model="formData.provideTime"
type="datetimerange" type="datetimerange"
value-format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
range-separator="-" range-separator="-"
start-placeholder="开始时间" start-placeholder="开始时间"
end-placeholder="结束时间" @change="provideTimeChange"> end-placeholder="结束时间" @change="provideTimeChange">
</el-date-picker> </el-date-picker>
</el-form-item> </el-form-item>
</el-col>--> </el-col>
</el-row> </el-row>
<el-row> <el-row>
@@ -129,7 +129,7 @@ layout("/layouts/platform.html"){
const now = this.$moment().valueOf() const now = this.$moment().valueOf()
if (overdueChoiceTimeEnd == null || overdueChoiceTimeEnd === "") { if (overdueChoiceTimeEnd == null || overdueChoiceTimeEnd === "") {
if (now > this.$moment(choiceTimeStart).valueOf() && now < moment(choiceTimeEnd).valueOf()) { if (now > this.$moment(choiceTimeStart).valueOf() && now < moment(choiceTimeEnd).valueOf()) {
return { text: isChoose ? "确定修改" : "确定选择", disabled: false } return { text: isChoose ? "修改" : "确定选择", disabled: false }
} else if (now > this.$moment(choiceTimeEnd).valueOf()) { } else if (now > this.$moment(choiceTimeEnd).valueOf()) {
return { text: "选择已结束", disabled: true } return { text: "选择已结束", disabled: true }
} else if (now < this.$moment(choiceTimeStart).valueOf()) { } else if (now < this.$moment(choiceTimeStart).valueOf()) {
@@ -118,7 +118,7 @@ const optionSelect = {
<el-dialog <el-dialog
title="福利详情" title="福利详情"
:visible.sync="showOptionDetailDialog" :visible.sync="showOptionDetailDialog"
width="600px" width="60%"
append-to-body append-to-body
custom-class="welfare-detail-dialog"> custom-class="welfare-detail-dialog">
<div class="welfare-detail-popup" v-if="selectedOption"> <div class="welfare-detail-popup" v-if="selectedOption">
@@ -1,6 +1,6 @@
const selectedUser = { const selectedUser = {
template: /*language=HTML*/ ` template: /*language=HTML*/ `
<el-dialog :title="unionName+'已选择用户'" :visible.sync="visible"> <el-dialog :title="unionName+'已选择用户'" :visible.sync="visible" width="70%">
<div style="display: flex; justify-content: space-between; margin-bottom: 10px;"> <div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
<div> <div>
<el-input <el-input
@@ -48,8 +48,12 @@ const selectedUser = {
tableColumns: [ tableColumns: [
{ label: "工号", prop: "loginName" }, { label: "工号", prop: "loginName" },
{ label: "姓名", prop: "userName" }, { label: "姓名", prop: "userName" },
{ label: "生日", prop: "birthday" },
{ prop: "userState", label: "在职状态", width: 120, sortable: true },
{ prop: "personType", label: "教职工类别", width: 120, sortable: true },
{ prop: "preparedBy", label: "聘用方式", width: 120, sortable: true },
{ prop: "postDoctoralJoinDate", label: "进站时间", sortable: true },
{ label: "单位", prop: "welfareUnitName" }, { label: "单位", prop: "welfareUnitName" },
{ label: "分工会", prop: "welfareUnionName" },
{ label: "手机号", prop: "mobile" }, { label: "手机号", prop: "mobile" },
{ label: "所选福利", prop: "selectOptionName" } { label: "所选福利", prop: "selectOptionName" }
] ]
@@ -1,6 +1,6 @@
const unSelectedUser = { const unSelectedUser = {
template: /*language=HTML*/ ` template: /*language=HTML*/ `
<el-dialog :title="unionName+'未选择用户'" :visible.sync="visible"> <el-dialog :title="unionName+'未选择用户'" :visible.sync="visible" width="70%">
<div style="display: flex; justify-content: space-between; margin-bottom: 10px;"> <div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
<div> <div>
<el-input <el-input
@@ -47,8 +47,12 @@ const unSelectedUser = {
tableColumns: [ tableColumns: [
{ label: "工号", prop: "loginName" }, { label: "工号", prop: "loginName" },
{ label: "姓名", prop: "userName" }, { label: "姓名", prop: "userName" },
{ label: "单位", prop: "welfareUnitName" }, { label: "生日", prop: "birthday" },
{ label: "分工会", prop: "welfareUnionName" } { prop: "userState", label: "在职状态", width: 120, sortable: true },
{ prop: "personType", label: "教职工类别", width: 120, sortable: true },
{ prop: "preparedBy", label: "聘用方式", width: 120, sortable: true },
{ prop: "postDoctoralJoinDate", label: "进站时间", sortable: true },
{ label: "单位", prop: "welfareUnitName" }
] ]
} }
}, },
@@ -992,7 +992,7 @@ layout("/layouts/platform_h5.html"){
if (!start || !end) return "未设置" if (!start || !end) return "未设置"
const startDate = this.$moment(start).format("YYYY-MM-DD") const startDate = this.$moment(start).format("YYYY-MM-DD")
const endDate = this.$moment(end).format("YYYY-MM-DD") const endDate = this.$moment(end).format("YYYY-MM-DD HH:mm")
if (startDate === endDate) { if (startDate === endDate) {
return startDate + " " + this.$moment(start).format("HH:mm") + "~" + this.$moment(end).format("HH:mm") return startDate + " " + this.$moment(start).format("HH:mm") + "~" + this.$moment(end).format("HH:mm")
+1
View File
@@ -205,6 +205,7 @@ public class JugTest {
} while (skip < totalCount); } while (skip < totalCount);
Files.write(new File("C:\\Users\\administrator\\Desktop\\博士后.txt"),allUsers);
System.out.println(allUsers.size()); System.out.println(allUsers.size());
} }
+6 -6
View File
@@ -34,12 +34,12 @@ public class Test {
String body = httpRequest.execute().body(); String body = httpRequest.execute().body();
System.out.println(body); System.out.println(body);
JSONObject entries = JSONUtil.parseObj(body); // JSONObject entries = JSONUtil.parseObj(body);
JSONArray value = entries.getJSONArray("value"); // JSONArray value = entries.getJSONArray("value");
//
for (Object o : value) { // for (Object o : value) {
JSONObject jsonObject = (JSONObject) o; // JSONObject jsonObject = (JSONObject) o;
} // }
+242 -13
View File
@@ -5,11 +5,17 @@ import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.annotation.Excel; import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.entity.ExportParams; import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams; import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.IdcardUtil; import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.budwk.app.sys.models.Sys_user; import cn.hutool.crypto.digest.DigestUtil;
import com.budwk.app.sys.models.Sys_user_role; import cn.hutool.http.HttpRequest;
import com.budwk.app.sys.models.Sys_user_source; import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.budwk.app.sys.models.*;
import com.budwk.app.zhgh.welfare.model.WelfareList; import com.budwk.app.zhgh.welfare.model.WelfareList;
import com.budwk.app.zhgh.welfare.model.WelfareProjectSubjectOption; import com.budwk.app.zhgh.welfare.model.WelfareProjectSubjectOption;
import com.budwk.app.zhgh.welfare.model.WelfareUserSelection; import com.budwk.app.zhgh.welfare.model.WelfareUserSelection;
@@ -19,12 +25,15 @@ import org.apache.poi.ss.usermodel.Workbook;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.nutz.boot.test.junit4.NbJUnit4Runner; import org.nutz.boot.test.junit4.NbJUnit4Runner;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd; import org.nutz.dao.Cnd;
import org.nutz.dao.Dao; import org.nutz.dao.Dao;
import org.nutz.dao.Sqls; import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql; import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap; import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.At;
@@ -34,10 +43,7 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.ArrayList; import java.util.*;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@IocBean @IocBean
@@ -289,7 +295,7 @@ public class WelfareTest {
@Test @Test
public void setMember() { public void setMember() {
List<Sys_user> list = dao.query(Sys_user.class, Cnd.where("loginname", "!=", "superadmin").and("userState","=","在岗")); List<Sys_user> list = dao.query(Sys_user.class, Cnd.where("loginname", "!=", "superadmin").and("userState", "=", "在岗"));
for (Sys_user user : list) { for (Sys_user user : list) {
user.setMember(true); user.setMember(true);
} }
@@ -309,15 +315,238 @@ public class WelfareTest {
dao.insert(list2); dao.insert(list2);
} }
@Test
public void updateWelfareListX() {
String[] loginNames = new String[]{"90892", "W11010", "90858", "W11004", "90847", "90849", "W11008", "W11002", "90862", "90861", "90881", "W11005", "W11009", "04409", "W11001", "90860", "W11003", "90859"};
public static void main(String[] args) { Sql sql = Sqls.create("""
String idCard = "42082619890101001X"; SELECT
id,
loginname,
username,
sex,
idCard,
birthday,
personType,
preparedBy,
userState,
unitId,
unitName,
unionId,
unionName,
member
FROM
vw_user
WHERE loginname in (@loginname)
""");
sql.setParam("loginname", loginNames);
List<NutMap> list = welfareService.listMap(sql);
for (NutMap map : list) {
System.out.println(map.getString("loginname") + ":" + map.getString("idCard"));
}
// 插入到福利名单表中
List<WelfareList> welfareList = list.stream().map(user -> {
WelfareList wl = new WelfareList();
String idCard = user.getString("idCard");
Short month = IdcardUtil.getMonthByIdCard(idCard);
if (month <= 3) {
wl.setProjectId("8ff1f9c1d6a547b4a54125efcb9a56b9");
} else if (month <= 6) {
wl.setProjectId("db4f1454e27449459990213740f455b6");
} else if (month <= 9) {
wl.setProjectId("638c6bc84b384fd4a2f64c56faa6a130");
} else if (month <= 12) {
wl.setProjectId("824f43e4286c4d96b8376368c2907be2");
}
wl.setUserId(user.getString("id"));
wl.setWelfareUnitId(user.getString("unitId"));
wl.setWelfareUnitName(user.getString("unitName"));
wl.setWelfareUnionId(user.getString("unionId"));
wl.setWelfareUnionName(user.getString("unionName"));
wl.setPersonType(user.getString("personType"));
wl.setPreparedBy(user.getString("preparedBy"));
wl.setUserState(user.getString("userState"));
return wl;
}).toList();
dao.insert(welfareList);
// 获取月份
Short month = IdcardUtil.getMonthByIdCard(idCard);
System.out.println(month);
} }
@Test
public void updateMember() {
Sql sql = Sqls.create("select * from sys_user where userState = '在岗' or (preparedBy = '博士后' and postDoctoralJoinDate >= '2023-07-01')");
List<NutMap> list = welfareService.listMap(sql);
dao.clear(Sys_user_role.class, Cnd.where(Sys_user_role::getRoleId, "=", "6d603b652abee584ba6274dc1fcee3bb"));
dao.update(Sys_user.class, Chain.make("member", 0), Cnd.where("id", "is not", null));
List<Sys_user_role> list2 = list.stream().map(v -> {
Sys_user_role sysUserRole = new Sys_user_role();
sysUserRole.setRoleId("6d603b652abee584ba6274dc1fcee3bb");
sysUserRole.setUserId(v.getString("id"));
return sysUserRole;
}).toList();
dao.insert(list2);
List<String> ids = list.stream().map(v -> v.getString("id")).toList();
dao.update(Sys_user.class, Chain.make("member", 1), Cnd.where("id", "in", ids));
}
@Test
public void bsh() {
String appId = "1926887238437818370";
String secret = "32df31fcf4fc43f9a647ee1f47134f36";
List<JSONObject> allUsers = new ArrayList<>();
int skip = 0;
int totalCount = 0;
boolean firstRequest = true;
do {
long ts = System.currentTimeMillis();
String sign = Base64.encode(DigestUtil.md5Hex(appId + secret + ts, CharsetUtil.CHARSET_UTF_8));
HttpRequest httpRequest = HttpUtil.createPost("https://sjzcpt.nnu.edu.cn/cdsp/data-api/v2/DS0040");
httpRequest.header("Content-Type", "application/json");
httpRequest.header("appId", appId);
httpRequest.header("timestamp", String.valueOf(ts));
httpRequest.header("sign", sign);
HashMap<String, Object> reqBody = new HashMap<>();
reqBody.put("$count", true);
reqBody.put("$skip", skip);
reqBody.put("$top", 1000);
httpRequest.body(JSONUtil.toJsonStr(reqBody));
String resBody = httpRequest.execute().body();
JSONObject entries = JSONUtil.parseObj(resBody);
if (firstRequest) {
totalCount = entries.getInt("@odata.count", 0);
firstRequest = false;
}
JSONArray value = entries.getJSONArray("value");
if (!value.isEmpty()) {
List<JSONObject> list = value.stream().map(item -> (JSONObject) item).toList();
allUsers.addAll(list);
skip += list.size();
} else {
break;
}
} while (skip < totalCount);
System.out.println(1);
}
@Test
public void importMoneyMember() {
// dao.clear(Sys_user_role.class, Cnd.where(Sys_user_role::getRoleId, "=", "6d603b652abee584ba6274dc1fcee3bb"));
// dao.update(Sys_user.class, Chain.make("member", 0), Cnd.where("id", "is not", null));
// List<Sys_user> list = dao.query(Sys_user.class, Cnd.where(Sys_user::getMember, "=", 1));
// List<String> loginNames = list.stream().map(v -> v.getLoginname()).toList();
//
// List<Map> excelList = ExcelImportUtil.importExcel(new File("C:\\Users\\administrator\\Desktop\\202506工会费统计3375人.xlsx"), Map.class, new ImportParams());
//
//
// for (Map map : excelList) {
// String gh = (String) map.get("工号");
// if(!loginNames.contains(gh)) {
// System.out.println(gh);
// }
// }
// for (Map map : list) {
// String gh = (String) map.get("工号");
// dao.update(Sys_user.class, Chain.make("member", 1), Cnd.where("loginname", "=", gh));
// Sys_user user = dao.fetch(Sys_user.class, Cnd.where("loginname", "=", gh));
//
// if(user == null){
// System.out.println(gh);
// continue;
// }
//
// Sys_user_role sysUserRole = new Sys_user_role();
// sysUserRole.setRoleId("6d603b652abee584ba6274dc1fcee3bb");
// sysUserRole.setUserId(user.getId());
// dao.insert(sysUserRole);
// }
Sql sql = Sqls.create("""
select id from sys_user where username in (
"张荣","夏冬梅","吴秋芹","徐红","蒋丽华","石慧","王英","周蒨","杨亚","夏明秀","赵方圆","郑晓梅","周世菊","肖文敏","陆玉甜","刘佳丽","王程庆子","杨丽","王淼","鲁秀莲","李军","余国华","朱凌","魏堃","李兵","李军友","刘伊丽","金芳杰","殷霞","薛端阳","丁立","刘学云","吴磊","卞振宇","黄适","郝明勤","张凌","管红地","孟进","卢富霞","周福喜","苏金成","陈智瑜","付玥","姜丹","韦益勤","李家保","张艳红","赵青","肖凡","鲁丹丹","和青","贺平","俞相平","严庆普","孟庆霖","罗连英","凌晓民","杜祥浩","王斌","金洪亮","于长翔","李国龙","平向阳","袁秀虎","吴家尧","章爱明","刘德兆","郭年顺","陈金莉","张亮","平向波","王林","王洪喜","吕长斌","金福来","张志婷","杨林","吕六娣","朱庆华","杨金全","刘霞","周宝兰","于小琴","薛颜","凌桂芳","陈万国","季莉","钱卫","黄朝娟","杨海峰","左晓辉","刘凤云","彭启忠","魏树元","张有进","翁念龙","朱宇","吴双林","吴春勇","胡兰平","王慊","宛嘉")
and username not in ('徐红', '陆玉甜', '王程庆子', '鲁秀莲', '李军', '余国华', '刘伊丽', '刘学云', '郝明勤', '孟进', '卢富霞', '周福喜', '付玥', '李家保', '和青', '贺平', '俞相平', '严庆普', '罗连英', '李国龙', '吴家尧', '王洪喜', '张志婷', '杨林', '周宝兰', '凌桂芳', '黄朝娟', '刘凤云', '胡兰平')
and loginname not in ('Y94000004', 'Z0811', 'Y27000299', 'W27071', '53139', 'Y27001708', 'Y33000003', 'W27070', 'Y27001509', 'Y86002837', 'W26003', 'W22001', 'Y69000065', 'Y86000529', '72040', 'W27042')
""");
List<NutMap> list = welfareService.listMap(sql);
List<String> ids = list.stream().map(v -> v.getString("id")).toList();
for (String id : ids) {
dao.update(Sys_user.class, Chain.make("member", 1), Cnd.where("id", "=", id));
Sys_user_role sysUserRole = new Sys_user_role();
sysUserRole.setRoleId("6d603b652abee584ba6274dc1fcee3bb");
sysUserRole.setUserId(id);
dao.insert(sysUserRole);
}
}
@Test
public void updateWelfareListPlus() {
// // 第三季度
// Sql sql = Sqls.create("SELECT id FROM sys_user where preparedBy = '博士后' and postDoctoralJoinDate < '2023-07-01'");
// List<NutMap> list = welfareService.listMap(sql);
//
// for (NutMap nutMap : list) {
// dao.update(Sys_user.class, Chain.make("member", 0), Cnd.where("id", "=", nutMap.getString("id")));
// dao.clear(Sys_user_role.class,Cnd.where(Sys_user_role::getUserId, "=", nutMap.getString("id")).and(Sys_user_role::getRoleId,"=","6d603b652abee584ba6274dc1fcee3bb"));
//
// }
List<NutMap> list = new ArrayList<>();
// list.add(new NutMap().addv("gh", "90954").addv("dw", "100587"));
// list.add(new NutMap().addv("gh", "90953").addv("dw", "100800"));
// list.add(new NutMap().addv("gh", "90976").addv("dw", "100605"));
// list.add(new NutMap().addv("gh", "90960").addv("dw", "100564"));
// list.add(new NutMap().addv("gh", "90942").addv("dw", "100387"));
// list.add(new NutMap().addv("gh", "90958").addv("dw", "100546"));
list.add(new NutMap().addv("gh", "90937").addv("dw", "100800"));
for (NutMap row : list) {
String gh = row.getString("gh");
String dw = row.getString("dw");
Sys_user user = dao.fetch(Sys_user.class, Cnd.where(Sys_user::getLoginname, "=", gh));
dao.update(Sys_user.class,Chain.make("unitid",dw),Cnd.where("id","=",user.getId()));
Sys_unit unit = dao.fetch(Sys_unit.class, dw);
Sys_union union = dao.fetch(Sys_union.class, unit.getUnionId());
WelfareList welfareList = dao.fetch(WelfareList.class, Cnd.where(WelfareList::getUserId, "=", user.getId()));
welfareList.setWelfareUnitId(dw);
welfareList.setWelfareUnitName(unit.getName());
welfareList.setWelfareUnionId(union.getId());
welfareList.setWelfareUnionName(union.getName());
dao.update(welfareList);
}
}
} }