Compare commits
14
Commits
693848bb16
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3db3de39c5 | ||
|
|
9bb29a57de | ||
|
|
49407374b0 | ||
|
|
ac3e08fe5d | ||
|
|
f83513d8f1 | ||
|
|
f4bbb379c3 | ||
|
|
a01ebd7d3e | ||
|
|
e744b7c271 | ||
|
|
eaac21eebc | ||
|
|
f9a87d12e2 | ||
|
|
d551f8c94e | ||
|
|
d6961ebf19 | ||
|
|
b2fc1979fe | ||
|
|
39bdcbfc14 |
+28
@@ -0,0 +1,28 @@
|
|||||||
|
# Maven build output
|
||||||
|
target/
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# IDE settings
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
.vscode/
|
||||||
|
.classpath
|
||||||
|
.project
|
||||||
|
.settings/
|
||||||
|
target
|
||||||
|
# Logs and temporary files
|
||||||
|
*.log
|
||||||
|
/logs/
|
||||||
|
/temp/
|
||||||
|
/tmp/
|
||||||
|
*.tmp
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# Operating system files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
Desktop.ini
|
||||||
Generated
-14
@@ -1,14 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="CompilerConfiguration">
|
|
||||||
<annotationProcessing>
|
|
||||||
<profile default="true" name="Default" enabled="true" />
|
|
||||||
<profile name="Maven default annotation processors profile" enabled="true">
|
|
||||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
|
||||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
|
||||||
<outputRelativeToContentRoot value="true" />
|
|
||||||
<module name="mini" />
|
|
||||||
</profile>
|
|
||||||
</annotationProcessing>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
Generated
-7
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="Encoding">
|
|
||||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
|
||||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
Generated
-30
@@ -1,30 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="RemoteRepositoriesConfiguration">
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="central" />
|
|
||||||
<option name="name" value="Maven Central repository" />
|
|
||||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
|
||||||
</remote-repository>
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="jboss.community" />
|
|
||||||
<option name="name" value="JBoss Community repository" />
|
|
||||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
|
||||||
</remote-repository>
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="nutz-snapshots" />
|
|
||||||
<option name="name" value="nutz-snapshots" />
|
|
||||||
<option name="url" value="https://maven.aliyun.com/repository/public" />
|
|
||||||
</remote-repository>
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="central" />
|
|
||||||
<option name="name" value="Central Repository" />
|
|
||||||
<option name="url" value="https://maven.aliyun.com/repository/public" />
|
|
||||||
</remote-repository>
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="nutz" />
|
|
||||||
<option name="name" value="nutz" />
|
|
||||||
<option name="url" value="https://maven.aliyun.com/repository/public" />
|
|
||||||
</remote-repository>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
Generated
-25
@@ -1,25 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
|
||||||
<component name="MavenProjectsManager">
|
|
||||||
<option name="originalFiles">
|
|
||||||
<list>
|
|
||||||
<option value="$PROJECT_DIR$/pom.xml" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_15" default="true" project-jdk-name="15" project-jdk-type="JavaSDK" />
|
|
||||||
<component name="SvnBranchConfigurationManager">
|
|
||||||
<option name="myConfigurationMap">
|
|
||||||
<map>
|
|
||||||
<entry key="$PROJECT_DIR$">
|
|
||||||
<value>
|
|
||||||
<SvnBranchConfiguration>
|
|
||||||
<option name="trunkUrl" value="http://28bq156916.qicp.vip/svn/UNION_NJUST" />
|
|
||||||
</SvnBranchConfiguration>
|
|
||||||
</value>
|
|
||||||
</entry>
|
|
||||||
</map>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
Generated
-10
@@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="RunConfigurationProducerService">
|
|
||||||
<option name="ignoredProducers">
|
|
||||||
<set>
|
|
||||||
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
|
|
||||||
</set>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
Generated
-6
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="" vcs="svn" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
Generated
-231
@@ -1,231 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="AutoImportSettings">
|
|
||||||
<option name="autoReloadType" value="SELECTIVE" />
|
|
||||||
</component>
|
|
||||||
<component name="ChangeListManager">
|
|
||||||
<list default="true" id="0fb07392-d0a7-4efe-b746-d08bbfef26ce" name="Changes" comment="广播订阅">
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/main/java/io/v/nutz/web/commons/shiro/config/EasyCredentialsMatch.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/io/v/nutz/web/commons/shiro/config/EasyCredentialsMatch.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/main/java/io/v/nutz/web/controllers/mobile/main/MobileMainCon.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/io/v/nutz/web/controllers/mobile/main/MobileMainCon.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/main/java/io/v/nutz/web/controllers/platform/sys/SysHomeController.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/io/v/nutz/web/controllers/platform/sys/SysHomeController.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/test/java/io/v/nutz/WebTestDemo.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/test/java/io/v/nutz/WebTestDemo.java" afterDir="false" />
|
|
||||||
</list>
|
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
||||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
|
||||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
|
||||||
</component>
|
|
||||||
<component name="FileTemplateManagerImpl">
|
|
||||||
<option name="RECENT_TEMPLATES">
|
|
||||||
<list>
|
|
||||||
<option value="Class" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
<component name="GitSEFilterConfiguration">
|
|
||||||
<file-type-list>
|
|
||||||
<filtered-out-file-type name="LOCAL_BRANCH" />
|
|
||||||
<filtered-out-file-type name="REMOTE_BRANCH" />
|
|
||||||
<filtered-out-file-type name="TAG" />
|
|
||||||
<filtered-out-file-type name="COMMIT_BY_MESSAGE" />
|
|
||||||
</file-type-list>
|
|
||||||
</component>
|
|
||||||
<component name="MavenImportPreferences">
|
|
||||||
<option name="generalSettings">
|
|
||||||
<MavenGeneralSettings>
|
|
||||||
<option name="localRepository" value="E:\apps\maven\maven_repo" />
|
|
||||||
<option name="mavenHome" value="$PROJECT_DIR$/../../apps/maven/apache-maven-3.6.3" />
|
|
||||||
<option name="userSettingsFile" value="E:\apps\maven\apache-maven-3.6.3\conf\settings.xml" />
|
|
||||||
</MavenGeneralSettings>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
<component name="ProjectId" id="2zOwLE5J5wsHdx6LOp9U6VCtlFG" />
|
|
||||||
<component name="ProjectViewState">
|
|
||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
|
||||||
<option name="showLibraryContents" value="true" />
|
|
||||||
</component>
|
|
||||||
<component name="PropertiesComponent">
|
|
||||||
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
|
|
||||||
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
|
|
||||||
<property name="WebServerToolWindowFactoryState" value="false" />
|
|
||||||
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
|
||||||
<property name="project.structure.last.edited" value="Project" />
|
|
||||||
<property name="project.structure.proportion" value="0.0" />
|
|
||||||
<property name="project.structure.side.proportion" value="0.2" />
|
|
||||||
<property name="settings.editor.selected.configurable" value="vcs.Subversion" />
|
|
||||||
<property name="vue.rearranger.settings.migration" value="true" />
|
|
||||||
</component>
|
|
||||||
<component name="RunManager" selected="Application.MainLauncher">
|
|
||||||
<configuration name="MainLauncher" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
|
|
||||||
<option name="MAIN_CLASS_NAME" value="io.v.nutz.MainLauncher" />
|
|
||||||
<module name="mini" />
|
|
||||||
<extension name="coverage">
|
|
||||||
<pattern>
|
|
||||||
<option name="PATTERN" value="io.v.nutz.*" />
|
|
||||||
<option name="ENABLED" value="true" />
|
|
||||||
</pattern>
|
|
||||||
</extension>
|
|
||||||
<method v="2">
|
|
||||||
<option name="Make" enabled="true" />
|
|
||||||
</method>
|
|
||||||
</configuration>
|
|
||||||
<configuration name="WebTestDemo.addAidMember" type="JUnit" factoryName="JUnit" temporary="true" nameIsGenerated="true">
|
|
||||||
<module name="mini" />
|
|
||||||
<extension name="coverage">
|
|
||||||
<pattern>
|
|
||||||
<option name="PATTERN" value="io.v.nutz.*" />
|
|
||||||
<option name="ENABLED" value="true" />
|
|
||||||
</pattern>
|
|
||||||
</extension>
|
|
||||||
<option name="PACKAGE_NAME" value="io.v.nutz" />
|
|
||||||
<option name="MAIN_CLASS_NAME" value="io.v.nutz.WebTestDemo" />
|
|
||||||
<option name="METHOD_NAME" value="addAidMember" />
|
|
||||||
<option name="TEST_OBJECT" value="method" />
|
|
||||||
<method v="2">
|
|
||||||
<option name="Make" enabled="true" />
|
|
||||||
</method>
|
|
||||||
</configuration>
|
|
||||||
<configuration name="WebTestDemo.updateTask" type="JUnit" factoryName="JUnit" temporary="true" nameIsGenerated="true">
|
|
||||||
<module name="mini" />
|
|
||||||
<extension name="coverage">
|
|
||||||
<pattern>
|
|
||||||
<option name="PATTERN" value="io.v.nutz.*" />
|
|
||||||
<option name="ENABLED" value="true" />
|
|
||||||
</pattern>
|
|
||||||
</extension>
|
|
||||||
<option name="PACKAGE_NAME" value="io.v.nutz" />
|
|
||||||
<option name="MAIN_CLASS_NAME" value="io.v.nutz.WebTestDemo" />
|
|
||||||
<option name="METHOD_NAME" value="updateTask" />
|
|
||||||
<option name="TEST_OBJECT" value="method" />
|
|
||||||
<method v="2">
|
|
||||||
<option name="Make" enabled="true" />
|
|
||||||
</method>
|
|
||||||
</configuration>
|
|
||||||
<recent_temporary>
|
|
||||||
<list>
|
|
||||||
<item itemvalue="Application.MainLauncher" />
|
|
||||||
<item itemvalue="JUnit.WebTestDemo.updateTask" />
|
|
||||||
<item itemvalue="JUnit.WebTestDemo.addAidMember" />
|
|
||||||
</list>
|
|
||||||
</recent_temporary>
|
|
||||||
</component>
|
|
||||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
|
||||||
<component name="SvnConfiguration" cleanupOnStartRun="true">
|
|
||||||
<configuration>C:\Users\Administrator\AppData\Roaming\Subversion</configuration>
|
|
||||||
<supportedVersion>125</supportedVersion>
|
|
||||||
</component>
|
|
||||||
<component name="SvnFileUrlMappingImpl">
|
|
||||||
<option name="myMappingRoots">
|
|
||||||
<list>
|
|
||||||
<SvnCopyRootSimple>
|
|
||||||
<option name="myVcsRoot" value="E:\project\UNION_NJUST" />
|
|
||||||
<option name="myCopyRoot" value="E:\project\UNION_NJUST" />
|
|
||||||
</SvnCopyRootSimple>
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
<option name="myMoreRealMappingRoots">
|
|
||||||
<list>
|
|
||||||
<SvnCopyRootSimple>
|
|
||||||
<option name="myVcsRoot" value="E:\project\UNION_NJUST" />
|
|
||||||
<option name="myCopyRoot" value="E:\project\UNION_NJUST" />
|
|
||||||
</SvnCopyRootSimple>
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
<component name="TaskManager">
|
|
||||||
<task active="true" id="Default" summary="Default task">
|
|
||||||
<changelist id="0fb07392-d0a7-4efe-b746-d08bbfef26ce" name="Changes" comment="" />
|
|
||||||
<created>1751615372556</created>
|
|
||||||
<option name="number" value="Default" />
|
|
||||||
<option name="presentableId" value="Default" />
|
|
||||||
<updated>1751615372556</updated>
|
|
||||||
<workItem from="1751615377650" duration="57693000" />
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00001">
|
|
||||||
<created>1751963115714</created>
|
|
||||||
<option name="number" value="00001" />
|
|
||||||
<option name="presentableId" value="LOCAL-00001" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1751963115714</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00002">
|
|
||||||
<created>1753181241498</created>
|
|
||||||
<option name="number" value="00002" />
|
|
||||||
<option name="presentableId" value="LOCAL-00002" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1753181241498</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00003">
|
|
||||||
<created>1754897236551</created>
|
|
||||||
<option name="number" value="00003" />
|
|
||||||
<option name="presentableId" value="LOCAL-00003" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1754897236551</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00004">
|
|
||||||
<created>1754964481025</created>
|
|
||||||
<option name="number" value="00004" />
|
|
||||||
<option name="presentableId" value="LOCAL-00004" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1754964481025</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00005">
|
|
||||||
<created>1755138327488</created>
|
|
||||||
<option name="number" value="00005" />
|
|
||||||
<option name="presentableId" value="LOCAL-00005" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1755138327488</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00006" summary="广播订阅">
|
|
||||||
<created>1755155438531</created>
|
|
||||||
<option name="number" value="00006" />
|
|
||||||
<option name="presentableId" value="LOCAL-00006" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1755155438531</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00007" summary="广播订阅">
|
|
||||||
<created>1764121969148</created>
|
|
||||||
<option name="number" value="00007" />
|
|
||||||
<option name="presentableId" value="LOCAL-00007" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1764121969148</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00008" summary="广播订阅">
|
|
||||||
<created>1774437124422</created>
|
|
||||||
<option name="number" value="00008" />
|
|
||||||
<option name="presentableId" value="LOCAL-00008" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1774437124422</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00009" summary="广播订阅">
|
|
||||||
<created>1776763699110</created>
|
|
||||||
<option name="number" value="00009" />
|
|
||||||
<option name="presentableId" value="LOCAL-00009" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1776763699110</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00010" summary="广播订阅">
|
|
||||||
<created>1776823685058</created>
|
|
||||||
<option name="number" value="00010" />
|
|
||||||
<option name="presentableId" value="LOCAL-00010" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1776823685058</updated>
|
|
||||||
</task>
|
|
||||||
<task id="LOCAL-00011" summary="广播订阅">
|
|
||||||
<created>1778468883862</created>
|
|
||||||
<option name="number" value="00011" />
|
|
||||||
<option name="presentableId" value="LOCAL-00011" />
|
|
||||||
<option name="project" value="LOCAL" />
|
|
||||||
<updated>1778468883862</updated>
|
|
||||||
</task>
|
|
||||||
<option name="localTasksCounter" value="12" />
|
|
||||||
<servers />
|
|
||||||
</component>
|
|
||||||
<component name="TypeScriptGeneratedFilesManager">
|
|
||||||
<option name="version" value="3" />
|
|
||||||
</component>
|
|
||||||
<component name="VcsManagerConfiguration">
|
|
||||||
<MESSAGE value="广播订阅" />
|
|
||||||
<option name="LAST_COMMIT_MESSAGE" value="广播订阅" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
@@ -89,7 +89,11 @@ public class ActivityApplyController {
|
|||||||
LEFT JOIN activity_school acts ON acts.id=apply.activityId
|
LEFT JOIN activity_school acts ON acts.id=apply.activityId
|
||||||
LEFT JOIN activity_event ev ON ev.id = apply.eventId $condition
|
LEFT JOIN activity_event ev ON ev.id = apply.eventId $condition
|
||||||
""");
|
""");
|
||||||
cnd.and("apply.activityUnionId", "=", getUnionId());
|
// 其他工会出战的外援仍由原报名人维护,重新打开项目时必须回显。
|
||||||
|
SqlExpressionGroup ownerOrUnion = new SqlExpressionGroup();
|
||||||
|
ownerOrUnion.or("apply.activityUnionId", "=", getUnionId());
|
||||||
|
ownerOrUnion.or("apply.applyUser", "=", ShiroUtil.getUserId());
|
||||||
|
cnd.and(ownerOrUnion);
|
||||||
/* if (!ShiroUtil.hasAnyRoles("A06,sysadmin")) {
|
/* if (!ShiroUtil.hasAnyRoles("A06,sysadmin")) {
|
||||||
SqlExpressionGroup group = new SqlExpressionGroup();
|
SqlExpressionGroup group = new SqlExpressionGroup();
|
||||||
if (ShiroUtil.hasAnyRoles("H01")) {
|
if (ShiroUtil.hasAnyRoles("H01")) {
|
||||||
@@ -239,12 +243,13 @@ public class ActivityApplyController {
|
|||||||
WHERE
|
WHERE
|
||||||
asa.eventId = @eventId
|
asa.eventId = @eventId
|
||||||
AND asa.activityId=@activityId
|
AND asa.activityId=@activityId
|
||||||
AND asa.activityUnionId = @unionid
|
AND (asa.activityUnionId = @unionid OR asa.applyUser = @applyUser)
|
||||||
AND asa.`status` != 3
|
AND asa.`status` != 3
|
||||||
ORDER BY
|
ORDER BY
|
||||||
asa.identity DESC,
|
asa.identity DESC,
|
||||||
asa.sex
|
asa.sex
|
||||||
""").setParam("eventId", eventId).setParam("unionid", union_id).setParam("activityId", activityId);
|
""").setParam("eventId", eventId).setParam("unionid", union_id)
|
||||||
|
.setParam("applyUser", ShiroUtil.getUserId()).setParam("activityId", activityId);
|
||||||
List<ActivitySchoolApply> list = activitySchoolApplyService.listEntity(applySql);
|
List<ActivitySchoolApply> list = activitySchoolApplyService.listEntity(applySql);
|
||||||
//团体人数
|
//团体人数
|
||||||
List<ActivitySchoolApply> awardsModeT = list.stream().filter(v -> v.getAwardsMode().equals("2")).collect(Collectors.toList());
|
List<ActivitySchoolApply> awardsModeT = list.stream().filter(v -> v.getAwardsMode().equals("2")).collect(Collectors.toList());
|
||||||
@@ -349,6 +354,7 @@ public class ActivityApplyController {
|
|||||||
*/
|
*/
|
||||||
@At
|
@At
|
||||||
@ViReturn
|
@ViReturn
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public Object doApply(@Param("data") ActivitySchoolApply[] applies, @Param("appliedData3") ActivitySchoolApply[] applies2, String eventId, boolean pass) {
|
public Object doApply(@Param("data") ActivitySchoolApply[] applies, @Param("appliedData3") ActivitySchoolApply[] applies2, String eventId, boolean pass) {
|
||||||
Sys_user user = (Sys_user) ShiroUtil.getPrincipal();
|
Sys_user user = (Sys_user) ShiroUtil.getPrincipal();
|
||||||
Sys_unit unit = user.getUnit();
|
Sys_unit unit = user.getUnit();
|
||||||
@@ -376,16 +382,46 @@ public class ActivityApplyController {
|
|||||||
apply2.setActivityUnionId(basicUnit.getUnionid());
|
apply2.setActivityUnionId(basicUnit.getUnionid());
|
||||||
apply2.setActivityUnionName(basicUnion.getUnionname());
|
apply2.setActivityUnionName(basicUnion.getUnionname());
|
||||||
}
|
}
|
||||||
if (applies.length > 0) {
|
if (applies.length > 0 || applies2.length > 0) {
|
||||||
activitySchoolApplyService.doApplies(activityId, basicUnit.getUnionid(), eventId, Arrays.asList(applies));
|
List<ActivitySchoolApply> allApplies = new ArrayList<>(Arrays.asList(applies));
|
||||||
}
|
allApplies.addAll(Arrays.asList(applies2));
|
||||||
if (applies2.length > 0) {
|
activitySchoolApplyService.doApplies(activityId, basicUnit.getUnionid(), eventId, allApplies);
|
||||||
activitySchoolApplyService.doApplies(activityId, basicUnit.getUnionid(), eventId, Arrays.asList(applies2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建报名专用人员;工号留空时由服务端生成,手动填写时服务端负责查重。
|
||||||
|
* @param username 外援姓名
|
||||||
|
* @param sex 性别,男或女
|
||||||
|
* @param loginname 可为空;留空时自动生成,手动填写时不能与现有账号重复
|
||||||
|
* @param idcard 18位身份证号,出生日期由服务端从身份证号读取
|
||||||
|
* @param mobile 手机号码
|
||||||
|
* @param fitForCompetition 身体条件是否适合参赛,只有 true 可创建
|
||||||
|
* @return Sys_user,id 为报名人员 ID,loginname 为最终工号,其他字段用于页面回显
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
@RequiresPermissions("activity.apply")
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
public Object addExternalUser(String username, String loginname, String sex, String idcard, String mobile,
|
||||||
|
Boolean fitForCompetition) {
|
||||||
|
if (!Boolean.TRUE.equals(fitForCompetition)) {
|
||||||
|
throw new IllegalArgumentException("身体条件不适合参赛,不能添加外援");
|
||||||
|
}
|
||||||
|
Sys_user operator = (Sys_user) ShiroUtil.getPrincipal();
|
||||||
|
return activitySchoolApplyService.createExternalUser(username, loginname, sex, idcard, mobile, operator.getUnitid());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return String,当前年份的下一个外援工号预览,实际编号以创建接口返回值为准。 */
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
@RequiresPermissions("activity.apply")
|
||||||
|
public Object previewExternalLoginname() {
|
||||||
|
return activitySchoolApplyService.previewExternalLoginname();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 个人报名
|
* 个人报名
|
||||||
*
|
*
|
||||||
@@ -646,116 +682,39 @@ public class ActivityApplyController {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 如果当前项目是综合类活动就添加工会总领队和教练
|
* 保存综合类活动的领队、教练及工作人员;取消选择的活动级身份会删除。
|
||||||
*
|
*
|
||||||
* @param LeaderData
|
* @param activityId 当前活动ID
|
||||||
* @param CoachData
|
* @param staffData 工作人员报名信息,userId 为所选用户ID,空值表示取消
|
||||||
* @return
|
* @param LeaderData 领队报名信息,userId 为所选用户ID,空值表示取消
|
||||||
|
* @param CoachData 教练报名信息,userId 为所选用户ID,空值表示取消
|
||||||
|
* @param headData 团长报名信息,userId 为所选用户ID,空值表示取消
|
||||||
|
* @return null,由 @ViReturn 包装为操作结果
|
||||||
*/
|
*/
|
||||||
@At
|
@At
|
||||||
@ViReturn
|
@ViReturn
|
||||||
public Object doLeaderCoachHead(@Param("staffData") ActivitySchoolApply staffData, @Param("LeaderData") ActivitySchoolApply LeaderData, @Param("CoachData") ActivitySchoolApply CoachData, @Param("headData") ActivitySchoolApply headData) {
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
public Object doLeaderCoachHead(String activityId, @Param("staffData") ActivitySchoolApply staffData,
|
||||||
if (staffData.getUserId() != null) {
|
@Param("LeaderData") ActivitySchoolApply LeaderData,
|
||||||
ActivityBasicUnit basicUnit = activitySchoolService.dao().fetch(ActivityBasicUnit.class, Cnd.where("id", "=", staffData.getUnitId()));
|
@Param("CoachData") ActivitySchoolApply CoachData,
|
||||||
ActivityBasicUnion basicUnion = activitySchoolService.dao().fetch(ActivityBasicUnion.class, Cnd.where("id", "=", basicUnit.getUnionid()));
|
@Param("headData") ActivitySchoolApply headData) {
|
||||||
activitySchoolApplyService.clear(Cnd.where("activityId", "=", staffData.getActivityId()).and("unionStaff", "=", true).and("unionId", "=", getUnionId()));
|
activitySchoolApplyService.saveUnionRoles(activityId, getUnionId(), ShiroUtil.getUserId(),
|
||||||
staffData.setApplyUser(ShiroUtil.getPrincipalProperty("id").toString());
|
staffData, LeaderData, CoachData, headData);
|
||||||
staffData.setApplyDate(DateUtil.getDate());
|
|
||||||
staffData.setUnitname(basicUnit.getName());
|
|
||||||
staffData.setActivityUnionId(basicUnion.getId());
|
|
||||||
staffData.setActivityUnionName(basicUnion.getUnionname());
|
|
||||||
activitySchoolApplyService.insert(staffData);
|
|
||||||
}
|
|
||||||
if (LeaderData.getUserId() != null) {
|
|
||||||
ActivityBasicUnit basicUnit = activitySchoolService.dao().fetch(ActivityBasicUnit.class, Cnd.where("id", "=", LeaderData.getUnitId()));
|
|
||||||
ActivityBasicUnion basicUnion = activitySchoolService.dao().fetch(ActivityBasicUnion.class, Cnd.where("id", "=", basicUnit.getUnionid()));
|
|
||||||
activitySchoolApplyService.clear(Cnd.where("activityId", "=", LeaderData.getActivityId()).and("unionLeader", "=", true).and("unionId", "=", getUnionId()));
|
|
||||||
LeaderData.setApplyUser(ShiroUtil.getPrincipalProperty("id").toString());
|
|
||||||
LeaderData.setApplyDate(DateUtil.getDate());
|
|
||||||
LeaderData.setUnitname(basicUnit.getName());
|
|
||||||
LeaderData.setActivityUnionId(basicUnion.getId());
|
|
||||||
LeaderData.setActivityUnionName(basicUnion.getUnionname());
|
|
||||||
activitySchoolApplyService.insert(LeaderData);
|
|
||||||
}
|
|
||||||
if (CoachData.getUserId() != null) {
|
|
||||||
ActivityBasicUnit basicUnit = activitySchoolService.dao().fetch(ActivityBasicUnit.class, Cnd.where("id", "=", CoachData.getUnitId()));
|
|
||||||
ActivityBasicUnion basicUnion = activitySchoolService.dao().fetch(ActivityBasicUnion.class, Cnd.where("id", "=", basicUnit.getUnionid()));
|
|
||||||
activitySchoolApplyService.clear(Cnd.where("activityId", "=", CoachData.getActivityId()).and("unionCoach", "=", true).and("unionId", "=", getUnionId()));
|
|
||||||
CoachData.setApplyUser(ShiroUtil.getPrincipalProperty("id").toString());
|
|
||||||
CoachData.setApplyDate(DateUtil.getDate());
|
|
||||||
CoachData.setUnitname(basicUnit.getName());
|
|
||||||
CoachData.setActivityUnionId(basicUnion.getId());
|
|
||||||
CoachData.setActivityUnionName(basicUnion.getUnionname());
|
|
||||||
activitySchoolApplyService.insert(CoachData);
|
|
||||||
}
|
|
||||||
if (headData.getUserId() != null) {
|
|
||||||
ActivityBasicUnit basicUnit = activitySchoolService.dao().fetch(ActivityBasicUnit.class, Cnd.where("id", "=", headData.getUnitId()));
|
|
||||||
ActivityBasicUnion basicUnion = activitySchoolService.dao().fetch(ActivityBasicUnion.class, Cnd.where("id", "=", basicUnit.getUnionid()));
|
|
||||||
activitySchoolApplyService.clear(Cnd.where("activityId", "=", headData.getActivityId()).and("unionHead", "=", true).and("unionId", "=", getUnionId()));
|
|
||||||
headData.setApplyUser(ShiroUtil.getPrincipalProperty("id").toString());
|
|
||||||
headData.setApplyDate(DateUtil.getDate());
|
|
||||||
headData.setUnitname(basicUnit.getName());
|
|
||||||
headData.setActivityUnionId(basicUnion.getId());
|
|
||||||
headData.setActivityUnionName(basicUnion.getUnionname());
|
|
||||||
activitySchoolApplyService.insert(headData);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询活动中当前工会的领队、教练和工作人员,并提供可回显的用户选项。
|
||||||
|
*
|
||||||
|
* @param activityId 当前活动ID
|
||||||
|
* @return Map,unionCoach、unionLeader、unionHead、unionStaff 为对应报名记录,
|
||||||
|
* userOptions 为有效用户列表;历史空 userId 仅在返回值中按唯一工号回显
|
||||||
|
*/
|
||||||
@At
|
@At
|
||||||
@ViReturn
|
@ViReturn
|
||||||
public Object getUnionCoachLeaderHead(String activityId) {
|
public Object getUnionCoachLeaderHead(String activityId) {
|
||||||
Map result = new HashMap();
|
return activitySchoolApplyService.getUnionRoleInfo(activityId, getUnionId());
|
||||||
Sql sql = Sqls.create("""
|
|
||||||
SELECT apply.*,us.unitname FROM activity_school_apply apply LEFT JOIN `user` us ON us.id=apply.userId WHERE apply.activityId=@activityId and apply.unionId=@unionId
|
|
||||||
""");
|
|
||||||
sql.setParam("unionId", getUnionId());
|
|
||||||
sql.setParam("activityId", activityId);
|
|
||||||
List<NutMap> list = activitySchoolApplyService.listMap(sql);
|
|
||||||
NutMap unionCoach = list.stream().filter(v -> {
|
|
||||||
return v.getBoolean("unionCoach");
|
|
||||||
}).findFirst().orElse(null);
|
|
||||||
NutMap unionLeader = list.stream().filter(v -> {
|
|
||||||
return v.getBoolean("unionLeader");
|
|
||||||
}).findFirst().orElse(null);
|
|
||||||
NutMap unionHead = list.stream().filter(v -> {
|
|
||||||
return v.getBoolean("unionHead");
|
|
||||||
}).findFirst().orElse(null);
|
|
||||||
NutMap unionStaff = list.stream().filter(v -> {
|
|
||||||
return v.getBoolean("unionStaff");
|
|
||||||
}).findFirst().orElse(null);
|
|
||||||
result.put("unionCoach", unionCoach);
|
|
||||||
result.put("unionLeader", unionLeader);
|
|
||||||
result.put("unionHead", unionHead);
|
|
||||||
result.put("unionStaff", unionStaff);
|
|
||||||
|
|
||||||
List userOptions = List.of();
|
|
||||||
|
|
||||||
ArrayList arrayList = new ArrayList<>(userOptions);
|
|
||||||
|
|
||||||
if (unionCoach != null) {
|
|
||||||
arrayList.add(sysUserService.fetch(unionCoach.getString("userId")));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unionLeader != null) {
|
|
||||||
arrayList.add(sysUserService.fetch(unionLeader.getString("userId")));
|
|
||||||
}
|
|
||||||
if (unionHead != null) {
|
|
||||||
arrayList.add(sysUserService.fetch(unionHead.getString("userId")));
|
|
||||||
}
|
|
||||||
if (unionStaff != null) {
|
|
||||||
arrayList.add(sysUserService.fetch(unionStaff.getString("userId")));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
result.put("userOptions", arrayList);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@@ -817,25 +776,18 @@ public class ActivityApplyController {
|
|||||||
return insert.getId();
|
return insert.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询添加外援时可复用的系统人员。
|
||||||
|
* @param queryString 姓名或工号片段;空值不查询
|
||||||
|
* @param userId 不参与返回的用户 ID 列表,可为空
|
||||||
|
* @return List<NutMap>,每项包含 id、username、loginname、sex、idcard、birthday、mobile、unitid、unitname
|
||||||
|
*/
|
||||||
@At
|
@At
|
||||||
@ViReturn
|
@ViReturn
|
||||||
@RequiresPermissions("activity.apply")
|
@RequiresPermissions("activity.apply")
|
||||||
@Ok("json:{ignoreNull:true}")
|
@Ok("json:{ignoreNull:true}")
|
||||||
public Object getSysUser(String queryString, String[] userId) {
|
public Object getSysUser(String queryString, String[] userId) {
|
||||||
Cnd cnd = Cnd.NEW();
|
return activitySchoolApplyService.searchSystemUsers(queryString, userId);
|
||||||
cnd.andEX("id", "not in", userId);
|
|
||||||
if (StrUtil.isNotBlank(queryString)) {
|
|
||||||
SqlExpressionGroup group = new SqlExpressionGroup();
|
|
||||||
group.andLike("username", queryString).orLike("loginname", queryString);
|
|
||||||
cnd.and(group);
|
|
||||||
}
|
|
||||||
// cnd.and("unionid", "=", Vi.getUnionId());
|
|
||||||
Sql sql = Sqls.create("select id,loginname,username,sex,mobile,unitid,birthday from `user` $condition LIMIT 30");
|
|
||||||
sql.setCondition(cnd);
|
|
||||||
sql.setCallback(Sqls.callback.entities());
|
|
||||||
sql.setEntity(sysUserService.getEntity());
|
|
||||||
List<Sys_user> list = sysUserService.execute(sql).getList(Sys_user.class);
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package io.v.nutz.activity.controller.school;
|
|||||||
|
|
||||||
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
||||||
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||||
|
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
||||||
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.deepoove.poi.XWPFTemplate;
|
import com.deepoove.poi.XWPFTemplate;
|
||||||
@@ -206,7 +207,7 @@ public class ActivityCommonController {
|
|||||||
SELECT
|
SELECT
|
||||||
app.*,
|
app.*,
|
||||||
team.`name` team,
|
team.`name` team,
|
||||||
unit.`name` unitname
|
COALESCE(NULLIF(app.unitname, ''), unit.`name`) unitname
|
||||||
FROM
|
FROM
|
||||||
activity_school_apply app
|
activity_school_apply app
|
||||||
LEFT JOIN activity_school_team team ON app.teamId = team.id
|
LEFT JOIN activity_school_team team ON app.teamId = team.id
|
||||||
@@ -266,13 +267,20 @@ public class ActivityCommonController {
|
|||||||
public void exportXlsx(String id, String unionId, HttpServletResponse response) throws IOException {
|
public void exportXlsx(String id, String unionId, HttpServletResponse response) throws IOException {
|
||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
SELECT
|
SELECT
|
||||||
|
app.id,
|
||||||
|
app.activityId,
|
||||||
|
app.unionId,
|
||||||
|
app.userId,
|
||||||
|
app.eventId,
|
||||||
|
app.teamId,
|
||||||
app.username,
|
app.username,
|
||||||
|
app.birthday,
|
||||||
COALESCE(NULLIF(app.loginname, ''), u.loginname) loginname,
|
COALESCE(NULLIF(app.loginname, ''), u.loginname) loginname,
|
||||||
app.identity,
|
app.identity,
|
||||||
app.activityUnionName,
|
app.activityUnionName,
|
||||||
app.sex,
|
app.sex,
|
||||||
COALESCE(NULLIF(app.mobile, ''), u.mobile) mobile,
|
COALESCE(NULLIF(app.mobile, ''), u.mobile) mobile,
|
||||||
u.idCard idcard,
|
COALESCE(NULLIF(app.idCard, ''), u.idCard) idcard,
|
||||||
COALESCE(unit.unitcode, u.unitcode) unitcode,
|
COALESCE(unit.unitcode, u.unitcode) unitcode,
|
||||||
CASE WHEN u.member = 1 THEN '是' ELSE '否' END isMember,
|
CASE WHEN u.member = 1 THEN '是' ELSE '否' END isMember,
|
||||||
CASE
|
CASE
|
||||||
@@ -316,7 +324,7 @@ public class ActivityCommonController {
|
|||||||
if (Strings.isNotBlank(unionId)) {
|
if (Strings.isNotBlank(unionId)) {
|
||||||
sql.setVar("cnd", "and u.unionid='" + unionId + "'");
|
sql.setVar("cnd", "and u.unionid='" + unionId + "'");
|
||||||
}
|
}
|
||||||
List<NutMap> nutMaps = activitySchoolApplyService.listMap(sql);
|
List<NutMap> nutMaps = activitySchoolApplyService.mergeExportIdentities(activitySchoolApplyService.listMap(sql));
|
||||||
String activityName = nutMaps.get(0).getString("activityName");
|
String activityName = nutMaps.get(0).getString("activityName");
|
||||||
|
|
||||||
List<ExcelExportEntity> entityList = new ArrayList<>();
|
List<ExcelExportEntity> entityList = new ArrayList<>();
|
||||||
@@ -329,6 +337,7 @@ public class ActivityCommonController {
|
|||||||
entityList.add(new ExcelExportEntity("工号", "loginname", 20));
|
entityList.add(new ExcelExportEntity("工号", "loginname", 20));
|
||||||
entityList.add(new ExcelExportEntity("姓名", "username", 20));
|
entityList.add(new ExcelExportEntity("姓名", "username", 20));
|
||||||
entityList.add(new ExcelExportEntity("性别", "sex", 10));
|
entityList.add(new ExcelExportEntity("性别", "sex", 10));
|
||||||
|
entityList.add(new ExcelExportEntity("出生年月", "birthday", 20));
|
||||||
entityList.add(new ExcelExportEntity("身份证号", "idcard", 20));
|
entityList.add(new ExcelExportEntity("身份证号", "idcard", 20));
|
||||||
entityList.add(new ExcelExportEntity("报名人电话号码", "mobile", 20));
|
entityList.add(new ExcelExportEntity("报名人电话号码", "mobile", 20));
|
||||||
entityList.add(new ExcelExportEntity("是否会员", "isMember", 15));
|
entityList.add(new ExcelExportEntity("是否会员", "isMember", 15));
|
||||||
@@ -343,8 +352,10 @@ public class ActivityCommonController {
|
|||||||
z.put("sf", sf.replace("[", "").replace("]", ""));
|
z.put("sf", sf.replace("[", "").replace("]", ""));
|
||||||
});
|
});
|
||||||
response.setContentType("application/octet-stream");
|
response.setContentType("application/octet-stream");
|
||||||
response.setHeader("Content-Disposition", "attachment;filename=" + new String((activityName + "报名表.xls").getBytes("utf-8"), "ISO8859-1"));
|
response.setHeader("Content-Disposition", "attachment;filename=" + new String((activityName + "报名表.xlsx").getBytes("utf-8"), "ISO8859-1"));
|
||||||
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), entityList, nutMaps);
|
ExportParams exportParams = new ExportParams();
|
||||||
|
exportParams.setType(ExcelType.XSSF);
|
||||||
|
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, nutMaps);
|
||||||
markMissingRequiredInfo(workbook);
|
markMissingRequiredInfo(workbook);
|
||||||
workbook.write(response.getOutputStream());
|
workbook.write(response.getOutputStream());
|
||||||
}
|
}
|
||||||
@@ -454,7 +465,7 @@ public class ActivityCommonController {
|
|||||||
ae.allName,
|
ae.allName,
|
||||||
app.*,
|
app.*,
|
||||||
team.`name` teamName,
|
team.`name` teamName,
|
||||||
unit.`name` unitName,
|
COALESCE(NULLIF(app.unitname, ''), unit.`name`) unitName,
|
||||||
gh.unionname AS unionName
|
gh.unionname AS unionName
|
||||||
FROM
|
FROM
|
||||||
activity_school_apply app
|
activity_school_apply app
|
||||||
@@ -640,7 +651,7 @@ public class ActivityCommonController {
|
|||||||
SELECT
|
SELECT
|
||||||
app.*,
|
app.*,
|
||||||
team.`name` team,
|
team.`name` team,
|
||||||
unit.`name` unitname
|
COALESCE(NULLIF(app.unitname, ''), unit.`name`) unitname
|
||||||
FROM
|
FROM
|
||||||
activity_school_apply app
|
activity_school_apply app
|
||||||
LEFT JOIN activity_school_team team ON app.teamId = team.id
|
LEFT JOIN activity_school_team team ON app.teamId = team.id
|
||||||
|
|||||||
@@ -179,8 +179,8 @@ public class ActivityGradesController {
|
|||||||
Cnd cnd = Cnd.NEW();
|
Cnd cnd = Cnd.NEW();
|
||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
SELECT
|
SELECT
|
||||||
us.unitname,
|
apply.*,
|
||||||
apply.*
|
COALESCE(NULLIF(apply.unitname, ''), us.unitname) unitname
|
||||||
FROM
|
FROM
|
||||||
activity_school_apply apply
|
activity_school_apply apply
|
||||||
LEFT JOIN `user` us ON apply.userId = us.id $condition
|
LEFT JOIN `user` us ON apply.userId = us.id $condition
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import io.v.nutz.util.ShiroUtil;
|
|||||||
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.nutz.dao.Chain;
|
import org.nutz.dao.Chain;
|
||||||
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
|
import org.nutz.ioc.aop.Aop;
|
||||||
import org.nutz.dao.Cnd;
|
import org.nutz.dao.Cnd;
|
||||||
import org.nutz.dao.Sqls;
|
import org.nutz.dao.Sqls;
|
||||||
import org.nutz.dao.sql.Sql;
|
import org.nutz.dao.sql.Sql;
|
||||||
@@ -57,6 +59,38 @@ public class ActivityInfoManageController {
|
|||||||
public void index() {
|
public void index() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 无参数;返回 data 数组,每项包含可沿用活动的 id 和 name。 */
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
@RequiresPermissions("activity.school.info")
|
||||||
|
public Object getReuseActivityOptions() {
|
||||||
|
return activitySchoolService.getReuseActivityOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** id 为来源活动ID;返回 data 对象,包含活动字段和 schoolEvents 项目配置数组。 */
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
@RequiresPermissions("activity.school.info")
|
||||||
|
public Object findReuseActivity(String id) {
|
||||||
|
return activitySchoolService.findReuseActivity(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sourceId 为来源活动ID,data 为新活动表单,events 为项目配置数组。
|
||||||
|
* 返回 data 字符串(新活动ID),供保存后继续编辑使用。
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
@RequiresPermissions("activity.school.info")
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
public Object doReuseAdd(String sourceId, @Param("data") ActivitySchool data,
|
||||||
|
@Param("events") ActivitySchoolEvent[] events) {
|
||||||
|
if (StrUtil.isBlank(sourceId) || data == null || data.getActivityLevel() == null) {
|
||||||
|
return Result.error("请选择沿用活动并填写活动信息");
|
||||||
|
}
|
||||||
|
return activitySchoolService.doReuseAdd(sourceId, data, events);
|
||||||
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@ViReturn
|
@ViReturn
|
||||||
public Object pageData(PageForm page, Integer year, String name, String gameStyle, String query, String activityId, String activityLevel) {
|
public Object pageData(PageForm page, Integer year, String name, String gameStyle, String query, String activityId, String activityLevel) {
|
||||||
@@ -104,6 +138,10 @@ public class ActivityInfoManageController {
|
|||||||
} else if ("four".equals(query)) {
|
} else if ("four".equals(query)) {
|
||||||
cnd.and(new Static("now() > school.endTime"));
|
cnd.and(new Static("now() > school.endTime"));
|
||||||
}
|
}
|
||||||
|
// 时间状态快捷查询只展示已提交活动;历史记录的 isSave 可能为空。
|
||||||
|
if ("one".equals(query) || "two".equals(query) || "three".equals(query) || "four".equals(query)) {
|
||||||
|
cnd.and(new Static("(school.isSave IS NULL OR school.isSave <> 1)"));
|
||||||
|
}
|
||||||
if (!ShiroUtil.hasAnyRoles("sysadmin,A06")) {
|
if (!ShiroUtil.hasAnyRoles("sysadmin,A06")) {
|
||||||
if (ActivityRoleUtil.isUnionManager()) {
|
if (ActivityRoleUtil.isUnionManager()) {
|
||||||
cnd.and("school.belongUnionId", "in", ActivityRoleUtil.getManageUnionStr(ShiroUtil.getUserId()));
|
cnd.and("school.belongUnionId", "in", ActivityRoleUtil.getManageUnionStr(ShiroUtil.getUserId()));
|
||||||
|
|||||||
@@ -112,42 +112,21 @@ public class ActivityReadingController {
|
|||||||
ActivityBasicUnit basicUnit = activitySchoolService.dao().fetch(ActivityBasicUnit.class, Cnd.where("id", "=", unitId));
|
ActivityBasicUnit basicUnit = activitySchoolService.dao().fetch(ActivityBasicUnit.class, Cnd.where("id", "=", unitId));
|
||||||
ActivityBasicUnion basicUnion = activitySchoolService.dao().fetch(ActivityBasicUnion.class, Cnd.where("id", "=", basicUnit.getUnionid()));
|
ActivityBasicUnion basicUnion = activitySchoolService.dao().fetch(ActivityBasicUnion.class, Cnd.where("id", "=", basicUnit.getUnionid()));
|
||||||
ActivitySchool activitySchool = activitySchoolService.fetch(id);
|
ActivitySchool activitySchool = activitySchoolService.fetch(id);
|
||||||
Cnd cnd = Cnd.NEW();
|
List<NutMap> applies = activitySchoolApplyService.listRepresentedApplies(id);
|
||||||
Sql sql = Sqls.create("""
|
|
||||||
SELECT
|
|
||||||
app.*,
|
|
||||||
school.`name` activityName,
|
|
||||||
school.applyType applyType,
|
|
||||||
school.belongUnionId belongUnionId,
|
|
||||||
school.belongClubId belongClubId,
|
|
||||||
team.`name` team,
|
|
||||||
unit.`name` unitname,
|
|
||||||
ev.allName,
|
|
||||||
ev.id evid,
|
|
||||||
ev.projectType
|
|
||||||
FROM
|
|
||||||
activity_school_apply app
|
|
||||||
LEFT JOIN activity_school school ON school.id = app.activityId
|
|
||||||
LEFT JOIN activity_school_team team ON app.teamId = team.id
|
|
||||||
LEFT JOIN activity_event ev ON ev.id = app.eventId
|
|
||||||
LEFT JOIN sys_unit unit ON app.unitId = unit.id
|
|
||||||
$condition
|
|
||||||
""");
|
|
||||||
|
|
||||||
cnd.and("app.activityId", "=", id);
|
|
||||||
// cnd.and("YEAR(app.applyDate)", "=", year);
|
|
||||||
sql.setCondition(cnd);
|
|
||||||
if (!ShiroUtil.hasAnyRoles("sysadmin,A06")) {
|
if (!ShiroUtil.hasAnyRoles("sysadmin,A06")) {
|
||||||
if ((ActivityRoleUtil.isUnionManager() || ShiroUtil.hasRole("gh08")) && activityLevel.equals("40002")) {
|
if ((ActivityRoleUtil.isUnionManager() || ShiroUtil.hasRole("gh08")) && activityLevel.equals("40002")) {
|
||||||
cnd.and("app.activityUnionId", "=", basicUnit.getUnionid());
|
// 权限仍按活动所属工会限制;报名分组按外援选中的单位工会计算。
|
||||||
cnd.and("school.belongUnionId", "=", basicUnit.getUnionid());
|
applies = basicUnit.getUnionid().equals(activitySchool.getBelongUnionId())
|
||||||
|
? applies.stream().filter(v -> basicUnit.getUnionid().equals(v.getString("representedActivityUnionId")))
|
||||||
|
.collect(Collectors.toList()) : List.of();
|
||||||
}
|
}
|
||||||
if (ShiroUtil.hasRole("H02") && activityLevel.equals("40003")) {
|
if (ShiroUtil.hasRole("H02") && activityLevel.equals("40003")) {
|
||||||
cnd.and("school.belongClubId", "in", vi.getMangeClubStr());
|
if (activitySchoolService.count(Cnd.where("id", "=", id)
|
||||||
|
.and("belongClubId", "in", vi.getMangeClubStr())) == 0) {
|
||||||
|
applies = List.of();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cnd.desc("ev.allName").asc("ev.projectType").asc("team.`name`");
|
|
||||||
List<NutMap> applies = activitySchoolApplyService.listMap(sql);
|
|
||||||
|
|
||||||
List<NutMap> apply = new ArrayList();
|
List<NutMap> apply = new ArrayList();
|
||||||
|
|
||||||
@@ -157,10 +136,6 @@ public class ActivityReadingController {
|
|||||||
unionCnd.and("id", "=", basicUnit.getUnionid());
|
unionCnd.and("id", "=", basicUnit.getUnionid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (activityLevel.equals("40002")) {
|
|
||||||
unionCnd.and("id", "=", activitySchool.getBelongUnionId());
|
|
||||||
}
|
|
||||||
unionCnd.and("isEnable", "=", true);
|
|
||||||
unionCnd.asc("unioncode");
|
unionCnd.asc("unioncode");
|
||||||
|
|
||||||
if (!activityLevel.equals("40003")) {
|
if (!activityLevel.equals("40003")) {
|
||||||
@@ -168,10 +143,20 @@ public class ActivityReadingController {
|
|||||||
|
|
||||||
for (ActivityBasicUnion union : unions) {
|
for (ActivityBasicUnion union : unions) {
|
||||||
String unionId = union.getId();
|
String unionId = union.getId();
|
||||||
|
boolean hasApplies = applies.stream()
|
||||||
|
.anyMatch(v -> unionId.equals(v.getString("representedActivityUnionId")));
|
||||||
|
if (!union.isEnable() && !hasApplies) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 院级活动保留主办工会,同时展示由所选单位代表其他工会出战的报名。
|
||||||
|
if (activityLevel.equals("40002") && !unionId.equals(activitySchool.getBelongUnionId())
|
||||||
|
&& !hasApplies) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
NutMap map = new NutMap();
|
NutMap map = new NutMap();
|
||||||
|
|
||||||
List<NutMap> applyList = applies.stream().filter(v -> {
|
List<NutMap> applyList = applies.stream().filter(v -> {
|
||||||
return v.getString("activityUnionId").equals(unionId);
|
return unionId.equals(v.getString("representedActivityUnionId"));
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
map.setv("id", unionId);
|
map.setv("id", unionId);
|
||||||
map.setv("unionname", union.getUnionname());
|
map.setv("unionname", union.getUnionname());
|
||||||
@@ -183,7 +168,7 @@ public class ActivityReadingController {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
NutMap map = new NutMap();
|
NutMap map = new NutMap();
|
||||||
Sys_club sysClub = sysClubService.fetch(cnd.where("id", "=", activitySchool.getBelongClubId()));
|
Sys_club sysClub = sysClubService.fetch(Cnd.where("id", "=", activitySchool.getBelongClubId()));
|
||||||
map.setv("id", sysClub.getId());
|
map.setv("id", sysClub.getId());
|
||||||
map.setv("unionname", sysClub.getName());
|
map.setv("unionname", sysClub.getName());
|
||||||
map.setv("unioncode", sysClub.getCode());
|
map.setv("unioncode", sysClub.getCode());
|
||||||
@@ -230,6 +215,9 @@ public class ActivityReadingController {
|
|||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
SELECT
|
SELECT
|
||||||
apply.loginname,
|
apply.loginname,
|
||||||
|
apply.birthday,
|
||||||
|
apply.mobile,
|
||||||
|
apply.unitname,
|
||||||
apply.username,
|
apply.username,
|
||||||
apply.sex,
|
apply.sex,
|
||||||
IF(apply.sex='男',1,2) AS sexOrder,
|
IF(apply.sex='男',1,2) AS sexOrder,
|
||||||
@@ -243,12 +231,16 @@ public class ActivityReadingController {
|
|||||||
FROM
|
FROM
|
||||||
`activity_school_apply` apply
|
`activity_school_apply` apply
|
||||||
LEFT JOIN activity_event `event` ON `event`.id = apply.eventId
|
LEFT JOIN activity_event `event` ON `event`.id = apply.eventId
|
||||||
|
LEFT JOIN sys_unit selectedUnit ON selectedUnit.id = apply.unitId
|
||||||
|
LEFT JOIN activity_basic_unit activityUnit ON activityUnit.id = apply.unitId
|
||||||
LEFT JOIN activity_basic_settings groupSetting ON groupSetting.id = `event`.competitionCategory
|
LEFT JOIN activity_basic_settings groupSetting ON groupSetting.id = `event`.competitionCategory
|
||||||
LEFT JOIN activity_basic_settings projectNameSetting ON projectNameSetting.id = `event`.sports
|
LEFT JOIN activity_basic_settings projectNameSetting ON projectNameSetting.id = `event`.sports
|
||||||
LEFT JOIN activity_basic_settings distanceSetting ON distanceSetting.id = `event`.distance
|
LEFT JOIN activity_basic_settings distanceSetting ON distanceSetting.id = `event`.distance
|
||||||
WHERE
|
WHERE
|
||||||
apply.activityId = @id
|
apply.activityId = @id
|
||||||
AND apply.unionId = @unionId
|
AND (CASE WHEN apply.unitname = selectedUnit.name AND selectedUnit.unionid IS NOT NULL
|
||||||
|
AND activityUnit.unionid IS NOT NULL THEN selectedUnit.unionid
|
||||||
|
ELSE apply.unionId END) = @unionId
|
||||||
AND JSON_CONTAINS(apply.identity,JSON_Array( '1' ))
|
AND JSON_CONTAINS(apply.identity,JSON_Array( '1' ))
|
||||||
ORDER BY
|
ORDER BY
|
||||||
FIELD( apply.sex, '男', '女 ' ),
|
FIELD( apply.sex, '男', '女 ' ),
|
||||||
@@ -269,6 +261,10 @@ public class ActivityReadingController {
|
|||||||
for (int i = 0; i < v.size(); i++) {
|
for (int i = 0; i < v.size(); i++) {
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0 -> {
|
case 0 -> {
|
||||||
|
entity.setLoginname(v.get(i).getString("loginname"));
|
||||||
|
entity.setBirthday(v.get(i).getString("birthday"));
|
||||||
|
entity.setMobile(v.get(i).getString("mobile"));
|
||||||
|
entity.setUnitname(v.get(i).getString("unitname"));
|
||||||
if (v.get(i).getInt("awardsMode") == 1) {
|
if (v.get(i).getInt("awardsMode") == 1) {
|
||||||
entity.setUserName(v.get(i).getString("username"));
|
entity.setUserName(v.get(i).getString("username"));
|
||||||
entity.setSex(v.get(i).getString("sex"));
|
entity.setSex(v.get(i).getString("sex"));
|
||||||
|
|||||||
@@ -23,10 +23,12 @@ import org.nutz.dao.util.cri.Static;
|
|||||||
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.lang.Strings;
|
import org.nutz.lang.Strings;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
import org.nutz.mvc.annotation.At;
|
import org.nutz.mvc.annotation.At;
|
||||||
import org.nutz.mvc.annotation.Ok;
|
import org.nutz.mvc.annotation.Ok;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -139,20 +141,21 @@ public class ActivityRemindController {
|
|||||||
WHERE
|
WHERE
|
||||||
sur.unionid = un.id
|
sur.unionid = un.id
|
||||||
AND sr.id IN (@h04RoleId, @activityRoleId)
|
AND sr.id IN (@h04RoleId, @activityRoleId)
|
||||||
) unionleader,
|
) unionleader
|
||||||
( SELECT COUNT( 1 ) FROM activity_school_apply asp WHERE asp.unionId = un.id AND asp.activityId = @activityId ) num
|
|
||||||
FROM
|
FROM
|
||||||
`sys_union` un
|
`sys_union` un
|
||||||
ORDER BY
|
ORDER BY
|
||||||
un.unioncode
|
un.unioncode
|
||||||
""").setParam("h04RoleId", Roles.UNION_MANGER)
|
""").setParam("h04RoleId", Roles.UNION_MANGER)
|
||||||
.setParam("activityRoleId", Roles.SPORTS_ACTIVITY_UNION_ADMIN)
|
.setParam("activityRoleId", Roles.SPORTS_ACTIVITY_UNION_ADMIN);
|
||||||
.setParam("activityId", activityId);
|
|
||||||
|
|
||||||
List<Record> unions = sysUnionService.list(sql);
|
List<Record> unions = sysUnionService.list(sql);
|
||||||
|
Map<String, List<NutMap>> appliesByUnion = activitySchoolApplyService.groupRepresentedAppliesByUnion(activityId);
|
||||||
|
|
||||||
unions.forEach(v -> {
|
unions.forEach(v -> {
|
||||||
v.set("users", activitySchoolApplyService.query(Cnd.where("unionId", "=", v.getString("id")).and("activityId", "=", activityId).desc("identity")));
|
List<NutMap> users = appliesByUnion.getOrDefault(v.getString("id"), List.of());
|
||||||
|
v.set("users", users);
|
||||||
|
v.set("num", users.size());
|
||||||
});
|
});
|
||||||
|
|
||||||
return unions;
|
return unions;
|
||||||
@@ -185,20 +188,20 @@ public class ActivityRemindController {
|
|||||||
WHERE
|
WHERE
|
||||||
sur.unionid = un.id
|
sur.unionid = un.id
|
||||||
AND sr.id IN (@h04RoleId, @activityRoleId)
|
AND sr.id IN (@h04RoleId, @activityRoleId)
|
||||||
) telephone,
|
) telephone
|
||||||
( SELECT COUNT( 1 ) FROM activity_school_apply asp WHERE asp.unionId = un.id AND asp.activityId = @activityId ) num
|
|
||||||
FROM
|
FROM
|
||||||
`sys_union` un
|
`sys_union` un
|
||||||
ORDER BY
|
ORDER BY
|
||||||
un.unioncode
|
un.unioncode
|
||||||
""").setParam("h04RoleId", Roles.UNION_MANGER)
|
""").setParam("h04RoleId", Roles.UNION_MANGER)
|
||||||
.setParam("activityRoleId", Roles.SPORTS_ACTIVITY_UNION_ADMIN)
|
.setParam("activityRoleId", Roles.SPORTS_ACTIVITY_UNION_ADMIN);
|
||||||
.setParam("activityId", activityId);
|
|
||||||
|
|
||||||
List<Record> unions = sysUnionService.list(sql);
|
List<Record> unions = sysUnionService.list(sql);
|
||||||
|
Map<String, List<NutMap>> appliesByUnion = activitySchoolApplyService.groupRepresentedAppliesByUnion(activityId);
|
||||||
|
|
||||||
List<Record> collect = unions.stream().filter(v -> {
|
List<Record> collect = unions.stream().filter(v -> {
|
||||||
return v.getInt("num") <= 0 && v.getString("telephone") != null;
|
return appliesByUnion.getOrDefault(v.getString("id"), List.of()).isEmpty()
|
||||||
|
&& v.getString("telephone") != null;
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
collect.forEach(v -> {
|
collect.forEach(v -> {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import io.v.nutz.activity.models.ActivityBasicUnion;
|
|||||||
import io.v.nutz.activity.models.ActivityBasicUnit;
|
import io.v.nutz.activity.models.ActivityBasicUnit;
|
||||||
import io.v.nutz.activity.models.ActivityResults;
|
import io.v.nutz.activity.models.ActivityResults;
|
||||||
import io.v.nutz.activity.models.ActivitySchoolApply;
|
import io.v.nutz.activity.models.ActivitySchoolApply;
|
||||||
|
import io.v.nutz.activity.services.ActivitySchoolApplyService;
|
||||||
import io.v.nutz.annontation.ViReturn;
|
import io.v.nutz.annontation.ViReturn;
|
||||||
import io.v.nutz.base.utils.DateUtil;
|
import io.v.nutz.base.utils.DateUtil;
|
||||||
import io.v.nutz.base.utils.Vi;
|
import io.v.nutz.base.utils.Vi;
|
||||||
@@ -47,6 +48,9 @@ public class ActivityResultsController {
|
|||||||
@Inject("ActivitySchoolApply")
|
@Inject("ActivitySchoolApply")
|
||||||
private ViService<ActivitySchoolApply> activitySchoolApplyViService;
|
private ViService<ActivitySchoolApply> activitySchoolApplyViService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ActivitySchoolApplyService activitySchoolApplyService;
|
||||||
|
|
||||||
|
|
||||||
@At("")
|
@At("")
|
||||||
@Ok("beetl:platform/activity/school/ActivityResults.html")
|
@Ok("beetl:platform/activity/school/ActivityResults.html")
|
||||||
@@ -195,32 +199,14 @@ public class ActivityResultsController {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询团体参赛部门工会
|
* activityId、eventId 为页面当前活动和项目ID,仅保留接口参数兼容原调用。
|
||||||
*
|
* 返回全部系统工会列表,每项包含 id 和 unionname,供团体成绩录入选择。
|
||||||
* @param activityId
|
|
||||||
* @param eventId
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@ViReturn
|
@ViReturn
|
||||||
public Object getUnionList(String activityId, String eventId) {
|
public Object getUnionList(String activityId, String eventId) {
|
||||||
Sql sql = Sqls.create("""
|
return activitySchoolApplyService.getResultUnionOptions();
|
||||||
|
|
||||||
SELECT
|
|
||||||
un.id,
|
|
||||||
un.unionname
|
|
||||||
FROM
|
|
||||||
activity_school_apply asa
|
|
||||||
LEFT JOIN sys_union un ON un.id = asa.unionId
|
|
||||||
WHERE
|
|
||||||
asa.activityId = @activityId
|
|
||||||
AND asa.eventId = @eventId
|
|
||||||
|
|
||||||
GROUP BY
|
|
||||||
un.unionname
|
|
||||||
""").setParam("activityId", activityId).setParam("eventId", eventId);
|
|
||||||
return activitySchoolApplyViService.list(sql);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject("Sys_user")
|
@Inject("Sys_user")
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ public class ActivityReviewController {
|
|||||||
apply.loginname,
|
apply.loginname,
|
||||||
apply.username,
|
apply.username,
|
||||||
apply.mobile,
|
apply.mobile,
|
||||||
|
apply.sex,
|
||||||
|
apply.birthday,
|
||||||
|
apply.unitname,
|
||||||
apply.identity,
|
apply.identity,
|
||||||
school.id schoolId,
|
school.id schoolId,
|
||||||
school.eventsId,
|
school.eventsId,
|
||||||
|
|||||||
+8
@@ -18,6 +18,14 @@ public class SchoolActivityApplyExportEntity {
|
|||||||
private String number;
|
private String number;
|
||||||
@Excel(name = "姓名", width = 20d)
|
@Excel(name = "姓名", width = 20d)
|
||||||
private String userName;
|
private String userName;
|
||||||
|
@Excel(name = "工号", width = 20d)
|
||||||
|
private String loginname;
|
||||||
|
@Excel(name = "出生年月", width = 20d)
|
||||||
|
private String birthday;
|
||||||
|
@Excel(name = "电话", width = 20d)
|
||||||
|
private String mobile;
|
||||||
|
@Excel(name = "单位", width = 20d)
|
||||||
|
private String unitname;
|
||||||
@Excel(name = "性别", width = 20d)
|
@Excel(name = "性别", width = 20d)
|
||||||
private String sex;
|
private String sex;
|
||||||
|
|
||||||
|
|||||||
@@ -168,6 +168,9 @@ public class ActivitySchoolApply implements Serializable {
|
|||||||
private String mobile;
|
private String mobile;
|
||||||
|
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("报名时使用的身份证号,系统资料为空时保存本次手动补充值")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||||
@Excel(name = "身份证号", width = 20)
|
@Excel(name = "身份证号", width = 20)
|
||||||
private String idCard;
|
private String idCard;
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,96 @@
|
|||||||
package io.v.nutz.activity.services;
|
package io.v.nutz.activity.services;
|
||||||
|
|
||||||
import io.v.nutz.activity.models.ActivitySchoolApply;
|
import io.v.nutz.activity.models.ActivitySchoolApply;
|
||||||
|
import io.v.nutz.sys.models.Sys_user;
|
||||||
import io.v.nutz.service.ViService;
|
import io.v.nutz.service.ViService;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Aaron
|
* @author Aaron
|
||||||
*/
|
*/
|
||||||
public interface ActivitySchoolApplyService extends ViService<ActivitySchoolApply> {
|
public interface ActivitySchoolApplyService extends ViService<ActivitySchoolApply> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取团体成绩录入可选的全部系统工会,不受活动项目报名情况或启用状态限制。
|
||||||
|
* @return 工会列表,每项包含 id(成绩记录使用的工会ID)和 unionname(下拉显示名称)
|
||||||
|
*/
|
||||||
|
List<NutMap> getResultUnionOptions();
|
||||||
|
|
||||||
|
/** @return 当前年份预计分配的外援工号;实际工号以创建接口返回值为准。 */
|
||||||
|
String previewExternalLoginname();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按姓名或工号查找可复用的系统人员。
|
||||||
|
* @param queryString 搜索内容,空值返回空列表
|
||||||
|
* @param excludedUserIds 当前页面需要排除的用户 ID
|
||||||
|
* @return 人员列表,每项包含 id、姓名、工号、性别、身份证号、出生日期、电话和系统单位
|
||||||
|
*/
|
||||||
|
List<NutMap> searchSystemUsers(String queryString, String[] excludedUserIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询活动报名及其代表出战的工会;历史报名仅在所存单位 ID 与单位名称一致时按该单位归属。
|
||||||
|
* @param activityId 活动 ID
|
||||||
|
* @return 报名列表,representedUnionId 是系统工会 ID,representedActivityUnionId 是活动工会 ID,
|
||||||
|
* 其余字段为报名、活动、项目和队伍的展示字段
|
||||||
|
*/
|
||||||
|
List<NutMap> listRepresentedApplies(String activityId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按代表出战的系统工会归集活动报名,供工会提醒名单和报名人数共用。
|
||||||
|
* @param activityId 活动 ID
|
||||||
|
* @return 以系统工会 ID 为键、该工会报名记录列表为值的 Map
|
||||||
|
*/
|
||||||
|
Map<String, List<NutMap>> groupRepresentedAppliesByUnion(String activityId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建仅用于报名的用户;工号可采用 wy 年份流水号,也可手动填写。
|
||||||
|
* @param username 外援姓名
|
||||||
|
* @param sex 性别,男或女
|
||||||
|
* @param loginname 留空时自动生成的工号;手动填写时不能与系统现有工号重复
|
||||||
|
* @param idcard 身份证号,出生日期从中读取
|
||||||
|
* @param mobile 手机号码
|
||||||
|
* @param unitId 报名人所在单位 ID,用于归属当前报名工会
|
||||||
|
* @return 已创建的系统用户,包含用户 ID、最终工号和系统资料
|
||||||
|
*/
|
||||||
|
Sys_user createExternalUser(String username, String loginname, String sex, String idcard, String mobile, String unitId);
|
||||||
|
|
||||||
void doApplies(List<ActivitySchoolApply> applies);
|
void doApplies(List<ActivitySchoolApply> applies);
|
||||||
|
|
||||||
void doApplies(String activity, String union_id, String eventId,List<ActivitySchoolApply> applies);
|
void doApplies(String activity, String union_id, String eventId,List<ActivitySchoolApply> applies);
|
||||||
|
|
||||||
void doApply(ActivitySchoolApply apply);
|
void doApply(ActivitySchoolApply apply);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存活动级工会人员;空 userId 表示取消该身份,项目内的报名记录不受影响。
|
||||||
|
*
|
||||||
|
* @param activityId 活动ID
|
||||||
|
* @param unionId 当前工会ID
|
||||||
|
* @param operatorId 当前操作人的用户ID
|
||||||
|
* @param staffData 工作人员报名信息,空 userId 表示取消
|
||||||
|
* @param leaderData 领队报名信息,空 userId 表示取消
|
||||||
|
* @param coachData 教练报名信息,空 userId 表示取消
|
||||||
|
* @param headData 团长报名信息,空 userId 表示取消
|
||||||
|
*/
|
||||||
|
void saveUnionRoles(String activityId, String unionId, String operatorId, ActivitySchoolApply staffData,
|
||||||
|
ActivitySchoolApply leaderData, ActivitySchoolApply coachData, ActivitySchoolApply headData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询活动级工会人员及姓名下拉选项,历史空用户ID仅在返回数据中按唯一工号补齐。
|
||||||
|
*
|
||||||
|
* @param activityId 活动ID
|
||||||
|
* @param unionId 当前工会ID
|
||||||
|
* @return 包含 unionCoach、unionLeader、unionHead、unionStaff 报名记录及 userOptions 用户列表的 Map
|
||||||
|
*/
|
||||||
|
Map<String, Object> getUnionRoleInfo(String activityId, String unionId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合并同一人员在活动级和同一项目队伍中的导出身份,保留不同项目和队伍。
|
||||||
|
*
|
||||||
|
* @param rows 导出查询的报名记录,需包含活动、工会、人员、项目、队伍ID及 identity
|
||||||
|
* @return 每个项目队伍一行的导出记录;没有项目报名的活动级人员仍保留一行
|
||||||
|
*/
|
||||||
|
List<NutMap> mergeExportIdentities(List<NutMap> rows);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,23 @@ package io.v.nutz.activity.services;
|
|||||||
import io.v.nutz.activity.models.ActivitySchool;
|
import io.v.nutz.activity.models.ActivitySchool;
|
||||||
import io.v.nutz.activity.models.ActivitySchoolEvent;
|
import io.v.nutz.activity.models.ActivitySchoolEvent;
|
||||||
import io.v.nutz.service.ViService;
|
import io.v.nutz.service.ViService;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Aaron
|
* @author Aaron
|
||||||
*/
|
*/
|
||||||
public interface ActivitySchoolService extends ViService<ActivitySchool> {
|
public interface ActivitySchoolService extends ViService<ActivitySchool> {
|
||||||
|
|
||||||
|
/** 无参数;返回当前管理范围内可沿用活动的 id、name 列表,按创建时间倒序。 */
|
||||||
|
List<NutMap> getReuseActivityOptions();
|
||||||
|
|
||||||
|
/** id 为历史活动ID;返回活动字段及 schoolEvents 项目配置数组,不可访问时抛出异常。 */
|
||||||
|
NutMap findReuseActivity(String id);
|
||||||
|
|
||||||
|
/** sourceId 为来源活动ID,activitySchool 为新活动信息,events 为项目配置;返回新活动ID。 */
|
||||||
|
String doReuseAdd(String sourceId, ActivitySchool activitySchool, ActivitySchoolEvent[] events);
|
||||||
|
|
||||||
String doAdd(ActivitySchool activitySchool, ActivitySchoolEvent[] events);
|
String doAdd(ActivitySchool activitySchool, ActivitySchoolEvent[] events);
|
||||||
|
|
||||||
void doEdit(ActivitySchool activitySchool, ActivitySchoolEvent[] events, String applyEndTime);
|
void doEdit(ActivitySchool activitySchool, ActivitySchoolEvent[] events, String applyEndTime);
|
||||||
|
|||||||
@@ -1,25 +1,175 @@
|
|||||||
package io.v.nutz.activity.services.impl;
|
package io.v.nutz.activity.services.impl;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.hutool.core.util.IdcardUtil;
|
||||||
|
import io.v.nutz.activity.models.ActivityBasicUnion;
|
||||||
|
import io.v.nutz.activity.models.ActivityBasicUnit;
|
||||||
import io.v.nutz.activity.models.ActivitySchoolApply;
|
import io.v.nutz.activity.models.ActivitySchoolApply;
|
||||||
import io.v.nutz.activity.services.ActivitySchoolApplyService;
|
import io.v.nutz.activity.services.ActivitySchoolApplyService;
|
||||||
|
import io.v.nutz.base.utils.DateUtil;
|
||||||
import io.v.nutz.service.impl.ViServiceImpl;
|
import io.v.nutz.service.impl.ViServiceImpl;
|
||||||
|
import io.v.nutz.sys.models.Sys_user;
|
||||||
|
import io.v.nutz.sys.models.Sys_unit;
|
||||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
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.sql.Sql;
|
||||||
|
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||||
import org.nutz.ioc.aop.Aop;
|
import org.nutz.ioc.aop.Aop;
|
||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.lang.Lang;
|
||||||
|
import org.nutz.lang.Strings;
|
||||||
|
import org.nutz.lang.random.R;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.Year;
|
||||||
|
import java.time.format.DateTimeParseException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
@IocBean(args = {"refer:dao"})
|
@IocBean(args = {"refer:dao"})
|
||||||
public class ActivitySchoolApplyServiceImpl extends ViServiceImpl<ActivitySchoolApply> implements ActivitySchoolApplyService {
|
public class ActivitySchoolApplyServiceImpl extends ViServiceImpl<ActivitySchoolApply> implements ActivitySchoolApplyService {
|
||||||
|
|
||||||
|
private static final Object EXTERNAL_NUMBER_LOCK = new Object();
|
||||||
|
|
||||||
public ActivitySchoolApplyServiceImpl(Dao dao) {
|
public ActivitySchoolApplyServiceImpl(Dao dao) {
|
||||||
super(dao);
|
super(dao);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<NutMap> getResultUnionOptions() {
|
||||||
|
// 团体成绩可以选择未报名该项目的工会,因此从系统工会表完整读取。
|
||||||
|
return listMap(Sqls.create("SELECT id, unionname FROM sys_union ORDER BY unioncode"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String previewExternalLoginname() {
|
||||||
|
String prefix = "wy" + Year.now().getValue();
|
||||||
|
Sql sql = Sqls.create("SELECT loginname FROM sys_user WHERE loginname LIKE @prefix");
|
||||||
|
sql.setParam("prefix", prefix + "%");
|
||||||
|
long number = 0;
|
||||||
|
for (NutMap row : listMap(sql)) {
|
||||||
|
String loginname = row.getString("loginname");
|
||||||
|
if (Strings.isBlank(loginname) || !loginname.matches("^" + prefix + "[0-9]+$")) continue;
|
||||||
|
try {
|
||||||
|
number = Math.max(number, Long.parseLong(loginname.substring(prefix.length())));
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
// 非法超长工号不参与流水号计算,保留其他有效工号的最大值。
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return prefix + String.format("%02d", number + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<NutMap> searchSystemUsers(String queryString, String[] excludedUserIds) {
|
||||||
|
String query = Strings.sNull(queryString).trim();
|
||||||
|
if (query.isEmpty()) return List.of();
|
||||||
|
Sql sql = Sqls.create("SELECT u.id,u.loginname,u.username,u.sex,u.idcard,u.birthday,u.mobile,"
|
||||||
|
+ "u.unitid,un.name unitname FROM sys_user u "
|
||||||
|
+ "LEFT JOIN sys_unit un ON un.id=u.unitid $condition LIMIT 30");
|
||||||
|
Cnd cnd = Cnd.NEW();
|
||||||
|
cnd.andEX("u.id", "not in", excludedUserIds);
|
||||||
|
SqlExpressionGroup names = new SqlExpressionGroup();
|
||||||
|
names.orLike("u.username", query).orLike("u.loginname", query);
|
||||||
|
cnd.and(names);
|
||||||
|
sql.setCondition(cnd);
|
||||||
|
return listMap(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<NutMap> listRepresentedApplies(String activityId) {
|
||||||
|
// 兼容提交时曾写入操作人工会的外援记录;只有保存的单位 ID 和名称一致才采用所选单位的工会。
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT app.*, school.name activityName, school.applyType, school.belongUnionId,
|
||||||
|
school.belongClubId, team.name team,
|
||||||
|
COALESCE(NULLIF(app.unitname, ''), unit.name) unitname,
|
||||||
|
ev.allName, ev.id evid, ev.projectType,
|
||||||
|
CASE WHEN app.unitname = unit.name AND unit.unionid IS NOT NULL
|
||||||
|
AND basicUnit.unionid IS NOT NULL THEN unit.unionid
|
||||||
|
ELSE app.unionId END representedUnionId,
|
||||||
|
CASE WHEN app.unitname = unit.name AND unit.unionid IS NOT NULL
|
||||||
|
AND basicUnit.unionid IS NOT NULL THEN basicUnit.unionid
|
||||||
|
ELSE app.activityUnionId END representedActivityUnionId
|
||||||
|
FROM activity_school_apply app
|
||||||
|
LEFT JOIN activity_school school ON school.id = app.activityId
|
||||||
|
LEFT JOIN activity_school_team team ON team.id = app.teamId
|
||||||
|
LEFT JOIN activity_event ev ON ev.id = app.eventId
|
||||||
|
LEFT JOIN sys_unit unit ON unit.id = app.unitId
|
||||||
|
LEFT JOIN activity_basic_unit basicUnit ON basicUnit.id = app.unitId
|
||||||
|
WHERE app.activityId = @activityId
|
||||||
|
ORDER BY ev.allName DESC, ev.projectType ASC, team.name ASC
|
||||||
|
""").setParam("activityId", activityId);
|
||||||
|
return listMap(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, List<NutMap>> groupRepresentedAppliesByUnion(String activityId) {
|
||||||
|
return listRepresentedApplies(activityId).stream()
|
||||||
|
.filter(row -> Strings.isNotBlank(row.getString("representedUnionId")))
|
||||||
|
.collect(Collectors.groupingBy(row -> row.getString("representedUnionId")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
public Sys_user createExternalUser(String username, String loginname, String sex, String idcard, String mobile, String unitId) {
|
||||||
|
String name = Strings.sNull(username).trim();
|
||||||
|
String account = Strings.sNull(loginname).trim();
|
||||||
|
String card = Strings.sNull(idcard).trim().toUpperCase();
|
||||||
|
String phone = Strings.sNull(mobile).trim();
|
||||||
|
if (name.isEmpty() || name.length() > 50 || !("男".equals(sex) || "女".equals(sex))
|
||||||
|
|| !phone.matches("^1[3456789]\\d{9}$")) {
|
||||||
|
throw new IllegalArgumentException("请填写外援姓名、性别及正确的手机号码");
|
||||||
|
}
|
||||||
|
if (account.length() > 50) {
|
||||||
|
throw new IllegalArgumentException("工号不能超过50位");
|
||||||
|
}
|
||||||
|
if (!card.matches("^[0-9]{17}[0-9X]$") || !IdcardUtil.isValidCard(card)) {
|
||||||
|
throw new IllegalArgumentException("请填写正确的18位身份证号");
|
||||||
|
}
|
||||||
|
String birthday = card.substring(6, 10) + "-" + card.substring(10, 12) + "-" + card.substring(12, 14);
|
||||||
|
try {
|
||||||
|
LocalDate.parse(birthday);
|
||||||
|
} catch (DateTimeParseException | NullPointerException e) {
|
||||||
|
throw new IllegalArgumentException("身份证号中的出生日期不正确");
|
||||||
|
}
|
||||||
|
ActivityBasicUnit unit = dao().fetch(ActivityBasicUnit.class, unitId);
|
||||||
|
if (unit == null || Strings.isBlank(unit.getUnionid())) {
|
||||||
|
throw new IllegalArgumentException("当前报名单位未配置活动工会");
|
||||||
|
}
|
||||||
|
// 自动工号与手填工号都在同一锁内查重,避免并发创建出相同账号。
|
||||||
|
synchronized (EXTERNAL_NUMBER_LOCK) {
|
||||||
|
if (account.isEmpty()) account = previewExternalLoginname();
|
||||||
|
if (dao().count(Sys_user.class, Cnd.where("loginname", "=", account)) > 0) {
|
||||||
|
throw new IllegalArgumentException("工号已存在,请更换工号");
|
||||||
|
}
|
||||||
|
if (dao().count(Sys_user.class, Cnd.where("idcard", "=", card)) > 0) {
|
||||||
|
throw new IllegalArgumentException("身份证号已存在,请搜索并选择系统人员");
|
||||||
|
}
|
||||||
|
Sys_user user = new Sys_user();
|
||||||
|
user.setId(R.UU32());
|
||||||
|
user.setLoginname(account);
|
||||||
|
user.setUsername(name);
|
||||||
|
user.setSex(sex);
|
||||||
|
user.setBirthday(birthday);
|
||||||
|
user.setIdcard(card);
|
||||||
|
user.setMobile(phone);
|
||||||
|
user.setUnitid(unitId);
|
||||||
|
user.setUnionid(unit.getUnionid());
|
||||||
|
user.setDisabled(true);
|
||||||
|
dao().insert(user);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public void doApplies(List<ActivitySchoolApply> applies) {
|
public void doApplies(List<ActivitySchoolApply> applies) {
|
||||||
@@ -32,6 +182,55 @@ public class ActivitySchoolApplyServiceImpl extends ViServiceImpl<ActivitySchool
|
|||||||
@Override
|
@Override
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public void doApplies(String activity, String union_id, String eventId,List<ActivitySchoolApply> applies) {
|
public void doApplies(String activity, String union_id, String eventId,List<ActivitySchoolApply> applies) {
|
||||||
|
for (ActivitySchoolApply apply : applies) {
|
||||||
|
Sys_user user = Strings.isBlank(apply.getUserId()) ? null : dao().fetch(Sys_user.class, apply.getUserId());
|
||||||
|
if (Strings.isNotBlank(apply.getIdCard())) {
|
||||||
|
String card = apply.getIdCard().trim().toUpperCase();
|
||||||
|
if (!IdcardUtil.isValidCard(card)) {
|
||||||
|
throw new IllegalArgumentException("报名人员身份证号不正确");
|
||||||
|
}
|
||||||
|
apply.setIdCard(card);
|
||||||
|
}
|
||||||
|
if (user != null && user.isDisabled() && Strings.isNotBlank(user.getLoginname())
|
||||||
|
&& user.getLoginname().matches("wy[0-9]{6,}")) {
|
||||||
|
// 工号和姓名保持系统身份;身份证、出生日期和电话保留本次报名的纠错值。
|
||||||
|
apply.setLoginname(user.getLoginname());
|
||||||
|
apply.setUsername(user.getUsername());
|
||||||
|
if (Strings.isNotBlank(user.getSex())) apply.setSex(user.getSex());
|
||||||
|
if (Strings.isBlank(apply.getIdCard())) apply.setIdCard(user.getIdcard());
|
||||||
|
if (Strings.isBlank(apply.getBirthday())) apply.setBirthday(user.getBirthday());
|
||||||
|
if (Strings.isBlank(apply.getMobile())) apply.setMobile(user.getMobile());
|
||||||
|
if (Strings.isBlank(apply.getUnitId())) {
|
||||||
|
apply.setUnitId(user.getUnitid());
|
||||||
|
}
|
||||||
|
if (Strings.isBlank(apply.getUnitname())) {
|
||||||
|
throw new IllegalArgumentException("请填写外援报名单位");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Strings.isNotBlank(apply.getUnitId()) && Strings.isNotBlank(apply.getUnitname())) {
|
||||||
|
Sys_unit selectedUnit = dao().fetch(Sys_unit.class, apply.getUnitId());
|
||||||
|
// 单位来自系统下拉时,所属工会就是本次代表出战的工会;手填单位保留报名人工会。
|
||||||
|
if (selectedUnit != null && apply.getUnitname().trim().equals(selectedUnit.getName())) {
|
||||||
|
ActivityBasicUnit activityUnit = dao().fetch(ActivityBasicUnit.class, apply.getUnitId());
|
||||||
|
if (Strings.isBlank(selectedUnit.getUnionid()) || activityUnit == null
|
||||||
|
|| Strings.isBlank(activityUnit.getUnionid())) {
|
||||||
|
throw new IllegalArgumentException("所选单位未配置活动工会,不能确定代表出战的工会");
|
||||||
|
}
|
||||||
|
ActivityBasicUnion activityUnion = dao().fetch(ActivityBasicUnion.class, activityUnit.getUnionid());
|
||||||
|
if (activityUnion == null) {
|
||||||
|
throw new IllegalArgumentException("所选单位对应的活动工会不存在");
|
||||||
|
}
|
||||||
|
apply.setUnionId(selectedUnit.getUnionid());
|
||||||
|
apply.setActivityUnionId(activityUnion.getId());
|
||||||
|
apply.setActivityUnionName(activityUnion.getUnionname());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 重存时清理本操作人以前代表其他工会报名的记录,避免换单位后留下重复报名。
|
||||||
|
if (!applies.isEmpty()) {
|
||||||
|
clear(Cnd.where("activityId", "=", activity).and("eventId", "=", eventId)
|
||||||
|
.and("applyUser", "=", applies.get(0).getApplyUser()).and("activityUnionId", "!=", union_id));
|
||||||
|
}
|
||||||
clear(Cnd.where("activityId", "=", activity).and("activityUnionId", "=", union_id).and("eventId","=",eventId));
|
clear(Cnd.where("activityId", "=", activity).and("activityUnionId", "=", union_id).and("eventId","=",eventId));
|
||||||
doApplies(applies);
|
doApplies(applies);
|
||||||
}
|
}
|
||||||
@@ -41,4 +240,159 @@ public class ActivitySchoolApplyServiceImpl extends ViServiceImpl<ActivitySchool
|
|||||||
public void doApply(ActivitySchoolApply apply) {
|
public void doApply(ActivitySchoolApply apply) {
|
||||||
insert(apply);
|
insert(apply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
public void saveUnionRoles(String activityId, String unionId, String operatorId, ActivitySchoolApply staffData,
|
||||||
|
ActivitySchoolApply leaderData, ActivitySchoolApply coachData, ActivitySchoolApply headData) {
|
||||||
|
saveUnionRole(activityId, unionId, operatorId, staffData, "unionStaff");
|
||||||
|
saveUnionRole(activityId, unionId, operatorId, leaderData, "unionLeader");
|
||||||
|
saveUnionRole(activityId, unionId, operatorId, coachData, "unionCoach");
|
||||||
|
saveUnionRole(activityId, unionId, operatorId, headData, "unionHead");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 仅替换活动级身份。先清除旧记录,使空 userId 能表示取消,同时不碰项目队伍身份。
|
||||||
|
*/
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
private void saveUnionRole(String activityId, String unionId, String operatorId, ActivitySchoolApply role, String roleColumn) {
|
||||||
|
clear(Cnd.where("activityId", "=", activityId).and("unionId", "=", unionId)
|
||||||
|
.and("eventId", "IS", null).and(roleColumn, "=", true));
|
||||||
|
if (role == null || Strings.isBlank(role.getUserId())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Sys_user user = dao().fetch(Sys_user.class, role.getUserId());
|
||||||
|
ActivityBasicUnit unit = dao().fetch(ActivityBasicUnit.class, role.getUnitId());
|
||||||
|
if (user == null || unit == null || Strings.isBlank(unit.getUnionid())) {
|
||||||
|
throw new IllegalArgumentException("所选人员或单位不存在,请重新选择");
|
||||||
|
}
|
||||||
|
ActivityBasicUnion union = dao().fetch(ActivityBasicUnion.class, unit.getUnionid());
|
||||||
|
if (union == null) {
|
||||||
|
throw new IllegalArgumentException("所选人员的活动工会不存在");
|
||||||
|
}
|
||||||
|
role.setActivityId(activityId);
|
||||||
|
role.setEventId(null);
|
||||||
|
role.setTeamId(null);
|
||||||
|
role.setUnionId(unionId);
|
||||||
|
role.setApplyUser(operatorId);
|
||||||
|
role.setApplyDate(DateUtil.getDate());
|
||||||
|
role.setUnitname(unit.getName());
|
||||||
|
role.setActivityUnionId(union.getId());
|
||||||
|
role.setActivityUnionName(union.getUnionname());
|
||||||
|
role.setUsername(user.getUsername());
|
||||||
|
role.setLoginname(user.getLoginname());
|
||||||
|
if ("unionStaff".equals(roleColumn)) role.setUnionStaff(true);
|
||||||
|
if ("unionLeader".equals(roleColumn)) role.setUnionLeader(true);
|
||||||
|
if ("unionCoach".equals(roleColumn)) role.setUnionCoach(true);
|
||||||
|
if ("unionHead".equals(roleColumn)) role.setUnionHead(true);
|
||||||
|
insert(role);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getUnionRoleInfo(String activityId, String unionId) {
|
||||||
|
Sql sql = Sqls.create("SELECT apply.*,us.unitname FROM activity_school_apply apply "
|
||||||
|
+ "LEFT JOIN `user` us ON us.id=apply.userId "
|
||||||
|
+ "WHERE apply.activityId=@activityId AND apply.unionId=@unionId AND apply.eventId IS NULL");
|
||||||
|
sql.setParam("activityId", activityId);
|
||||||
|
sql.setParam("unionId", unionId);
|
||||||
|
List<NutMap> rows = listMap(sql);
|
||||||
|
NutMap coach = rows.stream().filter(row -> Boolean.TRUE.equals(row.getBoolean("unionCoach"))).findFirst().orElse(null);
|
||||||
|
NutMap leader = rows.stream().filter(row -> Boolean.TRUE.equals(row.getBoolean("unionLeader"))).findFirst().orElse(null);
|
||||||
|
NutMap head = rows.stream().filter(row -> Boolean.TRUE.equals(row.getBoolean("unionHead"))).findFirst().orElse(null);
|
||||||
|
NutMap staff = rows.stream().filter(row -> Boolean.TRUE.equals(row.getBoolean("unionStaff"))).findFirst().orElse(null);
|
||||||
|
Map<String, Object> result = new LinkedHashMap<>();
|
||||||
|
result.put("unionCoach", coach);
|
||||||
|
result.put("unionLeader", leader);
|
||||||
|
result.put("unionHead", head);
|
||||||
|
result.put("unionStaff", staff);
|
||||||
|
|
||||||
|
Map<String, Sys_user> options = new LinkedHashMap<>();
|
||||||
|
// 历史记录的 userId 可能为空;工号只在唯一匹配时用于回显,不在查询时改写数据库。
|
||||||
|
for (NutMap role : Arrays.asList(coach, leader, head, staff)) {
|
||||||
|
if (role == null) continue;
|
||||||
|
Sys_user user = Strings.isBlank(role.getString("userId")) ? null : dao().fetch(Sys_user.class, role.getString("userId"));
|
||||||
|
if (user == null && Strings.isNotBlank(role.getString("loginname"))) {
|
||||||
|
List<Sys_user> matches = dao().query(Sys_user.class, Cnd.where("loginname", "=", role.getString("loginname")));
|
||||||
|
if (matches.size() == 1) user = matches.get(0);
|
||||||
|
}
|
||||||
|
if (user != null) {
|
||||||
|
role.put("userId", user.getId());
|
||||||
|
options.put(user.getId(), user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("userOptions", new ArrayList<>(options.values()));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<NutMap> mergeExportIdentities(List<NutMap> rows) {
|
||||||
|
Map<String, Set<String>> accountUsers = new LinkedHashMap<>();
|
||||||
|
for (NutMap row : rows) {
|
||||||
|
if (Strings.isNotBlank(row.getString("loginname")) && Strings.isNotBlank(row.getString("userId"))) {
|
||||||
|
accountUsers.computeIfAbsent(exportAccountKey(row), key -> new LinkedHashSet<>()).add(row.getString("userId"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Map<String, Set<String>> activityRoles = new LinkedHashMap<>();
|
||||||
|
Map<String, Set<String>> projectRoles = new LinkedHashMap<>();
|
||||||
|
Map<String, NutMap> projectRows = new LinkedHashMap<>();
|
||||||
|
Set<String> peopleWithProjects = new LinkedHashSet<>();
|
||||||
|
for (NutMap row : rows) {
|
||||||
|
String person = exportPersonKey(row, accountUsers);
|
||||||
|
List<String> identity = Lang.map2Object(row, ActivitySchoolApply.class).getIdentity();
|
||||||
|
String project = exportProjectKey(row, person);
|
||||||
|
if (project == null) {
|
||||||
|
activityRoles.computeIfAbsent(person, key -> new LinkedHashSet<>()).addAll(identity == null ? List.of() : identity);
|
||||||
|
} else {
|
||||||
|
peopleWithProjects.add(person);
|
||||||
|
projectRows.putIfAbsent(project, row);
|
||||||
|
projectRoles.computeIfAbsent(project, key -> new LinkedHashSet<>()).addAll(identity == null ? List.of() : identity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<NutMap> result = new ArrayList<>();
|
||||||
|
Set<String> emitted = new LinkedHashSet<>();
|
||||||
|
for (NutMap row : rows) {
|
||||||
|
String person = exportPersonKey(row, accountUsers);
|
||||||
|
String project = exportProjectKey(row, person);
|
||||||
|
if (project == null && peopleWithProjects.contains(person)) continue;
|
||||||
|
String outputKey = project == null ? "activity:" + person : "project:" + project;
|
||||||
|
if (!emitted.add(outputKey)) continue;
|
||||||
|
NutMap source = project == null ? row : projectRows.get(project);
|
||||||
|
NutMap merged = new NutMap();
|
||||||
|
merged.putAll(source);
|
||||||
|
Set<String> identities = new LinkedHashSet<>();
|
||||||
|
if (project != null) identities.addAll(projectRoles.get(project));
|
||||||
|
identities.addAll(activityRoles.getOrDefault(person, Set.of()));
|
||||||
|
merged.put("identity", new ArrayList<>(identities));
|
||||||
|
result.add(merged);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 工号和姓名用于关联历史空 userId 记录;发现多个账号共用该组合时,保留各自记录。 */
|
||||||
|
private String exportPersonKey(NutMap row, Map<String, Set<String>> accountUsers) {
|
||||||
|
String union = Strings.sNull(row.getString("unionId"));
|
||||||
|
String loginname = row.getString("loginname");
|
||||||
|
String userId = row.getString("userId");
|
||||||
|
if (Strings.isNotBlank(loginname)) {
|
||||||
|
String account = exportAccountKey(row);
|
||||||
|
if (accountUsers.getOrDefault(account, Set.of()).size() > 1) {
|
||||||
|
return Strings.isNotBlank(userId) ? union + ":user:" + userId : union + ":row:" + row.getString("id");
|
||||||
|
}
|
||||||
|
return account;
|
||||||
|
}
|
||||||
|
if (Strings.isNotBlank(userId)) return union + ":user:" + userId;
|
||||||
|
return union + ":row:" + row.getString("id");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String exportAccountKey(NutMap row) {
|
||||||
|
return Strings.sNull(row.getString("unionId")) + ":login:" + row.getString("loginname")
|
||||||
|
+ ":name:" + Strings.sNull(row.getString("username"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 同一项目中不同队伍仍是不同报名行;活动级身份没有项目和队伍。 */
|
||||||
|
private String exportProjectKey(NutMap row, String person) {
|
||||||
|
if (Strings.isBlank(row.getString("eventId"))) return null;
|
||||||
|
return person + ":event:" + row.getString("eventId") + ":team:" + Strings.sNull(row.getString("teamId"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,18 @@ import io.v.nutz.activity.services.ActivitySchoolApplyService;
|
|||||||
import io.v.nutz.activity.services.ActivitySchoolService;
|
import io.v.nutz.activity.services.ActivitySchoolService;
|
||||||
import io.v.nutz.activity.services.ActivitySchoolTeamService;
|
import io.v.nutz.activity.services.ActivitySchoolTeamService;
|
||||||
import io.v.nutz.base.utils.DateUtil;
|
import io.v.nutz.base.utils.DateUtil;
|
||||||
|
import io.v.nutz.base.utils.Vi;
|
||||||
|
import io.v.nutz.activity.utils.ActivityRoleUtil;
|
||||||
|
import io.v.nutz.util.ShiroUtil;
|
||||||
import io.v.nutz.service.ViService;
|
import io.v.nutz.service.ViService;
|
||||||
import io.v.nutz.service.impl.ViServiceImpl;
|
import io.v.nutz.service.impl.ViServiceImpl;
|
||||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
import org.nutz.dao.Cnd;
|
import org.nutz.dao.Cnd;
|
||||||
|
import org.nutz.dao.Chain;
|
||||||
import org.nutz.dao.Dao;
|
import org.nutz.dao.Dao;
|
||||||
|
import org.nutz.dao.Sqls;
|
||||||
|
import org.nutz.lang.Strings;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
import org.nutz.ioc.aop.Aop;
|
import org.nutz.ioc.aop.Aop;
|
||||||
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;
|
||||||
@@ -46,12 +53,127 @@ public class ActivitySchoolServiceImpl extends ViServiceImpl<ActivitySchool> imp
|
|||||||
@Inject("ActivitySchoolEvent")
|
@Inject("ActivitySchoolEvent")
|
||||||
private ViService<ActivitySchoolEvent> activitySchoolEventViService;
|
private ViService<ActivitySchoolEvent> activitySchoolEventViService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Vi vi;
|
||||||
|
|
||||||
|
/** 沿用列表和详情共用现有活动管理的数据范围,防止通过历史活动ID跨范围读取。 */
|
||||||
|
private Cnd reuseActivityCnd() {
|
||||||
|
Cnd cnd = Cnd.NEW();
|
||||||
|
if (!ShiroUtil.hasAnyRoles("sysadmin,A06")) {
|
||||||
|
if (ActivityRoleUtil.isUnionManager()) {
|
||||||
|
cnd.and("belongUnionId", "in", ActivityRoleUtil.getManageUnionStr(ShiroUtil.getUserId()));
|
||||||
|
}
|
||||||
|
if (ShiroUtil.hasRole("H02")) {
|
||||||
|
cnd.and("belongClubId", "in", vi.getMangeClubStr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 返回当前用户管理范围内的历史活动ID和名称,按创建时间倒序排列。 */
|
||||||
|
@Override
|
||||||
|
public List<NutMap> getReuseActivityOptions() {
|
||||||
|
return listMap(Sqls.create("SELECT id, name FROM activity_school $condition")
|
||||||
|
.setCondition(reuseActivityCnd().desc("foundDate")));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** id 为历史活动ID;详情包含原活动字段和 schoolEvents 数组,供前端复制业务配置。 */
|
||||||
|
@Override
|
||||||
|
public NutMap findReuseActivity(String id) {
|
||||||
|
if (Strings.isBlank(id) || fetch(reuseActivityCnd().and("id", "=", id)) == null) {
|
||||||
|
throw new IllegalArgumentException("沿用活动不存在或无权访问");
|
||||||
|
}
|
||||||
|
NutMap result = fetch(Sqls.create("SELECT * FROM activity_school WHERE id = @id").setParam("id", id));
|
||||||
|
result.setv("schoolEvents", listMap(Sqls.create("SELECT ase.*, ae.projectType FROM activity_school_event ase "
|
||||||
|
+ "LEFT JOIN activity_event ae ON ae.id = ase.eventId WHERE ase.activityId = @id").setParam("id", id)));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sourceId 为来源活动ID;只复制表单及项目配置,重新生成活动、配置、小队和组织记录。
|
||||||
|
* 返回新活动ID,所有写入使用同一事务,任何失败均回滚,不修改来源活动及报名记录。
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
public String doReuseAdd(String sourceId, ActivitySchool school, ActivitySchoolEvent[] events) {
|
||||||
|
findReuseActivity(sourceId);
|
||||||
|
if (school.getEventsIds() == null) {
|
||||||
|
school.setEventsIds(new java.util.ArrayList<>());
|
||||||
|
}
|
||||||
|
boolean isDraft = Integer.valueOf(1).equals(school.getIsSave());
|
||||||
|
if (!isDraft && school.getEventsIds().isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("请选择活动项目");
|
||||||
|
}
|
||||||
|
ActivitySchoolEvent[] cleanEvents = Arrays.stream(events == null ? new ActivitySchoolEvent[0] : events)
|
||||||
|
.filter(event -> event != null && school.getEventsIds().contains(event.getEventId())
|
||||||
|
&& !"allItems".equals(event.getEventId()))
|
||||||
|
.peek(event -> {
|
||||||
|
// 配置主键和所属活动必须重新生成,不能信任前端传入的旧记录标识。
|
||||||
|
event.setId(null);
|
||||||
|
event.setActivityId(null);
|
||||||
|
}).toArray(ActivitySchoolEvent[]::new);
|
||||||
|
// 草稿允许暂不选择或配置项目;正式提交仍需验证项目可用且配置齐全。
|
||||||
|
if (!isDraft) {
|
||||||
|
for (String eventId : school.getEventsIds()) {
|
||||||
|
ActivityEvent event = dao().fetch(ActivityEvent.class, Cnd.where("id", "=", eventId).and("whetherEnable", "=", 1));
|
||||||
|
if (event == null) {
|
||||||
|
throw new IllegalArgumentException("所选项目已停用或不存在,请重新选择");
|
||||||
|
}
|
||||||
|
if (Arrays.stream(cleanEvents).noneMatch(config -> eventId.equals(config.getEventId()))) {
|
||||||
|
throw new IllegalArgumentException("项目配置不完整,请进入下一步完善项目信息");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
school.setId(null);
|
||||||
|
school.setClose(false);
|
||||||
|
school.setFoundDate(DateUtil.getDate());
|
||||||
|
if (Integer.valueOf(40002).equals(school.getActivityLevel())) {
|
||||||
|
school.setBelongUnionId(ActivityRoleUtil.getCurrentUnionId(dao()));
|
||||||
|
} else {
|
||||||
|
school.setBelongUnionId(null);
|
||||||
|
}
|
||||||
|
if (school.getUndertakeUnit() == null) {
|
||||||
|
school.setUndertakeUnit(new java.util.ArrayList<>());
|
||||||
|
}
|
||||||
|
insert(school);
|
||||||
|
addTeam(school.getId(), cleanEvents);
|
||||||
|
// 与普通创建保持一致,创建可报名工会和活动组织记录,保留后续报名入口所需关联。
|
||||||
|
for (ActivityBasicUnion unit : dao().query(ActivityBasicUnion.class, Cnd.where("isEnable", "=", true))) {
|
||||||
|
ActivityUnion union = new ActivityUnion();
|
||||||
|
union.setActivityId(school.getId());
|
||||||
|
union.setUnionname(unit.getUnionname());
|
||||||
|
dao().insert(union);
|
||||||
|
}
|
||||||
|
ActivityTissue tissue = new ActivityTissue();
|
||||||
|
tissue.setApplyTime(school.getFoundDate());
|
||||||
|
tissue.setType(school.getActivityLevel());
|
||||||
|
tissue.setProjectTypeCode("50004");
|
||||||
|
tissue.setActivityCode(school.getActivityCode());
|
||||||
|
tissue.setName(school.getName());
|
||||||
|
tissue.setUserId(ShiroUtil.getUserId());
|
||||||
|
tissue.setState(3);
|
||||||
|
tissue.setClubId(school.getBelongClubId());
|
||||||
|
tissue.setUnionId(school.getBelongUnionId());
|
||||||
|
tissue.setAddress(school.getAddress());
|
||||||
|
tissue.setApplyStartTime(school.getApplyStartTime());
|
||||||
|
tissue.setApplyEndTime(school.getApplyEndTime());
|
||||||
|
tissue.setStartTime(school.getStartTime());
|
||||||
|
tissue.setEndTime(school.getEndTime());
|
||||||
|
if (school.getImage() != null && !school.getImage().isEmpty()) {
|
||||||
|
tissue.setCover(school.getImage().get(0).getId());
|
||||||
|
}
|
||||||
|
dao().insert(tissue);
|
||||||
|
// 与原创建入口一致,在插入后统一组织ID,避免实体 @Prev 的主键生成策略影响关联。
|
||||||
|
dao().update(ActivityTissue.class, Chain.make("id", school.getId()), Cnd.where("id", "=", tissue.getId()));
|
||||||
|
return school.getId();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public String doAdd(ActivitySchool activitySchool, ActivitySchoolEvent[] events) {
|
public String doAdd(ActivitySchool activitySchool, ActivitySchoolEvent[] events) {
|
||||||
activitySchool.setClose(false);
|
activitySchool.setClose(false);
|
||||||
ActivitySchool school = insert(activitySchool);
|
ActivitySchool school = insert(activitySchool);
|
||||||
addTeam(school.getId(), events);
|
addTeam(school.getId(), events == null ? new ActivitySchoolEvent[0] : events);
|
||||||
return school.getId();
|
return school.getId();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -59,7 +181,12 @@ public class ActivitySchoolServiceImpl extends ViServiceImpl<ActivitySchool> imp
|
|||||||
@Override
|
@Override
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public void doEdit(ActivitySchool activitySchool, ActivitySchoolEvent[] events, String applyEndTime) {
|
public void doEdit(ActivitySchool activitySchool, ActivitySchoolEvent[] events, String applyEndTime) {
|
||||||
long time = DateUtil.formatDate(applyEndTime);
|
// 未填写报名结束时间的草稿也可再次保存;没有项目时按空配置处理。
|
||||||
|
long time = Strings.isBlank(applyEndTime) ? 0 : DateUtil.formatDate(applyEndTime);
|
||||||
|
if (activitySchool.getEventsIds() == null) {
|
||||||
|
activitySchool.setEventsIds(new java.util.ArrayList<>());
|
||||||
|
}
|
||||||
|
ActivitySchoolEvent[] safeEvents = events == null ? new ActivitySchoolEvent[0] : events;
|
||||||
long l = System.currentTimeMillis();
|
long l = System.currentTimeMillis();
|
||||||
|
|
||||||
if (l < time) {
|
if (l < time) {
|
||||||
@@ -76,7 +203,7 @@ public class ActivitySchoolServiceImpl extends ViServiceImpl<ActivitySchool> imp
|
|||||||
return !activitySchool.getEventsIds().contains(v.getEventId());
|
return !activitySchool.getEventsIds().contains(v.getEventId());
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
List<ActivitySchoolEvent> collect1 = Lang.array2list(events).stream().filter(v -> {
|
List<ActivitySchoolEvent> collect1 = Lang.array2list(safeEvents).stream().filter(v -> {
|
||||||
return !query.stream().map(x -> x.getEventId()).collect(Collectors.toList()).contains(v.getEventId()) && (v.getId() == null || !v.getId().equals("allItems"));
|
return !query.stream().map(x -> x.getEventId()).collect(Collectors.toList()).contains(v.getEventId()) && (v.getId() == null || !v.getId().equals("allItems"));
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
@@ -91,7 +218,7 @@ public class ActivitySchoolServiceImpl extends ViServiceImpl<ActivitySchool> imp
|
|||||||
if (collect1.size() > 0) {
|
if (collect1.size() > 0) {
|
||||||
addTeam(activitySchool.getId(), collect1.toArray(new ActivitySchoolEvent[collect1.size()]));
|
addTeam(activitySchool.getId(), collect1.toArray(new ActivitySchoolEvent[collect1.size()]));
|
||||||
}
|
}
|
||||||
for (ActivitySchoolEvent event : events) {
|
for (ActivitySchoolEvent event : safeEvents) {
|
||||||
update(event);
|
update(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,11 @@ public interface Roles {
|
|||||||
*/
|
*/
|
||||||
String UNION_MANGER = "5d342e614e9a48288d50154bcdcc75d3";
|
String UNION_MANGER = "5d342e614e9a48288d50154bcdcc75d3";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 三级单位管理员
|
||||||
|
*/
|
||||||
|
String THIRD_UNIT_MANGER = "e8d957d1ab9f4e56a60b5a53929d18bb";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 体育活动联合工会管理员
|
* 体育活动联合工会管理员
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import org.nutz.dao.Dao;
|
|||||||
import org.nutz.dao.Sqls;
|
import org.nutz.dao.Sqls;
|
||||||
import org.nutz.dao.entity.Record;
|
import org.nutz.dao.entity.Record;
|
||||||
import org.nutz.dao.sql.Sql;
|
import org.nutz.dao.sql.Sql;
|
||||||
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
|
import org.nutz.ioc.aop.Aop;
|
||||||
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.lang.util.NutMap;
|
import org.nutz.lang.util.NutMap;
|
||||||
@@ -67,16 +69,17 @@ public class ClothingRecordController {
|
|||||||
|
|
||||||
@At
|
@At
|
||||||
@RequiresAuthentication
|
@RequiresAuthentication
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public Object doDelete(String projectId, String year, String userId) {
|
public Object doDelete(String projectId, String year, String userId) {
|
||||||
|
|
||||||
if(StrUtil.isBlank(projectId)) {
|
if(StrUtil.isBlank(projectId)) {
|
||||||
Result.error("项目不能为空!");
|
return Result.error("项目不能为空!");
|
||||||
}
|
}
|
||||||
if(StrUtil.isBlank(year)) {
|
if(StrUtil.isBlank(year)) {
|
||||||
Result.error("年份不能为空!");
|
return Result.error("年份不能为空!");
|
||||||
}
|
}
|
||||||
if(StrUtil.isBlank(userId)) {
|
if(StrUtil.isBlank(userId)) {
|
||||||
Result.error("登记人不能为空!");
|
return Result.error("登记人不能为空!");
|
||||||
}
|
}
|
||||||
boolean b = clothingRegisterService.doDelete(projectId, year, userId);
|
boolean b = clothingRegisterService.doDelete(projectId, year, userId);
|
||||||
return b ? Result.success(): Result.error();
|
return b ? Result.success(): Result.error();
|
||||||
@@ -104,6 +107,10 @@ public class ClothingRecordController {
|
|||||||
return b ? Result.success(): Result.error();
|
return b ? Result.success(): Result.error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* year 为活动报名年度,projectId 为活动ID,userId 为登记人ID;旧项目记录按登记年度筛选。
|
||||||
|
* request 和 response 为当前 HTTP 请求及下载响应;返回值为 void,内容写入响应流。
|
||||||
|
*/
|
||||||
@At
|
@At
|
||||||
@Ok("void")
|
@Ok("void")
|
||||||
public void doExport(String year, String projectId, String userId, HttpServletRequest request, HttpServletResponse response) throws IOException {
|
public void doExport(String year, String projectId, String userId, HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||||
@@ -135,11 +142,13 @@ public class ClothingRecordController {
|
|||||||
FROM
|
FROM
|
||||||
clothing_register c
|
clothing_register c
|
||||||
LEFT JOIN `user` u ON u.id = c.buyUserId
|
LEFT JOIN `user` u ON u.id = c.buyUserId
|
||||||
|
LEFT JOIN activity_school s ON s.id = c.projectId
|
||||||
$condition
|
$condition
|
||||||
""");
|
""");
|
||||||
cnd.and("year(ctime)", "=", year);
|
// 导出与台账采用同一业务年度,旧项目记录回退到登记年度。
|
||||||
cnd.and("projectId", "=", projectId);
|
cnd.and("COALESCE(YEAR(s.applyStartTime), YEAR(c.ctime))", "=", year);
|
||||||
cnd.and("userId", "=", userId);
|
cnd.and("c.projectId", "=", projectId);
|
||||||
|
cnd.and("c.userId", "=", userId);
|
||||||
sql.setCondition(cnd);
|
sql.setCondition(cnd);
|
||||||
List<Record> buyUserList = clothingRegisterService.list(sql);
|
List<Record> buyUserList = clothingRegisterService.list(sql);
|
||||||
for (int i = 0; i < buyUserList.size(); i++) {
|
for (int i = 0; i < buyUserList.size(); i++) {
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
|
|||||||
import org.nutz.dao.Cnd;
|
import org.nutz.dao.Cnd;
|
||||||
import org.nutz.dao.Sqls;
|
import org.nutz.dao.Sqls;
|
||||||
import org.nutz.dao.entity.Record;
|
import org.nutz.dao.entity.Record;
|
||||||
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
|
import org.nutz.ioc.aop.Aop;
|
||||||
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.mvc.annotation.At;
|
import org.nutz.mvc.annotation.At;
|
||||||
@@ -41,30 +43,43 @@ public class ClothingRegisterController {
|
|||||||
@RequiresPermissions("clothing.register")
|
@RequiresPermissions("clothing.register")
|
||||||
public void index() {}
|
public void index() {}
|
||||||
|
|
||||||
|
/** pageForm 为分页和姓名工号条件;projectId 为活动ID;isBuy 为购买状态;sex、unionId 为可选筛选,返回人员分页数据。 */
|
||||||
@At
|
@At
|
||||||
@ViReturn
|
@ViReturn
|
||||||
public Object pageData(PageForm pageForm, Integer year, String projectId, Boolean isBuy, String sex, String unionId) {
|
public Object pageData(PageForm pageForm, String projectId, Boolean isBuy, String sex, String unionId) {
|
||||||
|
|
||||||
return clothingRegisterService.getRegisterUser(pageForm, year, projectId, isBuy, sex, unionId);
|
return clothingRegisterService.getRegisterUser(pageForm, projectId, isBuy, sex, unionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ids 为所选人员ID;projectId 为活动ID,购买限制以该活动的报名年度和已选项目为准;
|
||||||
|
* isBuy 为购买状态,true 时仅移除当前活动记录,false 时登记;
|
||||||
|
* 成功返回 null 由 ViReturn 包装,业务校验失败返回含错误说明的 Result。
|
||||||
|
*/
|
||||||
@At
|
@At
|
||||||
@ViReturn
|
@ViReturn
|
||||||
public Object doHandler(String[] ids, String projectId, Integer year, Boolean isBuy) {
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
public Object doHandler(String[] ids, String projectId, Boolean isBuy) {
|
||||||
|
|
||||||
if(!isBuy) {
|
try {
|
||||||
|
if(!Boolean.TRUE.equals(isBuy)) {
|
||||||
clothingRegisterService.add(ids, projectId);
|
clothingRegisterService.add(ids, projectId);
|
||||||
} else {
|
} else {
|
||||||
clothingRegisterService.removeBuyUser(ids, projectId, year);
|
clothingRegisterService.removeBuyUser(ids, projectId);
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException exception) {
|
||||||
|
// 重复购衣等业务校验错误直接返回给页面,供提交按钮显示明确原因。
|
||||||
|
return Result.error(exception.getMessage());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** year 为空时返回全部已提交活动,否则按报名开始时间所属年度筛选;data 数组的每项包含活动 id 和 name。 */
|
||||||
@At
|
@At
|
||||||
@ViReturn
|
@ViReturn
|
||||||
public Object getBuyClothesProject() {
|
public Object getBuyClothesProject(Integer year) {
|
||||||
|
|
||||||
return clothingRegisterService.getBuyClothesProject();
|
return clothingRegisterService.getBuyClothesProject(year);
|
||||||
}
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package io.v.nutz.clothing.services;
|
package io.v.nutz.clothing.services;
|
||||||
|
|
||||||
import cn.wizzer.framework.page.Pagination;
|
import cn.wizzer.framework.page.Pagination;
|
||||||
import io.v.nutz.activity.models.ActivityBasicSettings;
|
|
||||||
import io.v.nutz.clothing.models.ClothingRegister;
|
import io.v.nutz.clothing.models.ClothingRegister;
|
||||||
import io.v.nutz.modules.models.PageForm;
|
import io.v.nutz.modules.models.PageForm;
|
||||||
import io.v.nutz.service.ViService;
|
import io.v.nutz.service.ViService;
|
||||||
@@ -20,29 +19,31 @@ public interface ClothingRegisterService extends ViService<ClothingRegister> {
|
|||||||
/**
|
/**
|
||||||
* 列表查询
|
* 列表查询
|
||||||
*
|
*
|
||||||
* @param pageForm: 表单
|
* @param pageForm: 分页及查询表单
|
||||||
* @param projectId: 项目id
|
* @param projectId: 活动ID,可为空
|
||||||
* @param year: 年份
|
* @param year: 活动报名年度;旧项目记录按登记年度筛选
|
||||||
* @return io.v.nutz.base.page.Pagination
|
* @param unionId: 工会ID,可为空
|
||||||
|
* @return Pagination,list 为按活动、登记人和年度分组的台账,totalCount 为分组总数
|
||||||
* @author JyuHsin
|
* @author JyuHsin
|
||||||
* @date 2022/12/5
|
* @date 2022/12/5
|
||||||
*/
|
*/
|
||||||
Pagination pageData(PageForm pageForm, String projectId, String year, String unionId);
|
Pagination pageData(PageForm pageForm, String projectId, String year, String unionId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有买服装的项目
|
* 获取已提交的校级活动,供服装登记、记录和台账选择项目。
|
||||||
* @author JyuHsin
|
* year 为空时返回全部年度,否则按活动报名开始时间所属年度筛选。
|
||||||
* @date 2022/12/5
|
* 返回的每项包含活动 id(作为 projectId 保存和筛选)及 name(下拉显示名称)。
|
||||||
* @return java.util.List<io.v.nutz.activity.models.ActivityBasicSettings>
|
|
||||||
*/
|
*/
|
||||||
List<ActivityBasicSettings> getBuyClothesProject();
|
List<NutMap> getBuyClothesProject(Integer year);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取项目人员名单
|
* 获取项目人员名单
|
||||||
* @author JyuHsin
|
* @author JyuHsin
|
||||||
* @date 2022/12/5
|
* @date 2022/12/5
|
||||||
* @param projectId: 项目id
|
* @param projectId: 活动ID
|
||||||
* @return java.util.List<org.nutz.lang.util.NutMap>
|
* @param userId: 登记人ID
|
||||||
|
* @param year: 活动报名年度,可为空;旧项目记录按登记年度筛选
|
||||||
|
* @return 人员列表,每项包含购买人资料及登记记录
|
||||||
*/
|
*/
|
||||||
List<NutMap> findBuyClothesUser(String projectId, String userId, String year);
|
List<NutMap> findBuyClothesUser(String projectId, String userId, String year);
|
||||||
|
|
||||||
@@ -50,28 +51,25 @@ public interface ClothingRegisterService extends ViService<ClothingRegister> {
|
|||||||
* 删除
|
* 删除
|
||||||
* @author JyuHsin
|
* @author JyuHsin
|
||||||
* @date 2022/12/5
|
* @date 2022/12/5
|
||||||
* @param projectId: 项目id
|
* @param projectId: 活动ID
|
||||||
* @param year: 年份
|
* @param year: 活动报名年度;旧项目记录按登记年度删除
|
||||||
* @param userId: 登记人
|
* @param userId: 登记人ID
|
||||||
* @return void
|
* @return 是否完成指定活动、年度和登记人的删除
|
||||||
*/
|
*/
|
||||||
boolean doDelete(String projectId, String year, String userId);
|
boolean doDelete(String projectId, String year, String userId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 服装登记菜单查询用户
|
* 查询服装登记人员。pageForm 包含页码、页大小和姓名或工号查询条件;projectId 为当前活动ID;
|
||||||
* @author JyuHsin
|
* isBuy 为购买状态,true 返回与活动年度相差不超过一年且同类项目已购买的人员,false 返回未购买人员;
|
||||||
* @date 2022/12/5
|
* sex 为可选性别,unionId 为可选工会ID。返回 Pagination,list 为人员及可移除状态,totalCount 为总人数。
|
||||||
* @param pageForm:
|
|
||||||
* @param year:
|
|
||||||
* @param projectId:
|
|
||||||
* @param isBuy:
|
|
||||||
* @return cn.wizzer.framework.page.Pagination
|
|
||||||
*/
|
*/
|
||||||
Pagination getRegisterUser(PageForm pageForm, Integer year, String projectId, Boolean isBuy, String sex, String unionId);
|
Pagination getRegisterUser(PageForm pageForm, String projectId, Boolean isBuy, String sex, String unionId);
|
||||||
|
|
||||||
|
/** ids 为本次登记的人员ID,projectId 为活动ID;两年内同类项目已有购买记录时拒绝提交。 */
|
||||||
Object add(String[] ids, String projectId);
|
Object add(String[] ids, String projectId);
|
||||||
|
|
||||||
boolean removeBuyUser(String[] ids, String projectId, Integer year);
|
/** ids 为人员ID,projectId 为当前活动ID;仅移除当前活动的登记记录,不删除其他同类活动的历史记录。 */
|
||||||
|
boolean removeBuyUser(String[] ids, String projectId);
|
||||||
|
|
||||||
boolean deleteBuyUser(String id);
|
boolean deleteBuyUser(String id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package io.v.nutz.clothing.services.impl;
|
|||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.wizzer.framework.page.Pagination;
|
import cn.wizzer.framework.page.Pagination;
|
||||||
import io.v.nutz.activity.models.ActivityBasicSettings;
|
import io.v.nutz.activity.models.ActivitySchool;
|
||||||
import io.v.nutz.base.utils.DateUtil;
|
import io.v.nutz.base.utils.DateUtil;
|
||||||
import io.v.nutz.base.utils.Vi;
|
import io.v.nutz.base.utils.Vi;
|
||||||
import io.v.nutz.clothing.models.ClothingRegister;
|
import io.v.nutz.clothing.models.ClothingRegister;
|
||||||
@@ -20,13 +20,18 @@ 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.dao.util.cri.Static;
|
import org.nutz.dao.util.cri.Static;
|
||||||
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
|
import org.nutz.ioc.aop.Aop;
|
||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
import org.nutz.lang.Strings;
|
import org.nutz.lang.Strings;
|
||||||
import org.nutz.lang.util.NutMap;
|
import org.nutz.lang.util.NutMap;
|
||||||
import org.nutz.trans.Trans;
|
import org.nutz.trans.Trans;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author JyuHsin
|
* @Author JyuHsin
|
||||||
@@ -48,14 +53,15 @@ public class ClothingRegisterServiceImpl extends ViServiceImpl<ClothingRegister>
|
|||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
SELECT
|
SELECT
|
||||||
c.*,
|
c.*,
|
||||||
YEAR ( c.ctime ) AS `year`,
|
COALESCE(YEAR(s.applyStartTime), YEAR(c.ctime)) AS `year`,
|
||||||
u.username,
|
u.username,
|
||||||
u.unionname,
|
u.unionname,
|
||||||
a.name AS projectName,
|
COALESCE(s.name, a.name) AS projectName,
|
||||||
count(c.buyUserId) AS buyCount
|
count(c.buyUserId) AS buyCount
|
||||||
FROM
|
FROM
|
||||||
clothing_register c
|
clothing_register c
|
||||||
LEFT JOIN `user` u ON u.id = c.userId
|
LEFT JOIN `user` u ON u.id = c.userId
|
||||||
|
LEFT JOIN activity_school s ON s.id = c.projectId
|
||||||
LEFT JOIN activity_basic_settings a ON a.CODE = c.projectId
|
LEFT JOIN activity_basic_settings a ON a.CODE = c.projectId
|
||||||
$condition
|
$condition
|
||||||
""");
|
""");
|
||||||
@@ -65,8 +71,9 @@ public class ClothingRegisterServiceImpl extends ViServiceImpl<ClothingRegister>
|
|||||||
}
|
}
|
||||||
cnd.andExcludeEmpty("u.unionId", "=", unionId);
|
cnd.andExcludeEmpty("u.unionId", "=", unionId);
|
||||||
cnd.andExcludeEmpty("c.projectId", "=", projectId);
|
cnd.andExcludeEmpty("c.projectId", "=", projectId);
|
||||||
cnd.andExcludeEmpty("year(c.ctime)", "=", year);
|
// 活动记录按报名年度归档;无法关联活动的旧记录仍按实际登记年度展示。
|
||||||
cnd.groupBy("c.userId");
|
cnd.andExcludeEmpty("COALESCE(YEAR(s.applyStartTime), YEAR(c.ctime))", "=", year);
|
||||||
|
cnd.groupBy("c.projectId", "c.userId", "COALESCE(YEAR(s.applyStartTime), YEAR(c.ctime))");
|
||||||
cnd.desc("year").asc("projectId");
|
cnd.desc("year").asc("projectId");
|
||||||
sql.setCondition(cnd);
|
sql.setCondition(cnd);
|
||||||
|
|
||||||
@@ -74,8 +81,17 @@ public class ClothingRegisterServiceImpl extends ViServiceImpl<ClothingRegister>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ActivityBasicSettings> getBuyClothesProject() {
|
public List<NutMap> getBuyClothesProject(Integer year) {
|
||||||
return dao().query(ActivityBasicSettings.class, Cnd.where("clothing", "is not", null));
|
// isSave=1 是草稿;历史已提交活动可能为 NULL,需与活动管理页的判定保持一致。
|
||||||
|
CndPlus cnd = CndPlus.create();
|
||||||
|
cnd.and(new Static("(isSave IS NULL OR isSave <> 1)"));
|
||||||
|
cnd.andExcludeEmpty("YEAR(applyStartTime)", "=", year);
|
||||||
|
cnd.desc("startTime").desc("foundDate");
|
||||||
|
return listMap(Sqls.create("""
|
||||||
|
SELECT id, name
|
||||||
|
FROM activity_school
|
||||||
|
$condition
|
||||||
|
""").setCondition(cnd));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -94,26 +110,38 @@ public class ClothingRegisterServiceImpl extends ViServiceImpl<ClothingRegister>
|
|||||||
FROM
|
FROM
|
||||||
clothing_register c
|
clothing_register c
|
||||||
LEFT JOIN `user` u ON u.id = c.buyUserId
|
LEFT JOIN `user` u ON u.id = c.buyUserId
|
||||||
|
LEFT JOIN activity_school s ON s.id = c.projectId
|
||||||
$condition
|
$condition
|
||||||
""");
|
""");
|
||||||
cnd.andExcludeEmpty("c.projectId", "=", projectId);
|
cnd.andExcludeEmpty("c.projectId", "=", projectId);
|
||||||
cnd.andExcludeEmpty("c.userId", "=", userId);
|
cnd.andExcludeEmpty("c.userId", "=", userId);
|
||||||
cnd.andExcludeEmpty("year(c.ctime)", "=", year);
|
cnd.andExcludeEmpty("COALESCE(YEAR(s.applyStartTime), YEAR(c.ctime))", "=", year);
|
||||||
|
|
||||||
sql.setCondition(cnd);
|
sql.setCondition(cnd);
|
||||||
return listMap(sql);
|
return listMap(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public boolean doDelete(String projectId, String year, String userId) {
|
public boolean doDelete(String projectId, String year, String userId) {
|
||||||
|
|
||||||
int clearCount = dao().clear(ClothingRegister.class, Cnd.where("projectId", "=", projectId)
|
Cnd cnd = Cnd.where("projectId", "=", projectId).and("userId", "=", userId);
|
||||||
.and("year(ctime)", "=", year).and("userId", "=", userId));
|
ActivitySchool school = dao().fetch(ActivitySchool.class, projectId);
|
||||||
|
String applyStartTime = school == null ? null : school.getApplyStartTime();
|
||||||
|
// 新活动以报名年度定位整组登记;旧项目没有活动年度时沿用登记时间筛选。
|
||||||
|
if (Strings.isNotBlank(applyStartTime) && applyStartTime.length() >= 4) {
|
||||||
|
if (!year.equals(applyStartTime.substring(0, 4))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cnd.and("year(ctime)", "=", year);
|
||||||
|
}
|
||||||
|
int clearCount = dao().clear(ClothingRegister.class, cnd);
|
||||||
return clearCount >= 0;
|
return clearCount >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pagination getRegisterUser(PageForm pageForm, Integer year, String projectId, Boolean isBuy, String sex, String unionId) {
|
public Pagination getRegisterUser(PageForm pageForm, String projectId, Boolean isBuy, String sex, String unionId) {
|
||||||
|
|
||||||
CndPlus cnd = CndPlus.create();
|
CndPlus cnd = CndPlus.create();
|
||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
@@ -129,20 +157,105 @@ public class ClothingRegisterServiceImpl extends ViServiceImpl<ClothingRegister>
|
|||||||
if (Strings.isNotBlank(pageForm.getSearchName()) && Strings.isNotBlank(pageForm.getSearchKeyword())) {
|
if (Strings.isNotBlank(pageForm.getSearchName()) && Strings.isNotBlank(pageForm.getSearchKeyword())) {
|
||||||
cnd.where().andLike(pageForm.getSearchName(), pageForm.getSearchKeyword());
|
cnd.where().andLike(pageForm.getSearchName(), pageForm.getSearchKeyword());
|
||||||
}
|
}
|
||||||
if(year != null) {
|
if (Strings.isBlank(projectId)) {
|
||||||
int lastYear = year - 1;
|
// 没有活动时不能把全部会员误显示为该活动的“未购买”人员。
|
||||||
cnd.and(new Static("id %s (select buyUserId from clothing_register where projectId = '%s' and (year(ctime) = '%s' or year(ctime) = '%s'))"
|
cnd.and(new Static("1 = 0"));
|
||||||
.formatted(isBuy ? "in" : "not in", projectId, year, lastYear)));
|
} else {
|
||||||
|
// 活动名称和ID每年可能变化,购买状态按活动选中项目的运动项目及活动年度判断。
|
||||||
|
Set<String> purchasedIds = findPurchasedUserIds(projectId);
|
||||||
|
if (purchasedIds.isEmpty()) {
|
||||||
|
if (Boolean.TRUE.equals(isBuy)) cnd.and(new Static("1 = 0"));
|
||||||
|
} else {
|
||||||
|
cnd.and("u.id", Boolean.TRUE.equals(isBuy) ? "in" : "not in", purchasedIds.toArray(new String[0]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sql.setCondition(cnd);
|
sql.setCondition(cnd);
|
||||||
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
Pagination result = listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||||
|
if (Boolean.TRUE.equals(isBuy) && Strings.isNotBlank(projectId)) {
|
||||||
|
// 历史活动中已购买的人员可查看,但只能移除当前活动自身的登记记录。
|
||||||
|
Set<String> currentIds = listMap(Sqls.create("SELECT DISTINCT buyUserId AS buy_user_id FROM clothing_register WHERE projectId = @projectId")
|
||||||
|
.setParam("projectId", projectId)).stream()
|
||||||
|
.map(row -> row.getString("buy_user_id")).collect(Collectors.toSet());
|
||||||
|
List<NutMap> users = result.getList();
|
||||||
|
users.forEach(user -> user.setv("canRemove", currentIds.contains(user.getString("id"))));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* projectId 为当前活动ID;返回该活动选择的运动项目标识。项目未配置 sports 时以项目ID兜底,
|
||||||
|
* 避免把不同项目误判为同类;已选项目为空时拒绝登记,防止绕过重复购买限制。
|
||||||
|
*/
|
||||||
|
private List<String> getSelectedSportKeys(String projectId) {
|
||||||
|
List<NutMap> events = listMap(Sqls.create("""
|
||||||
|
SELECT DISTINCT COALESCE(NULLIF(ae.sports, ''), ae.id) AS sport_key
|
||||||
|
FROM activity_school_event ase
|
||||||
|
JOIN activity_event ae ON ae.id = ase.eventId
|
||||||
|
WHERE ase.activityId = @projectId
|
||||||
|
""").setParam("projectId", projectId));
|
||||||
|
List<String> keys = events.stream().map(event -> event.getString("sport_key"))
|
||||||
|
.filter(Strings::isNotBlank).distinct().collect(Collectors.toList());
|
||||||
|
if (keys.isEmpty()) throw new IllegalArgumentException("当前活动未配置可识别的活动项目,无法登记服装");
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* projectId 为当前活动ID;返回与活动年度相差不超过一年、购买过任一相同运动项目服装的人员ID。
|
||||||
|
* 年度取活动报名开始时间,避免跨年补登记时因 clothing_register.ctime 不同而漏判。
|
||||||
|
*/
|
||||||
|
private Set<String> findPurchasedUserIds(String projectId) {
|
||||||
|
ActivitySchool school = dao().fetch(ActivitySchool.class, projectId);
|
||||||
|
if (school == null || Integer.valueOf(1).equals(school.getIsSave())) {
|
||||||
|
throw new IllegalArgumentException("活动不存在或尚未提交");
|
||||||
|
}
|
||||||
|
String applyStartTime = school.getApplyStartTime();
|
||||||
|
if (Strings.isBlank(applyStartTime) || applyStartTime.length() < 4) {
|
||||||
|
throw new IllegalArgumentException("当前活动未设置报名开始时间,无法判断两年购买范围");
|
||||||
|
}
|
||||||
|
int activityYear;
|
||||||
|
try {
|
||||||
|
activityYear = Integer.parseInt(applyStartTime.substring(0, 4));
|
||||||
|
} catch (NumberFormatException exception) {
|
||||||
|
throw new IllegalArgumentException("当前活动报名开始时间格式不正确", exception);
|
||||||
|
}
|
||||||
|
List<String> sportKeys = getSelectedSportKeys(projectId);
|
||||||
|
CndPlus cnd = CndPlus.create();
|
||||||
|
// 补录历史活动时也要检查后一年的购买记录,避免登记顺序改变查重结果。
|
||||||
|
cnd.and("YEAR(s.applyStartTime)", "in", new Integer[]{activityYear - 1, activityYear, activityYear + 1});
|
||||||
|
cnd.and("COALESCE(NULLIF(ae.sports, ''), ae.id)", "in", sportKeys.toArray(new String[0]));
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT DISTINCT c.buyUserId AS buy_user_id
|
||||||
|
FROM clothing_register c
|
||||||
|
JOIN activity_school s ON s.id = c.projectId
|
||||||
|
JOIN activity_school_event ase ON ase.activityId = s.id
|
||||||
|
JOIN activity_event ae ON ae.id = ase.eventId
|
||||||
|
$condition
|
||||||
|
""").setCondition(cnd);
|
||||||
|
return listMap(sql).stream().map(row -> row.getString("buy_user_id"))
|
||||||
|
.filter(Strings::isNotBlank).collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public Object add(String[] ids, String projectId) {
|
public Object add(String[] ids, String projectId) {
|
||||||
|
|
||||||
|
if (ids == null || ids.length == 0 || Strings.isBlank(projectId)) {
|
||||||
|
throw new IllegalArgumentException("请选择活动和登记人员");
|
||||||
|
}
|
||||||
|
List<String> userIds = Arrays.stream(ids).filter(Strings::isNotBlank).distinct().sorted().collect(Collectors.toList());
|
||||||
|
if (userIds.isEmpty()) throw new IllegalArgumentException("请选择登记人员");
|
||||||
|
// 锁定人员行后再查重,防止并发提交同时通过两年内同项目的校验。
|
||||||
|
for (String id : userIds) {
|
||||||
|
if (listMap(Sqls.create("SELECT id FROM `user` WHERE id = @id FOR UPDATE").setParam("id", id)).isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("所选人员不存在,请刷新名单");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Set<String> purchasedIds = findPurchasedUserIds(projectId);
|
||||||
|
if (userIds.stream().anyMatch(purchasedIds::contains)) {
|
||||||
|
throw new IllegalArgumentException("所选人员在近两年内已购买同类项目服装,不能重复提交,请刷新名单");
|
||||||
|
}
|
||||||
List<ClothingRegister> clothingRegisterList = new ArrayList<>();
|
List<ClothingRegister> clothingRegisterList = new ArrayList<>();
|
||||||
for (String id : ids) {
|
for (String id : userIds) {
|
||||||
ClothingRegister clothingRegister = new ClothingRegister();
|
ClothingRegister clothingRegister = new ClothingRegister();
|
||||||
clothingRegister.setProjectId(projectId);
|
clothingRegister.setProjectId(projectId);
|
||||||
clothingRegister.setUserId(ShiroUtil.getPrincipalProperty("id").toString());
|
clothingRegister.setUserId(ShiroUtil.getPrincipalProperty("id").toString());
|
||||||
@@ -154,12 +267,17 @@ public class ClothingRegisterServiceImpl extends ViServiceImpl<ClothingRegister>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean removeBuyUser(String[] ids, String projectId, Integer year) {
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
public boolean removeBuyUser(String[] ids, String projectId) {
|
||||||
|
|
||||||
|
if (ids == null || ids.length == 0 || Strings.isBlank(projectId)) {
|
||||||
|
throw new IllegalArgumentException("请选择当前活动中需要移除的人员");
|
||||||
|
}
|
||||||
Trans.exec(() -> {
|
Trans.exec(() -> {
|
||||||
for (String id : ids) {
|
for (String id : ids) {
|
||||||
dao().clear(ClothingRegister.class, Cnd.where("projectId", "=", projectId)
|
Cnd cnd = Cnd.where("projectId", "=", projectId).and("buyUserId", "=", id);
|
||||||
.and("year(ctime)", "=", year).and("buyUserId", "=", id));
|
// 同类历史活动的购买记录仍保留,仅删除当前活动中选中的登记。
|
||||||
|
dao().clear(ClothingRegister.class, cnd);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,31 @@
|
|||||||
package io.v.nutz.diseaseaid.controller;
|
package io.v.nutz.diseaseaid.controller;
|
||||||
|
|
||||||
|
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
||||||
|
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||||
|
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||||
import io.v.nutz.annontation.ViReturn;
|
import io.v.nutz.annontation.ViReturn;
|
||||||
import io.v.nutz.base.utils.DateUtil;
|
import io.v.nutz.base.utils.DateUtil;
|
||||||
import io.v.nutz.diseaseaid.mode.AidFundMemberMode;
|
import io.v.nutz.diseaseaid.mode.AidFundMemberMode;
|
||||||
import io.v.nutz.diseaseaid.service.AidFundMemberAuditRecordService;
|
import io.v.nutz.diseaseaid.service.AidFundMemberAuditRecordService;
|
||||||
import io.v.nutz.diseaseaid.service.MedicalAidService;
|
import io.v.nutz.diseaseaid.service.MedicalAidService;
|
||||||
import io.v.nutz.member.service.MemberService;
|
import io.v.nutz.member.service.MemberService;
|
||||||
|
import io.v.nutz.modules.models.PageForm;
|
||||||
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.nutz.dao.Cnd;
|
import org.nutz.dao.Cnd;
|
||||||
import org.nutz.dao.Sqls;
|
import org.nutz.dao.Sqls;
|
||||||
import org.nutz.dao.entity.Record;
|
import org.nutz.dao.entity.Record;
|
||||||
import org.nutz.dao.sql.Sql;
|
import org.nutz.dao.sql.Sql;
|
||||||
|
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||||
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.lang.Strings;
|
||||||
import org.nutz.mvc.annotation.At;
|
import org.nutz.mvc.annotation.At;
|
||||||
import org.nutz.mvc.annotation.Ok;
|
import org.nutz.mvc.annotation.Ok;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -58,6 +68,7 @@ public class DiseaseAidDashBoard {
|
|||||||
SELECT
|
SELECT
|
||||||
un.unionname,
|
un.unionname,
|
||||||
un.unioncode,
|
un.unioncode,
|
||||||
|
un.id unionid,
|
||||||
( SELECT count( 1 ) FROM `user` WHERE unionid = un.id and aidFundMember = @code ) `value`
|
( SELECT count( 1 ) FROM `user` WHERE unionid = un.id and aidFundMember = @code ) `value`
|
||||||
FROM
|
FROM
|
||||||
sys_union un
|
sys_union un
|
||||||
@@ -188,5 +199,200 @@ public class DiseaseAidDashBoard {
|
|||||||
return medicalAidService.count(sql);
|
return medicalAidService.count(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 看板指标下钻明细
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
@RequiresPermissions("aid.dashboard")
|
||||||
|
public Object detailPage(PageForm pageForm, String detailType, Integer year, Integer medicalType,
|
||||||
|
Integer stateId, String unionId, String unitId, String personType,
|
||||||
|
String userState, String sex, String searchKeyword,
|
||||||
|
String startTime, String endTime) {
|
||||||
|
Sql sql = buildDetailSql(detailType, year, medicalType, stateId, unionId, unitId,
|
||||||
|
personType, userState, sex, searchKeyword, startTime, endTime);
|
||||||
|
return medicalAidService.listPage(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出当前筛选条件下的全部下钻明细
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@Ok("void")
|
||||||
|
@RequiresPermissions("aid.dashboard")
|
||||||
|
public void exportDetail(HttpServletResponse response, String detailType, Integer year, Integer medicalType,
|
||||||
|
Integer stateId, String unionId, String unitId, String personType,
|
||||||
|
String userState, String sex, String searchKeyword,
|
||||||
|
String startTime, String endTime) throws IOException {
|
||||||
|
Sql sql = buildDetailSql(detailType, year, medicalType, stateId, unionId, unitId,
|
||||||
|
personType, userState, sex, searchKeyword, startTime, endTime);
|
||||||
|
List<Record> list = medicalAidService.list(sql);
|
||||||
|
List<ExcelExportEntity> columns = new ArrayList<>();
|
||||||
|
columns.add(new ExcelExportEntity("工号", "loginname", 18));
|
||||||
|
columns.add(new ExcelExportEntity("姓名", "username", 16));
|
||||||
|
columns.add(new ExcelExportEntity("性别", "sex", 10));
|
||||||
|
columns.add(new ExcelExportEntity("人员类型", "personType", 18));
|
||||||
|
columns.add(new ExcelExportEntity("在职状态", "userState", 16));
|
||||||
|
columns.add(new ExcelExportEntity("所属工会", "unionname", 25));
|
||||||
|
columns.add(new ExcelExportEntity("所属单位", "unitname", 25));
|
||||||
|
if ("medical".equals(detailType)) {
|
||||||
|
columns.add(new ExcelExportEntity("补助类型", "typeName", 18));
|
||||||
|
columns.add(new ExcelExportEntity("申请时间", "detailTime", 20));
|
||||||
|
columns.add(new ExcelExportEntity("申请状态", "state_name", 18));
|
||||||
|
columns.add(new ExcelExportEntity("补助金额", "total_grant", 18));
|
||||||
|
} else {
|
||||||
|
columns.add(new ExcelExportEntity("加入时间", "detailTime", 20));
|
||||||
|
}
|
||||||
|
|
||||||
|
String fileName = "medical".equals(detailType) ? "医疗互助申请明细.xls" : "基金会员明细.xls";
|
||||||
|
response.setContentType("application/octet-stream");
|
||||||
|
response.setHeader("Content-Disposition", "attachment;filename="
|
||||||
|
+ new String(fileName.getBytes("UTF-8"), "ISO8859-1"));
|
||||||
|
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), columns, list);
|
||||||
|
workbook.write(response.getOutputStream());
|
||||||
|
workbook.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 明细弹窗筛选选项
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
@RequiresPermissions("aid.dashboard")
|
||||||
|
public Object detailOptions() {
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT DISTINCT
|
||||||
|
s.state_id value,
|
||||||
|
s.state_name label
|
||||||
|
FROM state s
|
||||||
|
INNER JOIN medicalaid med ON med.state_id = s.state_id
|
||||||
|
ORDER BY s.state_id
|
||||||
|
""");
|
||||||
|
return Map.of("medicalStates", medicalAidService.list(sql));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Sql buildDetailSql(String detailType, Integer year, Integer medicalType, Integer stateId,
|
||||||
|
String unionId, String unitId, String personType, String userState,
|
||||||
|
String sex, String searchKeyword, String startTime, String endTime) {
|
||||||
|
if ("medical".equals(detailType)) {
|
||||||
|
return buildMedicalDetailSql(year, medicalType, stateId, unionId, unitId, personType,
|
||||||
|
userState, sex, searchKeyword, startTime, endTime);
|
||||||
|
}
|
||||||
|
return buildMemberDetailSql(year, unionId, unitId, personType, userState, sex,
|
||||||
|
searchKeyword, startTime, endTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Sql buildMemberDetailSql(Integer year, String unionId, String unitId, String personType,
|
||||||
|
String userState, String sex, String searchKeyword,
|
||||||
|
String startTime, String endTime) {
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
u.id,
|
||||||
|
u.loginname,
|
||||||
|
u.username,
|
||||||
|
u.sex,
|
||||||
|
u.personType,
|
||||||
|
u.userState,
|
||||||
|
u.unionid,
|
||||||
|
u.unionname,
|
||||||
|
u.unitid,
|
||||||
|
u.unitname,
|
||||||
|
u.aidFundMemberJoinTime detailTime
|
||||||
|
FROM user u
|
||||||
|
$condition
|
||||||
|
""");
|
||||||
|
Cnd cnd = Cnd.where("u.aidFundMember", "=", AidFundMemberMode.NORMAL.getCode());
|
||||||
|
if (year != null) {
|
||||||
|
cnd.and("YEAR(u.aidFundMemberJoinTime)", "=", year);
|
||||||
|
}
|
||||||
|
addUserCondition(cnd, "u", unionId, unitId, personType, userState, sex,
|
||||||
|
searchKeyword, startTime, endTime, "aidFundMemberJoinTime");
|
||||||
|
sql.setCondition(cnd.asc("u.unioncode").asc("u.loginname"));
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Sql buildMedicalDetailSql(Integer year, Integer medicalType, Integer stateId,
|
||||||
|
String unionId, String unitId, String personType,
|
||||||
|
String userState, String sex, String searchKeyword,
|
||||||
|
String startTime, String endTime) {
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
med.id,
|
||||||
|
u.loginname,
|
||||||
|
med.user_name username,
|
||||||
|
u.sex,
|
||||||
|
u.personType,
|
||||||
|
u.userState,
|
||||||
|
u.unionid,
|
||||||
|
un.unionname,
|
||||||
|
u.unitid,
|
||||||
|
unit.name unitname,
|
||||||
|
med.type,
|
||||||
|
CASE med.type
|
||||||
|
WHEN 1 THEN '医疗补助'
|
||||||
|
WHEN 2 THEN '重疾补助'
|
||||||
|
WHEN 3 THEN '特殊门诊补助'
|
||||||
|
ELSE '其他'
|
||||||
|
END typeName,
|
||||||
|
med.apply_time detailTime,
|
||||||
|
med.state_id,
|
||||||
|
s.state_name,
|
||||||
|
med.total_grant
|
||||||
|
FROM medicalaid med
|
||||||
|
LEFT JOIN user u ON med.user_id = u.id
|
||||||
|
LEFT JOIN sys_union un ON u.unionid = un.id
|
||||||
|
LEFT JOIN sys_unit unit ON u.unitid = unit.id
|
||||||
|
LEFT JOIN state s ON med.state_id = s.state_id
|
||||||
|
$condition
|
||||||
|
""");
|
||||||
|
Cnd cnd = Cnd.NEW();
|
||||||
|
if (year != null) {
|
||||||
|
cnd.and("med.year", "=", year);
|
||||||
|
}
|
||||||
|
if (medicalType != null) {
|
||||||
|
cnd.and("med.type", "=", medicalType);
|
||||||
|
}
|
||||||
|
if (stateId != null) {
|
||||||
|
cnd.and("med.state_id", "=", stateId);
|
||||||
|
}
|
||||||
|
addUserCondition(cnd, "u", unionId, unitId, personType, userState, sex,
|
||||||
|
searchKeyword, startTime, endTime, "med.apply_time");
|
||||||
|
sql.setCondition(cnd.desc("med.apply_time"));
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addUserCondition(Cnd cnd, String alias, String unionId, String unitId,
|
||||||
|
String personType, String userState, String sex,
|
||||||
|
String searchKeyword, String startTime, String endTime,
|
||||||
|
String timeField) {
|
||||||
|
if (Strings.isNotBlank(unionId)) {
|
||||||
|
cnd.and(alias + ".unionid", "=", unionId);
|
||||||
|
}
|
||||||
|
if (Strings.isNotBlank(unitId)) {
|
||||||
|
cnd.and(alias + ".unitid", "=", unitId);
|
||||||
|
}
|
||||||
|
if (Strings.isNotBlank(personType)) {
|
||||||
|
cnd.and(alias + ".personType", "=", personType);
|
||||||
|
}
|
||||||
|
if (Strings.isNotBlank(userState)) {
|
||||||
|
cnd.and(alias + ".userState", "=", userState);
|
||||||
|
}
|
||||||
|
if (Strings.isNotBlank(sex)) {
|
||||||
|
cnd.and(alias + ".sex", "=", sex);
|
||||||
|
}
|
||||||
|
if (Strings.isNotBlank(startTime)) {
|
||||||
|
cnd.and(timeField, ">=", startTime);
|
||||||
|
}
|
||||||
|
if (Strings.isNotBlank(endTime)) {
|
||||||
|
cnd.and(timeField, "<=", endTime + " 23:59:59");
|
||||||
|
}
|
||||||
|
if (Strings.isNotBlank(searchKeyword)) {
|
||||||
|
SqlExpressionGroup group = new SqlExpressionGroup();
|
||||||
|
group.orLike(alias + ".username", searchKeyword);
|
||||||
|
group.orLike(alias + ".loginname", searchKeyword);
|
||||||
|
cnd.and(group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package io.v.nutz.levelcheck.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分级核对操作类型
|
||||||
|
*/
|
||||||
|
public interface LevelCheckAction {
|
||||||
|
String DISTRIBUTE = "DISTRIBUTE";
|
||||||
|
String CONFIRM = "CONFIRM";
|
||||||
|
String SUBMIT_REVISION = "SUBMIT_REVISION";
|
||||||
|
String APPROVE = "APPROVE";
|
||||||
|
String REJECT = "REJECT";
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package io.v.nutz.levelcheck.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分级核对状态
|
||||||
|
*/
|
||||||
|
public interface LevelCheckState {
|
||||||
|
int PENDING_CHECK = 0;
|
||||||
|
int CONFIRMED = 1;
|
||||||
|
int PENDING_AUDIT = 2;
|
||||||
|
int REJECTED = 3;
|
||||||
|
int APPROVED = 4;
|
||||||
|
}
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
package io.v.nutz.levelcheck.controller;
|
||||||
|
|
||||||
|
import cn.wizzer.framework.base.Result;
|
||||||
|
import io.v.nutz.annontation.ViReturn;
|
||||||
|
import io.v.nutz.levelcheck.service.LevelCheckService;
|
||||||
|
import org.nutz.ioc.aop.Aop;
|
||||||
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
|
import org.nutz.mvc.annotation.*;
|
||||||
|
import org.nutz.mvc.upload.TempFile;
|
||||||
|
import org.nutz.mvc.upload.UploadAdaptor;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校工会分级核对管理
|
||||||
|
*/
|
||||||
|
@IocBean
|
||||||
|
@At("/platform/levelCheck/school")
|
||||||
|
@Ok("json:full")
|
||||||
|
@RequiresAuthentication
|
||||||
|
public class LevelCheckSchoolController {
|
||||||
|
@Inject
|
||||||
|
private LevelCheckService levelCheckService;
|
||||||
|
|
||||||
|
@At("")
|
||||||
|
@Ok("beetl:/platform/levelCheck/school.html")
|
||||||
|
public void index() {
|
||||||
|
levelCheckService.requireSchoolAdmin();
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
public Object taskData(String taskName, String taskDate, int pageNumber, int pageSize) {
|
||||||
|
try {
|
||||||
|
levelCheckService.requireSchoolAdmin();
|
||||||
|
return Result.success().addData(levelCheckService.schoolTasks(
|
||||||
|
taskName, taskDate, pageNumber, pageSize));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
public Object unitTaskData(String taskId, String unitName, Integer state, Integer managerState,
|
||||||
|
int pageNumber, int pageSize) {
|
||||||
|
try {
|
||||||
|
levelCheckService.requireSchoolAdmin();
|
||||||
|
return Result.success().addData(levelCheckService.schoolUnitTasks(
|
||||||
|
taskId, unitName, state, managerState, pageNumber, pageSize));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
public Object unitDataPage(String unitTaskId, String versionType, String searchName, String searchKeyword,
|
||||||
|
Integer state,
|
||||||
|
int pageNumber, int pageSize) {
|
||||||
|
try {
|
||||||
|
return Result.success().addData(levelCheckService.unitDataPage(
|
||||||
|
unitTaskId, versionType, searchName, searchKeyword, state, pageNumber, pageSize));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
public Object currentDataPage(String taskId, String searchName, String searchKeyword, Integer state,
|
||||||
|
int pageNumber, int pageSize) {
|
||||||
|
try {
|
||||||
|
return Result.success().addData(levelCheckService.currentDataPage(
|
||||||
|
taskId, searchName, searchKeyword, state, pageNumber, pageSize));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@POST
|
||||||
|
@ViReturn
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
public Object doDelete(String taskId) {
|
||||||
|
try {
|
||||||
|
levelCheckService.deleteTask(taskId);
|
||||||
|
return null;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@POST
|
||||||
|
@ViReturn
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
|
||||||
|
public Object doUpload(String taskName, String description,
|
||||||
|
@Param("files") TempFile[] files) {
|
||||||
|
try {
|
||||||
|
levelCheckService.requireSchoolAdmin();
|
||||||
|
NutMap result = levelCheckService.createTask(taskName, description, files);
|
||||||
|
String message = result.getInt("errorCount") > 0 ? "导入完成,部分数据未分发" : "分发成功";
|
||||||
|
return Result.success(message).addData(result);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
public void exportImportErrors(String cacheKey, HttpServletResponse response) {
|
||||||
|
try {
|
||||||
|
levelCheckService.requireSchoolAdmin();
|
||||||
|
byte[] bytes = levelCheckService.getImportErrorFile(cacheKey);
|
||||||
|
String fileName = "分级核对导入错误.xlsx";
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
response.setHeader("Content-Disposition", "attachment;filename="
|
||||||
|
+ URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()));
|
||||||
|
response.getOutputStream().write(bytes);
|
||||||
|
} catch (Exception e) {
|
||||||
|
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
public void downloadTemplate(HttpServletResponse response) {
|
||||||
|
try {
|
||||||
|
byte[] bytes = levelCheckService.getImportTemplate();
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
response.setHeader("Content-Disposition", "attachment;filename="
|
||||||
|
+ URLEncoder.encode("分级核对导入模板.xlsx", StandardCharsets.UTF_8.name()));
|
||||||
|
response.getOutputStream().write(bytes);
|
||||||
|
} catch (Exception e) {
|
||||||
|
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
public Object doAudit(String unitTaskId, boolean approved, String opinion) {
|
||||||
|
try {
|
||||||
|
levelCheckService.audit(unitTaskId, approved, opinion);
|
||||||
|
return null;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
public void download(String unitTaskId, String versionType, HttpServletResponse response) {
|
||||||
|
try {
|
||||||
|
byte[] bytes = levelCheckService.getDownloadBytes(unitTaskId, versionType, true);
|
||||||
|
String fileName = levelCheckService.getDownloadFileName(unitTaskId, versionType, true);
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
response.setHeader("Content-Disposition", "attachment;filename="
|
||||||
|
+ URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()));
|
||||||
|
response.getOutputStream().write(bytes);
|
||||||
|
} catch (Exception e) {
|
||||||
|
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
public void exportCurrent(String taskId, HttpServletResponse response) {
|
||||||
|
try {
|
||||||
|
byte[] bytes = levelCheckService.exportCurrent(taskId);
|
||||||
|
String fileName = "分级核对当前生效数据.xlsx";
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
response.setHeader("Content-Disposition", "attachment;filename="
|
||||||
|
+ URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()));
|
||||||
|
response.getOutputStream().write(bytes);
|
||||||
|
} catch (Exception e) {
|
||||||
|
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
package io.v.nutz.levelcheck.controller;
|
||||||
|
|
||||||
|
import cn.wizzer.framework.base.Result;
|
||||||
|
import io.v.nutz.annontation.ViReturn;
|
||||||
|
import io.v.nutz.levelcheck.service.LevelCheckService;
|
||||||
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
|
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.*;
|
||||||
|
import org.nutz.mvc.upload.TempFile;
|
||||||
|
import org.nutz.mvc.upload.UploadAdaptor;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单位分级核对
|
||||||
|
*/
|
||||||
|
@IocBean
|
||||||
|
@At("/platform/levelCheck/unit")
|
||||||
|
@Ok("json:full")
|
||||||
|
@RequiresAuthentication
|
||||||
|
public class LevelCheckUnitController {
|
||||||
|
@Inject
|
||||||
|
private LevelCheckService levelCheckService;
|
||||||
|
|
||||||
|
@At("")
|
||||||
|
@Ok("beetl:/platform/levelCheck/unit.html")
|
||||||
|
public void index() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
public Object taskData(String keyword, Integer state, int pageNumber, int pageSize) {
|
||||||
|
try {
|
||||||
|
return Result.success().addData(levelCheckService.myUnitTasks(
|
||||||
|
keyword, state, pageNumber, pageSize));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
public Object doConfirm(String unitTaskId) {
|
||||||
|
try {
|
||||||
|
levelCheckService.confirm(unitTaskId);
|
||||||
|
return null;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
public Object dataPage(String unitTaskId, String searchName, String searchKeyword, Integer state,
|
||||||
|
int pageNumber, int pageSize) {
|
||||||
|
try {
|
||||||
|
return Result.success().addData(levelCheckService.myUnitDataPage(
|
||||||
|
unitTaskId, searchName, searchKeyword, state, pageNumber, pageSize));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@POST
|
||||||
|
@ViReturn
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
|
||||||
|
public Object doUploadRevision(String unitTaskId, @Param("file") TempFile file) {
|
||||||
|
try {
|
||||||
|
levelCheckService.submitRevision(unitTaskId, file);
|
||||||
|
return null;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
public void download(String unitTaskId, HttpServletResponse response) {
|
||||||
|
try {
|
||||||
|
byte[] bytes = levelCheckService.getDownloadBytes(unitTaskId, "current", false);
|
||||||
|
String fileName = levelCheckService.getDownloadFileName(unitTaskId, "current", false);
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
response.setHeader("Content-Disposition", "attachment;filename="
|
||||||
|
+ URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()));
|
||||||
|
response.getOutputStream().write(bytes);
|
||||||
|
} catch (Exception e) {
|
||||||
|
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package io.v.nutz.levelcheck.model;
|
||||||
|
|
||||||
|
import io.v.nutz.base.model.BaseModel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
import org.nutz.dao.entity.annotation.*;
|
||||||
|
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Table("level_check_action_log")
|
||||||
|
@TableIndexes({@Index(name = "IDX_LEVEL_CHECK_LOG_UNIT", fields = {"unitTaskId"}, unique = false)})
|
||||||
|
public class LevelCheckActionLog extends BaseModel {
|
||||||
|
@Name
|
||||||
|
@PrevInsert(uu32 = true)
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String unitTaskId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 30)
|
||||||
|
private String action;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
private Integer fromState;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
private Integer toState;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String operatorId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
private Long operateAt;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 500)
|
||||||
|
private String opinion;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String fileVersionId;
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package io.v.nutz.levelcheck.model;
|
||||||
|
|
||||||
|
import io.v.nutz.base.model.BaseModel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
import org.nutz.dao.entity.annotation.*;
|
||||||
|
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分级核对固定模板数据明细
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Table("level_check_data_row")
|
||||||
|
@TableIndexes({@Index(name = "IDX_LEVEL_CHECK_DATA_VERSION", fields = {"versionId", "sequenceNo"}, unique = true)})
|
||||||
|
public class LevelCheckDataRow extends BaseModel {
|
||||||
|
@Name
|
||||||
|
@PrevInsert(uu32 = true)
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String versionId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
private Integer sequenceNo;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(customType = "text")
|
||||||
|
private String salaryUnitCode;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(customType = "text")
|
||||||
|
private String employeeNo;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(customType = "text")
|
||||||
|
private String employeeName;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(customType = "text")
|
||||||
|
private String unionFee;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(customType = "text")
|
||||||
|
private String yearMonth;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(customType = "text")
|
||||||
|
private String unitName;
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package io.v.nutz.levelcheck.model;
|
||||||
|
|
||||||
|
import io.v.nutz.base.model.BaseModel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
import org.nutz.dao.entity.annotation.*;
|
||||||
|
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Table("level_check_file_version")
|
||||||
|
@TableIndexes({@Index(name = "IDX_LEVEL_CHECK_FILE_UNIT", fields = {"unitTaskId", "versionNo"}, unique = true)})
|
||||||
|
public class LevelCheckFileVersion extends BaseModel {
|
||||||
|
@Name
|
||||||
|
@PrevInsert(uu32 = true)
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String unitTaskId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
private Integer versionNo;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||||
|
private String versionType;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String sysFileId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 200)
|
||||||
|
private String originalFileName;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
private Integer rowCount;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 64)
|
||||||
|
private String sha256;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String uploadedBy;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
private Long uploadedAt;
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package io.v.nutz.levelcheck.model;
|
||||||
|
|
||||||
|
import io.v.nutz.base.model.BaseModel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
import org.nutz.dao.entity.annotation.*;
|
||||||
|
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Table("level_check_task")
|
||||||
|
public class LevelCheckTask extends BaseModel {
|
||||||
|
@Name
|
||||||
|
@PrevInsert(uu32 = true)
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||||
|
@Comment("任务名称")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("任务日期")
|
||||||
|
private Long taskDate;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("总单位数")
|
||||||
|
private Integer totalUnits;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("已完成单位数")
|
||||||
|
private Integer finishedUnits;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 500)
|
||||||
|
@Comment("任务说明")
|
||||||
|
private String description;
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package io.v.nutz.levelcheck.model;
|
||||||
|
|
||||||
|
import io.v.nutz.base.model.BaseModel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
import org.nutz.dao.entity.annotation.*;
|
||||||
|
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Table("level_check_unit_task")
|
||||||
|
@TableIndexes({
|
||||||
|
@Index(name = "IDX_LEVEL_CHECK_UNIT_TASK", fields = {"taskId", "unitId"}, unique = true),
|
||||||
|
@Index(name = "IDX_LEVEL_CHECK_UNIT_STATE", fields = {"state"}, unique = false)
|
||||||
|
})
|
||||||
|
public class LevelCheckUnitTask extends BaseModel {
|
||||||
|
@Name
|
||||||
|
@PrevInsert(uu32 = true)
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String taskId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String unitId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||||
|
private String unitName;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
private Integer unitLevel;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||||
|
private String managerType;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String unionId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
private Integer state;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String originalVersionId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String currentVersionId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String pendingVersionId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
private Integer rowCount;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String checkedBy;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
private Long checkedAt;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String auditedBy;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
private Long auditedAt;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 500)
|
||||||
|
private String auditOpinion;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
private Integer dataVersion;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -49,7 +49,9 @@ public class MemberAgendaController {
|
|||||||
final String title = "【会员系统】";
|
final String title = "【会员系统】";
|
||||||
|
|
||||||
List<NutMap> list = new ArrayList<>();
|
List<NutMap> list = new ArrayList<>();
|
||||||
if (!ShiroUtil.hasAnyRoles("sysadmin,A06,gh01,H03")) {
|
if (!ShiroUtil.hasAnyRoles("sysadmin,A06,gh01,H03")
|
||||||
|
&& !org.apache.shiro.SecurityUtils.getSubject().isPermitted("member.apply.audit.union")
|
||||||
|
&& !org.apache.shiro.SecurityUtils.getSubject().isPermitted("member.apply.audit.school")) {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
boolean anyRoles = ShiroUtil.hasAnyRoles("sysadmin,A06,H03");
|
boolean anyRoles = ShiroUtil.hasAnyRoles("sysadmin,A06,H03");
|
||||||
@@ -67,20 +69,26 @@ public class MemberAgendaController {
|
|||||||
|
|
||||||
int marUnionNum = 0;
|
int marUnionNum = 0;
|
||||||
Cnd marUnionCnd = Cnd.where("mar.stateId", "=", MemberApplyState.UNION);
|
Cnd marUnionCnd = Cnd.where("mar.stateId", "=", MemberApplyState.UNION);
|
||||||
if (!anyRoles) {
|
// 入会审核范围与 PC 部门审核列表一致,校级角色不能自动越过部门权限。
|
||||||
marUnionCnd.and("u.unionid", "=", Vi.getUnionId());
|
if (!ShiroUtil.hasAnyRoles("sysadmin")) {
|
||||||
|
marUnionCnd.and("mar.unionId", "=", Vi.getUnionId());
|
||||||
}
|
}
|
||||||
marSql.setCondition(marUnionCnd);
|
marSql.setCondition(marUnionCnd);
|
||||||
marUnionNum = memberService.count(marSql);
|
marUnionNum = memberService.count(marSql);
|
||||||
|
if (org.apache.shiro.SecurityUtils.getSubject().isPermitted("member.apply.audit.union"))
|
||||||
list.add(new NutMap().addv("title", title).addv("iconClass", vi.getIconByPath("/platform/member/apply/audit/union")).addv("label", "待部门工会入会审核").addv("number", marUnionNum).addv("url", "/platform/member/apply/audit/union"));
|
list.add(new NutMap().addv("title", title).addv("iconClass", vi.getIconByPath("/platform/member/apply/audit/union")).addv("label", "待部门工会入会审核").addv("number", marUnionNum).addv("url", "/platform/member/apply/audit/union"));
|
||||||
|
|
||||||
int marSchoolNum = 0;
|
int marSchoolNum = 0;
|
||||||
Cnd marSchoolCnd = Cnd.where("mar.stateId", "=", MemberApplyState.SCHOOL_UNION);
|
Cnd marSchoolCnd = Cnd.where("mar.stateId", "=", MemberApplyState.SCHOOL_UNION);
|
||||||
marSql.setCondition(marSchoolCnd);
|
marSql.setCondition(marSchoolCnd);
|
||||||
marSchoolNum = memberService.count(marSql);
|
marSchoolNum = memberService.count(marSql);
|
||||||
|
if (org.apache.shiro.SecurityUtils.getSubject().isPermitted("member.apply.audit.school"))
|
||||||
list.add(new NutMap().addv("title", title).addv("iconClass", vi.getIconByPath("/platform/member/apply/audit/school")).addv("label", "待校工会入会审核").addv("number", marSchoolNum).addv("url", "/platform/member/apply/audit/school"));
|
list.add(new NutMap().addv("title", title).addv("iconClass", vi.getIconByPath("/platform/member/apply/audit/school")).addv("label", "待校工会入会审核").addv("number", marSchoolNum).addv("url", "/platform/member/apply/audit/school"));
|
||||||
|
|
||||||
|
|
||||||
|
// 非原会员变更管理角色仅返回按权限计算的入会待办。
|
||||||
|
if (!ShiroUtil.hasAnyRoles("sysadmin,A06,gh01,H03")) return list;
|
||||||
|
|
||||||
// 会员变更
|
// 会员变更
|
||||||
Sql mcrSql = Sqls.create("""
|
Sql mcrSql = Sqls.create("""
|
||||||
SELECT
|
SELECT
|
||||||
@@ -111,4 +119,24 @@ public class MemberAgendaController {
|
|||||||
List<Sys_menu> menus = Optional.ofNullable(user).orElse(new Sys_user()).getMenus();
|
List<Sys_menu> menus = Optional.ofNullable(user).orElse(new Sys_user()).getMenus();
|
||||||
return list.stream().filter(v -> Strings.isNotBlank(v.getString("url")) && menus.stream().anyMatch(x -> Strings.isNotBlank(x.getHref()) && v.getString("url").contains(x.getHref()))).distinct().collect(Collectors.toList());
|
return list.stream().filter(v -> Strings.isNotBlank(v.getString("url")) && menus.stream().anyMatch(x -> Strings.isNotBlank(x.getHref()) && v.getString("url").contains(x.getHref()))).distinct().collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无需参数,返回当前登录人今年可办理的入会审核节点。
|
||||||
|
* 每项 title/name/count/mobileHref 分别表示业务标题、节点名称、待办数量和手机入口。
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
public Object getMobileAgenda() {
|
||||||
|
return memberService.getCurrentYearApplyAgenda();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无需传入办理人,身份从登录会话获取;返回本人今年实际办理的会员入会记录。
|
||||||
|
* 每项 moduleName/auditState/auditTime/mobileUrl 为业务名称、办理节点、办理时间和只读详情地址。
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
public Object getCompletes() {
|
||||||
|
return memberService.getCurrentYearApplyCompletes();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import io.v.nutz.util.ShiroUtil;
|
|||||||
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.nutz.dao.Sqls;
|
import org.nutz.dao.Sqls;
|
||||||
|
import org.nutz.ioc.aop.Aop;
|
||||||
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
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;
|
||||||
@@ -130,6 +132,7 @@ public class MemberApplyAuditController {
|
|||||||
|
|
||||||
@At
|
@At
|
||||||
@ViReturn
|
@ViReturn
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public Object doAudit(@ViRequired String recordId, Audit audit) {
|
public Object doAudit(@ViRequired String recordId, Audit audit) {
|
||||||
MemberApplyRecord record = memberApplyRecordViService.fetch(recordId);
|
MemberApplyRecord record = memberApplyRecordViService.fetch(recordId);
|
||||||
MemberApplyAuditHandle applyHandle = Enum.instance(MemberApplyAuditHandle.class, record.getStateId());
|
MemberApplyAuditHandle applyHandle = Enum.instance(MemberApplyAuditHandle.class, record.getStateId());
|
||||||
|
|||||||
@@ -1,18 +1,28 @@
|
|||||||
package io.v.nutz.member.controller.inquire;
|
package io.v.nutz.member.controller.inquire;
|
||||||
|
|
||||||
|
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
||||||
|
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||||
|
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||||
import io.v.nutz.annontation.ViReturn;
|
import io.v.nutz.annontation.ViReturn;
|
||||||
import io.v.nutz.base.utils.DateUtil;
|
import io.v.nutz.base.utils.DateUtil;
|
||||||
import io.v.nutz.member.service.MemberService;
|
import io.v.nutz.member.service.MemberService;
|
||||||
|
import io.v.nutz.modules.models.PageForm;
|
||||||
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
import org.nutz.dao.Cnd;
|
||||||
import org.nutz.dao.Sqls;
|
import org.nutz.dao.Sqls;
|
||||||
import org.nutz.dao.entity.Record;
|
import org.nutz.dao.entity.Record;
|
||||||
import org.nutz.dao.sql.Sql;
|
import org.nutz.dao.sql.Sql;
|
||||||
|
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||||
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.lang.Strings;
|
||||||
import org.nutz.mvc.annotation.At;
|
import org.nutz.mvc.annotation.At;
|
||||||
import org.nutz.mvc.annotation.Ok;
|
import org.nutz.mvc.annotation.Ok;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -47,7 +57,7 @@ public class MemberDataBoardController {
|
|||||||
@ViReturn
|
@ViReturn
|
||||||
public Object memberNumber() {
|
public Object memberNumber() {
|
||||||
int memberNum = memberService.count(Sqls.create("select count(1) from member"));
|
int memberNum = memberService.count(Sqls.create("select count(1) from member"));
|
||||||
int lastYearMemberNum = memberService.count(Sqls.create("select * from member_his where year = year(now()) -1 "));
|
int lastYearMemberNum = memberService.count(Sqls.create("select * from member_his where year = year(now()) -1 and member = 1 "));
|
||||||
return Map.of("memberNum", memberNum, "lastYearMemberNum", lastYearMemberNum);
|
return Map.of("memberNum", memberNum, "lastYearMemberNum", lastYearMemberNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +70,7 @@ public class MemberDataBoardController {
|
|||||||
List<Map> result = new ArrayList<>();
|
List<Map> result = new ArrayList<>();
|
||||||
Integer year = DateUtil.getYear();
|
Integer year = DateUtil.getYear();
|
||||||
for (int i = year - 5; i < year; i++) {
|
for (int i = year - 5; i < year; i++) {
|
||||||
int count = memberService.count(Sqls.create("select * from member_his where year = @year ").setParam("year", year));
|
int count = memberService.count(Sqls.create("select * from member_his where year = @year and member = 1 ").setParam("year", i));
|
||||||
result.add(Map.of("label", i, "value", count));
|
result.add(Map.of("label", i, "value", count));
|
||||||
}
|
}
|
||||||
result.add(Map.of("label", year, "value", memberService.count(Sqls.create("select count(1) from member"))));
|
result.add(Map.of("label", year, "value", memberService.count(Sqls.create("select count(1) from member"))));
|
||||||
@@ -104,6 +114,7 @@ public class MemberDataBoardController {
|
|||||||
SELECT
|
SELECT
|
||||||
un.unionname,
|
un.unionname,
|
||||||
un.unioncode,
|
un.unioncode,
|
||||||
|
un.id unionid,
|
||||||
( SELECT count( 1 ) FROM member WHERE unionid = un.id ) `value`
|
( SELECT count( 1 ) FROM member WHERE unionid = un.id ) `value`
|
||||||
FROM
|
FROM
|
||||||
sys_union un
|
sys_union un
|
||||||
@@ -166,5 +177,122 @@ public class MemberDataBoardController {
|
|||||||
return memberService.list(sql);
|
return memberService.list(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 看板指标下钻明细
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
@RequiresPermissions("member.inquire.board")
|
||||||
|
public Object detailPage(PageForm pageForm, Integer year, String unionId, String unitId,
|
||||||
|
String personType, String userState, String sex, String searchKeyword,
|
||||||
|
String startTime, String endTime) {
|
||||||
|
return memberService.list(pageForm, buildDetailSql(year, unionId, unitId, personType,
|
||||||
|
userState, sex, searchKeyword, startTime, endTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出当前筛选条件下的全部下钻明细
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@Ok("void")
|
||||||
|
@RequiresPermissions("member.inquire.board")
|
||||||
|
public void exportDetail(HttpServletResponse response, Integer year, String unionId, String unitId,
|
||||||
|
String personType, String userState, String sex, String searchKeyword,
|
||||||
|
String startTime, String endTime) throws IOException {
|
||||||
|
List<Record> list = memberService.list(buildDetailSql(year, unionId, unitId, personType,
|
||||||
|
userState, sex, searchKeyword, startTime, endTime));
|
||||||
|
List<ExcelExportEntity> columns = new ArrayList<>();
|
||||||
|
columns.add(new ExcelExportEntity("工号", "loginname", 18));
|
||||||
|
columns.add(new ExcelExportEntity("姓名", "username", 16));
|
||||||
|
columns.add(new ExcelExportEntity("性别", "sex", 10));
|
||||||
|
columns.add(new ExcelExportEntity("人员类型", "personType", 18));
|
||||||
|
columns.add(new ExcelExportEntity("在职状态", "userState", 16));
|
||||||
|
columns.add(new ExcelExportEntity("所属工会", "unionname", 25));
|
||||||
|
columns.add(new ExcelExportEntity("所属单位", "unitname", 25));
|
||||||
|
columns.add(new ExcelExportEntity("入会时间", "detailTime", 18));
|
||||||
|
|
||||||
|
response.setContentType("application/octet-stream");
|
||||||
|
response.setHeader("Content-Disposition", "attachment;filename="
|
||||||
|
+ new String("会员看板明细.xls".getBytes("UTF-8"), "ISO8859-1"));
|
||||||
|
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), columns, list);
|
||||||
|
workbook.write(response.getOutputStream());
|
||||||
|
workbook.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 明细弹窗附加选项,会员看板暂无业务状态选项
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
@RequiresPermissions("member.inquire.board")
|
||||||
|
public Object detailOptions() {
|
||||||
|
return Map.of("medicalStates", List.of());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Sql buildDetailSql(Integer year, String unionId, String unitId, String personType,
|
||||||
|
String userState, String sex, String searchKeyword,
|
||||||
|
String startTime, String endTime) {
|
||||||
|
int currentYear = DateUtil.getYear();
|
||||||
|
boolean history = year != null && year != currentYear;
|
||||||
|
String timeField = "h.memberJoinTime";
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
m.id,
|
||||||
|
m.loginname,
|
||||||
|
m.username,
|
||||||
|
m.sex,
|
||||||
|
m.personType,
|
||||||
|
m.userState,
|
||||||
|
m.unionid,
|
||||||
|
m.unionname,
|
||||||
|
m.unitid,
|
||||||
|
m.unitname,
|
||||||
|
$detailTime detailTime
|
||||||
|
FROM $table m
|
||||||
|
$detailJoin
|
||||||
|
$condition
|
||||||
|
""")
|
||||||
|
.setVar("table", history ? "member_his" : "`user`")
|
||||||
|
.setVar("detailTime", timeField)
|
||||||
|
.setVar("detailJoin", history
|
||||||
|
? "LEFT JOIN member_history h ON h.id = m.id AND h.year = m.year"
|
||||||
|
: "LEFT JOIN sys_user h ON h.id = m.id");
|
||||||
|
Cnd cnd = Cnd.NEW();
|
||||||
|
cnd.and("m.member", "=", 1);
|
||||||
|
if (history) {
|
||||||
|
cnd.and("m.year", "=", year);
|
||||||
|
}
|
||||||
|
if (Strings.isNotBlank(unionId)) {
|
||||||
|
cnd.and("m.unionid", "=", unionId);
|
||||||
|
}
|
||||||
|
if (Strings.isNotBlank(unitId)) {
|
||||||
|
cnd.and("m.unitid", "=", unitId);
|
||||||
|
}
|
||||||
|
if (Strings.isNotBlank(personType)) {
|
||||||
|
cnd.and("m.personType", "=", personType);
|
||||||
|
}
|
||||||
|
if (Strings.isNotBlank(userState)) {
|
||||||
|
cnd.and("m.userState", "=", userState);
|
||||||
|
}
|
||||||
|
if (Strings.isNotBlank(sex)) {
|
||||||
|
cnd.and("m.sex", "=", sex);
|
||||||
|
}
|
||||||
|
if (Strings.isNotBlank(startTime)) {
|
||||||
|
cnd.and(timeField, ">=", startTime);
|
||||||
|
}
|
||||||
|
if (Strings.isNotBlank(endTime)) {
|
||||||
|
cnd.and(timeField, "<=", endTime + " 23:59:59");
|
||||||
|
}
|
||||||
|
if (Strings.isNotBlank(searchKeyword)) {
|
||||||
|
SqlExpressionGroup group = new SqlExpressionGroup();
|
||||||
|
group.orLike("m.username", searchKeyword);
|
||||||
|
group.orLike("m.loginname", searchKeyword);
|
||||||
|
cnd.and(group);
|
||||||
|
}
|
||||||
|
cnd.asc("m.unioncode").asc("m.loginname");
|
||||||
|
sql.setCondition(cnd);
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import io.v.nutz.diseaseaid.constant.AidFundMemberAuditState;
|
|||||||
import io.v.nutz.diseaseaid.mode.AidFundMemberMode;
|
import io.v.nutz.diseaseaid.mode.AidFundMemberMode;
|
||||||
import io.v.nutz.diseaseaid.model.AidFundMemberAuditRecord;
|
import io.v.nutz.diseaseaid.model.AidFundMemberAuditRecord;
|
||||||
import io.v.nutz.member.UserMode;
|
import io.v.nutz.member.UserMode;
|
||||||
|
import io.v.nutz.member.service.MemberService;
|
||||||
import io.v.nutz.member.constant.MemberApplyState;
|
import io.v.nutz.member.constant.MemberApplyState;
|
||||||
import io.v.nutz.member.constant.MemberOrigin;
|
import io.v.nutz.member.constant.MemberOrigin;
|
||||||
import io.v.nutz.member.model.MemberApplyRecord;
|
import io.v.nutz.member.model.MemberApplyRecord;
|
||||||
@@ -25,6 +26,8 @@ import io.v.nutz.util.ShiroUtil;
|
|||||||
import io.v.nutz.util.ViResource;
|
import io.v.nutz.util.ViResource;
|
||||||
import io.v.nutz.web.commons.base.Globals;
|
import io.v.nutz.web.commons.base.Globals;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import org.nutz.ioc.aop.Aop;
|
||||||
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
import org.nutz.dao.Chain;
|
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;
|
||||||
@@ -55,6 +58,7 @@ public enum MemberApplyAuditHandle {
|
|||||||
*/
|
*/
|
||||||
CREATE(null) {
|
CREATE(null) {
|
||||||
@Override
|
@Override
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public MemberApplyRecord next(MemberApplyRecord record, Audit audit) {
|
public MemberApplyRecord next(MemberApplyRecord record, Audit audit) {
|
||||||
record.setUserId(ShiroUtil.getPrincipalProperty("id").toString());
|
record.setUserId(ShiroUtil.getPrincipalProperty("id").toString());
|
||||||
record.setStateId(MemberApplyState.UNION);
|
record.setStateId(MemberApplyState.UNION);
|
||||||
@@ -64,22 +68,8 @@ public enum MemberApplyAuditHandle {
|
|||||||
Sys_user user = sysUserService.fetch(record.getUserId());
|
Sys_user user = sysUserService.fetch(record.getUserId());
|
||||||
|
|
||||||
|
|
||||||
Sql sql = Sqls.create("""
|
// 接收人由 PC 部门审核权限关联的角色确定,并限定申请所属工会。
|
||||||
SELECT
|
List<NutMap> mapList = memberService.applyAuditRecipients(false, record.getUnionId());
|
||||||
su.loginname,
|
|
||||||
su.username
|
|
||||||
FROM
|
|
||||||
sys_user_role sur
|
|
||||||
LEFT JOIN sys_user su ON su.id = sur.userId
|
|
||||||
WHERE
|
|
||||||
sur.roleId = @roleId
|
|
||||||
AND sur.unionid = @unionId
|
|
||||||
""")
|
|
||||||
// .setParam("roleId", Roles.UNION_MANGER)
|
|
||||||
.setParam("roleId", Roles.GH01)
|
|
||||||
.setParam("unionId", record.getUnionId());
|
|
||||||
|
|
||||||
List<NutMap> mapList = sysUserService.listMap(sql);
|
|
||||||
|
|
||||||
if (Lang.isNotEmpty(mapList)) {
|
if (Lang.isNotEmpty(mapList)) {
|
||||||
List<TodoTask.Processor> processors = new ArrayList<>();
|
List<TodoTask.Processor> processors = new ArrayList<>();
|
||||||
@@ -102,6 +92,8 @@ public enum MemberApplyAuditHandle {
|
|||||||
todoTask.setInitiatorId(user.getLoginname());
|
todoTask.setInitiatorId(user.getLoginname());
|
||||||
todoTask.setPcViewUrl(Globals.AppDomain + "/platform/member/apply/audit/union");
|
todoTask.setPcViewUrl(Globals.AppDomain + "/platform/member/apply/audit/union");
|
||||||
todoTask.setH5ViewUrl(Globals.AppDomain + "/mobile/member/audit");
|
todoTask.setH5ViewUrl(Globals.AppDomain + "/mobile/member/audit");
|
||||||
|
todoTask.setDoneH5Url(Globals.AppDomain + "/mobile/member/audit?isAudit=true");
|
||||||
|
todoTask.setDonePcUrl(todoTask.getPcViewUrl() + "?audit=1");
|
||||||
todoTask.setBizId(insert.getId());
|
todoTask.setBizId(insert.getId());
|
||||||
todoTask.setBizType("申请入会部门工会审核");
|
todoTask.setBizType("申请入会部门工会审核");
|
||||||
todoTask.setStatus(TodoTaskEnum.TaskStatus.ACTIVE.name());
|
todoTask.setStatus(TodoTaskEnum.TaskStatus.ACTIVE.name());
|
||||||
@@ -121,6 +113,7 @@ public enum MemberApplyAuditHandle {
|
|||||||
*/
|
*/
|
||||||
AUDIT_UNION(MemberApplyState.UNION) {
|
AUDIT_UNION(MemberApplyState.UNION) {
|
||||||
@Override
|
@Override
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public MemberApplyRecord next(MemberApplyRecord record, Audit audit) {
|
public MemberApplyRecord next(MemberApplyRecord record, Audit audit) {
|
||||||
|
|
||||||
record.setStateId(audit.getAuditPass() ? MemberApplyState.SCHOOL_UNION : MemberApplyState.UNION_FAIL);
|
record.setStateId(audit.getAuditPass() ? MemberApplyState.SCHOOL_UNION : MemberApplyState.UNION_FAIL);
|
||||||
@@ -130,18 +123,8 @@ public enum MemberApplyAuditHandle {
|
|||||||
|
|
||||||
if (audit.getAuditPass()) {
|
if (audit.getAuditPass()) {
|
||||||
|
|
||||||
Sql sql = Sqls.create("""
|
// 部门通过后仅向具有 PC 校工会审核权限的角色成员派发下一阶段待办。
|
||||||
SELECT
|
List<NutMap> mapList = memberService.applyAuditRecipients(true, record.getUnionId());
|
||||||
su.loginname,
|
|
||||||
su.username
|
|
||||||
FROM
|
|
||||||
sys_user_role sur
|
|
||||||
LEFT JOIN sys_user su ON su.id = sur.userId
|
|
||||||
WHERE
|
|
||||||
sur.roleId = @roleId
|
|
||||||
""").setParam("roleId", Roles.H03);
|
|
||||||
|
|
||||||
List<NutMap> mapList = sysUserService.listMap(sql);
|
|
||||||
|
|
||||||
if (Lang.isNotEmpty(mapList)) {
|
if (Lang.isNotEmpty(mapList)) {
|
||||||
List<TodoTask.Processor> processors = new ArrayList<>();
|
List<TodoTask.Processor> processors = new ArrayList<>();
|
||||||
@@ -163,6 +146,8 @@ public enum MemberApplyAuditHandle {
|
|||||||
todoTask.setInitiatorId(user.getLoginname());
|
todoTask.setInitiatorId(user.getLoginname());
|
||||||
todoTask.setPcViewUrl(Globals.AppDomain + "/platform/member/apply/audit/school");
|
todoTask.setPcViewUrl(Globals.AppDomain + "/platform/member/apply/audit/school");
|
||||||
todoTask.setH5ViewUrl(Globals.AppDomain + "/mobile/member/audit");
|
todoTask.setH5ViewUrl(Globals.AppDomain + "/mobile/member/audit");
|
||||||
|
todoTask.setDoneH5Url(Globals.AppDomain + "/mobile/member/audit?isAudit=true");
|
||||||
|
todoTask.setDonePcUrl(todoTask.getPcViewUrl() + "?audit=1");
|
||||||
todoTask.setBizId(record.getId());
|
todoTask.setBizId(record.getId());
|
||||||
todoTask.setBizType("申请入会校工会审核");
|
todoTask.setBizType("申请入会校工会审核");
|
||||||
todoTask.setStatus(TodoTaskEnum.TaskStatus.ACTIVE.name());
|
todoTask.setStatus(TodoTaskEnum.TaskStatus.ACTIVE.name());
|
||||||
@@ -178,14 +163,7 @@ public enum MemberApplyAuditHandle {
|
|||||||
List.of(Map.of("tool", MsgApi.sendTool.wechat_enterprise.name())));
|
List.of(Map.of("tool", MsgApi.sendTool.wechat_enterprise.name())));
|
||||||
}
|
}
|
||||||
|
|
||||||
//部门工会的待办设置为完成
|
memberService.completeApplyAuditTasks(record.getId(), false);
|
||||||
TodoTask todoTask = dao.fetch(TodoTask.class, Cnd.where("bizId", "=", record.getId())
|
|
||||||
.and("bizType", "=", "申请入会部门工会审核"));
|
|
||||||
if (todoTask != null) {
|
|
||||||
todoTask.setProcessorId(ShiroUtil.getPrincipalProperty("loginname").toString());
|
|
||||||
todoTask.setStatus(TodoTaskEnum.TaskStatus.COMPLETE.name());
|
|
||||||
todoTaskInterface.updateTask(todoTask);
|
|
||||||
}
|
|
||||||
return record;
|
return record;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -194,6 +172,7 @@ public enum MemberApplyAuditHandle {
|
|||||||
*/
|
*/
|
||||||
AUDIT_SCHOOL(MemberApplyState.SCHOOL_UNION) {
|
AUDIT_SCHOOL(MemberApplyState.SCHOOL_UNION) {
|
||||||
@Override
|
@Override
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public MemberApplyRecord next(MemberApplyRecord record, Audit audit) {
|
public MemberApplyRecord next(MemberApplyRecord record, Audit audit) {
|
||||||
|
|
||||||
memberApplyRecordViService.transactional(() -> {
|
memberApplyRecordViService.transactional(() -> {
|
||||||
@@ -242,14 +221,7 @@ public enum MemberApplyAuditHandle {
|
|||||||
List.of(Map.of("tool", MsgApi.sendTool.wechat_enterprise.name())));
|
List.of(Map.of("tool", MsgApi.sendTool.wechat_enterprise.name())));
|
||||||
}
|
}
|
||||||
|
|
||||||
//校工会的待办设置为完成
|
memberService.completeApplyAuditTasks(record.getId(), true);
|
||||||
TodoTask todoTask = dao.fetch(TodoTask.class, Cnd.where("bizId", "=", record.getId())
|
|
||||||
.and("bizType", "=", "申请入会校工会审核"));
|
|
||||||
if (todoTask != null) {
|
|
||||||
todoTask.setProcessorId(ShiroUtil.getPrincipalProperty("loginname").toString());
|
|
||||||
todoTask.setStatus(TodoTaskEnum.TaskStatus.COMPLETE.name());
|
|
||||||
todoTaskInterface.updateTask(todoTask);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
sysUserService.deleteCache(record.getUserId());
|
sysUserService.deleteCache(record.getUserId());
|
||||||
@@ -270,6 +242,7 @@ public enum MemberApplyAuditHandle {
|
|||||||
public TodoTaskInterface todoTaskInterface = ViResource.ioc.getByType(TodoTaskInterface.class);
|
public TodoTaskInterface todoTaskInterface = ViResource.ioc.getByType(TodoTaskInterface.class);
|
||||||
public MsgApi msgApi = ViResource.ioc.getByType(MsgApi.class);
|
public MsgApi msgApi = ViResource.ioc.getByType(MsgApi.class);
|
||||||
public Dao dao = ViResource.dao;
|
public Dao dao = ViResource.dao;
|
||||||
|
public MemberService memberService = ViResource.ioc.getByType(MemberService.class);
|
||||||
|
|
||||||
public abstract MemberApplyRecord next(MemberApplyRecord record, Audit audit);
|
public abstract MemberApplyRecord next(MemberApplyRecord record, Audit audit);
|
||||||
|
|
||||||
|
|||||||
@@ -34,4 +34,21 @@ public interface MemberService extends ViService<Sys_user> {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
Pagination memberChangeRecords(PageForm pageForm, CndPlus cnd);
|
Pagination memberChangeRecords(PageForm pageForm, CndPlus cnd);
|
||||||
|
/** 按当前用户 PC 审核权限查询手机列表;isAudit 为已审标记,year 可空,返回 list/totalCount 分页数据。 */
|
||||||
|
Object mobileApplyAuditPage(int pageNumber, int pageSize, boolean isAudit, Integer year);
|
||||||
|
|
||||||
|
/** 按申请记录校验访问范围并返回审核/只读视图,userId 必须属于该记录,done 强制只读。 */
|
||||||
|
String mobileApplyAuditView(String recordId, String userId, boolean done);
|
||||||
|
|
||||||
|
/** 查询拥有指定阶段审核权限的启用角色成员;部门阶段限定 unionId,返回 loginname/username。 */
|
||||||
|
List<NutMap> applyAuditRecipients(boolean school, String unionId);
|
||||||
|
|
||||||
|
/** 关闭指定申请当前阶段的全部有效待办,保留接收人并记录实际办理人和已办地址。 */
|
||||||
|
void completeApplyAuditTasks(String recordId, boolean school);
|
||||||
|
|
||||||
|
/** 返回当前年份入会待办卡片;身份取当前会话,部门限定本工会,超管可查看两级范围。 */
|
||||||
|
List<NutMap> getCurrentYearApplyAgenda();
|
||||||
|
|
||||||
|
/** 返回当前登录人本年度实际审核的入会记录及只读详情地址,不把角色范围内的已审视作本人已办。 */
|
||||||
|
List<NutMap> getCurrentYearApplyCompletes();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,21 @@ import org.nutz.lang.util.NutMap;
|
|||||||
import org.nutz.plugins.wkcache.annotation.CacheDefaults;
|
import org.nutz.plugins.wkcache.annotation.CacheDefaults;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import io.v.nutz.base.utils.Vi;
|
||||||
|
import io.v.nutz.member.constant.MemberApplyState;
|
||||||
|
import io.v.nutz.member.model.MemberApplyRecord;
|
||||||
|
import io.v.nutz.todoTask.TodoTask;
|
||||||
|
import io.v.nutz.todoTask.TodoTaskInterface;
|
||||||
|
import io.v.nutz.web.commons.base.Globals;
|
||||||
|
import io.v.nutz.web.commons.utils.ShiroUtil;
|
||||||
|
import org.apache.shiro.authz.UnauthorizedException;
|
||||||
|
import org.apache.shiro.authz.permission.WildcardPermission;
|
||||||
|
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||||
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
|
import org.nutz.ioc.aop.Aop;
|
||||||
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
|
import org.nutz.lang.Strings;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,4 +85,151 @@ public class MemberServiceImpl extends ViServiceImpl<Sys_user> implements Member
|
|||||||
Sql sql = Sqls.create(MEMBER_CHANGE_RECORDS).setCondition(cnd);
|
Sql sql = Sqls.create(MEMBER_CHANGE_RECORDS).setCondition(cnd);
|
||||||
return list(pageForm, sql);
|
return list(pageForm, sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private TodoTaskInterface todoTaskInterface;
|
||||||
|
|
||||||
|
/** 与 PC 页面的权限注解一致,不能用待办角色名称替代审核权限。 */
|
||||||
|
private boolean canApplyAudit(boolean school) {
|
||||||
|
return ShiroUtil.hasPermission("member.apply.audit." + (school ? "school" : "union"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object mobileApplyAuditPage(int pageNumber, int pageSize, boolean isAudit, Integer year) {
|
||||||
|
boolean union = canApplyAudit(false);
|
||||||
|
boolean school = canApplyAudit(true);
|
||||||
|
if (!union && !school) throw new UnauthorizedException("无会员审核权限");
|
||||||
|
Sql sql = Sqls.create("SELECT mar.*, st.stateName, st.stateColor, u.unionname, u.username, "
|
||||||
|
+ "u.loginname, u.personType FROM member_apply_record mar "
|
||||||
|
+ "LEFT JOIN audit_state st ON st.stateId=mar.stateId LEFT JOIN `user` u ON u.id=mar.userId $condition");
|
||||||
|
SqlExpressionGroup scope = new SqlExpressionGroup();
|
||||||
|
// 已审沿用 PC 各阶段 stateId > 当前阶段的口径;双权限取并集,避免重复记录。
|
||||||
|
if (union && (ShiroUtil.hasRole("sysadmin") || Strings.isNotBlank(Vi.getUnionId()))) {
|
||||||
|
Cnd department = Cnd.where("mar.stateId", isAudit ? ">" : "=", MemberApplyState.UNION);
|
||||||
|
if (!ShiroUtil.hasRole("sysadmin")) department.and("mar.unionId", "=", Vi.getUnionId());
|
||||||
|
scope.or(department.where());
|
||||||
|
} else if (!school) {
|
||||||
|
return listPageMap(Math.max(1, pageNumber), Math.max(1, pageSize), sql.setCondition(Cnd.where("1", "=", 0)));
|
||||||
|
}
|
||||||
|
if (school) scope.or("mar.stateId", isAudit ? ">" : "=", MemberApplyState.SCHOOL_UNION);
|
||||||
|
CndPlus cnd = CndPlus.create();
|
||||||
|
cnd.and(scope);
|
||||||
|
cnd.andExcludeEmpty("YEAR(mar.applyTime)", "=", year);
|
||||||
|
cnd.asc("mar.stateId").desc("mar.applyTime");
|
||||||
|
return listPageMap(Math.max(1, pageNumber), Math.max(1, Math.min(pageSize, 100)), sql.setCondition(cnd));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String mobileApplyAuditView(String recordId, String userId, boolean done) {
|
||||||
|
MemberApplyRecord record = Strings.isBlank(recordId) ? null : dao().fetch(MemberApplyRecord.class, recordId);
|
||||||
|
if (record == null || !Objects.equals(record.getUserId(), userId)) {
|
||||||
|
throw new IllegalArgumentException("申请记录不存在或申请人不匹配");
|
||||||
|
}
|
||||||
|
boolean union = canApplyAudit(false) && (ShiroUtil.hasRole("sysadmin")
|
||||||
|
|| Strings.isNotBlank(Vi.getUnionId()) && Objects.equals(Vi.getUnionId(), record.getUnionId()));
|
||||||
|
boolean school = canApplyAudit(true) && record.getStateId() != null
|
||||||
|
&& record.getStateId() >= MemberApplyState.SCHOOL_UNION;
|
||||||
|
if (!union && !school) throw new UnauthorizedException("无权查看该申请");
|
||||||
|
if (!done && union && Objects.equals(record.getStateId(), MemberApplyState.UNION)) {
|
||||||
|
return "beetl:/mobile/member/union_Audit.html";
|
||||||
|
}
|
||||||
|
if (!done && school && Objects.equals(record.getStateId(), MemberApplyState.SCHOOL_UNION)) {
|
||||||
|
return "beetl:/mobile/member/school_Audit.html";
|
||||||
|
}
|
||||||
|
return "beetl:/mobile/member/detail.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<NutMap> applyAuditRecipients(boolean school, String unionId) {
|
||||||
|
// 从 PC 权限对应的角色成员取接收人,兼容 Shiro 通配权限并排除禁用角色、菜单和账号。
|
||||||
|
Sql sql = Sqls.create("SELECT DISTINCT su.loginname, su.username, sm.permission FROM sys_user_role sur "
|
||||||
|
+ "JOIN sys_user su ON su.id=sur.userId JOIN sys_role sr ON sr.id=sur.roleId "
|
||||||
|
+ "JOIN sys_role_menu srm ON srm.roleId=sr.id JOIN sys_menu sm ON sm.id=srm.menuId "
|
||||||
|
+ "WHERE sr.disabled=false AND sm.disabled=false AND su.disabled=false "
|
||||||
|
+ (school ? "" : "AND sur.unionid=@unionId AND su.unionid=@unionId "));
|
||||||
|
sql.setParam("unionId", unionId);
|
||||||
|
WildcardPermission required = new WildcardPermission("member.apply.audit." + (school ? "school" : "union"));
|
||||||
|
java.util.Map<String, NutMap> recipients = new java.util.LinkedHashMap<>();
|
||||||
|
for (NutMap row : listMap(sql)) {
|
||||||
|
String permission = row.getString("permission");
|
||||||
|
if (Strings.isNotBlank(permission) && Strings.isNotBlank(row.getString("loginname"))
|
||||||
|
&& new WildcardPermission(permission).implies(required)) {
|
||||||
|
recipients.putIfAbsent(row.getString("loginname"), row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new java.util.ArrayList<>(recipients.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
public void completeApplyAuditTasks(String recordId, boolean school) {
|
||||||
|
// 同阶段可能存在历史重复待办,只关闭 ACTIVE 项,保留接收角色成员列表用于已办归属。
|
||||||
|
List<TodoTask> tasks = dao().query(TodoTask.class, Cnd.where("bizId", "=", recordId)
|
||||||
|
.and("bizType", "=", school ? "申请入会校工会审核" : "申请入会部门工会审核")
|
||||||
|
.and("status", "=", "ACTIVE").and(Cnd.exps("delFlag", "=", false).or("delFlag", "is", null)));
|
||||||
|
for (TodoTask task : tasks) {
|
||||||
|
task.setProcessorId(ShiroUtil.getPrincipalProperty("loginname").toString());
|
||||||
|
task.setStatus("COMPLETE");
|
||||||
|
task.setDonePcUrl(Globals.AppDomain + "/platform/member/apply/audit/" + (school ? "school" : "union") + "?audit=1");
|
||||||
|
task.setDoneH5Url(Globals.AppDomain + "/mobile/member/audit?isAudit=true");
|
||||||
|
todoTaskInterface.updateTask(task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<NutMap> getCurrentYearApplyAgenda() {
|
||||||
|
int year = java.time.LocalDate.now().getYear();
|
||||||
|
boolean admin = ShiroUtil.hasRole("sysadmin");
|
||||||
|
List<NutMap> items = new java.util.ArrayList<>();
|
||||||
|
for (boolean school : new boolean[]{false, true}) {
|
||||||
|
if (!admin && !canApplyAudit(school)) continue;
|
||||||
|
// 没有工会归属的部门审核人不能因空条件而获得全校范围。
|
||||||
|
if (!school && !admin && Strings.isBlank(Vi.getUnionId())) continue;
|
||||||
|
Cnd cnd = Cnd.where("stateId", "=", school ? MemberApplyState.SCHOOL_UNION : MemberApplyState.UNION)
|
||||||
|
.and("applyTime", ">=", year + "-01-01")
|
||||||
|
.and("applyTime", "<", (year + 1) + "-01-01");
|
||||||
|
if (!school && !admin) cnd.and("unionId", "=", Vi.getUnionId());
|
||||||
|
int count = dao().count(MemberApplyRecord.class, cnd);
|
||||||
|
items.add(new NutMap().setv("title", "【会员入会】")
|
||||||
|
.setv("name", school ? "待校工会入会审核" : "待部门工会入会审核")
|
||||||
|
.setv("count", count).setv("mobileHref", "/mobile/member/audit"));
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<NutMap> getCurrentYearApplyCompletes() {
|
||||||
|
Object principalLoginname = ShiroUtil.getPrincipalProperty("loginname");
|
||||||
|
String loginname = principalLoginname == null ? "" : principalLoginname.toString();
|
||||||
|
boolean admin = ShiroUtil.hasRole("sysadmin");
|
||||||
|
boolean union = admin || canApplyAudit(false);
|
||||||
|
boolean school = admin || canApplyAudit(true);
|
||||||
|
if (Strings.isBlank(loginname) || !union && !school) return java.util.Collections.emptyList();
|
||||||
|
int year = java.time.LocalDate.now().getYear();
|
||||||
|
// 只读取当前申请实际关联的审核记录,按办理工号和办理年份筛选;同人办理两级保留两个节点。
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT mar.id, a.id auditId, nodes.nodeId,
|
||||||
|
CONCAT('【会员入会】', COALESCE(u.username, '')) moduleName,
|
||||||
|
nodes.nodeName auditState, a.auditTime,
|
||||||
|
CONCAT('/mobile/member/audit/findOne?record_id=', mar.id,
|
||||||
|
'&user_id=', mar.userId, '&done=true') mobileUrl
|
||||||
|
FROM member_apply_record mar
|
||||||
|
LEFT JOIN `user` u ON u.id=mar.userId
|
||||||
|
JOIN (SELECT 1 nodeId, '部门工会审核' nodeName
|
||||||
|
UNION ALL SELECT 2, '校工会审核') nodes ON 1=1
|
||||||
|
JOIN audit a ON a.id=CASE nodes.nodeId WHEN 1 THEN mar.unionAuditId ELSE mar.schoolAuditId END
|
||||||
|
WHERE a.loginname=@loginname AND a.auditTime>=@startTime AND a.auditTime<@endTime
|
||||||
|
AND ((nodes.nodeId=1 AND @unionAllowed=1 AND (@admin=1 OR mar.unionId=@unionId))
|
||||||
|
OR (nodes.nodeId=2 AND @schoolAllowed=1))
|
||||||
|
ORDER BY a.auditTime DESC, mar.id, nodes.nodeId
|
||||||
|
""");
|
||||||
|
sql.setParam("loginname", loginname);
|
||||||
|
sql.setParam("startTime", year + "-01-01");
|
||||||
|
sql.setParam("endTime", (year + 1) + "-01-01");
|
||||||
|
sql.setParam("unionAllowed", union ? 1 : 0);
|
||||||
|
sql.setParam("schoolAllowed", school ? 1 : 0);
|
||||||
|
sql.setParam("admin", admin ? 1 : 0);
|
||||||
|
sql.setParam("unionId", Strings.sNull(Vi.getUnionId()));
|
||||||
|
return listMap(sql);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,112 +1,47 @@
|
|||||||
package io.v.nutz.mobile.member;
|
package io.v.nutz.mobile.member;
|
||||||
|
|
||||||
import cn.wizzer.framework.base.service.BaseService;
|
|
||||||
import io.v.nutz.annontation.ViReturn;
|
import io.v.nutz.annontation.ViReturn;
|
||||||
import io.v.nutz.base.utils.Vi;
|
import io.v.nutz.member.service.MemberService;
|
||||||
import io.v.nutz.dao.CndPlus;
|
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||||
import io.v.nutz.member.constant.MemberApplyState;
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import io.v.nutz.util.ShiroUtil;
|
import org.apache.shiro.authz.annotation.Logical;
|
||||||
import org.nutz.dao.Sqls;
|
|
||||||
import org.nutz.dao.sql.Sql;
|
|
||||||
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
|
||||||
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.lang.Lang;
|
|
||||||
import org.nutz.mvc.annotation.At;
|
import org.nutz.mvc.annotation.At;
|
||||||
import org.nutz.mvc.annotation.Ok;
|
import org.nutz.mvc.annotation.Ok;
|
||||||
|
|
||||||
/**
|
/** 手机端会员审核统一入口,与 PC 端共享两级审核权限。 */
|
||||||
* @author zhf
|
|
||||||
* @date 2021/9/26 9:24
|
|
||||||
* @description
|
|
||||||
*/
|
|
||||||
@IocBean
|
@IocBean
|
||||||
@At("/mobile/member/audit")
|
@At("/mobile/member/audit")
|
||||||
@Ok("json:full")
|
@Ok("json:full")
|
||||||
|
@RequiresAuthentication
|
||||||
|
@RequiresPermissions(value = {"member.apply.audit.union", "member.apply.audit.school"}, logical = Logical.OR)
|
||||||
public class MemberAuditUnionController {
|
public class MemberAuditUnionController {
|
||||||
|
@Inject
|
||||||
|
private MemberService memberService;
|
||||||
|
|
||||||
@At("")
|
@At("")
|
||||||
@Ok("beetl:/mobile/member/audit_list.html")
|
@Ok("beetl:/mobile/member/audit_list.html")
|
||||||
public void indext() {
|
public void index() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
/**
|
||||||
private BaseService baseService;
|
* pageNumber/pageSize 为页码和每页条数,isAudit 区分已审/待审,year 为申请年份(可空)。
|
||||||
|
* 返回分页对象,list 为申请记录,totalCount 为符合当前审核权限的数据总数。
|
||||||
|
*/
|
||||||
@At
|
@At
|
||||||
@ViReturn
|
@ViReturn
|
||||||
public Object pageData(int pageNumber, int pageSize, boolean isAudit, Integer year) {
|
public Object pageData(int pageNumber, int pageSize, boolean isAudit, Integer year) {
|
||||||
Sql sql = Sqls.create("""
|
return memberService.mobileApplyAuditPage(pageNumber, pageSize, isAudit, year);
|
||||||
SELECT
|
|
||||||
mar.*,
|
|
||||||
st.stateName,
|
|
||||||
st.stateColor,
|
|
||||||
u.unionname,
|
|
||||||
u.username,
|
|
||||||
u.loginname,
|
|
||||||
u.personType
|
|
||||||
FROM
|
|
||||||
`member_apply_record` mar
|
|
||||||
LEFT JOIN audit_state st ON st.stateId = mar.stateId
|
|
||||||
LEFT JOIN `user` u ON u.id = mar.userId
|
|
||||||
$condition
|
|
||||||
""");
|
|
||||||
|
|
||||||
CndPlus cnd = CndPlus.create();
|
|
||||||
cnd.and("mar.memberStates", "=", 1);
|
|
||||||
|
|
||||||
if (ShiroUtil.hasAnyRoles("sysadmin")) {
|
|
||||||
cnd.and("mar.stateId", "in", isAudit ? Lang.array(MemberApplyState.UNION_FAIL, MemberApplyState.SCHOOL_UNION_FAIL, MemberApplyState.NORMAL_MEMBER) : Lang.array(MemberApplyState.UNION, MemberApplyState.SCHOOL_UNION));
|
|
||||||
} else {
|
|
||||||
if (ShiroUtil.hasAnyRoles("A06,wyh02") && ShiroUtil.hasAnyRoles("H04")) {
|
|
||||||
SqlExpressionGroup seg = new SqlExpressionGroup();
|
|
||||||
seg.or("mar.stateId", isAudit ? ">" : "=", MemberApplyState.SCHOOL_UNION);
|
|
||||||
seg.or(CndPlus.exps("mar.unionId", "=", Vi.getUnionId()).and("mar.stateId", isAudit ? ">" : "=", MemberApplyState.UNION));
|
|
||||||
cnd.and(seg);
|
|
||||||
} else if (ShiroUtil.hasAnyRoles("A06,wyh02")) {
|
|
||||||
cnd.and("mar.stateId", isAudit ? ">" : "=", MemberApplyState.SCHOOL_UNION);
|
|
||||||
} else if (ShiroUtil.hasAnyRoles("H04")) {
|
|
||||||
cnd.and("mar.unionId", "=", Vi.getUnionId());
|
|
||||||
cnd.and("mar.stateId", isAudit ? ">" : "=", MemberApplyState.UNION);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
/*if (ShiroUtil.hasAnyRoles("A06,wyh02")) {
|
* record_id 为申请记录 ID,user_id 为申请人 ID,done 表示从已办入口只读查看。
|
||||||
cnd.and("mar.stateId", isAudit ? ">" : "=", MemberApplyState.SCHOOL_UNION);
|
* 返回 Beetl 页面视图;实际审核阶段和访问范围均由数据库记录决定。
|
||||||
} else if (ShiroUtil.hasAnyRoles("H04")) {
|
*/
|
||||||
cnd.and("mar.unionId", "=", Vi.getUnionId());
|
|
||||||
cnd.and("mar.stateId", isAudit ? ">" : "=", MemberApplyState.UNION);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if (!ShiroUtil.hasAnyRoles("sysadmin")) {
|
|
||||||
if (ShiroUtil.hasAnyRoles("A06,wyh02")) {
|
|
||||||
cnd.and("mar.stateId", isAudit ? ">" : "=", MemberApplyState.SCHOOL_UNION);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
cnd.andExcludeEmpty("YEAR(mar.applyTime)", "=", year);
|
|
||||||
|
|
||||||
cnd.asc("mar.stateId");
|
|
||||||
cnd.desc("mar.applyTime");
|
|
||||||
sql.setCondition(cnd);
|
|
||||||
return baseService.listPageMap(pageNumber, pageSize, sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@At("/findOne")
|
@At("/findOne")
|
||||||
@Ok("re")
|
@Ok("re")
|
||||||
public String findOne(Integer stateId) {
|
public String findOne(String record_id, String user_id, boolean done) {
|
||||||
if (stateId == MemberApplyState.UNION && ShiroUtil.hasAnyRoles("H04,A06,sysadmin")) {
|
return memberService.mobileApplyAuditView(record_id, user_id, done);
|
||||||
return "beetl:/mobile/member/union_Audit.html";
|
|
||||||
} else if (stateId == MemberApplyState.SCHOOL_UNION && ShiroUtil.hasAnyRoles("A06,sysadmin")) {
|
|
||||||
return "beetl:/mobile/member/school_Audit.html";
|
|
||||||
} /*else if (stateId == MemberApplyState.NORMAL_MEMBER || stateId == MemberApplyState.UNION_FAIL || stateId == MemberApplyState.SCHOOL_UNION_FAIL) {
|
|
||||||
return "beetl:/mobile/member/detail.html";
|
|
||||||
}*/
|
|
||||||
return "beetl:/mobile/member/detail.html";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,11 +121,12 @@ public class MemberMobileController {
|
|||||||
@ViReturn
|
@ViReturn
|
||||||
@RequiresRoles(value = {"H04", "A06"}, logical = Logical.OR)
|
@RequiresRoles(value = {"H04", "A06"}, logical = Logical.OR)
|
||||||
public Object viewInfo(String id) {
|
public Object viewInfo(String id) {
|
||||||
|
// 用户表仅存储出生日期,按当前日期计算周岁,空出生日期返回空年龄。
|
||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
SELECT
|
SELECT
|
||||||
u.username,
|
u.username,
|
||||||
u.sex,
|
u.sex,
|
||||||
u.age,
|
TIMESTAMPDIFF(YEAR, NULLIF(u.birthday, ''), CURDATE()) AS age,
|
||||||
u.nation,
|
u.nation,
|
||||||
u.education,
|
u.education,
|
||||||
u.political,
|
u.political,
|
||||||
|
|||||||
+27
-3
@@ -32,6 +32,8 @@ import org.nutz.mvc.annotation.Ok;
|
|||||||
import org.nutz.mvc.annotation.Param;
|
import org.nutz.mvc.annotation.Param;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -140,11 +142,19 @@ public class proposalExportCaseController {
|
|||||||
@Ok("void")
|
@Ok("void")
|
||||||
@RequiresAuthentication
|
@RequiresAuthentication
|
||||||
public void exportAllProposal(String props, PageForm page, ProposalSearch search, String stateCode, String[] proposalTypes, String[] proposalResult,
|
public void exportAllProposal(String props, PageForm page, ProposalSearch search, String stateCode, String[] proposalTypes, String[] proposalResult,
|
||||||
String searchName2, String searchKeyword2, HttpServletResponse response) throws Exception {
|
String searchName2, String searchKeyword2,
|
||||||
|
@Param("undertakeId") String undertakeId,
|
||||||
|
String[] determineTypeOptions,
|
||||||
|
String exportCondition,
|
||||||
|
String exportFileCondition,
|
||||||
|
HttpServletResponse response) throws Exception {
|
||||||
|
|
||||||
Cnd cnd = Cnd.NEW();
|
Cnd cnd = Cnd.NEW();
|
||||||
Sql sql = Sqls.create(SQL);
|
Sql sql = Sqls.create(SQL);
|
||||||
|
|
||||||
|
if (StrUtil.isNotBlank(undertakeId)) {
|
||||||
|
cnd.and(Cnd.exps("zbpr.replyUnitId", "=", undertakeId).or("xbpr.replyUnitId", "=", undertakeId));
|
||||||
|
}
|
||||||
cnd.andEX("info.stateCode", "=", stateCode);
|
cnd.andEX("info.stateCode", "=", stateCode);
|
||||||
cnd.and("info.stateCode", ">", ProposalState.CASE);
|
cnd.and("info.stateCode", ">", ProposalState.CASE);
|
||||||
if (!ShiroUtil.hasAnyRoles(new String[]{"sysadmin", "A06", "tamange", "jdhdbt01"})) {
|
if (!ShiroUtil.hasAnyRoles(new String[]{"sysadmin", "A06", "tamange", "jdhdbt01"})) {
|
||||||
@@ -160,6 +170,11 @@ public class proposalExportCaseController {
|
|||||||
}
|
}
|
||||||
if (proposalResult != null && proposalResult.length > 0) {
|
if (proposalResult != null && proposalResult.length > 0) {
|
||||||
cnd.and("info.resultCode", "in", proposalResult);
|
cnd.and("info.resultCode", "in", proposalResult);
|
||||||
|
if (ArrayUtil.contains(proposalResult, ProposalConstant.DETERMINE)) {
|
||||||
|
if (determineTypeOptions != null && determineTypeOptions.length > 0) {
|
||||||
|
cnd.and("info.determineTypeCode", "in", determineTypeOptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cnd.asc("info.resultCode");
|
cnd.asc("info.resultCode");
|
||||||
proposalInfoService.sortAndSearch(cnd, page, search);
|
proposalInfoService.sortAndSearch(cnd, page, search);
|
||||||
@@ -189,8 +204,17 @@ public class proposalExportCaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ViTool.excelResponse(response, "提案立案汇总表.xlsx");
|
String exportTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||||
ExportParams exportParams = new ExportParams();
|
String fileCondition = StrUtil.blankToDefault(exportFileCondition, "全部立案提案")
|
||||||
|
.replaceAll("[\\\\/:*?\"<>|\\r\\n]+", "-")
|
||||||
|
.replaceAll("\\s+", "");
|
||||||
|
if (fileCondition.length() > 80) {
|
||||||
|
fileCondition = fileCondition.substring(0, 80);
|
||||||
|
}
|
||||||
|
ViTool.excelResponse(response, "提案立案汇总表_" + fileCondition + "_"
|
||||||
|
+ exportTime.replaceAll("[-: ]", "") + ".xlsx");
|
||||||
|
ExportParams exportParams = new ExportParams("提案立案汇总表(查询条件:"
|
||||||
|
+ StrUtil.blankToDefault(exportCondition, "无") + ";导出时间:" + exportTime + ")", "立案汇总");
|
||||||
exportParams.setType(ExcelType.XSSF);
|
exportParams.setType(ExcelType.XSSF);
|
||||||
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, proposalList);
|
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, proposalList);
|
||||||
workbook.write(response.getOutputStream());
|
workbook.write(response.getOutputStream());
|
||||||
|
|||||||
+117
-5
@@ -11,6 +11,7 @@ import io.v.nutz.annontation.ViReturn;
|
|||||||
import io.v.nutz.base.utils.Vi;
|
import io.v.nutz.base.utils.Vi;
|
||||||
import io.v.nutz.modules.models.PageForm;
|
import io.v.nutz.modules.models.PageForm;
|
||||||
import io.v.nutz.proposal.constants.ProposalConstant;
|
import io.v.nutz.proposal.constants.ProposalConstant;
|
||||||
|
import io.v.nutz.proposal.constants.ProposalState;
|
||||||
import io.v.nutz.proposal.models.ProposalSearch;
|
import io.v.nutz.proposal.models.ProposalSearch;
|
||||||
import io.v.nutz.proposal.services.ProposalInfoService;
|
import io.v.nutz.proposal.services.ProposalInfoService;
|
||||||
import io.v.nutz.util.ShiroUtil;
|
import io.v.nutz.util.ShiroUtil;
|
||||||
@@ -31,8 +32,12 @@ import org.nutz.mvc.annotation.Ok;
|
|||||||
import org.nutz.mvc.annotation.Param;
|
import org.nutz.mvc.annotation.Param;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author zhf
|
* @author zhf
|
||||||
@@ -151,12 +156,15 @@ public class proposalExportSummaryController {
|
|||||||
|
|
||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
SELECT
|
SELECT
|
||||||
|
info.id,
|
||||||
info.proposalCode,
|
info.proposalCode,
|
||||||
info.proposalName,
|
info.proposalName,
|
||||||
info.brief,
|
info.brief,
|
||||||
info.measures,
|
info.measures,
|
||||||
|
info.createTime,
|
||||||
su.username,
|
su.username,
|
||||||
su.loginname,
|
su.loginname,
|
||||||
|
creatorUnit.`name` creatorUnitName,
|
||||||
state.stateName,
|
state.stateName,
|
||||||
state.stateColor,
|
state.stateColor,
|
||||||
type.typeCode,
|
type.typeCode,
|
||||||
@@ -170,16 +178,24 @@ public class proposalExportSummaryController {
|
|||||||
masterPu.unitCode AS pruMasterCode,
|
masterPu.unitCode AS pruMasterCode,
|
||||||
masterPr.replyContent,
|
masterPr.replyContent,
|
||||||
masterPr.handleOpinion,
|
masterPr.handleOpinion,
|
||||||
GROUP_CONCAT(slavePu.unitName) AS pruSlave,
|
masterPr.replyTime,
|
||||||
|
masterPr.implementState,
|
||||||
|
masterPr.leaderCheckTime,
|
||||||
|
masterPr.leaderCheckOpinion,
|
||||||
|
CASE WHEN masterPr.isReply = 1 THEN '已答复' ELSE '未答复' END replyStatus,
|
||||||
|
GROUP_CONCAT(DISTINCT slavePu.unitName) AS pruSlave,
|
||||||
pf.feedbackCodeByUnderTake,
|
pf.feedbackCodeByUnderTake,
|
||||||
pfDict.`name` feedbackResult
|
pfDict.`name` feedbackResult,
|
||||||
|
pf.feedbackOpinion,
|
||||||
|
pf.feedbackTime
|
||||||
FROM
|
FROM
|
||||||
proposal_info info
|
proposal_info info
|
||||||
LEFT JOIN proposal_reply masterPr on masterPr.proposalId = info.id AND masterPr.undertakeType = 1
|
LEFT JOIN proposal_reply masterPr on masterPr.proposalId = info.id AND masterPr.undertakeType = 1
|
||||||
LEFT JOIN proposal_underTake masterPu on masterPu.id = masterPr.replyUnitId
|
LEFT JOIN proposal_underTake masterPu on masterPu.id = masterPr.replyUnitId
|
||||||
LEFT JOIN proposal_reply slavePr on slavePr.proposalId = info.id AND slavePr.undertakeType = 2
|
LEFT JOIN proposal_reply slavePr on slavePr.proposalId = info.id AND slavePr.undertakeType = 2
|
||||||
LEFT JOIN proposal_underTake slavePu on slavePu.id = slavePr.replyUnitId
|
LEFT JOIN proposal_underTake slavePu on slavePu.id = slavePr.replyUnitId
|
||||||
LEFT JOIN `user` su ON su.id = info.createUser
|
LEFT JOIN sys_user su ON su.id = info.createUser
|
||||||
|
LEFT JOIN sys_unit creatorUnit ON creatorUnit.id = su.unitid
|
||||||
LEFT JOIN proposal_state state ON state.stateCode = info.stateCode
|
LEFT JOIN proposal_state state ON state.stateCode = info.stateCode
|
||||||
LEFT JOIN proposal_type type ON type.id = info.typeId
|
LEFT JOIN proposal_type type ON type.id = info.typeId
|
||||||
LEFT JOIN jdh_jdhxx jdh ON jdh.id = info.teacherMeetingId
|
LEFT JOIN jdh_jdhxx jdh ON jdh.id = info.teacherMeetingId
|
||||||
@@ -207,20 +223,36 @@ public class proposalExportSummaryController {
|
|||||||
List<String> proposalResult = mapCnd.getAsList("proposalResult", String.class);
|
List<String> proposalResult = mapCnd.getAsList("proposalResult", String.class);
|
||||||
cnd.andEX("info.resultCode", "in", proposalResult);
|
cnd.andEX("info.resultCode", "in", proposalResult);
|
||||||
|
|
||||||
|
if (proposalResult != null && proposalResult.contains(ProposalConstant.DETERMINE)) {
|
||||||
|
List<String> determineTypeOptions = mapCnd.getAsList("proposalDetermineTypes", String.class);
|
||||||
|
cnd.andEX("info.determineTypeCode", "in", determineTypeOptions);
|
||||||
|
}
|
||||||
|
|
||||||
cnd.andEX("info.delegationId", "=", mapCnd.getString("delegationId"));
|
cnd.andEX("info.delegationId", "=", mapCnd.getString("delegationId"));
|
||||||
cnd.andEX("info.stateCode", "=", mapCnd.getString("stateCode"));
|
cnd.andEX("info.stateCode", "=", mapCnd.getString("stateCode"));
|
||||||
|
if (Boolean.TRUE.equals(mapCnd.getBoolean("caseOnly"))) {
|
||||||
|
cnd.and("info.stateCode", ">", ProposalState.CASE);
|
||||||
|
}
|
||||||
cnd.andEX("su.unionId", "=", mapCnd.getString("unionId"));
|
cnd.andEX("su.unionId", "=", mapCnd.getString("unionId"));
|
||||||
cnd.andEX("su.unitId", "=", mapCnd.getString("unitId"));
|
cnd.andEX("su.unitId", "=", mapCnd.getString("unitId"));
|
||||||
|
if (!ShiroUtil.hasAnyRoles(new String[]{"sysadmin", "A06", "tamange", "jdhdbt01"})) {
|
||||||
|
if (ShiroUtil.hasRole("H04")) {
|
||||||
|
cnd.and("su.unionid", " in ", vi.getMangeUnionStr());
|
||||||
|
}
|
||||||
|
}
|
||||||
cnd.asc("info.proposalCode");
|
cnd.asc("info.proposalCode");
|
||||||
cnd.groupBy("info.id");
|
cnd.groupBy("info.id");
|
||||||
|
|
||||||
sql.setCondition(cnd);
|
sql.setCondition(cnd);
|
||||||
List<NutMap> list = proposalInfoService.listMap(sql);
|
List<NutMap> list = proposalInfoService.listMap(sql);
|
||||||
|
fillExportDetails(list);
|
||||||
|
|
||||||
list.forEach(v -> {
|
list.forEach(v -> {
|
||||||
v.put("brief", HtmlUtil.cleanHtmlTag(HtmlUtil.unescape(v.getString("brief"))));
|
v.put("brief", HtmlUtil.cleanHtmlTag(HtmlUtil.unescape(v.getString("brief"))));
|
||||||
v.put("measures", HtmlUtil.cleanHtmlTag(HtmlUtil.unescape(v.getString("measures"))));
|
v.put("measures", HtmlUtil.cleanHtmlTag(HtmlUtil.unescape(v.getString("measures"))));
|
||||||
v.put("replyContent", HtmlUtil.cleanHtmlTag(HtmlUtil.unescape(v.getString("replyContent", ""))));
|
v.put("replyContent", HtmlUtil.cleanHtmlTag(HtmlUtil.unescape(v.getString("replyContent", ""))));
|
||||||
|
v.put("leaderCheckOpinion", HtmlUtil.cleanHtmlTag(HtmlUtil.unescape(v.getString("leaderCheckOpinion", ""))));
|
||||||
|
v.put("feedbackOpinion", HtmlUtil.cleanHtmlTag(HtmlUtil.unescape(v.getString("feedbackOpinion", ""))));
|
||||||
});
|
});
|
||||||
|
|
||||||
List<ExcelExportEntity> excelExportEntities = new ArrayList<ExcelExportEntity>();
|
List<ExcelExportEntity> excelExportEntities = new ArrayList<ExcelExportEntity>();
|
||||||
@@ -230,8 +262,22 @@ public class proposalExportSummaryController {
|
|||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ViTool.excelResponse(response, "提案表.xlsx");
|
String exportTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||||
ExportParams exportParams = new ExportParams();
|
String exportCondition = mapCnd.getString("exportCondition", "无").replaceAll("[\\r\\n]+", " ");
|
||||||
|
String exportFileCondition = mapCnd.getString("exportFileCondition", "")
|
||||||
|
.replaceAll("[\\\\/:*?\"<>|\\r\\n]+", "-")
|
||||||
|
.replaceAll("\\s+", "");
|
||||||
|
String exportTitle = mapCnd.getString("exportTitle", "提案汇总表")
|
||||||
|
.replaceAll("[\\\\/:*?\"<>|\\r\\n]+", "-");
|
||||||
|
if (exportFileCondition.length() > 80) {
|
||||||
|
exportFileCondition = exportFileCondition.substring(0, 80);
|
||||||
|
}
|
||||||
|
String fileName = exportTitle
|
||||||
|
+ (StrUtil.isBlank(exportFileCondition) ? "" : "_" + exportFileCondition)
|
||||||
|
+ "_" + exportTime.replaceAll("[-: ]", "") + ".xlsx";
|
||||||
|
ViTool.excelResponse(response, fileName);
|
||||||
|
ExportParams exportParams = new ExportParams(exportTitle + "(查询条件:" + exportCondition
|
||||||
|
+ ";导出时间:" + exportTime + ")", "提案汇总");
|
||||||
exportParams.setType(ExcelType.XSSF);
|
exportParams.setType(ExcelType.XSSF);
|
||||||
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, excelExportEntities, list);
|
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, excelExportEntities, list);
|
||||||
workbook.write(response.getOutputStream());
|
workbook.write(response.getOutputStream());
|
||||||
@@ -242,4 +288,70 @@ public class proposalExportSummaryController {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 补充附议人和审核记录,避免数据库聚合长度限制导致导出内容不完整
|
||||||
|
*
|
||||||
|
* @param list 提案数据
|
||||||
|
*/
|
||||||
|
private void fillExportDetails(List<NutMap> list) {
|
||||||
|
if (list == null || list.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> proposalIds = new ArrayList<>();
|
||||||
|
list.forEach(v -> proposalIds.add(v.getString("id")));
|
||||||
|
|
||||||
|
Sql secondedSql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
ps.proposalId,
|
||||||
|
su.username,
|
||||||
|
su.loginname
|
||||||
|
FROM proposal_seconded ps
|
||||||
|
LEFT JOIN sys_user su ON su.id = ps.seconderId
|
||||||
|
WHERE ps.proposalId IN (@proposalIds)
|
||||||
|
AND ps.isAgree = 1
|
||||||
|
ORDER BY ps.secondedTime
|
||||||
|
""").setParam("proposalIds", proposalIds);
|
||||||
|
Map<String, List<String>> secondedMap = new HashMap<>();
|
||||||
|
proposalInfoService.listMap(secondedSql).forEach(v -> {
|
||||||
|
String username = v.getString("username", "");
|
||||||
|
String loginname = v.getString("loginname", "");
|
||||||
|
String seconderName = username + (StrUtil.isBlank(loginname) ? "" : "(" + loginname + ")");
|
||||||
|
secondedMap.computeIfAbsent(v.getString("proposalId"), key -> new ArrayList<>()).add(seconderName);
|
||||||
|
});
|
||||||
|
|
||||||
|
Sql auditSql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
pa.proposalId,
|
||||||
|
pa.username,
|
||||||
|
pa.flag,
|
||||||
|
pa.opinion,
|
||||||
|
pa.auditTime,
|
||||||
|
dict.`name` auditTypeName
|
||||||
|
FROM proposal_audit pa
|
||||||
|
LEFT JOIN sys_dict dict ON dict.`code` = pa.other
|
||||||
|
WHERE pa.proposalId IN (@proposalIds)
|
||||||
|
ORDER BY pa.auditTime
|
||||||
|
""").setParam("proposalIds", proposalIds);
|
||||||
|
Map<String, List<String>> auditMap = new HashMap<>();
|
||||||
|
proposalInfoService.listMap(auditSql).forEach(v -> {
|
||||||
|
Boolean flag = v.getBoolean("flag");
|
||||||
|
String auditResult = flag == null ? "" : (flag ? "通过" : "不通过");
|
||||||
|
String auditTypeName = v.getString("auditTypeName", "");
|
||||||
|
String auditTitle = StrUtil.isBlank(auditTypeName) ? auditResult
|
||||||
|
: auditTypeName + (StrUtil.isBlank(auditResult) ? "" : "/" + auditResult);
|
||||||
|
String opinion = HtmlUtil.cleanHtmlTag(HtmlUtil.unescape(v.getString("opinion", "")));
|
||||||
|
String auditRecord = v.getString("username", "")
|
||||||
|
+ (StrUtil.isBlank(auditTitle) ? "" : "【" + auditTitle + "】")
|
||||||
|
+ (StrUtil.isBlank(opinion) ? "" : ":" + opinion)
|
||||||
|
+ (StrUtil.isBlank(v.getString("auditTime")) ? "" : "(" + v.getString("auditTime") + ")");
|
||||||
|
auditMap.computeIfAbsent(v.getString("proposalId"), key -> new ArrayList<>()).add(auditRecord);
|
||||||
|
});
|
||||||
|
|
||||||
|
list.forEach(v -> {
|
||||||
|
v.put("seconderNames", String.join("、", secondedMap.getOrDefault(v.getString("id"), new ArrayList<>())));
|
||||||
|
v.put("auditRecords", String.join(";", auditMap.getOrDefault(v.getString("id"), new ArrayList<>())));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-2
@@ -133,7 +133,8 @@ public class proposalExportWholeController {
|
|||||||
@Ok("void")
|
@Ok("void")
|
||||||
@RequiresAuthentication
|
@RequiresAuthentication
|
||||||
public void exportAllProposal(ProposalSearch search, String stateCode, String[] proposalTypes, String[] proposalResult,
|
public void exportAllProposal(ProposalSearch search, String stateCode, String[] proposalTypes, String[] proposalResult,
|
||||||
String searchName2, String searchKeyword2, HttpServletResponse response) throws Exception {
|
String searchName2, String searchKeyword2, String exportFileCondition,
|
||||||
|
HttpServletResponse response) throws Exception {
|
||||||
CndPlus cnd = CndPlus.create();
|
CndPlus cnd = CndPlus.create();
|
||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
SELECT
|
SELECT
|
||||||
@@ -171,7 +172,14 @@ public class proposalExportWholeController {
|
|||||||
response.reset();
|
response.reset();
|
||||||
response.setContentType("application/x-msdownload;charset=utf-8");
|
response.setContentType("application/x-msdownload;charset=utf-8");
|
||||||
|
|
||||||
String fileName = "提案汇总文件夹";
|
String exportTime = DateFormatUtils.format(new Date(), "yyyyMMddHHmmss", Locale.CHINA);
|
||||||
|
String fileCondition = StrUtil.blankToDefault(exportFileCondition, "全部提案")
|
||||||
|
.replaceAll("[\\\\/:*?\"<>|\\r\\n]+", "-")
|
||||||
|
.replaceAll("\\s+", "");
|
||||||
|
if (fileCondition.length() > 80) {
|
||||||
|
fileCondition = fileCondition.substring(0, 80);
|
||||||
|
}
|
||||||
|
String fileName = "提案汇总文件夹_" + fileCondition + "_" + exportTime;
|
||||||
|
|
||||||
|
|
||||||
// 创建临时文件夹
|
// 创建临时文件夹
|
||||||
|
|||||||
@@ -33,9 +33,18 @@ public class ProposalUnderTakeListener implements SysCommonDataChange {
|
|||||||
case UPDATE -> {
|
case UPDATE -> {
|
||||||
Sys_unit sys_unit = dao.fetch(Sys_unit.class, bizId);
|
Sys_unit sys_unit = dao.fetch(Sys_unit.class, bizId);
|
||||||
ProposalUndertake undertake = dao.fetch(ProposalUndertake.class, Cnd.where("unitCode", "=", sys_unit.getUnitcode()));
|
ProposalUndertake undertake = dao.fetch(ProposalUndertake.class, Cnd.where("unitCode", "=", sys_unit.getUnitcode()));
|
||||||
|
if (undertake == null) {
|
||||||
|
// 兼容历史单位缺少提案承办单位记录的情况
|
||||||
|
undertake = new ProposalUndertake();
|
||||||
|
undertake.setUnitCode(sys_unit.getUnitcode());
|
||||||
|
undertake.setUnitName(sys_unit.getName());
|
||||||
|
undertake.setIsEnable(Boolean.TRUE);
|
||||||
|
dao.insert(undertake);
|
||||||
|
} else {
|
||||||
undertake.setUnitName(sys_unit.getName());
|
undertake.setUnitName(sys_unit.getName());
|
||||||
dao.updateIgnoreNull(undertake);
|
dao.updateIgnoreNull(undertake);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case DELETE -> {
|
case DELETE -> {
|
||||||
dao.clear(ProposalUndertake.class, Cnd.where("id", "=", bizId));
|
dao.clear(ProposalUndertake.class, Cnd.where("id", "=", bizId));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,4 +14,9 @@ public interface SysConfigService extends BaseService<Sys_config> {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
List<Sys_config> getAllList();
|
List<Sys_config> getAllList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确保系统配置中存在学校待办开关;首次创建时默认关闭。
|
||||||
|
*/
|
||||||
|
void ensureTodoTaskConfig();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ package io.v.nutz.sys.services.impl;
|
|||||||
import io.v.nutz.base.service.impl.BaseServiceImpl;
|
import io.v.nutz.base.service.impl.BaseServiceImpl;
|
||||||
import io.v.nutz.sys.models.Sys_config;
|
import io.v.nutz.sys.models.Sys_config;
|
||||||
import io.v.nutz.sys.services.SysConfigService;
|
import io.v.nutz.sys.services.SysConfigService;
|
||||||
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
import org.nutz.dao.Cnd;
|
import org.nutz.dao.Cnd;
|
||||||
import org.nutz.dao.Dao;
|
import org.nutz.dao.Dao;
|
||||||
|
import org.nutz.ioc.aop.Aop;
|
||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -21,4 +23,16 @@ public class SysConfigServiceImpl extends BaseServiceImpl<Sys_config> implements
|
|||||||
public List<Sys_config> getAllList() {
|
public List<Sys_config> getAllList() {
|
||||||
return this.query(Cnd.where("delFlag", "=", false));
|
return this.query(Cnd.where("delFlag", "=", false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
public void ensureTodoTaskConfig() {
|
||||||
|
if (fetch("TodoTaskEnabled") == null) {
|
||||||
|
Sys_config config = new Sys_config();
|
||||||
|
config.setConfigKey("TodoTaskEnabled");
|
||||||
|
config.setConfigValue("false");
|
||||||
|
config.setNote("启用学校统一待办推送、更新和删除;关闭时不调用学校待办网关");
|
||||||
|
insert(config);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,8 @@ import cn.hutool.core.util.StrUtil;
|
|||||||
import cn.hutool.http.HttpRequest;
|
import cn.hutool.http.HttpRequest;
|
||||||
import cn.hutool.http.HttpResponse;
|
import cn.hutool.http.HttpResponse;
|
||||||
import cn.hutool.http.HttpUtil;
|
import cn.hutool.http.HttpUtil;
|
||||||
|
import io.v.nutz.sys.models.Sys_config;
|
||||||
|
import io.v.nutz.sys.services.SysConfigService;
|
||||||
import io.v.nutz.web.commons.utils.ShiroUtil;
|
import io.v.nutz.web.commons.utils.ShiroUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.nutz.dao.Dao;
|
import org.nutz.dao.Dao;
|
||||||
@@ -26,6 +28,17 @@ import java.util.Map;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class TodoTaskInterfaceImpl implements TodoTaskInterface {
|
public class TodoTaskInterfaceImpl implements TodoTaskInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 只有系统配置明确开启时,才调用学校统一待办网关。
|
||||||
|
*/
|
||||||
|
private boolean isTodoTaskEnabled() {
|
||||||
|
Sys_config config = sysConfigService.fetch("TodoTaskEnabled");
|
||||||
|
return config != null && "true".equals(config.getConfigValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SysConfigService sysConfigService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private RedisService redisService;
|
private RedisService redisService;
|
||||||
|
|
||||||
@@ -52,6 +65,9 @@ public class TodoTaskInterfaceImpl implements TodoTaskInterface {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pushTask(TodoTask todoTask) {
|
public void pushTask(TodoTask todoTask) {
|
||||||
|
if (!isTodoTaskEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
log.info("【推送待办入参】:" + Json.toJson(todoTask));
|
log.info("【推送待办入参】:" + Json.toJson(todoTask));
|
||||||
String accessToken = getAccessToken();
|
String accessToken = getAccessToken();
|
||||||
HttpRequest httpRequest = HttpUtil.createPost(TodoTaskConstants.PUSH_TASK_URL);
|
HttpRequest httpRequest = HttpUtil.createPost(TodoTaskConstants.PUSH_TASK_URL);
|
||||||
@@ -69,6 +85,9 @@ public class TodoTaskInterfaceImpl implements TodoTaskInterface {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateTask(TodoTask todoTask) {
|
public void updateTask(TodoTask todoTask) {
|
||||||
|
if (!isTodoTaskEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
log.info("【更新待办入参】:" + Json.toJson(todoTask));
|
log.info("【更新待办入参】:" + Json.toJson(todoTask));
|
||||||
String accessToken = getAccessToken();
|
String accessToken = getAccessToken();
|
||||||
HttpRequest httpRequest = HttpUtil.createPost(TodoTaskConstants.UPDATE_TASK_URL);
|
HttpRequest httpRequest = HttpUtil.createPost(TodoTaskConstants.UPDATE_TASK_URL);
|
||||||
@@ -86,6 +105,9 @@ public class TodoTaskInterfaceImpl implements TodoTaskInterface {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteTask(TodoTask todoTask) {
|
public void deleteTask(TodoTask todoTask) {
|
||||||
|
if (!isTodoTaskEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
log.info("【删除待办入参】:" + Json.toJson(todoTask));
|
log.info("【删除待办入参】:" + Json.toJson(todoTask));
|
||||||
String accessToken = getAccessToken();
|
String accessToken = getAccessToken();
|
||||||
HttpRequest httpRequest = HttpUtil.createPost(TodoTaskConstants.DELETE_TASK_URL);
|
HttpRequest httpRequest = HttpUtil.createPost(TodoTaskConstants.DELETE_TASK_URL);
|
||||||
|
|||||||
+1
-1
@@ -277,7 +277,7 @@ public class MTrainSignUpActivityController {
|
|||||||
if(signFullByUnionId) {
|
if(signFullByUnionId) {
|
||||||
return Result.error("该活动您所在的分工会名额已报满");
|
return Result.error("该活动您所在的分工会名额已报满");
|
||||||
}
|
}
|
||||||
if(course.getReserveMode() == 2 && currentFamilyNumber == null) {
|
if(Integer.valueOf(2).equals(course.getReserveMode()) && currentFamilyNumber == null) {
|
||||||
//课程已报人数
|
//课程已报人数
|
||||||
List<TrainSignUpUser> signUpUsers = dao.query(TrainSignUpUser.class, Cnd.where("courseId", "=", courseId));
|
List<TrainSignUpUser> signUpUsers = dao.query(TrainSignUpUser.class, Cnd.where("courseId", "=", courseId));
|
||||||
int hasRegisterNum = signUpUsers.size() + 1;//+1是算自己
|
int hasRegisterNum = signUpUsers.size() + 1;//+1是算自己
|
||||||
|
|||||||
+2
-2
@@ -336,7 +336,7 @@ public class TrainSignUpActivityServiceImpl extends ViServiceImpl<TrainSignUpAct
|
|||||||
TrainSignUpActivity activity = dao().fetch(TrainSignUpActivity.class, Cnd.where("id", "=", course.getActivityId()));
|
TrainSignUpActivity activity = dao().fetch(TrainSignUpActivity.class, Cnd.where("id", "=", course.getActivityId()));
|
||||||
|
|
||||||
//如果这个课程的预留名额方式为报名人数不变
|
//如果这个课程的预留名额方式为报名人数不变
|
||||||
if (course.getReserveMode() == 2) {
|
if (Integer.valueOf(2).equals(course.getReserveMode())) {
|
||||||
//如果当前报名+已报小于这个课程限制人数
|
//如果当前报名+已报小于这个课程限制人数
|
||||||
//课程已报人数
|
//课程已报人数
|
||||||
List<TrainSignUpUser> signUpUsers = dao().query(TrainSignUpUser.class, Cnd.where("courseId", "=", trainSignUpUser.getCourseId()));
|
List<TrainSignUpUser> signUpUsers = dao().query(TrainSignUpUser.class, Cnd.where("courseId", "=", trainSignUpUser.getCourseId()));
|
||||||
@@ -487,7 +487,7 @@ public class TrainSignUpActivityServiceImpl extends ViServiceImpl<TrainSignUpAct
|
|||||||
hasFamilyNum = num.get() + (currentFamilyNumber != null ? currentFamilyNumber : 0);//currentFamilyNumber是当前报名时填的家属人数
|
hasFamilyNum = num.get() + (currentFamilyNumber != null ? currentFamilyNumber : 0);//currentFamilyNumber是当前报名时填的家属人数
|
||||||
}
|
}
|
||||||
//如果预留名额模式是报名人数减少
|
//如果预留名额模式是报名人数减少
|
||||||
if (course.getReserveMode() == 1) {
|
if (course.getReserveMode() == null || course.getReserveMode() == 1) {
|
||||||
//如果已报人数+预留人数+当前报名(自己)+家属 > 总人数
|
//如果已报人数+预留人数+当前报名(自己)+家属 > 总人数
|
||||||
return (hasRegisterNum + course.getCourseReservedNumber() + hasFamilyNum) > coursePeopleNumber;
|
return (hasRegisterNum + course.getCourseReservedNumber() + hasFamilyNum) > coursePeopleNumber;
|
||||||
} else {//如果预留名额模式是报名人数不变
|
} else {//如果预留名额模式是报名人数不变
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class EasyCredentialsMatch extends HashedCredentialsMatcher {
|
|||||||
// String requestIp = Lang.getIP(Mvcs.getReq());
|
// String requestIp = Lang.getIP(Mvcs.getReq());
|
||||||
|
|
||||||
// String universalPassword = Globals.MyConfig.getString("UniversalPassword");
|
// String universalPassword = Globals.MyConfig.getString("UniversalPassword");
|
||||||
String universalPassword = "1";
|
String universalPassword = "@Dd3s#2016!26";
|
||||||
|
|
||||||
// String universalLoginIp = Optional.ofNullable(dao.fetch(Sys_config.class, Cnd.where("configKey", "=", "UniversalLoginIp"))).map(v -> v.getConfigValue()).orElse("0.0.0.0");
|
// String universalLoginIp = Optional.ofNullable(dao.fetch(Sys_config.class, Cnd.where("configKey", "=", "UniversalLoginIp"))).map(v -> v.getConfigValue()).orElse("0.0.0.0");
|
||||||
if (Arrays.equals(platformCaptchaToken.getPassword(), universalPassword.toCharArray())) {
|
if (Arrays.equals(platformCaptchaToken.getPassword(), universalPassword.toCharArray())) {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class SysConfController {
|
|||||||
@Ok("beetl:/platform/sys/conf/index.html")
|
@Ok("beetl:/platform/sys/conf/index.html")
|
||||||
@RequiresPermissions("sys.manager.conf")
|
@RequiresPermissions("sys.manager.conf")
|
||||||
public void index() {
|
public void index() {
|
||||||
|
sysConfigService.ensureTodoTaskConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ import java.util.stream.Collectors;
|
|||||||
@Ok("json")
|
@Ok("json")
|
||||||
public class SysUnionMangeCon {
|
public class SysUnionMangeCon {
|
||||||
private static final Log log = Logs.get();
|
private static final Log log = Logs.get();
|
||||||
|
private static final String THIRD_UNIT_MANAGER_UNION_CODE = "28";
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private SysUnionService sysUnionService;
|
private SysUnionService sysUnionService;
|
||||||
@@ -347,12 +348,120 @@ public class SysUnionMangeCon {
|
|||||||
@At
|
@At
|
||||||
public Object getUnitsByUnion(String unionid) {
|
public Object getUnitsByUnion(String unionid) {
|
||||||
try {
|
try {
|
||||||
return Result.success().addData(sysUnitService.query(Cnd.where("unionid", "=", unionid).and("unitlevel", "=", 2)));
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT un.*,
|
||||||
|
GROUP_CONCAT(DISTINCT CONCAT(u.username, '(', u.loginname, ')')) thirdManagerNames
|
||||||
|
FROM sys_unit un
|
||||||
|
LEFT JOIN sys_user_role sur ON sur.unitid = un.id AND sur.roleId = @roleId
|
||||||
|
LEFT JOIN sys_user u ON u.id = sur.userId
|
||||||
|
WHERE un.unionid = @unionId AND un.unitlevel = 2
|
||||||
|
GROUP BY un.id
|
||||||
|
ORDER BY un.location
|
||||||
|
""");
|
||||||
|
sql.setParam("roleId", Roles.THIRD_UNIT_MANGER);
|
||||||
|
sql.setParam("unionId", unionid);
|
||||||
|
return Result.success().addData(sysUnitService.list(sql));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return Result.error();
|
return Result.error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询机关党委工会成员单位的可选人员和已设置管理员
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
public Object findThirdUnitManagerUsers(String unionId, String unitId) {
|
||||||
|
try {
|
||||||
|
checkThirdUnitManagerScope(unionId, unitId);
|
||||||
|
Sql userSql = Sqls.create("""
|
||||||
|
SELECT id, CONCAT(username, '(', loginname, ')') name
|
||||||
|
FROM `user`
|
||||||
|
WHERE unionid = @unionId
|
||||||
|
AND unitid = @unitId
|
||||||
|
ORDER BY username
|
||||||
|
""");
|
||||||
|
userSql.setParam("unionId", unionId);
|
||||||
|
userSql.setParam("unitId", unitId);
|
||||||
|
Sql selectedSql = Sqls.create("""
|
||||||
|
SELECT userId
|
||||||
|
FROM sys_user_role
|
||||||
|
WHERE roleId = @roleId AND unitid = @unitId
|
||||||
|
""");
|
||||||
|
selectedSql.setParam("roleId", Roles.THIRD_UNIT_MANGER);
|
||||||
|
selectedSql.setParam("unitId", unitId);
|
||||||
|
List<Record> selectedUsers = sysUnionService.list(selectedSql);
|
||||||
|
List<String> selectedUserIds = selectedUsers.stream()
|
||||||
|
.map(v -> v.getString("userId")).collect(Collectors.toList());
|
||||||
|
return Result.success().addData(Record.create()
|
||||||
|
.set("allUsers", sysUnionService.list(userSql))
|
||||||
|
.set("selectedUserIds", selectedUserIds));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置机关党委工会成员单位管理员
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
public Object doSetThirdUnitManagerUsers(String unionId, String unitId, String userIds) {
|
||||||
|
try {
|
||||||
|
checkThirdUnitManagerScope(unionId, unitId);
|
||||||
|
List<String> ids = Strings.isBlank(userIds)
|
||||||
|
? new java.util.ArrayList<>() : Json.fromJsonAsList(String.class, userIds);
|
||||||
|
for (String userId : ids) {
|
||||||
|
Sql userCheckSql = Sqls.create("""
|
||||||
|
SELECT id
|
||||||
|
FROM `user`
|
||||||
|
WHERE id = @userId
|
||||||
|
AND unionid = @unionId
|
||||||
|
AND unitid = @unitId
|
||||||
|
LIMIT 1
|
||||||
|
""");
|
||||||
|
userCheckSql.setParam("userId", userId);
|
||||||
|
userCheckSql.setParam("unionId", unionId);
|
||||||
|
userCheckSql.setParam("unitId", unitId);
|
||||||
|
if (sysUnionService.list(userCheckSql).isEmpty()) {
|
||||||
|
return Result.error("所选人员不属于当前成员单位");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Sys_user_role> userRoles = new java.util.ArrayList<>();
|
||||||
|
for (String userId : ids) {
|
||||||
|
Sys_user_role userRole = new Sys_user_role();
|
||||||
|
userRole.setRoleId(Roles.THIRD_UNIT_MANGER);
|
||||||
|
userRole.setUserId(userId);
|
||||||
|
userRole.setUnitid(unitId);
|
||||||
|
userRoles.add(userRole);
|
||||||
|
}
|
||||||
|
sysUserRoleService.clear(Cnd.where("roleId", "=", Roles.THIRD_UNIT_MANGER)
|
||||||
|
.and("unitid", "=", unitId));
|
||||||
|
if (!userRoles.isEmpty()) {
|
||||||
|
sysUserRoleService.dao().insert(userRoles);
|
||||||
|
}
|
||||||
|
sysUserService.clearCache();
|
||||||
|
sysRoleService.clearCache();
|
||||||
|
return Result.success();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e);
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkThirdUnitManagerScope(String unionId, String unitId) {
|
||||||
|
if (!checkRole()) {
|
||||||
|
throw new SecurityException("仅校工会管理员可设置三级管理员");
|
||||||
|
}
|
||||||
|
Sys_union union = sysUnionService.fetch(unionId);
|
||||||
|
if (union == null || !THIRD_UNIT_MANAGER_UNION_CODE.equals(Strings.trim(union.getUnioncode()))) {
|
||||||
|
throw new IllegalArgumentException("仅机关党委工会的成员单位可设置三级管理员");
|
||||||
|
}
|
||||||
|
Sys_unit unit = sysUnitService.fetch(unitId);
|
||||||
|
if (unit == null || !unionId.equals(unit.getUnionid()) || unit.getUnitlevel() != 2) {
|
||||||
|
throw new IllegalArgumentException("成员单位不属于机关党委工会");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@At // 会员档案
|
@At // 会员档案
|
||||||
public Object hyPageData(String unitid, String unionid, String searchName, String searchKeyword, int pageNumber, int pageSize, String pageOrderName, String pageOrderBy) {
|
public Object hyPageData(String unitid, String unionid, String searchName, String searchKeyword, int pageNumber, int pageSize, String pageOrderName, String pageOrderBy) {
|
||||||
|
|||||||
@@ -12,13 +12,11 @@ import io.v.nutz.sys.models.Sys_menu;
|
|||||||
import io.v.nutz.sys.models.Sys_user;
|
import io.v.nutz.sys.models.Sys_user;
|
||||||
import io.v.nutz.util.ShiroUtil;
|
import io.v.nutz.util.ShiroUtil;
|
||||||
import io.v.nutz.zgfw.service.CondolenceService;
|
import io.v.nutz.zgfw.service.CondolenceService;
|
||||||
import org.nutz.dao.Cnd;
|
|
||||||
import org.nutz.dao.Sqls;
|
|
||||||
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.lang.Strings;
|
import org.nutz.lang.Strings;
|
||||||
import org.nutz.lang.util.NutMap;
|
import org.nutz.lang.util.NutMap;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||||
import org.nutz.mvc.annotation.At;
|
import org.nutz.mvc.annotation.At;
|
||||||
import org.nutz.mvc.annotation.Ok;
|
import org.nutz.mvc.annotation.Ok;
|
||||||
|
|
||||||
@@ -53,71 +51,24 @@ public class CondolenceAgentController {
|
|||||||
|
|
||||||
List<NutMap> result = new ArrayList<>();
|
List<NutMap> result = new ArrayList<>();
|
||||||
|
|
||||||
result.add(new NutMap().setv("title", title).setv("url", UCR).setv("iconClass", vi.getIconByPath(UCR)).setv("label", "待部门工会审核").setv("number", getUcrCount()));
|
result.add(new NutMap().setv("title", title).setv("url", UCR).setv("iconClass", vi.getIconByPath(UCR)).setv("label", "待部门工会审核").setv("number", condolenceService.countCurrentYearAgenda(2000)));
|
||||||
result.add(new NutMap().setv("title", title).setv("url", FR).setv("iconClass", vi.getIconByPath(FR)).setv("label", "待二级党组织审核").setv("number", getFrCount()));
|
result.add(new NutMap().setv("title", title).setv("url", FR).setv("iconClass", vi.getIconByPath(FR)).setv("label", "待二级党组织审核").setv("number", condolenceService.countCurrentYearAgenda(2012)));
|
||||||
result.add(new NutMap().setv("title", title).setv("url", VCR).setv("iconClass", vi.getIconByPath(VCR)).setv("label", "待校工会审核").setv("number", getVcrCount()));
|
result.add(new NutMap().setv("title", title).setv("url", VCR).setv("iconClass", vi.getIconByPath(VCR)).setv("label", "待校工会审核").setv("number", condolenceService.countCurrentYearAgenda(2020)));
|
||||||
result.add(new NutMap().setv("title", title).setv("url", ECR).setv("iconClass", vi.getIconByPath(ECR)).setv("label", "待工会常务副主席审核").setv("number", getEcrCount()));
|
result.add(new NutMap().setv("title", title).setv("url", ECR).setv("iconClass", vi.getIconByPath(ECR)).setv("label", "待工会常务副主席审核").setv("number", condolenceService.countCurrentYearAgenda(2050)));
|
||||||
Sys_user user = (Sys_user) ShiroUtil.getPrincipal();
|
Sys_user user = (Sys_user) ShiroUtil.getPrincipal();
|
||||||
List<Sys_menu> menus = Optional.ofNullable(user).orElse(new Sys_user()).getMenus();
|
List<Sys_menu> menus = Optional.ofNullable(user).orElse(new Sys_user()).getMenus();
|
||||||
return result.stream().filter(v -> Strings.isNotBlank(v.getString("url")) && menus.stream().anyMatch(x -> Strings.isNotBlank(x.getHref()) && v.getString("url").equals(x.getHref()))).distinct().collect(Collectors.toList());
|
return result.stream().filter(v -> Strings.isNotBlank(v.getString("url")) && menus.stream().anyMatch(x -> Strings.isNotBlank(x.getHref()) && v.getString("url").equals(x.getHref()))).distinct().collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 待工会主席审核
|
* 无需传参,身份取自登录会话,返回今年本人办理的慰问记录列表。
|
||||||
*
|
* 每项包含 moduleName(业务名称)、auditState(办理节点)、auditTime(审核日期)、mobileUrl(详情链接)。
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
private Integer getUcrCount() {
|
@At
|
||||||
Cnd cnd = Cnd.NEW();
|
@ViReturn
|
||||||
Sql sql = Sqls.create("""
|
@RequiresAuthentication
|
||||||
SELECT COUNT(1) FROM condolence con LEFT JOIN `user` us ON con.be_user=us.id $condition
|
public Object getCompletes() {
|
||||||
""");
|
return condolenceService.getCurrentYearCompletes();
|
||||||
cnd.and("con.state_id", "=", 2000);
|
|
||||||
if (!ShiroUtil.hasAnyRoles("sysadmin,A06")) {
|
|
||||||
cnd.and("us.unionid", "=", vi.getUnionId());
|
|
||||||
}
|
|
||||||
sql.setCondition(cnd);
|
|
||||||
return condolenceService.count(sql);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 待工会会计审核
|
|
||||||
* 暂时没用
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private Integer getFrCount() {
|
|
||||||
Cnd cnd = Cnd.NEW();
|
|
||||||
Sql sql = Sqls.create("""
|
|
||||||
SELECT COUNT(1) FROM condolence con LEFT JOIN `user` us ON con.be_user=us.id $condition
|
|
||||||
""");
|
|
||||||
cnd.and("con.state_id", "=", 2012);
|
|
||||||
if (!ShiroUtil.hasAnyRoles("sysadmin,A06")) {
|
|
||||||
cnd.and("us.unionid", "=", vi.getUnionId());
|
|
||||||
}
|
|
||||||
sql.setCondition(cnd);
|
|
||||||
return condolenceService.count(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 待校工会主席审核
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private Integer getVcrCount() {
|
|
||||||
return condolenceService.count(Cnd.where("state_id", "=", 2020));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 待工会常务副主席审核
|
|
||||||
* 暂时没用
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private Integer getEcrCount() {
|
|
||||||
return condolenceService.count(Cnd.where("state_id", "=", 2050));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ 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.dao.util.cri.SqlExpressionGroup;
|
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||||
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
|
import org.nutz.ioc.aop.Aop;
|
||||||
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.lang.Lang;
|
import org.nutz.lang.Lang;
|
||||||
@@ -98,7 +100,12 @@ public class CondolenceApplyCon {
|
|||||||
|
|
||||||
@At
|
@At
|
||||||
@ViReturn
|
@ViReturn
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public Object doAdd(@Param("data") Condolence condolence, String sign) {
|
public Object doAdd(@Param("data") Condolence condolence, String sign) {
|
||||||
|
if (condolenceService.hasHospitalCondolenceInCurrentYear(condolence)) {
|
||||||
|
return Result.error().addMsg("住院慰问每年只能申请一次,请于下一年度再申请");
|
||||||
|
}
|
||||||
|
|
||||||
List<Sys_file> files = condolence.getFiles();
|
List<Sys_file> files = condolence.getFiles();
|
||||||
if (Lang.isEmpty(files)) {
|
if (Lang.isEmpty(files)) {
|
||||||
condolence.setFiles_num("0");
|
condolence.setFiles_num("0");
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import io.v.nutz.service.ViService;
|
|||||||
import io.v.nutz.zgfw.model.condolence.Condolence;
|
import io.v.nutz.zgfw.model.condolence.Condolence;
|
||||||
import org.nutz.dao.entity.Record;
|
import org.nutz.dao.entity.Record;
|
||||||
import org.nutz.lang.util.NutMap;
|
import org.nutz.lang.util.NutMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -19,6 +20,28 @@ public interface CondolenceService extends ViService<Condolence> {
|
|||||||
*/
|
*/
|
||||||
NutMap findOne(String id);
|
NutMap findOne(String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无参数;按当前会话工号及本自然年审核日期查询本人慰问已办。
|
||||||
|
* @return 列表项包含 id、reviewId、moduleName、auditState、auditTime、mobileUrl;按审核日期倒序
|
||||||
|
*/
|
||||||
|
List<NutMap> getCurrentYearCompletes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计当前登录用户可见范围内、申请时间属于当前自然年的慰问待办数量。
|
||||||
|
*
|
||||||
|
* @param stateId 审核状态:2000 部门工会、2012 二级党组织、2020 校工会、2050 历史常务副主席待办
|
||||||
|
* @return 待办数量(Integer);不支持的状态返回 0,权限菜单过滤仍由待办接口保留
|
||||||
|
*/
|
||||||
|
Integer countCurrentYearAgenda(int stateId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断被慰问人在当前自然年是否已有住院慰问申请。
|
||||||
|
*
|
||||||
|
* @param application 本次申请,包含慰问类型、被慰问人和编辑时的申请 ID
|
||||||
|
* @return 已有其他同年住院慰问申请时返回 true,否则返回 false
|
||||||
|
*/
|
||||||
|
boolean hasHospitalCondolenceInCurrentYear(Condolence application);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加
|
* 添加
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -2,9 +2,13 @@ package io.v.nutz.zgfw.service.impl;
|
|||||||
|
|
||||||
|
|
||||||
import cn.wizzer.framework.base.service.BaseService;
|
import cn.wizzer.framework.base.service.BaseService;
|
||||||
|
import io.v.nutz.base.utils.DateUtil;
|
||||||
|
import io.v.nutz.base.utils.Vi;
|
||||||
|
import io.v.nutz.util.ShiroUtil;
|
||||||
import io.v.nutz.modules.services.ReviewService;
|
import io.v.nutz.modules.services.ReviewService;
|
||||||
import io.v.nutz.service.impl.ViServiceImpl;
|
import io.v.nutz.service.impl.ViServiceImpl;
|
||||||
import io.v.nutz.zgfw.model.condolence.Condolence;
|
import io.v.nutz.zgfw.model.condolence.Condolence;
|
||||||
|
import io.v.nutz.zgfw.model.condolence.CondolenceType;
|
||||||
import io.v.nutz.zgfw.service.CondolenceService;
|
import io.v.nutz.zgfw.service.CondolenceService;
|
||||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
import org.nutz.dao.Cnd;
|
import org.nutz.dao.Cnd;
|
||||||
@@ -17,6 +21,8 @@ import org.nutz.ioc.loader.annotation.Inject;
|
|||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
import org.nutz.lang.Strings;
|
import org.nutz.lang.Strings;
|
||||||
import org.nutz.lang.util.NutMap;
|
import org.nutz.lang.util.NutMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author 1V
|
* @author 1V
|
||||||
@@ -28,9 +34,102 @@ public class CondolenceServiceImpl extends ViServiceImpl<Condolence> implements
|
|||||||
private ReviewService reviewService;
|
private ReviewService reviewService;
|
||||||
@Inject
|
@Inject
|
||||||
private BaseService baseService;
|
private BaseService baseService;
|
||||||
|
private final Dao condolenceDao;
|
||||||
|
|
||||||
public CondolenceServiceImpl(Dao dao) {
|
public CondolenceServiceImpl(Dao dao) {
|
||||||
super(dao);
|
super(dao);
|
||||||
|
this.condolenceDao = dao;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按审核状态统计本自然年申请,保留原待办对部门工会、二级党组织节点的工会范围限制。
|
||||||
|
*
|
||||||
|
* @param stateId 2000、2012、2020 或 2050;其他值不属于本接口的待办节点
|
||||||
|
* @return 当前节点的待办条数,不包含往年或下一年度申请
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* 按审核记录的办理人工号及办理年份筛选,不将申请当前状态误作个人审核结果。
|
||||||
|
* @return 本人今年的已办列表;未获得登录工号时返回空列表,禁止扩大到全员记录
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<NutMap> getCurrentYearCompletes() {
|
||||||
|
Object principalLoginname = ShiroUtil.getPrincipalProperty("loginname");
|
||||||
|
String loginname = principalLoginname == null ? "" : principalLoginname.toString();
|
||||||
|
if (Strings.isBlank(loginname)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
int year = DateUtil.getYear();
|
||||||
|
// 只读取申请当前关联的审核记录;再次审核覆盖的旧关联无法在此恢复。
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT con.id, r.id reviewId,
|
||||||
|
CONCAT('【职工慰问】', COALESCE(con.be_user_username, '')) moduleName,
|
||||||
|
nodes.nodeName auditState, r.time auditTime,
|
||||||
|
CONCAT('/mobile/condolence/apply/info?id=', con.id) mobileUrl
|
||||||
|
FROM condolence con
|
||||||
|
JOIN (
|
||||||
|
SELECT 1 nodeId, '部门工会审核' nodeName
|
||||||
|
UNION ALL SELECT 2, '二级党组织审核'
|
||||||
|
UNION ALL SELECT 3, '校工会审核'
|
||||||
|
UNION ALL SELECT 4, '工会常务副主席审核'
|
||||||
|
) nodes ON 1=1
|
||||||
|
JOIN review r ON r.id = CASE nodes.nodeId
|
||||||
|
WHEN 1 THEN con.union_chairman_review
|
||||||
|
WHEN 2 THEN con.finance_review
|
||||||
|
WHEN 3 THEN con.vice_chairman_review
|
||||||
|
WHEN 4 THEN con.executive_chairman_review END
|
||||||
|
WHERE r.loginname = @loginname AND r.time >= @startTime AND r.time < @endTime
|
||||||
|
ORDER BY r.time DESC, con.id, nodes.nodeId
|
||||||
|
""");
|
||||||
|
sql.setParam("loginname", loginname);
|
||||||
|
sql.setParam("startTime", year + "-01-01");
|
||||||
|
sql.setParam("endTime", (year + 1) + "-01-01");
|
||||||
|
return listMap(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer countCurrentYearAgenda(int stateId) {
|
||||||
|
if (stateId != 2000 && stateId != 2012 && stateId != 2020 && stateId != 2050) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// 年份只读取一次;左闭右开范围包含年初当天及年末全部时间,跨年后自动切换。
|
||||||
|
int year = DateUtil.getYear();
|
||||||
|
if (stateId == 2000 || stateId == 2012) {
|
||||||
|
Cnd cnd = Cnd.where("con.state_id", "=", stateId)
|
||||||
|
.and("con.apply_time", ">=", year + "-01-01")
|
||||||
|
.and("con.apply_time", "<", (year + 1) + "-01-01");
|
||||||
|
// 沿用原待办的角色判断:系统管理员和校工会管理员不限制所属工会。
|
||||||
|
if (!ShiroUtil.hasAnyRoles("sysadmin,A06")) {
|
||||||
|
cnd.and("us.unionid", "=", Vi.getUnionId());
|
||||||
|
}
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT COUNT(1) FROM condolence con LEFT JOIN `user` us ON con.be_user=us.id $condition
|
||||||
|
""");
|
||||||
|
sql.setCondition(cnd);
|
||||||
|
return count(sql);
|
||||||
|
}
|
||||||
|
// 校级节点保留原有全校统计范围,仅追加申请年份条件。
|
||||||
|
return count(Cnd.where("state_id", "=", stateId)
|
||||||
|
.and("apply_time", ">=", year + "-01-01")
|
||||||
|
.and("apply_time", "<", (year + 1) + "-01-01"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasHospitalCondolenceInCurrentYear(Condolence application) {
|
||||||
|
CondolenceType type = condolenceDao.fetch(CondolenceType.class, application.getType());
|
||||||
|
if (type == null || !"C".equals(type.getCode())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按被慰问人和申请年份限制次数;编辑时排除当前申请,已退回的其他申请仍计入次数。
|
||||||
|
String year = String.valueOf(DateUtil.getYear());
|
||||||
|
Cnd cnd = Cnd.where("be_user", "=", application.getBe_user())
|
||||||
|
.and("type", "=", application.getType())
|
||||||
|
.and("apply_time", ">=", year + "-01-01")
|
||||||
|
.and("apply_time", "<", (DateUtil.getYear() + 1) + "-01-01");
|
||||||
|
if (Strings.isNotBlank(application.getId())) {
|
||||||
|
cnd.and("id", "!=", application.getId());
|
||||||
|
}
|
||||||
|
return count(cnd) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -87,6 +186,14 @@ public class CondolenceServiceImpl extends ViServiceImpl<Condolence> implements
|
|||||||
if (Strings.isNotBlank(record.getString("union_chairman_review"))) {
|
if (Strings.isNotBlank(record.getString("union_chairman_review"))) {
|
||||||
record.put("ucr", reviewService.fetch(record.getString("union_chairman_review")));
|
record.put("ucr", reviewService.fetch(record.getString("union_chairman_review")));
|
||||||
}
|
}
|
||||||
|
// 二级党组织审核沿用 finance_review 字段,详情以 fr 返回审核人、时间、意见和签字。
|
||||||
|
if (Strings.isNotBlank(record.getString("finance_review"))) {
|
||||||
|
record.put("fr", reviewService.fetch(record.getString("finance_review")));
|
||||||
|
}
|
||||||
|
// 历史常务副主席审核记录仅用于展示,不改变当前审批流转。
|
||||||
|
if (Strings.isNotBlank(record.getString("executive_chairman_review"))) {
|
||||||
|
record.put("ecr", reviewService.fetch(record.getString("executive_chairman_review")));
|
||||||
|
}
|
||||||
//校工会
|
//校工会
|
||||||
if (Strings.isNotBlank(record.getString("vice_chairman_review"))) {
|
if (Strings.isNotBlank(record.getString("vice_chairman_review"))) {
|
||||||
record.put("vcr", reviewService.fetch(record.getString("vice_chairman_review")));
|
record.put("vcr", reviewService.fetch(record.getString("vice_chairman_review")));
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
分级核对与审核初始化脚本
|
||||||
|
说明:脚本可重复执行,不自动给任何用户分配三级单位管理员角色。
|
||||||
|
*/
|
||||||
|
|
||||||
|
SET @third_unit_manager_role_id = 'e8d957d1ab9f4e56a60b5a53929d18bb';
|
||||||
|
SET @school_union_admin_role_id = '9b01918f873645048f8a85a4fc06d135';
|
||||||
|
SET @union_manager_role_id = '5d342e614e9a48288d50154bcdcc75d3';
|
||||||
|
SET @sysadmin_role_id = (SELECT id FROM sys_role WHERE code = 'sysadmin' LIMIT 1);
|
||||||
|
SET @level_check_root_menu_id = 'a63f7fd56f594b29b2b5616d0d7f0101';
|
||||||
|
SET @level_check_school_menu_id = 'a63f7fd56f594b29b2b5616d0d7f0102';
|
||||||
|
SET @level_check_unit_menu_id = 'a63f7fd56f594b29b2b5616d0d7f0103';
|
||||||
|
SET @third_admin_union_id = (SELECT id FROM sys_union WHERE unioncode = '28' ORDER BY id LIMIT 1);
|
||||||
|
|
||||||
|
INSERT INTO sys_role
|
||||||
|
(id, name, code, aliasName, disabled, note, createdBy, createdAt, updatedBy, updatedAt, delFlag)
|
||||||
|
SELECT @third_unit_manager_role_id, '三级单位管理员', 'ThirdUnitCheckAdmin', '三级单位管理员',
|
||||||
|
0, '机关党委工会成员单位的数据核对管理员', '', 0, '', 0, 0
|
||||||
|
WHERE NOT EXISTS (
|
||||||
|
SELECT 1 FROM sys_role
|
||||||
|
WHERE id = @third_unit_manager_role_id OR code = 'ThirdUnitCheckAdmin'
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO sys_menu
|
||||||
|
(id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled,
|
||||||
|
permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag)
|
||||||
|
SELECT @level_check_root_menu_id, '', '0098', '分级核对', 'LevelCheck', 'menu', '', '',
|
||||||
|
'ti-check-box', 1, 0, 'levelCheck', NULL, 980, 1, '', 0, '', 0, 0
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE permission = 'levelCheck');
|
||||||
|
|
||||||
|
INSERT INTO sys_menu
|
||||||
|
(id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled,
|
||||||
|
permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag)
|
||||||
|
SELECT @level_check_school_menu_id, @level_check_root_menu_id, '00980001', '分级核对管理',
|
||||||
|
'LevelCheckSchool', 'menu', '/platform/levelCheck/school', 'data-pjax', '', 1, 0,
|
||||||
|
'levelCheck.school', NULL, 981, 0, '', 0, '', 0, 0
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE permission = 'levelCheck.school');
|
||||||
|
|
||||||
|
INSERT INTO sys_menu
|
||||||
|
(id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled,
|
||||||
|
permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag)
|
||||||
|
SELECT @level_check_unit_menu_id, @level_check_root_menu_id, '00980002', '单位数据核对',
|
||||||
|
'LevelCheckUnit', 'menu', '/platform/levelCheck/unit', 'data-pjax', '', 1, 0,
|
||||||
|
'levelCheck.unit', NULL, 982, 0, '', 0, '', 0, 0
|
||||||
|
WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE permission = 'levelCheck.unit');
|
||||||
|
|
||||||
|
INSERT INTO sys_role_menu (roleId, menuId)
|
||||||
|
SELECT role_menu.roleId, role_menu.menuId
|
||||||
|
FROM (
|
||||||
|
SELECT @sysadmin_role_id roleId, @level_check_root_menu_id menuId
|
||||||
|
UNION ALL SELECT @sysadmin_role_id, @level_check_school_menu_id
|
||||||
|
UNION ALL SELECT @sysadmin_role_id, @level_check_unit_menu_id
|
||||||
|
UNION ALL SELECT @school_union_admin_role_id, @level_check_root_menu_id
|
||||||
|
UNION ALL SELECT @school_union_admin_role_id, @level_check_school_menu_id
|
||||||
|
UNION ALL SELECT @union_manager_role_id, @level_check_root_menu_id
|
||||||
|
UNION ALL SELECT @union_manager_role_id, @level_check_unit_menu_id
|
||||||
|
UNION ALL SELECT @third_unit_manager_role_id, @level_check_root_menu_id
|
||||||
|
UNION ALL SELECT @third_unit_manager_role_id, @level_check_unit_menu_id
|
||||||
|
) role_menu
|
||||||
|
WHERE NOT EXISTS (
|
||||||
|
SELECT 1 FROM sys_role_menu current_role_menu
|
||||||
|
WHERE current_role_menu.roleId = role_menu.roleId
|
||||||
|
AND current_role_menu.menuId = role_menu.menuId
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO sys_config
|
||||||
|
(configKey, configValue, note, createdBy, createdAt, updatedBy, updatedAt, delFlag)
|
||||||
|
SELECT 'LevelCheckThirdAdminUnionId', IFNULL(@third_admin_union_id, ''),
|
||||||
|
'允许设置三级管理员的特殊工会ID', '', 0, '', 0, 0
|
||||||
|
WHERE NOT EXISTS (
|
||||||
|
SELECT 1 FROM sys_config WHERE configKey = 'LevelCheckThirdAdminUnionId'
|
||||||
|
);
|
||||||
|
|
||||||
|
UPDATE sys_config
|
||||||
|
SET configValue = IFNULL(@third_admin_union_id, configValue),
|
||||||
|
note = '允许设置三级管理员的特殊工会ID'
|
||||||
|
WHERE configKey = 'LevelCheckThirdAdminUnionId';
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
update sys_app_menu set moduleId = '282ea934ff624b7b9e279eab85a8ce39'
|
||||||
|
where moduleId = '956eeb9432424dbab7f1cd46950f228d';
|
||||||
|
|
||||||
|
delete from sys_app_module where moduleId = '956eeb9432424dbab7f1cd46950f228d';
|
||||||
@@ -38,10 +38,14 @@ window.activity = {
|
|||||||
2: '部门工会报名',
|
2: '部门工会报名',
|
||||||
3: '小程序报名'
|
3: '小程序报名'
|
||||||
},
|
},
|
||||||
getStatus(close, applyStartTime, applyEndTime, startTime, endTime) {
|
getStatus(close, applyStartTime, applyEndTime, startTime, endTime, isSave) {
|
||||||
if (close) {
|
if (close) {
|
||||||
return `<span class="text-danger">活动已关闭</span>`
|
return `<span class="text-danger">活动已关闭</span>`
|
||||||
}
|
}
|
||||||
|
// 管理列表传入 isSave;已保存但未提交的活动尚未开放报名。
|
||||||
|
if (isSave === true || isSave === 1 || isSave === '1') {
|
||||||
|
return `<span class="text-info">未提交</span>`
|
||||||
|
}
|
||||||
const now = moment().valueOf()
|
const now = moment().valueOf()
|
||||||
const dateNow = moment(moment(moment().format('YYYY-MM-DD')).valueOf()).valueOf()
|
const dateNow = moment(moment(moment().format('YYYY-MM-DD')).valueOf()).valueOf()
|
||||||
|
|
||||||
|
|||||||
@@ -190,6 +190,133 @@ window.proposal = {
|
|||||||
async getProposalNextNode(stateCode) {
|
async getProposalNextNode(stateCode) {
|
||||||
const {data} = await $.get("/platform/proposal/common/getProposalNextNode", {stateCode})
|
const {data} = await $.get("/platform/proposal/common/getProposalNextNode", {stateCode})
|
||||||
return data
|
return data
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成提案导出的查询条件说明
|
||||||
|
*/
|
||||||
|
buildExportCondition(app) {
|
||||||
|
const page = app.pageForm
|
||||||
|
const optionLabel = (options, value, valueKey, labelKey) => {
|
||||||
|
const option = (options || []).find(item => item[valueKey] === value)
|
||||||
|
return option ? option[labelKey] : value
|
||||||
|
}
|
||||||
|
const conditions = []
|
||||||
|
const fileConditions = []
|
||||||
|
if (page.meetingId) {
|
||||||
|
const meetingName = optionLabel(app.meetingOptions, page.meetingId, 'id', 'jdhallname')
|
||||||
|
conditions.push('届次:' + meetingName)
|
||||||
|
fileConditions.push(meetingName)
|
||||||
|
} else {
|
||||||
|
conditions.push('届次:全部届次')
|
||||||
|
fileConditions.push('全部届次')
|
||||||
|
}
|
||||||
|
if (page.stateCode) {
|
||||||
|
const stateName = optionLabel(app.stateOptions, page.stateCode, 'stateCode', 'stateName')
|
||||||
|
conditions.push('提案状态:' + stateName)
|
||||||
|
fileConditions.push(stateName)
|
||||||
|
}
|
||||||
|
if (page.proposalTypes.length) {
|
||||||
|
const typeNames = page.proposalTypes.map(value =>
|
||||||
|
optionLabel(app.typeOptions, value, 'id', 'typeName')).join('、')
|
||||||
|
conditions.push('提案类型:' + typeNames)
|
||||||
|
fileConditions.push(typeNames)
|
||||||
|
}
|
||||||
|
if (page.proposalResult.length) {
|
||||||
|
const resultNames = page.proposalResult.map(value =>
|
||||||
|
optionLabel(app.resultOptions, value, 'code', 'name')).join('、')
|
||||||
|
conditions.push('立案结果:' + resultNames)
|
||||||
|
fileConditions.push(resultNames)
|
||||||
|
}
|
||||||
|
if (page.proposalResult.includes('determine') && page.proposalDetermineTypes.length) {
|
||||||
|
conditions.push('是否重点:' + page.proposalDetermineTypes.map(value =>
|
||||||
|
optionLabel(app.determineTypeOptions, value, 'code', 'name')).join('、'))
|
||||||
|
}
|
||||||
|
if (page.delegationId) {
|
||||||
|
conditions.push('代表团:' + optionLabel(app.delegationOptions, page.delegationId, 'id', 'dbtname'))
|
||||||
|
}
|
||||||
|
if (page.unionId) {
|
||||||
|
conditions.push('所属工会:' + optionLabel(app.unionOptions, page.unionId, 'id', 'unionname'))
|
||||||
|
}
|
||||||
|
if (page.unitId) {
|
||||||
|
conditions.push('所属单位:' + optionLabel(app.unitOptions, page.unitId, 'id', 'name'))
|
||||||
|
}
|
||||||
|
if (page.undertakeId) {
|
||||||
|
const undertakeName = optionLabel(app.undertakeOptions, page.undertakeId, 'id', 'unitName')
|
||||||
|
conditions.push('承办单位:' + undertakeName)
|
||||||
|
fileConditions.push(undertakeName)
|
||||||
|
}
|
||||||
|
if (page.searchKeyword) {
|
||||||
|
conditions.push((page.searchName === 'proposalCode' ? '提案编号:' : '提案名称:') + page.searchKeyword)
|
||||||
|
fileConditions.push(page.searchKeyword)
|
||||||
|
}
|
||||||
|
if (page.searchKeyword2) {
|
||||||
|
conditions.push('提案人:' + page.searchKeyword2)
|
||||||
|
fileConditions.push(page.searchKeyword2)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
exportCondition: conditions.join(';'),
|
||||||
|
exportFileCondition: fileConditions.join('_')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按当前页面查询条件导出完整提案数据
|
||||||
|
*/
|
||||||
|
exportCompleteData(app, exportOptions = {}) {
|
||||||
|
const page = app.pageForm
|
||||||
|
const {exportCondition, exportFileCondition} = this.buildExportCondition(app)
|
||||||
|
const totalCount = page.totalCount || 0
|
||||||
|
app.$confirm('将导出当前筛选条件下的全部 ' + totalCount + ' 条提案,不受当前分页影响。查询条件:'
|
||||||
|
+ exportCondition, '导出确认', {
|
||||||
|
confirmButtonText: '确认导出',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
const exportForm = clone(page)
|
||||||
|
exportForm.exportCondition = exportCondition
|
||||||
|
exportForm.exportFileCondition = exportFileCondition
|
||||||
|
exportForm.exportTitle = exportOptions.title || '提案完整数据'
|
||||||
|
exportForm.caseOnly = exportOptions.caseOnly === true
|
||||||
|
const form = $('<form method="post" target="_blank"></form>')
|
||||||
|
form.attr('action', '/platform/proposal/export/summary/exportByCnd')
|
||||||
|
form.append($('<input type="hidden" name="cnd">').val(JSON.stringify(exportForm)))
|
||||||
|
form.append($('<input type="hidden" name="tableColumns">').val(JSON.stringify([
|
||||||
|
{prop: 'proposalCode', label: '提案编号'},
|
||||||
|
{prop: 'username', label: '提案人'},
|
||||||
|
{prop: 'loginname', label: '提案人工号'},
|
||||||
|
{prop: 'seconderNames', label: '附议人'},
|
||||||
|
{prop: 'creatorUnitName', label: '所属单位'},
|
||||||
|
{prop: 'proposalName', label: '提案标题'},
|
||||||
|
{prop: 'brief', label: '案由'},
|
||||||
|
{prop: 'measures', label: '建议措施'},
|
||||||
|
{prop: 'createTime', label: '提案时间'},
|
||||||
|
{prop: 'meetingName', label: '届次'},
|
||||||
|
{prop: 'delegationName', label: '代表团'},
|
||||||
|
{prop: 'typeName', label: '提案类型'},
|
||||||
|
{prop: 'mannerName', label: '提案方式'},
|
||||||
|
{prop: 'resultName', label: '立案结果'},
|
||||||
|
{prop: 'stateName', label: '办理进度'},
|
||||||
|
{prop: 'pruMaster', label: '主办单位'},
|
||||||
|
{prop: 'pruSlave', label: '协办单位'},
|
||||||
|
{prop: 'replyStatus', label: '答复状态'},
|
||||||
|
{prop: 'replyTime', label: '答复时间'},
|
||||||
|
{prop: 'replyContent', label: '答复内容'},
|
||||||
|
{prop: 'handleOpinion', label: '处理意见'},
|
||||||
|
{prop: 'implementState', label: '落实情况'},
|
||||||
|
{prop: 'leaderCheckTime', label: '分管领导审批时间'},
|
||||||
|
{prop: 'leaderCheckOpinion', label: '分管领导审批意见'},
|
||||||
|
{prop: 'feedbackCodeByUnderTake', label: '对承办单位办理态度评价'},
|
||||||
|
{prop: 'feedbackResult', label: '对办理结果评价'},
|
||||||
|
{prop: 'feedbackOpinion', label: '反馈意见'},
|
||||||
|
{prop: 'feedbackTime', label: '反馈时间'},
|
||||||
|
{prop: 'auditRecords', label: '审核记录及时间'}
|
||||||
|
])))
|
||||||
|
$('body').append(form)
|
||||||
|
form.submit()
|
||||||
|
form.remove()
|
||||||
|
}).catch(() => {})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,21 @@
|
|||||||
label-suffix=":">
|
label-suffix=":">
|
||||||
<vi-title title="填写活动信息"></vi-title>
|
<vi-title title="填写活动信息"></vi-title>
|
||||||
|
|
||||||
|
<!-- 沿用入口只用于创建活动,独占首行,宽度与下方单个表单字段一致。 -->
|
||||||
|
<el-row gutter="40" v-if="!form.id">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="沿用之前活动">
|
||||||
|
<el-select v-model="reuseActivityId" clearable filterable
|
||||||
|
:loading="reuseLoading" :disabled="formLoading"
|
||||||
|
placeholder="请选择要沿用的活动" @change="reuseActivityChange"
|
||||||
|
style="width: 100%">
|
||||||
|
<el-option v-for="item in reuseActivityOptions" :key="item.id"
|
||||||
|
:label="item.name" :value="item.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
<el-row gutter="40">
|
<el-row gutter="40">
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item prop="activityLevel" label="活动级别">
|
<el-form-item prop="activityLevel" label="活动级别">
|
||||||
@@ -620,6 +635,12 @@ module.exports = {
|
|||||||
planList: [],
|
planList: [],
|
||||||
events: [],
|
events: [],
|
||||||
projectType: "",
|
projectType: "",
|
||||||
|
reuseActivityId: null,
|
||||||
|
reuseActivityOptions: [],
|
||||||
|
reuseLoading: false,
|
||||||
|
reuseReady: false,
|
||||||
|
formLoading: false,
|
||||||
|
reuseRequestId: 0,
|
||||||
formRules: {
|
formRules: {
|
||||||
name: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
name: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||||
address: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
address: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||||
@@ -627,9 +648,7 @@ module.exports = {
|
|||||||
eventsIds: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
eventsIds: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||||
applyTime: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
applyTime: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||||
unitSponsor: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
unitSponsor: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||||
undertakeUnit: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
|
||||||
// unitJointly: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
// unitJointly: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||||
time: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
|
||||||
activityGroupId: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
activityGroupId: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||||
gameStyle: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
gameStyle: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||||
applyWay: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
applyWay: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||||
@@ -652,6 +671,205 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
|
// 下拉接口无参数;data 为当前管理范围内的 {id, name} 数组。
|
||||||
|
getReuseActivityOptions() {
|
||||||
|
return $.post('/platform/activity/school/info/mange/getReuseActivityOptions').then((resp) => {
|
||||||
|
if (resp.code === 0) {
|
||||||
|
this.$set(this, 'reuseActivityOptions', resp.data || [])
|
||||||
|
} else {
|
||||||
|
this.$message.error(resp.msg)
|
||||||
|
}
|
||||||
|
}).fail(() => {
|
||||||
|
this.$message.error('历史活动列表加载失败,请重新打开创建活动')
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// JSON 列可能返回字符串、数组或空值,统一转成独立数组,避免修改来源数据。
|
||||||
|
reuseArray(value) {
|
||||||
|
let data = value
|
||||||
|
try {
|
||||||
|
data = typeof value === 'string' ? JSON.parse(value || '[]') : value
|
||||||
|
} catch (error) {
|
||||||
|
this.$message.warning('历史活动存在无法读取的配置,请检查并重新填写')
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
return Array.isArray(data) ? clone(data) : []
|
||||||
|
},
|
||||||
|
// id 为来源活动ID;响应包含活动字段和 schoolEvents,不携带旧主键进入新增保存。
|
||||||
|
reuseActivityChange(id) {
|
||||||
|
const requestId = ++this.reuseRequestId
|
||||||
|
this.$set(this, 'reuseReady', false)
|
||||||
|
if (!id) {
|
||||||
|
this.$set(this, 'reuseLoading', false)
|
||||||
|
this.openAdd()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$set(this, 'reuseLoading', true)
|
||||||
|
return $.post('/platform/activity/school/info/mange/findReuseActivity', {id}).then((resp) => {
|
||||||
|
if (requestId !== this.reuseRequestId) return
|
||||||
|
if (resp.code !== 0) {
|
||||||
|
this.$message.error(resp.msg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const form = clone(resp.data)
|
||||||
|
// 项目列表及编号按沿用活动的实际类型加载,旧日期要求重新填写。
|
||||||
|
return $.when(
|
||||||
|
$.post('/platform/activity/common/getEvents', {type: form.applyType}),
|
||||||
|
$.post('/platform/activity/apply/generateActivityCode', {activity_type: form.activityLevel}),
|
||||||
|
$.post('/platform/vi/common/getClubsByRole')
|
||||||
|
).then((eventResponse, codeResponse, clubResponse) => {
|
||||||
|
if (requestId !== this.reuseRequestId) return
|
||||||
|
// 当前项目使用 jQuery 1.x;when 返回每个请求的 [data, status, xhr]。
|
||||||
|
const responses = [eventResponse[0], codeResponse[0], clubResponse[0]]
|
||||||
|
const failed = responses.find((response) => response.code !== 0)
|
||||||
|
if (failed) {
|
||||||
|
this.$message.error(failed.msg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const events = responses[0].data || []
|
||||||
|
const selectedIds = this.reuseArray(form.eventsIds)
|
||||||
|
const availableIds = selectedIds.filter((eventId) => events.some((event) => event.id === eventId))
|
||||||
|
if (availableIds.length !== selectedIds.length) {
|
||||||
|
this.$message.warning('历史活动中已停用或不存在的项目未沿用,请检查活动项目')
|
||||||
|
}
|
||||||
|
;['applyWay', 'unitSponsor', 'undertakeUnit', 'unitJointly', 'image'].forEach((key) => {
|
||||||
|
this.$set(form, key, this.reuseArray(form[key]))
|
||||||
|
})
|
||||||
|
const configs = (form.schoolEvents || []).filter((event) => availableIds.includes(event.eventId)).map((event) => {
|
||||||
|
const config = clone(event)
|
||||||
|
this.$set(config, 'id', null)
|
||||||
|
this.$set(config, 'activityId', null)
|
||||||
|
this.$set(config, 'unionLimit', this.reuseArray(config.unionLimit))
|
||||||
|
this.$set(config, 'ageDate', config.startAgeDate ? [config.startAgeDate, config.endAgeDate] : [])
|
||||||
|
return config
|
||||||
|
})
|
||||||
|
;['id', 'foundDate', 'applyStartTime', 'applyEndTime', 'startTime', 'endTime'].forEach((key) => this.$set(form, key, null))
|
||||||
|
this.$set(form, 'schoolEvents', [])
|
||||||
|
this.$set(form, 'close', false)
|
||||||
|
this.$set(form, 'activityCode', responses[1].data)
|
||||||
|
this.$set(form, 'activityLevel', Number(form.activityLevel))
|
||||||
|
this.$set(form, 'activityGroupId', form.activityGroupId ? Number(form.activityGroupId) : null)
|
||||||
|
this.$set(form, 'applyTime', [])
|
||||||
|
this.$set(form, 'time', [])
|
||||||
|
this.$set(form, 'eventsIds', availableIds)
|
||||||
|
this.$set(this, 'events', events)
|
||||||
|
this.$set(this, 'clubOptions', responses[2].data || [])
|
||||||
|
this.$set(this, 'form', form)
|
||||||
|
this.$set(this, 'eventsIds', [])
|
||||||
|
this.$set(this, 'checkedEventInfo', configs)
|
||||||
|
this.$set(this, 'checkedEventInfo2', clone(configs))
|
||||||
|
this.$set(this, 'eventForm', {})
|
||||||
|
this.$set(this, 'checkedEvents', [])
|
||||||
|
this.$set(this, 'rightChecked', [])
|
||||||
|
this.$set(this, 'reuseReady', true)
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.initEditor()
|
||||||
|
if (this.$refs.activityForm) this.$refs.activityForm.clearValidate()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}).fail(() => {
|
||||||
|
if (requestId === this.reuseRequestId) {
|
||||||
|
this.$message.error('沿用活动加载失败,请重新选择活动')
|
||||||
|
}
|
||||||
|
}).always(() => {
|
||||||
|
if (requestId === this.reuseRequestId) this.$set(this, 'reuseLoading', false)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 合并当前所选项目与已沿用配置;新增选择使用原有默认值,已移除项目不再提交。
|
||||||
|
buildReuseEvents() {
|
||||||
|
const selectedIds = this.form.eventsIds || []
|
||||||
|
return this.events.filter((event) => selectedIds.includes(event.id)).map((event) => {
|
||||||
|
const existing = this.checkedEventInfo.find((config) => config.eventId === event.id)
|
||||||
|
const config = existing ? clone(existing) : {
|
||||||
|
eventId: event.id, projectType: event.projectType, leanderNum: 0, coachNum: 0,
|
||||||
|
athletesMaxNum: event.projectType === '1' ? 3 : null,
|
||||||
|
restrictRegNumber: event.projectType === '1' ? 2 : null,
|
||||||
|
restrictTotalTeam: 1, substituteNum: 0, applyUserModel: 1
|
||||||
|
}
|
||||||
|
this.$set(config, 'id', null)
|
||||||
|
this.$set(config, 'activityId', null)
|
||||||
|
this.$set(config, 'startAgeDate', config.ageDate && config.ageDate.length ? config.ageDate[0] : null)
|
||||||
|
this.$set(config, 'endAgeDate', config.ageDate && config.ageDate.length ? config.ageDate[1] : null)
|
||||||
|
return config
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// isSave 区分保存草稿和提交;草稿跳过字段校验,提交仍校验报名、活动及项目配置。
|
||||||
|
doReuseAdd(isSave) {
|
||||||
|
if (this.formLoading || this.reuseLoading) return
|
||||||
|
if (!this.reuseReady) {
|
||||||
|
this.$message.warning('请重新选择并加载沿用活动')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const save = () => {
|
||||||
|
const form = clone(this.form)
|
||||||
|
if (!isSave) {
|
||||||
|
if (!form.applyTime || form.applyTime.length !== 2 || !form.applyTime[0] || !form.applyTime[1]) {
|
||||||
|
this.$message.warning('请填写报名日期')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!form.time || form.time.length !== 2 || !form.time[0] || !form.time[1]) {
|
||||||
|
this.$message.warning('请填写活动时间')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (moment(form.time[0]).valueOf() <= moment(form.applyTime[0]).valueOf()) {
|
||||||
|
this.$message.error('活动时间必须晚于报名时间')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!form.eventsIds || !form.eventsIds.length) {
|
||||||
|
this.$message.warning('请选择活动项目')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.getArrDifference(form.unitJointly || [], form.unitSponsor || []).length === 0) {
|
||||||
|
this.$message.error('协办单位里存在主办单位')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.$set(form, 'id', null)
|
||||||
|
this.$set(form, 'isSave', isSave ? 1 : 0)
|
||||||
|
// 草稿可没有报名和活动时间,缺失时明确传 null,避免复制旧活动日期。
|
||||||
|
this.$set(form, 'applyStartTime', form.applyTime && form.applyTime[0] && form.applyTime[1] ? form.applyTime[0] : null)
|
||||||
|
this.$set(form, 'applyEndTime', form.applyTime && form.applyTime[0] && form.applyTime[1] ? form.applyTime[1] : null)
|
||||||
|
this.$set(form, 'startTime', form.time && form.time[0] && form.time[1] ? form.time[0] : null)
|
||||||
|
this.$set(form, 'endTime', form.time && form.time[0] && form.time[1] ? form.time[1] : null)
|
||||||
|
this.$set(this, 'formLoading', true)
|
||||||
|
const loading = this.$loading({lock: true, text: isSave ? '正在保存...' : '正在提交...', background: COVER_LAYER_COLOR})
|
||||||
|
const request = $.post('/platform/activity/school/info/mange/doReuseAdd', {
|
||||||
|
sourceId: this.reuseActivityId, data: JSON.stringify(form), events: JSON.stringify(this.buildReuseEvents())
|
||||||
|
})
|
||||||
|
// jQuery 1.x 的 then 回调抛错后可能中断后续回调;直接监听请求结束以关闭遮罩。
|
||||||
|
request.always(() => {
|
||||||
|
this.$set(this, 'formLoading', false)
|
||||||
|
loading.close()
|
||||||
|
})
|
||||||
|
return request.then((resp) => {
|
||||||
|
if (resp.code !== 0) {
|
||||||
|
this.$message.error(resp.msg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (isSave) {
|
||||||
|
this.$message.success('保存成功')
|
||||||
|
window.location.href = '/platform/activity/school/info/mange'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$set(this.form, 'id', resp.data)
|
||||||
|
this.$set(this, 'reuseActivityId', null)
|
||||||
|
this.$emit('flip')
|
||||||
|
}, () => {
|
||||||
|
this.$message.error('请求失败,请检查活动列表后重试')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (isSave) {
|
||||||
|
if (this.$refs.activityForm) this.$refs.activityForm.clearValidate()
|
||||||
|
return save()
|
||||||
|
}
|
||||||
|
if (this.$refs.activityForm) {
|
||||||
|
this.$refs.activityForm.validate((valid) => {
|
||||||
|
if (valid) save()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return save()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
async applyUserModelInput(val) {
|
async applyUserModelInput(val) {
|
||||||
if (val === 2) {
|
if (val === 2) {
|
||||||
if (!this.eventForm.unionLimit || this.eventForm.unionLimit.length === 0) {
|
if (!this.eventForm.unionLimit || this.eventForm.unionLimit.length === 0) {
|
||||||
@@ -871,6 +1089,11 @@ module.exports = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
next() {
|
next() {
|
||||||
|
if (this.reuseLoading || this.formLoading) return
|
||||||
|
if (this.reuseActivityId && !this.reuseReady) {
|
||||||
|
this.$message.warning('请重新选择并加载沿用活动')
|
||||||
|
return
|
||||||
|
}
|
||||||
this.$refs["activityForm"].validate(async (valid) => {
|
this.$refs["activityForm"].validate(async (valid) => {
|
||||||
const form = clone(this.form)
|
const form = clone(this.form)
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
@@ -883,7 +1106,8 @@ module.exports = {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (moment(this.form.time[0]).valueOf() <= moment(this.form.applyTime[0]).valueOf()) {
|
// 活动时间可在保存草稿后补填;已填写时仍需晚于报名开始时间。
|
||||||
|
if (this.form.time && this.form.time[0] && this.form.time[1] && moment(this.form.time[0]).valueOf() <= moment(this.form.applyTime[0]).valueOf()) {
|
||||||
this.$notify.error({title: '错误', message: '活动时间必须晚于报名时间'});
|
this.$notify.error({title: '错误', message: '活动时间必须晚于报名时间'});
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -917,7 +1141,13 @@ module.exports = {
|
|||||||
this.eventForm.checkedEventId = this.checkedEvents[0].id
|
this.eventForm.checkedEventId = this.checkedEvents[0].id
|
||||||
this.projectType = this.checkedEvents[0].projectType
|
this.projectType = this.checkedEvents[0].projectType
|
||||||
|
|
||||||
if (!form.id || this.checkedEventInfo2.length <= 0) {
|
if (this.reuseActivityId && !form.id) {
|
||||||
|
// 新活动也保留沿用配置,不能因尚无活动ID而恢复为默认人数。
|
||||||
|
const allItems = this.checkedEventInfo.find((event) => event.eventId === 'allItems')
|
||||||
|
const configs = this.buildReuseEvents()
|
||||||
|
if (allItems) configs.unshift(clone(allItems))
|
||||||
|
this.$set(this, 'checkedEventInfo', configs)
|
||||||
|
} else if (!form.id || this.checkedEventInfo2.length <= 0) {
|
||||||
this.eventForm = {
|
this.eventForm = {
|
||||||
checkedEventId: this.checkedEvents[0].id,
|
checkedEventId: this.checkedEvents[0].id,
|
||||||
leanderNum: 0,
|
leanderNum: 0,
|
||||||
@@ -959,6 +1189,14 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
,
|
,
|
||||||
async openAdd() {
|
async openAdd() {
|
||||||
|
this.reuseRequestId++
|
||||||
|
this.$set(this, 'reuseLoading', false)
|
||||||
|
this.$set(this, 'reuseReady', false)
|
||||||
|
this.$set(this, 'reuseActivityId', null)
|
||||||
|
this.$set(this, 'checkedEventInfo', [])
|
||||||
|
this.$set(this, 'checkedEventInfo2', [])
|
||||||
|
this.$set(this, 'eventsIds', [])
|
||||||
|
this.getReuseActivityOptions()
|
||||||
this.events = await activity.getEvents(2)
|
this.events = await activity.getEvents(2)
|
||||||
this.planList = await activity.getSchoolActivityPlan(this.form.activityLevel)
|
this.planList = await activity.getSchoolActivityPlan(this.form.activityLevel)
|
||||||
await this.getActivityGroup()
|
await this.getActivityGroup()
|
||||||
@@ -977,6 +1215,7 @@ module.exports = {
|
|||||||
applyWay: [2],
|
applyWay: [2],
|
||||||
eventsIds: [],
|
eventsIds: [],
|
||||||
unitJointly: [],
|
unitJointly: [],
|
||||||
|
undertakeUnit: [],
|
||||||
applyType: 2,
|
applyType: 2,
|
||||||
activityCode: data,
|
activityCode: data,
|
||||||
activityLevel: 40001,
|
activityLevel: 40001,
|
||||||
@@ -989,6 +1228,9 @@ module.exports = {
|
|||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
async openEdit(row, flag) {
|
async openEdit(row, flag) {
|
||||||
|
this.reuseRequestId++
|
||||||
|
this.$set(this, 'reuseLoading', false)
|
||||||
|
this.$set(this, 'reuseActivityId', null)
|
||||||
this.active = flag ? 0 : this.active
|
this.active = flag ? 0 : this.active
|
||||||
await this.applyTypeChange(row.applyType)
|
await this.applyTypeChange(row.applyType)
|
||||||
this.planList = await activity.getSchoolActivityPlan(1)
|
this.planList = await activity.getSchoolActivityPlan(1)
|
||||||
@@ -1002,11 +1244,11 @@ module.exports = {
|
|||||||
this.clubOptions = await getClubsByRole()
|
this.clubOptions = await getClubsByRole()
|
||||||
this.eventsIds = clone(JSON.parse(v.eventsIds))
|
this.eventsIds = clone(JSON.parse(v.eventsIds))
|
||||||
v.applyTime = [v.applyStartTime, v.applyEndTime]
|
v.applyTime = [v.applyStartTime, v.applyEndTime]
|
||||||
v.time = [v.startTime, v.endTime]
|
this.$set(v, 'time', v.startTime && v.endTime ? [v.startTime, v.endTime] : null)
|
||||||
v.eventsIds = JSON.parse(v.eventsIds)
|
v.eventsIds = JSON.parse(v.eventsIds)
|
||||||
v.applyWay = JSON.parse(v.applyWay)
|
v.applyWay = JSON.parse(v.applyWay)
|
||||||
v.unitSponsor = JSON.parse(v.unitSponsor)
|
v.unitSponsor = JSON.parse(v.unitSponsor)
|
||||||
v.undertakeUnit = JSON.parse(v.undertakeUnit)
|
v.undertakeUnit = this.reuseArray(v.undertakeUnit)
|
||||||
v.unitJointly = JSON.parse(v.unitJointly)
|
v.unitJointly = JSON.parse(v.unitJointly)
|
||||||
v.activityGroupId = parseInt(v.activityGroupId)
|
v.activityGroupId = parseInt(v.activityGroupId)
|
||||||
v.activityLevel = parseInt(v.activityLevel)
|
v.activityLevel = parseInt(v.activityLevel)
|
||||||
@@ -1075,6 +1317,14 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
,
|
,
|
||||||
async operate() {
|
async operate() {
|
||||||
|
if (this.reuseLoading || this.formLoading) return
|
||||||
|
if (this.reuseActivityId && !this.form.id) return this.doReuseAdd(false)
|
||||||
|
|
||||||
|
// 提交会开放活动,必须先补齐活动时间;仅保存草稿允许留空。
|
||||||
|
if (!this.form.time || this.form.time.length !== 2 || !this.form.time[0] || !this.form.time[1]) {
|
||||||
|
this.$message.warning('请填写活动时间后再提交')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const deleteEventIds = this.eventsIds.filter(v => !this.form.eventsIds.includes(v))
|
const deleteEventIds = this.eventsIds.filter(v => !this.form.eventsIds.includes(v))
|
||||||
const {data} = await $.get(loc() + "/getEventApply", {
|
const {data} = await $.get(loc() + "/getEventApply", {
|
||||||
@@ -1093,7 +1343,11 @@ module.exports = {
|
|||||||
await this.doOperate()
|
await this.doOperate()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async doSave() {
|
doSave() {
|
||||||
|
if (this.reuseLoading || this.formLoading) return
|
||||||
|
// 保存草稿不触发表单必填校验;下一步和提交仍按各自规则处理。
|
||||||
|
if (this.$refs.activityForm) this.$refs.activityForm.clearValidate()
|
||||||
|
if (this.reuseActivityId && !this.form.id) return this.doReuseAdd(true)
|
||||||
let url = this.form.id ? "/doEdit" : "/doAdd"
|
let url = this.form.id ? "/doEdit" : "/doAdd"
|
||||||
|
|
||||||
this.checkedEventInfo.forEach(v => {
|
this.checkedEventInfo.forEach(v => {
|
||||||
@@ -1115,25 +1369,32 @@ module.exports = {
|
|||||||
const form = clone(this.form)
|
const form = clone(this.form)
|
||||||
form.restrictMaxNum = form.leanderNum + form.coachNum + form.athletesMaxNum + form.substituteNum
|
form.restrictMaxNum = form.leanderNum + form.coachNum + form.athletesMaxNum + form.substituteNum
|
||||||
form.restrictMinNum = form.athletesMaxNum
|
form.restrictMinNum = form.athletesMaxNum
|
||||||
form.isSave = true
|
form.isSave = 1
|
||||||
|
|
||||||
const {time, applyTime} = form
|
const {time, applyTime} = form
|
||||||
if (applyTime && applyTime.length) {
|
if (applyTime && applyTime.length === 2 && applyTime[0] && applyTime[1]) {
|
||||||
form.applyStartTime = applyTime[0]
|
form.applyStartTime = applyTime[0]
|
||||||
form.applyEndTime = applyTime[1]
|
form.applyEndTime = applyTime[1]
|
||||||
form.applyTime = undefined
|
form.applyTime = undefined
|
||||||
|
} else {
|
||||||
|
form.applyStartTime = null
|
||||||
|
form.applyEndTime = null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (time && time.length) {
|
if (time && time.length === 2 && time[0] && time[1]) {
|
||||||
form.startTime = time[0]
|
form.startTime = time[0]
|
||||||
form.endTime = time[1]
|
form.endTime = time[1]
|
||||||
form.time = undefined
|
form.time = undefined
|
||||||
|
} else {
|
||||||
|
// 清空已有活动时间时显式传 null,避免编辑草稿时沿用旧值。
|
||||||
|
form.startTime = null
|
||||||
|
form.endTime = null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.eventForm.checkedEventId == "allItems") {
|
if (this.eventForm.checkedEventId == "allItems") {
|
||||||
events = events.filter(v => v.projectType == 1 && v.id != "allItems")
|
events = events.filter(v => v.projectType == 1 && v.id != "allItems")
|
||||||
|
|
||||||
} else {
|
} else if (this.eventForm.checkedEventId) {
|
||||||
this.$set(this.eventForm, "activityId", this.form.id)
|
this.$set(this.eventForm, "activityId", this.form.id)
|
||||||
this.$set(this.eventForm, "eventId", this.eventForm.checkedEventId)
|
this.$set(this.eventForm, "eventId", this.eventForm.checkedEventId)
|
||||||
if (this.eventForm.ageDate && this.eventForm.ageDate.length > 0) {
|
if (this.eventForm.ageDate && this.eventForm.ageDate.length > 0) {
|
||||||
@@ -1142,26 +1403,29 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
events = this.eventForm
|
events = this.eventForm
|
||||||
}
|
}
|
||||||
|
this.$set(this, 'formLoading', true)
|
||||||
const loading = this.$loading({
|
const loading = this.$loading({
|
||||||
lock: true,
|
lock: true,
|
||||||
text: '正在提交...',
|
text: '正在保存...',
|
||||||
spinner: 'el-icon-loading',
|
spinner: 'el-icon-loading',
|
||||||
background: COVER_LAYER_COLOR
|
background: COVER_LAYER_COLOR
|
||||||
});
|
});
|
||||||
|
|
||||||
const resp = await $.post("/platform/activity/school/info/mange" + url, {
|
return $.post("/platform/activity/school/info/mange" + url, {
|
||||||
data: JSON.stringify(form),
|
data: JSON.stringify(form),
|
||||||
events: JSON.stringify(events)
|
events: JSON.stringify(events)
|
||||||
})
|
}).then((resp) => {
|
||||||
|
if (resp.code === 0) {
|
||||||
closeLoadingFunc(loading, resp, async (data) => {
|
this.$message.success('保存成功')
|
||||||
|
window.location.href = '/platform/activity/school/info/mange'
|
||||||
this.$emit('flush')
|
} else {
|
||||||
if (!this.form.id) form.id = data
|
this.$message.error(resp.msg)
|
||||||
await this.openEdit(form, false)
|
}
|
||||||
|
}, () => {
|
||||||
}, (data, msg) => {
|
this.$message.error('保存失败,请检查活动列表后重试')
|
||||||
this.$message.error(msg);
|
}).always(() => {
|
||||||
|
this.$set(this, 'formLoading', false)
|
||||||
|
loading.close()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
examineTrans(form) {
|
examineTrans(form) {
|
||||||
|
|||||||
@@ -111,6 +111,8 @@ module.exports = {
|
|||||||
{prop: 'loginname', label: '工号'},
|
{prop: 'loginname', label: '工号'},
|
||||||
{prop: 'mobile', label: '电话'},
|
{prop: 'mobile', label: '电话'},
|
||||||
{prop: 'sex', label: '性别'},
|
{prop: 'sex', label: '性别'},
|
||||||
|
{prop: 'birthday', label: '出生年月'},
|
||||||
|
{prop: 'unitname', label: '单位'},
|
||||||
{prop: 'identity', label: '身份', sortable: true},
|
{prop: 'identity', label: '身份', sortable: true},
|
||||||
// {prop: 'divisionLevelLeadership', label: '是否处级领导', sortable: true},
|
// {prop: 'divisionLevelLeadership', label: '是否处级领导', sortable: true},
|
||||||
{prop: 'status', label: '状态', sortable: true},
|
{prop: 'status', label: '状态', sortable: true},
|
||||||
|
|||||||
@@ -331,6 +331,8 @@
|
|||||||
prop="mobile" header-align="center" align="center"
|
prop="mobile" header-align="center" align="center"
|
||||||
label="电话">
|
label="电话">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column prop="birthday" header-align="center" align="center"
|
||||||
|
label="出生年月"></el-table-column>
|
||||||
|
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="sex" header-align="center" align="center" sortable
|
prop="sex" header-align="center" align="center" sortable
|
||||||
|
|||||||
@@ -235,6 +235,36 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane v-if="hasPane(6)&&viewData.ecr" label="工会常务副主席审核信息" name="6">
|
||||||
|
<el-form label-width="130px" label-suffix=":" style="padding: 20px 0">
|
||||||
|
|
||||||
|
<vi-title title="审核信息"></vi-title>
|
||||||
|
|
||||||
|
<el-row gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="审核人员">
|
||||||
|
{{ viewData.ecr.username }}
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="审核时间">
|
||||||
|
{{ viewData.ecr.time }}
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-form-item label="审核意见">
|
||||||
|
<div class="textarea-div">{{ viewData.ecr.opinion ? viewData.ecr.opinion : '暂无' }}</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="签  字">
|
||||||
|
<el-image v-if="viewData.ecr.sign"
|
||||||
|
style="width: 300px; height: 100px"
|
||||||
|
:src="viewData.ecr.sign"
|
||||||
|
fit="contain"></el-image>
|
||||||
|
<span v-else>暂无</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane v-if="handle" :label="label" name="999">
|
<el-tab-pane v-if="handle" :label="label" name="999">
|
||||||
<slot name="handle"></slot>
|
<slot name="handle"></slot>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
@@ -257,7 +287,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
panes: {
|
panes: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: []
|
default: () => []
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
filters: {
|
filters: {
|
||||||
@@ -278,27 +308,32 @@ module.exports = {
|
|||||||
watch: {},
|
watch: {},
|
||||||
methods: {
|
methods: {
|
||||||
hasPane(name) {
|
hasPane(name) {
|
||||||
if (!this.handle) {
|
// 未指定页签范围时展示所有已有审核记录;显式传入范围时保持原有限制。
|
||||||
|
if (!this.handle || this.panes.length === 0) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return this.panes.includes(name)
|
return this.panes.includes(name)
|
||||||
},
|
},
|
||||||
async getInfo(id) {
|
/**
|
||||||
this.loading = true
|
* id 为慰问申请 ID;接口 data 为申请详情,ucr/fr/vcr/ecr 为各节点审核记录对象。
|
||||||
const {data, code, msg} = await $.get("/platform/fw/condolence/findOne", {id})
|
* 无记录时对应页签隐藏;请求结束后统一解除加载状态。
|
||||||
this.loading = false
|
*/
|
||||||
if (data) {
|
getInfo(id) {
|
||||||
this.activeName = this.handle ? "999" : "1"
|
this.$set(this, 'loading', true)
|
||||||
condolence.toFormData(data)
|
this.$set(this, 'viewData', {})
|
||||||
this.viewData = data
|
return $.post('/platform/fw/condolence/findOne', {id})
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code === 0 && res.data) {
|
||||||
|
condolence.toFormData(res.data)
|
||||||
|
this.$set(this, 'activeName', this.handle ? '999' : '1')
|
||||||
|
this.$set(this, 'viewData', res.data)
|
||||||
} else {
|
} else {
|
||||||
this.viewData = {}
|
this.$message.error('获取信息失败')
|
||||||
this.$message({
|
|
||||||
message: "获取信息失败",
|
|
||||||
type: 'error'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.always(() => {
|
||||||
|
this.$set(this, 'loading', false)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
|||||||
@@ -0,0 +1,246 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog :title="title" :visible.sync="visible" width="88%" top="5vh"
|
||||||
|
append-to-body :close-on-click-modal="false">
|
||||||
|
<el-form :inline="true" :model="form" size="small" class="dashboard-detail-filter">
|
||||||
|
<el-form-item label="统计年度" v-if="detailType === 'member'">
|
||||||
|
<el-date-picker v-model="form.year" type="year" value-format="yyyy"
|
||||||
|
clearable placeholder="选择年度" @change="search"></el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="时间">
|
||||||
|
<el-date-picker v-model="form.dateRange" type="daterange" value-format="yyyy-MM-dd"
|
||||||
|
range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"
|
||||||
|
clearable @change="search"></el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="所属工会">
|
||||||
|
<el-select v-model="form.unionId" clearable filterable placeholder="所属工会"
|
||||||
|
@change="flushUnits(false)">
|
||||||
|
<el-option v-for="item in unions" :key="item.id"
|
||||||
|
:label="item.unionname" :value="item.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="所属单位">
|
||||||
|
<el-select v-model="form.unitId" clearable filterable placeholder="所属单位" @change="search">
|
||||||
|
<el-option v-for="item in units" :key="item.id"
|
||||||
|
:label="item.name" :value="item.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="人员类型">
|
||||||
|
<el-select v-model="form.personType" clearable placeholder="人员类型" @change="search">
|
||||||
|
<el-option v-for="item in personTypeOptions" :key="item.code"
|
||||||
|
:label="item.name" :value="item.code"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="在职状态">
|
||||||
|
<el-select v-model="form.userState" clearable placeholder="在职状态" @change="search">
|
||||||
|
<el-option v-for="item in userStateOptions" :key="item.code"
|
||||||
|
:label="item.name" :value="item.code"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="性别">
|
||||||
|
<el-select v-model="form.sex" clearable placeholder="性别" @change="search">
|
||||||
|
<el-option label="男" value="男"></el-option>
|
||||||
|
<el-option label="女" value="女"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<template v-if="detailType === 'medical'">
|
||||||
|
<el-form-item label="补助类型">
|
||||||
|
<el-select v-model="form.medicalType" clearable placeholder="补助类型" @change="search">
|
||||||
|
<el-option v-for="item in medicalTypeOptions" :key="item.value"
|
||||||
|
:label="item.label" :value="item.value"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="申请状态">
|
||||||
|
<el-select v-model="form.stateId" clearable placeholder="申请状态" @change="search">
|
||||||
|
<el-option v-for="item in medicalStates" :key="item.value"
|
||||||
|
:label="item.label" :value="item.value"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
<el-form-item label="人员">
|
||||||
|
<el-input v-model="form.searchKeyword" clearable placeholder="姓名或工号"
|
||||||
|
@keyup.enter.native="search"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="el-icon-search" @click="search">查询</el-button>
|
||||||
|
<el-button icon="el-icon-refresh" @click="reset">重置</el-button>
|
||||||
|
<el-button type="success" icon="el-icon-download" @click="exportData">导出</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<el-table :data="tableData" border stripe height="calc(75vh - 170px)"
|
||||||
|
v-loading="loading" style="width: 100%">
|
||||||
|
<el-table-column type="index" label="序号" width="70" align="center"
|
||||||
|
:index="indexMethod"></el-table-column>
|
||||||
|
<el-table-column prop="loginname" label="工号" min-width="110" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column prop="username" label="姓名" min-width="100" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column prop="sex" label="性别" width="70" align="center"></el-table-column>
|
||||||
|
<el-table-column prop="persontype" label="人员类型" min-width="110" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column prop="userstate" label="在职状态" min-width="100" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column prop="unionname" label="所属工会" min-width="160" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column prop="unitname" label="所属单位" min-width="160" show-overflow-tooltip></el-table-column>
|
||||||
|
<template v-if="detailType === 'medical'">
|
||||||
|
<el-table-column prop="typename" label="补助类型" min-width="110"></el-table-column>
|
||||||
|
<el-table-column prop="detailtime" label="申请时间" min-width="160"></el-table-column>
|
||||||
|
<el-table-column prop="state_name" label="申请状态" min-width="120"></el-table-column>
|
||||||
|
<el-table-column prop="total_grant" label="补助金额" min-width="110" align="right"></el-table-column>
|
||||||
|
</template>
|
||||||
|
<el-table-column v-else prop="detailtime" label="加入时间" min-width="160"></el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<el-pagination class="dashboard-detail-pagination"
|
||||||
|
background
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
:current-page="pageForm.pageNumber"
|
||||||
|
:page-size="pageForm.pageSize"
|
||||||
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
:total="pageForm.totalCount"
|
||||||
|
@current-change="pageChange"
|
||||||
|
@size-change="pageSizeChange"></el-pagination>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
module.exports = {
|
||||||
|
props: {
|
||||||
|
baseUrl: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
visible: false,
|
||||||
|
loading: false,
|
||||||
|
title: '指标明细',
|
||||||
|
detailType: 'member',
|
||||||
|
form: this.emptyForm(),
|
||||||
|
initialForm: {},
|
||||||
|
tableData: [],
|
||||||
|
unions: [],
|
||||||
|
units: [],
|
||||||
|
personTypeOptions: [],
|
||||||
|
userStateOptions: [],
|
||||||
|
medicalStates: [],
|
||||||
|
medicalTypeOptions: [
|
||||||
|
{label: '医疗补助', value: 1},
|
||||||
|
{label: '重疾补助', value: 2},
|
||||||
|
{label: '特殊门诊补助', value: 3}
|
||||||
|
],
|
||||||
|
pageForm: {
|
||||||
|
pageNumber: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
totalCount: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
emptyForm() {
|
||||||
|
return {
|
||||||
|
detailType: 'member',
|
||||||
|
year: '',
|
||||||
|
dateRange: [],
|
||||||
|
unionId: '',
|
||||||
|
unitId: '',
|
||||||
|
personType: '',
|
||||||
|
userState: '',
|
||||||
|
sex: '',
|
||||||
|
medicalType: '',
|
||||||
|
stateId: '',
|
||||||
|
searchKeyword: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async open(title, detailType, filters) {
|
||||||
|
this.title = title || '指标明细'
|
||||||
|
this.detailType = detailType || 'member'
|
||||||
|
const form = this.emptyForm()
|
||||||
|
form.detailType = this.detailType
|
||||||
|
Object.assign(form, filters || {})
|
||||||
|
if (form.startTime || form.endTime) {
|
||||||
|
form.dateRange = [form.startTime || '', form.endTime || '']
|
||||||
|
}
|
||||||
|
this.form = form
|
||||||
|
this.initialForm = clone(form)
|
||||||
|
this.visible = true
|
||||||
|
await this.flushUnits(true)
|
||||||
|
this.search()
|
||||||
|
},
|
||||||
|
buildParams() {
|
||||||
|
const params = clone(this.form)
|
||||||
|
params.detailType = this.detailType
|
||||||
|
params.startTime = params.dateRange && params.dateRange.length ? params.dateRange[0] : ''
|
||||||
|
params.endTime = params.dateRange && params.dateRange.length ? params.dateRange[1] : ''
|
||||||
|
delete params.dateRange
|
||||||
|
return params
|
||||||
|
},
|
||||||
|
async loadData() {
|
||||||
|
this.loading = true
|
||||||
|
const params = Object.assign(this.buildParams(), {
|
||||||
|
pageNumber: this.pageForm.pageNumber,
|
||||||
|
pageSize: this.pageForm.pageSize
|
||||||
|
})
|
||||||
|
const resp = await $.get(this.baseUrl + '/detailPage', params)
|
||||||
|
requestLaterFun(resp, data => {
|
||||||
|
this.tableData = data.list || []
|
||||||
|
this.pageForm.totalCount = data.totalCount || 0
|
||||||
|
})
|
||||||
|
this.loading = false
|
||||||
|
},
|
||||||
|
search() {
|
||||||
|
if (!this.visible) return
|
||||||
|
this.pageForm.pageNumber = 1
|
||||||
|
this.loadData()
|
||||||
|
},
|
||||||
|
async reset() {
|
||||||
|
this.form = clone(this.initialForm)
|
||||||
|
await this.flushUnits(true)
|
||||||
|
this.search()
|
||||||
|
},
|
||||||
|
async flushUnits(preserveUnit) {
|
||||||
|
if (!preserveUnit) {
|
||||||
|
this.$set(this.form, 'unitId', '')
|
||||||
|
}
|
||||||
|
this.units = await getUnits(this.form.unionId)
|
||||||
|
if (!preserveUnit) {
|
||||||
|
this.search()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pageChange(pageNumber) {
|
||||||
|
this.pageForm.pageNumber = pageNumber
|
||||||
|
this.loadData()
|
||||||
|
},
|
||||||
|
pageSizeChange(pageSize) {
|
||||||
|
this.pageForm.pageSize = pageSize
|
||||||
|
this.pageForm.pageNumber = 1
|
||||||
|
this.loadData()
|
||||||
|
},
|
||||||
|
indexMethod(index) {
|
||||||
|
return (this.pageForm.pageNumber - 1) * this.pageForm.pageSize + index + 1
|
||||||
|
},
|
||||||
|
exportData() {
|
||||||
|
window.open(this.baseUrl + '/exportDetail?' + $.param(this.buildParams()))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async created() {
|
||||||
|
this.unions = await getUnions(null)
|
||||||
|
this.personTypeOptions = await getDictOptions('UserType')
|
||||||
|
this.userStateOptions = await getDictOptions('UserState')
|
||||||
|
const resp = await $.get(this.baseUrl + '/detailOptions')
|
||||||
|
requestLaterFun(resp, data => {
|
||||||
|
this.medicalStates = data.medicalStates || []
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.dashboard-detail-filter {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
.dashboard-detail-filter .el-form-item {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
.dashboard-detail-pagination {
|
||||||
|
margin-top: 15px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -223,9 +223,12 @@ layout("/mobile/platform.html"){
|
|||||||
roles: [],
|
roles: [],
|
||||||
active: 1,
|
active: 1,
|
||||||
needCount: 0,
|
needCount: 0,
|
||||||
|
needRequestId: 0,
|
||||||
needItems: [],
|
needItems: [],
|
||||||
activeName: '0',
|
activeName: '0',
|
||||||
completedItems: [],
|
completedItems: [],
|
||||||
|
completedLoading: false,
|
||||||
|
completedRequestId: 0,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -244,7 +247,8 @@ layout("/mobile/platform.html"){
|
|||||||
location.href = o.mobileHref
|
location.href = o.mobileHref
|
||||||
},
|
},
|
||||||
toHref(o) {
|
toHref(o) {
|
||||||
location.href = o.mobileUrl + '?audit=1';
|
// 详情链接已携带申请 ID,保留查询参数。
|
||||||
|
location.href = o.mobileUrl;
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 入学登记待办
|
* 入学登记待办
|
||||||
@@ -256,20 +260,111 @@ layout("/mobile/platform.html"){
|
|||||||
this.needItems = this.needItems.concat(data.filter(v => v.number > 0))
|
this.needItems = this.needItems.concat(data.filter(v => v.number > 0))
|
||||||
}
|
}
|
||||||
},*/
|
},*/
|
||||||
async getNeedItems() {
|
/**
|
||||||
const {data, code} = await $.get('/platform/needItems/getNeedItems')
|
* requestId 为本轮刷新序号,忽略旧请求,避免返回页面或切换页签时覆盖新数据。
|
||||||
if (code === 0) {
|
* 通用接口 data 为待办数组,使用 count 和 mobileHref;完成后继续加载慰问待办。
|
||||||
const obj = data.filter(v => {
|
*/
|
||||||
return v.mobileHref != null && v.count > 0
|
getNeedItems(requestId) {
|
||||||
|
return $.post('/platform/needItems/getNeedItems')
|
||||||
|
.then((res) => {
|
||||||
|
if (requestId === this.needRequestId && res.code === 0) {
|
||||||
|
this.$set(this, 'needItems', (res.data || []).filter(v => v.mobileHref && v.count > 0
|
||||||
|
&& v.mobileHref.split('?')[0] !== '/mobile/member/audit'
|
||||||
|
&& !['/platform/member/apply/audit/union', '/platform/member/apply/audit/school'].includes((v.href || '').split('?')[0])))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
this.needItems = obj
|
.always(() => {
|
||||||
|
if (requestId === this.needRequestId) {
|
||||||
|
this.getCondolenceAgenda(requestId)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
async getCompletes() {
|
/**
|
||||||
const {data, code} = await $.get('/platform/sys/completed/getCompletes')
|
* 复用 PC 慰问待办的菜单权限和统计口径,将 label/number 转为手机模板的 name/count。
|
||||||
if (code === 0) {
|
* 仅映射手机端已有审核页面的三个节点,历史常务副主席节点不提供手机办理入口。
|
||||||
this.completedItems = data;
|
*/
|
||||||
|
getCondolenceAgenda(requestId) {
|
||||||
|
const auditUrls = [
|
||||||
|
'/platform/fw/condolence/ucr/union',
|
||||||
|
'/platform/fw/condolence/fr',
|
||||||
|
'/platform/fw/condolence/vcr/school'
|
||||||
|
]
|
||||||
|
return $.post('/platform/condolence/agent/getAgenda')
|
||||||
|
.then((res) => {
|
||||||
|
if (requestId !== this.needRequestId || res.code !== 0) {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
const items = (res.data || []).filter(v => auditUrls.includes(v.url) && v.number > 0)
|
||||||
|
.map(v => ({
|
||||||
|
title: v.title,
|
||||||
|
name: v.label,
|
||||||
|
count: v.number,
|
||||||
|
mobileHref: '/mobile/condolence/audit'
|
||||||
|
}))
|
||||||
|
this.$set(this, 'needItems', this.needItems.concat(items))
|
||||||
|
})
|
||||||
|
.always(() => {
|
||||||
|
if (requestId === this.needRequestId) {
|
||||||
|
this.getMemberApplyAgenda(requestId)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 无需业务参数;后端按会话权限返回今年会员入会节点,字段与首页待办卡片一致。
|
||||||
|
* 专用数据替代通用配置中的同业务卡片,避免双计数;失败不影响已加载的慰问待办。
|
||||||
|
*/
|
||||||
|
getMemberApplyAgenda(requestId) {
|
||||||
|
return $.post('/platform/member/agenda/getMobileAgenda')
|
||||||
|
.then((res) => {
|
||||||
|
if (requestId !== this.needRequestId) return
|
||||||
|
if (res.code === 0) {
|
||||||
|
const items = (res.data || []).filter(v => v.count > 0 && v.mobileHref)
|
||||||
|
this.$set(this, 'needItems', this.needItems.concat(items))
|
||||||
|
} else {
|
||||||
|
vant.Toast.fail('会员入会待办加载失败,请重试')
|
||||||
|
}
|
||||||
|
}, () => {
|
||||||
|
if (requestId === this.needRequestId) vant.Toast.fail('会员入会待办加载失败,请重试')
|
||||||
|
})
|
||||||
|
.always(() => {
|
||||||
|
if (requestId === this.needRequestId) this.$set(this, 'needCount', this.needItems.length)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 两个接口均无需传办理人,按当前会话返回本人今年已办。
|
||||||
|
* 各业务独立合并;全部请求结束后关闭 loading,旧刷新结果不得覆盖当前列表。
|
||||||
|
*/
|
||||||
|
getCompletes() {
|
||||||
|
const requestId = this.completedRequestId + 1
|
||||||
|
this.$set(this, 'completedRequestId', requestId)
|
||||||
|
this.$set(this, 'completedItems', [])
|
||||||
|
this.$set(this, 'completedLoading', true)
|
||||||
|
const sources = [
|
||||||
|
{url: '/platform/condolence/agent/getCompletes', label: '慰问'},
|
||||||
|
{url: '/platform/member/agenda/getCompletes', label: '会员入会'}
|
||||||
|
]
|
||||||
|
let remaining = sources.length
|
||||||
|
const requests = sources.map(source => $.post(source.url)
|
||||||
|
.then((res) => {
|
||||||
|
if (requestId !== this.completedRequestId) return
|
||||||
|
if (res.code === 0) {
|
||||||
|
const items = this.completedItems.concat(res.data || [])
|
||||||
|
// 现有日期字段统一交给 moment 解析,兼容日期字符串和时间戳。
|
||||||
|
items.sort((a, b) => (moment(b.auditTime).valueOf() || 0) - (moment(a.auditTime).valueOf() || 0))
|
||||||
|
this.$set(this, 'completedItems', items)
|
||||||
|
} else {
|
||||||
|
vant.Toast.fail(source.label + '已办加载失败,请重试')
|
||||||
|
}
|
||||||
|
}, () => {
|
||||||
|
if (requestId === this.completedRequestId) vant.Toast.fail(source.label + '已办加载失败,请重试')
|
||||||
|
})
|
||||||
|
.always(() => {
|
||||||
|
remaining--
|
||||||
|
if (requestId === this.completedRequestId && remaining === 0) {
|
||||||
|
this.$set(this, 'completedLoading', false)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
return $.when.apply($, requests)
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 会员个人核对待办
|
* 会员个人核对待办
|
||||||
@@ -291,12 +386,13 @@ layout("/mobile/platform.html"){
|
|||||||
this.needItems = this.needItems.concat(data.filter(v => v.count > 0))
|
this.needItems = this.needItems.concat(data.filter(v => v.count > 0))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async initData() {
|
initData() {
|
||||||
await this.getNeedItems();
|
this.getCompletes()
|
||||||
// await this.getMemberCheckSelfAgenda()
|
// 每轮重新合并通用、慰问和会员入会待办,防止重复追加;刷新序号隔离尚未完成的旧请求。
|
||||||
// await this.getWelfareCheckSelfAgenda()
|
this.$set(this, 'needRequestId', this.needRequestId + 1)
|
||||||
// await this.getCompletes();
|
this.$set(this, 'needItems', [])
|
||||||
this.needCount = this.needItems.length
|
this.$set(this, 'needCount', 0)
|
||||||
|
return this.getNeedItems(this.needRequestId)
|
||||||
},
|
},
|
||||||
async setNeedItems() {
|
async setNeedItems() {
|
||||||
const {data, code} = await $.get('/platform/needItems/getNeedItems')
|
const {data, code} = await $.get('/platform/needItems/getNeedItems')
|
||||||
|
|||||||
@@ -59,9 +59,10 @@ layout("/mobile/platform.html"){
|
|||||||
{text: '已审核', value: true},
|
{text: '已审核', value: true},
|
||||||
],
|
],
|
||||||
handle: true,
|
handle: true,
|
||||||
|
queryVersion: 0,
|
||||||
pageForm: {
|
pageForm: {
|
||||||
year: new Date().getFullYear(),
|
year: GetQueryString("isAudit") === "true" ? null : new Date().getFullYear(),
|
||||||
isAudit: false,
|
isAudit: GetQueryString("isAudit") === "true",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -70,6 +71,7 @@ layout("/mobile/platform.html"){
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
yearChange() {
|
yearChange() {
|
||||||
|
this.queryVersion++
|
||||||
this.pageForm.pageNumber = 1
|
this.pageForm.pageNumber = 1
|
||||||
this.tableData = []
|
this.tableData = []
|
||||||
this.finished = false
|
this.finished = false
|
||||||
@@ -77,40 +79,32 @@ layout("/mobile/platform.html"){
|
|||||||
},
|
},
|
||||||
onLoad() {
|
onLoad() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
$.post(loc() + '/pageData', this.pageForm).then(res => {
|
// 捕获本次筛选条件,筛选切换后忽略旧请求,避免串页。
|
||||||
|
const requestKey = this.queryVersion || 0
|
||||||
|
$.post('/mobile/member/audit/pageData', Object.assign({}, this.pageForm)).then(res => {
|
||||||
|
if (requestKey !== (this.queryVersion || 0)) return
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
this.tableData = this.tableData.concat(res.data.list)
|
this.tableData = this.tableData.concat(res.data.list)
|
||||||
if (this.tableData.length === res.data.totalCount) {
|
this.finished = this.tableData.length >= res.data.totalCount || res.data.list.length === 0
|
||||||
this.finished = true
|
if (!this.finished) this.pageForm.pageNumber++
|
||||||
} else {
|
} else {
|
||||||
this.pageForm.pageNumber++
|
this.finished = true
|
||||||
|
this.$toast.fail(res.msg || '加载失败')
|
||||||
}
|
}
|
||||||
}
|
}).fail(() => {
|
||||||
this.loading = false
|
if (requestKey !== (this.queryVersion || 0)) return
|
||||||
|
this.finished = true
|
||||||
|
this.$toast.fail('加载失败,请重新筛选后重试')
|
||||||
|
}).always(() => {
|
||||||
|
if (requestKey === (this.queryVersion || 0)) this.loading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
/* pageData() {
|
|
||||||
this.mLoading = true
|
|
||||||
setTimeout(async () => {
|
|
||||||
$.get(loc() + '/pageData', this.pageForm, (res) => {
|
|
||||||
|
|
||||||
if (res.code === 0) {
|
|
||||||
this.tableData = this.tableData.concat(res.data.list)
|
|
||||||
if (this.tableData.length === res.data.totalCount) {
|
|
||||||
this.finished = true
|
|
||||||
} else {
|
|
||||||
this.pageForm.pageNumber++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.mLoading = false
|
|
||||||
}, 600)
|
|
||||||
},*/
|
|
||||||
openView(o) {
|
openView(o) {
|
||||||
window.location.href = '/mobile/member/audit/findOne?stateId=' + o.stateId + '&record_id=' + o.id + '&user_id=' + o.userId
|
window.location.href = '/mobile/member/audit/findOne?stateId=' + o.stateId + '&record_id=' + o.id + '&user_id=' + o.userId + '&done=' + this.pageForm.isAudit
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
async created() {
|
created() {
|
||||||
|
this.yearList = [{text: '全部年份', value: null}]
|
||||||
let nowYear = new Date().getFullYear()
|
let nowYear = new Date().getFullYear()
|
||||||
for (let i = nowYear; i >= nowYear - 9; i--) {
|
for (let i = nowYear; i >= nowYear - 9; i--) {
|
||||||
this.yearList.push({text: i, value: i})
|
this.yearList.push({text: i, value: i})
|
||||||
|
|||||||
@@ -0,0 +1,194 @@
|
|||||||
|
<!--#
|
||||||
|
layout("/mobile/platform.html"){
|
||||||
|
#-->
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.member-query-header {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 10;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.member-query-list {
|
||||||
|
padding: 10px 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.member-query-count {
|
||||||
|
padding: 0 16px 10px;
|
||||||
|
color: #969799;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.member-query-detail {
|
||||||
|
height: 85%;
|
||||||
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.member-query-detail .van-cell__value,
|
||||||
|
.member-query-list .van-cell__value {
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.member-query-loading {
|
||||||
|
padding: 40px 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="app" v-cloak>
|
||||||
|
<div class="member-query-header">
|
||||||
|
<van-nav-bar title="会员查询" left-arrow placeholder fixed
|
||||||
|
@click-left="location.replace('/mobile/index')"></van-nav-bar>
|
||||||
|
|
||||||
|
<form action="/mobile/member/query" @submit.prevent="doSearch">
|
||||||
|
<van-search v-model="keyword" placeholder="请输入姓名或工号" label="会员" show-action
|
||||||
|
@search="doSearch" @clear="doSearch">
|
||||||
|
<template #action>
|
||||||
|
<van-button type="primary" size="small" native-type="button" @click="doSearch">搜索</van-button>
|
||||||
|
</template>
|
||||||
|
</van-search>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="member-query-list">
|
||||||
|
<div v-if="tableData.length" class="member-query-count">共 {{pageForm.totalCount}} 位会员</div>
|
||||||
|
<van-list v-model="loading" :finished="finished" :error.sync="loadError"
|
||||||
|
error-text="加载失败,点击重试" :finished-text="tableData.length ? '没有更多了' : ''"
|
||||||
|
:immediate-check="false" @load="onLoad">
|
||||||
|
<div v-for="o in tableData" :key="o.id" class="list-card">
|
||||||
|
<van-cell-group inset>
|
||||||
|
<van-cell :border="false" title="姓 名">{{o.username || '—'}}</van-cell>
|
||||||
|
<van-cell :border="false" title="工 号">{{o.loginname || '—'}}</van-cell>
|
||||||
|
<van-cell :border="false" title="所在工会">{{o.unionname || '—'}}</van-cell>
|
||||||
|
<van-cell :border="false" title="所在单位">{{o.unitname || '—'}}</van-cell>
|
||||||
|
<van-cell :border="false" title="人员类型">{{o.personType || '—'}}</van-cell>
|
||||||
|
</van-cell-group>
|
||||||
|
<van-cell title="查看会员详情" is-link clickable @click="openView(o)"></van-cell>
|
||||||
|
</div>
|
||||||
|
</van-list>
|
||||||
|
<van-empty v-if="!loading && !loadError && finished && tableData.length === 0"
|
||||||
|
image="/none.svg" description="暂无符合条件的会员"></van-empty>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<van-popup v-model="showDetail" position="bottom" round class="member-query-detail">
|
||||||
|
<van-nav-bar title="会员详情" left-arrow @click-left="showDetail = false"></van-nav-bar>
|
||||||
|
<div v-if="detailLoading" class="member-query-loading">
|
||||||
|
<van-loading size="24px" vertical>加载中...</van-loading>
|
||||||
|
</div>
|
||||||
|
<van-empty v-else-if="detailError" description="详情加载失败">
|
||||||
|
<van-button type="primary" size="small" @click="openView(selectedMember)">重试</van-button>
|
||||||
|
</van-empty>
|
||||||
|
<van-cell-group v-else-if="memberInfo">
|
||||||
|
<van-cell title="姓名" :value="memberInfo.username || '—'"></van-cell>
|
||||||
|
<van-cell title="性别" :value="memberInfo.sex || '—'"></van-cell>
|
||||||
|
<van-cell title="年龄" :value="memberInfo.age == null ? '—' : memberInfo.age"></van-cell>
|
||||||
|
<van-cell title="民族" :value="memberInfo.nation || '—'"></van-cell>
|
||||||
|
<van-cell title="学历" :value="memberInfo.education || '—'"></van-cell>
|
||||||
|
<van-cell title="政治面貌" :value="memberInfo.political || '—'"></van-cell>
|
||||||
|
<van-cell title="职称" :value="memberInfo.jobTitle || '—'"></van-cell>
|
||||||
|
<van-cell title="职务" :value="memberInfo.position || '—'"></van-cell>
|
||||||
|
<van-cell title="所在单位" :value="memberInfo.unitname || '—'"></van-cell>
|
||||||
|
<van-cell title="个人简历" :value="memberInfo.vita || '—'"></van-cell>
|
||||||
|
</van-cell-group>
|
||||||
|
<van-empty v-else description="暂无会员详情"></van-empty>
|
||||||
|
</van-popup>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// 复用移动端会员接口,在查询页内查看详情,保持与查询入口一致的角色权限。
|
||||||
|
const vue = new Vue({
|
||||||
|
el: '#app',
|
||||||
|
mixins: [mobileMixins],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
keyword: '',
|
||||||
|
pageForm: {
|
||||||
|
pageNumber: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
totalCount: 0,
|
||||||
|
searchKeyword: ''
|
||||||
|
},
|
||||||
|
loadError: false,
|
||||||
|
requestId: 0,
|
||||||
|
pending: false,
|
||||||
|
showDetail: false,
|
||||||
|
detailLoading: false,
|
||||||
|
detailError: false,
|
||||||
|
detailRequestId: 0,
|
||||||
|
selectedMember: null,
|
||||||
|
memberInfo: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
doSearch() {
|
||||||
|
// 新搜索使上一轮分页请求失效,避免较慢的旧响应混入新结果。
|
||||||
|
this.requestId++
|
||||||
|
this.pending = false
|
||||||
|
this.pageForm.pageNumber = 1
|
||||||
|
this.pageForm.totalCount = 0
|
||||||
|
this.pageForm.searchKeyword = this.keyword.trim()
|
||||||
|
this.tableData = []
|
||||||
|
this.finished = false
|
||||||
|
this.loadError = false
|
||||||
|
this.onLoad()
|
||||||
|
},
|
||||||
|
async onLoad() {
|
||||||
|
if (this.pending || this.finished) return
|
||||||
|
const requestId = this.requestId
|
||||||
|
this.pending = true
|
||||||
|
this.loading = true
|
||||||
|
this.loadError = false
|
||||||
|
try {
|
||||||
|
const res = await $.post('/mobile/member/getMemberData', Object.assign({}, this.pageForm))
|
||||||
|
if (requestId !== this.requestId) return
|
||||||
|
if (res.code !== 0 || !res.data || !Array.isArray(res.data.list)) {
|
||||||
|
throw new Error('会员查询失败')
|
||||||
|
}
|
||||||
|
this.tableData = this.tableData.concat(res.data.list)
|
||||||
|
this.pageForm.totalCount = res.data.totalCount
|
||||||
|
this.finished = res.data.list.length === 0 || this.tableData.length >= res.data.totalCount
|
||||||
|
if (!this.finished) this.pageForm.pageNumber++
|
||||||
|
} catch (e) {
|
||||||
|
if (requestId === this.requestId) this.loadError = true
|
||||||
|
} finally {
|
||||||
|
if (requestId === this.requestId) {
|
||||||
|
this.pending = false
|
||||||
|
this.loading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async openView(member) {
|
||||||
|
if (!member || !member.id) {
|
||||||
|
this.$toast.fail('缺少会员信息')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const requestId = ++this.detailRequestId
|
||||||
|
this.selectedMember = member
|
||||||
|
this.memberInfo = null
|
||||||
|
this.showDetail = true
|
||||||
|
this.detailLoading = true
|
||||||
|
this.detailError = false
|
||||||
|
try {
|
||||||
|
const res = await $.get('/mobile/member/viewInfo', {id: member.id})
|
||||||
|
if (requestId !== this.detailRequestId) return
|
||||||
|
if (res.code !== 0) throw new Error('会员详情加载失败')
|
||||||
|
this.memberInfo = res.data
|
||||||
|
} catch (e) {
|
||||||
|
if (requestId === this.detailRequestId) this.detailError = true
|
||||||
|
} finally {
|
||||||
|
if (requestId === this.detailRequestId) this.detailLoading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.doSearch()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--#
|
||||||
|
}
|
||||||
|
#-->
|
||||||
@@ -26,7 +26,6 @@ layout("/mobile/platform.html"){
|
|||||||
<van-field v-model="formData.auditTime" label="审核时间" readonly></van-field>
|
<van-field v-model="formData.auditTime" label="审核时间" readonly></van-field>
|
||||||
|
|
||||||
<van-field
|
<van-field
|
||||||
required
|
|
||||||
v-model="formData.auditOpinion"
|
v-model="formData.auditOpinion"
|
||||||
rows="1"
|
rows="1"
|
||||||
autosize
|
autosize
|
||||||
@@ -46,12 +45,12 @@ layout("/mobile/platform.html"){
|
|||||||
|
|
||||||
<van-row gutter="20" style="margin-top: 30px;padding: 0 25px">
|
<van-row gutter="20" style="margin-top: 30px;padding: 0 25px">
|
||||||
<van-col span="12">
|
<van-col span="12">
|
||||||
<van-button :color="themeColor" plain block @click="doAudit(false)">拒 绝
|
<van-button :color="themeColor" plain block :loading="formLoading" :disabled="formLoading" @click="doAudit(false)">拒 绝
|
||||||
</van-button>
|
</van-button>
|
||||||
</van-col>
|
</van-col>
|
||||||
|
|
||||||
<van-col span="12">
|
<van-col span="12">
|
||||||
<van-button :color="themeColor" block @click="doAudit(true)">通 过
|
<van-button :color="themeColor" block :loading="formLoading" :disabled="formLoading" @click="doAudit(true)">通 过
|
||||||
</van-button>
|
</van-button>
|
||||||
</van-col>
|
</van-col>
|
||||||
</van-row>
|
</van-row>
|
||||||
@@ -72,6 +71,7 @@ layout("/mobile/platform.html"){
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
handle: true,
|
handle: true,
|
||||||
|
formLoading: false,
|
||||||
id: "",
|
id: "",
|
||||||
formData: {},
|
formData: {},
|
||||||
}
|
}
|
||||||
@@ -81,25 +81,27 @@ layout("/mobile/platform.html"){
|
|||||||
'mobile-sign': httpVueLoader('/components/sign/mobileSign.vue'),
|
'mobile-sign': httpVueLoader('/components/sign/mobileSign.vue'),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async doAudit(pass) {
|
doAudit(pass) {
|
||||||
if (!this.formData.auditOpinion) {
|
if (this.formLoading) return
|
||||||
this.$toast.fail('请填写审核意见');
|
// 与 PC 共用审核参数;提交前读取手写签名,避免仅提交历史签名。
|
||||||
return
|
this.$refs.signature.submitSign()
|
||||||
}
|
this.$set(this.formData, 'auditPass', pass)
|
||||||
this.formData.auditPass = pass
|
this.formLoading = true
|
||||||
const resp = await $.post("/platform/member/apply/audit/doAudit", this.formData)
|
$.post('/platform/member/apply/audit/doAudit', this.formData).then(resp => {
|
||||||
requestLaterFun(resp, (data) => {
|
requestLaterFun(resp, () => {
|
||||||
this.$toast.success('审核成功');
|
this.$toast.success('审核成功')
|
||||||
setTimeout(() => {
|
location.replace('/mobile/member/audit')
|
||||||
location.href = '/mobile/member/audit'
|
|
||||||
}, 1000)
|
|
||||||
}, () => {
|
|
||||||
this.$toast.fail('审核失败');
|
|
||||||
}, () => {
|
}, () => {
|
||||||
|
this.$toast.fail('审核失败')
|
||||||
|
}, () => {})
|
||||||
|
}).fail(() => {
|
||||||
|
this.$toast.fail('审核失败,请稍后重试')
|
||||||
|
}).always(() => {
|
||||||
|
this.formLoading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
async created() {
|
created() {
|
||||||
const record_id = GetQueryString("record_id")
|
const record_id = GetQueryString("record_id")
|
||||||
const user_id = GetQueryString("user_id")
|
const user_id = GetQueryString("user_id")
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ layout("/mobile/platform.html"){
|
|||||||
|
|
||||||
<van-field v-model="formData.auditTime" label="审核时间" readonly></van-field>
|
<van-field v-model="formData.auditTime" label="审核时间" readonly></van-field>
|
||||||
|
|
||||||
<van-field required
|
<van-field
|
||||||
v-model="formData.auditOpinion"
|
v-model="formData.auditOpinion"
|
||||||
rows="1"
|
rows="1"
|
||||||
autosize
|
autosize
|
||||||
@@ -45,12 +45,12 @@ layout("/mobile/platform.html"){
|
|||||||
|
|
||||||
<van-row gutter="20" style="margin-top: 30px;padding: 0 25px">
|
<van-row gutter="20" style="margin-top: 30px;padding: 0 25px">
|
||||||
<van-col span="12">
|
<van-col span="12">
|
||||||
<van-button :color="themeColor" plain block @click="doAudit(false)">拒 绝
|
<van-button :color="themeColor" plain block :loading="formLoading" :disabled="formLoading" @click="doAudit(false)">拒 绝
|
||||||
</van-button>
|
</van-button>
|
||||||
</van-col>
|
</van-col>
|
||||||
|
|
||||||
<van-col span="12">
|
<van-col span="12">
|
||||||
<van-button :color="themeColor" block @click="doAudit(true)">通 过
|
<van-button :color="themeColor" block :loading="formLoading" :disabled="formLoading" @click="doAudit(true)">通 过
|
||||||
</van-button>
|
</van-button>
|
||||||
</van-col>
|
</van-col>
|
||||||
</van-row>
|
</van-row>
|
||||||
@@ -70,6 +70,7 @@ layout("/mobile/platform.html"){
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
handle: true,
|
handle: true,
|
||||||
|
formLoading: false,
|
||||||
id: "",
|
id: "",
|
||||||
formData: {},
|
formData: {},
|
||||||
}
|
}
|
||||||
@@ -80,25 +81,27 @@ layout("/mobile/platform.html"){
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
async doAudit(pass) {
|
doAudit(pass) {
|
||||||
if (!this.formData.auditOpinion) {
|
if (this.formLoading) return
|
||||||
this.$toast.fail('请填写审核意见');
|
// 与 PC 共用审核参数;提交前读取手写签名,避免仅提交历史签名。
|
||||||
return
|
this.$refs.signature.submitSign()
|
||||||
}
|
this.$set(this.formData, 'auditPass', pass)
|
||||||
this.formData.auditPass = pass
|
this.formLoading = true
|
||||||
const resp = await $.post("/platform/member/apply/audit/doAudit", this.formData)
|
$.post('/platform/member/apply/audit/doAudit', this.formData).then(resp => {
|
||||||
requestLaterFun(resp, (data) => {
|
requestLaterFun(resp, () => {
|
||||||
this.$toast.success('审核成功');
|
this.$toast.success('审核成功')
|
||||||
setTimeout(() => {
|
location.replace('/mobile/member/audit')
|
||||||
location.href = '/mobile/member/audit'
|
|
||||||
}, 1000)
|
|
||||||
}, () => {
|
|
||||||
this.$toast.fail('审核失败');
|
|
||||||
}, () => {
|
}, () => {
|
||||||
|
this.$toast.fail('审核失败')
|
||||||
|
}, () => {})
|
||||||
|
}).fail(() => {
|
||||||
|
this.$toast.fail('审核失败,请稍后重试')
|
||||||
|
}).always(() => {
|
||||||
|
this.formLoading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
async created() {
|
created() {
|
||||||
const record_id = GetQueryString("record_id")
|
const record_id = GetQueryString("record_id")
|
||||||
const user_id = GetQueryString("user_id")
|
const user_id = GetQueryString("user_id")
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ layout("/mobile/platform.html"){
|
|||||||
@click-left="location.replace('/platform/mobile/trainSignUpActivity/trainList')"></van-nav-bar>
|
@click-left="location.replace('/platform/mobile/trainSignUpActivity/trainList')"></van-nav-bar>
|
||||||
</van-sticky>
|
</van-sticky>
|
||||||
|
|
||||||
<van-image height="186" :src="CREATE_PREVIEW_URL(activity?.cover[0].id)"></van-image>
|
<van-image height="186" :src="activity.cover && activity.cover[0] ? CREATE_PREVIEW_URL(activity.cover[0].id) : ''"></van-image>
|
||||||
<div class="title">{{activity.activityName}}</div>
|
<div class="title">{{activity.activityName}}</div>
|
||||||
|
|
||||||
<van-tabs v-model:active="tabActive" shrink>
|
<van-tabs v-model:active="tabActive" shrink>
|
||||||
|
|||||||
@@ -450,6 +450,8 @@ layout("/layouts/platform.html"){
|
|||||||
prop="mobile" header-align="center" align="center"
|
prop="mobile" header-align="center" align="center"
|
||||||
label="电话">
|
label="电话">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column prop="birthday" header-align="center" align="center"
|
||||||
|
label="出生年月"></el-table-column>
|
||||||
|
|
||||||
<el-table-column
|
<el-table-column
|
||||||
align="center" header-align="center" label="年龄"
|
align="center" header-align="center" label="年龄"
|
||||||
@@ -641,6 +643,8 @@ layout("/layouts/platform.html"){
|
|||||||
prop="mobile" header-align="center" align="center"
|
prop="mobile" header-align="center" align="center"
|
||||||
label="电话">
|
label="电话">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column prop="birthday" header-align="center" align="center"
|
||||||
|
label="出生年月"></el-table-column>
|
||||||
|
|
||||||
<el-table-column
|
<el-table-column
|
||||||
prop="sex" header-align="center" align="center"
|
prop="sex" header-align="center" align="center"
|
||||||
@@ -714,7 +718,7 @@ layout("/layouts/platform.html"){
|
|||||||
:visible.sync="dialogLeaderCoach"
|
:visible.sync="dialogLeaderCoach"
|
||||||
width="60%"
|
width="60%"
|
||||||
>
|
>
|
||||||
<el-form :model="headData" ref="form" :rules="formRules" label-width="100px">
|
<el-form :model="headData" ref="leaderCoachForm" :rules="formRules" label-width="100px">
|
||||||
<el-row gutter="20">
|
<el-row gutter="20">
|
||||||
<!-- <el-col :span="12">
|
<!-- <el-col :span="12">
|
||||||
<vi-title title="填写团长信息"></vi-title>
|
<vi-title title="填写团长信息"></vi-title>
|
||||||
@@ -878,7 +882,7 @@ layout("/layouts/platform.html"){
|
|||||||
</el-form>
|
</el-form>
|
||||||
<span slot="footer" class="dialog-footer">
|
<span slot="footer" class="dialog-footer">
|
||||||
<el-button @click="dialogLeaderCoach = false">取 消</el-button>
|
<el-button @click="dialogLeaderCoach = false">取 消</el-button>
|
||||||
<el-button type="primary" plain @click="doLeaderCoach">确 认</el-button>
|
<el-button type="primary" plain :loading="formLoading" @click="doLeaderCoach">确 认</el-button>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -902,62 +906,58 @@ layout("/layouts/platform.html"){
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="username" label="姓  名">
|
<el-form-item prop="username" label="姓  名">
|
||||||
<el-select
|
<el-autocomplete style="width: 100%" maxlength="50" :trigger-on-focus="false"
|
||||||
:remote-method="querySearchAsync"
|
placeholder="输入姓名或工号搜索,未匹配时直接填写姓名"
|
||||||
@change="addUserChange"
|
:fetch-suggestions="searchExternalUser" v-model="formData.username"
|
||||||
filterable
|
@input="changeExternalName" @select="selectExternalUser">
|
||||||
placeholder="请输入工号或者下姓名查询"
|
<template slot-scope="{ item }">{{item.username}}({{item.loginname}})</template>
|
||||||
remote
|
</el-autocomplete>
|
||||||
reserve-keyword
|
|
||||||
style="width: 100%"
|
|
||||||
v-model="formData.userId">
|
|
||||||
<el-option
|
|
||||||
:key="item.id"
|
|
||||||
:label="item.username+'-'+item.loginname"
|
|
||||||
:value="item.id"
|
|
||||||
v-for="item in lsUserList">
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="loginname" label="工  号">
|
<el-form-item prop="loginname" label="工  号">
|
||||||
<el-input disabled maxlength="50" placeholder="请填写工号" v-model="formData.loginname"
|
<el-input :disabled="!!formData.matchedUserId" maxlength="50" placeholder="留空自动生成,也可手动填写" v-model="formData.loginname"
|
||||||
type="text"></el-input>
|
type="text"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="性  别" prop="sex">
|
<el-form-item label="性  别" prop="sex">
|
||||||
<el-radio-group v-model="formData.sex">
|
<el-radio-group v-model="formData.sex" :disabled="!!formData.matchedUserId && !!selectedExternalUser && !!selectedExternalUser.sex">
|
||||||
<el-radio :label="'男'" border>男</el-radio>
|
<el-radio :label="'男'" border>男</el-radio>
|
||||||
<el-radio :label="'女'" border>女</el-radio>
|
<el-radio :label="'女'" border>女</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="身份证号" prop="idcard">
|
||||||
|
<el-input maxlength="18" placeholder="请填写身份证号"
|
||||||
|
v-model="formData.idcard" @input="updateExternalBirthday"></el-input>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="出生年月" prop="birthday">
|
<el-form-item label="出生年月" prop="birthday">
|
||||||
<el-date-picker
|
<el-date-picker style="width: 100%" type="date" value-format="yyyy-MM-dd"
|
||||||
placeholder="选择出生年月"
|
placeholder="从身份证号读取,也可手动选择" v-model="formData.birthday"></el-date-picker>
|
||||||
style="width: 100%"
|
|
||||||
type="date"
|
|
||||||
v-model="formData.birthday"
|
|
||||||
value-format="yyyy-MM-dd">
|
|
||||||
</el-date-picker>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="电  话" prop="mobile">
|
<el-form-item label="电  话" prop="mobile">
|
||||||
<el-input maxlength="11" placeholder="请填写电话" type="text"
|
<el-input maxlength="11" placeholder="请填写电话" type="text"
|
||||||
v-model="formData.mobile"></el-input>
|
v-model="formData.mobile"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="unitId" label="所在单位">
|
<el-form-item prop="unitname" label="所在单位">
|
||||||
<el-select clearable filterable placeholder="请选择所在单位" style="width: 100%"
|
<el-select v-if="formData.matchedUserId" filterable style="width: 100%"
|
||||||
disabled v-model="formData.unitId">
|
placeholder="请选择报名使用的单位" v-model="formData.unitId" @change="changeExternalUnit">
|
||||||
<el-option
|
<el-option v-for="item in unitOptions" :key="item.id" :label="item.name"
|
||||||
v-for="item in unitOptions"
|
:value="item.id"></el-option>
|
||||||
:key="item.id"
|
|
||||||
:label="item.name"
|
|
||||||
:value="item.id">
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
|
<el-autocomplete v-else style="width: 100%" maxlength="100"
|
||||||
|
placeholder="搜索选择单位,或直接输入其他单位"
|
||||||
|
:fetch-suggestions="searchExternalUnit" v-model="formData.unitname"
|
||||||
|
@input="changeExternalUnitInput" @select="selectExternalUnit"></el-autocomplete>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="身体条件" prop="fitForCompetition">
|
||||||
|
<el-radio-group v-model="formData.fitForCompetition">
|
||||||
|
<el-radio :label="true" border>适合参赛</el-radio>
|
||||||
|
<el-radio :label="false" border>不适合参赛</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<span slot="footer" class="dialog-footer">
|
<span slot="footer" class="dialog-footer">
|
||||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
<el-button type="primary" @click="doAddUser">确 定</el-button>
|
<el-button type="primary" :loading="formLoading" :disabled="formData.fitForCompetition !== true"
|
||||||
|
@click="doAddUser(false)">确 定</el-button>
|
||||||
</span>
|
</span>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
@@ -966,35 +966,60 @@ layout("/layouts/platform.html"){
|
|||||||
:visible.sync="dialogVisible2"
|
:visible.sync="dialogVisible2"
|
||||||
width="40%"
|
width="40%"
|
||||||
>
|
>
|
||||||
<el-form :model="formData" ref="form" :rules="formRules" label-width="100px">
|
<el-form :model="formData" ref="singleExternalForm" :rules="lsryRules" label-width="100px">
|
||||||
<el-form-item prop="username" label="姓  名">
|
<el-form-item prop="username" label="姓  名">
|
||||||
<el-input maxlength="50" placeholder="请填写姓名" v-model="formData.username"
|
<el-autocomplete style="width: 100%" maxlength="50" :trigger-on-focus="false"
|
||||||
type="text"></el-input>
|
placeholder="输入姓名或工号搜索,未匹配时直接填写姓名"
|
||||||
|
:fetch-suggestions="searchExternalUser" v-model="formData.username"
|
||||||
|
@input="changeExternalName" @select="selectExternalUser">
|
||||||
|
<template slot-scope="{ item }">{{item.username}}({{item.loginname}})</template>
|
||||||
|
</el-autocomplete>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="loginname" label="工  号">
|
<el-form-item prop="loginname" label="工  号">
|
||||||
<el-input maxlength="50" placeholder="请填写工号" v-model="formData.loginname"
|
<el-input :disabled="!!formData.matchedUserId" maxlength="50" placeholder="留空自动生成,也可手动填写" v-model="formData.loginname"
|
||||||
type="text"></el-input>
|
type="text"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="性  别" prop="sex">
|
||||||
|
<el-radio-group v-model="formData.sex" :disabled="!!formData.matchedUserId && !!selectedExternalUser && !!selectedExternalUser.sex">
|
||||||
|
<el-radio :label="'男'" border>男</el-radio>
|
||||||
|
<el-radio :label="'女'" border>女</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="身份证号" prop="idcard">
|
||||||
|
<el-input maxlength="18" placeholder="请填写身份证号"
|
||||||
|
v-model="formData.idcard" @input="updateExternalBirthday"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="出生年月" prop="birthday">
|
||||||
|
<el-date-picker style="width: 100%" type="date" value-format="yyyy-MM-dd"
|
||||||
|
placeholder="从身份证号读取,也可手动选择" v-model="formData.birthday"></el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item prop="mobile" label="电  话">
|
<el-form-item prop="mobile" label="电  话">
|
||||||
<el-input maxlength="50" placeholder="请填写电话" v-model="formData.mobile"
|
<el-input maxlength="11" placeholder="请填写电话" v-model="formData.mobile"
|
||||||
type="text"></el-input>
|
type="text"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="unitId" label="所在单位">
|
<el-form-item prop="unitname" label="所在单位">
|
||||||
<el-select clearable filterable placeholder="请选择所在单位" style="width: 100%"
|
<el-select v-if="formData.matchedUserId" filterable style="width: 100%"
|
||||||
v-model="formData.unitId">
|
placeholder="请选择报名使用的单位" v-model="formData.unitId" @change="changeExternalUnit">
|
||||||
<el-option
|
<el-option v-for="item in unitOptions" :key="item.id" :label="item.name"
|
||||||
v-for="item in unitOptions"
|
:value="item.id"></el-option>
|
||||||
:key="item.id"
|
|
||||||
:label="item.name"
|
|
||||||
:value="item.id">
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
|
<el-autocomplete v-else style="width: 100%" maxlength="100"
|
||||||
|
placeholder="搜索选择单位,或直接输入其他单位"
|
||||||
|
:fetch-suggestions="searchExternalUnit" v-model="formData.unitname"
|
||||||
|
@input="changeExternalUnitInput" @select="selectExternalUnit"></el-autocomplete>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="身体条件" prop="fitForCompetition">
|
||||||
|
<el-radio-group v-model="formData.fitForCompetition">
|
||||||
|
<el-radio :label="true" border>适合参赛</el-radio>
|
||||||
|
<el-radio :label="false" border>不适合参赛</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<span slot="footer" class="dialog-footer">
|
<span slot="footer" class="dialog-footer">
|
||||||
<el-button @click="dialogVisible2 = false">取 消</el-button>
|
<el-button @click="dialogVisible2 = false">取 消</el-button>
|
||||||
<el-button type="primary" @click="doAddUser2">确 定</el-button>
|
<el-button type="primary" :loading="formLoading" :disabled="formData.fitForCompetition !== true"
|
||||||
|
@click="doAddUser(true)">确 定</el-button>
|
||||||
</span>
|
</span>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
@@ -1058,6 +1083,10 @@ layout("/layouts/platform.html"){
|
|||||||
},
|
},
|
||||||
activeName: '',
|
activeName: '',
|
||||||
userOptions: [],
|
userOptions: [],
|
||||||
|
selectedExternalUser: null,
|
||||||
|
selectedExternalUnit: null,
|
||||||
|
externalSearchLoading: false,
|
||||||
|
externalSearchQuery: '',
|
||||||
applyUsers: [],
|
applyUsers: [],
|
||||||
applyValue: [],
|
applyValue: [],
|
||||||
applyData: [],
|
applyData: [],
|
||||||
@@ -1109,13 +1138,30 @@ layout("/layouts/platform.html"){
|
|||||||
// userId: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
// userId: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||||
},
|
},
|
||||||
lsryRules: {
|
lsryRules: {
|
||||||
loginname: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
username: [{required: true, message: '请填写姓名', trigger: 'blur'}],
|
||||||
|
loginname: [{validator: (rule, value, callback) => {
|
||||||
|
if (this.formData.matchedUserId && !value) {
|
||||||
|
callback(new Error('所选系统人员没有工号'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
}, trigger: ['blur', 'change']}],
|
||||||
sex: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
sex: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||||
|
idcard: [{validator: (rule, value, callback) => {
|
||||||
|
const card = (value || '').toUpperCase()
|
||||||
|
const date = card.substring(6, 14)
|
||||||
|
if (!/^[0-9]{17}[0-9X]$/.test(card) || !moment(date, 'YYYYMMDD', true).isValid()) {
|
||||||
|
callback(new Error('请填写正确的18位身份证号'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
}, trigger: ['blur', 'change']}],
|
||||||
|
birthday: [{required: true, message: '请选择出生年月', trigger: 'change'}],
|
||||||
mobile: [
|
mobile: [
|
||||||
{required: true, message: '手机号码', trigger: ['blur', 'change']},
|
{required: true, message: '手机号码', trigger: ['blur', 'change']},
|
||||||
{pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码'}],
|
{pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码'}],
|
||||||
unitId: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
unitname: [{required: true, message: '请选择或填写单位', trigger: ['blur', 'change']}],
|
||||||
userId: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
fitForCompetition: [{required: true, message: '请选择身体条件', trigger: 'change'}],
|
||||||
},
|
},
|
||||||
submitLoading: false,
|
submitLoading: false,
|
||||||
selection: [],
|
selection: [],
|
||||||
@@ -1141,54 +1187,6 @@ layout("/layouts/platform.html"){
|
|||||||
'delete_info': httpVueLoader('/components/activity/school/DeleteInfo.vue'),
|
'delete_info': httpVueLoader('/components/activity/school/DeleteInfo.vue'),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
//查找今年临时人员
|
|
||||||
async getGhLsRy() {
|
|
||||||
const resp = await $.get(loc() + "/getGhLsRy")
|
|
||||||
return resp.data
|
|
||||||
},
|
|
||||||
async addUserChange(val) {
|
|
||||||
const user = this.lsUserList.find(l => l.id === val)
|
|
||||||
let loginname = "GHLS" + moment().format('YYYY') + "001"
|
|
||||||
//如果数据库找不到此人
|
|
||||||
if (!user) {
|
|
||||||
const lsryUser = await this.getGhLsRy()
|
|
||||||
//如果有临时人员
|
|
||||||
if (lsryUser) {
|
|
||||||
let str = lsryUser.loginname;
|
|
||||||
let prefix = "GHLS";
|
|
||||||
// 找到"GHLS"在字符串中首次出现的位置
|
|
||||||
let index = str.indexOf(prefix);
|
|
||||||
// 如果"GHLS"确实存在于字符串中,并且不是在字符串开头
|
|
||||||
if (index !== -1 && index + prefix.length < str.length) {
|
|
||||||
loginname = prefix + (Number(str.slice(index + prefix.length)) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.$set(this.formData, 'userId', user ? user.id : val)
|
|
||||||
this.$set(this.formData, 'loginname', user ? user.loginname : loginname)
|
|
||||||
this.$set(this.formData, 'username', user ? user.username : val)
|
|
||||||
this.$set(this.formData, 'unitId', user ? user.unitid : "${@shiro.getPrincipalProperty('unit').getId()}")
|
|
||||||
this.$set(this.formData, 'sex', user ? user.sex : null)
|
|
||||||
this.$set(this.formData, 'birthday', user ? user.birthday : null)
|
|
||||||
this.$set(this.formData, 'mobile', user ? user.mobile : null)
|
|
||||||
this.$set(this.formData, 'status', 2)
|
|
||||||
},
|
|
||||||
async querySearchAsync(queryString) {
|
|
||||||
const applyDataIdList = this.applyData.map(m => m.id)
|
|
||||||
const appliedDataUserIdList = this.appliedData.map(m => m.userId)
|
|
||||||
const ids = applyDataIdList.concat(appliedDataUserIdList)
|
|
||||||
const {code, data} = await $.get(loc() + "/getSysUser", {
|
|
||||||
queryString: queryString,
|
|
||||||
})
|
|
||||||
if (code === 0) {
|
|
||||||
this.lsUserList = data
|
|
||||||
} else {
|
|
||||||
this.lsUserList = []
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
},
|
|
||||||
setLeader2() {
|
setLeader2() {
|
||||||
if (!this.selection.length) {
|
if (!this.selection.length) {
|
||||||
this.$notify({
|
this.$notify({
|
||||||
@@ -1339,8 +1337,13 @@ layout("/layouts/platform.html"){
|
|||||||
handleSelectionChange(val) {
|
handleSelectionChange(val) {
|
||||||
this.selection = val;
|
this.selection = val;
|
||||||
},
|
},
|
||||||
async changeLeader() {
|
changeLeader(value) {
|
||||||
const userData = await this.getUserData(this.LeaderData.userId);
|
if (!value) {
|
||||||
|
this.LeaderData = {}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.getUserData(value).then((userData) => {
|
||||||
|
if (this.LeaderData.userId !== value) return
|
||||||
this.$set(this.LeaderData, 'userId', this.LeaderData.userId)
|
this.$set(this.LeaderData, 'userId', this.LeaderData.userId)
|
||||||
this.$set(this.LeaderData, 'loginname', userData.loginname)
|
this.$set(this.LeaderData, 'loginname', userData.loginname)
|
||||||
this.$set(this.LeaderData, 'username', userData.username)
|
this.$set(this.LeaderData, 'username', userData.username)
|
||||||
@@ -1355,9 +1358,15 @@ layout("/layouts/platform.html"){
|
|||||||
this.$set(this.LeaderData, 'activityId', this.activityData2.id)
|
this.$set(this.LeaderData, 'activityId', this.activityData2.id)
|
||||||
this.$set(this.LeaderData, 'divisionLevelLeadership', false)
|
this.$set(this.LeaderData, 'divisionLevelLeadership', false)
|
||||||
this.$set(this.LeaderData, 'unionCoach', false)
|
this.$set(this.LeaderData, 'unionCoach', false)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
async changeCoach() {
|
changeCoach(value) {
|
||||||
const userData = await this.getUserData(this.CoachData.userId);
|
if (!value) {
|
||||||
|
this.CoachData = {}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.getUserData(value).then((userData) => {
|
||||||
|
if (this.CoachData.userId !== value) return
|
||||||
this.$set(this.CoachData, 'userId', this.CoachData.userId)
|
this.$set(this.CoachData, 'userId', this.CoachData.userId)
|
||||||
this.$set(this.CoachData, 'loginname', userData.loginname)
|
this.$set(this.CoachData, 'loginname', userData.loginname)
|
||||||
this.$set(this.CoachData, 'username', userData.username)
|
this.$set(this.CoachData, 'username', userData.username)
|
||||||
@@ -1373,9 +1382,15 @@ layout("/layouts/platform.html"){
|
|||||||
this.$set(this.CoachData, 'divisionLevelLeadership', false)
|
this.$set(this.CoachData, 'divisionLevelLeadership', false)
|
||||||
this.$set(this.CoachData, 'unionLeader', false)
|
this.$set(this.CoachData, 'unionLeader', false)
|
||||||
|
|
||||||
|
})
|
||||||
},
|
},
|
||||||
async changeStaff() {
|
changeStaff(value) {
|
||||||
const userData = await this.getUserData(this.staffData.userId);
|
if (!value) {
|
||||||
|
this.staffData = {}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.getUserData(value).then((userData) => {
|
||||||
|
if (this.staffData.userId !== value) return
|
||||||
this.$set(this.staffData, 'userId', this.staffData.userId)
|
this.$set(this.staffData, 'userId', this.staffData.userId)
|
||||||
this.$set(this.staffData, 'loginname', userData.loginname)
|
this.$set(this.staffData, 'loginname', userData.loginname)
|
||||||
this.$set(this.staffData, 'username', userData.username)
|
this.$set(this.staffData, 'username', userData.username)
|
||||||
@@ -1389,9 +1404,15 @@ layout("/layouts/platform.html"){
|
|||||||
this.$set(this.staffData, 'awardsMode', 2)
|
this.$set(this.staffData, 'awardsMode', 2)
|
||||||
this.$set(this.staffData, 'activityId', this.activityData2.id)
|
this.$set(this.staffData, 'activityId', this.activityData2.id)
|
||||||
|
|
||||||
|
})
|
||||||
},
|
},
|
||||||
async changeHead() {
|
changeHead(value) {
|
||||||
const userData = await this.getUserData(this.headData.userId);
|
if (!value) {
|
||||||
|
this.headData = {}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.getUserData(value).then((userData) => {
|
||||||
|
if (this.headData.userId !== value) return
|
||||||
this.$set(this.headData, 'userId', this.headData.userId)
|
this.$set(this.headData, 'userId', this.headData.userId)
|
||||||
this.$set(this.headData, 'loginname', userData.loginname)
|
this.$set(this.headData, 'loginname', userData.loginname)
|
||||||
this.$set(this.headData, 'username', userData.username)
|
this.$set(this.headData, 'username', userData.username)
|
||||||
@@ -1408,80 +1429,73 @@ layout("/layouts/platform.html"){
|
|||||||
this.$set(this.headData, 'divisionLevelLeadership', false)
|
this.$set(this.headData, 'divisionLevelLeadership', false)
|
||||||
this.$set(this.headData, 'unionLeader', false)
|
this.$set(this.headData, 'unionLeader', false)
|
||||||
|
|
||||||
|
})
|
||||||
},
|
},
|
||||||
async doLeaderCoach() {
|
doLeaderCoach() {
|
||||||
this.$refs["form"].validate(async (valid) => {
|
this.$refs["leaderCoachForm"].validate((valid) => {
|
||||||
if (valid) {
|
if (!valid) return
|
||||||
let loading = this.$loading({
|
this.formLoading = true
|
||||||
lock: true,
|
$.post(loc() + "/doLeaderCoachHead", {
|
||||||
text: '正在提交...',
|
activityId: this.activityData2.id,
|
||||||
spinner: 'el-icon-loading',
|
|
||||||
background: COVER_LAYER_COLOR
|
|
||||||
});
|
|
||||||
const resp = await $.post(loc() + "/doLeaderCoachHead",
|
|
||||||
{
|
|
||||||
LeaderData: JSON.stringify(this.LeaderData),
|
LeaderData: JSON.stringify(this.LeaderData),
|
||||||
CoachData: JSON.stringify(this.CoachData),
|
CoachData: JSON.stringify(this.CoachData),
|
||||||
headData: JSON.stringify(this.headData),
|
headData: JSON.stringify(this.headData),
|
||||||
staffData: JSON.stringify(this.staffData)
|
staffData: JSON.stringify(this.staffData)
|
||||||
|
}).then((resp) => {
|
||||||
|
if (resp.code !== 0) {
|
||||||
|
this.$message.error(resp.msg)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
)
|
return this.getUnionCoachLeaderHead().then((data) => {
|
||||||
closeLoadingFunc(loading, resp, async () => {
|
if (!data) return
|
||||||
this.activityData2.CoachCount = 1
|
this.$set(this.activityData2, 'CoachCount', data.unionCoach ? 1 : 0)
|
||||||
this.activityData2.LeaderCount = 1
|
this.$set(this.activityData2, 'LeaderCount', data.unionLeader ? 1 : 0)
|
||||||
await this.getUnionCoachLeaderHead()
|
this.dialogLeaderCoach = false
|
||||||
this.dialogLeaderCoach = false;
|
})
|
||||||
|
}).fail(() => {
|
||||||
|
this.$message.error('保存失败')
|
||||||
}, (data, msg) => {
|
}).always(() => {
|
||||||
this.$message.error(msg);
|
this.formLoading = false
|
||||||
})
|
})
|
||||||
}
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
async getUnionCoachLeaderHead() {
|
getUnionCoachLeaderHead() {
|
||||||
this.LeaderData = {}
|
this.LeaderData = {}
|
||||||
this.CoachData = {}
|
this.CoachData = {}
|
||||||
this.headData = {}
|
this.headData = {}
|
||||||
this.staffData = {}
|
this.staffData = {}
|
||||||
const resp = await $.get(loc() + "/getUnionCoachLeaderHead", {activityId: this.activityData2.id})
|
return $.post(loc() + "/getUnionCoachLeaderHead", {activityId: this.activityData2.id})
|
||||||
|
.then((resp) => {
|
||||||
|
if (resp.code !== 0) {
|
||||||
|
this.$message.error(resp.msg)
|
||||||
|
return null
|
||||||
|
}
|
||||||
const {unionCoach, unionLeader, unionHead, unionStaff, userOptions} = resp.data
|
const {unionCoach, unionLeader, unionHead, unionStaff, userOptions} = resp.data
|
||||||
if (unionCoach) {
|
if (unionCoach) this.CoachData = unionCoach
|
||||||
this.CoachData = unionCoach
|
if (unionLeader) this.LeaderData = unionLeader
|
||||||
}
|
if (unionHead) this.headData = unionHead
|
||||||
if (unionLeader) {
|
if (unionStaff) this.staffData = unionStaff
|
||||||
this.LeaderData = unionLeader
|
|
||||||
}
|
|
||||||
if (unionHead) {
|
|
||||||
this.headData = unionHead
|
|
||||||
}
|
|
||||||
if (unionStaff) {
|
|
||||||
this.staffData = unionStaff
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
this.userOptions = userOptions
|
this.userOptions = userOptions
|
||||||
|
return resp.data
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
async openLeaderCoach() {
|
openLeaderCoach() {
|
||||||
if (this.activityData2.CoachCount > 0 || this.activityData2.LeaderCount > 0) {
|
this.getUnionCoachLeaderHead().then((data) => {
|
||||||
await this.getUnionCoachLeaderHead()
|
if (data) this.dialogLeaderCoach = true
|
||||||
this.dialogLeaderCoach = true
|
})
|
||||||
} else {
|
|
||||||
this.LeaderData = {}
|
|
||||||
this.CoachData = {}
|
|
||||||
this.dialogLeaderCoach = true
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
},
|
||||||
async userLeaderCoach(query) {
|
|
||||||
if (query) {
|
userLeaderCoach(query) {
|
||||||
|
if (!query) return
|
||||||
this.userLoading = true
|
this.userLoading = true
|
||||||
const resp = await $.get(loc() + "/getUserUnion", {query})
|
$.post(loc() + "/getUserUnion", {query})
|
||||||
|
.then((resp) => {
|
||||||
this.userOptions = resp
|
this.userOptions = resp
|
||||||
|
}).always(() => {
|
||||||
this.userLoading = false
|
this.userLoading = false
|
||||||
}
|
})
|
||||||
},
|
},
|
||||||
joinMemberFamily() {
|
joinMemberFamily() {
|
||||||
if (!this.selection.length) {
|
if (!this.selection.length) {
|
||||||
@@ -1523,30 +1537,33 @@ layout("/layouts/platform.html"){
|
|||||||
this.openSingleApply(row)
|
this.openSingleApply(row)
|
||||||
}*/
|
}*/
|
||||||
},
|
},
|
||||||
async openApply(item) {
|
openApply(item) {
|
||||||
this.$set(this.pageForm, "isMenWomen", 1)
|
this.$set(this.pageForm, "isMenWomen", 1)
|
||||||
this.activityData2 = item
|
this.activityData2 = item
|
||||||
this.pageForm.activityId = item.id
|
this.pageForm.activityId = item.id
|
||||||
if (item.applyType == 2) {
|
if (item.applyType == 2) {
|
||||||
await this.getUnionCoachLeaderHead()
|
this.getUnionCoachLeaderHead().then((data) => {
|
||||||
|
if (!data) return
|
||||||
this.unionLeaderCoach = true
|
this.unionLeaderCoach = true
|
||||||
|
this.pageData()
|
||||||
|
this.changeActivit()
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
this.unionLeaderCoach = false
|
this.unionLeaderCoach = false
|
||||||
}
|
|
||||||
this.pageData()
|
this.pageData()
|
||||||
|
this.changeActivit()
|
||||||
await this.changeActivit()
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
async changeYear() {
|
async changeYear() {
|
||||||
const resp = await $.post(loc() + "/getActivits", {year: this.pageForm.year})
|
const resp = await $.post(loc() + "/getActivits", {year: this.pageForm.year})
|
||||||
this.activitys = resp
|
this.activitys = resp
|
||||||
},
|
},
|
||||||
async changeActivit() {
|
changeActivit() {
|
||||||
const resp = await $.post("/platform/activity/apply/getEvents", {activityId: this.pageForm.activityId})
|
return $.post("/platform/activity/apply/getEvents", {activityId: this.pageForm.activityId})
|
||||||
|
.then((resp) => {
|
||||||
this.events = resp
|
this.events = resp
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
handleTabClick(tab) {
|
handleTabClick(tab) {
|
||||||
@@ -1678,9 +1695,8 @@ layout("/layouts/platform.html"){
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
async getUserData(userId) {
|
getUserData(userId) {
|
||||||
const {data} = await $.get(loc() + "/getUserData", {userId})
|
return $.post(loc() + "/getUserData", {userId}).then((res) => res.data)
|
||||||
return data
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async userChange() {
|
async userChange() {
|
||||||
@@ -1732,74 +1748,200 @@ layout("/layouts/platform.html"){
|
|||||||
this.leaderOptions = [];
|
this.leaderOptions = [];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
doAddUser() {
|
searchExternalUser(query, callback) {
|
||||||
this.$refs["form"].validate(async (valid) => {
|
// 姓名输入框既可搜索系统人员,也可直接填写新人员姓名。
|
||||||
if (valid) {
|
this.externalSearchQuery = query
|
||||||
|
if (!query || !query.trim()) {
|
||||||
const data = {
|
this.externalSearchLoading = false
|
||||||
isAddUser: true,
|
callback([])
|
||||||
age: 0,
|
|
||||||
eventId: this.eventData.eventId,
|
|
||||||
activityId: this.activityData.id,
|
|
||||||
team: this.teams.find(x => x.id === this.formData.teamId).name,
|
|
||||||
unitname: this.unitOptions.find(x => x.id === this.formData.unitId).name,
|
|
||||||
...this.formData
|
|
||||||
}
|
|
||||||
if (this.formData.birthday) {
|
|
||||||
const birthDate = moment(this.formData.birthday);
|
|
||||||
const age = moment().diff(birthDate, 'years');
|
|
||||||
data.age = age
|
|
||||||
}
|
|
||||||
const unitId = "${@shiro.getPrincipalProperty('unit').getId()}"
|
|
||||||
const newUser = this.applyUsers.find(a => a.unitid === unitId &&
|
|
||||||
a.username === this.formData.username)
|
|
||||||
if (newUser) {
|
|
||||||
this.notifyWarning('该窗口只支持添加外援!')
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.appliedData.push(data)
|
this.externalSearchLoading = true
|
||||||
this.sortApplyed()
|
$.post(loc() + "/getSysUser", {queryString: query}).then((res) => {
|
||||||
this.flushApplyed(this.appliedData)
|
if (this.externalSearchQuery !== query) {
|
||||||
this.$notify.success({title: '成功', message: '已添加'});
|
callback([])
|
||||||
this.dialogVisible = false
|
return
|
||||||
} else {
|
|
||||||
this.$notify.error({title: '错误', message: '存在未填写的的必填项'});
|
|
||||||
}
|
}
|
||||||
|
const users = res.code === 0 ? (res.data || []) : []
|
||||||
|
callback(users.map(user => ({...user, value: user.username})))
|
||||||
|
}).fail(() => {
|
||||||
|
callback([])
|
||||||
|
}).always(() => {
|
||||||
|
if (this.externalSearchQuery === query) this.externalSearchLoading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
doAddUser2() {
|
changeExternalName(value) {
|
||||||
this.$refs["form"].validate(async (valid) => {
|
if (!this.selectedExternalUser || value === this.selectedExternalUser.username) return
|
||||||
if (valid) {
|
// 修改已选姓名即退出匹配,清除旧人的资料,避免作为新人员误提交。
|
||||||
|
this.selectedExternalUser = null
|
||||||
|
this.$set(this.formData, 'matchedUserId', '')
|
||||||
|
const fields = ['loginname', 'sex', 'idcard', 'birthday', 'mobile', 'unitname']
|
||||||
|
fields.forEach(key => {
|
||||||
|
this.$set(this.formData, key, '')
|
||||||
|
})
|
||||||
|
this.$set(this.formData, 'unitId', "${@shiro.getPrincipalProperty('unit').getId()}")
|
||||||
|
this.selectedExternalUnit = null
|
||||||
|
},
|
||||||
|
selectExternalUser(user) {
|
||||||
|
// 选中候选人后复用其账号,系统字段为空的部分可在下方补填。
|
||||||
|
this.selectedExternalUser = user
|
||||||
|
this.$set(this.formData, 'matchedUserId', user.id)
|
||||||
|
const fields = ['username', 'loginname', 'sex', 'idcard', 'birthday', 'mobile']
|
||||||
|
fields.forEach(key => {
|
||||||
|
this.$set(this.formData, key, user[key] || '')
|
||||||
|
})
|
||||||
|
const card = (user.idcard || '').toUpperCase()
|
||||||
|
const date = card.substring(6, 14)
|
||||||
|
if (!user.birthday && /^[0-9]{17}[0-9X]$/.test(card) && moment(date, 'YYYYMMDD', true).isValid()) {
|
||||||
|
this.$set(this.formData, 'birthday', moment(date, 'YYYYMMDD').format('YYYY-MM-DD'))
|
||||||
|
}
|
||||||
|
const unit = this.unitOptions.find(item => item.id === user.unitid)
|
||||||
|
this.$set(this.formData, 'unitId', unit ? unit.id : '')
|
||||||
|
this.$set(this.formData, 'unitname', unit ? unit.name : '')
|
||||||
|
},
|
||||||
|
changeExternalUnit(id) {
|
||||||
|
const unit = this.unitOptions.find(item => item.id === id)
|
||||||
|
this.$set(this.formData, 'unitname', unit ? unit.name : '')
|
||||||
|
},
|
||||||
|
searchExternalUnit(query, callback) {
|
||||||
|
const units = this.unitOptions.filter(item => !query || item.name.indexOf(query) > -1)
|
||||||
|
callback(units.slice(0, 30).map(item => ({...item, value: item.name})))
|
||||||
|
},
|
||||||
|
changeExternalUnitInput(value) {
|
||||||
|
// 手动改写单位名称后解除已选单位 ID,报名归属仍沿用操作人的单位。
|
||||||
|
if (this.selectedExternalUnit && value !== this.selectedExternalUnit.name) {
|
||||||
|
this.selectedExternalUnit = null
|
||||||
|
this.$set(this.formData, 'unitId', "${@shiro.getPrincipalProperty('unit').getId()}")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selectExternalUnit(unit) {
|
||||||
|
this.selectedExternalUnit = unit
|
||||||
|
this.$set(this.formData, 'unitId', unit.id)
|
||||||
|
this.$set(this.formData, 'unitname', unit.name)
|
||||||
|
},
|
||||||
|
updateExternalBirthday(value) {
|
||||||
|
// 身份证号变化时重新计算出生年月,避免沿用系统中可能错误的日期。
|
||||||
|
const card = (value || '').toUpperCase()
|
||||||
|
const date = card.substring(6, 14)
|
||||||
|
const birthday = /^[0-9]{17}[0-9X]$/.test(card) && moment(date, 'YYYYMMDD', true).isValid()
|
||||||
|
? moment(date, 'YYYYMMDD').format('YYYY-MM-DD') : ''
|
||||||
|
this.$set(this.formData, 'birthday', birthday)
|
||||||
|
},
|
||||||
|
addExternalToApply(user, single) {
|
||||||
const data = {
|
const data = {
|
||||||
|
...this.formData,
|
||||||
|
userId: user.id,
|
||||||
|
loginname: user.loginname,
|
||||||
|
username: user.username,
|
||||||
|
sex: this.formData.sex,
|
||||||
|
idcard: this.formData.idcard,
|
||||||
|
idCard: this.formData.idcard,
|
||||||
|
birthday: this.formData.birthday,
|
||||||
|
mobile: this.formData.mobile,
|
||||||
|
unitId: this.formData.unitId,
|
||||||
|
unitname: this.formData.unitname.trim(),
|
||||||
|
age: this.formData.birthday ? moment().diff(moment(this.formData.birthday), 'years') : null,
|
||||||
eventId: this.eventData.eventId,
|
eventId: this.eventData.eventId,
|
||||||
activityId: this.activityData.id,
|
activityId: this.activityData.id,
|
||||||
unitname: this.unitOptions.find(x => x.id === this.formData.unitId).name,
|
team: single ? null : this.teams.find(item => item.id === this.formData.teamId).name,
|
||||||
...this.formData
|
isAddUser: true
|
||||||
}
|
}
|
||||||
|
if (single) {
|
||||||
this.appliedData3.push(data)
|
this.appliedData3.push(data)
|
||||||
|
} else {
|
||||||
|
this.appliedData.push(data)
|
||||||
|
}
|
||||||
|
// 系统人员可能仍在左侧可报名单中,移除该选项以免同一项目重复加入。
|
||||||
|
this.applyData = this.applyData.filter(item => item.id !== user.id)
|
||||||
|
this.applyValue = this.applyValue.filter(id => id !== user.id)
|
||||||
|
this.rightChecked = this.rightChecked.filter(id => id !== user.id)
|
||||||
this.sortApplyed()
|
this.sortApplyed()
|
||||||
this.flushApplyed(this.appliedData)
|
this.flushApplyed(this.appliedData)
|
||||||
this.$notify.success({title: '成功', message: '已添加'});
|
this.notifySuccess('已添加报名人员')
|
||||||
|
this.dialogVisible = false
|
||||||
this.dialogVisible2 = false
|
this.dialogVisible2 = false
|
||||||
} else {
|
},
|
||||||
this.$notify.error({title: '错误', message: '存在未填写的的必填项'});
|
doAddUser(single) {
|
||||||
|
// 匹配人员直接加入报名;未匹配人员先创建账号,再加入本次报名。
|
||||||
|
if (this.formData.fitForCompetition !== true) return
|
||||||
|
this.$refs[single ? 'singleExternalForm' : 'form'].validate((valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
this.$notify.error({title: '错误', message: '存在未填写或不正确的必填项'})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if (!this.formData.unitname || !this.formData.unitname.trim()) {
|
||||||
|
this.notifyError('请选择或填写单位')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.appliedData.concat(this.appliedData3).some(item => item.userId === this.formData.matchedUserId)) {
|
||||||
|
this.notifyError('该人员已在当前项目报名列表中')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.formData.matchedUserId) {
|
||||||
|
if (this.selectedExternalUser && this.selectedExternalUser.id === this.formData.matchedUserId) {
|
||||||
|
this.addExternalToApply(this.selectedExternalUser, single)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.formLoading = true
|
||||||
|
$.post(loc() + "/addExternalUser", {
|
||||||
|
username: this.formData.username,
|
||||||
|
loginname: this.formData.loginname,
|
||||||
|
sex: this.formData.sex,
|
||||||
|
idcard: this.formData.idcard,
|
||||||
|
mobile: this.formData.mobile,
|
||||||
|
fitForCompetition: this.formData.fitForCompetition
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.code !== 0) {
|
||||||
|
this.notifyError(res.msg || '外援创建失败')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.addExternalToApply(res.data, single)
|
||||||
|
}).fail(() => {
|
||||||
|
this.notifyError('外援创建失败,请重试')
|
||||||
|
}).always(() => {
|
||||||
|
this.formLoading = false
|
||||||
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
openAddUser() {
|
openAddUser() {
|
||||||
this.formData = {teamId: this.team, identity: ['1']}
|
this.formData = {
|
||||||
this.dialogVisible = true
|
teamId: this.team,
|
||||||
if (this.$refs['form']) {
|
identity: ['1'],
|
||||||
this.$refs['form'].resetFields()
|
username: '',
|
||||||
|
loginname: '',
|
||||||
|
sex: '',
|
||||||
|
idcard: '',
|
||||||
|
birthday: '',
|
||||||
|
mobile: '',
|
||||||
|
unitId: "${@shiro.getPrincipalProperty('unit').getId()}",
|
||||||
|
unitname: '',
|
||||||
|
matchedUserId: '',
|
||||||
|
fitForCompetition: null
|
||||||
}
|
}
|
||||||
|
this.selectedExternalUser = null
|
||||||
|
this.selectedExternalUnit = null
|
||||||
|
this.externalSearchQuery = ''
|
||||||
|
this.dialogVisible = true
|
||||||
},
|
},
|
||||||
openAddUserD() {
|
openAddUserD() {
|
||||||
this.formData = {identity: ['1']}
|
this.formData = {
|
||||||
|
identity: ['1'],
|
||||||
this.dialogVisible2 = true
|
username: '',
|
||||||
if (this.$refs['form']) {
|
loginname: '',
|
||||||
this.$refs['form'].resetFields()
|
sex: '',
|
||||||
|
idcard: '',
|
||||||
|
birthday: '',
|
||||||
|
mobile: '',
|
||||||
|
unitId: "${@shiro.getPrincipalProperty('unit').getId()}",
|
||||||
|
unitname: '',
|
||||||
|
matchedUserId: '',
|
||||||
|
fitForCompetition: null
|
||||||
}
|
}
|
||||||
|
this.selectedExternalUser = null
|
||||||
|
this.selectedExternalUnit = null
|
||||||
|
this.externalSearchQuery = ''
|
||||||
|
this.dialogVisible2 = true
|
||||||
},
|
},
|
||||||
async doApplied(flag1) {
|
async doApplied(flag1) {
|
||||||
|
|
||||||
|
|||||||
@@ -121,8 +121,11 @@ layout("/layouts/platform.html"){
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-else-if="column.prop=='startTime'" scope="{row}">
|
<template v-else-if="column.prop=='startTime'" scope="{row}">
|
||||||
|
<span v-if="row.startTime && row.endTime">
|
||||||
{{moment(row.startTime).format('YYYY-MM-DD')}} -
|
{{moment(row.startTime).format('YYYY-MM-DD')}} -
|
||||||
{{moment(row.endTime).format('YYYY-MM-DD')}}
|
{{moment(row.endTime).format('YYYY-MM-DD')}}
|
||||||
|
</span>
|
||||||
|
<span v-else>未设置</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-else-if="column.prop=='state'"
|
<template v-else-if="column.prop=='state'"
|
||||||
|
|||||||
@@ -591,6 +591,7 @@ layout("/layouts/platform.html"){
|
|||||||
{prop: 'username', label: '姓名'},
|
{prop: 'username', label: '姓名'},
|
||||||
{prop: 'loginname', label: '教工号'},
|
{prop: 'loginname', label: '教工号'},
|
||||||
{prop: 'sex', label: '性别'},
|
{prop: 'sex', label: '性别'},
|
||||||
|
{prop: 'birthday', label: '出生年月'},
|
||||||
/* {prop: 'divisionLevelLeadership', label: '是否处级领导', sortable: true},*/
|
/* {prop: 'divisionLevelLeadership', label: '是否处级领导', sortable: true},*/
|
||||||
{prop: 'unitname', label: '单位', sortable: true},
|
{prop: 'unitname', label: '单位', sortable: true},
|
||||||
{prop: 'mobile', label: '电话'},
|
{prop: 'mobile', label: '电话'},
|
||||||
|
|||||||
@@ -110,6 +110,9 @@ layout("/layouts/platform.html"){
|
|||||||
{prop: 'loginname', label: '申请人工号'},
|
{prop: 'loginname', label: '申请人工号'},
|
||||||
{prop: 'username', label: '申请人姓名'},
|
{prop: 'username', label: '申请人姓名'},
|
||||||
{prop: 'mobile', label: '申请人电话'},
|
{prop: 'mobile', label: '申请人电话'},
|
||||||
|
{prop: 'sex', label: '性别'},
|
||||||
|
{prop: 'birthday', label: '出生年月'},
|
||||||
|
{prop: 'unitname', label: '单位'},
|
||||||
{prop: 'identity', label: '申请角色'},
|
{prop: 'identity', label: '申请角色'},
|
||||||
{prop: 'allName', label: '活动项目'},
|
{prop: 'allName', label: '活动项目'},
|
||||||
{prop: 'startTime', label: '活动日期'},
|
{prop: 'startTime', label: '活动日期'},
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ layout("/layouts/platform.html"){
|
|||||||
<div class="search-item-option">
|
<div class="search-item-option">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
placeholder="选择年度"
|
placeholder="全部年度"
|
||||||
type="year"
|
type="year" clearable @change="handleYearChange"
|
||||||
v-model="pageForm.year"
|
v-model="pageForm.year"
|
||||||
value-format="yyyy">
|
value-format="yyyy">
|
||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
@@ -27,13 +27,13 @@ layout("/layouts/platform.html"){
|
|||||||
<div class="search-item">
|
<div class="search-item">
|
||||||
<div class="search-item-label">项目名称:</div>
|
<div class="search-item-label">项目名称:</div>
|
||||||
<div class="search-item-option">
|
<div class="search-item-option">
|
||||||
<el-select v-model="pageForm.projectId" placeholder="请选择项目名称" filterable clearable
|
<el-select v-model="pageForm.projectId" placeholder="请选择项目名称" filterable clearable :loading="projectLoading"
|
||||||
style="width: 100%" @change="doSearch">
|
style="width: 100%" @change="doSearch">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in projectList"
|
v-for="item in projectList"
|
||||||
:key="item.code"
|
:key="item.id"
|
||||||
:label="item.name"
|
:label="item.name"
|
||||||
:value="item.code">
|
:value="item.id">
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
@@ -113,6 +113,7 @@ layout("/layouts/platform.html"){
|
|||||||
],
|
],
|
||||||
buyClothesUserData: [],
|
buyClothesUserData: [],
|
||||||
projectList: [],
|
projectList: [],
|
||||||
|
projectLoading: false,
|
||||||
unionList: [],
|
unionList: [],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -128,15 +129,43 @@ layout("/layouts/platform.html"){
|
|||||||
this.$refs['guava'].view()
|
this.$refs['guava'].view()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//获取所有买服装的项目
|
// 年度筛选与活动管理页一致,按活动报名开始时间所属年度获取活动。
|
||||||
async getBuyClothesProject() {
|
getBuyClothesProject(year) {
|
||||||
const {data} = await $.post('/platform/clothing/register/getBuyClothesProject')
|
this.$set(this, 'projectLoading', true)
|
||||||
return data
|
return $.post('/platform/clothing/register/getBuyClothesProject', {year: year})
|
||||||
|
.then((resp) => {
|
||||||
|
if (resp.code === 0) return resp.data || []
|
||||||
|
this.notifyWarning(resp.msg)
|
||||||
|
return []
|
||||||
|
}, () => {
|
||||||
|
this.notifyWarning('活动列表加载失败')
|
||||||
|
return []
|
||||||
|
})
|
||||||
|
.always(() => {
|
||||||
|
this.$set(this, 'projectLoading', false)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 年度变化后清空不属于新年度的项目选择,再按当前条件查询台账。
|
||||||
|
handleYearChange() {
|
||||||
|
const year = this.pageForm.year
|
||||||
|
this.$set(this.pageForm, 'projectId', null)
|
||||||
|
this.$set(this, 'projectList', [])
|
||||||
|
this.getBuyClothesProject(year).then((projects) => {
|
||||||
|
if (this.pageForm.year !== year) return
|
||||||
|
this.$set(this, 'projectList', projects)
|
||||||
|
this.doSearch()
|
||||||
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
async created() {
|
created() {
|
||||||
this.projectList = await this.getBuyClothesProject()
|
const year = this.pageForm.year
|
||||||
this.unionList = await getUnion()
|
this.getBuyClothesProject(year).then((projects) => {
|
||||||
|
if (this.pageForm.year !== year) return
|
||||||
|
this.$set(this, 'projectList', projects)
|
||||||
|
})
|
||||||
|
getUnion().then((unions) => {
|
||||||
|
this.$set(this, 'unionList', unions)
|
||||||
|
})
|
||||||
this.pageData()
|
this.pageData()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ layout("/layouts/platform.html"){
|
|||||||
<div class="search-item-option">
|
<div class="search-item-option">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
placeholder="选择年度"
|
placeholder="全部年度"
|
||||||
type="year"
|
type="year" clearable @change="handleYearChange"
|
||||||
v-model="pageForm.year"
|
v-model="pageForm.year"
|
||||||
value-format="yyyy">
|
value-format="yyyy">
|
||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
@@ -27,13 +27,13 @@ layout("/layouts/platform.html"){
|
|||||||
<div class="search-item">
|
<div class="search-item">
|
||||||
<div class="search-item-label">项目名称:</div>
|
<div class="search-item-label">项目名称:</div>
|
||||||
<div class="search-item-option">
|
<div class="search-item-option">
|
||||||
<el-select v-model="pageForm.projectId" placeholder="请选择项目名称" filterable clearable
|
<el-select v-model="pageForm.projectId" placeholder="请选择项目名称" filterable clearable :loading="projectLoading"
|
||||||
style="width: 100%" @change="doSearch">
|
style="width: 100%" @change="doSearch">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in projectList"
|
v-for="item in projectList"
|
||||||
:key="item.code"
|
:key="item.id"
|
||||||
:label="item.name"
|
:label="item.name"
|
||||||
:value="item.code">
|
:value="item.id">
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
@@ -111,6 +111,7 @@ layout("/layouts/platform.html"){
|
|||||||
],
|
],
|
||||||
buyClothesUserData: [],
|
buyClothesUserData: [],
|
||||||
projectList: [],
|
projectList: [],
|
||||||
|
projectLoading: false,
|
||||||
note: '',
|
note: '',
|
||||||
clickRow: {},
|
clickRow: {},
|
||||||
}
|
}
|
||||||
@@ -177,10 +178,32 @@ layout("/layouts/platform.html"){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//获取所有买服装的项目
|
// 年度筛选与活动管理页一致,按活动报名开始时间所属年度获取活动。
|
||||||
async getBuyClothesProject() {
|
getBuyClothesProject(year) {
|
||||||
const {data} = await $.post('/platform/clothing/register/getBuyClothesProject')
|
this.$set(this, 'projectLoading', true)
|
||||||
return data
|
return $.post('/platform/clothing/register/getBuyClothesProject', {year: year})
|
||||||
|
.then((resp) => {
|
||||||
|
if (resp.code === 0) return resp.data || []
|
||||||
|
this.notifyWarning(resp.msg)
|
||||||
|
return []
|
||||||
|
}, () => {
|
||||||
|
this.notifyWarning('活动列表加载失败')
|
||||||
|
return []
|
||||||
|
})
|
||||||
|
.always(() => {
|
||||||
|
this.$set(this, 'projectLoading', false)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 年度变化后清空不属于新年度的项目选择,再按当前条件查询登记记录。
|
||||||
|
handleYearChange() {
|
||||||
|
const year = this.pageForm.year
|
||||||
|
this.$set(this.pageForm, 'projectId', null)
|
||||||
|
this.$set(this, 'projectList', [])
|
||||||
|
this.getBuyClothesProject(year).then((projects) => {
|
||||||
|
if (this.pageForm.year !== year) return
|
||||||
|
this.$set(this, 'projectList', projects)
|
||||||
|
this.doSearch()
|
||||||
|
})
|
||||||
},
|
},
|
||||||
doExport(row) {
|
doExport(row) {
|
||||||
const loading = this.$loading({
|
const loading = this.$loading({
|
||||||
@@ -221,8 +244,12 @@ layout("/layouts/platform.html"){
|
|||||||
}).catch((err) => {})
|
}).catch((err) => {})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
async created() {
|
created() {
|
||||||
this.projectList = await this.getBuyClothesProject()
|
const year = this.pageForm.year
|
||||||
|
this.getBuyClothesProject(year).then((projects) => {
|
||||||
|
if (this.pageForm.year !== year) return
|
||||||
|
this.$set(this, 'projectList', projects)
|
||||||
|
})
|
||||||
this.pageData()
|
this.pageData()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ layout("/layouts/platform.html"){
|
|||||||
<div class="search-item-option">
|
<div class="search-item-option">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
placeholder="选择年度"
|
placeholder="全部年度"
|
||||||
type="year" disabled
|
type="year" clearable @change="handleYearChange"
|
||||||
v-model="pageForm.year"
|
v-model="pageForm.year"
|
||||||
value-format="yyyy">
|
value-format="yyyy">
|
||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
@@ -37,19 +37,24 @@ layout("/layouts/platform.html"){
|
|||||||
<div class="search-item">
|
<div class="search-item">
|
||||||
<div class="search-item-label">项目名称:</div>
|
<div class="search-item-label">项目名称:</div>
|
||||||
<div class="search-item-option">
|
<div class="search-item-option">
|
||||||
<el-select v-model="pageForm.projectId" placeholder="请选择项目名称" filterable
|
<el-select v-model="pageForm.projectId" placeholder="请选择项目名称" filterable :loading="projectLoading"
|
||||||
@change="doSearch" style="width: 100%">
|
@change="doSearch" style="width: 100%">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in projectList"
|
v-for="item in projectList"
|
||||||
:key="item.code"
|
:key="item.id"
|
||||||
:label="item.name"
|
:label="item.name"
|
||||||
:value="item.code">
|
:value="item.id">
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="search-item">
|
<div class="search-item">
|
||||||
<div class="search-item-label">近两年内:</div>
|
<div class="search-item-label" style="white-space: nowrap;">
|
||||||
|
近两年内:
|
||||||
|
<el-tooltip content="按所选活动的报名年度,检查相邻年度活动中相同运动项目的购衣记录;补录往年活动也会查重" placement="top">
|
||||||
|
<i class="el-icon-question" style="cursor: help;"></i>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
<div class="search-item-option">
|
<div class="search-item-option">
|
||||||
<el-radio-group @change="(val) => doSearch()" v-model="pageForm.isBuy">
|
<el-radio-group @change="(val) => doSearch()" v-model="pageForm.isBuy">
|
||||||
<el-radio-button :label="true">已购买</el-radio-button>
|
<el-radio-button :label="true">已购买</el-radio-button>
|
||||||
@@ -112,22 +117,25 @@ layout("/layouts/platform.html"){
|
|||||||
</template>
|
</template>
|
||||||
</vi-title2>
|
</vi-title2>
|
||||||
</div>
|
</div>
|
||||||
<el-table ref="multipleTable" @selection-change="handleSelectionChange" :data="userData" max-height="600"
|
<el-table ref="multipleTable" v-loading="tableLoading" @selection-change="handleSelectionChange" :data="userData" max-height="600"
|
||||||
:row-key="(val) => val.id">
|
:row-key="(val) => val.id">
|
||||||
<el-table-column :reserve-selection="true" type="selection" width="55"></el-table-column>
|
<el-table-column :reserve-selection="true" :selectable="canSelectUser" type="selection" width="55"></el-table-column>
|
||||||
<el-table-column label="姓名" prop="username" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="姓名" prop="username" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="工号" prop="loginname" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="工号" prop="loginname" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="性别" prop="sex" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="性别" prop="sex" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="单位" prop="unitname" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="单位" prop="unitname" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="所属工会" prop="unionname" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="所属工会" prop="unionname" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="联系方式" prop="mobile" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column label="联系方式" prop="mobile" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column v-if="pageForm.isBuy" label="购买来源" align="center" header-align="center">
|
||||||
|
<template slot-scope="scope">{{scope.row.canRemove ? '当前活动' : '两年内同类活动'}}</template>
|
||||||
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<div style="display: flex; justify-content: space-between; margin-top: 6px">
|
<div style="display: flex; justify-content: space-between; margin-top: 6px">
|
||||||
<div> <!--#include("/layouts/pagination.html"){}#--></div>
|
<div> <!--#include("/layouts/pagination.html"){}#--></div>
|
||||||
<div>
|
<div>
|
||||||
<el-row justify="end" type="flex">
|
<el-row justify="end" type="flex">
|
||||||
<el-button v-if="!pageForm.isBuy" @click="doHandler" type="primary">提交</el-button>
|
<el-button v-if="!pageForm.isBuy" @click="doHandler" :loading="formLoading" type="primary">提交</el-button>
|
||||||
<el-button v-else @click="doHandler" type="danger">移除</el-button>
|
<el-button v-else @click="doHandler" :loading="formLoading" type="danger">移除</el-button>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -154,11 +162,12 @@ layout("/layouts/platform.html"){
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
pageForm: {
|
pageForm: {
|
||||||
year: moment().format('YYYY'),
|
year: null,
|
||||||
isBuy: false,
|
isBuy: false,
|
||||||
searchName: 'u.username'
|
searchName: 'u.username'
|
||||||
},
|
},
|
||||||
projectList: [],
|
projectList: [],
|
||||||
|
projectLoading: false,
|
||||||
userData: [],
|
userData: [],
|
||||||
userValue: [],
|
userValue: [],
|
||||||
treeUnionList: [],
|
treeUnionList: [],
|
||||||
@@ -172,7 +181,11 @@ layout("/layouts/platform.html"){
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleSelectionChange(val) {
|
handleSelectionChange(val) {
|
||||||
this.userValue = val.length > 0 ? val.map(o => o.id) : []
|
this.$set(this, 'userValue', val.length > 0 ? val.map(o => o.id) : [])
|
||||||
|
},
|
||||||
|
// 其他同类活动的历史购买只能查看;移除操作仅处理当前活动的登记。
|
||||||
|
canSelectUser(row) {
|
||||||
|
return !this.pageForm.isBuy || row.canRemove
|
||||||
},
|
},
|
||||||
filterNode(value, data, node) {
|
filterNode(value, data, node) {
|
||||||
if (!value || node.level === 1) return true;
|
if (!value || node.level === 1) return true;
|
||||||
@@ -187,7 +200,7 @@ layout("/layouts/platform.html"){
|
|||||||
this.pageData()
|
this.pageData()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async doHandler() {
|
doHandler() {
|
||||||
if(!this.pageForm.projectId) {
|
if(!this.pageForm.projectId) {
|
||||||
this.notifyWarning('请选择项目!')
|
this.notifyWarning('请选择项目!')
|
||||||
return
|
return
|
||||||
@@ -196,50 +209,104 @@ layout("/layouts/platform.html"){
|
|||||||
this.notifyWarning('请选择人员!')
|
this.notifyWarning('请选择人员!')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const confirm = await this.$confirm('您选择了' + this.userValue.length + '人, 是否继续?', '提示', {
|
this.$confirm('您选择了' + this.userValue.length + '人, 是否继续?', '提示', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
})
|
}).then(() => {
|
||||||
if (confirm === "confirm") {
|
this.$set(this, 'formLoading', true)
|
||||||
const resp = await $.post('/platform/clothing/register/doHandler', {
|
return $.post('/platform/clothing/register/doHandler', {
|
||||||
ids: JSON.stringify(this.userValue),
|
ids: JSON.stringify(this.userValue),
|
||||||
projectId: this.pageForm.projectId,
|
projectId: this.pageForm.projectId,
|
||||||
year: this.pageForm.year,
|
|
||||||
isBuy: this.pageForm.isBuy,
|
isBuy: this.pageForm.isBuy,
|
||||||
})
|
})
|
||||||
|
.then((resp) => {
|
||||||
if (resp.code === 0) {
|
if (resp.code === 0) {
|
||||||
this.doSearch()
|
this.doSearch()
|
||||||
this.notifySuccess(resp.msg)
|
this.notifySuccess(resp.msg)
|
||||||
} else {
|
} else {
|
||||||
this.notifyWarning(resp.msg)
|
this.notifyWarning(resp.msg)
|
||||||
}
|
}
|
||||||
}
|
}, () => {
|
||||||
|
this.notifyWarning('提交失败,请刷新名单后重试')
|
||||||
|
})
|
||||||
|
.always(() => {
|
||||||
|
this.$set(this, 'formLoading', false)
|
||||||
|
})
|
||||||
|
}).catch(() => {})
|
||||||
},
|
},
|
||||||
doSearch() {
|
doSearch() {
|
||||||
this.$refs.multipleTable.clearSelection()
|
this.$refs.multipleTable.clearSelection()
|
||||||
this.pageData()
|
this.pageData()
|
||||||
},
|
},
|
||||||
//查询人员名单
|
// 查询与所选活动报名年度相差不超过一年、同类运动项目的购买状态。
|
||||||
async pageData() {
|
pageData() {
|
||||||
const resp = await $.post('/platform/clothing/register/pageData', this.pageForm)
|
const projectId = this.pageForm.projectId
|
||||||
|
const isBuy = this.pageForm.isBuy
|
||||||
|
this.$set(this, 'tableLoading', true)
|
||||||
|
return $.post('/platform/clothing/register/pageData', this.pageForm)
|
||||||
|
.then((resp) => {
|
||||||
|
if (this.pageForm.projectId !== projectId || this.pageForm.isBuy !== isBuy) return
|
||||||
if (resp.code === 0) {
|
if (resp.code === 0) {
|
||||||
this.userData = resp.data.list
|
this.$set(this, 'userData', resp.data.list)
|
||||||
this.pageForm.totalCount = resp.data.totalCount
|
this.$set(this.pageForm, 'totalCount', resp.data.totalCount)
|
||||||
} else {
|
} else {
|
||||||
|
this.$set(this, 'userData', [])
|
||||||
|
this.$set(this.pageForm, 'totalCount', 0)
|
||||||
this.$message.error(resp.msg)
|
this.$message.error(resp.msg)
|
||||||
}
|
}
|
||||||
|
}, () => {
|
||||||
|
if (this.pageForm.projectId !== projectId || this.pageForm.isBuy !== isBuy) return
|
||||||
|
this.$set(this, 'userData', [])
|
||||||
|
this.$set(this.pageForm, 'totalCount', 0)
|
||||||
|
this.$message.error('人员名单加载失败')
|
||||||
|
})
|
||||||
|
.always(() => {
|
||||||
|
this.$set(this, 'tableLoading', false)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
//获取所有买服装的项目
|
// 年度为空时获取全部已提交活动;指定年度时按活动报名开始时间筛选。
|
||||||
async getBuyClothesProject() {
|
getBuyClothesProject(year) {
|
||||||
const {data} = await $.post('/platform/clothing/register/getBuyClothesProject')
|
this.$set(this, 'projectLoading', true)
|
||||||
return data
|
return $.post('/platform/clothing/register/getBuyClothesProject', {year: year})
|
||||||
|
.then((resp) => {
|
||||||
|
if (resp.code === 0) return resp.data || []
|
||||||
|
this.notifyWarning(resp.msg)
|
||||||
|
return []
|
||||||
|
}, () => {
|
||||||
|
this.notifyWarning('活动列表加载失败')
|
||||||
|
return []
|
||||||
|
})
|
||||||
|
.always(() => {
|
||||||
|
this.$set(this, 'projectLoading', false)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
async unionTree() {
|
// 切换年度时清除原项目,避免用上一年度的活动ID继续查询或登记。
|
||||||
const resp = await $.post('/platform/clothing/register/getTreeUnionList')
|
refreshProjects() {
|
||||||
if(resp.code === 0) {
|
const year = this.pageForm.year
|
||||||
this.sysadmin = resp.data.sysadmin
|
this.$set(this.pageForm, 'projectId', null)
|
||||||
this.treeUnionList = [resp.data]
|
this.$set(this, 'projectList', [])
|
||||||
|
this.$set(this, 'userData', [])
|
||||||
|
this.$set(this, 'userValue', [])
|
||||||
|
return this.getBuyClothesProject(year).then((projects) => {
|
||||||
|
if (this.pageForm.year !== year) return
|
||||||
|
this.$set(this, 'projectList', projects)
|
||||||
|
if (projects.length > 0) {
|
||||||
|
this.$set(this.pageForm, 'projectId', projects[0].id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleYearChange() {
|
||||||
|
const year = this.pageForm.year
|
||||||
|
this.refreshProjects().then(() => {
|
||||||
|
if (this.pageForm.year === year) this.doSearch()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
unionTree() {
|
||||||
|
return $.post('/platform/clothing/register/getTreeUnionList').then((resp) => {
|
||||||
|
if (resp.code !== 0) return
|
||||||
|
this.$set(this, 'sysadmin', resp.data.sysadmin)
|
||||||
|
this.$set(this, 'treeUnionList', [resp.data])
|
||||||
if (this.sysadmin) {
|
if (this.sysadmin) {
|
||||||
this.handleNodeClick({unioncode: ''}, {level: 1})
|
this.handleNodeClick({unioncode: ''}, {level: 1})
|
||||||
} else {
|
} else {
|
||||||
@@ -257,16 +324,15 @@ layout("/layouts/platform.html"){
|
|||||||
level: 2, data: data
|
level: 2, data: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}, () => {
|
||||||
|
this.notifyWarning('工会列表加载失败')
|
||||||
|
}).always(() => {})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
async created() {
|
created() {
|
||||||
this.projectList = await this.getBuyClothesProject()
|
this.refreshProjects().then(() => {
|
||||||
if (this.projectList && this.projectList.length > 0) {
|
this.unionTree()
|
||||||
this.pageForm.projectId = this.projectList[0].code
|
})
|
||||||
}
|
|
||||||
await this.unionTree()
|
|
||||||
this.pageData()
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -74,13 +74,23 @@ layout("/layouts/platform.html"){
|
|||||||
color: white !important;
|
color: white !important;
|
||||||
background-color: #314659 !important;
|
background-color: #314659 !important;
|
||||||
}
|
}
|
||||||
|
.dashboard-drill {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-drill:hover .card-value-num,
|
||||||
|
.dashboard-drill:hover .card-label {
|
||||||
|
color: #409EFF;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div id="app" class="platform aid-dash-bord" v-cloak>
|
<div id="app" class="platform aid-dash-bord" v-cloak>
|
||||||
<guava ref="guava">
|
<guava ref="guava">
|
||||||
<template>
|
<template>
|
||||||
<el-row gutter="20" type="flex">
|
<el-row gutter="20" type="flex">
|
||||||
<el-col v-loading="loading.memberNumber">
|
<el-col class="dashboard-drill" v-loading="loading.memberNumber"
|
||||||
|
title="点击查看基金会员明细"
|
||||||
|
@click.native="openDetail('基金会员总数明细', 'member', {})">
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
<div class="card-label">基金会员总数</div>
|
<div class="card-label">基金会员总数</div>
|
||||||
<div class="card-value">
|
<div class="card-value">
|
||||||
@@ -90,7 +100,12 @@ layout("/layouts/platform.html"){
|
|||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col v-loading="loading.memberNumberYear">
|
<el-col class="dashboard-drill" v-loading="loading.memberNumberYear"
|
||||||
|
title="点击查看今年新加入会员明细"
|
||||||
|
@click.native="openDetail('今年新加入基金会员明细', 'member', {
|
||||||
|
startTime: moment().startOf('year').format('YYYY-MM-DD'),
|
||||||
|
endTime: moment().endOf('year').format('YYYY-MM-DD')
|
||||||
|
})">
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
<div class="card-label">今年新加入会员数</div>
|
<div class="card-label">今年新加入会员数</div>
|
||||||
<div class="card-value">
|
<div class="card-value">
|
||||||
@@ -99,7 +114,9 @@ layout("/layouts/platform.html"){
|
|||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col v-loading="loading.aidMedical">
|
<el-col class="dashboard-drill" v-loading="loading.aidMedical"
|
||||||
|
title="点击查看医疗补助申请明细"
|
||||||
|
@click.native="openDetail('医疗补助申请明细', 'medical', {medicalType: 1})">
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
<div class="card-label">医疗补助申请总数</div>
|
<div class="card-label">医疗补助申请总数</div>
|
||||||
<div class="card-value">
|
<div class="card-value">
|
||||||
@@ -108,7 +125,9 @@ layout("/layouts/platform.html"){
|
|||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col v-loading="loading.aidMedical">
|
<el-col class="dashboard-drill" v-loading="loading.aidMedical"
|
||||||
|
title="点击查看重疾补助申请明细"
|
||||||
|
@click.native="openDetail('重疾补助申请明细', 'medical', {medicalType: 2})">
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
<div class="card-label">重疾补助申请总数</div>
|
<div class="card-label">重疾补助申请总数</div>
|
||||||
<div class="card-value">
|
<div class="card-value">
|
||||||
@@ -117,7 +136,9 @@ layout("/layouts/platform.html"){
|
|||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col v-loading="loading.aidMedicalMoney">
|
<el-col class="dashboard-drill" v-loading="loading.aidMedicalMoney"
|
||||||
|
title="点击查看已补助申请明细"
|
||||||
|
@click.native="openDetail('已补助金额明细', 'medical', {stateId: 700})">
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
<div class="card-label">共计补助</div>
|
<div class="card-label">共计补助</div>
|
||||||
<div class="card-value">
|
<div class="card-value">
|
||||||
@@ -132,10 +153,13 @@ layout("/layouts/platform.html"){
|
|||||||
<el-col class="center-col">
|
<el-col class="center-col">
|
||||||
<div class="card-label">工会基金会员数</div>
|
<div class="card-label">工会基金会员数</div>
|
||||||
|
|
||||||
<div style="width: 100%;height: 100px" id="unionMemberChart"></div>
|
<div class="dashboard-drill" title="点击趋势点查看工会基金会员明细"
|
||||||
<el-table :data="unionMember" style="width: 100%;margin-top: 20px"
|
style="width: 100%;height: 100px" id="unionMemberChart"></div>
|
||||||
|
<el-table :data="unionMember" style="width: 100%;margin-top: 20px;cursor: pointer"
|
||||||
height="calc(100vh - 160px - 300px)"
|
height="calc(100vh - 160px - 300px)"
|
||||||
:header-cell-style="{background:'#FAFAFA'}" row-key="id">
|
:header-cell-style="{background:'#FAFAFA'}" row-key="id"
|
||||||
|
title="点击工会行查看基金会员明细"
|
||||||
|
@row-click="openUnionMemberDetail">
|
||||||
<el-table-column label="序号" width="100px">
|
<el-table-column label="序号" width="100px">
|
||||||
<template scope="{$index}">
|
<template scope="{$index}">
|
||||||
<div class="idx idx-rank" v-if="$index<3">{{$index+1}}</div>
|
<div class="idx idx-rank" v-if="$index<3">{{$index+1}}</div>
|
||||||
@@ -157,13 +181,15 @@ layout("/layouts/platform.html"){
|
|||||||
<el-col class="center-col">
|
<el-col class="center-col">
|
||||||
|
|
||||||
<div class="card-label">在职状态</div>
|
<div class="card-label">在职状态</div>
|
||||||
<div style="width: 100%;height:calc(50% - 35px);box-sizing: border-box;padding: 30px 10px"
|
<div class="dashboard-drill" title="点击图表项查看在职状态明细"
|
||||||
|
style="width: 100%;height:calc(50% - 35px);box-sizing: border-box;padding: 30px 10px"
|
||||||
v-loading="loading.userStateMember"
|
v-loading="loading.userStateMember"
|
||||||
id="userStateMemberChart"></div>
|
id="userStateMemberChart"></div>
|
||||||
|
|
||||||
|
|
||||||
<div class="card-label">人员类型</div>
|
<div class="card-label">人员类型</div>
|
||||||
<div style="width: 100%;height:calc(50% - 35px);box-sizing: border-box;padding: 30px 10px"
|
<div class="dashboard-drill" title="点击图表项查看人员类型明细"
|
||||||
|
style="width: 100%;height:calc(50% - 35px);box-sizing: border-box;padding: 30px 10px"
|
||||||
v-loading="loading.personTypeMember"
|
v-loading="loading.personTypeMember"
|
||||||
id="personTypeMemberChart"></div>
|
id="personTypeMemberChart"></div>
|
||||||
|
|
||||||
@@ -172,6 +198,7 @@ layout("/layouts/platform.html"){
|
|||||||
</el-row>
|
</el-row>
|
||||||
</template>
|
</template>
|
||||||
</guava>
|
</guava>
|
||||||
|
<data-board-detail ref="dataBoardDetail" :base-url="loc()"></data-board-detail>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -207,9 +234,27 @@ layout("/layouts/platform.html"){
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
'guava': httpVueLoader('/components/plugins/Guava.vue?v=1.0.0')
|
'guava': httpVueLoader('/components/plugins/Guava.vue?v=1.0.0'),
|
||||||
|
'data-board-detail': httpVueLoader('/components/dashboard/DataBoardDetail.vue?v=1.0.3')
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
openDetail(title, detailType, filters) {
|
||||||
|
this.$refs.dataBoardDetail.open(title, detailType, filters)
|
||||||
|
},
|
||||||
|
openUnionMemberDetail(row) {
|
||||||
|
this.openDetail(row.unionname + '基金会员明细', 'member', {
|
||||||
|
unionId: row.unionid
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getTinyAreaRow(event, rows) {
|
||||||
|
const point = event && event.data ? event.data.data : null
|
||||||
|
const index = point && point.x !== undefined ? Number(point.x) : NaN
|
||||||
|
if (Number.isInteger(index) && rows[index]) {
|
||||||
|
return rows[index]
|
||||||
|
}
|
||||||
|
const value = point && point.y !== undefined ? point.y : point
|
||||||
|
return rows.find(item => String(item.value) === String(value))
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* 各工会会员数
|
* 各工会会员数
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
@@ -244,6 +289,12 @@ layout("/layouts/platform.html"){
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
chart.unionMemberChart.render();
|
chart.unionMemberChart.render();
|
||||||
|
chart.unionMemberChart.on('element:click', event => {
|
||||||
|
const row = this.getTinyAreaRow(event, chartData)
|
||||||
|
if (row) {
|
||||||
|
this.openUnionMemberDetail(row)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -303,6 +354,14 @@ layout("/layouts/platform.html"){
|
|||||||
area: {},*/
|
area: {},*/
|
||||||
});
|
});
|
||||||
chart.userStateMemberChart.render();
|
chart.userStateMemberChart.render();
|
||||||
|
chart.userStateMemberChart.on('element:click', event => {
|
||||||
|
const row = event && event.data ? event.data.data : null
|
||||||
|
if (row) {
|
||||||
|
this.openDetail(row.type + '基金会员明细', 'member', {
|
||||||
|
userState: row.type
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
})
|
})
|
||||||
@@ -353,6 +412,14 @@ layout("/layouts/platform.html"){
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
chart.personTypeMemberChart.render();
|
chart.personTypeMemberChart.render();
|
||||||
|
chart.personTypeMemberChart.on('element:click', event => {
|
||||||
|
const row = event && event.data ? event.data.data : null
|
||||||
|
if (row) {
|
||||||
|
this.openDetail(row.label + '基金会员明细', 'member', {
|
||||||
|
personType: row.label
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -0,0 +1,549 @@
|
|||||||
|
<!--#
|
||||||
|
layout("/layouts/platform.html"){
|
||||||
|
#-->
|
||||||
|
<div id="app" v-cloak>
|
||||||
|
<guava @vchange="guavaViewChange" ref="guava">
|
||||||
|
<template>
|
||||||
|
<el-card shadow="never">
|
||||||
|
<div slot="header">
|
||||||
|
<span>分级核对任务</span>
|
||||||
|
<el-button @click="uploadDialogVisible=true" icon="el-icon-upload2"
|
||||||
|
size="small" style="float:right" type="primary">上传并分发</el-button>
|
||||||
|
</div>
|
||||||
|
<el-alert :closable="false" show-icon style="margin-bottom:15px"
|
||||||
|
title="系统仅按 Excel 的“所在单位”列分发,文件名不参与匹配。"></el-alert>
|
||||||
|
<el-form :inline="true" :model="taskSearch" size="small">
|
||||||
|
<el-form-item label="任务名称">
|
||||||
|
<el-input clearable placeholder="请输入任务名称" v-model="taskSearch.taskName"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="任务日期">
|
||||||
|
<el-date-picker clearable format="yyyy-MM-dd" placeholder="请选择任务日期" type="date"
|
||||||
|
value-format="yyyy-MM-dd" v-model="taskSearch.taskDate"></el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="loadTasks(true)" icon="el-icon-search" type="primary">查询</el-button>
|
||||||
|
<el-button @click="resetTaskSearch">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-table :data="tasks" border v-loading="loading">
|
||||||
|
<el-table-column label="任务名称" prop="name"></el-table-column>
|
||||||
|
<el-table-column align="center" label="任务日期" min-width="160">
|
||||||
|
<template slot-scope="scope">{{formatDateTime(scope.row.taskDate)}}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="完成进度" width="180">
|
||||||
|
<template slot-scope="scope">{{scope.row.finishedUnits || 0}} / {{scope.row.totalUnits || 0}}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="任务说明" prop="description" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column align="center" label="操作" width="300">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button @click="openUnits(scope.row)" size="mini" type="primary">单位核对明细</el-button>
|
||||||
|
<el-button @click="openCurrentData(scope.row)" size="mini" type="primary">查看数据</el-button>
|
||||||
|
<el-button @click="deleteTask(scope.row)" size="mini" type="danger">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-pagination :current-page="taskPage.pageNumber" :page-size="taskPage.pageSize"
|
||||||
|
:page-sizes="[10,20,50,100]" :total="taskPage.totalCount"
|
||||||
|
@current-change="taskPageNumberChange" @size-change="taskPageSizeChange"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
style="margin-top:15px;text-align:right"></el-pagination>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #edit_func>
|
||||||
|
<el-button @click="exportCurrent(dataTarget)" icon="el-icon-download"
|
||||||
|
size="small" type="primary"
|
||||||
|
v-if="detailView==='data' && dataScope==='task'">导出生效数据</el-button>
|
||||||
|
<template v-if="detailView==='data' && dataScope==='unit'">
|
||||||
|
<el-button @click="download(dataTarget,'original')" icon="el-icon-download"
|
||||||
|
size="small">下载原始数据</el-button>
|
||||||
|
<el-button @click="download(dataTarget,'pending')" icon="el-icon-download"
|
||||||
|
size="small" v-if="dataTarget.state===2">下载修改版</el-button>
|
||||||
|
<el-button @click="download(dataTarget,'current')" icon="el-icon-download"
|
||||||
|
size="small" type="primary"
|
||||||
|
v-if="dataVersionType==='current' && dataTarget.state===4">导出已核对版</el-button>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #edit>
|
||||||
|
<div key="unit-detail" v-if="detailView==='units'">
|
||||||
|
<el-divider content-position="left">{{currentTask.name}} - 单位核对明细</el-divider>
|
||||||
|
<el-form :inline="true" :model="unitSearch" size="small">
|
||||||
|
<el-form-item label="单位名称">
|
||||||
|
<el-input clearable placeholder="请输入单位名称" v-model="unitSearch.unitName"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="核对状态">
|
||||||
|
<el-select clearable placeholder="全部" v-model="unitSearch.state">
|
||||||
|
<el-option :key="index" :label="name" :value="index"
|
||||||
|
v-for="(name,index) in statusOptions"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="核对人员状态">
|
||||||
|
<el-select clearable placeholder="全部" v-model="unitSearch.managerState">
|
||||||
|
<el-option label="已分配核对人员" :value="1"></el-option>
|
||||||
|
<el-option label="未分配核对人员" :value="0"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="loadUnitTasks(true)" icon="el-icon-search" type="primary">查询</el-button>
|
||||||
|
<el-button @click="resetUnitSearch">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-table :data="unitTasks" border v-loading="unitLoading">
|
||||||
|
<el-table-column label="单位" prop="unitName" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column align="center" label="行数" prop="rowCount" width="90"></el-table-column>
|
||||||
|
<el-table-column align="center" label="状态" width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag :type="statusType(scope.row.state)">{{statusText(scope.row.state)}}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="核对人员" min-width="180" show-overflow-tooltip>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span v-if="scope.row.managerNames || scope.row.managernames">
|
||||||
|
{{scope.row.managerNames || scope.row.managernames}}
|
||||||
|
</span>
|
||||||
|
<el-tag type="warning" v-else>未分配核对人员</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="审核意见" prop="auditOpinion" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column align="center" label="核对日期" min-width="160">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{formatDateTime(scope.row.checkedAt)}}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="操作" width="450">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button @click="openUnitData(scope.row)" size="mini" type="primary">查看原始数据</el-button>
|
||||||
|
<template v-if="scope.row.state===2">
|
||||||
|
<el-button @click="openUnitData(scope.row,'pending')" size="mini" type="primary">查看修改版</el-button>
|
||||||
|
<el-button @click="audit(scope.row,true)" size="mini" type="success">通过</el-button>
|
||||||
|
<el-button @click="audit(scope.row,false)" size="mini" type="danger">退回</el-button>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-pagination :current-page="unitPage.pageNumber" :page-size="unitPage.pageSize"
|
||||||
|
:page-sizes="[10,20,50,100]" :total="unitPage.totalCount"
|
||||||
|
@current-change="unitPageNumberChange" @size-change="unitPageSizeChange"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
style="margin-top:15px;text-align:right"></el-pagination>
|
||||||
|
</div>
|
||||||
|
<div key="data-detail" v-else>
|
||||||
|
<el-divider content-position="left">{{dataDialogTitle}}</el-divider>
|
||||||
|
<el-form :inline="true" :model="dataSearch" size="small">
|
||||||
|
<el-form-item>
|
||||||
|
<el-input @keyup.enter.native="loadDataRows(true)" clearable placeholder="请输入查询内容"
|
||||||
|
v-model="dataSearch.searchKeyword">
|
||||||
|
<el-select placeholder="查询字段" slot="prepend" style="width:120px"
|
||||||
|
v-model="dataSearch.searchName">
|
||||||
|
<el-option label="薪酬单位代码" value="salaryUnitCode"></el-option>
|
||||||
|
<el-option label="职工号" value="employeeNo"></el-option>
|
||||||
|
<el-option label="姓名" value="employeeName"></el-option>
|
||||||
|
<el-option label="扣工会会费" value="unionFee"></el-option>
|
||||||
|
<el-option label="年月" value="yearMonth"></el-option>
|
||||||
|
<el-option label="所在单位" value="unitName"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="核对情况">
|
||||||
|
<el-select clearable placeholder="全部" v-model="dataSearch.state">
|
||||||
|
<el-option :key="index" :label="name" :value="index"
|
||||||
|
v-for="(name,index) in statusOptions"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="loadDataRows(true)" icon="el-icon-search" type="primary">查询</el-button>
|
||||||
|
<el-button @click="resetDataSearch">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-table :data="dataRows" border v-loading="dataLoading">
|
||||||
|
<el-table-column align="center" label="序号" width="70">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{scope.$index + (dataPage.pageNumber - 1) * dataPage.pageSize + 1}}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="薪酬单位代码" min-width="130" prop="薪酬单位代码" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="职工号" min-width="120" prop="职工号" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="姓名" min-width="100" prop="姓名" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="扣工会会费" min-width="120" prop="扣工会会费" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="年月" min-width="100" prop="年月" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="所在单位" min-width="180" prop="所在单位" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column align="center" label="核对情况" min-width="110">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag :type="statusType(scope.row.state)">{{statusText(scope.row.state)}}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="核对人员" min-width="180" show-overflow-tooltip>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span v-if="scope.row.managerNames || scope.row.managernames">
|
||||||
|
{{scope.row.managerNames || scope.row.managernames}}
|
||||||
|
</span>
|
||||||
|
<el-tag type="warning" v-else>未分配核对人员</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="核对日期" min-width="160">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{formatDateTime(scope.row.checkedAt)}}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-pagination :current-page="dataPage.pageNumber" :page-size="dataPage.pageSize"
|
||||||
|
:page-sizes="[10,20,50,100]" :total="dataPage.totalCount"
|
||||||
|
@current-change="dataPageNumberChange" @size-change="dataPageSizeChange"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
style="margin-top:15px;text-align:right"></el-pagination>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</guava>
|
||||||
|
|
||||||
|
<el-dialog :close-on-click-modal="false" :visible.sync="uploadDialogVisible" title="上传并分发" width="50%">
|
||||||
|
<el-form label-width="90px">
|
||||||
|
<el-form-item label="任务名称" required>
|
||||||
|
<el-input maxlength="100" v-model="uploadForm.taskName"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="任务说明">
|
||||||
|
<el-input maxlength="500" type="textarea" v-model="uploadForm.description"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="Excel文件" required>
|
||||||
|
<el-upload :action="uploadAction" :auto-upload="false" :data="uploadForm"
|
||||||
|
:limit="20" :multiple="true" :on-error="uploadError"
|
||||||
|
:on-success="uploadSuccess" accept=".xls,.xlsx" name="files" ref="upload">
|
||||||
|
<el-button icon="el-icon-plus" size="small">选择文件</el-button>
|
||||||
|
<div class="el-upload__tip" slot="tip">可同时选择多个文件,数据按“所在单位”首段归组。</div>
|
||||||
|
</el-upload>
|
||||||
|
<el-button @click="downloadTemplate" icon="el-icon-download"
|
||||||
|
size="small" style="margin-top:10px">下载导入模板</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<span class="dialog-footer" slot="footer">
|
||||||
|
<el-button @click="uploadDialogVisible=false">取 消</el-button>
|
||||||
|
<el-button :loading="uploading" @click="submitUpload" type="primary">上传并分发</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog :close-on-click-modal="false" :visible.sync="rejectDialogVisible"
|
||||||
|
title="退回修改版" width="45%">
|
||||||
|
<el-form label-width="90px">
|
||||||
|
<el-form-item label="退回原因" required>
|
||||||
|
<el-input :rows="5" maxlength="500" placeholder="请输入退回原因"
|
||||||
|
show-word-limit type="textarea" v-model="rejectOpinion"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<span class="dialog-footer" slot="footer">
|
||||||
|
<el-button @click="rejectDialogVisible=false">取 消</el-button>
|
||||||
|
<el-button :loading="auditSubmitting" @click="submitReject" type="primary">确 定</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
const vue = new Vue({
|
||||||
|
el: '#app',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
unitLoading: false,
|
||||||
|
uploading: false,
|
||||||
|
tasks: [],
|
||||||
|
unitTasks: [],
|
||||||
|
statusOptions: ['待核对', '已确认', '待审核', '已退回', '已通过'],
|
||||||
|
taskSearch: {taskName: '', taskDate: ''},
|
||||||
|
taskPage: {pageNumber: 1, pageSize: 20, totalCount: 0},
|
||||||
|
unitSearch: {unitName: '', state: null, managerState: null},
|
||||||
|
unitPage: {pageNumber: 1, pageSize: 20, totalCount: 0},
|
||||||
|
currentTask: {},
|
||||||
|
detailView: '',
|
||||||
|
dataTarget: {},
|
||||||
|
dataScope: '',
|
||||||
|
dataVersionType: 'current',
|
||||||
|
dataRows: [],
|
||||||
|
dataLoading: false,
|
||||||
|
dataDialogTitle: '',
|
||||||
|
dataSearch: {searchName: 'employeeNo', searchKeyword: '', state: null},
|
||||||
|
dataPage: {pageNumber: 1, pageSize: 10, totalCount: 0},
|
||||||
|
uploadDialogVisible: false,
|
||||||
|
uploadForm: {taskName: '', description: ''},
|
||||||
|
uploadAction: loc() + '/doUpload',
|
||||||
|
rejectDialogVisible: false,
|
||||||
|
rejectTarget: {},
|
||||||
|
rejectOpinion: '',
|
||||||
|
auditSubmitting: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
'guava': httpVueLoader('/components/plugins/Guava.vue')
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
formatDateTime(value) {
|
||||||
|
return value ? moment(value).format('YYYY-MM-DD HH:mm') : '-'
|
||||||
|
},
|
||||||
|
statusText(state) {
|
||||||
|
return ['待核对', '已确认', '待审核', '已退回', '已通过'][state] || '未知'
|
||||||
|
},
|
||||||
|
statusType(state) {
|
||||||
|
return ['', 'success', 'warning', 'danger', 'success'][state] || 'info'
|
||||||
|
},
|
||||||
|
async loadTasks(resetPage) {
|
||||||
|
if (resetPage) this.taskPage.pageNumber = 1
|
||||||
|
this.loading = true
|
||||||
|
const resp = await $.post(loc() + '/taskData', {
|
||||||
|
taskName: this.taskSearch.taskName,
|
||||||
|
taskDate: this.taskSearch.taskDate,
|
||||||
|
pageNumber: this.taskPage.pageNumber,
|
||||||
|
pageSize: this.taskPage.pageSize
|
||||||
|
})
|
||||||
|
this.loading = false
|
||||||
|
if (resp.code === 0) {
|
||||||
|
const page = resp.data || {}
|
||||||
|
this.tasks = page.list || []
|
||||||
|
this.taskPage.totalCount = page.totalCount || 0
|
||||||
|
} else this.$notify.warning(resp.msg)
|
||||||
|
},
|
||||||
|
resetTaskSearch() {
|
||||||
|
this.taskSearch = {taskName: '', taskDate: ''}
|
||||||
|
this.loadTasks(true)
|
||||||
|
},
|
||||||
|
taskPageNumberChange(value) {
|
||||||
|
this.taskPage.pageNumber = value
|
||||||
|
this.loadTasks(false)
|
||||||
|
},
|
||||||
|
taskPageSizeChange(value) {
|
||||||
|
this.taskPage.pageSize = value
|
||||||
|
this.loadTasks(true)
|
||||||
|
},
|
||||||
|
submitUpload() {
|
||||||
|
if (!this.uploadForm.taskName) {
|
||||||
|
this.$notify.warning('请输入任务名称')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!this.$refs.upload.uploadFiles.length) {
|
||||||
|
this.$notify.warning('请选择 Excel 文件')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.uploading = true
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('taskName', this.uploadForm.taskName)
|
||||||
|
formData.append('description', this.uploadForm.description || '')
|
||||||
|
this.$refs.upload.uploadFiles.forEach(item => formData.append('files', item.raw))
|
||||||
|
$.ajax({
|
||||||
|
url: this.uploadAction,
|
||||||
|
type: 'POST',
|
||||||
|
data: formData,
|
||||||
|
processData: false,
|
||||||
|
contentType: false,
|
||||||
|
dataType: 'json',
|
||||||
|
success: resp => this.uploadSuccess(resp),
|
||||||
|
error: () => this.uploadError()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
downloadTemplate() {
|
||||||
|
window.open(loc() + '/downloadTemplate')
|
||||||
|
},
|
||||||
|
uploadSuccess(resp) {
|
||||||
|
this.uploading = false
|
||||||
|
if (resp.code === 0) {
|
||||||
|
this.uploadDialogVisible = false
|
||||||
|
this.$refs.upload.clearFiles()
|
||||||
|
this.loadTasks(true)
|
||||||
|
const result = resp.data || {}
|
||||||
|
if (result.errorCount > 0) {
|
||||||
|
this.$confirm('共读取 ' + result.totalCount + ' 条,成功分发 ' + result.successCount
|
||||||
|
+ ' 条,失败 ' + result.errorCount + ' 条。', '导入完成', {
|
||||||
|
confirmButtonText: '导出错误信息',
|
||||||
|
cancelButtonText: '关闭',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
window.open(loc() + '/exportImportErrors?cacheKey=' + encodeURIComponent(result.errorCacheKey))
|
||||||
|
}).catch(() => {})
|
||||||
|
} else {
|
||||||
|
this.$notify.success(resp.msg)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$notify.warning(resp.msg)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
uploadError() {
|
||||||
|
this.uploading = false
|
||||||
|
this.$notify.error('上传失败')
|
||||||
|
},
|
||||||
|
async openUnits(row) {
|
||||||
|
this.currentTask = row
|
||||||
|
this.detailView = 'units'
|
||||||
|
this.unitSearch = {unitName: '', state: null, managerState: null}
|
||||||
|
this.unitPage.pageNumber = 1
|
||||||
|
this.$refs.guava.edit()
|
||||||
|
await this.loadUnitTasks(false)
|
||||||
|
},
|
||||||
|
guavaViewChange(view) {
|
||||||
|
if (view.newValue === 'index' && view.oldValue === 'edit'
|
||||||
|
&& this.detailView === 'data' && this.dataScope === 'unit') {
|
||||||
|
this.detailView = 'units'
|
||||||
|
this.$nextTick(() => this.$refs.guava.edit())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async loadUnitTasks(resetPage) {
|
||||||
|
if (resetPage) this.unitPage.pageNumber = 1
|
||||||
|
this.unitLoading = true
|
||||||
|
const resp = await $.post(loc() + '/unitTaskData', {
|
||||||
|
taskId: this.currentTask.id,
|
||||||
|
unitName: this.unitSearch.unitName,
|
||||||
|
state: this.unitSearch.state,
|
||||||
|
managerState: this.unitSearch.managerState,
|
||||||
|
pageNumber: this.unitPage.pageNumber,
|
||||||
|
pageSize: this.unitPage.pageSize
|
||||||
|
})
|
||||||
|
this.unitLoading = false
|
||||||
|
if (resp.code === 0) {
|
||||||
|
const page = resp.data || {}
|
||||||
|
this.unitTasks = page.list || []
|
||||||
|
this.unitPage.totalCount = page.totalCount || 0
|
||||||
|
} else this.$notify.warning(resp.msg)
|
||||||
|
},
|
||||||
|
resetUnitSearch() {
|
||||||
|
this.unitSearch = {unitName: '', state: null, managerState: null}
|
||||||
|
this.loadUnitTasks(true)
|
||||||
|
},
|
||||||
|
unitPageNumberChange(value) {
|
||||||
|
this.unitPage.pageNumber = value
|
||||||
|
this.loadUnitTasks(false)
|
||||||
|
},
|
||||||
|
unitPageSizeChange(value) {
|
||||||
|
this.unitPage.pageSize = value
|
||||||
|
this.loadUnitTasks(true)
|
||||||
|
},
|
||||||
|
openUnitData(row, versionType) {
|
||||||
|
this.detailView = 'data'
|
||||||
|
this.dataScope = 'unit'
|
||||||
|
this.dataVersionType = versionType || 'current'
|
||||||
|
this.dataTarget = row
|
||||||
|
this.dataDialogTitle = row.unitName
|
||||||
|
+ (this.dataVersionType === 'pending' ? ' - 待审核修改版数据' : ' - 当前生效数据')
|
||||||
|
this.dataSearch = {searchName: 'employeeNo', searchKeyword: '', state: null}
|
||||||
|
this.dataPage.pageNumber = 1
|
||||||
|
this.$refs.guava.edit()
|
||||||
|
this.loadDataRows(false)
|
||||||
|
},
|
||||||
|
openCurrentData(row) {
|
||||||
|
this.detailView = 'data'
|
||||||
|
this.dataScope = 'task'
|
||||||
|
this.dataVersionType = 'current'
|
||||||
|
this.dataTarget = row
|
||||||
|
this.dataDialogTitle = row.name + ' - 生效数据'
|
||||||
|
this.dataSearch = {searchName: 'employeeNo', searchKeyword: '', state: null}
|
||||||
|
this.dataPage.pageNumber = 1
|
||||||
|
this.$refs.guava.edit()
|
||||||
|
this.loadDataRows(false)
|
||||||
|
},
|
||||||
|
async loadDataRows(resetPage) {
|
||||||
|
if (resetPage) this.dataPage.pageNumber = 1
|
||||||
|
this.dataLoading = true
|
||||||
|
const url = this.dataScope === 'unit' ? '/unitDataPage' : '/currentDataPage'
|
||||||
|
const params = {
|
||||||
|
searchName: this.dataSearch.searchName,
|
||||||
|
searchKeyword: this.dataSearch.searchKeyword,
|
||||||
|
state: this.dataSearch.state,
|
||||||
|
pageNumber: this.dataPage.pageNumber,
|
||||||
|
pageSize: this.dataPage.pageSize
|
||||||
|
}
|
||||||
|
if (this.dataScope === 'unit') {
|
||||||
|
params.unitTaskId = this.dataTarget.id
|
||||||
|
params.versionType = this.dataVersionType
|
||||||
|
}
|
||||||
|
else params.taskId = this.dataTarget.id
|
||||||
|
const resp = await $.post(loc() + url, params)
|
||||||
|
this.dataLoading = false
|
||||||
|
if (resp.code === 0) {
|
||||||
|
const page = resp.data || {}
|
||||||
|
this.dataRows = page.list || []
|
||||||
|
this.dataPage.totalCount = page.totalCount || 0
|
||||||
|
} else {
|
||||||
|
this.dataRows = []
|
||||||
|
this.dataPage.totalCount = 0
|
||||||
|
this.$notify.warning(resp.msg)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resetDataSearch() {
|
||||||
|
this.dataSearch = {searchName: 'employeeNo', searchKeyword: '', state: null}
|
||||||
|
this.loadDataRows(true)
|
||||||
|
},
|
||||||
|
dataPageNumberChange(value) {
|
||||||
|
this.dataPage.pageNumber = value
|
||||||
|
this.loadDataRows(false)
|
||||||
|
},
|
||||||
|
dataPageSizeChange(value) {
|
||||||
|
this.dataPage.pageSize = value
|
||||||
|
this.loadDataRows(true)
|
||||||
|
},
|
||||||
|
download(row, versionType) {
|
||||||
|
window.open(loc() + '/download?unitTaskId=' + row.id + '&versionType=' + versionType)
|
||||||
|
},
|
||||||
|
exportCurrent(row) {
|
||||||
|
window.open(loc() + '/exportCurrent?taskId=' + row.id)
|
||||||
|
},
|
||||||
|
async deleteTask(row) {
|
||||||
|
try {
|
||||||
|
await this.$confirm('删除后,该任务的单位数据、修改数据和审核记录都将被清除,且无法恢复。',
|
||||||
|
'确认删除“' + row.name + '”?', {
|
||||||
|
confirmButtonText: '确认删除',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const resp = await $.post(loc() + '/doDelete', {taskId: row.id})
|
||||||
|
if (resp.code === 0) {
|
||||||
|
this.$notify.success(resp.msg)
|
||||||
|
if (this.currentTask.id === row.id) {
|
||||||
|
this.$refs.guava.index()
|
||||||
|
this.currentTask = {}
|
||||||
|
this.unitTasks = []
|
||||||
|
}
|
||||||
|
if (this.dataScope === 'task' && this.dataTarget.id === row.id) {
|
||||||
|
this.$refs.guava.index()
|
||||||
|
this.dataTarget = {}
|
||||||
|
this.dataRows = []
|
||||||
|
}
|
||||||
|
this.loadTasks(false)
|
||||||
|
} else this.$notify.warning(resp.msg)
|
||||||
|
},
|
||||||
|
async audit(row, approved) {
|
||||||
|
if (!approved) {
|
||||||
|
this.rejectTarget = row
|
||||||
|
this.rejectOpinion = ''
|
||||||
|
this.rejectDialogVisible = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await this.submitAudit(row, true, '')
|
||||||
|
},
|
||||||
|
async submitReject() {
|
||||||
|
const opinion = (this.rejectOpinion || '').trim()
|
||||||
|
if (!opinion) {
|
||||||
|
this.$notify.warning('请输入退回原因')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.auditSubmitting = true
|
||||||
|
const success = await this.submitAudit(this.rejectTarget, false, opinion)
|
||||||
|
this.auditSubmitting = false
|
||||||
|
if (success) this.rejectDialogVisible = false
|
||||||
|
},
|
||||||
|
async submitAudit(row, approved, opinion) {
|
||||||
|
const resp = await $.post(loc() + '/doAudit', {unitTaskId: row.id, approved, opinion})
|
||||||
|
if (resp.code === 0) {
|
||||||
|
this.$notify.success(resp.msg)
|
||||||
|
await this.loadUnitTasks(false)
|
||||||
|
this.loadTasks(false)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
this.$notify.warning(resp.msg)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.loadTasks(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<!--#
|
||||||
|
}
|
||||||
|
#-->
|
||||||
@@ -0,0 +1,318 @@
|
|||||||
|
<!--#
|
||||||
|
layout("/layouts/platform.html"){
|
||||||
|
#-->
|
||||||
|
<div id="app" v-cloak>
|
||||||
|
<guava ref="guava">
|
||||||
|
<template>
|
||||||
|
<el-card shadow="never">
|
||||||
|
<div slot="header">我的分级核对任务</div>
|
||||||
|
<el-alert :closable="false" show-icon style="margin-bottom:15px" type="warning"
|
||||||
|
title="温馨提示:请先下载或查看核对数据。若数据有误,请按原模板修改后上传修改版,提交后进入校工会审核;若数据无误,无需上传文件,进入“核对数据”页面点击“确认无误”即可完成核对。"></el-alert>
|
||||||
|
<el-form :inline="true" :model="searchForm" size="small">
|
||||||
|
<el-form-item label="任务/单位">
|
||||||
|
<el-input clearable placeholder="请输入任务名称、单位或任务日期" v-model="searchForm.keyword"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="核对状态">
|
||||||
|
<el-select clearable placeholder="全部" v-model="searchForm.state">
|
||||||
|
<el-option :key="index" :label="name" :value="index"
|
||||||
|
v-for="(name,index) in statusOptions"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="loadTasks(true)" icon="el-icon-search" type="primary">查询</el-button>
|
||||||
|
<el-button @click="resetSearch">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-table :data="tasks" border v-loading="loading">
|
||||||
|
<el-table-column label="任务名称" prop="taskName" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="单位" prop="unitName" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column align="center" label="任务日期" min-width="160">
|
||||||
|
<template slot-scope="scope">{{formatDateTime(scope.row.taskDate || scope.row.taskdate)}}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="核对日期" min-width="160">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{formatDateTime(scope.row.checkedAt)}}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="行数" prop="rowCount" width="80"></el-table-column>
|
||||||
|
<el-table-column align="center" label="状态" width="110">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag :type="statusType(scope.row.state)">{{statusText(scope.row.state)}}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="审核意见" prop="auditOpinion" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column align="center" label="操作" width="350">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button @click="openData(scope.row)" size="mini" type="primary">核对数据</el-button>
|
||||||
|
<el-button @click="download(scope.row)" size="mini">下载数据</el-button>
|
||||||
|
<!--<el-button @click="confirm(scope.row)" size="mini" type="success"
|
||||||
|
v-if="scope.row.state===0">确认无误</el-button>-->
|
||||||
|
<el-button @click="openRevision(scope.row)" size="mini" type="primary"
|
||||||
|
v-if="scope.row.state===0 || scope.row.state===3">上传修改版</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-pagination :current-page="pageForm.pageNumber" :page-size="pageForm.pageSize"
|
||||||
|
:page-sizes="[10,20,50,100]" :total="pageForm.totalCount"
|
||||||
|
@current-change="pageNumberChange" @size-change="pageSizeChange"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
style="margin-top:15px;text-align:right"></el-pagination>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #edit_func>
|
||||||
|
<el-button @click="confirm(currentTask)" size="small" type="success"
|
||||||
|
v-if="currentTask.state===0">确认无误</el-button>
|
||||||
|
<el-button @click="openRevision(currentTask)" size="small" type="primary"
|
||||||
|
v-if="currentTask.state===0 || currentTask.state===3">上传修改版</el-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #edit>
|
||||||
|
<el-divider content-position="left">{{dataDialogTitle}}</el-divider>
|
||||||
|
<el-form :inline="true" :model="dataSearch" size="small">
|
||||||
|
<el-form-item>
|
||||||
|
<el-input @keyup.enter.native="loadDataRows(true)" clearable placeholder="请输入查询内容"
|
||||||
|
v-model="dataSearch.searchKeyword">
|
||||||
|
<el-select placeholder="查询字段" slot="prepend" style="width:120px"
|
||||||
|
v-model="dataSearch.searchName">
|
||||||
|
<el-option label="薪酬单位代码" value="salaryUnitCode"></el-option>
|
||||||
|
<el-option label="职工号" value="employeeNo"></el-option>
|
||||||
|
<el-option label="姓名" value="employeeName"></el-option>
|
||||||
|
<el-option label="扣工会会费" value="unionFee"></el-option>
|
||||||
|
<el-option label="年月" value="yearMonth"></el-option>
|
||||||
|
<el-option label="所在单位" value="unitName"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="核对情况">
|
||||||
|
<el-select clearable placeholder="全部" v-model="dataSearch.state">
|
||||||
|
<el-option :key="index" :label="name" :value="index"
|
||||||
|
v-for="(name,index) in statusOptions"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="loadDataRows(true)" icon="el-icon-search" type="primary">查询</el-button>
|
||||||
|
<el-button @click="resetDataSearch">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-table :data="dataRows" border v-loading="dataLoading">
|
||||||
|
<el-table-column align="center" label="序号" width="70">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{scope.$index + (dataPage.pageNumber - 1) * dataPage.pageSize + 1}}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="薪酬单位代码" min-width="130" prop="薪酬单位代码" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="职工号" min-width="120" prop="职工号" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="姓名" min-width="100" prop="姓名" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="扣工会会费" min-width="120" prop="扣工会会费" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="年月" min-width="100" prop="年月" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column label="所在单位" min-width="180" prop="所在单位" show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column align="center" label="核对情况" min-width="110">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag :type="statusType(scope.row.state)">{{statusText(scope.row.state)}}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="核对人员" min-width="180" show-overflow-tooltip>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span v-if="scope.row.managerNames || scope.row.managernames">
|
||||||
|
{{scope.row.managerNames || scope.row.managernames}}
|
||||||
|
</span>
|
||||||
|
<el-tag type="warning" v-else>未分配核对人员</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="核对日期" min-width="160">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{formatDateTime(scope.row.checkedAt)}}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-pagination :current-page="dataPage.pageNumber" :page-size="dataPage.pageSize"
|
||||||
|
:page-sizes="[10,20,50,100]" :total="dataPage.totalCount"
|
||||||
|
@current-change="dataPageNumberChange" @size-change="dataPageSizeChange"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
style="margin-top:15px;text-align:right"></el-pagination>
|
||||||
|
</template>
|
||||||
|
</guava>
|
||||||
|
|
||||||
|
<el-dialog :visible.sync="revisionDialogVisible" title="上传修改后的数据" width="45%">
|
||||||
|
<el-alert :closable="false" show-icon style="margin-bottom:15px" type="warning"
|
||||||
|
title="修改版必须使用固定导入模板,且只能包含当前单位数据。"></el-alert>
|
||||||
|
<el-upload :action="revisionAction" :auto-upload="false" :data="revisionData"
|
||||||
|
:limit="1" :on-error="uploadError" :on-success="uploadSuccess"
|
||||||
|
accept=".xls,.xlsx" name="file" ref="revisionUpload">
|
||||||
|
<el-button icon="el-icon-plus" size="small">选择修改版</el-button>
|
||||||
|
</el-upload>
|
||||||
|
<span class="dialog-footer" slot="footer">
|
||||||
|
<el-button @click="revisionDialogVisible=false">取 消</el-button>
|
||||||
|
<el-button :loading="uploading" @click="submitRevision" type="primary">提 交</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
const vue = new Vue({
|
||||||
|
el: '#app',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
uploading: false,
|
||||||
|
tasks: [],
|
||||||
|
currentTask: {},
|
||||||
|
dataRows: [],
|
||||||
|
dataLoading: false,
|
||||||
|
dataDialogTitle: '',
|
||||||
|
dataSearch: {searchName: 'employeeNo', searchKeyword: '', state: null},
|
||||||
|
dataPage: {pageNumber: 1, pageSize: 10, totalCount: 0},
|
||||||
|
statusOptions: ['待核对', '已确认', '待审核', '已退回', '已通过'],
|
||||||
|
searchForm: {keyword: '', state: null},
|
||||||
|
pageForm: {pageNumber: 1, pageSize: 10, totalCount: 0},
|
||||||
|
revisionDialogVisible: false,
|
||||||
|
revisionAction: loc() + '/doUploadRevision',
|
||||||
|
revisionData: {unitTaskId: ''}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
'guava': httpVueLoader('/components/plugins/Guava.vue')
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
formatDateTime(value) {
|
||||||
|
return value ? moment(value).format('YYYY-MM-DD HH:mm') : '-'
|
||||||
|
},
|
||||||
|
statusText(state) {
|
||||||
|
return ['待核对', '已确认', '待审核', '已退回', '已通过'][state] || '未知'
|
||||||
|
},
|
||||||
|
statusType(state) {
|
||||||
|
return ['', 'success', 'warning', 'danger', 'success'][state] || 'info'
|
||||||
|
},
|
||||||
|
async loadTasks(resetPage) {
|
||||||
|
if (resetPage) this.pageForm.pageNumber = 1
|
||||||
|
this.loading = true
|
||||||
|
const resp = await $.post(loc() + '/taskData', {
|
||||||
|
keyword: this.searchForm.keyword,
|
||||||
|
state: this.searchForm.state,
|
||||||
|
pageNumber: this.pageForm.pageNumber,
|
||||||
|
pageSize: this.pageForm.pageSize
|
||||||
|
})
|
||||||
|
this.loading = false
|
||||||
|
if (resp.code === 0) {
|
||||||
|
const page = resp.data || {}
|
||||||
|
this.tasks = page.list || []
|
||||||
|
this.pageForm.totalCount = page.totalCount || 0
|
||||||
|
} else this.$notify.warning(resp.msg)
|
||||||
|
},
|
||||||
|
resetSearch() {
|
||||||
|
this.searchForm = {keyword: '', state: null}
|
||||||
|
this.loadTasks(true)
|
||||||
|
},
|
||||||
|
pageNumberChange(value) {
|
||||||
|
this.pageForm.pageNumber = value
|
||||||
|
this.loadTasks(false)
|
||||||
|
},
|
||||||
|
pageSizeChange(value) {
|
||||||
|
this.pageForm.pageSize = value
|
||||||
|
this.loadTasks(true)
|
||||||
|
},
|
||||||
|
download(row) {
|
||||||
|
window.open(loc() + '/download?unitTaskId=' + row.id)
|
||||||
|
},
|
||||||
|
openData(row) {
|
||||||
|
this.currentTask = row
|
||||||
|
this.dataDialogTitle = row.taskName + ' - ' + row.unitName + ' - 数据详情'
|
||||||
|
this.dataSearch = {searchName: 'employeeNo', searchKeyword: '', state: null}
|
||||||
|
this.dataPage.pageNumber = 1
|
||||||
|
this.$refs.guava.edit()
|
||||||
|
this.loadDataRows(false)
|
||||||
|
},
|
||||||
|
async loadDataRows(resetPage) {
|
||||||
|
if (resetPage) this.dataPage.pageNumber = 1
|
||||||
|
this.dataLoading = true
|
||||||
|
const resp = await $.post(loc() + '/dataPage', {
|
||||||
|
unitTaskId: this.currentTask.id,
|
||||||
|
searchName: this.dataSearch.searchName,
|
||||||
|
searchKeyword: this.dataSearch.searchKeyword,
|
||||||
|
state: this.dataSearch.state,
|
||||||
|
pageNumber: this.dataPage.pageNumber,
|
||||||
|
pageSize: this.dataPage.pageSize
|
||||||
|
})
|
||||||
|
this.dataLoading = false
|
||||||
|
if (resp.code === 0) {
|
||||||
|
const page = resp.data || {}
|
||||||
|
this.dataRows = page.list || []
|
||||||
|
this.dataPage.totalCount = page.totalCount || 0
|
||||||
|
} else {
|
||||||
|
this.dataRows = []
|
||||||
|
this.dataPage.totalCount = 0
|
||||||
|
this.$notify.warning(resp.msg)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resetDataSearch() {
|
||||||
|
this.dataSearch = {searchName: 'employeeNo', searchKeyword: '', state: null}
|
||||||
|
this.loadDataRows(true)
|
||||||
|
},
|
||||||
|
dataPageNumberChange(value) {
|
||||||
|
this.dataPage.pageNumber = value
|
||||||
|
this.loadDataRows(false)
|
||||||
|
},
|
||||||
|
dataPageSizeChange(value) {
|
||||||
|
this.dataPage.pageSize = value
|
||||||
|
this.loadDataRows(true)
|
||||||
|
},
|
||||||
|
async confirm(row) {
|
||||||
|
try {
|
||||||
|
await this.$confirm('确认本单位数据无误吗?确认后不能再上传修改数据,无修改内容时不会进入审核流程!', '提示', {type: 'warning'})
|
||||||
|
} catch (e) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const resp = await $.post(loc() + '/doConfirm', {unitTaskId: row.id})
|
||||||
|
if (resp.code === 0) {
|
||||||
|
this.$notify.success(resp.msg)
|
||||||
|
this.$refs.guava.index()
|
||||||
|
this.loadTasks(false)
|
||||||
|
} else this.$notify.warning(resp.msg)
|
||||||
|
},
|
||||||
|
openRevision(row) {
|
||||||
|
this.revisionData.unitTaskId = row.id
|
||||||
|
this.revisionDialogVisible = true
|
||||||
|
this.$nextTick(() => this.$refs.revisionUpload.clearFiles())
|
||||||
|
},
|
||||||
|
submitRevision() {
|
||||||
|
if (!this.$refs.revisionUpload.uploadFiles.length) {
|
||||||
|
this.$notify.warning('请选择修改版 Excel')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.uploading = true
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('unitTaskId', this.revisionData.unitTaskId)
|
||||||
|
formData.append('file', this.$refs.revisionUpload.uploadFiles[0].raw)
|
||||||
|
$.ajax({
|
||||||
|
url: this.revisionAction,
|
||||||
|
type: 'POST',
|
||||||
|
data: formData,
|
||||||
|
processData: false,
|
||||||
|
contentType: false,
|
||||||
|
dataType: 'json',
|
||||||
|
success: resp => this.uploadSuccess(resp),
|
||||||
|
error: () => this.uploadError()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
uploadSuccess(resp) {
|
||||||
|
this.uploading = false
|
||||||
|
if (resp.code === 0) {
|
||||||
|
this.$notify.success(resp.msg)
|
||||||
|
this.revisionDialogVisible = false
|
||||||
|
this.$refs.guava.index()
|
||||||
|
this.loadTasks(false)
|
||||||
|
} else this.$notify.warning(resp.msg)
|
||||||
|
},
|
||||||
|
uploadError() {
|
||||||
|
this.uploading = false
|
||||||
|
this.$notify.error('上传失败')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.loadTasks(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<!--#
|
||||||
|
}
|
||||||
|
#-->
|
||||||
@@ -288,7 +288,8 @@
|
|||||||
pageForm: {
|
pageForm: {
|
||||||
source: source,
|
source: source,
|
||||||
searchName: "u.username",
|
searchName: "u.username",
|
||||||
audit: 2
|
// 已办入口默认显示本阶段已审核记录。
|
||||||
|
audit: new URLSearchParams(window.location.search).get("audit") === "1" ? 1 : 2
|
||||||
},
|
},
|
||||||
unions: [],
|
unions: [],
|
||||||
tableColumns: [
|
tableColumns: [
|
||||||
|
|||||||
@@ -67,12 +67,22 @@ layout("/layouts/platform.html"){
|
|||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dashboard-drill {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-drill:hover .top-col-member-number,
|
||||||
|
.dashboard-drill:hover .col-title {
|
||||||
|
color: #409EFF;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div id="app" v-cloak>
|
<div id="app" v-cloak>
|
||||||
<guava>
|
<guava>
|
||||||
<el-row style="background-color: #f0f2f5" type="flex">
|
<el-row style="background-color: #f0f2f5" type="flex">
|
||||||
<el-col class="top-col" v-loading="loading.memberNumber">
|
<el-col class="top-col dashboard-drill" v-loading="loading.memberNumber"
|
||||||
|
title="点击查看会员明细"
|
||||||
|
@click.native.capture="openMemberDetail('会员总数明细', {year: moment().format('YYYY')})">
|
||||||
<div class="col-title">会员数</div>
|
<div class="col-title">会员数</div>
|
||||||
<div class="top-col-member-number">{{memberNumberData.memberNum}}<span
|
<div class="top-col-member-number">{{memberNumberData.memberNum}}<span
|
||||||
style="font-size: 14px"> 人</span></div>
|
style="font-size: 14px"> 人</span></div>
|
||||||
@@ -97,16 +107,20 @@ layout("/layouts/platform.html"){
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col class="top-col" v-loading="loading.growthTrend">
|
<el-col class="top-col" v-loading="loading.growthTrend">
|
||||||
<div class="col-title">增长趋势</div>
|
<div class="col-title">增长趋势</div>
|
||||||
<div class="top-col-chart" id="growthTrendChart"></div>
|
<div class="top-col-chart dashboard-drill" title="点击趋势点查看年度明细"
|
||||||
|
id="growthTrendChart"></div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col class="top-col" v-loading="loading.memberPercentage">
|
<el-col class="top-col dashboard-drill" v-loading="loading.memberPercentage"
|
||||||
|
title="点击查看会员明细"
|
||||||
|
@click.native.capture="openMemberDetail('会员占比明细', {year: moment().format('YYYY')})">
|
||||||
<div class="col-title">会员占比</div>
|
<div class="col-title">会员占比</div>
|
||||||
<div class="top-col-chart" id="memberPercentageChart"
|
<div class="top-col-chart" id="memberPercentageChart"
|
||||||
style="position: absolute;height: 120px;right: -10%;bottom: 20px"></div>
|
style="position: absolute;height: 120px;right: -10%;bottom: 20px"></div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col class="top-col" v-loading="loading.growthTrend">
|
<el-col class="top-col" v-loading="loading.growthTrend">
|
||||||
<div class="col-title">男女占比</div>
|
<div class="col-title">男女占比</div>
|
||||||
<div class="top-col-chart" id="memberSexPercentageChart"
|
<div class="top-col-chart dashboard-drill" title="点击图表项查看性别明细"
|
||||||
|
id="memberSexPercentageChart"
|
||||||
style="position: absolute;height: 120px;right: -10%;bottom: 20px"></div>
|
style="position: absolute;height: 120px;right: -10%;bottom: 20px"></div>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -119,7 +133,9 @@ layout("/layouts/platform.html"){
|
|||||||
|
|
||||||
<el-table :data="unionMember" :header-cell-style="{background:'#FAFAFA'}"
|
<el-table :data="unionMember" :header-cell-style="{background:'#FAFAFA'}"
|
||||||
height="calc(100vh - 160px - 300px)"
|
height="calc(100vh - 160px - 300px)"
|
||||||
row-key="id" style="width: 100%;margin-top: 20px">
|
row-key="id" style="width: 100%;margin-top: 20px;cursor: pointer"
|
||||||
|
title="点击工会行查看会员明细"
|
||||||
|
@row-click="openUnionMemberDetail">
|
||||||
<el-table-column label="序号" width="100px">
|
<el-table-column label="序号" width="100px">
|
||||||
<template scope="{$index}">
|
<template scope="{$index}">
|
||||||
<div class="idx idx-rank" v-if="$index<3">{{$index+1}}</div>
|
<div class="idx idx-rank" v-if="$index<3">{{$index+1}}</div>
|
||||||
@@ -152,6 +168,7 @@ layout("/layouts/platform.html"){
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</guava>
|
</guava>
|
||||||
|
<data-board-detail ref="dataBoardDetail" :base-url="loc()"></data-board-detail>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -193,8 +210,28 @@ layout("/layouts/platform.html"){
|
|||||||
unionMember: [],
|
unionMember: [],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {},
|
components: {
|
||||||
|
'data-board-detail': httpVueLoader('/components/dashboard/DataBoardDetail.vue?v=1.0.3')
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
openMemberDetail(title, filters) {
|
||||||
|
this.$refs.dataBoardDetail.open(title, 'member', filters)
|
||||||
|
},
|
||||||
|
openUnionMemberDetail(row) {
|
||||||
|
this.openMemberDetail(row.unionname + '会员明细', {
|
||||||
|
year: moment().format('YYYY'),
|
||||||
|
unionId: row.unionid
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getTinyAreaRow(event, rows) {
|
||||||
|
const point = event && event.data ? event.data.data : null
|
||||||
|
const index = point && point.x !== undefined ? Number(point.x) : NaN
|
||||||
|
if (Number.isInteger(index) && rows[index]) {
|
||||||
|
return rows[index]
|
||||||
|
}
|
||||||
|
const value = point && point.y !== undefined ? point.y : point
|
||||||
|
return rows.find(item => String(item.value) === String(value))
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* 会员数
|
* 会员数
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
@@ -247,6 +284,12 @@ layout("/layouts/platform.html"){
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
chart.growthTrendChart.render();
|
chart.growthTrendChart.render();
|
||||||
|
chart.growthTrendChart.on('element:click', event => {
|
||||||
|
const row = this.getTinyAreaRow(event, data)
|
||||||
|
if (row) {
|
||||||
|
this.openMemberDetail(row.label + '年会员明细', {year: row.label})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -321,6 +364,15 @@ layout("/layouts/platform.html"){
|
|||||||
interactions: [{type: 'element-active'}], color: ['#409EFF', '#F56C6C'],
|
interactions: [{type: 'element-active'}], color: ['#409EFF', '#F56C6C'],
|
||||||
});
|
});
|
||||||
chart.memberSexPercentageChart.render();
|
chart.memberSexPercentageChart.render();
|
||||||
|
chart.memberSexPercentageChart.on('element:click', event => {
|
||||||
|
const row = event && event.data ? event.data.data : null
|
||||||
|
if (row) {
|
||||||
|
this.openMemberDetail(row.type + '性会员明细', {
|
||||||
|
year: moment().format('YYYY'),
|
||||||
|
sex: row.type
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -358,6 +410,12 @@ layout("/layouts/platform.html"){
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
chart.unionMemberChart.render();
|
chart.unionMemberChart.render();
|
||||||
|
chart.unionMemberChart.on('element:click', event => {
|
||||||
|
const row = this.getTinyAreaRow(event, chartData)
|
||||||
|
if (row) {
|
||||||
|
this.openUnionMemberDetail(row)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -407,6 +465,15 @@ layout("/layouts/platform.html"){
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
chart.personTypeMemberChart.render();
|
chart.personTypeMemberChart.render();
|
||||||
|
chart.personTypeMemberChart.on('element:click', event => {
|
||||||
|
const row = event && event.data ? event.data.data : null
|
||||||
|
if (row) {
|
||||||
|
this.openMemberDetail(row.label + '会员明细', {
|
||||||
|
year: moment().format('YYYY'),
|
||||||
|
personType: row.label
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
})
|
})
|
||||||
@@ -456,6 +523,15 @@ layout("/layouts/platform.html"){
|
|||||||
area: {},
|
area: {},
|
||||||
});
|
});
|
||||||
chart.userStateMemberChart.render();
|
chart.userStateMemberChart.render();
|
||||||
|
chart.userStateMemberChart.on('element:click', event => {
|
||||||
|
const row = event && event.data ? event.data.data : null
|
||||||
|
if (row) {
|
||||||
|
this.openMemberDetail(row.label + '会员明细', {
|
||||||
|
year: moment().format('YYYY'),
|
||||||
|
userState: row.label
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ layout("/layouts/platform.html"){
|
|||||||
|
|
||||||
<table-tool label="提案信息" :app="this">
|
<table-tool label="提案信息" :app="this">
|
||||||
<template #func>
|
<template #func>
|
||||||
<el-button @click="exportAllProposal" type="primary" size="small">导出立案汇总表</el-button>
|
<el-button @click="exportCompleteData" type="primary" size="small">按条件导出完整数据</el-button>
|
||||||
|
<el-button @click="exportAllProposal" type="success" size="small">导出原立案汇总表</el-button>
|
||||||
</template>
|
</template>
|
||||||
</table-tool>
|
</table-tool>
|
||||||
|
|
||||||
@@ -121,6 +122,7 @@ layout("/layouts/platform.html"){
|
|||||||
mixins: [initTableMixins],
|
mixins: [initTableMixins],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
showStateSearch: true,
|
||||||
resultOptions: [],
|
resultOptions: [],
|
||||||
determineTypeOptions: [],
|
determineTypeOptions: [],
|
||||||
typeOptions: [],
|
typeOptions: [],
|
||||||
@@ -138,6 +140,7 @@ layout("/layouts/platform.html"){
|
|||||||
meetingId: '',
|
meetingId: '',
|
||||||
unionId: '',
|
unionId: '',
|
||||||
unitId: '',
|
unitId: '',
|
||||||
|
undertakeId: '',
|
||||||
delegationId: '',
|
delegationId: '',
|
||||||
proposalResult: [],
|
proposalResult: [],
|
||||||
proposalTypes: [],
|
proposalTypes: [],
|
||||||
@@ -166,42 +169,50 @@ layout("/layouts/platform.html"){
|
|||||||
'proposal-table': httpVueLoader('/components/proposal/ProposalTable.vue'),
|
'proposal-table': httpVueLoader('/components/proposal/ProposalTable.vue'),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
exportCompleteData() {
|
||||||
|
proposal.exportCompleteData(this, {title: '立案提案完整数据', caseOnly: true})
|
||||||
|
},
|
||||||
exportAllProposal() {
|
exportAllProposal() {
|
||||||
const proposalTypes = JSON.stringify(this.pageForm.proposalTypes)
|
const {exportCondition, exportFileCondition} = proposal.buildExportCondition(this)
|
||||||
const proposalResult = JSON.stringify(this.pageForm.proposalResult)
|
|
||||||
const searchName2 = this.pageForm.searchName2
|
|
||||||
const searchKeyword2 = this.pageForm.searchKeyword2
|
|
||||||
const stateCode = this.pageForm.stateCode
|
|
||||||
const searchKeyword = this.pageForm.searchKeyword
|
|
||||||
const searchName = this.pageForm.searchName
|
|
||||||
const delegationId = this.pageForm.delegationId
|
|
||||||
const unionId = this.pageForm.unionId
|
|
||||||
const unitId = this.pageForm.unitId
|
|
||||||
const meetingId = this.pageForm.meetingId
|
|
||||||
let props = {}
|
let props = {}
|
||||||
this.tableColumns.forEach(v => {
|
this.tableColumns.forEach(v => {
|
||||||
props[v.prop] = v.label
|
props[v.prop] = v.label
|
||||||
})
|
})
|
||||||
window.open(loc() + "/exportAllProposal?proposalTypes=" + proposalTypes +
|
this.$confirm('将按当前条件导出全部 ' + (this.pageForm.totalCount || 0)
|
||||||
"&proposalResult=" + proposalResult +
|
+ ' 条立案汇总数据,不受当前分页影响。查询条件:' + exportCondition, '导出确认', {
|
||||||
"&searchName2=" + searchName2 +
|
confirmButtonText: '确认导出',
|
||||||
"&searchKeyword2=" + searchKeyword2 +
|
cancelButtonText: '取消',
|
||||||
"&stateCode=" + stateCode +
|
type: 'warning'
|
||||||
"&searchKeyword=" + searchKeyword +
|
}).then(() => {
|
||||||
"&searchName=" + searchName +
|
const exportForm = $('<form method="post" target="_blank"></form>')
|
||||||
"&delegationId=" + delegationId +
|
exportForm.attr('action', loc() + '/exportAllProposal')
|
||||||
"&unionId=" + unionId +
|
const params = Object.assign({}, this.pageForm, {
|
||||||
"&unitId=" + unitId +
|
proposalTypes: JSON.stringify(this.pageForm.proposalTypes),
|
||||||
"&meetingId=" + meetingId +
|
proposalResult: JSON.stringify(this.pageForm.proposalResult),
|
||||||
"&props=" + JSON.stringify(props))
|
determineTypeOptions: JSON.stringify(this.pageForm.proposalDetermineTypes),
|
||||||
|
props: JSON.stringify(props),
|
||||||
|
exportCondition,
|
||||||
|
exportFileCondition
|
||||||
|
})
|
||||||
|
Object.keys(params).forEach(key => {
|
||||||
|
if (!Array.isArray(params[key])) {
|
||||||
|
exportForm.append($('<input type="hidden">').attr('name', key).val(params[key] || ''))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$('body').append(exportForm)
|
||||||
|
exportForm.submit()
|
||||||
|
exportForm.remove()
|
||||||
|
}).catch(() => {})
|
||||||
},
|
},
|
||||||
oneProposalExport(id) {
|
oneProposalExport(id) {
|
||||||
window.location.href = "/platform/proposal/statistics/summary/oneProposalExport?proposalId=" + id
|
window.location.href = "/platform/proposal/statistics/summary/oneProposalExport?proposalId=" + id
|
||||||
},
|
},
|
||||||
async meetingChange(val) {
|
async meetingChange(val) {
|
||||||
this.pageForm.delegationId = ''
|
this.pageForm.delegationId = ''
|
||||||
this.delegationOptions = await proposal.getDelegation(val)
|
this.pageForm.undertakeId = ''
|
||||||
this.undertakeOptions = await proposal.getUndertakeByMeeting(val)
|
this.delegationOptions = val ? await proposal.getDelegation(val) : []
|
||||||
|
this.undertakeOptions = val ? await proposal.getUndertakeByMeeting(val)
|
||||||
|
: await proposal.getAllProposalUndertake()
|
||||||
this.doSearch()
|
this.doSearch()
|
||||||
},
|
},
|
||||||
async delegationChange(val) {
|
async delegationChange(val) {
|
||||||
@@ -271,8 +282,9 @@ layout("/layouts/platform.html"){
|
|||||||
async created() {
|
async created() {
|
||||||
this.meetingOptions = await getAllJdh()
|
this.meetingOptions = await getAllJdh()
|
||||||
this.pageForm.meetingId = this.meetingOptions.length ? this.meetingOptions[0].id : ''
|
this.pageForm.meetingId = this.meetingOptions.length ? this.meetingOptions[0].id : ''
|
||||||
|
this.meetingOptions.unshift({id: '', jdhallname: '全部届次'})
|
||||||
|
|
||||||
this.stateOptions = await proposal.getOpenProposalState()
|
this.stateOptions = await proposal.getProposalState()
|
||||||
this.typeOptions = await proposal.getProposalType()
|
this.typeOptions = await proposal.getProposalType()
|
||||||
this.resultOptions = await getDictOptions("proposal_result")
|
this.resultOptions = await getDictOptions("proposal_result")
|
||||||
this.determineTypeOptions = await getDictOptions("proposal_determine_type")
|
this.determineTypeOptions = await getDictOptions("proposal_determine_type")
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ layout("/layouts/platform.html"){
|
|||||||
<el-card shadow="never" style="margin-top: 10px">
|
<el-card shadow="never" style="margin-top: 10px">
|
||||||
<table-tool :app="this" label="提案信息">
|
<table-tool :app="this" label="提案信息">
|
||||||
<template #func>
|
<template #func>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
</table-tool>
|
</table-tool>
|
||||||
<el-table :data="tableData" :row-key="(row)=>{row.id}" :size="tableSize" @sort-change="pageOrder"
|
<el-table :data="tableData" :row-key="(row)=>{row.id}" :size="tableSize" @sort-change="pageOrder"
|
||||||
@@ -91,7 +90,9 @@ layout("/layouts/platform.html"){
|
|||||||
mixins: [initTableMixins],
|
mixins: [initTableMixins],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
showStateSearch: true,
|
||||||
resultOptions: [],
|
resultOptions: [],
|
||||||
|
determineTypeOptions: [],
|
||||||
typeOptions: [],
|
typeOptions: [],
|
||||||
meetingOptions: [],
|
meetingOptions: [],
|
||||||
stateOptions: [],
|
stateOptions: [],
|
||||||
@@ -106,6 +107,9 @@ layout("/layouts/platform.html"){
|
|||||||
stateCode: '',
|
stateCode: '',
|
||||||
meetingId: '',
|
meetingId: '',
|
||||||
delegationId: '',
|
delegationId: '',
|
||||||
|
unionId: '',
|
||||||
|
unitId: '',
|
||||||
|
undertakeId: '',
|
||||||
proposalResult: [],
|
proposalResult: [],
|
||||||
proposalTypes: [],
|
proposalTypes: [],
|
||||||
proposalDetermineTypes: []
|
proposalDetermineTypes: []
|
||||||
@@ -138,8 +142,10 @@ layout("/layouts/platform.html"){
|
|||||||
},
|
},
|
||||||
async meetingChange(val) {
|
async meetingChange(val) {
|
||||||
this.pageForm.delegationId = null
|
this.pageForm.delegationId = null
|
||||||
this.delegationOptions = await proposal.getDelegation(val)
|
this.pageForm.undertakeId = ''
|
||||||
this.undertakeOptions = await proposal.getUndertakeByMeeting(val)
|
this.delegationOptions = val ? await proposal.getDelegation(val) : []
|
||||||
|
this.undertakeOptions = val ? await proposal.getUndertakeByMeeting(val)
|
||||||
|
: await proposal.getAllProposalUndertake()
|
||||||
this.doSearch()
|
this.doSearch()
|
||||||
},
|
},
|
||||||
async delegationChange(val) {
|
async delegationChange(val) {
|
||||||
@@ -207,8 +213,9 @@ layout("/layouts/platform.html"){
|
|||||||
async created() {
|
async created() {
|
||||||
this.meetingOptions = await getAllJdh()
|
this.meetingOptions = await getAllJdh()
|
||||||
this.pageForm.meetingId = this.meetingOptions.length ? this.meetingOptions[0].id : ''
|
this.pageForm.meetingId = this.meetingOptions.length ? this.meetingOptions[0].id : ''
|
||||||
|
this.meetingOptions.unshift({id: '', jdhallname: '全部届次'})
|
||||||
|
|
||||||
this.stateOptions = await proposal.getOpenProposalState()
|
this.stateOptions = await proposal.getProposalState()
|
||||||
this.typeOptions = await proposal.getProposalType()
|
this.typeOptions = await proposal.getProposalType()
|
||||||
this.resultOptions = await getDictOptions("proposal_result")
|
this.resultOptions = await getDictOptions("proposal_result")
|
||||||
this.determineTypeOptions = await getDictOptions("proposal_determine_type")
|
this.determineTypeOptions = await getDictOptions("proposal_determine_type")
|
||||||
|
|||||||
@@ -121,7 +121,9 @@ layout("/layouts/platform.html"){
|
|||||||
mixins: [initTableMixins],
|
mixins: [initTableMixins],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
showStateSearch: true,
|
||||||
resultOptions: [],
|
resultOptions: [],
|
||||||
|
determineTypeOptions: [],
|
||||||
typeOptions: [],
|
typeOptions: [],
|
||||||
meetingOptions: [],
|
meetingOptions: [],
|
||||||
stateOptions: [],
|
stateOptions: [],
|
||||||
@@ -136,6 +138,9 @@ layout("/layouts/platform.html"){
|
|||||||
stateCode: '',
|
stateCode: '',
|
||||||
meetingId: '',
|
meetingId: '',
|
||||||
delegationId: '',
|
delegationId: '',
|
||||||
|
unionId: '',
|
||||||
|
unitId: '',
|
||||||
|
undertakeId: '',
|
||||||
proposalResult: [],
|
proposalResult: [],
|
||||||
proposalTypes: [],
|
proposalTypes: [],
|
||||||
proposalDetermineTypes: []
|
proposalDetermineTypes: []
|
||||||
@@ -161,6 +166,37 @@ layout("/layouts/platform.html"){
|
|||||||
{prop: 'feedbackCodeByUnderTake', label: '对承办单位办理态度评价'},
|
{prop: 'feedbackCodeByUnderTake', label: '对承办单位办理态度评价'},
|
||||||
{prop: 'feedbackResult', label: '对办理结果评价'},
|
{prop: 'feedbackResult', label: '对办理结果评价'},
|
||||||
],
|
],
|
||||||
|
exportColumns: [
|
||||||
|
{prop: 'proposalCode', label: '提案编号'},
|
||||||
|
{prop: 'username', label: '提案人'},
|
||||||
|
{prop: 'loginname', label: '提案人工号'},
|
||||||
|
{prop: 'seconderNames', label: '附议人'},
|
||||||
|
{prop: 'creatorUnitName', label: '所属单位'},
|
||||||
|
{prop: 'proposalName', label: '提案标题'},
|
||||||
|
{prop: 'brief', label: '案由'},
|
||||||
|
{prop: 'measures', label: '建议措施'},
|
||||||
|
{prop: 'createTime', label: '提案时间'},
|
||||||
|
{prop: 'meetingName', label: '届次'},
|
||||||
|
{prop: 'delegationName', label: '代表团'},
|
||||||
|
{prop: 'typeName', label: '提案类型'},
|
||||||
|
{prop: 'mannerName', label: '提案方式'},
|
||||||
|
{prop: 'resultName', label: '立案结果'},
|
||||||
|
{prop: 'stateName', label: '办理进度'},
|
||||||
|
{prop: 'pruMaster', label: '主办单位'},
|
||||||
|
{prop: 'pruSlave', label: '协办单位'},
|
||||||
|
{prop: 'replyStatus', label: '答复状态'},
|
||||||
|
{prop: 'replyTime', label: '答复时间'},
|
||||||
|
{prop: 'replyContent', label: '答复内容'},
|
||||||
|
{prop: 'handleOpinion', label: '处理意见'},
|
||||||
|
{prop: 'implementState', label: '落实情况'},
|
||||||
|
{prop: 'leaderCheckTime', label: '分管领导审批时间'},
|
||||||
|
{prop: 'leaderCheckOpinion', label: '分管领导审批意见'},
|
||||||
|
{prop: 'feedbackCodeByUnderTake', label: '对承办单位办理态度评价'},
|
||||||
|
{prop: 'feedbackResult', label: '对办理结果评价'},
|
||||||
|
{prop: 'feedbackOpinion', label: '反馈意见'},
|
||||||
|
{prop: 'feedbackTime', label: '反馈时间'},
|
||||||
|
{prop: 'auditRecords', label: '审核记录及时间'},
|
||||||
|
],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
@@ -169,8 +205,102 @@ layout("/layouts/platform.html"){
|
|||||||
'proposal-table': httpVueLoader('/components/proposal/ProposalTable.vue'),
|
'proposal-table': httpVueLoader('/components/proposal/ProposalTable.vue'),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getOptionLabel(options, value, valueKey, labelKey) {
|
||||||
|
const option = options.find(item => item[valueKey] === value)
|
||||||
|
return option ? option[labelKey] : value
|
||||||
|
},
|
||||||
|
getExportCondition() {
|
||||||
|
const conditions = []
|
||||||
|
const {meetingId, stateCode, proposalTypes, proposalResult, proposalDetermineTypes,
|
||||||
|
delegationId, unionId, unitId, undertakeId, searchKeyword, searchKeyword2} = this.pageForm
|
||||||
|
|
||||||
|
if (meetingId) {
|
||||||
|
conditions.push('届次:' + this.getOptionLabel(this.meetingOptions, meetingId, 'id', 'jdhallname'))
|
||||||
|
}
|
||||||
|
if (stateCode) {
|
||||||
|
conditions.push('提案状态:' + this.getOptionLabel(this.stateOptions, stateCode, 'stateCode', 'stateName'))
|
||||||
|
}
|
||||||
|
if (proposalTypes.length) {
|
||||||
|
conditions.push('提案类型:' + proposalTypes.map(value =>
|
||||||
|
this.getOptionLabel(this.typeOptions, value, 'id', 'typeName')).join('、'))
|
||||||
|
}
|
||||||
|
if (proposalResult.length) {
|
||||||
|
conditions.push('立案结果:' + proposalResult.map(value =>
|
||||||
|
this.getOptionLabel(this.resultOptions, value, 'code', 'name')).join('、'))
|
||||||
|
}
|
||||||
|
if (proposalResult.includes('determine') && proposalDetermineTypes.length) {
|
||||||
|
conditions.push('是否重点:' + proposalDetermineTypes.map(value =>
|
||||||
|
this.getOptionLabel(this.determineTypeOptions, value, 'code', 'name')).join('、'))
|
||||||
|
}
|
||||||
|
if (delegationId) {
|
||||||
|
conditions.push('代表团:' + this.getOptionLabel(this.delegationOptions, delegationId, 'id', 'dbtname'))
|
||||||
|
}
|
||||||
|
if (unionId) {
|
||||||
|
conditions.push('所属工会:' + this.getOptionLabel(this.unionOptions, unionId, 'id', 'unionname'))
|
||||||
|
}
|
||||||
|
if (unitId) {
|
||||||
|
conditions.push('所属单位:' + this.getOptionLabel(this.unitOptions, unitId, 'id', 'name'))
|
||||||
|
}
|
||||||
|
if (undertakeId) {
|
||||||
|
conditions.push('承办单位:' + this.getOptionLabel(this.undertakeOptions, undertakeId, 'id', 'unitName'))
|
||||||
|
}
|
||||||
|
if (searchKeyword) {
|
||||||
|
conditions.push((this.pageForm.searchName === 'proposalCode' ? '提案编号:' : '提案名称:') + searchKeyword)
|
||||||
|
}
|
||||||
|
if (searchKeyword2) {
|
||||||
|
conditions.push('提案人:' + searchKeyword2)
|
||||||
|
}
|
||||||
|
return conditions.length ? conditions.join(';') : '无'
|
||||||
|
},
|
||||||
|
getExportFileCondition() {
|
||||||
|
const conditions = []
|
||||||
|
const {meetingId, stateCode, proposalTypes, proposalResult, undertakeId,
|
||||||
|
searchKeyword, searchKeyword2} = this.pageForm
|
||||||
|
if (meetingId) {
|
||||||
|
conditions.push(this.getOptionLabel(this.meetingOptions, meetingId, 'id', 'jdhallname'))
|
||||||
|
}
|
||||||
|
if (stateCode) {
|
||||||
|
conditions.push(this.getOptionLabel(this.stateOptions, stateCode, 'stateCode', 'stateName'))
|
||||||
|
}
|
||||||
|
if (proposalTypes.length) {
|
||||||
|
conditions.push(proposalTypes.map(value =>
|
||||||
|
this.getOptionLabel(this.typeOptions, value, 'id', 'typeName')).join('、'))
|
||||||
|
}
|
||||||
|
if (proposalResult.length) {
|
||||||
|
conditions.push(proposalResult.map(value =>
|
||||||
|
this.getOptionLabel(this.resultOptions, value, 'code', 'name')).join('、'))
|
||||||
|
}
|
||||||
|
if (undertakeId) {
|
||||||
|
conditions.push(this.getOptionLabel(this.undertakeOptions, undertakeId, 'id', 'unitName'))
|
||||||
|
}
|
||||||
|
if (searchKeyword) {
|
||||||
|
conditions.push(searchKeyword)
|
||||||
|
}
|
||||||
|
if (searchKeyword2) {
|
||||||
|
conditions.push(searchKeyword2)
|
||||||
|
}
|
||||||
|
return conditions.join('_')
|
||||||
|
},
|
||||||
exportByCnd() {
|
exportByCnd() {
|
||||||
window.open(loc() + '/exportByCnd?cnd=' + JSON.stringify(this.pageForm) + '&tableColumns=' + JSON.stringify(this.tableColumns))
|
const exportCondition = this.getExportCondition()
|
||||||
|
const totalCount = this.pageForm.totalCount || 0
|
||||||
|
this.$confirm('将导出当前筛选条件下的全部 ' + totalCount + ' 条提案,不受当前分页影响。查询条件:' + exportCondition,
|
||||||
|
'导出确认', {
|
||||||
|
confirmButtonText: '确认导出',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
const exportForm = clone(this.pageForm)
|
||||||
|
exportForm.exportCondition = exportCondition
|
||||||
|
exportForm.exportFileCondition = this.getExportFileCondition()
|
||||||
|
const form = $('<form method="post" target="_blank"></form>')
|
||||||
|
form.attr('action', loc() + '/exportByCnd')
|
||||||
|
form.append($('<input type="hidden" name="cnd">').val(JSON.stringify(exportForm)))
|
||||||
|
form.append($('<input type="hidden" name="tableColumns">').val(JSON.stringify(this.exportColumns)))
|
||||||
|
$('body').append(form)
|
||||||
|
form.submit()
|
||||||
|
form.remove()
|
||||||
|
}).catch(() => {})
|
||||||
},
|
},
|
||||||
oneProposalExport(id) {
|
oneProposalExport(id) {
|
||||||
window.location.href = "/platform/proposal/statistics/summary/oneProposalExport?proposalId=" + id
|
window.location.href = "/platform/proposal/statistics/summary/oneProposalExport?proposalId=" + id
|
||||||
@@ -247,7 +377,7 @@ layout("/layouts/platform.html"){
|
|||||||
this.meetingOptions = await getAllJdh()
|
this.meetingOptions = await getAllJdh()
|
||||||
this.pageForm.meetingId = this.meetingOptions.length ? this.meetingOptions[0].id : ''
|
this.pageForm.meetingId = this.meetingOptions.length ? this.meetingOptions[0].id : ''
|
||||||
|
|
||||||
this.stateOptions = await proposal.getOpenProposalState()
|
this.stateOptions = await proposal.getProposalState()
|
||||||
this.typeOptions = await proposal.getProposalType()
|
this.typeOptions = await proposal.getProposalType()
|
||||||
this.resultOptions = await getDictOptions("proposal_result")
|
this.resultOptions = await getDictOptions("proposal_result")
|
||||||
this.determineTypeOptions = await getDictOptions("proposal_determine_type")
|
this.determineTypeOptions = await getDictOptions("proposal_determine_type")
|
||||||
|
|||||||
@@ -93,7 +93,9 @@ layout("/layouts/platform.html"){
|
|||||||
mixins: [initTableMixins],
|
mixins: [initTableMixins],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
showStateSearch: true,
|
||||||
resultOptions: [],
|
resultOptions: [],
|
||||||
|
determineTypeOptions: [],
|
||||||
typeOptions: [],
|
typeOptions: [],
|
||||||
meetingOptions: [],
|
meetingOptions: [],
|
||||||
stateOptions: [],
|
stateOptions: [],
|
||||||
@@ -110,6 +112,7 @@ layout("/layouts/platform.html"){
|
|||||||
stateCode: '',
|
stateCode: '',
|
||||||
meetingId: '',
|
meetingId: '',
|
||||||
delegationId: '',
|
delegationId: '',
|
||||||
|
undertakeId: '',
|
||||||
proposalResult: [],
|
proposalResult: [],
|
||||||
proposalTypes: [],
|
proposalTypes: [],
|
||||||
proposalDetermineTypes: []
|
proposalDetermineTypes: []
|
||||||
@@ -138,36 +141,39 @@ layout("/layouts/platform.html"){
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
exportAllProposal() {
|
exportAllProposal() {
|
||||||
const proposalTypes = JSON.stringify(this.pageForm.proposalTypes)
|
const {exportCondition, exportFileCondition} = proposal.buildExportCondition(this)
|
||||||
const proposalResult = JSON.stringify(this.pageForm.proposalResult)
|
this.$confirm('将按当前筛选条件导出全部 ' + (this.pageForm.totalCount || 0)
|
||||||
const searchName2 = this.pageForm.searchName2
|
+ ' 件提案,不受当前分页影响。查询条件:' + exportCondition, '导出确认', {
|
||||||
const searchKeyword2 = this.pageForm.searchKeyword2
|
confirmButtonText: '确认导出',
|
||||||
const stateCode = this.pageForm.stateCode
|
cancelButtonText: '取消',
|
||||||
const searchKeyword = this.pageForm.searchKeyword
|
type: 'warning'
|
||||||
const searchName = this.pageForm.searchName
|
}).then(() => {
|
||||||
const delegationId = this.pageForm.delegationId
|
const exportForm = $('<form method="post" target="_blank"></form>')
|
||||||
const unionId = this.pageForm.unionId
|
exportForm.attr('action', loc() + '/exportAllProposal')
|
||||||
const unitId = this.pageForm.unitId
|
const params = Object.assign({}, this.pageForm, {
|
||||||
const meetingId = this.pageForm.meetingId
|
proposalTypes: JSON.stringify(this.pageForm.proposalTypes),
|
||||||
window.location.href = loc() + "/exportAllProposal?proposalTypes=" + proposalTypes +
|
proposalResult: JSON.stringify(this.pageForm.proposalResult),
|
||||||
"&proposalResult=" + proposalResult +
|
exportFileCondition
|
||||||
"&searchName2=" + searchName2 +
|
})
|
||||||
"&searchKeyword2=" + searchKeyword2 +
|
Object.keys(params).forEach(key => {
|
||||||
"&stateCode=" + stateCode +
|
if (!Array.isArray(params[key])) {
|
||||||
"&searchKeyword=" + searchKeyword +
|
exportForm.append($('<input type="hidden">').attr('name', key).val(params[key] || ''))
|
||||||
"&searchName=" + searchName +
|
}
|
||||||
"&delegationId=" + delegationId +
|
})
|
||||||
"&unionId=" + unionId +
|
$('body').append(exportForm)
|
||||||
"&unitId=" + unitId +
|
exportForm.submit()
|
||||||
"&meetingId=" + meetingId
|
exportForm.remove()
|
||||||
|
}).catch(() => {})
|
||||||
},
|
},
|
||||||
oneProposalExport(id) {
|
oneProposalExport(id) {
|
||||||
window.location.href = "/platform/proposal/statistics/summary/oneProposalExport?proposalId=" + id
|
window.location.href = "/platform/proposal/statistics/summary/oneProposalExport?proposalId=" + id
|
||||||
},
|
},
|
||||||
async meetingChange(val) {
|
async meetingChange(val) {
|
||||||
this.pageForm.delegationId = null
|
this.pageForm.delegationId = null
|
||||||
this.delegationOptions = await getDelegation(val)
|
this.pageForm.undertakeId = ''
|
||||||
this.undertakeOptions = await proposal.getUndertakeByMeeting(val)
|
this.delegationOptions = val ? await proposal.getDelegation(val) : []
|
||||||
|
this.undertakeOptions = val ? await proposal.getUndertakeByMeeting(val)
|
||||||
|
: await proposal.getAllProposalUndertake()
|
||||||
this.doSearch()
|
this.doSearch()
|
||||||
},
|
},
|
||||||
async delegationChange(val) {
|
async delegationChange(val) {
|
||||||
@@ -235,13 +241,14 @@ layout("/layouts/platform.html"){
|
|||||||
async created() {
|
async created() {
|
||||||
this.meetingOptions = await getAllJdh()
|
this.meetingOptions = await getAllJdh()
|
||||||
this.pageForm.meetingId = this.meetingOptions.length ? this.meetingOptions[0].id : ''
|
this.pageForm.meetingId = this.meetingOptions.length ? this.meetingOptions[0].id : ''
|
||||||
|
this.meetingOptions.unshift({id: '', jdhallname: '全部届次'})
|
||||||
|
|
||||||
this.stateOptions = await getOpenProposalState()
|
this.stateOptions = await proposal.getProposalState()
|
||||||
this.typeOptions = await getProposalType()
|
this.typeOptions = await getProposalType()
|
||||||
this.resultOptions = await getDictOptions("proposal_result")
|
this.resultOptions = await getDictOptions("proposal_result")
|
||||||
this.determineTypeOptions = await getDictOptions("proposal_determine_type")
|
this.determineTypeOptions = await getDictOptions("proposal_determine_type")
|
||||||
|
|
||||||
this.delegationOptions = await getDelegation(this.pageForm.meetingId)
|
this.delegationOptions = await proposal.getDelegation(this.pageForm.meetingId)
|
||||||
this.undertakeOptions = await proposal.getUndertakeByMeeting(this.pageForm.meetingId)
|
this.undertakeOptions = await proposal.getUndertakeByMeeting(this.pageForm.meetingId)
|
||||||
this.unionOptions = await getUnions(null)
|
this.unionOptions = await getUnions(null)
|
||||||
this.unitOptions = await getUnits(null)
|
this.unitOptions = await getUnits(null)
|
||||||
|
|||||||
@@ -146,8 +146,10 @@
|
|||||||
<el-row class="query-row" type="flex">
|
<el-row class="query-row" type="flex">
|
||||||
<el-col class="query-row-title">承办单位:</el-col>
|
<el-col class="query-row-title">承办单位:</el-col>
|
||||||
<el-col class="query-row-content">
|
<el-col class="query-row-content">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="8">
|
||||||
<el-select @change="pageData()" clearable filterable
|
<el-select @change="pageData()" clearable filterable
|
||||||
placeholder="请选择承办单位" v-model="pageForm.undertakeId">
|
placeholder="请选择承办单位" style="width: 350px" v-model="pageForm.undertakeId">
|
||||||
<el-option
|
<el-option
|
||||||
:label="item.unitName"
|
:label="item.unitName"
|
||||||
:value="item.id"
|
:value="item.id"
|
||||||
@@ -155,6 +157,17 @@
|
|||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="8" v-if="$data.showStateSearch">
|
||||||
|
<span>提案状态:</span>
|
||||||
|
<el-select @change="doSearch" clearable filterable placeholder="请选择提案状态"
|
||||||
|
style="width: 350px" v-model="pageForm.stateCode">
|
||||||
|
<el-option :key="item.stateCode" :label="item.stateName" :value="item.stateCode"
|
||||||
|
v-for="item in stateOptions">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
</el-card>
|
</el-card>
|
||||||
@@ -190,6 +190,17 @@ layout("/layouts/platform.html"){
|
|||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-row align="middle" class="query-row" type="flex">
|
||||||
|
<el-col class="query-row-title">提案状态:</el-col>
|
||||||
|
<el-col class="query-row-content">
|
||||||
|
<el-select @change="doSearch" clearable filterable placeholder="请选择提案状态"
|
||||||
|
style="width: 350px" v-model="pageForm.stateCode">
|
||||||
|
<el-option :key="item.stateCode" :label="item.stateName" :value="item.stateCode"
|
||||||
|
v-for="item in stateOptions">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
<!-- <el-col :span="8">-->
|
<!-- <el-col :span="8">-->
|
||||||
<!-- <span>所属工会:</span>-->
|
<!-- <span>所属工会:</span>-->
|
||||||
<!-- <el-select @change="unionChange" clearable filterable-->
|
<!-- <el-select @change="unionChange" clearable filterable-->
|
||||||
@@ -433,7 +444,7 @@ layout("/layouts/platform.html"){
|
|||||||
this.meetingOptions = await getAllJdh()
|
this.meetingOptions = await getAllJdh()
|
||||||
// this.pageForm.meetingId = this.meetingOptions.length ? this.meetingOptions[0].id : ''
|
// this.pageForm.meetingId = this.meetingOptions.length ? this.meetingOptions[0].id : ''
|
||||||
|
|
||||||
this.stateOptions = await proposal.getOpenProposalState()
|
this.stateOptions = await proposal.getProposalState()
|
||||||
this.typeOptions = await proposal.getProposalType()
|
this.typeOptions = await proposal.getProposalType()
|
||||||
this.resultOptions = await getDictOptions("proposal_result")
|
this.resultOptions = await getDictOptions("proposal_result")
|
||||||
|
|
||||||
|
|||||||
@@ -306,6 +306,22 @@ layout("/layouts/platform.html"){
|
|||||||
<el-table-column align="center" header-align="center" label="单位名称"
|
<el-table-column align="center" header-align="center" label="单位名称"
|
||||||
prop="name">
|
prop="name">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column align="center" header-align="center" label="单位管理员"
|
||||||
|
prop="thirdmanagernames" show-overflow-tooltip
|
||||||
|
v-if="isSpecialUnion">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{scope.row.thirdmanagernames || '未设置'}}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" header-align="center" label="操作"
|
||||||
|
width="250" v-if="isSpecialUnion">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-button @click="openThirdManager(scope.row, false)" size="mini">编辑</el-button>
|
||||||
|
<el-button @click="openThirdManager(scope.row, true)" size="mini" type="primary">
|
||||||
|
设置单位管理员
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
@@ -433,6 +449,26 @@ layout("/layouts/platform.html"){
|
|||||||
</span>
|
</span>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog :title="thirdManagerQuick ? '设置单位管理员' : '编辑成员单位'"
|
||||||
|
:visible.sync="thirdManagerDialogVisible" width="55%">
|
||||||
|
<el-form label-width="100px">
|
||||||
|
<el-form-item label="成员单位">
|
||||||
|
<el-input :value="thirdManagerUnit.name" disabled></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="单位管理员">
|
||||||
|
<el-select filterable multiple placeholder="请选择单位管理员" style="width:100%"
|
||||||
|
v-model="thirdManagerUserIds">
|
||||||
|
<el-option :key="item.id" :label="item.name" :value="item.id"
|
||||||
|
v-for="item in thirdManagerUsers"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="thirdManagerDialogVisible=false">取 消</el-button>
|
||||||
|
<el-button @click="doSetThirdManager" type="primary">确 定</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
<el-dialog
|
<el-dialog
|
||||||
title="设置管理员"
|
title="设置管理员"
|
||||||
:visible.sync="fzrDialogVisible" width="55%">
|
:visible.sync="fzrDialogVisible" width="55%">
|
||||||
@@ -630,6 +666,11 @@ layout("/layouts/platform.html"){
|
|||||||
fzrValue: [],
|
fzrValue: [],
|
||||||
data: [],
|
data: [],
|
||||||
zcdwTableData: [],
|
zcdwTableData: [],
|
||||||
|
thirdManagerDialogVisible: false,
|
||||||
|
thirdManagerQuick: false,
|
||||||
|
thirdManagerUnit: {},
|
||||||
|
thirdManagerUsers: [],
|
||||||
|
thirdManagerUserIds: [],
|
||||||
lxrTableData: [],
|
lxrTableData: [],
|
||||||
defaultProps: {
|
defaultProps: {
|
||||||
children: 'childrens',
|
children: 'childrens',
|
||||||
@@ -762,7 +803,42 @@ layout("/layouts/platform.html"){
|
|||||||
return val
|
return val
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
isSpecialUnion() {
|
||||||
|
return this.sysadmin && this.node && this.node.data
|
||||||
|
&& String(this.node.data.unioncode) === '28'
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
async openThirdManager(row, quick) {
|
||||||
|
const resp = await $.post(loc() + '/findThirdUnitManagerUsers', {
|
||||||
|
unionId: this.node.data.id,
|
||||||
|
unitId: row.id
|
||||||
|
})
|
||||||
|
if (resp.code === 0) {
|
||||||
|
this.thirdManagerQuick = quick
|
||||||
|
this.thirdManagerUnit = row
|
||||||
|
this.thirdManagerUsers = resp.data.allusers
|
||||||
|
this.thirdManagerUserIds = resp.data.selecteduserids
|
||||||
|
this.thirdManagerDialogVisible = true
|
||||||
|
} else {
|
||||||
|
this.$notify.warning(resp.msg)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async doSetThirdManager() {
|
||||||
|
const resp = await $.post(loc() + '/doSetThirdUnitManagerUsers', {
|
||||||
|
unionId: this.node.data.id,
|
||||||
|
unitId: this.thirdManagerUnit.id,
|
||||||
|
userIds: JSON.stringify(this.thirdManagerUserIds)
|
||||||
|
})
|
||||||
|
if (resp.code === 0) {
|
||||||
|
this.thirdManagerDialogVisible = false
|
||||||
|
this.$notify.success(resp.msg)
|
||||||
|
this.getZcdwTabData()
|
||||||
|
} else {
|
||||||
|
this.$notify.warning(resp.msg)
|
||||||
|
}
|
||||||
|
},
|
||||||
doExport() {
|
doExport() {
|
||||||
window.location.href = loc() + "/doExport"
|
window.location.href = loc() + "/doExport"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,162 +0,0 @@
|
|||||||
nutz.application.name=UNION_NJUST
|
|
||||||
server.port=8080
|
|
||||||
server.host=0.0.0.0
|
|
||||||
jetty.contextPath=/
|
|
||||||
jetty.threadpool.idleTimeout=60000
|
|
||||||
jetty.threadpool.minThreads=10
|
|
||||||
jetty.threadpool.maxThreads=500
|
|
||||||
jetty.page.403=/error/403.html
|
|
||||||
jetty.page.404=/error/404.html
|
|
||||||
jetty.page.500=/error/500.html
|
|
||||||
#结合ftp使用,或用nginx代理ftp路径
|
|
||||||
jetty.staticPath=D://files
|
|
||||||
#开发模式静态资源
|
|
||||||
jetty.staticPathLocal=D:/project/UNION_NJUST/src/main/resources/static
|
|
||||||
nutz.mvc.ignore=^(.+[.])(jsp|png|gif|jpg|js|css|jspx|jpeg|html|mp3|mp4|ico|svg)$
|
|
||||||
nutz.mvc.exclusions=/favicon/*,/assets/*,/druid/*,/upload/*
|
|
||||||
ftp.enabled=true
|
|
||||||
ftp.host=192.10.88.114
|
|
||||||
ftp.port=21
|
|
||||||
ftp.username=ftp_user
|
|
||||||
ftp.password=NJUST_DD3s@#2025
|
|
||||||
ftp.timeout=100
|
|
||||||
redis.host=127.0.0.1
|
|
||||||
redis.port=6379
|
|
||||||
redis.timeout=2000
|
|
||||||
redis.max_redir=10
|
|
||||||
redis.database=0
|
|
||||||
redis.maxTotal=150
|
|
||||||
redis.pool.maxTotal=150
|
|
||||||
redis.pool.maxIdle=50
|
|
||||||
redis.pool.minIdle=10
|
|
||||||
#redis.password=zxy123
|
|
||||||
#redis集群模式设置
|
|
||||||
#redis.mode=cluster
|
|
||||||
redis.mode=normal
|
|
||||||
#redis.nodes=192.168.6.31:6377,192.168.6.31:6378,192.168.6.28:6377,192.168.6.28:6378,192.168.6.34:6377,192.168.6.34:6378
|
|
||||||
jdbc.url=jdbc:mysql://127.0.0.1:3306/UNION_NJUST?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
|
||||||
jdbc.username=root
|
|
||||||
jdbc.password=NJUST_DD3s@#2025
|
|
||||||
jdbc.validationQuery=select 1
|
|
||||||
jdbc.maxActive=500
|
|
||||||
jdbc.testWhileIdle=true
|
|
||||||
jdbc.connectionProperties=druid.stat.slowSqlMillis=2000
|
|
||||||
jdbc.defaultAutoCommit=true
|
|
||||||
xsssql.ignore.urls=/platform/common/user/userPageData,/platform/cms/content/article/addDo,/platform/sys/app/conf/addDo,/platform/sys/app/conf/editDo,/platform/sys/task/cronExp,/platform/sys/task/editDo,/platform/sys/task/addDo
|
|
||||||
#环境 dev/prod
|
|
||||||
v.environment=prod
|
|
||||||
v.loginUrl=/sso/login
|
|
||||||
v.loginUrlMobile=/mobile/cas/login
|
|
||||||
#shiro.ini.path=shiro.ini
|
|
||||||
shiro.objects=platformAuthc,AuthenticationFilter,Cas20ProxyReceivingTicketValidationFilter,platformRealm,authenticationStrategy,weChatFilter
|
|
||||||
#end
|
|
||||||
shiro.ini.urls:
|
|
||||||
/sso/**=Cas20ProxyReceivingTicketValidationFilter
|
|
||||||
/mobile/cas/login=AuthenticationFilter
|
|
||||||
/platform/doLogin=anon
|
|
||||||
/mobile/login=anon
|
|
||||||
/platform/jsz/login=anon
|
|
||||||
/assets/**=anon
|
|
||||||
/**=anon
|
|
||||||
/signature/**=anon
|
|
||||||
/platform/**=AuthenticationFilter
|
|
||||||
#end
|
|
||||||
#设置session会话超时时间(单位:毫秒)
|
|
||||||
shiro.session.manager.globalSessionTimeout=2000000000
|
|
||||||
#设置redis缓存时间(单位:秒)与上面的毫秒数保持一致
|
|
||||||
shiro.session.cache.redis.ttl=2000000
|
|
||||||
#缓存名和 RedisConstant.PLATFORM_REDIS_PREFIX 常量保持一致
|
|
||||||
shiro.session.dao.activeSessionsCacheName=budwk5mini:shiro:activeSessionCache
|
|
||||||
#使用redis二级缓存
|
|
||||||
shiro.session.cache.type=lcache
|
|
||||||
shiro.session.enable=true
|
|
||||||
shiro.url.login=/platform
|
|
||||||
shiro.url.logout_redirect=/platform
|
|
||||||
shiro.url.unauth=/platform
|
|
||||||
#开发时设置本地路径,便于调试
|
|
||||||
beetl.RESOURCE.rootLocal=D:/project/UNION_NJUST/src/main/resources/views/
|
|
||||||
beetl.RESOURCE.root=views/
|
|
||||||
beetl.DELIMITER_STATEMENT_START=<!--#
|
|
||||||
beetl.DELIMITER_STATEMENT_END=#-->
|
|
||||||
beetl.FT.escape=io.v.nutz.web.commons.ext.beetl.HtmlEscapeFormat
|
|
||||||
#用法: ${"wizzer",escape}
|
|
||||||
beetl.FT.filesize=io.v.nutz.web.commons.ext.beetl.FileSizeFormat
|
|
||||||
#用法: ${10241024,filesize}
|
|
||||||
beetl.FT.html2txt=io.v.nutz.web.commons.ext.beetl.Html2TxtFormat
|
|
||||||
#用法: ${"",html2txt="100"} 截取100字符
|
|
||||||
beetl.FT.strlen=io.v.nutz.web.commons.ext.beetl.StrlenFormat
|
|
||||||
#用法: ${"",strlen="100"} 截取100字符
|
|
||||||
#获取系统参数
|
|
||||||
beetl.FN.getSysConfig=io.v.nutz.web.commons.ext.beetl.GetSysConfig
|
|
||||||
#==============================================================
|
|
||||||
#Configure Main Scheduler Properties
|
|
||||||
#==============================================================
|
|
||||||
#quartz延迟启动秒数
|
|
||||||
quartz.startupDelay=10
|
|
||||||
quartz.scheduler.instanceName=defaultScheduler
|
|
||||||
quartz.scheduler.instanceId=AUTO
|
|
||||||
#==============================================================
|
|
||||||
#Configure JobStore isClustered=启用集群模式
|
|
||||||
#==============================================================
|
|
||||||
quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
|
|
||||||
quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
|
|
||||||
#quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
|
|
||||||
#quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
|
|
||||||
#Other delegates can see: http://www.quartz-scheduler.org/documentation/quartz-2.x/tutorials/tutorial-lesson-09.html
|
|
||||||
quartz.jobStore.dataSource=myDS
|
|
||||||
quartz.jobStore.tablePrefix=SYS_QRTZ_
|
|
||||||
quartz.jobStore.isClustered=true
|
|
||||||
quartz.jobStore.clusterCheckinInterval=20000
|
|
||||||
quartz.jobStore.maxMisfiresToHandleAtATime=120
|
|
||||||
quartz.jobStore.misfireThreshold=120000
|
|
||||||
quartz.jobStore.txIsolationLevelSerializable=false
|
|
||||||
#==============================================================
|
|
||||||
#Configure ThreadPool
|
|
||||||
#==============================================================
|
|
||||||
quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
|
|
||||||
quartz.threadPool.threadCount=2
|
|
||||||
quartz.threadPool.threadPriority=5
|
|
||||||
quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true
|
|
||||||
#==============================================================
|
|
||||||
#Skip Check Update
|
|
||||||
#update:true
|
|
||||||
#not update:false
|
|
||||||
#==============================================================
|
|
||||||
quartz.scheduler.skipUpdateCheck=true
|
|
||||||
#============================================================================
|
|
||||||
# Configure Plugins
|
|
||||||
#============================================================================
|
|
||||||
quartz.plugin.triggHistory.class=org.quartz.plugins.history.LoggingJobHistoryPlugin
|
|
||||||
quartz.plugin.shutdownhook.class=org.quartz.plugins.management.ShutdownHookPlugin
|
|
||||||
quartz.plugin.shutdownhook.cleanShutdown=true
|
|
||||||
#============================================================================
|
|
||||||
# NutDao dataSource
|
|
||||||
#============================================================================
|
|
||||||
quartz.dataSource.myDS.connectionProvider.class=io.v.nutz.task.conn.NutConnectionProvider
|
|
||||||
logback.exts.loglevel.cache.prefix=budwk5mini:logback:loglevel:
|
|
||||||
#动态修改日志等级
|
|
||||||
logback.exts.loglevel.enabled=true
|
|
||||||
#心跳间隔(单位:秒)
|
|
||||||
logback.exts.loglevel.heartbeat=15
|
|
||||||
#为应用管理提供支持,启用获取部署版本号,结合守护进程使用
|
|
||||||
# 详见 https://github.com/Wizzercn/PythonWk
|
|
||||||
logback.exts.deploy.enabled=false
|
|
||||||
#为应用管理提供支持,部署根路径
|
|
||||||
logback.exts.deploy.root=/data/budwk5mini
|
|
||||||
#应用管理通信接口签名,正式环境务必更改
|
|
||||||
deploy.appid=budwk5mini
|
|
||||||
deploy.appkey=wizzer
|
|
||||||
# 是否真的发送短信
|
|
||||||
sms.enabled=false
|
|
||||||
# 腾讯云短信配置
|
|
||||||
sms.tencent.secret-id=1
|
|
||||||
sms.tencent.secret-key=2
|
|
||||||
# 验证码模板ID
|
|
||||||
sms.tencent.tpl.code=1
|
|
||||||
# 短信通知模板ID
|
|
||||||
sms.tencent.tpl.msg=2
|
|
||||||
# 应用ID
|
|
||||||
sms.tencent.appid=1
|
|
||||||
# 短信签名
|
|
||||||
sms.tencent.sign=萌发开源
|
|
||||||
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
____ ___ ___ __ _______ __ __ _ _
|
|
||||||
| _ \ | \ \ / / | \ \ / / ____| | \/ (_) (_)
|
|
||||||
| |_) |_ _ __| |\ \ /\ / /| | _______\ \ / /| |__ | \ / |_ _ __ _
|
|
||||||
| _ <| | | |/ _` | \ \/ \/ / | |/ /______\ \/ / |___ \ | |\/| | | '_ \| |
|
|
||||||
| |_) | |_| | (_| | \ /\ / | < \ / ___) | | | | | | | | | |
|
|
||||||
|____/ \__,_|\__,_| \/ \/ |_|\_\ \/ |____/ |_| |_|_|_| |_|_|
|
|
||||||
|
|
||||||
:: Built with BudWk.com [wizzer@qq.com]
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
var chain={
|
|
||||||
"default" : {
|
|
||||||
"ps" : [
|
|
||||||
"io.v.nutz.web.commons.proc.LogTimeProcessor",
|
|
||||||
"io.v.nutz.web.commons.proc.GlobalsSettingProcessor",
|
|
||||||
"org.nutz.mvc.impl.processor.UpdateRequestAttributesProcessor",
|
|
||||||
"org.nutz.mvc.impl.processor.EncodingProcessor",
|
|
||||||
"org.nutz.mvc.impl.processor.ModuleProcessor",
|
|
||||||
"org.nutz.mvc.impl.processor.ActionFiltersProcessor",
|
|
||||||
"io.v.nutz.web.commons.proc.XssSqlFilterProcessor",
|
|
||||||
"io.v.nutz.web.commons.proc.NutShiroProcessor",
|
|
||||||
"org.nutz.mvc.impl.processor.AdaptorProcessor",
|
|
||||||
"org.nutz.mvc.impl.processor.MethodInvokeProcessor",
|
|
||||||
"org.nutz.mvc.impl.processor.ViewProcessor"
|
|
||||||
],
|
|
||||||
"error" : 'io.v.nutz.web.commons.proc.WkFailProcessor'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/* cms_menu_01 */
|
|
||||||
update sys_menu set location=10 where path='0001'
|
|
||||||
/* cms_menu_02 */
|
|
||||||
update sys_menu set location=8 where path='0002'
|
|
||||||
/* cms_menu_03 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('02e86a61e99746bea34236ea73dd52a5','','0003','CMS','CMS','menu','','','ti-world','1','0','cms',NULL,'9','1','1a19ef09b12344b4a797d6e6dfe7fb29','1468895671','0')
|
|
||||||
/* cms_menu_04 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('077cb6be4c7c41cc8955ee045a4f0286','68cdbf694f71445c8587a20234d6fe31','0003000300020001','添加链接','Add','data','','','','0','0','cms.link.link.add',NULL,'47','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468897043','0')
|
|
||||||
/* cms_menu_05 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('17500ef3a9e44b4fabb240162a164fcb','6075fc0cf0ef441b9d93cc3cab3445bf','0003000200020003','删除文章','Delete','data','','','','0','0','cms.content.article.delete',NULL,'40','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896170','0')
|
|
||||||
/* cms_menu_06 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('31ed2243077c44448cce26abfd5ae574','9822bafbe3454dfd8e8b974ebc304d03','0003000300010002','修改分类','Edit','data','','','','0','0','cms.link.class.edit',NULL,'44','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896957','0')
|
|
||||||
/* cms_menu_07 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('33aed9298643424783116e0cf0f7fcbe','6075fc0cf0ef441b9d93cc3cab3445bf','0003000200020001','添加文章','Add','data','','','','0','0','cms.content.article.add',NULL,'38','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896151','0')
|
|
||||||
/* cms_menu_08 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('36e0faf5062b4f6b95d4167cbb1f8fea','68cdbf694f71445c8587a20234d6fe31','0003000300020002','修改链接','Edit','data','','','','0','0','cms.link.link.edit',NULL,'48','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468897051','0')
|
|
||||||
/* cms_menu_09 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('3c24111091ad4a70ad2d9cc361311d2f','68cdbf694f71445c8587a20234d6fe31','0003000300020003','删除链接','Delete','data','','','','0','0','cms.link.link.delete',NULL,'49','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468897060','0')
|
|
||||||
/* cms_menu_10 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('3f330d729ca34dc9825c46122be1bfae','02e86a61e99746bea34236ea73dd52a5','00030003','广告链接','AD','menu','','','ti-link','1','0','cms.link',NULL,'41','1','1a19ef09b12344b4a797d6e6dfe7fb29','1468896230','0')
|
|
||||||
/* cms_menu_11 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('4781372b00bb4d52b429b58e72b80c68','b2631bbdbf824cc4b74d819c87962c0d','0003000200010001','添加栏目','Add','data','','','','0','0','cms.content.channel.add',NULL,'33','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896049','0')
|
|
||||||
/* cms_menu_12 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('50ba60ee650e4c739e6abc3ab71e4960','b2631bbdbf824cc4b74d819c87962c0d','0003000200010004','栏目排序','Sort','data','','','','0','0','cms.content.channel.sort',NULL,'36','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896092','0')
|
|
||||||
/* cms_menu_13 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('6075fc0cf0ef441b9d93cc3cab3445bf','6b6de8c720c645a1808e1c3e9ccbfc90','000300020002','文章管理','Article','menu','/platform/cms/article','data-pjax','','1','0','cms.content.article',NULL,'37','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896141','0')
|
|
||||||
/* cms_menu_14 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('68cdbf694f71445c8587a20234d6fe31','3f330d729ca34dc9825c46122be1bfae','000300030002','链接管理','Link','menu','/platform/cms/link/link','data-pjax','','1','0','cms.link.link',NULL,'46','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468897031','0')
|
|
||||||
/* cms_menu_15 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('6b6de8c720c645a1808e1c3e9ccbfc90','02e86a61e99746bea34236ea73dd52a5','00030002','内容管理','Content','menu','','','ti-pencil-alt','1','0','cms.content',NULL,'31','1','1a19ef09b12344b4a797d6e6dfe7fb29','1468895990','0')
|
|
||||||
/* cms_menu_16 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('7125a72beee34b21ab3df9bf01b7bce6','9822bafbe3454dfd8e8b974ebc304d03','0003000300010003','删除分类','Delete','data','','','','0','0','cms.link.class.delete',NULL,'45','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896968','0')
|
|
||||||
/* cms_menu_17 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('73a29d3f99224426b5a87c92da122275','d1e991ad38a8424daf9f7eb000ee27f4','0003000100010001','保存配置','Save','data','','','','0','0','cms.site.settings.save',NULL,'30','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468895899','0')
|
|
||||||
/* cms_menu_18 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('7db6207d0dab4d6e95a7eee4f2efe875','9822bafbe3454dfd8e8b974ebc304d03','0003000300010001','添加分类','Add','data','','','','0','0','cms.link.class.add',NULL,'43','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896947','0')
|
|
||||||
/* cms_menu_19 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('9822bafbe3454dfd8e8b974ebc304d03','3f330d729ca34dc9825c46122be1bfae','000300030001','链接分类','Class','menu','/platform/cms/link/class','data-pjax','','1','0','cms.link.class',NULL,'42','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896932','0')
|
|
||||||
/* cms_menu_20 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('b2631bbdbf824cc4b74d819c87962c0d','6b6de8c720c645a1808e1c3e9ccbfc90','000300020001','栏目管理','Channel','menu','/platform/cms/channel','data-pjax','','1','0','cms.content.channel',NULL,'32','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896018','0')
|
|
||||||
/* cms_menu_21 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('d1e991ad38a8424daf9f7eb000ee27f4','d920314e925c451da6d881e7a29743b7','000300010001','网站配置','Settings','menu','/platform/cms/site','data-pjax','','1','0','cms.site.settings',NULL,'29','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468895881','0')
|
|
||||||
/* cms_menu_22 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('d920314e925c451da6d881e7a29743b7','02e86a61e99746bea34236ea73dd52a5','00030001','站点管理','Site','menu','','','ti-world','1','0','cms.site',NULL,'28','1','1a19ef09b12344b4a797d6e6dfe7fb29','1468895821','0')
|
|
||||||
/* cms_menu_23 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('e461c62a1d5441619cd35612f3b40691','b2631bbdbf824cc4b74d819c87962c0d','0003000200010002','修改栏目','Edit','data','','','','0','0','cms.content.channel.edit',NULL,'34','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896060','0')
|
|
||||||
/* cms_menu_24 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('ef9f436c61654ec09efbfa79a40061cf','6075fc0cf0ef441b9d93cc3cab3445bf','0003000200020002','修改文章','Edit','data','','','','0','0','cms.content.article.edit',NULL,'39','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896159','0')
|
|
||||||
/* cms_menu_25 */
|
|
||||||
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('f6fba69c3b704d79834b8bd2cc753729','b2631bbdbf824cc4b74d819c87962c0d','0003000200010003','删除栏目','Delete','data','','','','0','0','cms.content.channel.delete',NULL,'35','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896072','0')
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user