Compare commits

..

4 Commits

Author SHA1 Message Date
lSun 12520642e4 人员库-全员重置密码 2025-08-28 16:44:57 +08:00
lSun 9e91f12009 人员库功能变更 2025-07-04 10:34:13 +08:00
lSun f99c80395a 人员库功能变更 2025-07-03 14:48:50 +08:00
lSun 96538cb264 体验预约人员导入功能 2025-06-30 14:57:30 +08:00
45 changed files with 2129 additions and 6187 deletions

View File

@ -19,6 +19,7 @@ import com.bonus.boot.manager.manager.utils.GlobalConst;
import com.bonus.boot.manager.task.UnifyTask; import com.bonus.boot.manager.task.UnifyTask;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -86,24 +87,26 @@ public class PersonnelLibraryController {
UnifyTask unifyTask = new UnifyTask(); UnifyTask unifyTask = new UnifyTask();
if (cb != 3 && cb != 5){ if (cb != 3 && cb != 5){
String token = login(); String token = login();
String isActive = addUser(bean.getPersonName(), bean.getPhone(),token); if(token!=null && token.length()>0 ){
if(isActive.equals("1")){ String isActive = addUser(bean.getPersonName(), bean.getPhone(),token);
ks = 1; if(isActive.equals("1")){
ar.setFailMsg(GlobalConst.INIT_SUCCEED); ks = 1;
}else{ ar.setFailMsg(GlobalConst.INIT_SUCCEED);
for (int i = 0; i < 3; i++) { }else{
isActive = addUser(bean.getPersonName(), bean.getPhone(),token); for (int i = 0; i < 3; i++) {
if(isActive.equals("1")){ isActive = addUser(bean.getPersonName(), bean.getPhone(),token);
ks = 1; if(isActive.equals("1")){
ar.setFailMsg(GlobalConst.INIT_SUCCEED); ks = 1;
break; ar.setFailMsg(GlobalConst.INIT_SUCCEED);
break;
}
} }
} }
} //三次都未推送成功 修改推送状态
//三次都未推送成功 修改推送状态 if(ks!=1){
if(ks!=1){ userService.updateUnify(Long.valueOf(bean.getHospId()));
userService.updateUnify(Long.valueOf(bean.getHospId())); ar.setFailMsg(GlobalConst.INIT_SUCCEED);
ar.setFailMsg(GlobalConst.INIT_SUCCEED); }
} }
}else { }else {
ar.setFailMsg(GlobalConst.DATA_FAIL); ar.setFailMsg(GlobalConst.DATA_FAIL);
@ -214,7 +217,7 @@ public class PersonnelLibraryController {
@LogAnnotation @LogAnnotation
@PostMapping("resetPassword") @PostMapping("resetPassword")
@ApiOperation(value = "体检人员库-删除") @ApiOperation(value = "体检人员库-重置密码")
public AjaxRes resetPassword(PersonnelLibraryBean bean) { public AjaxRes resetPassword(PersonnelLibraryBean bean) {
AjaxRes ar = new AjaxRes(); AjaxRes ar = new AjaxRes();
int result = service.resetPassword(bean); int result = service.resetPassword(bean);
@ -267,7 +270,10 @@ public class PersonnelLibraryController {
JSONObject object = JSON.parseObject(params); JSONObject object = JSON.parseObject(params);
String result = HttpClientUtils.doHttpPost(AddressConfiguration.UNIFICATION_URL + "/ynuw/sys/api/putUser", object, token); String result = HttpClientUtils.doHttpPost(AddressConfiguration.UNIFICATION_URL + "/ynuw/sys/api/putUser", object, token);
JSONObject jsonObject = JSONObject.parseObject(result); JSONObject jsonObject = JSONObject.parseObject(result);
String code = jsonObject.getString("code"); String code = "00";
if(jsonObject != null && jsonObject.containsKey("code")){
code = jsonObject.getString("code");
}
System.err.println("新增code="+code); System.err.println("新增code="+code);
if("200".equals(code)){ if("200".equals(code)){
JSONArray data = jsonObject.getJSONArray("data"); JSONArray data = jsonObject.getJSONArray("data");
@ -315,4 +321,19 @@ public class PersonnelLibraryController {
return isActive; return isActive;
} }
@LogAnnotation
@PostMapping("resetPasswordAll")
@ApiOperation(value = "体检人员库-重置密码-全员")
@PreAuthorize("hasAuthority('sys:reset:all')")
public AjaxRes resetPasswordAll(PersonnelLibraryBean bean) {
AjaxRes ar = new AjaxRes();
int result = service.resetPasswordAll(bean);
if (result > 0 ) {
ar.setSucceedMsg(GlobalConst.DATA_SUCCEED);
} else {
ar.setFailMsg(GlobalConst.DATA_FAIL);
}
return ar;
}
} }

View File

@ -35,11 +35,6 @@ public class SysLogController {
*/ */
@RequestMapping(value = "/queryByPage") @RequestMapping(value = "/queryByPage")
public String queryByPage(SysLogs sysLogs, @RequestParam("page") Integer page, @RequestParam("limit") Integer pageSize) { public String queryByPage(SysLogs sysLogs, @RequestParam("page") Integer page, @RequestParam("limit") Integer pageSize) {
String username = sysLogs.getUsername();
// 用正则匹配是否包含非法字符若匹配到则说明有非法字符
if (username.matches(".*[^a-zA-Z0-9\u4e00-\u9fa5-].*")) {
return "{\"code\":1 , \"msg\":\"操作人仅允许输入中英文、数字和连字符\"}";
}
int count = sysLogDao.count(sysLogs); int count = sysLogDao.count(sysLogs);
page = (page - 1) * pageSize; page = (page - 1) * pageSize;
List<SysLogs> list = this.sysLogDao.queryAllByLimit(sysLogs, page, pageSize); List<SysLogs> list = this.sysLogDao.queryAllByLimit(sysLogs, page, pageSize);

View File

@ -97,4 +97,25 @@ public class importExcelController {
return ar; return ar;
} }
@LogAnnotation
@PostMapping("/reservationNew")
@ApiOperation(value = "体检人员库导入")
public AjaxRes reservationNew(@RequestParam("file") MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws IOException {
int result = 1;
AjaxRes ar = new AjaxRes();
try {
List<JSONObject> lstObj = (List<JSONObject>) ImportNoPhotoExcelHelper.readExcel(file, PersonnelReservationBean.class);
String code = service.reservationNew(lstObj);
if ("导入成功".equals(code)){
ar.setSucceedMsg("导入成功");
}else{
ar.setFailMsg(code);
}
} catch (Exception e) {
e.printStackTrace();
ar.setFailMsg(e.getMessage());
}
return ar;
}
} }

View File

@ -55,4 +55,8 @@ public interface PersonnelLibraryDao {
int getPhoneBy(@Param("personName")String personName,@Param("phone")String phone); int getPhoneBy(@Param("personName")String personName,@Param("phone")String phone);
int getIdNumber(@Param("idNumber")String idNumber); int getIdNumber(@Param("idNumber")String idNumber);
PersonnelReservationBean getMealNameNew(@Param("setMeal")String setMeal);
int resetPasswordAll(PersonnelLibraryBean bean);
} }

View File

@ -116,4 +116,14 @@ public class PersonnelLibraryBean extends HospitalBean{
private String userId; private String userId;
/**
* 套餐名称
*/
private String typeName;
/**
* 套餐名称id
*/
private String baseNameId;
} }

View File

@ -13,4 +13,6 @@ public interface ImportExcelService {
String savenegativeResult(List<JSONObject> lstObj); String savenegativeResult(List<JSONObject> lstObj);
String reservation(List<JSONObject> lstObj); String reservation(List<JSONObject> lstObj);
String reservationNew(List<JSONObject> lstObj);
} }

View File

@ -19,4 +19,6 @@ public interface PersonnelLibraryService {
int resetPassword(PersonnelLibraryBean bean); int resetPassword(PersonnelLibraryBean bean);
List<ZNode> getDepartmentTree(); List<ZNode> getDepartmentTree();
int resetPasswordAll(PersonnelLibraryBean bean);
} }

View File

@ -460,6 +460,207 @@ public class ImportExcelServiceImpl implements ImportExcelService {
} }
@Override
public String reservationNew(List<JSONObject> lstObj) {
List<PersonnelReservationBean> validBeans = new ArrayList<>(); // 用于存储通过验证的数据
String res = "";
int team = 1;
int i = 0;
String personName = "";
String phone = "";
String idNumber = "";
String department = "";
String hospital = "";
String sex = "";
String setMeal = "";
boolean hasError = false; // 标志位用于记录是否有错误
try {
if (lstObj != null && lstObj.size() > 0) {
for (JSONObject obj : lstObj) {
i++;
PersonnelReservationBean bean = new PersonnelReservationBean(); // 每个对象创建一个新的Bean
personName = obj.getString("personName").trim();
idNumber = obj.getString("idNumber").trim();
sex = obj.getString("sex").trim();
department = obj.getString("department").trim();
hospital = obj.getString("hospital").trim();
setMeal = obj.getString("setMeal").trim();
phone = obj.getString("phone").trim();
// 判断姓名为空
if (StringHelper.isEmpty(personName)) {
res += "" + i + "行姓名为空;";
hasError = true;
}
bean.setPersonName(personName);
// 判断身份证为空
/*if (StringHelper.isEmpty(idNumber) || "0.0".equals(idNumber.trim())) {
res += "" + i + "" + personName + "行身份证为空;";
team = 2;
hasError = true;
} else if (idNumber.length() != 18) {
res += "" + i + "" + personName + "行身份证格式错误;";
team = 2;
hasError = true;
}
bean.setIdNumber(idNumber);*/
// 判断性别为空
/*if (StringHelper.isEmpty(sex)) {
res += "" + i + "" + personName + "行性别为空;";
team = 2;
hasError = true;
} else {
String a = getSexByIdcard(idNumber);
String b = "";
if (sex.equals("")) {
b = "0";
} else {
b = "1";
}
if (!a.equals(b)) {
res += "" + i + "" + personName + "行身份证与性别不匹配;";
hasError = true;
} else {
bean.setSex(b);
}
}*/
// 判断部门名称为空
/*if (!department.isEmpty()) {
String departmentName = dao.getdepartmentName(department);
if (StringHelper.isEmpty(departmentName) || "0.0".equals(departmentName.trim())) {
team = 2;
res += "" + i + "" + personName + "部门名称有误,请检查";
hasError = true;
} else {
bean.setDepartment(departmentName + "");
}
} else {
team = 2;
res += "" + i + "" + personName + "部门名称为空";
hasError = true;
}*/
// 判断医院名称为空
if (StringHelper.isEmpty(hospital)) {
res += "" + i + "" + personName + "行医院名称为空;";
team = 2;
hasError = true;
} else {
if (hospital.equals("1")) {
bean.setHospital("33");
} else if (hospital.equals("2")) {
bean.setHospital("34");
} else if (hospital.equals("3")) {
bean.setHospital("35");
} else {
res += "" + i + "" + personName + "行医院名称有误,请检查";
hasError = true;
}
}
String ifHighee = null; // 判断是否为高职
// 判断体检套餐为空
if (StringHelper.isEmpty(setMeal)) {
res += "" + i + "" + personName + "行体检套餐为空;";
team = 2;
hasError = true;
} else {
// PersonnelReservationBean bean1 = dao.getMealName(setMeal);
PersonnelReservationBean bean1 = dao.getMealNameNew(setMeal);
if(bean1!=null){
String setMealName = bean1.getSetMealId();
ifHighee = bean1.getIfHighee();
if (StringHelper.isEmpty(setMealName) || "0.0".equals(setMealName.trim())) {
team = 2;
res += "" + i + "" + personName + "体检套餐有误,请检查";
hasError = true;
} else {
bean.setSetMeal(setMealName + "");
bean.setCheckType(bean1.getCheckType());
bean.setCombName(setMeal);
}
}else{
team = 2;
res += "" + i + "" + personName + "体检套餐有误,请检查";
hasError = true;
}
}
// 判断手机号码为空
if (StringHelper.isEmpty(phone) || "0.0".equals(phone.trim())) {
res += "" + i + "" + personName + "行手机号码为空;";
team = 2;
hasError = true;
} else if (!isLegalMobileNumber(phone)) {
res += "" + i + "" + personName + "行手机号码格式错误;";
team = 2;
hasError = true;
}
bean.setPhone(phone);
// 查询通过身份证姓名电话去查询
int personNameNum = dao.getPersonNameBy(personName);
if (personNameNum > 0) {
} else {
res += "" + i + "" + personName + "行姓名有误。请检查";
team = 2;
hasError = true;
}
int phoneNum = dao.getPhoneBy(personName,phone);
if (phoneNum > 0) {
}else{
res += "" + i + "" + personName + "行手机号有误。请检查";
team = 2;
hasError = true;
}
if (team != 2) {
PersonnelReservationBean beans = dao.getInfoById(personName, "", phone,"");
if (beans != null) {
// 获取预约人的id
// bean.setId(beans.getId());
} else {
res += "" + i + "" + personName + "行身份证有误。请检查";
hasError = true;
}
PersonnelReservationBean beans1 = dao.getInfoById(personName, "", phone,"");
if (beans1 != null) {
// 获取预约人的id
bean.setId(beans1.getId());
} else {
res += "" + i + "" + personName + "行高职与非高职有误。请检查";
hasError = true;
}
}
// 只有在没有错误的情况下才执行新增操作
if (!hasError) {
validBeans.add(bean);
}
}
// 只有在没有错误的情况下才执行批量导入操作
if (!hasError) {
for (PersonnelReservationBean bean : validBeans) {
int k = dao.updateReservation(bean);
}
res = "导入成功";
}
}
} catch (Exception e) {
e.printStackTrace();
}
return res;
}
private String ChangepersonType(String personType) { private String ChangepersonType(String personType) {
String team; String team;
if (personType.equals("在职")) { if (personType.equals("在职")) {

View File

@ -32,7 +32,7 @@ public class PackageTypeServiceImpl implements PackageTypeService {
@Override @Override
public int addInfo(BaseTypePackageBean bean) { public int addInfo(BaseTypePackageBean bean) {
int num = utilDao.determineIfExists("pm_base_type_package","type_name",bean.getTypeName(),""); int num = utilDao.determineIfExists("pm_base_type_package_name","type_name",bean.getTypeName(),"");
if(num > 0){ if(num > 0){
num = 3; num = 3;
}else { }else {
@ -43,7 +43,7 @@ public class PackageTypeServiceImpl implements PackageTypeService {
@Override @Override
public int updateInfo(BaseTypePackageBean bean) { public int updateInfo(BaseTypePackageBean bean) {
int num = utilDao.determineIfExists("pm_base_type_package","type_name",bean.getTypeName(),bean.getId()+""); int num = utilDao.determineIfExists("pm_base_type_package_name","type_name",bean.getTypeName(),bean.getId()+"");
if(num > 0){ if(num > 0){
num = 3; num = 3;
}else { }else {

View File

@ -120,4 +120,11 @@ public class PersonnelLibraryServiceImpl implements PersonnelLibraryService {
public List<ZNode> getDepartmentTree() { public List<ZNode> getDepartmentTree() {
return dao.getDepartmentTree(); return dao.getDepartmentTree();
} }
@Override
public int resetPasswordAll(PersonnelLibraryBean bean) {
bean.setPassword(passwordEncoder.encode("YNsbd@123456"));
return dao.resetPasswordAll(bean);
}
} }

View File

@ -16,11 +16,10 @@ import org.springframework.security.web.authentication.AuthenticationFailureHand
import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.web.cors.CorsConfigurationSource;
/** /**
* spring security配置 * spring security配置
* *
*/ */
@EnableGlobalMethodSecurity(prePostEnabled = true) @EnableGlobalMethodSecurity(prePostEnabled = true)
public class BnsSecurityConfig extends WebSecurityConfigurerAdapter { public class BnsSecurityConfig extends WebSecurityConfigurerAdapter {
@ -38,9 +37,6 @@ public class BnsSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired @Autowired
private TokenFilter tokenFilter; private TokenFilter tokenFilter;
@Autowired
private CorsConfigurationSource corsConfigurationSource;
@Bean @Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() { public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder(); return new BCryptPasswordEncoder();
@ -49,8 +45,7 @@ public class BnsSecurityConfig extends WebSecurityConfigurerAdapter {
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable(); http.csrf().disable();
// 使用新的跨域配置
http.cors(cors -> cors.configurationSource(corsConfigurationSource));
// 基于token所以不需要session // 基于token所以不需要session
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
@ -65,7 +60,7 @@ public class BnsSecurityConfig extends WebSecurityConfigurerAdapter {
.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint); .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint);
http.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler); http.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler);
// 解决不允许显示在iframe的问题 // 解决不允许显示在iframe的问题
//http.headers().frameOptions().disable(); http.headers().frameOptions().disable();
http.headers().cacheControl(); http.headers().cacheControl();
http.addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class); http.addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class);

View File

@ -1,89 +0,0 @@
package com.bonus.boot.manager.manager.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.Arrays;
import java.util.List;
/**
* 跨域配置类
* 解决前后端不分离项目的跨域问题
*/
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Value("${cors.allowed-origins}")
private String allowedOrigins;
@Value("${cors.allowed-methods}")
private String allowedMethods;
@Value("${cors.allowed-headers}")
private String allowedHeaders;
@Value("${cors.allow-credentials}")
private boolean allowCredentials;
@Value("${cors.max-age}")
private long maxAge;
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns(getAllowedOriginPatterns().toArray(new String[0]))
.allowedMethods(getAllowedMethodArray())
.allowedHeaders(getAllowedHeaderArray())
.allowCredentials(allowCredentials)
.maxAge(maxAge)
.exposedHeaders("Content-Length", "Content-Type", "Token", "Authorization");
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOriginPatterns(getAllowedOriginPatterns());
configuration.setAllowedMethods(Arrays.asList(getAllowedMethodArray()));
configuration.setAllowedHeaders(Arrays.asList(getAllowedHeaderArray()));
configuration.setExposedHeaders(Arrays.asList("Content-Length", "Content-Type", "Token", "Authorization"));
configuration.setAllowCredentials(allowCredentials);
configuration.setMaxAge(maxAge);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
// 统一仅注册一套白名单策略避免出现*
source.registerCorsConfiguration("/**", configuration);
return source;
}
private List<String> getAllowedOriginPatterns() {
if (allowedOrigins == null || allowedOrigins.trim().isEmpty()) {
return Arrays.asList(
"http://localhost:*",
"http://127.0.0.1:*",
"http://192.168.*.*:*",
"http://10.*.*.*:*"
);
}
return Arrays.asList(allowedOrigins.split(","));
}
private String[] getAllowedMethodArray() {
if (allowedMethods == null || allowedMethods.trim().isEmpty()) {
return new String[]{"GET", "POST", "PUT", "DELETE", "OPTIONS"};
}
return allowedMethods.split(",");
}
private String[] getAllowedHeaderArray() {
if (allowedHeaders == null || allowedHeaders.trim().isEmpty()) {
return new String[]{"Content-Type", "X-Requested-With", "Token", "Authorization", "X-Custom-Header"};
}
return allowedHeaders.split(",");
}
}

View File

@ -1,236 +0,0 @@
package com.bonus.boot.manager.manager.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
@Component
@Order(1) // 确保过滤器优先级
public class CspFilter implements Filter {
// 静态资源扩展名模式
private static final Pattern STATIC_RESOURCE_PATTERN = Pattern.compile(
".*\\.(css|js|map|png|jpg|jpeg|gif|ico|svg|webp|bmp|" +
"woff|woff2|ttf|eot|otf|pdf|txt|xml|json|" +
"zip|rar|7z|tar|gz|mp4|mp3|wav|avi|mov|webm|" +
"doc|docx|xls|xlsx|ppt|pptx)$",
Pattern.CASE_INSENSITIVE
);
// 静态资源路径前缀
private static final List<String> STATIC_PATH_PREFIXES = Arrays.asList(
"/static/", "/public/", "/resources/", "/assets/", "/css/", "/js/",
"/images/", "/img/", "/fonts/", "/webjars/", "/vendor/", "/dist/",
"/uploads/", "/downloads/", "/libs/", "/layui/"
);
// WebGL和3D地图相关页面路径
private static final List<String> WEBGL_PAGE_PATHS = Arrays.asList(
"/pages/synthesisQuery/digitalSignage.html",
"/pages/basic/lineManagement/child/setSpanTowerLonAndLat.html"
);
@Value("${spring.profiles.active:prod}")
private String activeProfile;
@Value("${csp.report-only:false}")
private boolean cspReportOnly;
@Value("${csp.allow-iframe:true}")
private boolean allowIframe;
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String requestUri = httpRequest.getRequestURI();
// 设置所有必要的安全头
setSecurityHeaders(httpResponse, requestUri);
chain.doFilter(request, response);
}
private void setSecurityHeaders(HttpServletResponse response, String requestUri) {
// 1. 设置ClickJacking防护头优先解决
setClickJackingProtectionHeaders(response, requestUri);
// 2. 设置CSP头
setCspHeader(response, requestUri);
// 3. 设置其他安全头
setAdditionalSecurityHeaders(response);
}
private void setCspHeader(HttpServletResponse response, String requestUri) {
String cspPolicy;
if (isStaticResource(requestUri)) {
// 静态资源使用简单策略
cspPolicy = "default-src 'self'";
}
else if (isLoginPage(requestUri)) {
// 登录页面 - 使用安全的CSP策略移除不安全的指令
String frameAncestors = allowIframe ? "'self'" : "'none'";
cspPolicy = "default-src 'self'; " +
// 允许同源脚本和外部JavaScript库
"script-src 'self' 'unsafe-inline' https:; " +
// 只允许同源样式
"style-src 'self' 'unsafe-inline' https:; " +
// 只允许同源图片和数据URI
"img-src 'self' data: blob: https:; " +
// 只允许同源字体和数据URI
"font-src 'self' data: https:; " +
// 只允许同源连接
"connect-src 'self' https:; " +
"frame-ancestors " + frameAncestors + "; " +
"form-action 'self'; " +
"object-src 'none'; " +
"base-uri 'self'; " +
"report-uri /api/csp-violation";
}
else if (isWebglPage(requestUri)) {
// WebGL和3D地图页面 - 需要更宽松的策略支持WebGLWorker等
String frameAncestors = allowIframe ? "'self'" : "'none'";
cspPolicy = "default-src 'self'; " +
"script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: data:; " +
"style-src 'self' 'unsafe-inline' data: blob:; " +
"img-src 'self' data: blob: https:; " +
"font-src 'self' data: blob: https:; " +
"connect-src 'self' https: blob: data: http://data.mars3d.cn; " +
"frame-ancestors " + frameAncestors + "; " +
"form-action 'self'; " +
"object-src 'none'; " +
"base-uri 'self'; " +
"worker-src 'self' blob: data:; " +
"child-src 'self' blob: data:; " +
"report-uri /api/csp-violation"; // 移除 upgrade-insecure-requests避免强制HTTPS
} else {
// 普通HTML页面 - 根据配置决定是否允许iframe
String frameAncestors = allowIframe ? "'self'" : "'none'";
cspPolicy = "default-src 'self'; " +
"script-src 'self' 'unsafe-inline' 'unsafe-eval' https:; " +
"style-src 'self' 'unsafe-inline' https:; " +
"img-src 'self' data: blob: https:; " +
"font-src 'self' data: https:; " +
"connect-src 'self' https:; " +
"frame-ancestors " + frameAncestors + "; " +
"form-action 'self'; " +
"object-src 'none'; " +
"base-uri 'self'; " +
"report-uri /api/csp-violation"; // 移除 upgrade-insecure-requests避免强制HTTPS
}
String headerName = cspReportOnly ?
"Content-Security-Policy-Report-Only" : "Content-Security-Policy";
response.setHeader(headerName, cspPolicy);
}
private void setClickJackingProtectionHeaders(HttpServletResponse response, String requestUri) {
// 对于静态资源使用宽松的ClickJacking防护
if (isStaticResource(requestUri)) {
response.setHeader("X-Frame-Options", "SAMEORIGIN");
return;
}
// 对于HTML页面根据配置决定防护级别
if (allowIframe) {
response.setHeader("X-Frame-Options", "SAMEORIGIN");
} else {
response.setHeader("X-Frame-Options", "DENY");
}
}
private void setAdditionalSecurityHeaders(HttpServletResponse response) {
response.setHeader("X-Content-Type-Options", "nosniff");
response.setHeader("X-XSS-Protection", "1; mode=block");
response.setHeader("Referrer-Policy", "strict-origin-when-cross-origin");
response.setHeader("Permissions-Policy",
"geolocation=(), microphone=(), camera=(), payment=(), usb=(), magnetometer=(), gyroscope=()");
// 注意HSTS 只应在 HTTPS 部署下开启当前未在此处强制设置
// 如需开启请在 HTTPS 部署完成后通过配置控制
// 例如Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
}
private boolean isStaticResource(String uri) {
if (uri == null || uri.isEmpty()) {
return false;
}
String path = uri.split("\\?")[0];
if (STATIC_RESOURCE_PATTERN.matcher(path).matches()) {
return true;
}
return STATIC_PATH_PREFIXES.stream().anyMatch(path::startsWith);
}
/**
* 判断是否为登录页面
*/
private boolean isLoginPage(String requestUri) {
return requestUri != null && (
requestUri.endsWith("/login.html") ||
requestUri.endsWith("/login") ||
requestUri.contains("/login")
);
}
/**
* 生成随机nonce值
*/
private String generateNonce() {
byte[] nonceBytes = new byte[16];
new java.util.Random().nextBytes(nonceBytes);
return java.util.Base64.getEncoder().encodeToString(nonceBytes);
}
/**
* 生成内容的SHA-256哈希值
*/
private String generateHash(String content) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(content.getBytes("UTF-8"));
return "'sha256-" + java.util.Base64.getEncoder().encodeToString(hash) + "'";
} catch (Exception e) {
return "";
}
}
private boolean isWebglPage(String uri) {
if (uri == null || uri.isEmpty()) {
return false;
}
String path = uri.split("\\?")[0];
return WEBGL_PAGE_PATHS.stream().anyMatch(path::contains);
}
private boolean isProduction() {
return "prod".equals(activeProfile) || "production".equals(activeProfile);
}
@Override
public void destroy() {
// 清理资源
}
}

View File

@ -1,71 +0,0 @@
package com.bonus.boot.manager.manager.config;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 额外的安全头过滤器
* 用于设置更多的安全相关头信息
*/
@Component
@Order(2)
public class SecurityHeadersFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
// 设置额外的安全头
setAdditionalSecurityHeaders(httpRequest, httpResponse);
chain.doFilter(request, response);
}
private void setAdditionalSecurityHeaders(HttpServletRequest request, HttpServletResponse response) {
// 1) 缓存控制
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", "0");
// 2) IE下载策略
response.setHeader("X-Download-Options", "noopen");
// 3) 跨域策略条件化设置
if (isPotentiallyTrustworthy(request)) {
response.setHeader("Cross-Origin-Opener-Policy", "same-origin");
response.setHeader("Cross-Origin-Resource-Policy", "same-origin");
response.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
} else {
response.setHeader("Cross-Origin-Opener-Policy", "");
response.setHeader("Cross-Origin-Resource-Policy", "");
response.setHeader("Cross-Origin-Embedder-Policy", "");
}
// 4) 不再设置已废弃的 Feature-Policy避免与 Permissions-Policy 冲突
// Permissions-Policy 已在 CspFilter 中统一设置
}
private boolean isPotentiallyTrustworthy(HttpServletRequest request) {
boolean isSecure = request.isSecure();
String forwardedProto = request.getHeader("X-Forwarded-Proto");
if (!isSecure && forwardedProto != null) {
isSecure = "https".equalsIgnoreCase(forwardedProto);
}
String host = request.getServerName();
boolean isLocalhost = "localhost".equalsIgnoreCase(host) || "127.0.0.1".equals(host);
return isSecure || isLocalhost;
}
@Override
public void destroy() {
// 清理资源
}
}

View File

@ -19,10 +19,10 @@ public class WebMvcConfig implements WebMvcConfigurer {
/** /**
* 跨域支持 * 跨域支持
* *
* @return * @return
*/ */
/*@Bean @Bean
public WebMvcConfigurer corsConfigurer() { public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() { return new WebMvcConfigurer() {
@Override @Override
@ -30,11 +30,11 @@ public class WebMvcConfig implements WebMvcConfigurer {
registry.addMapping("/**").allowedMethods("*"); registry.addMapping("/**").allowedMethods("*");
} }
}; };
}*/ }
/** /**
* datatable分页解析 * datatable分页解析
* *
* @return * @return
*/ */
@Bean @Bean

View File

@ -119,10 +119,7 @@ public class UserController {
@ApiOperation(value = "当前登录用户") @ApiOperation(value = "当前登录用户")
@GetMapping("/current") @GetMapping("/current")
public SysUser currentUser() { public SysUser currentUser() {
//置空password return UserUtil.getLoginUser();
SysUser sysUser = UserUtil.getLoginUser();
sysUser.setPassword(null);
return sysUser;
} }
@GetMapping("/getTokenKey") @GetMapping("/getTokenKey")
@ -158,7 +155,7 @@ public class UserController {
} }
/**-------------------------------------------以上为老代码,以下为layui新页面所使用的方法-----------------------------------------------------------------*/ /**-------------------------------------------以上为老代码,以下为layui新页面所使用的方法-----------------------------------------------------------------*/
@LogAnnotation @LogAnnotation
@PostMapping("getMsgContent") @PostMapping("getMsgContent")
@ApiOperation(value = "用户管理-列表") @ApiOperation(value = "用户管理-列表")
@ -353,8 +350,12 @@ public class UserController {
// String result = HttpClientUtils.doHttpPost("http://112.29.103.165:1616/ynuw/sys/api/userLogin", object, null); // String result = HttpClientUtils.doHttpPost("http://112.29.103.165:1616/ynuw/sys/api/userLogin", object, null);
String result = HttpClientUtils.doHttpPost(AddressConfiguration.UNIFICATION_URL + "/ynuw/sys/api/userLogin", object, null); String result = HttpClientUtils.doHttpPost(AddressConfiguration.UNIFICATION_URL + "/ynuw/sys/api/userLogin", object, null);
JSONObject jsonObject = JSONObject.parseObject(result); JSONObject jsonObject = JSONObject.parseObject(result);
String string = JSONObject.parseObject(jsonObject.getString("data")).getString("token"); if(jsonObject == null || jsonObject.isEmpty()){
return string; return "";
}else{
String string = JSONObject.parseObject(jsonObject.getString("data")).getString("token");
return string;
}
} }
//统一平台后台新增接口 获取token //统一平台后台新增接口 获取token

View File

@ -107,5 +107,13 @@ public class UtilController {
List<MapBean> list = service.getSetMeal(o); List<MapBean> list = service.getSetMeal(o);
return R.okTable(list, list.size()); return R.okTable(list, list.size());
} }
@LogAnnotation
@PostMapping(value = "/getPackageTypeName")
@ApiOperation(value = "套餐类型select列表")
public List<MapBean> getPackageTypeName() {
List<MapBean> result = service.getPackageTypeName();
return result;
}
} }

View File

@ -62,4 +62,6 @@ public interface UtilDao {
List<MapBean> getExaminationHospital(); List<MapBean> getExaminationHospital();
List<MapBean> getNewHospitalSelect(MapBean bean); List<MapBean> getNewHospitalSelect(MapBean bean);
List<MapBean> getPackageTypeName();
} }

View File

@ -2,7 +2,8 @@ package com.bonus.boot.manager.manager.filter;
import java.io.IOException; import java.io.IOException;
import javax.servlet.*; import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -21,7 +22,7 @@ import com.bonus.boot.manager.manager.entity.LoginUser;
* Token过滤器 * Token过滤器
*/ */
@Component @Component
public class TokenFilter extends OncePerRequestFilter implements Filter { public class TokenFilter extends OncePerRequestFilter {
public static final String TOKEN_KEY = "token"; public static final String TOKEN_KEY = "token";
@ -44,18 +45,14 @@ public class TokenFilter extends OncePerRequestFilter implements Filter {
SecurityContextHolder.getContext().setAuthentication(authentication); SecurityContextHolder.getContext().setAuthentication(authentication);
} }
} }
// 在这里设置 CSP 头或其他过滤逻辑
/*response.setHeader(
"Content-Security-Policy",
"default-src 'self'; script-src 'self' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline';font-src 'self' data:;img-src 'self' data:;"
);*/
filterChain.doFilter(request, response); filterChain.doFilter(request, response);
} }
/** /**
* 校验时间<br> * 校验时间<br>
* 过期时间与当前时间对比临近过期10分钟内的话自动刷新缓存 * 过期时间与当前时间对比临近过期10分钟内的话自动刷新缓存
* *
* @param loginUser * @param loginUser
* @return * @return
*/ */
@ -73,7 +70,7 @@ public class TokenFilter extends OncePerRequestFilter implements Filter {
/** /**
* 根据参数或者header获取token * 根据参数或者header获取token
* *
* @param request * @param request
* @return * @return
*/ */
@ -85,4 +82,5 @@ public class TokenFilter extends OncePerRequestFilter implements Filter {
return token; return token;
} }
} }

View File

@ -44,4 +44,6 @@ public interface UtilService {
List<MapBean> getExaminationHospital(); List<MapBean> getExaminationHospital();
List<MapBean> getNewHospitalSelect(MapBean o); List<MapBean> getNewHospitalSelect(MapBean o);
List<MapBean> getPackageTypeName();
} }

View File

@ -75,4 +75,9 @@ public class UtilServiceImpl implements UtilService {
bean.setHospitalId(hospiral); bean.setHospitalId(hospiral);
return utilDao.getNewHospitalSelect(bean); return utilDao.getNewHospitalSelect(bean);
} }
@Override
public List<MapBean> getPackageTypeName() {
return utilDao.getPackageTypeName();
}
} }

View File

@ -1,20 +1,20 @@
#\u8BBF\u95EE\u7AEF\u53E3 #\u8BBF\u95EE\u7AEF\u53E3
#\u6B63\u5F0F\u7AEF\u53E3 #\u6B63\u5F0F\u7AEF\u53E3
#server.port=18088 #server.port=18088
#\u672C\u5730\u7AEF\u53E3 #\u672C\u5730\u7AEF\u53E3
#server.port=18088
#\u6D4B\u8BD5\u7AEF\u53E3
server.port=18088 server.port=18088
#\u6D4B\u8BD5\u7AEF\u53E3
#server.port=18088
#\u8BBF\u95EE\u8DEF\u5F84 #\u8BBF\u95EE\u8DEF\u5F84
server.servlet.context-path=/YSpeaManager server.servlet.context-path=/YSpeaManager
#\u6B63\u5F0F\u5E93 #\u6B63\u5F0F\u5E93
#spring.datasource.url=jdbc:mysql://192.168.1.8:23342/yn_tj_appoint?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true spring.datasource.url=jdbc:mysql://192.168.1.8:23342/yn_tj_appoint?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
#spring.datasource.username=root
#spring.datasource.password=Bonus@yntj123!
#\u6D4B\u8BD5\u5E93
spring.datasource.url=jdbc:mysql://192.168.0.14:1115/yn_tj_appoint?useSSL=false&allowMultiQueries=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root spring.datasource.username=root
spring.datasource.password=xbzadmin@szedu14! spring.datasource.password=Bonus@yntj123!
#\u6D4B\u8BD5\u5E93
#spring.datasource.url=jdbc:mysql://192.168.0.14:1115/yn_tj_appoint?useSSL=false&allowMultiQueries=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
#spring.datasource.username=root
#spring.datasource.password=xbzadmin@szedu14!
#\u672C\u5730\u5E93 #\u672C\u5730\u5E93
#spring.datasource.url=jdbc:mysql://127.0.0.1:3306/yn_tj_appoint?useSSL=false&allowMultiQueries=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai #spring.datasource.url=jdbc:mysql://127.0.0.1:3306/yn_tj_appoint?useSSL=false&allowMultiQueries=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
#spring.datasource.username=root #spring.datasource.username=root
@ -32,13 +32,13 @@ mybatis.mapper-locations=classpath:mappers/*/*Mapper.xml
mybatis.type-aliases-package=com.bonus.boot.manager.*.entity mybatis.type-aliases-package=com.bonus.boot.manager.*.entity
#\u7EBF\u4E0A #\u7EBF\u4E0A
#spring.redis.host=192.168.1.8 spring.redis.host=192.168.1.8
#spring.redis.port=23347 spring.redis.port=23347
#spring.redis.password=Bonus@yntj123! spring.redis.password=Bonus@yntj123!
#\u6D4B\u8BD5 #\u6D4B\u8BD5
spring.redis.host=192.168.0.14 #spring.redis.host=192.168.0.14
spring.redis.port=2001 #spring.redis.port=2001
spring.redis.password=Dszbns@Redis123! #spring.redis.password=Dszbns@Redis123!
#\u672C\u5730 #\u672C\u5730
#spring.redis.host=127.0.0.1 #spring.redis.host=127.0.0.1
#spring.redis.port=6379 #spring.redis.port=6379
@ -65,49 +65,12 @@ token.expire.seconds=7200
spring.servlet.multipart.enabled=true spring.servlet.multipart.enabled=true
#\u6B63\u5F0F #\u6B63\u5F0F
#files.url=http://112.29.103.165:1616/medicalDocumentation/statics files.url=http://112.29.103.165:1616/medicalDocumentation/statics
#files.path=/data/yn
#\u6D4B\u8BD5
files.url=http://192.168.0.14:18088/medicalDocumentation/statics
files.path=/data/yn files.path=/data/yn
#\u6D4B\u8BD5
#files.url=http://192.168.0.14:18077/medicalDocumentation/statics
#files.path=/data/yn
#\u672C\u5730 #\u672C\u5730
#files.url=http://192.168.0.110:18088/YSpeaManager/statics #files.url=http://192.168.0.110:18088/YSpeaManager/statics
#files.path=d:\\data\\yn #files.path=d:\\data\\yn
#files.upload=d:\\files #files.upload=d:\\files
# \u8DE8\u57DF\u914D\u7F6E
# \u5141\u8BB8\u7684\u6E90\uFF08\u591A\u4E2A\u7528\u9017\u53F7\u5206\u9694\uFF09
cors.allowed-origins=http://localhost:18088,http://127.0.0.1:18088,http://192.168.0.39:1616,http://192.168.0.14:18088,http://112.29.103.165:1616
# \u5141\u8BB8\u7684HTTP\u65B9\u6CD5
cors.allowed-methods=GET,POST,PUT,DELETE,OPTIONS
# \u5141\u8BB8\u7684\u8BF7\u6C42\u5934
cors.allowed-headers=Content-Type,X-Requested-With,Token,Authorization,X-Custom-Header
# \u662F\u5426\u5141\u8BB8\u643A\u5E26\u8BA4\u8BC1\u4FE1\u606F
cors.allow-credentials=true
# \u9884\u68C0\u8BF7\u6C42\u7F13\u5B58\u65F6\u95F4\uFF08\u79D2\uFF09
cors.max-age=3600
# \u5B89\u5168\u5934\u914D\u7F6E
# \u662F\u5426\u542F\u7528\u4E25\u683C\u7684\u5B89\u5168\u5934
security.headers.strict=true
# \u662F\u5426\u542F\u7528HSTS\uFF08HTTP\u4E25\u683C\u4F20\u8F93\u5B89\u5168\uFF09
security.hsts.enabled=true
# \u662F\u5426\u6E05\u9664\u670D\u52A1\u5668\u4FE1\u606F\u5934
security.headers.clear-server-info=true
management.endpoint.caches.enabled=false
# CSP\u548C\u5B89\u5168\u5934\u914D\u7F6E
# \u662F\u5426\u542F\u7528CSP\u62A5\u544A\u6A21\u5F0F\uFF08true\u4E3A\u4EC5\u62A5\u544A\uFF0Cfalse\u4E3A\u5F3A\u5236\u6267\u884C\uFF09
csp.report-only=false
# \u662F\u5426\u5141\u8BB8\u9875\u9762\u5728iframe\u4E2D\u663E\u793A\uFF08true\u4E3A\u5141\u8BB8\u540C\u6E90iframe\uFF0Cfalse\u4E3A\u5B8C\u5168\u7981\u6B62\uFF09
csp.allow-iframe=true
# \u662F\u5426\u542F\u7528WebGL\u652F\u6301\uFF08true\u4E3A\u542F\u7528\uFF0Cfalse\u4E3A\u7981\u7528\uFF09
csp.enable-webgl=true

View File

@ -2,25 +2,24 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bonus.boot.manager.basic.dao.PackageTypeDao"> <mapper namespace="com.bonus.boot.manager.basic.dao.PackageTypeDao">
<insert id="addInfo"> <insert id="addInfo">
insert into pm_base_type_package (type_name,package_descri,is_active) insert into pm_base_type_package_name (type_name,is_active)
values (#{typeName},#{packageDescri},'1') values (#{typeName},'1')
</insert> </insert>
<update id="updateInfo"> <update id="updateInfo">
update pm_base_type_package set type_name = #{typeName},package_descri = #{packageDescri} update pm_base_type_package_name set type_name = #{typeName}
where id = #{id} where id = #{id}
</update> </update>
<delete id="delById"> <delete id="delById">
update pm_base_type_package set is_active = '0' where id = #{id} update pm_base_type_package_name set is_active = '0' where id = #{id}
</delete> </delete>
<select id="getList" resultType="com.bonus.boot.manager.basic.entity.BaseTypePackageBean"> <select id="getList" resultType="com.bonus.boot.manager.basic.entity.BaseTypePackageBean">
select select
id, id,
case when type_name = '1' then '标准套餐' when type_name = '2' then '个性化套餐' when type_name = '3' then '职业健康套餐' end as typeName, type_name as typeName
package_descri as packageDescri from pm_base_type_package_name
from pm_base_type_package
where is_active = '1' where is_active = '1'
<if test="typeName != null and typeName != ''"> <if test="typeName != null and typeName != ''">
AND type_name LIKE concat ('%',#{typeName},'%') AND type_name LIKE concat ('%',#{typeName},'%')
@ -30,9 +29,8 @@
<select id="getListById" resultType="com.bonus.boot.manager.basic.entity.BaseTypePackageBean"> <select id="getListById" resultType="com.bonus.boot.manager.basic.entity.BaseTypePackageBean">
select select
id, id,
type_name as typeName, type_name as typeName
package_descri as packageDescri from pm_base_type_package_name
from pm_base_type_package
where is_active = '1' and id = #{id} where is_active = '1' and id = #{id}
</select> </select>
</mapper> </mapper>

View File

@ -5,9 +5,9 @@
<insert id="addInfo" keyProperty="hospId" useGeneratedKeys="true"> <insert id="addInfo" keyProperty="hospId" useGeneratedKeys="true">
<!-- 插入到pm_base_physical表 --> <!-- 插入到pm_base_physical表 -->
insert into insert into
pm_base_physical(phy_name,idcard,age,depart_id,sex,if_higher,telep_number,if_job,special_job,phy_password,is_active,status,nosocomium,set_meal,personnel_type,pushStatus) pm_base_physical(phy_name,idcard,age,depart_id,sex,if_higher,telep_number,if_job,special_job,phy_password,is_active,status,nosocomium,personnel_type,pushStatus,base_name_id)
values values
(#{personName},#{idNumber},#{age},#{departmentId},#{sex},#{higherJob},#{phone},#{personType},#{specialPost},#{password},'1','1',#{hospital},#{setMeal},#{personnelType},'1') (#{personName},#{idNumber},#{age},#{departmentId},#{sex},#{higherJob},#{phone},#{personType},#{specialPost},#{password},'1','1',#{hospital},#{personnelType},'1',#{baseNameId})
</insert> </insert>
<insert id="addresult"> <insert id="addresult">
insert into pm_physical_result(physical_id) insert into pm_physical_result(physical_id)
@ -27,7 +27,7 @@
special_job = #{specialPost}, special_job = #{specialPost},
nosocomium = #{hospital}, nosocomium = #{hospital},
personnel_type = #{personnelType}, personnel_type = #{personnelType},
set_meal = #{setMeal} base_name_id = #{baseNameId}
where id = #{id} where id = #{id}
and is_active = '1' and is_active = '1'
</update> </update>
@ -92,12 +92,14 @@
when '2' then '肿瘤' when '2' then '肿瘤'
when '3' then '综合' when '3' then '综合'
else '' else ''
end as setMeal end as setMeal,
pn.type_name as typeName
from pm_base_physical pbp from pm_base_physical pbp
left join pm_base_hospital pbh on pbh.id = pbp.nosocomium left join pm_base_hospital pbh on pbh.id = pbp.nosocomium
left join sys_dic_detail sdd on sdd.id = pbp.if_job left join sys_dic_detail sdd on sdd.id = pbp.if_job
left join pm_base_special_job pbsj on pbsj.id = pbp.special_job and pbsj.is_active = '1' left join pm_base_special_job pbsj on pbsj.id = pbp.special_job and pbsj.is_active = '1'
left join pm_phy_organization po on po.id = pbp.depart_id left join pm_organization po on po.id = pbp.depart_id
LEFT JOIN pm_base_type_package_name pn on pn.id = pbp.base_name_id
where pbp.is_active = '1' where pbp.is_active = '1'
<if test="personName != null and personName != ''"> <if test="personName != null and personName != ''">
AND pbp.phy_name LIKE concat ('%',#{personName},'%') AND pbp.phy_name LIKE concat ('%',#{personName},'%')
@ -124,10 +126,13 @@
pbsj.job_name as specialPostName, pbsj.job_name as specialPostName,
pbp.nosocomium as hospital, pbp.nosocomium as hospital,
pbp.personnel_type as personnelType, pbp.personnel_type as personnelType,
pbp.set_meal as setMeal pbp.set_meal as setMeal,
pbp.base_name_id as baseNameId,
pn.type_name as typeName
from pm_base_physical pbp from pm_base_physical pbp
left join pm_base_special_job pbsj on pbsj.id = pbp.special_job and pbsj.is_active = '1' left join pm_base_special_job pbsj on pbsj.id = pbp.special_job and pbsj.is_active = '1'
left join pm_phy_organization po on po.id = pbp.depart_id left join pm_organization po on po.id = pbp.depart_id
LEFT JOIN pm_base_type_package_name pn on pn.id = pbp.base_name_id
where pbp.is_active = '1' where pbp.is_active = '1'
and pbp.id = #{id} and pbp.id = #{id}
</select> </select>
@ -147,7 +152,7 @@
</select> </select>
<select id="getdepartmentName" resultType="java.lang.String"> <select id="getdepartmentName" resultType="java.lang.String">
select id select id
from pm_phy_organization from pm_organization
where `name` = #{department} where `name` = #{department}
and is_active = '1' limit 1 and is_active = '1' limit 1
</select> </select>
@ -167,8 +172,12 @@
<select id="getInfoById" resultType="com.bonus.boot.manager.basic.entity.PersonnelReservationBean"> <select id="getInfoById" resultType="com.bonus.boot.manager.basic.entity.PersonnelReservationBean">
SELECT id SELECT id
from pm_base_physical from pm_base_physical
where is_active = '1' and if_job = '1' and phy_name = #{personName} and idcard = #{idNumber} where is_active = '1' and if_job = '1' and phy_name = #{personName}
and telep_number = #{phone} and telep_number = #{phone}
<if test="idNumber!=null and idNumber !='' and idNumber !='null' ">
and idcard = #{idNumber}
</if>
<if test="ifHighee!=null and ifHighee !='' and ifHighee !='null' "> <if test="ifHighee!=null and ifHighee !='' and ifHighee !='null' ">
and if_higher = #{ifHighee} and if_higher = #{ifHighee}
</if> </if>
@ -197,13 +206,23 @@
where is_active = '1' and idcard = #{idNumber} where is_active = '1' and idcard = #{idNumber}
</select> </select>
<select id="getMealNameNew" resultType="com.bonus.boot.manager.basic.entity.PersonnelReservationBean">
SELECT id as setMealId FROM `pm_base_type_package_name`
WHERE type_name LIKE concat ('%',#{setMeal},'%')
</select>
<update id="updateReservation"> <update id="updateReservation">
update pm_base_physical update pm_base_physical
set set
depart_id=#{department},
nosocomium=#{hospital}, nosocomium=#{hospital},
set_meal = #{checkType} base_name_id = #{setMeal}
where is_active = '1' and id=#{id} where is_active = '1' and id=#{id}
</update> </update>
<update id="resetPasswordAll">
update pm_base_physical
set phy_password = #{password}
where is_active = '1'
</update>
</mapper> </mapper>

View File

@ -70,6 +70,10 @@ select count(1) from pm_base_physical where telep_number=#{0} and is_active='1'
select id as `key`,hospital as `value` from pm_base_hospital where is_active ='1' select id as `key`,hospital as `value` from pm_base_hospital where is_active ='1'
</select> </select>
<select id="getPackageTypeName" resultType="com.bonus.boot.manager.basic.entity.MapBean">
select id as `key`,type_name AS `value` from pm_base_type_package_name where is_active ='1'
</select>
</mapper> </mapper>

View File

@ -67,7 +67,7 @@
where ppr.is_active = '1' where ppr.is_active = '1'
<if test="physicalTime !=null and physicalTime !='null' and physicalTime !=''"> <if test="physicalTime !=null and physicalTime !='null' and physicalTime !=''">
AND SUBSTRING(ppr.create_time, 1, 4) = #{physicalTime} and ppr.create_time like concat ('%',#{physicalTime},'%')
</if> </if>
<if test="physicalStatus !=null and physicalStatus !='null' and physicalStatus !=''"> <if test="physicalStatus !=null and physicalStatus !='null' and physicalStatus !=''">
and pbpa.appoint_status = #{physicalStatus} and pbpa.appoint_status = #{physicalStatus}

View File

@ -6,7 +6,7 @@
SELECT a.phy_appont_time as `key`,COUNT(a.id) as `value` SELECT a.phy_appont_time as `key`,COUNT(a.id) as `value`
FROM pm_base_phy_appont a FROM pm_base_phy_appont a
LEFT JOIN pm_base_physical b on b.id = a.user_id LEFT JOIN pm_base_physical b on b.id = a.user_id
WHERE a.if_cancel ='2' and b.is_active = '1' and a.if_career_appoint = '2' WHERE a.if_cancel ='2' and b.is_active = '1'
<if test="hospitalId !=null and hospitalId !='null'"> <if test="hospitalId !=null and hospitalId !='null'">
<if test="type == 1"> <if test="type == 1">
@ -44,15 +44,17 @@
a.phy_name AS personName, a.phy_name AS personName,
a.idcard AS idNumber, a.idcard AS idNumber,
a.age, a.age,
CASE case when check_content_id != "" THEN '常规体检'
WHEN check_content_id = 1 THEN else '职业体检' END AS checkContentId,
'心血管' -- CASE
WHEN check_content_id = 2 THEN -- WHEN check_content_id = 1 THEN
'肿瘤' -- '心血管'
WHEN check_content_id = 3 THEN -- WHEN check_content_id = 2 THEN
'综合' -- '肿瘤'
ELSE -- WHEN check_content_id = 3 THEN
'' end AS checkContentId, -- '综合'
-- ELSE
-- '' end AS checkContentId,
IF (a.sex = '0', '男', '女') AS sex, IF (a.sex = '0', '男', '女') AS sex,
# IF (b.if_edu = '0', '否', '是') AS ifEdu, # IF (b.if_edu = '0', '否', '是') AS ifEdu,
IF(a.if_higher = '0', '否', '是') AS higherJob, IF(a.if_higher = '0', '否', '是') AS higherJob,
@ -75,7 +77,7 @@
WHERE WHERE
if_cancel = '2' AND (check_content_id != "" OR check_content_id IS NOT NULL) if_cancel = '2' AND (check_content_id != "" OR check_content_id IS NOT NULL)
) b ON a.id = b.user_id and a.is_active ='1' ) b ON a.id = b.user_id and a.is_active ='1'
LEFT JOIN pm_phy_organization pmo ON pmo.ID = a.depart_id and pmo.IS_ACTIVE ='1' LEFT JOIN pm_organization pmo ON pmo.ID = a.depart_id and pmo.IS_ACTIVE ='1'
LEFT JOIN pm_base_hospital pbh ON pbh.id = b.hospital_id and pbh.is_active = '1' LEFT JOIN pm_base_hospital pbh ON pbh.id = b.hospital_id and pbh.is_active = '1'
LEFT JOIN sys_user sysu ON sysu.id = b.appoint_name_id and sysu.is_active ='1' LEFT JOIN sys_user sysu ON sysu.id = b.appoint_name_id and sysu.is_active ='1'
WHERE WHERE

View File

@ -1 +1,3 @@
1.主分支 1.notMerge分支用于修改体检名称-施亮提出
2.不能与主分支master合并
3.更新日期 2025-06-30

View File

@ -136,7 +136,7 @@
</div> </div>
<div class="site-mobile-shade"></div> <div class="site-mobile-shade"></div>
<script type="text/javascript" src="layui-v2.8.3/layui/layui.js"></script> <script type="text/javascript" src="layui-v2.8.3/layui/layui.js"></script>
<script type="text/javascript" src="js/libs/jquery-3.7.1.min.js"></script> <script type="text/javascript" src="js/libs/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="js/common_methon.js"></script> <script type="text/javascript" src="js/common_methon.js"></script>
<script type="text/javascript" src="js/jq.js"></script> <script type="text/javascript" src="js/jq.js"></script>
<script type="text/javascript" src="js/publicJs.js"></script> <script type="text/javascript" src="js/publicJs.js"></script>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -223,4 +223,31 @@ function getHazard(form,hazard) {
console.log("获取危害因素下拉列表出错:", err); console.log("获取危害因素下拉列表出错:", err);
} }
}); });
}
function getPackageTypeName(form,baseNameId) {
$("#baseNameId").html("");
$.ajax({
type: 'post',
url: ctxPath + '/utilConnection/getPackageTypeName',
data: {
},
async: false,
success: function (data) {
var html = '<option value="">--请选择套餐类型--</option>';
for (var i = 0; i < data.length; i++) {
if (baseNameId == data[i].key) {
html += '<option selected="selected" value=\'' + data[i].key + '\'>' + data[i].value + '</option>';
} else {
html += '<option value=\'' + data[i].key + '\'>' + data[i].value + '</option>';
}
}
$("#baseNameId").html(html);
layui.form.render('select'); //这里就是我们要渲染的地方了
},
error: function (err) {
console.log("获取套餐类型下拉列表出错:", err);
}
});
} }

View File

@ -15,9 +15,8 @@ layui.use(['table', 'layer', 'laydate', 'jquery', 'form'], function () {
{ {
field: 'number', width:120,title: '序号', align: 'center', type: 'numbers' field: 'number', width:120,title: '序号', align: 'center', type: 'numbers'
} }
, {field: 'typeName', align: 'center', title: '类型名称'} , {field: 'typeName', align: 'center', title: '类型名称'}
, {field: 'packageDescri', align: 'center', title: '套餐描述'} , {fixed: 'right', title: '操作', align: 'center', toolbar: '#toolsBar'}
, {fixed: 'right', title: '操作', width: 200, align: 'center', toolbar: '#toolsBar'}
]] ]]
, id: 'menuTable' , id: 'menuTable'
, page: true //开启分页 , page: true //开启分页

View File

@ -38,7 +38,7 @@ layui.use(['table', 'layer', 'laydate', 'jquery', 'form'], function () {
, {field: 'personnelType', width: 120, align: 'center', title: '人员类型'} , {field: 'personnelType', width: 120, align: 'center', title: '人员类型'}
, {field: 'specialPost', width: 150, align: 'center', title: '是否特殊岗位'} , {field: 'specialPost', width: 150, align: 'center', title: '是否特殊岗位'}
, {field: 'hospital', width: 150, align: 'center', title: '体检医院'} , {field: 'hospital', width: 150, align: 'center', title: '体检医院'}
, {field: 'setMeal', width: 150, align: 'center', title: '体检套餐'} , {field: 'typeName', width: 150, align: 'center', title: '体检套餐'}
, {fixed: 'right',width: 270, title: '操作', align: 'center', toolbar: '#toolsBar'} , {fixed: 'right',width: 270, title: '操作', align: 'center', toolbar: '#toolsBar'}
]] ]]
, id: 'menuTable' , id: 'menuTable'
@ -261,4 +261,74 @@ function importExcelYu() {
} }
}); });
$("#articleImageFileYu").val(""); $("#articleImageFileYu").val("");
}
function fetchExcelNew(){
window.location.href = ctxPath + "/download/download?filename=预约体检模版.xlsx"
}
function importExcelNew() {
var formData = new FormData($('form')[0]);
var name = $("#articleImageFileNew").val();
if (name == null || name == "") {
layer.msg("请上传Excel表格(.xlsx)");
return;
}
if (!(name.endsWith(".xlsx"))) {
layer.msg("请上传正确的Excel表格(.xlsx)!");
$("#articleImageFileNew").val("");
return;
}
formData.append("file", $("#articleImageFileNew")[0].files[0]);
console.log(formData)
var idx = layer.msg('正在提交数据,请稍等...', {
icon: 16
, shade: 0.01
, time: '-1'
});
$.ajax({
url: ctxPath + "/export/reservationNew",
type: 'POST',
async: true,
data: formData,
timeout: 60 * 1000 * 10,
// 告诉jQuery不要去处理发送的数据
processData: false,
// 告诉jQuery不要去设置Content-Type请求头
contentType: false,
success: function (data) {
if (data.resMsg == '导入成功') {
showMessages('导入成功!', true);
setTimeout(() => {
window.location.reload();
}, 30001)
} else {
showMessage(data.resMsg, false);
}
console.log(data)
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
console.log(JSON.stringify(errorThrown));
layer.close(idx);
}
});
$("#articleImageFileNew").val("");
}
/**
* 重置密码
* @param id
*/
function resetPasswordAll(){
layer.confirm('确定要重置密码吗?', {
btn : [ '确定', '取消' ]
}, function() {
ajaxCommonMethods('/personnelLibrary/resetPasswordAll',{},"重置成功","重置失败","1");
layer.close(1);
});
} }

View File

@ -35,10 +35,19 @@ layui.use(['table', 'layer', 'laydate', 'jquery', 'form'], function () {
, {field: 'higherJob', width: 240, align: 'center', title: '是否高职'} , {field: 'higherJob', width: 240, align: 'center', title: '是否高职'}
, {field: 'reservationTime', width: 200, align: 'center', title: '预约体检时间'} , {field: 'reservationTime', width: 200, align: 'center', title: '预约体检时间'}
, {field: 'name', width: 200, align: 'center', title: '预约医院'} , {field: 'name', width: 200, align: 'center', title: '预约医院'}
, {field: 'checkContentId', width: 200, align: 'center', title: '预约套餐'} , {field: 'checkContentId', width: 200, align: 'center', title: '预约体检',
// templet:function(res){
// var checkContentId = res.checkContentId;
// if(checkContentId){
// return "常规体检";
// }else{
// return "职业体检";
// }
// }
}
, {field: 'combName', width: 200, align: 'center', title: '套餐名称'} , {field: 'combName', width: 200, align: 'center', title: '套餐名称'}
, {field: 'operateTime', width: 130, align: 'center', title: '操作时间'} , {field: 'operateTime', width: 130, align: 'center', title: '操作时间'}
, {field: 'operatePerson', width: 120, align: 'center', title: '操作人员'} // , {field: 'operatePerson', width: 120, align: 'center', title: '操作人员'}
]] ]]
,done: function (res, curr, count) { ,done: function (res, curr, count) {
var state = ""; var state = "";

View File

@ -5,7 +5,7 @@
<title>Insert title here</title> <title>Insert title here</title>
<link rel="icon" href="img/favicon.ico" type="image/x-icon" /> <link rel="icon" href="img/favicon.ico" type="image/x-icon" />
<script src="../../js/jquery/jquery-3.7.1.min.js"></script> <script src="../../js/jquery/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="../../layui/layui.all.js"></script> <script type="text/javascript" src="../../layui/layui.all.js"></script>
<script type="text/javascript" src="../../js/publicJs.js"></script> <script type="text/javascript" src="../../js/publicJs.js"></script>
<script type="text/javascript" src="../../js/jq.js"></script> <script type="text/javascript" src="../../js/jq.js"></script>

View File

@ -5,7 +5,7 @@
<title>Insert title here</title> <title>Insert title here</title>
<link rel="icon" href="img/favicon.ico" type="image/x-icon" /> <link rel="icon" href="img/favicon.ico" type="image/x-icon" />
<script src="../../js/jquery/jquery-3.7.1.min.js"></script> <script src="../../js/jquery/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="../../layui/layui.all.js"></script> <script type="text/javascript" src="../../layui/layui.all.js"></script>
<script type="text/javascript" src="../../js/publicJs.js"></script> <script type="text/javascript" src="../../js/publicJs.js"></script>
<script type="text/javascript" src="../../js/jq.js"></script> <script type="text/javascript" src="../../js/jq.js"></script>

View File

@ -44,22 +44,16 @@
<div class="layui-form-item" style="margin-top: 10%;"> <div class="layui-form-item" style="margin-top: 10%;">
<div class="layui-inline"> <div class="layui-inline">
<label class="layui-form-label"><i class="tip-required" style="color: red;font-size: 20px">*</i>类型名称:</label> <label class="layui-form-label"><i class="tip-required" style="color: red;font-size: 20px">*</i>类型名称:</label>
<!-- <input type="text" name="typeName" minlength="2" maxlength="10" title="字数2-10" lay-verify="required" id="typeName" required class="layui-input">--> <input type="text" name="typeName" maxlength="40" lay-verify="required" id="typeName" required class="layui-input">
<select class="layui-select" id="typeName" lay-verify="required" name="typeName">
<option value="">--请选择类型名称--</option>
<option value="1">标准套餐</option>
<option value="2">个性化套餐</option>
<option value="3">职业健康套餐</option>
</select>
</div> </div>
</div> </div>
<div class="layui-form-item" style="margin-top: 20px;"> <!--<div class="layui-form-item" style="margin-top: 20px;">
<div class="layui-inline"> <div class="layui-inline">
<label class="layui-form-label"><i class="tip-required" style="color: red;font-size: 20px">*</i>套餐描述:</label> <label class="layui-form-label"><i class="tip-required" style="color: red;font-size: 20px">*</i>套餐描述:</label>
<input type="text" name="packageDescri" minlength="4" maxlength="30" title="字数4-30" <input type="text" name="packageDescri" minlength="4" maxlength="30" title="字数4-30"
lay-verify="required" id="packageDescri" required class="layui-input"> lay-verify="required" id="packageDescri" required class="layui-input">
</div> </div>
</div> </div>-->
<div class="layui-form-item" style="display: none"> <div class="layui-form-item" style="display: none">
<div class="layui-input-block"> <div class="layui-input-block">
<button type="submit" class="layui-btn subBtn" id="commit" lay-submit lay-filter="formDemo">提交 <button type="submit" class="layui-btn subBtn" id="commit" lay-submit lay-filter="formDemo">提交
@ -196,8 +190,7 @@
var resMsg = data.resMsg; var resMsg = data.resMsg;
if ("数据获取成功" == resMsg) { if ("数据获取成功" == resMsg) {
let info = data.obj.BaseTypePackageBean; let info = data.obj.BaseTypePackageBean;
$("#typeName").find('option[value=\'' + info.typeName + '\']').prop("selected", "selected"); $("#typeName").val(info.typeName);
$("#packageDescri").val(info.packageDescri);
form.render(); form.render();
} }
}, },

View File

@ -93,13 +93,7 @@
<div class="layui-form-item"> <div class="layui-form-item">
<div class="layui-input-inline" style="width: 30%;"> <div class="layui-input-inline" style="width: 30%;">
<label class="layui-form-label" style="width: 37%;">套餐类型名称:</label> <label class="layui-form-label" style="width: 37%;">套餐类型名称:</label>
<!-- <input type="text" id="typeName" placeholder="请输入套餐类型名称" autocomplete="off" class="layui-input">--> <input type="text" id="typeName" maxlength="40" title="字数40" placeholder="请输入套餐类型名称" autocomplete="off" class="layui-input">
<select class="layui-select" id="typeName" name="typeName">
<option value="">--请选择类型名称--</option>
<option value="1">标准套餐</option>
<option value="2">个性化套餐</option>
<option value="3">职业健康套餐</option>
</select>
</div> </div>
<div class="layui-inline" style="width: 5%;margin-top: 4px"> <div class="layui-inline" style="width: 5%;margin-top: 4px">

View File

@ -145,20 +145,17 @@
<div class="layui-form-item" style="margin-top: 20px;"> <div class="layui-form-item" style="margin-top: 20px;">
<div class="layui-inline"> <div class="layui-inline">
<label class="layui-form-label">体检医院:</label> <label class="layui-form-label"><i class="tip-required" style="color: red;font-size: 20px">*</i>体检医院:</label>
<select id="hospital" class="layui-select" name="hospital"> <select id="hospital" class="layui-select" name="hospital" lay-verify="required">
</select> </select>
</div> </div>
</div> </div>
<div class="layui-form-item" style="margin-top: 20px;"> <div class="layui-form-item" style="margin-top: 20px;">
<div class="layui-inline"> <div class="layui-inline">
<label class="layui-form-label">体检套餐:</label> <label class="layui-form-label"><i class="tip-required" style="color: red;font-size: 20px">*</i>体检套餐:</label>
<select id="setMeal" name="setMeal"> <select id="baseNameId" name="baseNameId" lay-verify="required">
<option value="">选择套餐</option>
<option value="1">心血管</option>
<option value="2">肿瘤</option>
<option value="3">综合</option>
</select> </select>
</div> </div>
</div> </div>
@ -221,6 +218,12 @@
* 部门下拉树 * 部门下拉树
*/ */
loadOrgTree(); loadOrgTree();
/**
* 体检套餐下拉框
*/
getPackageTypeName(form,null)
/** /**
* 修改方法调用数据回显 * 修改方法调用数据回显
*/ */
@ -370,7 +373,10 @@
$("#idNumber").prop("readonly", true); $("#idNumber").prop("readonly", true);
$("#phone").prop("readonly", true); $("#phone").prop("readonly", true);
getExaminationHospital(form, info.hospital); getExaminationHospital(form, info.hospital);
$("#setMeal").find('option[value=\'' + info.setMeal + '\']').prop("selected", "selected");
getPackageTypeName(form, info.baseNameId)
// $("#setMeal").find('option[value=\'' + info.setMeal + '\']').prop("selected", "selected");
form.render(); form.render();
// isSpecial('higherJob'); // isSpecial('higherJob');
if (info.higherJob == '1'){ if (info.higherJob == '1'){

View File

@ -113,7 +113,7 @@
</div> </div>
<div class="layui-input-inline" style="width: 20%;"> <div class="layui-input-inline" style="width: 20%;">
<label class="layui-form-label" style="width: 30%;;padding: 12px 0px">高职人员:</label> <label class="layui-form-label" style="width: 30%;padding: 12px 0px">高职人员:</label>
<select class="layui-select" id="higherJob" name="higherJob"> <select class="layui-select" id="higherJob" name="higherJob">
<option value="">--请选择是否高职人员--</option> <option value="">--请选择是否高职人员--</option>
<option value="1"></option> <option value="1"></option>
@ -148,5 +148,18 @@
<button id="importExcelYu" style="margin-bottom: 3px" onclick="importExcelYu()" class="layui-btn layui-btn-sm" ><i class="layui-icon">&#xe601;</i>导入预约</button> <button id="importExcelYu" style="margin-bottom: 3px" onclick="importExcelYu()" class="layui-btn layui-btn-sm" ><i class="layui-icon">&#xe601;</i>导入预约</button>
</div> </div>
<div class="layui-inline" style="width: 6%;margin-top: 4px">
<button id="exportBtnNew" class="layui-btn layui-btn-sm" onclick="fetchExcelNew()" ><i class="layui-icon">&#xe67d;</i>导出预约模板-新</button>
</div>
<div class="layui-inline" >
<input id="articleImageFileNew" name="excelFile" type="file" class="form-control" style="width: 200px; padding-top: 8px;margin-left: 70px;" />
<button id="importExcelNew" style="margin-bottom: 3px" onclick="importExcelNew()" class="layui-btn layui-btn-sm" ><i class="layui-icon">&#xe601;</i>导入预约-新</button>
</div>
<div class="layui-inline">
<button class="layui-btn layui-btn-sm" onclick="resetPasswordAll()" permission="sys:reset:all" ><i class="layui-icon">&#xe67d;</i>全员重置密码</button>
</div>
</div> </div>
</script> </script>