diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..b5446f5f4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,49 @@ +.git +.svn + +###################################################################### +# Build Tools + +.gradle +/build/ +!gradle/wrapper/gradle-wrapper.jar + +target/ +!.mvn/wrapper/maven-wrapper.jar + +###################################################################### +# IDE + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### JRebel ### +rebel.xml +### NetBeans ### +nbproject/private/ +build/* +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +###################################################################### +# Others +*.log +*.xml.versionsBackup +*.swp + +!*/build/*.java +!*/build/*.html +!*/build/*.xml \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..8564f294c --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2018 RuoYi + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/bin/clean.bat b/bin/clean.bat new file mode 100644 index 000000000..24c09741e --- /dev/null +++ b/bin/clean.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [信息] 清理工程target生成路径。 +echo. + +%~d0 +cd %~dp0 + +cd .. +call mvn clean + +pause \ No newline at end of file diff --git a/bin/package.bat b/bin/package.bat new file mode 100644 index 000000000..c693ec067 --- /dev/null +++ b/bin/package.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [信息] 打包Web工程,生成war/jar包文件。 +echo. + +%~d0 +cd %~dp0 + +cd .. +call mvn clean package -Dmaven.test.skip=true + +pause \ No newline at end of file diff --git a/bin/run.bat b/bin/run.bat new file mode 100644 index 000000000..41efbd0f3 --- /dev/null +++ b/bin/run.bat @@ -0,0 +1,14 @@ +@echo off +echo. +echo [信息] 使用Jar命令运行Web工程。 +echo. + +cd %~dp0 +cd ../ruoyi-admin/target + +set JAVA_OPTS=-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m + +java -jar %JAVA_OPTS% ruoyi-admin.jar + +cd bin +pause \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000..29de1868a --- /dev/null +++ b/pom.xml @@ -0,0 +1,261 @@ + + + 4.0.0 + + com.ruoyi + WorkOrder + 4.7.5 + + NJ_WorkOrder + + NJ_WorkOrder + + + 4.7.5 + UTF-8 + UTF-8 + 1.8 + 3.1.1 + 1.9.1 + 2.1.0 + 1.2.11 + 1.21 + 2.3.2 + 3.0.0 + 2.2.2 + 1.4.3 + 1.2.83 + 6.2.2 + 2.11.0 + 1.4 + 4.1.2 + 2.3 + 1.6.2 + + + + + + + + + org.springframework.boot + spring-boot-dependencies + 2.5.14 + pom + import + + + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + + + com.github.penggle + kaptcha + ${kaptcha.version} + + + + + org.apache.shiro + shiro-core + ${shiro.version} + + + + + org.apache.shiro + shiro-spring + ${shiro.version} + + + + + org.apache.shiro + shiro-ehcache + ${shiro.version} + + + + + com.github.theborakompanioni + thymeleaf-extras-shiro + ${thymeleaf.extras.shiro.version} + + + + + eu.bitwalker + UserAgentUtils + ${bitwalker.version} + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + ${mybatis-spring-boot.version} + + + + + com.github.pagehelper + pagehelper-spring-boot-starter + ${pagehelper.boot.version} + + + + + com.github.oshi + oshi-core + ${oshi.version} + + + + + io.springfox + springfox-boot-starter + ${swagger.version} + + + io.swagger + swagger-models + + + + + + + commons-io + commons-io + ${commons.io.version} + + + + + commons-fileupload + commons-fileupload + ${commons.fileupload.version} + + + + + org.apache.poi + poi-ooxml + ${poi.version} + + + + + org.apache.velocity + velocity-engine-core + ${velocity.version} + + + + + com.alibaba + fastjson + ${fastjson.version} + + + + + com.ruoyi + ruoyi-quartz + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-generator + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-framework + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-system + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-common + ${ruoyi.version} + + + + + + + ruoyi-admin + ruoyi-framework + ruoyi-system + ruoyi-quartz + ruoyi-generator + ruoyi-common + + pom + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + ${java.version} + ${java.version} + ${project.build.sourceEncoding} + + + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public + + true + + + + + + + public + aliyun nexus + https://maven.aliyun.com/repository/public + + true + + + false + + + + + \ No newline at end of file diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml new file mode 100644 index 000000000..83ca74adf --- /dev/null +++ b/ruoyi-admin/pom.xml @@ -0,0 +1,141 @@ + + + + WorkOrder + com.ruoyi + 4.7.5 + + 4.0.0 + jar + ruoyi-admin + + + web鏈嶅姟鍏ュ彛 + + + + + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + + org.springframework.boot + spring-boot-devtools + true + + + + + io.springfox + springfox-boot-starter + + + + + io.swagger + swagger-models + 1.6.2 + + + + + mysql + mysql-connector-java + + + + + com.ruoyi + ruoyi-framework + + + + + com.ruoyi + ruoyi-quartz + + + + + com.ruoyi + ruoyi-generator + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.1.1.RELEASE + + true + + + + + repackage + + + + + + org.apache.maven.plugins + maven-war-plugin + 3.0.0 + + false + ${project.artifactId} + + + + + ${project.artifactId} + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java new file mode 100644 index 000000000..ad6c2f3dd --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java @@ -0,0 +1,46 @@ +package com.ruoyi; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; + +/** + * 鍚姩绋嬪簭 + * + * @author ruoyi + */ +@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) +public class RuoYiApplication +{ + public static void main(String[] args) + { + // System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(RuoYiApplication.class, args); + System.out.println("(鈾モ棤鈥库棤)锞夛緸 Silergy 宸ヤ綔娴佸鎵圭郴缁熷惎鍔ㄦ垚鍔 醿(麓凇`醿)锞 \n" + + " \n" + + " \n" + + " SSSSSSSSSSSSSSS iiii lllllll \n" + + " SS:::::::::::::::S i::::i l:::::l \n" + + "S:::::SSSSSS::::::S iiii l:::::l \n" + + "S:::::S SSSSSSS l:::::l \n" + + "S:::::S iiiiiii l::::l eeeeeeeeeeee rrrrr rrrrrrrrr ggggggggg ggggg yyyyyyy yyyyyyy\n" + + "S:::::S i:::::i l::::l ee::::::::::::ee r::::rrr:::::::::r g:::::::::ggg::::g y:::::y y:::::y \n" + + " S::::SSSS i::::i l::::l e::::::eeeee:::::ee r:::::::::::::::::r g:::::::::::::::::g y:::::y y:::::y \n" + + " SS::::::SSSSS i::::i l::::l e::::::e e:::::e rr::::::rrrrr::::::r g::::::ggggg::::::gg y:::::y y:::::y \n" + + " SSS::::::::SS i::::i l::::l e:::::::eeeee::::::e r:::::r r:::::r g:::::g g:::::g y:::::y y:::::y \n" + + " SSSSSS::::S i::::i l::::l e:::::::::::::::::e r:::::r rrrrrrr g:::::g g:::::g y:::::y y:::::y \n" + + " S:::::S i::::i l::::l e::::::eeeeeeeeeee r:::::r g:::::g g:::::g y:::::y:::::y \n" + + " S:::::S i::::i l::::l e:::::::e r:::::r g::::::g g:::::g y:::::::::y \n" + + "SSSSSSS S:::::S i::::::i l::::::l e::::::::e r:::::r g:::::::ggggg:::::g y:::::::y \n" + + "S::::::SSSSSS:::::S i::::::i l::::::l e::::::::eeeeeeee r:::::r g::::::::::::::::g y:::::y \n" + + "S:::::::::::::::SS i::::::i l::::::l ee:::::::::::::e r:::::r gg::::::::::::::g y:::::y \n" + + " SSSSSSSSSSSSSSS iiiiiiii llllllll eeeeeeeeeeeeee rrrrrrr gggggggg::::::g y:::::y \n" + + " g:::::g y:::::y \n" + + " gggggg g:::::g y:::::y \n" + + " g:::::gg gg:::::g y:::::y \n" + + " g::::::ggg:::::::g y:::::y \n" + + " gg:::::::::::::g yyyyyyy \n" + + " ggg::::::ggg \n" + + " gggggg "); + } +} \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiServletInitializer.java b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiServletInitializer.java new file mode 100644 index 000000000..6de67dc76 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiServletInitializer.java @@ -0,0 +1,18 @@ +package com.ruoyi; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +/** + * web瀹瑰櫒涓繘琛岄儴缃 + * + * @author ruoyi + */ +public class RuoYiServletInitializer extends SpringBootServletInitializer +{ + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) + { + return application.sources(RuoYiApplication.class); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/PaymentRequestApi.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/PaymentRequestApi.java new file mode 100644 index 000000000..7e26160e7 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/PaymentRequestApi.java @@ -0,0 +1,532 @@ +package com.ruoyi.web.controller.api; + + +import com.alibaba.fastjson.JSON; + +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.constant.FormFileConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.enums.OrderTypes; +import com.ruoyi.common.exception.GlobalException; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.file.FileUploadUtils; +import com.ruoyi.common.utils.file.MimeTypeUtils; +import com.ruoyi.framework.jwt.utils.JwtUtils; +import com.ruoyi.system.component.paymentRequest.PaymentRequestComponentApp; +import com.ruoyi.system.domain.FormFile; +import com.ruoyi.system.domain.PaymentAccount; +import com.ruoyi.system.domain.ProcessFlow; +import com.ruoyi.system.domain.paymentRequest.PaymentAuditResults; +import com.ruoyi.system.domain.paymentRequest.PaymentRequest; +import com.ruoyi.system.domain.paymentRequest.PaymentRequestDt1; +import com.ruoyi.system.service.IFormFileService; +import com.ruoyi.system.service.IPaymentAccountService; +import com.ruoyi.system.service.IProcessFlowService; +import com.ruoyi.system.service.ISysUserService; +import com.ruoyi.system.service.paymentRequest.IPaymentRequestDt1Service; +import com.ruoyi.system.service.paymentRequest.IPaymentRequestService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import java.util.*; +import java.util.stream.Collectors; + + +@Controller +@RequestMapping("/api/paymentRequest") +public class PaymentRequestApi extends BaseController { + + private static final Logger log = LoggerFactory.getLogger(PaymentRequestApi.class); + + private String prefix = "system/paymentRequest"; + + @Autowired + private ISysUserService userService; + + @Autowired + private PaymentRequestComponentApp paymentRequestComponentApp; + + @Autowired + private IPaymentRequestService paymentRequestService; + + @Autowired + private IProcessFlowService processFlowService; + + @Autowired + private IPaymentRequestDt1Service paymentRequestDt1Service; + + @Autowired + private IFormFileService formFileService; + + @Autowired + private IPaymentAccountService paymentAccountService; + /** + * 鍒楄〃鏌ヨ + * @param infos 淇℃伅 + * @param sid 鎿嶄綔鐢ㄦ埛 + * @param token 浠ょ墝 + * @return + */ + @Log(title = "璇锋鍗旳PI鍒楄〃鏌ヨ", businessType = BusinessType.OTHER) + @RequestMapping("/page") + @ResponseBody + public AjaxResult paymentRequestPage(@RequestParam(name="infos")String infos, + @RequestParam(name="sid")String sid, + @RequestParam(name="token")String token) { +// if (!TokenUtil.verifyToken(token)) { +// return error(-1, "韬唤淇℃伅杩囨湡锛岃鑱旂郴IT浜哄憳銆"); +// } + + log.info("璇锋鍗旳PP鍒楄〃鏌ヨ鎺ュ彛infos鏁版嵁------>{},sid鏁版嵁------>{}", infos, sid); + Map apiParameter = JSON.parseObject(infos, Map.class); + if (StringUtils.isNull(apiParameter)) { + log.error("璇锋鍗旳PP鍒楄〃鏌ヨ鎺ュ彛鍑洪敊锛屾湭鑾峰彇鍒版纭甶nfos鏁版嵁锛岄棶棰榠nfos------>{}", infos); + return error(-1, "鏌ヨ鍒楄〃淇℃伅鍑洪敊锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + SysUser user = userService.selectUserByUserCode(sid); + if (StringUtils.isNull(user)) { + log.error("璇锋鍗旳PP鍒楄〃鏌ヨ鎺ュ彛鍑洪敊锛屾湭鑾峰彇鍒版纭殑鐢ㄦ埛鏍囪瘑锛岄棶棰樼敤鎴锋爣璇------>{}", sid); + return error(-1, "鑾峰彇鐧诲綍鐢ㄦ埛淇℃伅澶辫触锛岃閲嶆柊鐧诲綍鎴栬仈绯籌T浜哄憳銆"); + } + PaymentRequest paymentRequest = new PaymentRequest(); + List resList = new ArrayList<>(); + if(Objects.equals(apiParameter.get("type").toString(),"1")){ + //璇存槑鏄垪琛 + //鎷ユ湁FinanceAudit瑙掕壊\鑰佹籠绠$悊鍛樻煡鐪嬫墍鏈 + List roles = user.getRoles().stream().filter(r -> r.getRoleKey().equals("FinanceAudit")).collect(Collectors.toList()); + if (user.isAdmin() || StringUtils.isNotEmpty(roles) || + user.getUserCode().contains("S00001") || + user.getUserCode().contains("S00002") || + user.getUserCode().contains("S00003")) { + + }else { + //鍙兘鏌ョ湅鑷繁鐨 + paymentRequest.setEmployeeNo(sid); +// paymentRequest.setDept(user.getDept().getDeptName().trim()); + } + resList = paymentRequestService.selectPaymentRequestList(paymentRequest); + }else if(Objects.equals(apiParameter.get("type").toString(),"2")){ + //璇存槑鏄垜鐨勫緟鍔 + if (!user.isAdmin()) { + paymentRequest.setSendToCode(sid); + } +// startPage(); + resList = paymentRequestService.selectPaymentRequestList(paymentRequest); + }else if(Objects.equals(apiParameter.get("type").toString(),"3")){ + //璇存槑鏄垜鐨勫凡鍔 +// startPage(); + paymentRequest.setHandlesCode(sid); + resList = paymentRequestService.selectPaymentRequestList(paymentRequest); + } + return AjaxResult.success("S",resList); + } + + /** + * 绉诲姩绔柊澧炶娆 + * @param infos 璇锋鍗曟暟鎹 + * @param file0 鏂囦欢1 + * @param file1 鏂囦欢2 + * @param file2 鏂囦欢3 + * @param file3 鏂囦欢4 + * @param operationType 鎿嶄綔绫诲瀷, 1-淇濆瓨, 2-鎻愪氦 + * @param sid 鍛樺伐缂栧彿 + * @param token 浠ょ墝 + * @return 缁撴灉 + */ + @Log(title = "璇锋鍗旳PI鏂板", businessType = BusinessType.INSERT) + @PostMapping("/add/{operationType}") + @ResponseBody + @Transactional(rollbackFor = Exception.class) + public AjaxResult addPaymentRequestSave(@RequestParam(name="infos")String infos, + @RequestParam(name = "file0", required = false) MultipartFile file0, + @RequestParam(name = "file1", required = false) MultipartFile file1, + @RequestParam(name = "file2", required = false) MultipartFile file2, + @RequestParam(name = "file3", required = false) MultipartFile file3, + @PathVariable(name = "operationType", required = false) String operationType, + @RequestParam(name="sid")String sid, + @RequestParam(name="token")String token) { +// if (!TokenUtil.verifyToken(token)) { +// return error(-1, "韬唤淇℃伅杩囨湡锛岃鑱旂郴IT浜哄憳銆"); +// } + PaymentRequest paymentRequest = JSON.parseObject(infos, PaymentRequest.class); + if (StringUtils.isNull(paymentRequest)) { + log.error("璇锋鍗旳PP鏂板鎺ュ彛鍑洪敊锛屾湭鑾峰彇鍒版纭甶nfos鏁版嵁锛岄棶棰榠nfos------>{}", infos); + return error(-1, "鏂板璇锋鍗曞嚭閿欙紝璇风◢鍚庨噸璇曟垨鑱旂郴IT浜哄憳銆"); + } + SysUser user = userService.selectUserByUserCode(sid); + if (StringUtils.isNull(user)) { + log.error("璇锋鍗旳PP鏂板鎺ュ彛鍑洪敊锛屾湭鑾峰彇鍒版纭殑鐢ㄦ埛鏍囪瘑锛岄棶棰樼敤鎴锋爣璇------>{}", sid); + return error(-1, "鑾峰彇鐧诲綍鐢ㄦ埛淇℃伅澶辫触锛岃閲嶆柊鐧诲綍鎴栬仈绯籌T浜哄憳銆"); + } + String msg = paymentRequestComponentApp.insertCheck(paymentRequest); + if (StringUtils.isNotEmpty(msg)) { + return error(-1, msg); + } + paymentRequest.setApplicant(user.getUserName()); + paymentRequest.setEmployeeNo(user.getUserCode()); + paymentRequest.setDept(user.getDept().getDeptName()); + paymentRequest.setDeptCode(user.getDepartmentCode()); + AjaxResult ajaxResult; + try { + ajaxResult = paymentRequestService.insertPaymentRequest(paymentRequest, user); + //鏂囦欢涓婁紶 + List files = new ArrayList<>(); + if (StringUtils.isNotNull(file0)){ + files.add(file0); + } + if (StringUtils.isNotNull(file1)){ + files.add(file1); + } + if (StringUtils.isNotNull(file2)){ + files.add(file2); + } + if (StringUtils.isNotNull(file3)){ + files.add(file3); + } + if (StringUtils.isNotEmpty(files)){ +// for (MultipartFile file:files) { +// String filePath = RuoYiConfig.getUploadPath(); +// String fileNameRes = file.getOriginalFilename().replaceAll(" ","").replaceAll("&",""); +// String suffix = fileNameRes.substring(fileNameRes.lastIndexOf(".")); +// String filePath1 = FileUploadUtils.upload(filePath, file, suffix); +// PaymentRequestFile paymentRequestFile = new PaymentRequestFile(); +// paymentRequestFile.setAssociationId(ajaxResult.get("data")); +// paymentRequestFile.setType(1); +// paymentRequestFile.setFile(filePath1); +// paymentRequestFile.setFileName(fileNameRes); +// paymentRequestFile.setCreateTime(new Date()); +// paymentRequestFileService.insertPaymentRequestFile(paymentRequestFile); +// } + } + if (Objects.equals(operationType, "2")) { + //杩涜鎻愪氦 + paymentRequestService.submitProcess((Long) ajaxResult.get("data"), user); + } + } catch (Exception e) { + log.error("璇锋鍗旳PP鏂板鎺ュ彛鎻愪氦鍑洪敊", e); + return error(-1, "鎻愪氦鍑洪敊锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + return success(ajaxResult.get("data").toString()); + } + + /** + * APP璇︽儏(鍖呭惈瀹℃牳椤甸潰璇︽儏) + * @param id + * @param type + * @param sid + * @param token + * @return + */ + @RequestMapping(value = "/detail/{id}/{type}") + @ResponseBody + public AjaxResult paymentRequestDetail(@PathVariable("id") Long id, + @PathVariable("type") Integer type, + @RequestParam(name="sid")String sid, + @RequestParam(name="token")String token) + { +// if (!TokenUtil.verifyToken(token)) { +// return error(-1, "韬唤淇℃伅杩囨湡锛岃鑱旂郴IT浜哄憳銆"); +// } + SysUser user = userService.selectUserByUserCode(sid); + if (StringUtils.isNull(user)) { + log.error("璇锋鍗旳PP璇︽儏鎺ュ彛鍑洪敊锛屾湭鑾峰彇鍒版纭殑鐢ㄦ埛鏍囪瘑锛岄棶棰樼敤鎴锋爣璇------>{}", sid); + return error(-1, "鑾峰彇鐧诲綍鐢ㄦ埛淇℃伅澶辫触锛岃閲嶆柊鐧诲綍鎴栬仈绯籌T浜哄憳銆"); + } + Map map = new HashMap<>(); + try { + PaymentRequest paymentRequest = paymentRequestService.selectPaymentRequestById(id); + if (StringUtils.isNull(paymentRequest)){ + log.error("璇锋鍗旳PP璇︽儏鎺ュ彛鍑洪敊锛屾湭鏌ヨ鍒颁富鏁版嵁淇℃伅锛岄棶棰業D------>{}",id); + throw new GlobalException("鑾峰彇璇锋鍗曚富鏁版嵁鍑洪敊锛"); + } + map.put("paymentRequest", paymentRequest); + PaymentRequestDt1 paymentRequestDt1 = new PaymentRequestDt1(); + paymentRequestDt1.setRequestId(id); + List paymentRequestDt1List = paymentRequestDt1Service.selectPaymentRequestDt1List(paymentRequestDt1); + map.put("paymentRequestDt1List", paymentRequestDt1List); + ProcessFlow processFlow = new ProcessFlow(); + processFlow.setOrderId(id); + processFlow.setOrderType(OrderTypes.PAYMENT_REQUEST.getCode()); + List lists = processFlowService.selectProcessFlowListByOrderId(id,OrderTypes.PAYMENT_REQUEST.getCode()); + map.put("lists", lists); + FormFile formFile = new FormFile(); + formFile.setFileType(FormFileConstants.PAYMENTREQUEST); + formFile.setParentId(id); + List formFiles = formFileService.selectFormFileList(formFile); + map.put("listFile", formFiles); + //璇︽儏椤靛姛鑳芥帶鍒 + Map resultMap = paymentRequestComponentApp.editableArea(paymentRequest, user, type); + map.put("event", resultMap); + }catch (Exception e){ + log.error("璇锋鍗旳PP璇︽儏鎺ュ彛鍑洪敊锛岃幏鍙栬鎯呬俊鎭椂鍑洪敊------>{}", e); + return error(-1, "鑾峰彇璇︽儏鍑洪敊锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + return AjaxResult.success("S",map); + } + + /** + * 瀹℃牳鎻愪氦 + * @param infos 瀹℃牳淇℃伅 + * @param sid 鎿嶄綔鐢ㄦ埛 + * @param token 浠ょ墝 + * @return + */ + @Log(title = "璇锋鍗旳PI瀹℃牳鎻愪氦", businessType = BusinessType.UPDATE) + @RequestMapping("/auditSubmit") + @ResponseBody + public AjaxResult requisitionSubmit1(@RequestParam(name="infos")String infos, + @RequestParam(name="sid")String sid, + @RequestParam(name="token")String token) + { +// if(!TokenUtil.verifyToken(token)) { +// return error(-1, "韬唤淇℃伅杩囨湡锛岃鑱旂郴IT浜哄憳銆"); +// } + log.info("璇锋鍗曞鏍告彁浜PI 琛ㄥ崟鏁版嵁------>{},鎿嶄綔浜------>{}",infos,sid); + try { + //瑙f瀽鏁版嵁 + PaymentAuditResults auditResults = JSON.parseObject(infos, PaymentAuditResults.class); + PaymentRequest paymentRequestRes = paymentRequestService.selectPaymentRequestById(auditResults.getPaymentRequestId()); + SysUser userRes = userService.selectUserByUserCode(sid); + if(!paymentRequestRes.getSendToCode().contains(userRes.getUserCode()) && !userRes.isAdmin()){ + return error(-1,"宸茬粡绛炬牳瀹屾垚锛岃绛炬牳涓嬩竴鍗"); + } + paymentRequestService.auditSubmit(auditResults, userRes, paymentRequestRes); + } catch (GlobalException e){ + return error(-1, e.getMessage()); + } catch (Exception e){ + log.error("璇锋鍗曞鏍告彁浜PI鍑洪敊锛侀敊璇------>{}",e); + return error(-1,"鎻愪氦澶辫触锛岃杩斿洖閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + return AjaxResult.success("Success","鎿嶄綔鎴愬姛"); + } + + /** + * 鎵归噺瀹℃牳 + * @param infos + * @param sid + * @param token + * @return + */ + @Log(title = "璇锋鍗旳PI鎵归噺瀹℃牳", businessType = BusinessType.UPDATE) + @PostMapping("/batchReview") + @ResponseBody + public AjaxResult batchReview(@RequestParam(name="infos")String infos, + @RequestParam(name="sid")String sid, + @RequestParam(name="token")String token){ +// if(!TokenUtil.verifyToken(token)) { +// return error(-1, "韬唤淇℃伅杩囨湡锛岃鑱旂郴IT浜哄憳銆"); +// } + long startTime = System.currentTimeMillis(); // 寮濮嬫椂闂 + log.info("璇锋鍗曟壒閲忓鏍窤PI 琛ㄥ崟鏁版嵁------>{},鎿嶄綔浜------>{}",infos,sid); + String s = ""; + try { + //瑙f瀽鏁版嵁 + PaymentAuditResults auditResults = JSON.parseObject(infos, PaymentAuditResults.class); + SysUser userRes = userService.selectUserByUserCode(sid); + s = paymentRequestService.paymentRequestBatchReview(auditResults, userRes); + } catch (GlobalException e){ + return error(-1, e.getMessage()); + } catch (Exception e){ + log.error("璇锋鍗曟壒閲忓鏍窤PI鍑洪敊锛侀敊璇------>{}",e); + return error(-1,"鎻愪氦澶辫触锛岃杩斿洖閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + + long endTime = System.currentTimeMillis(); // 鎵ц瀹屾椂闂 + log.info("APP鎵归噺瀹℃牳鑺辫垂鏃堕棿 timecost=[{}]ms;",(endTime - startTime)); // 璁$畻鏃堕棿宸 + return AjaxResult.success("Success",s.replaceAll("
","\n")); + } + + + + /** + * 鑾峰彇琛ㄥ崟涓嬫媺妗嗕俊鎭 + * + * @return + */ + @RequestMapping("/getSelectInformation") + @ResponseBody + public AjaxResult getSelectInformation(){ +// if (!TokenUtil.verifyToken(token)) { +// return error(-1, "韬唤淇℃伅杩囨湡锛岃鑱旂郴IT浜哄憳銆"); +// } + Map map = paymentRequestComponentApp.selectInformation(); + return AjaxResult.success("success",map); + } + + /** + * 涓婁紶闄勪欢 + * + * @param multipartFiles + * @return + */ + @Log(title = "璇锋鍗旳PI涓婁紶闄勪欢", businessType = BusinessType.INSERT) + @PostMapping(value = "/file/upload") + @ResponseBody + public AjaxResult uploadFile1(@RequestParam("file") MultipartFile multipartFiles) + { + if (multipartFiles == null) { + return error(8, "鏂囦欢涓虹┖銆"); + } + Map map = new HashMap<>(); + try { + // 涓婁紶鏂囦欢璺緞 + String filePath = RuoYiConfig.getUploadPath(); + // 涓婁紶骞惰繑鍥炴柊鏂囦欢鍚嶇О + String fileNameRes = multipartFiles.getOriginalFilename().replaceAll(" ", "").replaceAll("&", ""); + String suffix = fileNameRes.substring(fileNameRes.lastIndexOf(".")); + String fileName = FileUploadUtils.uploads(filePath, multipartFiles, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + String url = fileName; + map.put("fileName", fileNameRes); + map.put("filePath", url); + } catch (Exception e) { + return AjaxResult.error(e.getMessage()); + } + return AjaxResult.success("success", map); + } + + /** + * 鍒犻櫎璇锋鍗 + * @param infos + * @return + */ + @Log(title = "璇锋鍗旳PI鍒犻櫎", businessType = BusinessType.DELETE) + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(@RequestParam(name = "infos") String infos, @RequestParam(name = "token") String token) { +// if (!TokenUtil.verifyToken(token)) { +// return error(-1, "韬唤淇℃伅杩囨湡锛岃鑱旂郴IT浜哄憳銆"); +// } + String ids; + try { + HashMap map = JSON.parseObject(infos, HashMap.class); + ids = (String) map.get("ids"); + if (StringUtils.isEmpty(ids)) { + throw new GlobalException("鍒犻櫎澶辫触锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + paymentRequestService.deletePaymentRequestByIds(ids); + return success(); + } catch (GlobalException businessException) { + log.error("璇锋鍗曞垹闄PI鍑洪敊锛侀敊璇師鍥------>", businessException.getMessage()); + return error(-1, businessException.getMessage()); + } catch (Exception exception) { + log.error("璇锋鍗曞垹闄PI鍑洪敊锛侀敊璇師鍥------>", exception); + return error(-1, "鍒犻櫎澶辫触锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + } + + + /** + * 璇锋鍗曟挙鍥 + * @param infos 璇锋鍗曚俊鎭 + * @param token token + * @return + */ + @Log(title = "璇锋鍗旳PI鎾ゅ洖", businessType = BusinessType.UPDATE) + @PostMapping("/withdrawal") + @ResponseBody + public AjaxResult Withdrawal(@RequestParam(name = "infos") String infos, @RequestParam(name = "token") String token) { +// if (!TokenUtil.verifyToken(token)) { +// return error(-1, "韬唤淇℃伅杩囨湡锛岃鑱旂郴IT浜哄憳銆"); +// } + Long id; + try { + HashMap map = JSON.parseObject(infos, HashMap.class); + id = Long.valueOf((String)map.get("id")); + if (StringUtils.isNull(id)) { + throw new GlobalException("鎾ゅ洖澶辫触锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + paymentRequestService.WithdrawalOfInitiation(id); + return success(); + } catch (GlobalException businessException) { + return error(businessException.getMessage()); + } catch (Exception e) { + log.error("璇锋鍗曟挙鍥濧PI鍑洪敊锛侀敊璇師鍥------>", e); + return error(-1, "鎿嶄綔澶辫触锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + } + + /** + * 璇锋鍗曠紪杈 + * @param infos 璇锋鍗曚俊鎭 + * @param operationType 鎿嶄綔绫诲瀷 1-淇濆瓨, 2-鎻愪氦 + * @param sid 鍛樺伐缂栧彿 + * @param token 浠ょ墝 + * @return 缁撴灉 + */ + @Log(title = "璇锋鍗旳PI缂栬緫", businessType = BusinessType.UPDATE) + @PostMapping("/edit/{operationType}") + @ResponseBody + public AjaxResult editSave(@RequestParam(name = "infos") String infos, + @PathVariable(name = "operationType", required = false) String operationType, + @RequestParam(name="sid")String sid, + @RequestParam(name = "token") String token) { +// if (!TokenUtil.verifyToken(token)) { +// return error(-1, "韬唤淇℃伅杩囨湡锛岃鑱旂郴IT浜哄憳銆"); +// } + PaymentRequest paymentRequest = JSON.parseObject(infos, PaymentRequest.class); + if (StringUtils.isNull(paymentRequest)) { + log.error("璇锋鍗旳PP缂栬緫鎺ュ彛鍑洪敊锛屾湭鑾峰彇鍒版纭甶nfos鏁版嵁锛岄棶棰榠nfos------>{}", infos); + return error(-1, "鎿嶄綔澶辫触锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + SysUser user = userService.selectUserByUserCode(sid); + if (StringUtils.isNull(user)) { + log.error("璇锋鍗旳PP缂栬緫鎺ュ彛鍑洪敊锛屾湭鑾峰彇鍒版纭殑鐢ㄦ埛鏍囪瘑锛岄棶棰樼敤鎴锋爣璇------>{}", sid); + return error(-1, "鑾峰彇鐧诲綍鐢ㄦ埛淇℃伅澶辫触锛岃閲嶆柊鐧诲綍鎴栬仈绯籌T浜哄憳銆"); + } + String msg = paymentRequestComponentApp.insertCheck(paymentRequest); + if (StringUtils.isNotEmpty(msg)) { + return error(-1, msg); + } + Long paymentRequestId; + try { + AjaxResult ajaxResult = paymentRequestService.updatePaymentRequest(paymentRequest); + if (Objects.equals(operationType, "2")) { + //杩涜鎻愪氦 + paymentRequestService.submitProcess((Long) ajaxResult.get("data"), user); + } + return success(); + } catch (GlobalException businessException) { + return error(businessException.getMessage()); + } catch (Exception e) { + log.error("璇锋鍗曠紪杈慉PI鍑洪敊锛侀敊璇師鍥------>", e); + return error(-1, "鎿嶄綔澶辫触锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + } + + + /** + * 璇锋鍗曞巻鍙蹭粯娆句俊鎭 + * @param sid 鐢ㄦ埛id + * @param token 浠ょ墝 + * @return + */ + @RequestMapping("/payAccountHistory") + @ResponseBody + public AjaxResult payAccountHistory(@RequestParam(name="sid")String sid, + @RequestParam(name="token")String token) { +// if(!TokenUtil.verifyToken(token)) { +// return error(-1, "韬唤淇℃伅杩囨湡锛岃鑱旂郴IT浜哄憳銆"); +// } + Map mmap = new HashMap<>(); + SysUser user = userService.selectUserByLoginName(sid); + if (StringUtils.isNull(user)) { + log.error("璇锋鍗旳PP鍒楄〃鏌ヨ鎺ュ彛鍑洪敊锛屾湭鑾峰彇鍒版纭殑鐢ㄦ埛鏍囪瘑锛岄棶棰樼敤鎴锋爣璇------>{}", sid); + return error(-1, "鑾峰彇鐧诲綍鐢ㄦ埛淇℃伅澶辫触锛岃閲嶆柊鐧诲綍鎴栬仈绯籌T浜哄憳銆"); + } + PaymentAccount paymentAccount = new PaymentAccount(); + paymentAccount.setCreateBy(user.getUserCode()); + //鍘嗗彶浠樻璐﹀彿淇℃伅 + mmap.put("payeeList", paymentAccountService.selectPaymentAccountList(paymentAccount)); + return AjaxResult.success("S",mmap); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/RequisitionAppApi.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/RequisitionAppApi.java new file mode 100644 index 000000000..c47cb554c --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/RequisitionAppApi.java @@ -0,0 +1,618 @@ +package com.ruoyi.web.controller.api; + +import com.alibaba.fastjson.JSON; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.enums.OrderTypes; +import com.ruoyi.common.enums.RequisitionStatus; +import com.ruoyi.common.exception.GlobalException; +import com.ruoyi.common.utils.CacheUtils; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.file.FileUploadUtils; +import com.ruoyi.common.utils.file.MimeTypeUtils; +import com.ruoyi.system.component.requisition.RequisitionComponent; +import com.ruoyi.system.component.requisition.RequisitionComponentApp; +import com.ruoyi.system.domain.FormFile; +import com.ruoyi.system.domain.ProcessFlow; +import com.ruoyi.system.domain.requisition.Requisition; +import com.ruoyi.system.domain.requisition.RequisitionAuditResults; +import com.ruoyi.system.dto.requisition.RequisitionDto; +import com.ruoyi.system.service.IFormFileService; +import com.ruoyi.system.service.IProcessFlowService; +import com.ruoyi.system.service.ISysUserService; +import com.ruoyi.system.service.requisition.IRequisitionService; +import com.ruoyi.web.controller.common.CommonController; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.util.*; + + +@Controller +@RequestMapping("/api/requisition") +public class RequisitionAppApi extends BaseController +{ + + protected final Logger log = LoggerFactory.getLogger(this.getClass()); + + private String prefix = "system/requisition"; + + @Autowired + private IRequisitionService requisitionService; + + @Autowired + private IProcessFlowService processFlowService; + + @Autowired + private ISysUserService userService; + + @Autowired + private RequisitionComponentApp requisitionComponentApp; + + @Autowired + private IFormFileService formFileService; + + @Autowired + private CommonController commonController; + + /** + * 鑾峰彇琛ㄥ崟涓嬫媺妗嗕俊鎭 + * + * @param token + * @return + */ + @RequestMapping("/getSelectInformation") + @ResponseBody + public AjaxResult getSelectInformation(@RequestParam(name = "token") String token) + { + /*if (!JwtUtils.verify(token)) { + return error(-1, "韬唤淇℃伅杩囨湡锛岃鑱旂郴IT浜哄憳銆"); + }*/ + Map map = requisitionComponentApp.selectInformation(); + return AjaxResult.success("success", map); + } + + /** + * 鑾峰彇渚涘簲鍟嗕俊鎭 + * + * @return + */ + @RequestMapping("/getCodeName") + @ResponseBody + public AjaxResult getCodeName(@RequestParam(name = "token") String token) + { + + return AjaxResult.success("success", CacheUtils.get(Constants.SYS_SUPPLIER_CACHE, Constants.SYS_SUPPLIER_KEY)); + } + + /** + * 浜哄憳涓嬫媺鎺ュ彛 + * + * @param userName + * @return + */ + @RequestMapping(value = "/user/search") + @ResponseBody + public AjaxResult userSearch(@RequestParam(name = "userName", required = false) String userName) + { + return AjaxResult.success("success", null); + } + + /** + * 璇疯喘鍗曟柊澧 + * + * @param infos 璇疯喘鍗曚俊鎭 + * @param file0 鏂囦欢1 + * @param file1 鏂囦欢2 + * @param file2 鏂囦欢3 + * @param file3 鏂囦欢4 + * @param operationType 鎿嶄綔绫诲瀷 + * @param sid 鍛樺伐缂栧彿 + * @param token 浠ょ墝 + * @return 缁撴灉 + */ + @Log(title = "璇疯喘鍗旳PI鏂板", businessType = BusinessType.INSERT) + @RequestMapping("/add/{operationType}") + @ResponseBody + @Transactional(rollbackFor = Exception.class) + public AjaxResult addSave(@RequestParam(name = "infos") String infos, + @RequestParam(name = "file0", required = false) MultipartFile file0, + @RequestParam(name = "file1", required = false) MultipartFile file1, + @RequestParam(name = "file2", required = false) MultipartFile file2, + @RequestParam(name = "file3", required = false) MultipartFile file3, + @PathVariable(name = "operationType", required = false) String operationType, + @RequestParam(name = "sid") String sid, + @RequestParam(name = "token") String token) + { + log.info("璇疯喘鍗旳PP鏂板鎺ュ彛infos鏁版嵁------>{},sid鏁版嵁------>{}", infos, sid); + SysUser user = userService.selectUserByLoginName(sid); + if (StringUtils.isNull(user)) { + log.error("璇疯喘鍗旳PP鏂板鎺ュ彛鍑洪敊锛屾湭鑾峰彇鍒版纭殑鐢ㄦ埛鏍囪瘑锛岄棶棰樼敤鎴锋爣璇------>{}", sid); + return error(-1, "鑾峰彇鐧诲綍鐢ㄦ埛淇℃伅澶辫触锛岃閲嶆柊鐧诲綍鎴栬仈绯籌T浜哄憳銆"); + } + RequisitionDto requisitionDto = JSON.parseObject(infos, RequisitionDto.class); + if (StringUtils.isNull(requisitionDto)) { + log.error("璇疯喘鍗旳PP鏂板鎺ュ彛鍑洪敊锛屾湭鑾峰彇鍒版纭甶nfos鏁版嵁锛岄棶棰榠nfos------>{}", infos); + return error(-1, "鏂板璇疯喘鍗曞嚭閿欙紝璇风◢鍚庨噸璇曟垨鑱旂郴IT浜哄憳銆"); + } + String msg = requisitionComponentApp.insertCheck(requisitionDto); + if (StringUtils.isNotEmpty(msg)) { + return error(-1, msg); + } + requisitionDto.getRequisition().setCreateBy(user.getUserName()); + requisitionDto.getRequisition().setCreateByCode(user.getUserCode()); + requisitionDto.getRequisition().setStatus(RequisitionStatus.SAVE.getCode()); + requisitionDto.getRequisition().setCreateTime(DateUtils.getNowDate()); + requisitionDto.getRequisition().setUpdateTime(DateUtils.getNowDate()); + requisitionDto.getRequisition().setUserDepartment(user.getDept().getDeptName()); + requisitionDto.getRequisition().setUserName(user.getUserName()); + requisitionDto.getRequisition().setOffice(user.getOffices()); + requisitionDto.getRequisition().setSendToCode(user.getUserCode()); + Long requisitionId; + try { + Requisition requisition = requisitionDto.getRequisition(); + requisition.setRequisitionDt1List(requisitionDto.getRequisitionDt1s()); + requisition.setRequisitionDt2List(requisitionDto.getRequisitionDt2s()); + requisitionId = requisitionService.insertRequisition(requisitionDto.getRequisition(), user); + //鏂囦欢涓婁紶 + List files = new ArrayList<>(); + if (StringUtils.isNotNull(file0)) { + files.add(file0); + } + if (StringUtils.isNotNull(file1)) { + files.add(file1); + } + if (StringUtils.isNotNull(file2)) { + files.add(file2); + } + if (StringUtils.isNotNull(file3)) { + files.add(file3); + } + //鏂囦欢涓婁紶鐩稿叧 + /*if (StringUtils.isNotEmpty(files)){ + for (MultipartFile file:files) { + String filePath = RuoYiConfig.getUploadPath(); + String fileNameRes = file.getOriginalFilename().replaceAll(" ","").replaceAll("&",""); + String suffix = fileNameRes.substring(fileNameRes.lastIndexOf(".")); + String filePath1 = FileUploadUtils.upload(filePath, file, suffix); + RequisitionFile requisitionFile = new RequisitionFile(); + requisitionFile.setAssociationId(requisitionId); + requisitionFile.setType(1); + requisitionFile.setFile(filePath1); + requisitionFile.setFileName(fileNameRes); + requisitionFileService.insertRequisitionFile(requisitionFile); + } + }*/ + if (Objects.equals(operationType, "2")) { + requisitionService.submit(requisitionId, user); + } + } catch (GlobalException e) { + log.error("璇疯喘鍗旳PP鏂板鎺ュ彛鎻愪氦鍑洪敊--->", e); + return error(-1, "鎻愪氦鍑洪敊锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } catch (Exception e) { + log.error("璇疯喘鍗旳PP鏂板鎺ュ彛鎻愪氦鍑洪敊", e); + return error(-1, "鎻愪氦鍑洪敊锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + return AjaxResult.success("success", requisitionId); + } + + /** + * 璇疯喘鍗曞垪琛 + * + * @param infos + * @param sid + * @param token + * @return + */ + @Log(title = "璇疯喘鍗旳PI鍒楄〃鏌ヨ", businessType = BusinessType.OTHER) + @RequestMapping("/page") + @ResponseBody + public AjaxResult page(@RequestParam(name = "infos") String infos, + @RequestParam(name = "sid") String sid, + @RequestParam(name = "token") String token) + { + log.info("璇疯喘鍗旳PP鍒楄〃鏌ヨ鎺ュ彛infos鏁版嵁------>{},sid鏁版嵁------>{}", infos, sid); + Map apiParameter = JSON.parseObject(infos, Map.class); + if (StringUtils.isNull(apiParameter)) { + log.error("璇疯喘鍗旳PP鍒楄〃鏌ヨ鎺ュ彛鍑洪敊锛屾湭鑾峰彇鍒版纭甶nfos鏁版嵁锛岄棶棰榠nfos------>{}", infos); + return error(-1, "鏌ヨ鍒楄〃淇℃伅鍑洪敊锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + SysUser user = userService.selectUserByUserCode(sid); + if (StringUtils.isNull(user)) { + log.error("璇疯喘鍗旳PP鍒楄〃鏌ヨ鎺ュ彛鍑洪敊锛屾湭鑾峰彇鍒版纭殑鐢ㄦ埛鏍囪瘑锛岄棶棰樼敤鎴锋爣璇------>{}", sid); + return error(-1, "鑾峰彇鐧诲綍鐢ㄦ埛淇℃伅澶辫触锛岃閲嶆柊鐧诲綍鎴栬仈绯籌T浜哄憳銆"); + } + Requisition requisition = new Requisition(); + List resList = null; + if (Objects.equals(apiParameter.get("type").toString(), "1")) { + //璇存槑鏄垪琛 + requisition.setEmployeeNo(user.getUserCode()); + resList = requisitionService.selectRequisitionList(requisition); + } else if (Objects.equals(apiParameter.get("type").toString(), "2")) { + //璇存槑鏄垜鐨勫緟鍔 + if (!user.isAdmin()) { + requisition.setSendToCode(sid); + } + resList = requisitionService.selectRequisitionList(requisition); + } else if (Objects.equals(apiParameter.get("type").toString(), "3")) { + //璇存槑鏄垜鐨勫凡鍔 + requisition.setHandlesCode(sid); + resList = requisitionService.selectRequisitionList(requisition); + } else { + return error(-1, "鏌ヨ鍒楄〃淇℃伅鍑洪敊锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + return AjaxResult.success("success", resList); + } + + /** + * APP璇︽儏(鍖呭惈瀹℃牳椤甸潰璇︽儏) + * + * @param id 璇疯喘鍗昳d + * @param type 鍒楄〃绫诲瀷(1.绫诲埆 2.寰呭姙 3.宸插姙) + * @param sid 澶勭悊浜篶ode + * @param token + * @return + */ + @RequestMapping(value = "/detail/{id}/{type}") + @ResponseBody + public AjaxResult deatil(@PathVariable("id") Long id, + @PathVariable("type") Integer type, + @RequestParam(name = "sid") String sid, + @RequestParam(name = "token") String token) + { + SysUser user = userService.selectUserByUserCode(sid); + if (StringUtils.isNull(user)) { + log.error("璇疯喘鍗旳PP璇︽儏鎺ュ彛鍑洪敊锛屾湭鑾峰彇鍒版纭殑鐢ㄦ埛鏍囪瘑锛岄棶棰樼敤鎴锋爣璇------>{}", sid); + return error(-1, "鑾峰彇鐧诲綍鐢ㄦ埛淇℃伅澶辫触锛岃閲嶆柊鐧诲綍鎴栬仈绯籌T浜哄憳銆"); + } + Map map = new HashMap<>(); + try { + Requisition requisition = requisitionService.selectRequisitionById(id); + if (StringUtils.isNotEmpty(requisition.getTotalAmount())) { + requisition.setRemark(requisition.getTotalAmount()); + } + map.put("requisition", requisition); + map.put("requisitionDt1s", requisition.getRequisitionDt1List()); + map.put("requisitionDt2s", requisition.getRequisitionDt2List()); + ProcessFlow processFlow = new ProcessFlow(); + processFlow.setOrderId(id); + processFlow.setOrderType(OrderTypes.REQUISITION.getCode()); + List list = processFlowService.selectProcessFlowList(processFlow); + map.put("lists", list); + FormFile requisitionFile = new FormFile(); + requisitionFile.setParentId(id); + List listFile = formFileService.selectFormFileList(requisitionFile); + listFile.forEach(f -> f.setFile(f.getFilePath())); + map.put("listFile", listFile); + Map resultMap = requisitionComponentApp.editableArea(requisition, user, type); + map.put("event", resultMap); + } catch (Exception e) { + log.error("璇疯喘鍗旳PP璇︽儏鎺ュ彛鍑洪敊锛岃幏鍙栬鎯呬俊鎭椂鍑洪敊------>{}", e); + return error(-1, "鑾峰彇璇︽儏鍑洪敊锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + return AjaxResult.success("success", map); + } + + /** + * 瀹℃牳鎻愪氦 + * + * @param infos 瀹℃牳淇℃伅 + * @param sid 鎿嶄綔鐢ㄦ埛 + * @param token 浠ょ墝 + * @return + */ + @Log(title = "璇疯喘鍗旳PI瀹℃牳鎻愪氦", businessType = BusinessType.UPDATE) + @RequestMapping("/auditSubmit") + @ResponseBody + public AjaxResult requisitionSubmit(@RequestParam(name = "infos") String infos, + @RequestParam(name = "sid") String sid, + @RequestParam(name = "token") String token) + { + log.info("璇疯喘鍗曞鏍告彁浜PI 琛ㄥ崟鏁版嵁------>{},鎿嶄綔浜------>{}", infos, sid); + try { + //瑙f瀽鏁版嵁 + RequisitionAuditResults auditResults = JSON.parseObject(infos, RequisitionAuditResults.class); + Requisition requisitionRes = requisitionService.selectRequisitionById(auditResults.getRequisitionId()); + SysUser userRes = userService.selectUserByUserCode(sid); + if (!requisitionRes.getSendToCode().equals(userRes.getUserCode()) && !userRes.isAdmin()) { + return error(-1, "宸茬粡绛炬牳瀹屾垚锛岃绛炬牳涓嬩竴鍗"); + } + requisitionService.auditSubmit(auditResults, userRes); + } catch (GlobalException e) { + return error(-1, e.getMessage()); + } catch (Exception e) { + log.error("璇疯喘鍗曞鏍告彁浜PI鍑洪敊锛侀敊璇------>{}", e); + return error(-1, "鎻愪氦澶辫触锛岃杩斿洖閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + return AjaxResult.success("success", "鎿嶄綔鎴愬姛"); + } + + /** + * + * + * @param infos + * @param sid + * @param token + * @param response + * @param request + * @return + */ + /*@RequestMapping(value = "/file/download") + @ResponseBody + public AjaxResult downloadFile(@RequestParam(name = "infos") String infos, + @RequestParam(name = "sid") String sid, + @RequestParam(name = "token") String token, HttpServletResponse response, HttpServletRequest request) + { + if (StringUtils.isEmpty(infos)) { + return error(-1, "涓嬭浇鏂囦欢鍑洪敊锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + log.info("璇疯喘鍗曚笅杞介檮浠禔PI 鏁版嵁------>{},鎿嶄綔浜------>{}", infos, sid); + Map resultMap = new HashMap<>(); + HashMap map = JSON.parseObject(infos, HashMap.class); + String filePath = (String) map.get("filepath"); + String ext = FileUtils.ext(filePath); + try { + String filePathRes = RuoYiConfig.getUploadPath() + filePath; + File f = new File(filePathRes); + if (!f.exists()) { + throw new FileNotFoundException(filePathRes); + } + // 璇诲彇鍥剧墖瀛楄妭鏁扮粍 + ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length()); + BufferedInputStream in = null; + try { + in = new BufferedInputStream(new FileInputStream(f)); + int buf_size = 1024; + byte[] buffer = new byte[buf_size]; + int len = 0; + while (-1 != (len = in.read(buffer, 0, buf_size))) { + bos.write(buffer, 0, len); + } + in.close(); + bos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + String file = requisitionComponentApp.byteToBase64(bos.toByteArray()); + resultMap.put("file", file); + resultMap.put("title", UUID.randomUUID().toString()); + resultMap.put("extension", ext); + return AjaxResult.success("success", resultMap); + } catch (Exception e) { + log.error("璇疯喘鍗曚笅杞芥枃浠禔PI鍑洪敊锛侀敊璇------>{}", e); + return error(-1, "涓嬭浇鏂囦欢鍑洪敊锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + }*/ + + /** + * 涓婁紶闄勪欢 + * + * @param multipartFiles + * @return + */ + @Log(title = "璇疯喘鍗旳PI闄勪欢涓婁紶", businessType = BusinessType.INSERT) + @PostMapping(value = "/file/upload") + @ResponseBody + public AjaxResult uploadFile1(@RequestParam("file") MultipartFile multipartFiles) + { + if (multipartFiles == null) { + return error(8, "鏂囦欢涓虹┖銆"); + } + Map map = new HashMap<>(); + try { + // 涓婁紶鏂囦欢璺緞 + String filePath = RuoYiConfig.getUploadPath(); + // 涓婁紶骞惰繑鍥炴柊鏂囦欢鍚嶇О + String fileNameRes = multipartFiles.getOriginalFilename().replaceAll(" ", "").replaceAll("&", ""); + String suffix = fileNameRes.substring(fileNameRes.lastIndexOf(".")); + String fileName = FileUploadUtils.uploads(filePath, multipartFiles, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + String url = fileName; + map.put("fileName", fileNameRes); + map.put("filePath", url); + } catch (Exception e) { + return AjaxResult.error(e.getMessage()); + } + return AjaxResult.success("success", map); + } + + /** + * 涓嬭浇鏂囦欢 + * + * @param infos + * @param sid + * @param token + * @param response + * @param request + * @return + */ + @Log(title = "璇疯喘鍗旳PI闄勪欢涓嬭浇", businessType = BusinessType.OTHER) + @RequestMapping(value = "/file/download/image") + @ResponseBody + public AjaxResult download(@RequestParam(name = "infos") String infos, + @RequestParam(name = "sid") String sid, + @RequestParam(name = "token") String token, HttpServletResponse response, HttpServletRequest request) + { + if (StringUtils.isEmpty(infos)) { + return error(-1, "涓嬭浇鏂囦欢鍑洪敊锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + Map resultMap = new HashMap<>(); + HashMap map = JSON.parseObject(infos, HashMap.class); + String filePath = (String) map.get("filepath"); + String suffix = filePath.substring(filePath.lastIndexOf(".")); + try { + if (".jpg".equals(suffix) || ".png".equals(suffix)) { + String filePathRes = RuoYiConfig.getUploadPath() + filePath; + File f = new File(filePathRes); + if (!f.exists()) { + throw new FileNotFoundException(filePathRes); + } + // 璇诲彇鍥剧墖瀛楄妭鏁扮粍 + ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length()); + BufferedInputStream in = null; + try { + in = new BufferedInputStream(new FileInputStream(f)); + int buf_size = 1024; + byte[] buffer = new byte[buf_size]; + int len = 0; + while (-1 != (len = in.read(buffer, 0, buf_size))) { + bos.write(buffer, 0, len); + } + in.close(); + bos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + String file = requisitionComponentApp.byteToBase64(bos.toByteArray()); + if (".jpg".equals(suffix)) { + suffix = ".jpeg"; + } + file = "data:image/" + suffix.replace(".", "") + ";base64," + file; + resultMap.put("file", file); + return AjaxResult.success("success", resultMap); + } else { + String fileName = UUID.randomUUID().toString(); + commonController.resourceDownloads(filePath, fileName, request, response); + return null; + } + } catch (Exception e) { + log.error("涓嬭浇澶辫触"); + return error(-1, "涓嬭浇鏂囦欢鍑洪敊锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + } + + /** + * 鍒犻櫎璇疯喘鍗 + * + * @param infos + * @return + */ + @Log(title = "璇疯喘鍗旳PI鍒犻櫎", businessType = BusinessType.DELETE) + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(@RequestParam(name = "infos") String infos, @RequestParam(name = "token") String token) + { + String ids; + try { + HashMap map = JSON.parseObject(infos, HashMap.class); + ids = (String) map.get("ids"); + if (StringUtils.isEmpty(ids)) { + throw new GlobalException("鍒犻櫎澶辫触锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + requisitionService.deleteRequisitionByIds(ids); + return success(); + } catch (GlobalException e) { + log.error("璇疯喘鍗曞垹闄PI鍑洪敊锛侀敊璇師鍥------>", e.getMessage()); + return error(-1, e.getMessage()); + } catch (Exception exception) { + log.error("璇疯喘鍗曞垹闄PI鍑洪敊锛侀敊璇師鍥------>", exception); + return error(-1, "鍒犻櫎澶辫触锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + } + + /** + * 鑾峰彇椤圭洰缂栧彿 + * + * @return 椤圭洰缂栧彿鍒楄〃 + */ + @PostMapping("/getProjectCode") + @ResponseBody + public AjaxResult getProjectCode(@RequestParam(name = "token") String token) + { + return AjaxResult.success("success!", CacheUtils.get(Constants.ZT_WGCPRORELEASE_CACHE, Constants.ZT_WGCPRORELEASE_KEY + "proCode")); + } + + /** + * 鎾ゅ洖璇疯喘鍗 + * + * @param infos 璇疯喘鍗曚俊鎭 + * @param token 浠ょ墝 + * @return + */ + @Log(title = "璇疯喘鍗旳PI鎾ゅ洖", businessType = BusinessType.UPDATE) + @PostMapping("/withdrawal") + @ResponseBody + public AjaxResult withdrawal(@RequestParam(name = "infos") String infos, @RequestParam(name = "token") String token) + { + Long id; + try { + HashMap map = JSON.parseObject(infos, HashMap.class); + id = Long.valueOf((String) map.get("id")); + if (StringUtils.isNull(id)) { + throw new GlobalException("鎾ゅ洖澶辫触锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + requisitionService.withdraw(id); + return success(); + } catch (GlobalException e) { + log.error("璇疯喘鍗曞垹闄PI鍑洪敊锛侀敊璇師鍥------>", e.getMessage()); + return error(-1, e.getMessage()); + } catch (Exception exception) { + log.error("璇疯喘鍗曟挙鍥濧PI鍑洪敊锛侀敊璇師鍥------>", exception); + return error(-1, "鎿嶄綔澶辫触锛屽彂鐢熸湭鐭ュ紓甯革紝璇蜂繚瀛樻埅鍥撅紝鍦ㄧ郴缁熷伐鍗曟ā鍧楀彂璧封滃伐浣滄祦瀹℃壒绯荤粺鈥濆伐鍗曞弽棣堛"); + } + } + + /** + * 璇疯喘鍗曠紪杈 + * + * @param infos 璇疯喘鍗曚俊鎭 + * @param operationType 鎿嶄綔绫诲瀷 + * @param sid 鍛樺伐缂栧彿 + * @param token 浠ょ墝 + * @return 缁撴灉 + */ + @Log(title = "璇疯喘鍗旳PI缂栬緫", businessType = BusinessType.UPDATE) + @PostMapping("/edit/{operationType}") + @ResponseBody + public AjaxResult editSave(@RequestParam(name = "infos") String infos, + @PathVariable(name = "operationType", required = false) String operationType, + @RequestParam(name = "sid") String sid, + @RequestParam(name = "token") String token) + { + RequisitionDto requisitionDto = JSON.parseObject(infos, RequisitionDto.class); + if (StringUtils.isNull(requisitionDto)) { + log.error("璇疯喘鍗旳PP缂栬緫鎺ュ彛鍑洪敊锛屾湭鑾峰彇鍒版纭甶nfos鏁版嵁锛岄棶棰榠nfos------>{}", infos); + return error(-1, "鎿嶄綔澶辫触锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + SysUser user = userService.selectUserByUserCode(sid); + if (StringUtils.isNull(user)) { + log.error("璇疯喘鍗旳PP缂栬緫鎺ュ彛鍑洪敊锛屾湭鑾峰彇鍒版纭殑鐢ㄦ埛鏍囪瘑锛岄棶棰樼敤鎴锋爣璇------>{}", sid); + return error(-1, "鑾峰彇鐧诲綍鐢ㄦ埛淇℃伅澶辫触锛岃閲嶆柊鐧诲綍鎴栬仈绯籌T浜哄憳銆"); + } + String msg = requisitionComponentApp.insertCheck(requisitionDto); + if (StringUtils.isNotEmpty(msg)) { + return error(-1, msg); + } + Long requisitionId; + try { + Requisition requisition = requisitionDto.getRequisition(); + requisition.setRequisitionDt1List(requisitionDto.getRequisitionDt1s()); + requisition.setRequisitionDt2List(requisitionDto.getRequisitionDt2s()); + requisitionId = requisitionService.updateRequisition(requisition, user); + if (Objects.equals(operationType, "2")) { + //杩涜鎻愪氦 + requisitionService.submit(requisitionId, user); + } + return success(); + } catch (GlobalException e) { + return error(e.getMessage()); + } catch (Exception e) { + log.error("璇疯喘鍗曠紪杈慉PI鍑洪敊锛侀敊璇師鍥------>", e); + return error(-1, "鎿嶄綔澶辫触锛岃绋嶅悗閲嶈瘯鎴栬仈绯籌T浜哄憳銆"); + } + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java new file mode 100644 index 000000000..ed19b0456 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java @@ -0,0 +1,275 @@ +package com.ruoyi.web.controller.common; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ruoyi.common.constant.FormFileConstants; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.ShiroUtils; +import com.ruoyi.common.utils.file.MimeTypeUtils; +import com.ruoyi.system.domain.FormFile; +import com.ruoyi.system.service.IFormFileService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.config.ServerConfig; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.file.FileUploadUtils; +import com.ruoyi.common.utils.file.FileUtils; + + +/** + * 閫氱敤璇锋眰澶勭悊 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/common") +public class CommonController +{ + private static final Logger log = LoggerFactory.getLogger(CommonController.class); + + @Autowired + private ServerConfig serverConfig; + + @Autowired + private IFormFileService formFileService; + + private static final String FILE_DELIMETER = ","; + + /** + * 閫氱敤涓嬭浇璇锋眰 + * + * @param fileName 鏂囦欢鍚嶇О + * @param delete 鏄惁鍒犻櫎 + */ + @GetMapping("/download") + public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request) + { + try + { + if (!FileUtils.checkAllowDownload(fileName)) + { + throw new Exception(StringUtils.format("鏂囦欢鍚嶇О({})闈炴硶锛屼笉鍏佽涓嬭浇銆 ", fileName)); + } + String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1); + String filePath = RuoYiConfig.getDownloadPath() + fileName; + + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); + FileUtils.setAttachmentResponseHeader(response, realFileName); + FileUtils.writeBytes(filePath, response.getOutputStream()); + if (delete) + { + FileUtils.deleteFile(filePath); + } + } + catch (Exception e) + { + log.error("涓嬭浇鏂囦欢澶辫触", e); + } + } + + /** + * 閫氱敤涓婁紶璇锋眰锛堝崟涓級 + */ + @PostMapping("/upload") + @ResponseBody + public AjaxResult uploadFile(MultipartFile file) throws Exception + { + try + { + // 涓婁紶鏂囦欢璺緞 + String filePath = RuoYiConfig.getUploadPath(); + // 涓婁紶骞惰繑鍥炴柊鏂囦欢鍚嶇О + String fileName = FileUploadUtils.upload(filePath, file); + String url = serverConfig.getUrl() + fileName; + AjaxResult ajax = AjaxResult.success(); + ajax.put("url", url); + ajax.put("fileName", fileName); + ajax.put("newFileName", FileUtils.getName(fileName)); + ajax.put("originalFilename", file.getOriginalFilename()); + return ajax; + } + catch (Exception e) + { + return AjaxResult.error(e.getMessage()); + } + } + + /** + * 閫氱敤涓婁紶璇锋眰锛堝涓級 + */ + @PostMapping("/uploads") + @ResponseBody + public AjaxResult uploadFiles(List files) throws Exception + { + try + { + // 涓婁紶鏂囦欢璺緞 + String filePath = RuoYiConfig.getUploadPath(); + List urls = new ArrayList(); + List fileNames = new ArrayList(); + List newFileNames = new ArrayList(); + List originalFilenames = new ArrayList(); + for (MultipartFile file : files) + { + // 涓婁紶骞惰繑鍥炴柊鏂囦欢鍚嶇О + String fileName = FileUploadUtils.upload(filePath, file); + String url = serverConfig.getUrl() + fileName; + urls.add(url); + fileNames.add(fileName); + newFileNames.add(FileUtils.getName(fileName)); + originalFilenames.add(file.getOriginalFilename()); + } + AjaxResult ajax = AjaxResult.success(); + ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER)); + ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER)); + ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER)); + ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER)); + return ajax; + } + catch (Exception e) + { + return AjaxResult.error(e.getMessage()); + } + } + + /** + * 鑷畾涔夋枃浠朵笂浼 + * @param files 鏂囦欢鍒楄〃 + * @param type 鏂囦欢绫诲瀷 + * @return + */ + @PostMapping("/uploadFiles") + @ResponseBody + public AjaxResult customizeUploadFile(List files, Long parentId, Integer type) + { + try + { + String uploadPath = ""; + if (Objects.equals(type, FormFileConstants.PAYMENTREQUEST_TEMPLATE) || Objects.equals(type, FormFileConstants.PAYMENTREQUEST)){ + uploadPath = FormFileConstants.PAYMENTREQUEST_PATH; + } else if (Objects.equals(type, FormFileConstants.REQUISTION_TEMPLATE) || Objects.equals(type, FormFileConstants.REQUISITION)){ + uploadPath = FormFileConstants.REQUISITION_PATH; + } else if (Objects.equals(type, FormFileConstants.PETITION_TEMPLATE) || Objects.equals(type, FormFileConstants.PETITION)){ + uploadPath = FormFileConstants.PETITION_PATH; + } + // 涓婁紶鏂囦欢璺緞 + String filePath = RuoYiConfig.getUploadPath() + uploadPath; + List list = new ArrayList<>(); + for (MultipartFile file : files) + { + // 涓婁紶骞惰繑鍥炴柊鏂囦欢鍚嶇О + String path = FileUploadUtils.uploads(filePath, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); + FormFile formFile = new FormFile(); + if (StringUtils.isNotNull(parentId)) { + formFile.setParentId(parentId); + } + formFile.setFileType(type); + formFile.setFilePath(uploadPath + path); + formFile.setFileName(file.getOriginalFilename()); + formFile.setCreateBy(ShiroUtils.getSysUser().getUserName()); + formFile.setCreateTime(DateUtils.getNowDate()); + list.add(formFile); + } + //淇濆瓨鏂囦欢淇℃伅 + formFileService.batchFormFile(list); + return AjaxResult.success(); + } + catch (Exception e) + { + return AjaxResult.error(e.getMessage()); + } + } + + /** + * 鏈湴璧勬簮閫氱敤涓嬭浇(鑷畾涔夋枃浠跺悕) + * @param resource 鏂囦欢璺緞 + * @param fileName 鏂囦欢鍚 + * @throws Exception + */ + @GetMapping("/download/resources") + public void resourceDownloads(String resource, String fileName, HttpServletRequest request, HttpServletResponse response) + { + try + { + if (!FileUtils.checkAllowDownload(resource)) + { + throw new Exception(StringUtils.format("璧勬簮鏂囦欢({})闈炴硶锛屼笉鍏佽涓嬭浇銆 ", resource)); + } + // 鏈湴璧勬簮璺緞 + String localPath = RuoYiConfig.getUploadPath(); + // 鏁版嵁搴撹祫婧愬湴鍧 + String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX) + resource; + // 涓嬭浇鍚嶇О + String downloadName = StringUtils.substringAfterLast(downloadPath, "/"); + if(StringUtils.isNotEmpty(fileName)){ + downloadName = fileName; + } + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); + FileUtils.setAttachmentResponseHeader(response, downloadName); + FileUtils.writeBytes(downloadPath, response.getOutputStream()); + } + catch (Exception e) + { + log.error("涓嬭浇鏂囦欢澶辫触", e); + } + } + + /** + * 鏈湴鏂囦欢鍒犻櫎 + */ + @PostMapping("/remove/file") + @ResponseBody + public AjaxResult removeFile(FormFile formFile) + { + String filePath = RuoYiConfig.getUploadPath(); + boolean b = FileUtils.deleteFile(filePath + formFile.getFilePath()); + if (b) { + formFileService.deleteFormFileById(formFile.getId()); + return AjaxResult.success(); + } else { + return AjaxResult.error(); + } + } + + /** + * 鏈湴璧勬簮閫氱敤涓嬭浇 + */ + @GetMapping("/download/resource") + public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response) + throws Exception + { + try + { + if (!FileUtils.checkAllowDownload(resource)) + { + throw new Exception(StringUtils.format("璧勬簮鏂囦欢({})闈炴硶锛屼笉鍏佽涓嬭浇銆 ", resource)); + } + // 鏈湴璧勬簮璺緞 + String localPath = RuoYiConfig.getProfile(); + // 鏁版嵁搴撹祫婧愬湴鍧 + String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX); + // 涓嬭浇鍚嶇О + String downloadName = StringUtils.substringAfterLast(downloadPath, "/"); + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); + FileUtils.setAttachmentResponseHeader(response, downloadName); + FileUtils.writeBytes(downloadPath, response.getOutputStream()); + } + catch (Exception e) + { + log.error("涓嬭浇鏂囦欢澶辫触", e); + } + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/controller/DemoDialogController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/controller/DemoDialogController.java new file mode 100644 index 000000000..30300579f --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/controller/DemoDialogController.java @@ -0,0 +1,98 @@ +package com.ruoyi.web.controller.demo.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * 妯℃佺獥鍙 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/demo/modal") +public class DemoDialogController +{ + private String prefix = "demo/modal"; + + /** + * 妯℃佺獥鍙 + */ + @GetMapping("/dialog") + public String dialog() + { + return prefix + "/dialog"; + } + + /** + * 寮瑰眰缁勪欢 + */ + @GetMapping("/layer") + public String layer() + { + return prefix + "/layer"; + } + + /** + * 琛ㄥ崟 + */ + @GetMapping("/form") + public String form() + { + return prefix + "/form"; + } + + /** + * 琛ㄦ牸 + */ + @GetMapping("/table") + public String table() + { + return prefix + "/table"; + } + + /** + * 琛ㄦ牸check + */ + @GetMapping("/check") + public String check() + { + return prefix + "/table/check"; + } + + /** + * 琛ㄦ牸radio + */ + @GetMapping("/radio") + public String radio() + { + return prefix + "/table/radio"; + } + + /** + * 琛ㄦ牸鍥炰紶鐖剁獥浣 + */ + @GetMapping("/parent") + public String parent() + { + return prefix + "/table/parent"; + } + + /** + * 澶氬眰绐楀彛frame1 + */ + @GetMapping("/frame1") + public String frame1() + { + return prefix + "/table/frame1"; + } + + /** + * 澶氬眰绐楀彛frame2 + */ + @GetMapping("/frame2") + public String frame2() + { + return prefix + "/table/frame2"; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/controller/DemoFormController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/controller/DemoFormController.java new file mode 100644 index 000000000..7cc6faa1c --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/controller/DemoFormController.java @@ -0,0 +1,399 @@ +package com.ruoyi.web.controller.demo.controller; + +import java.util.ArrayList; +import java.util.List; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.alibaba.fastjson.JSON; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.CxSelect; +import com.ruoyi.common.json.JSONObject; +import com.ruoyi.common.json.JSONObject.JSONArray; +import com.ruoyi.common.utils.StringUtils; + +/** + * 琛ㄥ崟鐩稿叧 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/demo/form") +public class DemoFormController +{ + private String prefix = "demo/form"; + + private final static List users = new ArrayList(); + { + users.add(new UserFormModel(1, "1000001", "娴嬭瘯1", "15888888888")); + users.add(new UserFormModel(2, "1000002", "娴嬭瘯2", "15666666666")); + users.add(new UserFormModel(3, "1000003", "娴嬭瘯3", "15666666666")); + users.add(new UserFormModel(4, "1000004", "娴嬭瘯4", "15666666666")); + users.add(new UserFormModel(5, "1000005", "娴嬭瘯5", "15666666666")); + } + + /** + * 鎸夐挳椤 + */ + @GetMapping("/button") + public String button() + { + return prefix + "/button"; + } + + /** + * 涓嬫媺妗 + */ + @GetMapping("/select") + public String select() + { + return prefix + "/select"; + } + + /** + * 鏃堕棿杞 + */ + @GetMapping("/timeline") + public String timeline() + { + return prefix + "/timeline"; + } + + /** + * 杩涘害鏉 + */ + @GetMapping("/progress_bars") + public String progress_bars() + { + return prefix + "/progress_bars"; + } + + /** + * 琛ㄥ崟鏍¢獙 + */ + @GetMapping("/validate") + public String validate() + { + return prefix + "/validate"; + } + + /** + * 鍔熻兘鎵╁睍锛堝寘鍚枃浠朵笂浼狅級 + */ + @GetMapping("/jasny") + public String jasny() + { + return prefix + "/jasny"; + } + + /** + * 鎷栧姩鎺掑簭 + */ + @GetMapping("/sortable") + public String sortable() + { + return prefix + "/sortable"; + } + + /** + * 鍗曟嵁鎵撳嵃 + */ + @GetMapping("/invoice") + public String invoice() + { + return prefix + "/invoice"; + } + + /** + * 鏍囩 & 鎻愮ず + */ + @GetMapping("/labels_tips") + public String labels_tips() + { + return prefix + "/labels_tips"; + } + + /** + * 閫夐」鍗 & 闈㈡澘 + */ + @GetMapping("/tabs_panels") + public String tabs_panels() + { + return prefix + "/tabs_panels"; + } + + /** + * 鏍呮牸 + */ + @GetMapping("/grid") + public String grid() + { + return prefix + "/grid"; + } + + /** + * 琛ㄥ崟鍚戝 + */ + @GetMapping("/wizard") + public String wizard() + { + return prefix + "/wizard"; + } + + /** + * 鏂囦欢涓婁紶 + */ + @GetMapping("/upload") + public String upload() + { + return prefix + "/upload"; + } + + /** + * 鏃ユ湡鍜屾椂闂撮〉 + */ + @GetMapping("/datetime") + public String datetime() + { + return prefix + "/datetime"; + } + + /** + * 宸﹀彸浜掗夌粍浠 + */ + @GetMapping("/duallistbox") + public String duallistbox() + { + return prefix + "/duallistbox"; + } + + /** + * 鍩烘湰琛ㄥ崟 + */ + @GetMapping("/basic") + public String basic() + { + return prefix + "/basic"; + } + + /** + * 鍗$墖鍒楄〃 + */ + @GetMapping("/cards") + public String cards() + { + return prefix + "/cards"; + } + + /** + * summernote 瀵屾枃鏈紪杈戝櫒 + */ + @GetMapping("/summernote") + public String summernote() + { + return prefix + "/summernote"; + } + + /** + * 鎼滅储鑷姩琛ュ叏 + */ + @GetMapping("/autocomplete") + public String autocomplete() + { + return prefix + "/autocomplete"; + } + + /** + * 澶氱骇鑱斿姩涓嬫媺 + */ + @GetMapping("/cxselect") + public String cxselect(ModelMap mmap) + { + CxSelect cxSelectTB = new CxSelect(); + cxSelectTB.setN("娣樺疂"); + cxSelectTB.setV("taobao"); + CxSelect cxSelectTm = new CxSelect(); + cxSelectTm.setN("澶╃尗"); + cxSelectTm.setV("tm"); + CxSelect cxSelectJhs = new CxSelect(); + cxSelectJhs.setN("鑱氬垝绠"); + cxSelectJhs.setV("jhs"); + List tmList = new ArrayList(); + tmList.add(cxSelectTm); + tmList.add(cxSelectJhs); + cxSelectTB.setS(tmList); + + CxSelect cxSelectJD = new CxSelect(); + cxSelectJD.setN("浜笢"); + cxSelectJD.setV("jd"); + CxSelect cxSelectCs = new CxSelect(); + cxSelectCs.setN("浜笢瓒呭競"); + cxSelectCs.setV("jdcs"); + CxSelect cxSelectSx = new CxSelect(); + cxSelectSx.setN("浜笢鐢熼矞"); + cxSelectSx.setV("jdsx"); + List jdList = new ArrayList(); + jdList.add(cxSelectCs); + jdList.add(cxSelectSx); + cxSelectJD.setS(jdList); + + List cxList = new ArrayList(); + cxList.add(cxSelectTB); + cxList.add(cxSelectJD); + + mmap.put("data", JSON.toJSON(cxList)); + return prefix + "/cxselect"; + } + + /** + * 灞閮ㄥ埛鏂 + */ + @GetMapping("/localrefresh") + public String localRefresh(ModelMap mmap) + { + JSONArray list = new JSONArray(); + JSONObject item = new JSONObject(); + item.put("name", "杩欐潯浠诲姟鏁版嵁鏄敱ModelMap浼犻掑埌椤甸潰鐨勶紝鐐瑰嚮娣诲姞鎸夐挳鍚庝細灏嗚繖鏉℃暟鎹浛鎹负鏂版暟鎹"); + item.put("type", "榛樿"); + item.put("date", "2020.06.10"); + list.add(item); + mmap.put("tasks", list); + mmap.put("min", 2); + mmap.put("max", 10); + return prefix + "/localrefresh"; + } + + /** + * 灞閮ㄥ埛鏂-娣诲姞浠诲姟 + * + * @param fragment 椤甸潰涓殑妯℃澘鍚嶇О + * @param taskName 浠诲姟鍚嶇О + */ + @PostMapping("/localrefresh/task") + public String localRefreshTask(String fragment, String taskName, ModelMap mmap) + { + JSONArray list = new JSONArray(); + JSONObject item = new JSONObject(); + item.put("name", StringUtils.defaultIfBlank(taskName, "閫氳繃鐢佃瘽閿鍞繃绋嬩腑浜嗚В鍚勭洓甯傜殑璁惧浠櫒浣跨敤銆侀噰璐儏鍐靛強鐩稿叧閲嶈杩借釜浜")); + item.put("type", "鏂板"); + item.put("date", "2018.06.10"); + list.add(item); + item = new JSONObject(); + item.put("name", "鎻愰珮鑷繁鐢佃瘽钀ラ攢鎶宸э紝鐏垫椿涓撲笟鍦颁笌瀹㈡埛杩涜鐢佃瘽浜ゆ祦"); + item.put("type", "鏂板"); + item.put("date", "2018.06.12"); + list.add(item); + mmap.put("tasks", list); + return prefix + "/localrefresh::" + fragment; + } + + /** + * 妯℃嫙鏁版嵁 + */ + @GetMapping("/cityData") + @ResponseBody + public String cityData() + { + String data = "[{\"n\":\"婀栧崡鐪乗",\"s\":[{\"n\":\"闀挎矙甯俓",\"s\":[{\"n\":\"鑺欒搲鍖篭"},{\"n\":\"澶╁績鍖篭"},{\"n\":\"宀抽簱鍖篭"},{\"n\":\"寮绂忓尯\"},{\"n\":\"闆ㄨ姳鍖篭"},{\"n\":\"鏈涘煄鍖篭"},{\"n\":\"闀挎矙鍘縗"},{\"n\":\"瀹佷埂鍘縗"},{\"n\":\"娴忛槼甯俓"}]},{\"n\":\"鏍床甯俓",\"s\":[{\"n\":\"鑽峰鍖篭"},{\"n\":\"鑺︽窞鍖篭"},{\"n\":\"鐭冲嘲鍖篭"},{\"n\":\"澶╁厓鍖篭"},{\"n\":\"鏍床鍘縗"},{\"n\":\"鏀稿幙\"},{\"n\":\"鑼堕櫟鍘縗"},{\"n\":\"鐐庨櫟鍘縗"},{\"n\":\"閱撮櫟甯俓"}]},{\"n\":\"婀樻江甯俓",\"s\":[{\"n\":\"闆ㄦ箹鍖篭"},{\"n\":\"宀冲鍖篭"},{\"n\":\"婀樻江鍘縗"},{\"n\":\"婀樹埂甯俓"},{\"n\":\"闊跺北甯俓"}]},{\"n\":\"琛¢槼甯俓",\"s\":[{\"n\":\"鐝犳櫀鍖篭"},{\"n\":\"闆佸嘲鍖篭"},{\"n\":\"鐭抽紦鍖篭"},{\"n\":\"钂告箻鍖篭"},{\"n\":\"鍗楀渤鍖篭"},{\"n\":\"琛¢槼鍘縗"},{\"n\":\"琛″崡鍘縗"},{\"n\":\"琛″北鍘縗"},{\"n\":\"琛′笢鍘縗"},{\"n\":\"绁佷笢鍘縗"},{\"n\":\"鑰掗槼甯俓"},{\"n\":\"甯稿畞甯俓"}]},{\"n\":\"閭甸槼甯俓",\"s\":[{\"n\":\"鍙屾竻鍖篭"},{\"n\":\"澶хゥ鍖篭"},{\"n\":\"鍖楀鍖篭"},{\"n\":\"閭典笢鍘縗"},{\"n\":\"鏂伴偟鍘縗"},{\"n\":\"閭甸槼鍘縗"},{\"n\":\"闅嗗洖鍘縗"},{\"n\":\"娲炲彛鍘縗"},{\"n\":\"缁ュ畞鍘縗"},{\"n\":\"鏂板畞鍘縗"},{\"n\":\"鍩庢鑻楁棌鑷不鍘縗"},{\"n\":\"姝﹀唸甯俓"}]},{\"n\":\"宀抽槼甯俓",\"s\":[{\"n\":\"宀抽槼妤煎尯\"},{\"n\":\"浜戞邯鍖篭"},{\"n\":\"鍚涘北鍖篭"},{\"n\":\"宀抽槼鍘縗"},{\"n\":\"鍗庡鍘縗"},{\"n\":\"婀橀槾鍘縗"},{\"n\":\"骞虫睙鍘縗"},{\"n\":\"姹ㄧ綏甯俓"},{\"n\":\"涓存箻甯俓"}]},{\"n\":\"甯稿痉甯俓",\"s\":[{\"n\":\"姝﹂櫟鍖篭"},{\"n\":\"榧庡煄鍖篭"},{\"n\":\"瀹変埂鍘縗"},{\"n\":\"姹夊鍘縗"},{\"n\":\"婢у幙\"},{\"n\":\"涓存晶鍘縗"},{\"n\":\"妗冩簮鍘縗"},{\"n\":\"鐭抽棬鍘縗"},{\"n\":\"娲ュ競甯俓"}]},{\"n\":\"寮犲鐣屽競\",\"s\":[{\"n\":\"姘稿畾鍖篭"},{\"n\":\"姝﹂櫟婧愬尯\"},{\"n\":\"鎱堝埄鍘縗"},{\"n\":\"妗戞鍘縗"}]},{\"n\":\"鐩婇槼甯俓",\"s\":[{\"n\":\"璧勯槼鍖篭"},{\"n\":\"璧北鍖篭"},{\"n\":\"鍗楀幙\"},{\"n\":\"妗冩睙鍘縗"},{\"n\":\"瀹夊寲鍘縗"},{\"n\":\"娌呮睙甯俓"}]},{\"n\":\"閮村窞甯俓",\"s\":[{\"n\":\"鍖楁箹鍖篭"},{\"n\":\"鑻忎粰鍖篭"},{\"n\":\"妗傞槼鍘縗"},{\"n\":\"瀹滅珷鍘縗"},{\"n\":\"姘稿叴鍘縗"},{\"n\":\"鍢夌鍘縗"},{\"n\":\"涓存鍘縗"},{\"n\":\"姹濆煄鍘縗"},{\"n\":\"妗備笢鍘縗"},{\"n\":\"瀹変粊鍘縗"},{\"n\":\"璧勫叴甯俓"}]},{\"n\":\"姘稿窞甯俓",\"s\":[{\"n\":\"闆堕櫟鍖篭"},{\"n\":\"鍐锋按婊╁尯\"},{\"n\":\"绁侀槼鍘縗"},{\"n\":\"涓滃畨鍘縗"},{\"n\":\"鍙岀墝鍘縗"},{\"n\":\"閬撳幙\"},{\"n\":\"姹熸案鍘縗"},{\"n\":\"瀹佽繙鍘縗"},{\"n\":\"钃濆北鍘縗"},{\"n\":\"鏂扮敯鍘縗"},{\"n\":\"姹熷崕鐟舵棌鑷不鍘縗"}]},{\"n\":\"鎬鍖栧競\",\"s\":[{\"n\":\"楣ゅ煄鍖篭"},{\"n\":\"涓柟鍘縗"},{\"n\":\"娌呴櫟鍘縗"},{\"n\":\"杈版邯鍘縗"},{\"n\":\"婧嗘郸鍘縗"},{\"n\":\"浼氬悓鍘縗"},{\"n\":\"楹婚槼鑻楁棌鑷不鍘縗"},{\"n\":\"鏂版檭渚楁棌鑷不鍘縗"},{\"n\":\"鑺锋睙渚楁棌鑷不鍘縗"},{\"n\":\"闈栧窞鑻楁棌渚楁棌鑷不鍘縗"},{\"n\":\"閫氶亾渚楁棌鑷不鍘縗"},{\"n\":\"娲睙甯俓"}]},{\"n\":\"濞勫簳甯俓",\"s\":[{\"n\":\"濞勬槦鍖篭"},{\"n\":\"鍙屽嘲鍘縗"},{\"n\":\"鏂板寲鍘縗"},{\"n\":\"鍐锋按姹熷競\"},{\"n\":\"娑熸簮甯俓"}]},{\"n\":\"婀樿タ鍦熷鏃忚嫍鏃忚嚜娌诲窞\",\"s\":[{\"n\":\"鍚夐甯俓"},{\"n\":\"娉告邯鍘縗"},{\"n\":\"鍑ゅ嚢鍘縗"},{\"n\":\"鑺卞灒鍘縗"},{\"n\":\"淇濋潠鍘縗"},{\"n\":\"鍙や笀鍘縗"},{\"n\":\"姘搁『鍘縗"},{\"n\":\"榫欏北鍘縗"}]}]},{\"n\":\"骞夸笢鐪乗",\"s\":[{\"n\":\"骞垮窞甯俓",\"s\":[{\"n\":\"鑽旀咕鍖篭"},{\"n\":\"瓒婄鍖篭"},{\"n\":\"娴风彔鍖篭"},{\"n\":\"澶╂渤鍖篭"},{\"n\":\"鐧戒簯鍖篭"},{\"n\":\"榛勫煍鍖篭"},{\"n\":\"鐣鍖篭"},{\"n\":\"鑺遍兘鍖篭"},{\"n\":\"鍗楁矙鍖篭"},{\"n\":\"钀濆矖鍖篭"},{\"n\":\"澧炲煄甯俓"},{\"n\":\"浠庡寲甯俓"}]},{\"n\":\"闊跺叧甯俓",\"s\":[{\"n\":\"姝︽睙鍖篭"},{\"n\":\"娴堟睙鍖篭"},{\"n\":\"鏇叉睙鍖篭"},{\"n\":\"濮嬪叴鍘縗"},{\"n\":\"浠佸寲鍘縗"},{\"n\":\"缈佹簮鍘縗"},{\"n\":\"涔虫簮鐟舵棌鑷不鍘縗"},{\"n\":\"鏂颁赴鍘縗"},{\"n\":\"涔愭槍甯俓"},{\"n\":\"鍗楅泟甯俓"}]},{\"n\":\"娣卞湷甯俓",\"s\":[{\"n\":\"缃楁箹鍖篭"},{\"n\":\"绂忕敯鍖篭"},{\"n\":\"鍗楀北鍖篭"},{\"n\":\"瀹濆畨鍖篭"},{\"n\":\"榫欏矖鍖篭"},{\"n\":\"鐩愮敯鍖篭"}]},{\"n\":\"鐝犳捣甯俓",\"s\":[{\"n\":\"棣欐床鍖篭"},{\"n\":\"鏂楅棬鍖篭"},{\"n\":\"閲戞咕鍖篭"}]},{\"n\":\"姹曞ご甯俓",\"s\":[{\"n\":\"榫欐箹鍖篭"},{\"n\":\"閲戝钩鍖篭"},{\"n\":\"婵犳睙鍖篭"},{\"n\":\"娼槼鍖篭"},{\"n\":\"娼崡鍖篭"},{\"n\":\"婢勬捣鍖篭"},{\"n\":\"鍗楁境鍘縗"}]},{\"n\":\"浣涘北甯俓",\"s\":[{\"n\":\"绂呭煄鍖篭"},{\"n\":\"鍗楁捣鍖篭"},{\"n\":\"椤哄痉鍖篭"},{\"n\":\"涓夋按鍖篭"},{\"n\":\"楂樻槑鍖篭"}]},{\"n\":\"姹熼棬甯俓",\"s\":[{\"n\":\"钃睙鍖篭"},{\"n\":\"姹熸捣鍖篭"},{\"n\":\"鏂颁細鍖篭"},{\"n\":\"鍙板北甯俓"},{\"n\":\"寮骞冲競\"},{\"n\":\"楣ゅ北甯俓"},{\"n\":\"鎭╁钩甯俓"}]},{\"n\":\"婀涙睙甯俓",\"s\":[{\"n\":\"璧ゅ潕鍖篭"},{\"n\":\"闇炲北鍖篭"},{\"n\":\"鍧″ご鍖篭"},{\"n\":\"楹荤珷鍖篭"},{\"n\":\"閬傛邯鍘縗"},{\"n\":\"寰愰椈鍘縗"},{\"n\":\"寤夋睙甯俓"},{\"n\":\"闆峰窞甯俓"},{\"n\":\"鍚村窛甯俓"}]},{\"n\":\"鑼傚悕甯俓",\"s\":[{\"n\":\"鑼傚崡鍖篭"},{\"n\":\"鑼傛腐鍖篭"},{\"n\":\"鐢电櫧鍘縗"},{\"n\":\"楂樺窞甯俓"},{\"n\":\"鍖栧窞甯俓"},{\"n\":\"淇″疁甯俓"}]},{\"n\":\"鑲囧簡甯俓",\"s\":[{\"n\":\"绔窞鍖篭"},{\"n\":\"榧庢箹鍖篭"},{\"n\":\"骞垮畞鍘縗"},{\"n\":\"鎬闆嗗幙\"},{\"n\":\"灏佸紑鍘縗"},{\"n\":\"寰峰簡鍘縗"},{\"n\":\"楂樿甯俓"},{\"n\":\"鍥涗細甯俓"}]},{\"n\":\"鎯犲窞甯俓",\"s\":[{\"n\":\"鎯犲煄鍖篭"},{\"n\":\"鎯犻槼鍖篭"},{\"n\":\"鍗氱綏鍘縗"},{\"n\":\"鎯犱笢鍘縗"},{\"n\":\"榫欓棬鍘縗"}]},{\"n\":\"姊呭窞甯俓",\"s\":[{\"n\":\"姊呮睙鍖篭"},{\"n\":\"姊呭幙\"},{\"n\":\"澶у煍鍘縗"},{\"n\":\"涓伴『鍘縗"},{\"n\":\"浜斿崕鍘縗"},{\"n\":\"骞宠繙鍘縗"},{\"n\":\"钑夊箔鍘縗"},{\"n\":\"鍏村畞甯俓"}]},{\"n\":\"姹曞熬甯俓",\"s\":[{\"n\":\"鍩庡尯\"},{\"n\":\"娴蜂赴鍘縗"},{\"n\":\"闄嗘渤鍘縗"},{\"n\":\"闄嗕赴甯俓"}]},{\"n\":\"娌虫簮甯俓",\"s\":[{\"n\":\"婧愬煄鍖篭"},{\"n\":\"绱噾鍘縗"},{\"n\":\"榫欏窛鍘縗"},{\"n\":\"杩炲钩鍘縗"},{\"n\":\"鍜屽钩鍘縗"},{\"n\":\"涓滄簮鍘縗"}]},{\"n\":\"闃虫睙甯俓",\"s\":[{\"n\":\"姹熷煄鍖篭"},{\"n\":\"闃宠タ鍘縗"},{\"n\":\"闃充笢鍘縗"},{\"n\":\"闃虫槬甯俓"}]},{\"n\":\"娓呰繙甯俓",\"s\":[{\"n\":\"娓呭煄鍖篭"},{\"n\":\"娓呮柊鍖篭"},{\"n\":\"浣涘唸鍘縗"},{\"n\":\"闃冲北鍘縗"},{\"n\":\"杩炲北澹棌鐟舵棌鑷不鍘縗"},{\"n\":\"杩炲崡鐟舵棌鑷不鍘縗"},{\"n\":\"鑻卞痉甯俓"},{\"n\":\"杩炲窞甯俓"}]},{\"n\":\"涓滆帪甯俓"},{\"n\":\"涓北甯俓"},{\"n\":\"娼窞甯俓",\"s\":[{\"n\":\"婀樻ˉ鍖篭"},{\"n\":\"娼畨鍖篭"},{\"n\":\"楗跺钩鍘縗"}]},{\"n\":\"鎻槼甯俓",\"s\":[{\"n\":\"姒曞煄鍖篭"},{\"n\":\"鎻笢鍖篭"},{\"n\":\"鎻タ鍘縗"},{\"n\":\"鎯犳潵鍘縗"},{\"n\":\"鏅畞甯俓"}]},{\"n\":\"浜戞诞甯俓",\"s\":[{\"n\":\"浜戝煄鍖篭"},{\"n\":\"鏂板叴鍘縗"},{\"n\":\"閮佸崡鍘縗"},{\"n\":\"浜戝畨鍘縗"},{\"n\":\"缃楀畾甯俓"}]}]}]"; + return data; + } + + /** + * 鑾峰彇鐢ㄦ埛鏁版嵁 + */ + @GetMapping("/userModel") + @ResponseBody + public AjaxResult userModel() + { + AjaxResult ajax = new AjaxResult(); + + ajax.put("code", 200); + ajax.put("value", users); + return ajax; + } + + /** + * 鑾峰彇鏁版嵁闆嗗悎 + */ + @GetMapping("/collection") + @ResponseBody + public AjaxResult collection() + { + String[] array = { "ruoyi 1", "ruoyi 2", "ruoyi 3", "ruoyi 4", "ruoyi 5" }; + AjaxResult ajax = new AjaxResult(); + ajax.put("value", array); + return ajax; + } +} + +class UserFormModel +{ + /** 鐢ㄦ埛ID */ + private int userId; + + /** 鐢ㄦ埛缂栧彿 */ + private String userCode; + + /** 鐢ㄦ埛濮撳悕 */ + private String userName; + + /** 鐢ㄦ埛鎵嬫満 */ + private String userPhone; + + public UserFormModel() + { + + } + + public UserFormModel(int userId, String userCode, String userName, String userPhone) + { + this.userId = userId; + this.userCode = userCode; + this.userName = userName; + this.userPhone = userPhone; + } + + public int getUserId() + { + return userId; + } + + public void setUserId(int userId) + { + this.userId = userId; + } + + public String getUserCode() + { + return userCode; + } + + public void setUserCode(String userCode) + { + this.userCode = userCode; + } + + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public String getUserPhone() + { + return userPhone; + } + + public void setUserPhone(String userPhone) + { + this.userPhone = userPhone; + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/controller/DemoIconController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/controller/DemoIconController.java new file mode 100644 index 000000000..b6884cc1e --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/controller/DemoIconController.java @@ -0,0 +1,35 @@ +package com.ruoyi.web.controller.demo.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * 鍥炬爣鐩稿叧 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/demo/icon") +public class DemoIconController +{ + private String prefix = "demo/icon"; + + /** + * FontAwesome鍥炬爣 + */ + @GetMapping("/fontawesome") + public String fontAwesome() + { + return prefix + "/fontawesome"; + } + + /** + * Glyphicons鍥炬爣 + */ + @GetMapping("/glyphicons") + public String glyphicons() + { + return prefix + "/glyphicons"; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/controller/DemoOperateController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/controller/DemoOperateController.java new file mode 100644 index 000000000..18cb90ab6 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/controller/DemoOperateController.java @@ -0,0 +1,326 @@ +package com.ruoyi.web.controller.demo.controller; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.PageDomain; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.page.TableSupport; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.web.controller.demo.domain.CustomerModel; +import com.ruoyi.web.controller.demo.domain.UserOperateModel; + +/** + * 鎿嶄綔鎺у埗 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/demo/operate") +public class DemoOperateController extends BaseController +{ + private String prefix = "demo/operate"; + + private final static Map users = new LinkedHashMap(); + { + users.put(1, new UserOperateModel(1, "1000001", "娴嬭瘯1", "0", "15888888888", "ry@qq.com", 150.0, "0")); + users.put(2, new UserOperateModel(2, "1000002", "娴嬭瘯2", "1", "15666666666", "ry@qq.com", 180.0, "1")); + users.put(3, new UserOperateModel(3, "1000003", "娴嬭瘯3", "0", "15666666666", "ry@qq.com", 110.0, "1")); + users.put(4, new UserOperateModel(4, "1000004", "娴嬭瘯4", "1", "15666666666", "ry@qq.com", 220.0, "1")); + users.put(5, new UserOperateModel(5, "1000005", "娴嬭瘯5", "0", "15666666666", "ry@qq.com", 140.0, "1")); + users.put(6, new UserOperateModel(6, "1000006", "娴嬭瘯6", "1", "15666666666", "ry@qq.com", 330.0, "1")); + users.put(7, new UserOperateModel(7, "1000007", "娴嬭瘯7", "0", "15666666666", "ry@qq.com", 160.0, "1")); + users.put(8, new UserOperateModel(8, "1000008", "娴嬭瘯8", "1", "15666666666", "ry@qq.com", 170.0, "1")); + users.put(9, new UserOperateModel(9, "1000009", "娴嬭瘯9", "0", "15666666666", "ry@qq.com", 180.0, "1")); + users.put(10, new UserOperateModel(10, "1000010", "娴嬭瘯10", "0", "15666666666", "ry@qq.com", 210.0, "1")); + users.put(11, new UserOperateModel(11, "1000011", "娴嬭瘯11", "1", "15666666666", "ry@qq.com", 110.0, "1")); + users.put(12, new UserOperateModel(12, "1000012", "娴嬭瘯12", "0", "15666666666", "ry@qq.com", 120.0, "1")); + users.put(13, new UserOperateModel(13, "1000013", "娴嬭瘯13", "1", "15666666666", "ry@qq.com", 380.0, "1")); + users.put(14, new UserOperateModel(14, "1000014", "娴嬭瘯14", "0", "15666666666", "ry@qq.com", 280.0, "1")); + users.put(15, new UserOperateModel(15, "1000015", "娴嬭瘯15", "0", "15666666666", "ry@qq.com", 570.0, "1")); + users.put(16, new UserOperateModel(16, "1000016", "娴嬭瘯16", "1", "15666666666", "ry@qq.com", 260.0, "1")); + users.put(17, new UserOperateModel(17, "1000017", "娴嬭瘯17", "1", "15666666666", "ry@qq.com", 210.0, "1")); + users.put(18, new UserOperateModel(18, "1000018", "娴嬭瘯18", "1", "15666666666", "ry@qq.com", 340.0, "1")); + users.put(19, new UserOperateModel(19, "1000019", "娴嬭瘯19", "1", "15666666666", "ry@qq.com", 160.0, "1")); + users.put(20, new UserOperateModel(20, "1000020", "娴嬭瘯20", "1", "15666666666", "ry@qq.com", 220.0, "1")); + users.put(21, new UserOperateModel(21, "1000021", "娴嬭瘯21", "1", "15666666666", "ry@qq.com", 120.0, "1")); + users.put(22, new UserOperateModel(22, "1000022", "娴嬭瘯22", "1", "15666666666", "ry@qq.com", 130.0, "1")); + users.put(23, new UserOperateModel(23, "1000023", "娴嬭瘯23", "1", "15666666666", "ry@qq.com", 490.0, "1")); + users.put(24, new UserOperateModel(24, "1000024", "娴嬭瘯24", "1", "15666666666", "ry@qq.com", 570.0, "1")); + users.put(25, new UserOperateModel(25, "1000025", "娴嬭瘯25", "1", "15666666666", "ry@qq.com", 250.0, "1")); + users.put(26, new UserOperateModel(26, "1000026", "娴嬭瘯26", "1", "15666666666", "ry@qq.com", 250.0, "1")); + } + + /** + * 琛ㄦ牸 + */ + @GetMapping("/table") + public String table() + { + return prefix + "/table"; + } + + /** + * 鍏朵粬 + */ + @GetMapping("/other") + public String other() + { + return prefix + "/other"; + } + + /** + * 鏌ヨ鏁版嵁 + */ + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(UserOperateModel userModel) + { + TableDataInfo rspData = new TableDataInfo(); + List userList = new ArrayList(users.values()); + // 鏌ヨ鏉′欢杩囨护 + if (StringUtils.isNotEmpty(userModel.getSearchValue())) + { + userList.clear(); + for (Map.Entry entry : users.entrySet()) + { + if (entry.getValue().getUserName().equals(userModel.getSearchValue())) + { + userList.add(entry.getValue()); + } + } + } + else if (StringUtils.isNotEmpty(userModel.getUserName())) + { + userList.clear(); + for (Map.Entry entry : users.entrySet()) + { + if (entry.getValue().getUserName().equals(userModel.getUserName())) + { + userList.add(entry.getValue()); + } + } + } + PageDomain pageDomain = TableSupport.buildPageRequest(); + if (null == pageDomain.getPageNum() || null == pageDomain.getPageSize()) + { + rspData.setRows(userList); + rspData.setTotal(userList.size()); + return rspData; + } + Integer pageNum = (pageDomain.getPageNum() - 1) * 10; + Integer pageSize = pageDomain.getPageNum() * 10; + if (pageSize > userList.size()) + { + pageSize = userList.size(); + } + rspData.setRows(userList.subList(pageNum, pageSize)); + rspData.setTotal(userList.size()); + return rspData; + } + + /** + * 鏂板鐢ㄦ埛 + */ + @GetMapping("/add") + public String add(ModelMap mmap) + { + return prefix + "/add"; + } + + /** + * 鏂板淇濆瓨鐢ㄦ埛 + */ + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(UserOperateModel user) + { + Integer userId = users.size() + 1; + user.setUserId(userId); + return AjaxResult.success(users.put(userId, user)); + } + + /** + * 鏂板淇濆瓨涓诲瓙琛ㄤ俊鎭 + */ + @PostMapping("/customer/add") + @ResponseBody + public AjaxResult addSave(CustomerModel customerModel) + { + System.out.println(customerModel.toString()); + return AjaxResult.success(); + } + + /** + * 淇敼鐢ㄦ埛 + */ + @GetMapping("/edit/{userId}") + public String edit(@PathVariable("userId") Integer userId, ModelMap mmap) + { + mmap.put("user", users.get(userId)); + return prefix + "/edit"; + } + + /** + * 淇敼淇濆瓨鐢ㄦ埛 + */ + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(UserOperateModel user) + { + return AjaxResult.success(users.put(user.getUserId(), user)); + } + + /** + * 瀵煎嚭 + */ + @PostMapping("/export") + @ResponseBody + public AjaxResult export(UserOperateModel user) + { + List list = new ArrayList(users.values()); + ExcelUtil util = new ExcelUtil(UserOperateModel.class); + return util.exportExcel(list, "鐢ㄦ埛鏁版嵁"); + } + + /** + * 涓嬭浇妯℃澘 + */ + @GetMapping("/importTemplate") + @ResponseBody + public AjaxResult importTemplate() + { + ExcelUtil util = new ExcelUtil(UserOperateModel.class); + return util.importTemplateExcel("鐢ㄦ埛鏁版嵁"); + } + + /** + * 瀵煎叆鏁版嵁 + */ + @PostMapping("/importData") + @ResponseBody + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception + { + ExcelUtil util = new ExcelUtil(UserOperateModel.class); + List userList = util.importExcel(file.getInputStream()); + String message = importUser(userList, updateSupport); + return AjaxResult.success(message); + } + + /** + * 鍒犻櫎鐢ㄦ埛 + */ + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + Integer[] userIds = Convert.toIntArray(ids); + for (Integer userId : userIds) + { + users.remove(userId); + } + return AjaxResult.success(); + } + + /** + * 鏌ョ湅璇︾粏 + */ + @GetMapping("/detail/{userId}") + public String detail(@PathVariable("userId") Integer userId, ModelMap mmap) + { + mmap.put("user", users.get(userId)); + return prefix + "/detail"; + } + + @PostMapping("/clean") + @ResponseBody + public AjaxResult clean() + { + users.clear(); + return success(); + } + + /** + * 瀵煎叆鐢ㄦ埛鏁版嵁 + * + * @param userList 鐢ㄦ埛鏁版嵁鍒楄〃 + * @param isUpdateSupport 鏄惁鏇存柊鏀寔锛屽鏋滃凡瀛樺湪锛屽垯杩涜鏇存柊鏁版嵁 + * @return 缁撴灉 + */ + public String importUser(List userList, Boolean isUpdateSupport) + { + if (StringUtils.isNull(userList) || userList.size() == 0) + { + throw new ServiceException("瀵煎叆鐢ㄦ埛鏁版嵁涓嶈兘涓虹┖锛"); + } + int successNum = 0; + int failureNum = 0; + StringBuilder successMsg = new StringBuilder(); + StringBuilder failureMsg = new StringBuilder(); + for (UserOperateModel user : userList) + { + try + { + // 楠岃瘉鏄惁瀛樺湪杩欎釜鐢ㄦ埛 + boolean userFlag = false; + for (Map.Entry entry : users.entrySet()) + { + if (entry.getValue().getUserName().equals(user.getUserName())) + { + userFlag = true; + break; + } + } + if (!userFlag) + { + Integer userId = users.size() + 1; + user.setUserId(userId); + users.put(userId, user); + successNum++; + successMsg.append("
" + successNum + "銆佺敤鎴 " + user.getUserName() + " 瀵煎叆鎴愬姛"); + } + else if (isUpdateSupport) + { + users.put(user.getUserId(), user); + successNum++; + successMsg.append("
" + successNum + "銆佺敤鎴 " + user.getUserName() + " 鏇存柊鎴愬姛"); + } + else + { + failureNum++; + failureMsg.append("
" + failureNum + "銆佺敤鎴 " + user.getUserName() + " 宸插瓨鍦"); + } + } + catch (Exception e) + { + failureNum++; + String msg = "
" + failureNum + "銆佽处鍙 " + user.getUserName() + " 瀵煎叆澶辫触锛"; + failureMsg.append(msg + e.getMessage()); + } + } + if (failureNum > 0) + { + failureMsg.insert(0, "寰堟姳姝夛紝瀵煎叆澶辫触锛佸叡 " + failureNum + " 鏉℃暟鎹牸寮忎笉姝g‘锛岄敊璇涓嬶細"); + throw new ServiceException(failureMsg.toString()); + } + else + { + successMsg.insert(0, "鎭枩鎮紝鏁版嵁宸插叏閮ㄥ鍏ユ垚鍔燂紒鍏 " + successNum + " 鏉★紝鏁版嵁濡備笅锛"); + } + return successMsg.toString(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/controller/DemoReportController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/controller/DemoReportController.java new file mode 100644 index 000000000..610100874 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/controller/DemoReportController.java @@ -0,0 +1,53 @@ +package com.ruoyi.web.controller.demo.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * 鎶ヨ〃 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/demo/report") +public class DemoReportController +{ + private String prefix = "demo/report"; + + /** + * 鐧惧害ECharts + */ + @GetMapping("/echarts") + public String echarts() + { + return prefix + "/echarts"; + } + + /** + * 鍥捐〃鎻掍欢 + */ + @GetMapping("/peity") + public String peity() + { + return prefix + "/peity"; + } + + /** + * 绾跨姸鍥炬彃浠 + */ + @GetMapping("/sparkline") + public String sparkline() + { + return prefix + "/sparkline"; + } + + /** + * 鍥捐〃缁勫悎 + */ + @GetMapping("/metrics") + public String metrics() + { + return prefix + "/metrics"; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/controller/DemoTableController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/controller/DemoTableController.java new file mode 100644 index 000000000..71f411a12 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/controller/DemoTableController.java @@ -0,0 +1,846 @@ +package com.ruoyi.web.controller.demo.controller; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.annotation.Excel.ColumnType; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.PageDomain; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.page.TableSupport; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; + +/** + * 琛ㄦ牸鐩稿叧 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/demo/table") +public class DemoTableController extends BaseController +{ + private String prefix = "demo/table"; + + private final static List users = new ArrayList(); + { + users.add(new UserTableModel(1, "1000001", "娴嬭瘯1", "0", "15888888888", "ry@qq.com", 150.0, "0")); + users.add(new UserTableModel(2, "1000002", "娴嬭瘯2", "1", "15666666666", "ry@qq.com", 180.0, "1")); + users.add(new UserTableModel(3, "1000003", "娴嬭瘯3", "0", "15666666666", "ry@qq.com", 110.0, "1")); + users.add(new UserTableModel(4, "1000004", "娴嬭瘯4", "1", "15666666666", "ry@qq.com", 220.0, "1")); + users.add(new UserTableModel(5, "1000005", "娴嬭瘯5", "0", "15666666666", "ry@qq.com", 140.0, "1")); + users.add(new UserTableModel(6, "1000006", "娴嬭瘯6", "1", "15666666666", "ry@qq.com", 330.0, "1")); + users.add(new UserTableModel(7, "1000007", "娴嬭瘯7", "0", "15666666666", "ry@qq.com", 160.0, "1")); + users.add(new UserTableModel(8, "1000008", "娴嬭瘯8", "1", "15666666666", "ry@qq.com", 170.0, "1")); + users.add(new UserTableModel(9, "1000009", "娴嬭瘯9", "0", "15666666666", "ry@qq.com", 180.0, "1")); + users.add(new UserTableModel(10, "1000010", "娴嬭瘯10", "0", "15666666666", "ry@qq.com", 210.0, "1")); + users.add(new UserTableModel(11, "1000011", "娴嬭瘯11", "1", "15666666666", "ry@qq.com", 110.0, "1")); + users.add(new UserTableModel(12, "1000012", "娴嬭瘯12", "0", "15666666666", "ry@qq.com", 120.0, "1")); + users.add(new UserTableModel(13, "1000013", "娴嬭瘯13", "1", "15666666666", "ry@qq.com", 380.0, "1")); + users.add(new UserTableModel(14, "1000014", "娴嬭瘯14", "0", "15666666666", "ry@qq.com", 280.0, "1")); + users.add(new UserTableModel(15, "1000015", "娴嬭瘯15", "0", "15666666666", "ry@qq.com", 570.0, "1")); + users.add(new UserTableModel(16, "1000016", "娴嬭瘯16", "1", "15666666666", "ry@qq.com", 260.0, "1")); + users.add(new UserTableModel(17, "1000017", "娴嬭瘯17", "1", "15666666666", "ry@qq.com", 210.0, "1")); + users.add(new UserTableModel(18, "1000018", "娴嬭瘯18", "1", "15666666666", "ry@qq.com", 340.0, "1")); + users.add(new UserTableModel(19, "1000019", "娴嬭瘯19", "1", "15666666666", "ry@qq.com", 160.0, "1")); + users.add(new UserTableModel(20, "1000020", "娴嬭瘯20", "1", "15666666666", "ry@qq.com", 220.0, "1")); + users.add(new UserTableModel(21, "1000021", "娴嬭瘯21", "1", "15666666666", "ry@qq.com", 120.0, "1")); + users.add(new UserTableModel(22, "1000022", "娴嬭瘯22", "1", "15666666666", "ry@qq.com", 130.0, "1")); + users.add(new UserTableModel(23, "1000023", "娴嬭瘯23", "1", "15666666666", "ry@qq.com", 490.0, "1")); + users.add(new UserTableModel(24, "1000024", "娴嬭瘯24", "1", "15666666666", "ry@qq.com", 570.0, "1")); + users.add(new UserTableModel(25, "1000025", "娴嬭瘯25", "1", "15666666666", "ry@qq.com", 250.0, "1")); + users.add(new UserTableModel(26, "1000026", "娴嬭瘯26", "1", "15666666666", "ry@qq.com", 250.0, "1")); + } + + private final static List areas = new ArrayList(); + { + areas.add(new AreaModel(1, 0, "骞夸笢鐪", "440000", "GDS", "GuangDongSheng", 1)); + areas.add(new AreaModel(2, 0, "婀栧崡鐪", "430000", "HNS", "HuNanSheng", 1)); + areas.add(new AreaModel(3, 0, "娌冲崡鐪", "410000", "HNS", "HeNanSheng", 0)); + areas.add(new AreaModel(4, 0, "婀栧寳鐪", "420000", "HBS", "HuBeiSheng", 0)); + areas.add(new AreaModel(5, 0, "杈藉畞鐪", "210000", "LNS", "LiaoNingSheng", 0)); + areas.add(new AreaModel(6, 0, "灞变笢鐪", "370000", "SDS", "ShanDongSheng", 0)); + areas.add(new AreaModel(7, 0, "闄曡タ鐪", "610000", "SXS", "ShanXiSheng", 0)); + areas.add(new AreaModel(8, 0, "璐靛窞鐪", "520000", "GZS", "GuiZhouSheng", 0)); + areas.add(new AreaModel(9, 0, "涓婃捣甯", "310000", "SHS", "ShangHaiShi", 0)); + areas.add(new AreaModel(10, 0, "閲嶅簡甯", "500000", "CQS", "ChongQingShi", 0)); + areas.add(new AreaModel(11, 0, "鑻ヤ緷鐪", "666666", "YYS", "RuoYiSheng", 0)); + areas.add(new AreaModel(12, 0, "瀹夊窘鐪", "340000", "AHS", "AnHuiSheng", 0)); + areas.add(new AreaModel(13, 0, "绂忓缓鐪", "350000", "FJS", "FuJianSheng", 0)); + areas.add(new AreaModel(14, 0, "娴峰崡鐪", "460000", "HNS", "HaiNanSheng", 0)); + areas.add(new AreaModel(15, 0, "姹熻嫃鐪", "320000", "JSS", "JiangSuSheng", 0)); + areas.add(new AreaModel(16, 0, "闈掓捣鐪", "630000", "QHS", "QingHaiSheng", 0)); + areas.add(new AreaModel(17, 0, "骞胯タ澹棌鑷不鍖", "450000", "GXZZZZQ", "GuangXiZhuangZuZiZhiQu", 0)); + areas.add(new AreaModel(18, 0, "瀹佸鍥炴棌鑷不鍖", "640000", "NXHZZZQ", "NingXiaHuiZuZiZhiQu", 0)); + areas.add(new AreaModel(19, 0, "鍐呰挋鍙よ嚜娌诲尯", "150000", "NMGZZQ", "NeiMengGuZiZhiQu", 0)); + areas.add(new AreaModel(20, 0, "鏂扮枂缁村惥灏旇嚜娌诲尯", "650000", "XJWWEZZQ", "XinJiangWeiWuErZiZhiQu", 0)); + areas.add(new AreaModel(21, 0, "姹熻タ鐪", "360000", "JXS", "JiangXiSheng", 0)); + areas.add(new AreaModel(22, 0, "娴欐睙鐪", "330000", "ZJS", "ZheJiangSheng", 0)); + areas.add(new AreaModel(23, 0, "娌冲寳鐪", "130000", "HBS", "HeBeiSheng", 0)); + areas.add(new AreaModel(24, 0, "澶╂触甯", "120000", "TJS", "TianJinShi", 0)); + areas.add(new AreaModel(25, 0, "灞辫タ鐪", "140000", "SXS", "ShanXiSheng", 0)); + areas.add(new AreaModel(26, 0, "鍙版咕鐪", "710000", "TWS", "TaiWanSheng", 0)); + areas.add(new AreaModel(27, 0, "鐢樿們鐪", "620000", "GSS", "GanSuSheng", 0)); + areas.add(new AreaModel(28, 0, "鍥涘窛鐪", "510000", "SCS", "SiChuanSheng", 0)); + areas.add(new AreaModel(29, 0, "浜戝崡鐪", "530000", "YNS", "YunNanSheng", 0)); + areas.add(new AreaModel(30, 0, "鍖椾含甯", "110000", "BJS", "BeiJingShi", 0)); + areas.add(new AreaModel(31, 0, "棣欐腐鐗瑰埆琛屾斂鍖", "810000", "XGTBXZQ", "XiangGangTeBieXingZhengQu", 0)); + areas.add(new AreaModel(32, 0, "婢抽棬鐗瑰埆琛屾斂鍖", "820000", "AMTBXZQ", "AoMenTeBieXingZhengQu", 0)); + + areas.add(new AreaModel(100, 1, "娣卞湷甯", "440300", "SZS", "ShenZhenShi", 1)); + areas.add(new AreaModel(101, 1, "骞垮窞甯", "440100", "GZS", "GuangZhouShi", 0)); + areas.add(new AreaModel(102, 1, "涓滆帪甯", "441900", "DGS", "DongGuanShi", 0)); + areas.add(new AreaModel(103, 2, "闀挎矙甯", "410005", "CSS", "ChangShaShi", 1)); + areas.add(new AreaModel(104, 2, "宀抽槼甯", "414000", "YYS", "YueYangShi", 0)); + + areas.add(new AreaModel(1000, 100, "榫欏矖鍖", "518172", "LGQ", "LongGangQu", 0)); + areas.add(new AreaModel(1001, 100, "鍗楀北鍖", "518051", "NSQ", "NanShanQu", 0)); + areas.add(new AreaModel(1002, 100, "瀹濆畨鍖", "518101", "BAQ", "BaoAnQu", 0)); + areas.add(new AreaModel(1003, 100, "绂忕敯鍖", "518081", "FTQ", "FuTianQu", 0)); + areas.add(new AreaModel(1004, 103, "澶╁績鍖", "410004", "TXQ", "TianXinQu", 0)); + areas.add(new AreaModel(1005, 103, "寮绂忓尯", "410008", "KFQ", "KaiFuQu", 0)); + areas.add(new AreaModel(1006, 103, "鑺欒搲鍖", "410011", "FRQ", "FuRongQu", 0)); + areas.add(new AreaModel(1007, 103, "闆ㄨ姳鍖", "410011", "YHQ", "YuHuaQu", 0)); + } + + private final static List columns = new ArrayList(); + { + columns.add(new UserTableColumn("鐢ㄦ埛ID", "userId")); + columns.add(new UserTableColumn("鐢ㄦ埛缂栧彿", "userCode")); + columns.add(new UserTableColumn("鐢ㄦ埛濮撳悕", "userName")); + columns.add(new UserTableColumn("鐢ㄦ埛鎵嬫満", "userPhone")); + columns.add(new UserTableColumn("鐢ㄦ埛閭", "userEmail")); + columns.add(new UserTableColumn("鐢ㄦ埛鐘舵", "status")); + } + + /** + * 鎼滅储鐩稿叧 + */ + @GetMapping("/search") + public String search() + { + return prefix + "/search"; + } + + /** + * 鏁版嵁姹囨 + */ + @GetMapping("/footer") + public String footer() + { + return prefix + "/footer"; + } + + /** + * 缁勫悎琛ㄥご + */ + @GetMapping("/groupHeader") + public String groupHeader() + { + return prefix + "/groupHeader"; + } + + /** + * 琛ㄦ牸瀵煎嚭 + */ + @GetMapping("/export") + public String export() + { + return prefix + "/export"; + } + + /** + * 琛ㄦ牸瀵煎嚭閫夋嫨鍒 + */ + @GetMapping("/exportSelected") + public String exportSelected() + { + return prefix + "/exportSelected"; + } + + /** + * 瀵煎嚭鏁版嵁 + */ + @PostMapping("/exportData") + @ResponseBody + public AjaxResult exportSelected(UserTableModel userModel, String userIds) + { + List userList = new ArrayList(Arrays.asList(new UserTableModel[users.size()])); + Collections.copy(userList, users); + + // 鏉′欢杩囨护 + if (StringUtils.isNotEmpty(userIds)) + { + userList.clear(); + for (Long userId : Convert.toLongArray(userIds)) + { + for (UserTableModel user : users) + { + if (user.getUserId() == userId) + { + userList.add(user); + } + } + } + } + ExcelUtil util = new ExcelUtil(UserTableModel.class); + return util.exportExcel(userList, "鐢ㄦ埛鏁版嵁"); + } + + /** + * 缈婚〉璁颁綇閫夋嫨 + */ + @GetMapping("/remember") + public String remember() + { + return prefix + "/remember"; + } + + /** + * 璺宠浆鑷虫寚瀹氶〉 + */ + @GetMapping("/pageGo") + public String pageGo() + { + return prefix + "/pageGo"; + } + + /** + * 鑷畾涔夋煡璇㈠弬鏁 + */ + @GetMapping("/params") + public String params() + { + return prefix + "/params"; + } + + /** + * 澶氳〃鏍 + */ + @GetMapping("/multi") + public String multi() + { + return prefix + "/multi"; + } + + /** + * 鐐瑰嚮鎸夐挳鍔犺浇琛ㄦ牸 + */ + @GetMapping("/button") + public String button() + { + return prefix + "/button"; + } + + /** + * 鐩存帴鍔犺浇琛ㄦ牸鏁版嵁 + */ + @GetMapping("/data") + public String data(ModelMap mmap) + { + mmap.put("users", users); + return prefix + "/data"; + } + + /** + * 琛ㄦ牸鍐荤粨鍒 + */ + @GetMapping("/fixedColumns") + public String fixedColumns() + { + return prefix + "/fixedColumns"; + } + + /** + * 鑷畾涔夎Е鍙戜簨浠 + */ + @GetMapping("/event") + public String event() + { + return prefix + "/event"; + } + + /** + * 琛ㄦ牸缁嗚妭瑙嗗浘 + */ + @GetMapping("/detail") + public String detail() + { + return prefix + "/detail"; + } + + /** + * 琛ㄦ牸鐖跺瓙瑙嗗浘 + */ + @GetMapping("/child") + public String child() + { + return prefix + "/child"; + } + + /** + * 琛ㄦ牸鍥剧墖棰勮 + */ + @GetMapping("/image") + public String image() + { + return prefix + "/image"; + } + + /** + * 鍔ㄦ佸鍒犳敼鏌 + */ + @GetMapping("/curd") + public String curd() + { + return prefix + "/curd"; + } + + /** + * 琛ㄦ牸琛屾嫋鎷芥搷浣 + */ + @GetMapping("/reorderRows") + public String reorderRows() + { + return prefix + "/reorderRows"; + } + + /** + * 琛ㄦ牸鍒楁嫋鎷芥搷浣 + */ + @GetMapping("/reorderColumns") + public String reorderColumns() + { + return prefix + "/reorderColumns"; + } + + /** + * 琛ㄦ牸鍒楀鎷栧姩 + */ + @GetMapping("/resizable") + public String resizable() + { + return prefix + "/resizable"; + } + + /** + * 琛ㄦ牸琛屽唴缂栬緫鎿嶄綔 + */ + @GetMapping("/editable") + public String editable() + { + return prefix + "/editable"; + } + + /** + * 涓诲瓙琛ㄦ彁浜 + */ + @GetMapping("/subdata") + public String subdata() + { + return prefix + "/subdata"; + } + + /** + * 琛ㄦ牸鑷姩鍒锋柊 + */ + @GetMapping("/refresh") + public String refresh() + { + return prefix + "/refresh"; + } + + /** + * 琛ㄦ牸鎵撳嵃閰嶇疆 + */ + @GetMapping("/print") + public String print() + { + return prefix + "/print"; + } + + /** + * 琛ㄦ牸鏍囬鏍煎紡鍖 + */ + @GetMapping("/headerStyle") + public String headerStyle() + { + return prefix + "/headerStyle"; + } + + /** + * 琛ㄦ牸鍔ㄦ佸垪 + */ + @GetMapping("/dynamicColumns") + public String dynamicColumns() + { + return prefix + "/dynamicColumns"; + } + + /** + * 鑷畾涔夎鍥惧垎椤 + */ + @GetMapping("/customView") + public String customView() + { + return prefix + "/customView"; + } + + /** + * 寮傛鍔犺浇琛ㄦ牸鏍 + */ + @GetMapping("/asynTree") + public String asynTree() + { + return prefix + "/asynTree"; + } + + /** + * 琛ㄦ牸鍏朵粬鎿嶄綔 + */ + @GetMapping("/other") + public String other() + { + return prefix + "/other"; + } + + /** + * 鍔ㄦ佽幏鍙栧垪 + */ + @PostMapping("/ajaxColumns") + @ResponseBody + public AjaxResult ajaxColumns(UserTableColumn userColumn) + { + List columnList = new ArrayList(Arrays.asList(new UserTableColumn[columns.size()])); + Collections.copy(columnList, columns); + if (userColumn != null && "userBalance".equals(userColumn.getField())) + { + columnList.add(new UserTableColumn("鐢ㄦ埛浣欓", "userBalance")); + } + return AjaxResult.success(columnList); + } + + /** + * 鏌ヨ鏁版嵁 + */ + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(UserTableModel userModel) + { + TableDataInfo rspData = new TableDataInfo(); + List userList = new ArrayList(Arrays.asList(new UserTableModel[users.size()])); + Collections.copy(userList, users); + // 鏌ヨ鏉′欢杩囨护 + if (StringUtils.isNotEmpty(userModel.getUserName())) + { + userList.clear(); + for (UserTableModel user : users) + { + if (user.getUserName().equals(userModel.getUserName())) + { + userList.add(user); + } + } + } + PageDomain pageDomain = TableSupport.buildPageRequest(); + if (null == pageDomain.getPageNum() || null == pageDomain.getPageSize()) + { + rspData.setRows(userList); + rspData.setTotal(userList.size()); + return rspData; + } + Integer pageNum = (pageDomain.getPageNum() - 1) * 10; + Integer pageSize = pageDomain.getPageNum() * 10; + if (pageSize > userList.size()) + { + pageSize = userList.size(); + } + rspData.setRows(userList.subList(pageNum, pageSize)); + rspData.setTotal(userList.size()); + return rspData; + } + + /** + * 鏌ヨ鏍戣〃鏁版嵁 + */ + @PostMapping("/tree/list") + @ResponseBody + public TableDataInfo treeList(AreaModel areaModel) + { + TableDataInfo rspData = new TableDataInfo(); + List areaList = new ArrayList(Arrays.asList(new AreaModel[areas.size()])); + // 榛樿鏌ヨ鏉′欢 parentId 0 + Collections.copy(areaList, areas); + areaList.clear(); + if (StringUtils.isNotEmpty(areaModel.getAreaName())) + { + for (AreaModel area : areas) + { + if (area.getParentId() == 0 && area.getAreaName().equals(areaModel.getAreaName())) + { + areaList.add(area); + } + } + } + else + { + for (AreaModel area : areas) + { + if (area.getParentId() == 0) + { + areaList.add(area); + } + } + } + PageDomain pageDomain = TableSupport.buildPageRequest(); + Integer pageNum = (pageDomain.getPageNum() - 1) * 10; + Integer pageSize = pageDomain.getPageNum() * 10; + if (pageSize > areaList.size()) + { + pageSize = areaList.size(); + } + rspData.setRows(areaList.subList(pageNum, pageSize)); + rspData.setTotal(areaList.size()); + return rspData; + } + + /** + * 鏌ヨ鏍戣〃瀛愯妭鐐规暟鎹 + */ + @PostMapping("/tree/listChild") + @ResponseBody + public List listChild(AreaModel areaModel) + { + List areaList = new ArrayList(Arrays.asList(new AreaModel[areas.size()])); + // 鏌ヨ鏉′欢 parentId + Collections.copy(areaList, areas); + areaList.clear(); + if (StringUtils.isNotEmpty(areaModel.getAreaName())) + { + for (AreaModel area : areas) + { + if (area.getParentId().intValue() == areaModel.getParentId().intValue() && area.getAreaName().equals(areaModel.getAreaName())) + { + areaList.add(area); + } + } + } + else + { + for (AreaModel area : areas) + { + if (area.getParentId().intValue() == areaModel.getParentId().intValue()) + { + areaList.add(area); + } + } + } + return areaList; + } +} + +class UserTableColumn +{ + /** 琛ㄥご */ + private String title; + /** 瀛楁 */ + private String field; + + public UserTableColumn() + { + + } + + public UserTableColumn(String title, String field) + { + this.title = title; + this.field = field; + } + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } + + public String getField() + { + return field; + } + + public void setField(String field) + { + this.field = field; + } +} + +class UserTableModel +{ + /** 鐢ㄦ埛ID */ + private int userId; + + /** 鐢ㄦ埛缂栧彿 */ + @Excel(name = "鐢ㄦ埛缂栧彿", cellType = ColumnType.NUMERIC) + private String userCode; + + /** 鐢ㄦ埛濮撳悕 */ + @Excel(name = "鐢ㄦ埛濮撳悕") + private String userName; + + /** 鐢ㄦ埛鎬у埆 */ + private String userSex; + + /** 鐢ㄦ埛鎵嬫満 */ + @Excel(name = "鐢ㄦ埛鎵嬫満") + private String userPhone; + + /** 鐢ㄦ埛閭 */ + @Excel(name = "鐢ㄦ埛閭") + private String userEmail; + + /** 鐢ㄦ埛浣欓 */ + @Excel(name = "鐢ㄦ埛浣欓", cellType = ColumnType.NUMERIC) + private double userBalance; + + /** 鐢ㄦ埛鐘舵侊紙0姝e父 1鍋滅敤锛 */ + private String status; + + /** 鍒涘缓鏃堕棿 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + public UserTableModel() + { + + } + + public UserTableModel(int userId, String userCode, String userName, String userSex, String userPhone, + String userEmail, double userBalance, String status) + { + this.userId = userId; + this.userCode = userCode; + this.userName = userName; + this.userSex = userSex; + this.userPhone = userPhone; + this.userEmail = userEmail; + this.userBalance = userBalance; + this.status = status; + this.createTime = DateUtils.getNowDate(); + } + + public int getUserId() + { + return userId; + } + + public void setUserId(int userId) + { + this.userId = userId; + } + + public String getUserCode() + { + return userCode; + } + + public void setUserCode(String userCode) + { + this.userCode = userCode; + } + + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public String getUserSex() + { + return userSex; + } + + public void setUserSex(String userSex) + { + this.userSex = userSex; + } + + public String getUserPhone() + { + return userPhone; + } + + public void setUserPhone(String userPhone) + { + this.userPhone = userPhone; + } + + public String getUserEmail() + { + return userEmail; + } + + public void setUserEmail(String userEmail) + { + this.userEmail = userEmail; + } + + public double getUserBalance() + { + return userBalance; + } + + public void setUserBalance(double userBalance) + { + this.userBalance = userBalance; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public Date getCreateTime() + { + return createTime; + } + + public void setCreateTime(Date createTime) + { + this.createTime = createTime; + } +} +class AreaModel +{ + /** 缂栧彿 */ + private Long id; + + /** 鐖剁紪鍙 */ + private Long parentId; + + /** 鍖哄煙鍚嶇О */ + private String areaName; + + /** 鍖哄煙浠g爜 */ + private String areaCode; + + /** 鍚嶇О棣栧瓧姣 */ + private String simplePy; + + /** 鍚嶇О鍏ㄦ嫾 */ + private String pinYin; + + /** 鏄惁鏈夊瓙鑺傜偣锛0鏃 1鏈夛級 */ + private Integer isTreeLeaf = 1; + + public AreaModel() + { + + } + + public AreaModel(int id, int parentId, String areaName, String areaCode, String simplePy, String pinYin, Integer isTreeLeaf) + { + this.id = Long.valueOf(id); + this.parentId = Long.valueOf(parentId); + this.areaName = areaName; + this.areaCode = areaCode; + this.simplePy = simplePy; + this.pinYin = pinYin; + this.isTreeLeaf = isTreeLeaf; + } + + public Long getId() + { + return id; + } + + public void setId(Long id) + { + this.id = id; + } + + public Long getParentId() + { + return parentId; + } + + public void setParentId(Long parentId) + { + this.parentId = parentId; + } + + public String getAreaName() + { + return areaName; + } + + public void setAreaName(String areaName) + { + this.areaName = areaName; + } + + public String getAreaCode() + { + return areaCode; + } + + public void setAreaCode(String areaCode) + { + this.areaCode = areaCode; + } + + public String getSimplePy() + { + return simplePy; + } + + public void setSimplePy(String simplePy) + { + this.simplePy = simplePy; + } + + public String getPinYin() + { + return pinYin; + } + + public void setPinYin(String pinYin) + { + this.pinYin = pinYin; + } + + public Integer getIsTreeLeaf() + { + return isTreeLeaf; + } + + public void setIsTreeLeaf(Integer isTreeLeaf) + { + this.isTreeLeaf = isTreeLeaf; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/domain/CustomerModel.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/domain/CustomerModel.java new file mode 100644 index 000000000..5e7d6e55d --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/domain/CustomerModel.java @@ -0,0 +1,116 @@ +package com.ruoyi.web.controller.demo.domain; + +import java.util.List; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 瀹㈡埛娴嬭瘯淇℃伅 + * + * @author ruoyi + */ +public class CustomerModel +{ + /** + * 瀹㈡埛濮撳悕 + */ + private String name; + + /** + * 瀹㈡埛鎵嬫満 + */ + private String phonenumber; + + /** + * 瀹㈡埛鎬у埆 + */ + private String sex; + + /** + * 瀹㈡埛鐢熸棩 + */ + private String birthday; + + /** + * 瀹㈡埛鎻忚堪 + */ + private String remark; + + /** + * 鍟嗗搧淇℃伅 + */ + private List goods; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getPhonenumber() + { + return phonenumber; + } + + public void setPhonenumber(String phonenumber) + { + this.phonenumber = phonenumber; + } + + + public String getSex() + { + return sex; + } + + public void setSex(String sex) + { + this.sex = sex; + } + + public String getBirthday() + { + return birthday; + } + + public void setBirthday(String birthday) + { + this.birthday = birthday; + } + + public String getRemark() + { + return remark; + } + + public void setRemark(String remark) + { + this.remark = remark; + } + + public List getGoods() + { + return goods; + } + + public void setGoods(List goods) + { + this.goods = goods; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("name", getName()) + .append("phonenumber", getPhonenumber()) + .append("sex", getSex()) + .append("birthday", getBirthday()) + .append("goods", getGoods()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/domain/GoodsModel.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/domain/GoodsModel.java new file mode 100644 index 000000000..b25542a08 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/domain/GoodsModel.java @@ -0,0 +1,99 @@ +package com.ruoyi.web.controller.demo.domain; + +import java.util.Date; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 鍟嗗搧娴嬭瘯淇℃伅 + * + * @author ruoyi + */ +public class GoodsModel +{ + /** + * 鍟嗗搧鍚嶇О + */ + private String name; + + /** + * 鍟嗗搧閲嶉噺 + */ + private Integer weight; + + /** + * 鍟嗗搧浠锋牸 + */ + private Double price; + + /** + * 鍟嗗搧鏃ユ湡 + */ + private Date date; + + /** + * 鍟嗗搧绉嶇被 + */ + private String type; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public Integer getWeight() + { + return weight; + } + + public void setWeight(Integer weight) + { + this.weight = weight; + } + + public Double getPrice() + { + return price; + } + + public void setPrice(Double price) + { + this.price = price; + } + + public Date getDate() + { + return date; + } + + public void setDate(Date date) + { + this.date = date; + } + + public String getType() + { + return type; + } + + public void setType(String type) + { + this.type = type; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("name", getName()) + .append("weight", getWeight()) + .append("price", getPrice()) + .append("date", getDate()) + .append("type", getType()) + .toString(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/domain/UserOperateModel.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/domain/UserOperateModel.java new file mode 100644 index 000000000..8b158aa10 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/domain/UserOperateModel.java @@ -0,0 +1,149 @@ +package com.ruoyi.web.controller.demo.domain; + +import java.util.Date; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.annotation.Excel.Type; +import com.ruoyi.common.core.domain.BaseEntity; +import com.ruoyi.common.utils.DateUtils; + +public class UserOperateModel extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + private int userId; + + @Excel(name = "鐢ㄦ埛缂栧彿") + private String userCode; + + @Excel(name = "鐢ㄦ埛濮撳悕") + private String userName; + + @Excel(name = "鐢ㄦ埛鎬у埆", readConverterExp = "0=鐢,1=濂,2=鏈煡") + private String userSex; + + @Excel(name = "鐢ㄦ埛鎵嬫満") + private String userPhone; + + @Excel(name = "鐢ㄦ埛閭") + private String userEmail; + + @Excel(name = "鐢ㄦ埛浣欓") + private double userBalance; + + @Excel(name = "鐢ㄦ埛鐘舵", readConverterExp = "0=姝e父,1=鍋滅敤") + private String status; + + @Excel(name = "鍒涘缓鏃堕棿", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT) + private Date createTime; + + public UserOperateModel() + { + + } + + public UserOperateModel(int userId, String userCode, String userName, String userSex, String userPhone, + String userEmail, double userBalance, String status) + { + this.userId = userId; + this.userCode = userCode; + this.userName = userName; + this.userSex = userSex; + this.userPhone = userPhone; + this.userEmail = userEmail; + this.userBalance = userBalance; + this.status = status; + this.createTime = DateUtils.getNowDate(); + } + + public int getUserId() + { + return userId; + } + + public void setUserId(int userId) + { + this.userId = userId; + } + + public String getUserCode() + { + return userCode; + } + + public void setUserCode(String userCode) + { + this.userCode = userCode; + } + + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public String getUserSex() + { + return userSex; + } + + public void setUserSex(String userSex) + { + this.userSex = userSex; + } + + public String getUserPhone() + { + return userPhone; + } + + public void setUserPhone(String userPhone) + { + this.userPhone = userPhone; + } + + public String getUserEmail() + { + return userEmail; + } + + public void setUserEmail(String userEmail) + { + this.userEmail = userEmail; + } + + public double getUserBalance() + { + return userBalance; + } + + public void setUserBalance(double userBalance) + { + this.userBalance = userBalance; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Override + public Date getCreateTime() + { + return createTime; + } + + @Override + public void setCreateTime(Date createTime) + { + this.createTime = createTime; + } +} \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java new file mode 100644 index 000000000..baeb2b837 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java @@ -0,0 +1,90 @@ +package com.ruoyi.web.controller.monitor; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.framework.web.service.CacheService; + +/** + * 缂撳瓨鐩戞帶 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/monitor/cache") +public class CacheController extends BaseController +{ + private String prefix = "monitor/cache"; + + @Autowired + private CacheService cacheService; + + @RequiresPermissions("monitor:cache:view") + @GetMapping() + public String cache(ModelMap mmap) + { + mmap.put("cacheNames", cacheService.getCacheNames()); + return prefix + "/cache"; + } + + @RequiresPermissions("monitor:cache:view") + @PostMapping("/getNames") + public String getCacheNames(String fragment, ModelMap mmap) + { + mmap.put("cacheNames", cacheService.getCacheNames()); + return prefix + "/cache::" + fragment; + } + + @RequiresPermissions("monitor:cache:view") + @PostMapping("/getKeys") + public String getCacheKeys(String fragment, String cacheName, ModelMap mmap) + { + mmap.put("cacheName", cacheName); + mmap.put("cacheKeys", cacheService.getCacheKeys(cacheName)); + return prefix + "/cache::" + fragment; + } + + @RequiresPermissions("monitor:cache:view") + @PostMapping("/getValue") + public String getCacheValue(String fragment, String cacheName, String cacheKey, ModelMap mmap) + { + mmap.put("cacheName", cacheName); + mmap.put("cacheKey", cacheKey); + mmap.put("cacheValue", cacheService.getCacheValue(cacheName, cacheKey)); + return prefix + "/cache::" + fragment; + } + + @RequiresPermissions("monitor:cache:view") + @PostMapping("/clearCacheName") + @ResponseBody + public AjaxResult clearCacheName(String cacheName, ModelMap mmap) + { + cacheService.clearCacheName(cacheName); + return AjaxResult.success(); + } + + @RequiresPermissions("monitor:cache:view") + @PostMapping("/clearCacheKey") + @ResponseBody + public AjaxResult clearCacheKey(String cacheName, String cacheKey, ModelMap mmap) + { + cacheService.clearCacheKey(cacheName, cacheKey); + return AjaxResult.success(); + } + + @RequiresPermissions("monitor:cache:view") + @GetMapping("/clearAll") + @ResponseBody + public AjaxResult clearAll(ModelMap mmap) + { + cacheService.clearAll(); + return AjaxResult.success(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/DruidController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/DruidController.java new file mode 100644 index 000000000..a51bf2030 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/DruidController.java @@ -0,0 +1,26 @@ +package com.ruoyi.web.controller.monitor; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import com.ruoyi.common.core.controller.BaseController; + +/** + * druid 鐩戞帶 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/monitor/data") +public class DruidController extends BaseController +{ + private String prefix = "/druid"; + + @RequiresPermissions("monitor:data:view") + @GetMapping() + public String index() + { + return redirect(prefix + "/index.html"); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/ServerController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/ServerController.java new file mode 100644 index 000000000..386b5c7da --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/ServerController.java @@ -0,0 +1,31 @@ +package com.ruoyi.web.controller.monitor; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.framework.web.domain.Server; + +/** + * 鏈嶅姟鍣ㄧ洃鎺 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/monitor/server") +public class ServerController extends BaseController +{ + private String prefix = "monitor/server"; + + @RequiresPermissions("monitor:server:view") + @GetMapping() + public String server(ModelMap mmap) throws Exception + { + Server server = new Server(); + server.copyTo(); + mmap.put("server", server); + return prefix + "/server"; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java new file mode 100644 index 000000000..0d30e427b --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysLogininforController.java @@ -0,0 +1,94 @@ +package com.ruoyi.web.controller.monitor; + +import java.util.List; +import com.ruoyi.framework.shiro.service.SysPasswordService; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.domain.SysLogininfor; +import com.ruoyi.system.service.ISysLogininforService; + +/** + * 绯荤粺璁块棶璁板綍 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/monitor/logininfor") +public class SysLogininforController extends BaseController +{ + private String prefix = "monitor/logininfor"; + + @Autowired + private ISysLogininforService logininforService; + + @Autowired + private SysPasswordService passwordService; + + @RequiresPermissions("monitor:logininfor:view") + @GetMapping() + public String logininfor() + { + return prefix + "/logininfor"; + } + + @RequiresPermissions("monitor:logininfor:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(SysLogininfor logininfor) + { + startPage(); + List list = logininforService.selectLogininforList(logininfor); + return getDataTable(list); + } + + @Log(title = "鐧诲綍鏃ュ織", businessType = BusinessType.EXPORT) + @RequiresPermissions("monitor:logininfor:export") + @PostMapping("/export") + @ResponseBody + public AjaxResult export(SysLogininfor logininfor) + { + List list = logininforService.selectLogininforList(logininfor); + ExcelUtil util = new ExcelUtil(SysLogininfor.class); + return util.exportExcel(list, "鐧诲綍鏃ュ織"); + } + + @RequiresPermissions("monitor:logininfor:remove") + @Log(title = "鐧诲綍鏃ュ織", businessType = BusinessType.DELETE) + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + return toAjax(logininforService.deleteLogininforByIds(ids)); + } + + @RequiresPermissions("monitor:logininfor:remove") + @Log(title = "鐧诲綍鏃ュ織", businessType = BusinessType.CLEAN) + @PostMapping("/clean") + @ResponseBody + public AjaxResult clean() + { + logininforService.cleanLogininfor(); + return success(); + } + + @RequiresPermissions("monitor:logininfor:unlock") + @Log(title = "璐︽埛瑙i攣", businessType = BusinessType.OTHER) + @PostMapping("/unlock") + @ResponseBody + public AjaxResult unlock(String loginName) + { + passwordService.clearLoginRecordCache(loginName); + return success(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java new file mode 100644 index 000000000..cddd972dd --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysOperlogController.java @@ -0,0 +1,90 @@ +package com.ruoyi.web.controller.monitor; + +import java.util.List; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.domain.SysOperLog; +import com.ruoyi.system.service.ISysOperLogService; + +/** + * 鎿嶄綔鏃ュ織璁板綍 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/monitor/operlog") +public class SysOperlogController extends BaseController +{ + private String prefix = "monitor/operlog"; + + @Autowired + private ISysOperLogService operLogService; + + @RequiresPermissions("monitor:operlog:view") + @GetMapping() + public String operlog() + { + return prefix + "/operlog"; + } + + @RequiresPermissions("monitor:operlog:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(SysOperLog operLog) + { + startPage(); + List list = operLogService.selectOperLogList(operLog); + return getDataTable(list); + } + + @Log(title = "鎿嶄綔鏃ュ織", businessType = BusinessType.EXPORT) + @RequiresPermissions("monitor:operlog:export") + @PostMapping("/export") + @ResponseBody + public AjaxResult export(SysOperLog operLog) + { + List list = operLogService.selectOperLogList(operLog); + ExcelUtil util = new ExcelUtil(SysOperLog.class); + return util.exportExcel(list, "鎿嶄綔鏃ュ織"); + } + + @Log(title = "鎿嶄綔鏃ュ織", businessType = BusinessType.DELETE) + @RequiresPermissions("monitor:operlog:remove") + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + return toAjax(operLogService.deleteOperLogByIds(ids)); + } + + @RequiresPermissions("monitor:operlog:detail") + @GetMapping("/detail/{operId}") + public String detail(@PathVariable("operId") Long operId, ModelMap mmap) + { + mmap.put("operLog", operLogService.selectOperLogById(operId)); + return prefix + "/detail"; + } + + @Log(title = "鎿嶄綔鏃ュ織", businessType = BusinessType.CLEAN) + @RequiresPermissions("monitor:operlog:remove") + @PostMapping("/clean") + @ResponseBody + public AjaxResult clean() + { + operLogService.cleanOperLog(); + return success(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java new file mode 100644 index 000000000..19435e941 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java @@ -0,0 +1,88 @@ +package com.ruoyi.web.controller.monitor; + +import java.util.List; +import org.apache.shiro.authz.annotation.Logical; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.enums.OnlineStatus; +import com.ruoyi.common.utils.ShiroUtils; +import com.ruoyi.framework.shiro.session.OnlineSession; +import com.ruoyi.framework.shiro.session.OnlineSessionDAO; +import com.ruoyi.system.domain.SysUserOnline; +import com.ruoyi.system.service.ISysUserOnlineService; + +/** + * 鍦ㄧ嚎鐢ㄦ埛鐩戞帶 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/monitor/online") +public class SysUserOnlineController extends BaseController +{ + private String prefix = "monitor/online"; + + @Autowired + private ISysUserOnlineService userOnlineService; + + @Autowired + private OnlineSessionDAO onlineSessionDAO; + + @RequiresPermissions("monitor:online:view") + @GetMapping() + public String online() + { + return prefix + "/online"; + } + + @RequiresPermissions("monitor:online:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(SysUserOnline userOnline) + { + startPage(); + List list = userOnlineService.selectUserOnlineList(userOnline); + return getDataTable(list); + } + + @RequiresPermissions(value = { "monitor:online:batchForceLogout", "monitor:online:forceLogout" }, logical = Logical.OR) + @Log(title = "鍦ㄧ嚎鐢ㄦ埛", businessType = BusinessType.FORCE) + @PostMapping("/batchForceLogout") + @ResponseBody + public AjaxResult batchForceLogout(String ids) + { + for (String sessionId : Convert.toStrArray(ids)) + { + SysUserOnline online = userOnlineService.selectOnlineById(sessionId); + if (online == null) + { + return error("鐢ㄦ埛宸蹭笅绾"); + } + OnlineSession onlineSession = (OnlineSession) onlineSessionDAO.readSession(online.getSessionId()); + if (onlineSession == null) + { + return error("鐢ㄦ埛宸蹭笅绾"); + } + if (sessionId.equals(ShiroUtils.getSessionId())) + { + return error("褰撳墠鐧诲綍鐢ㄦ埛鏃犳硶寮洪"); + } + onlineSessionDAO.delete(onlineSession); + online.setStatus(OnlineStatus.off_line); + userOnlineService.saveOnline(online); + userOnlineService.removeUserCache(online.getLoginName(), sessionId); + } + return success(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/PaymentRequestController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/PaymentRequestController.java new file mode 100644 index 000000000..f44b5a9dc --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/PaymentRequestController.java @@ -0,0 +1,883 @@ +package com.ruoyi.web.controller.system; + +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.FormFileConstants; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.enums.OrderTypes; +import com.ruoyi.common.enums.PaymentRequestStatus; +import com.ruoyi.common.exception.GlobalException; +import com.ruoyi.common.utils.CacheUtils; +import com.ruoyi.common.utils.ShiroUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.file.FileUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.domain.FormFile; +import com.ruoyi.system.domain.PaymentAccount; +import com.ruoyi.system.domain.ProcessFlow; +import com.ruoyi.system.domain.paymentRequest.PaymentAuditResults; +import com.ruoyi.system.domain.paymentRequest.PaymentRequest; +import com.ruoyi.system.domain.paymentRequest.PaymentRequestDt1; +import com.ruoyi.system.domain.paymentRequest.PaymentRequestFile; +import com.ruoyi.system.domain.requisition.Requisition; +import com.ruoyi.system.dto.paymentRequest.PaymentRequestDt1Dto; +import com.ruoyi.system.service.IFormFileService; +import com.ruoyi.system.service.IPaymentAccountService; +import com.ruoyi.system.service.IProcessFlowService; +import com.ruoyi.system.service.ISysUserService; +import com.ruoyi.system.service.paymentRequest.IPaymentRequestDt1Service; +import com.ruoyi.system.service.paymentRequest.IPaymentRequestFileService; +import com.ruoyi.system.service.paymentRequest.IPaymentRequestService; +import com.ruoyi.system.component.paymentRequest.PaymentRequestComponent; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Controller; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.*; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import static com.ruoyi.common.utils.CacheUtils.getCacheKey; +import static com.ruoyi.common.utils.CacheUtils.getCacheName; + + +/** + * 璇锋鍗旵ontroller + * + * @author SKaiL + * @date 2022-09-21 + */ +@Controller +@RequestMapping("/system/paymentRequest") +public class PaymentRequestController extends BaseController +{ + private String prefix = "system/paymentRequest"; + + private static final Logger log = LoggerFactory.getLogger(PaymentRequestController.class); + + @Autowired + private IPaymentRequestService paymentRequestService; + + @Autowired + private IPaymentAccountService paymentAccountService; + + @Autowired + private PaymentRequestComponent paymentRequestComponent; + + @Autowired + private IPaymentRequestDt1Service paymentRequestDt1Service; + + @Autowired + private ISysUserService iSysUserService; + + @Autowired + private IPaymentRequestFileService iPaymentRequestFileService; + + @Autowired + private IProcessFlowService processFlowService; + + @Autowired + private IFormFileService formFileService; + +// @Autowired +// private RequisitionComponent requisitionComponent; + + @RequiresPermissions("system:paymentRequest:view") + @GetMapping() + public String paymentRequest() + { + return prefix + "/paymentRequest"; + } + + /** + * 鏌ヨ璇锋鍗曞垪琛 + */ + @RequiresPermissions("system:paymentRequest:listAll") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(PaymentRequest paymentRequest) + { + startPage(); + SysUser sysUser = ShiroUtils.getSysUser(); + List roles = sysUser.getRoles().stream().filter(r -> r.getRoleKey().equals("FinanceAudit")).collect(Collectors.toList()); + if (!sysUser.isAdmin() && StringUtils.isEmpty(roles) && + !sysUser.getUserCode().contains("S00001") && + !sysUser.getUserCode().contains("S00002") && + !sysUser.getUserCode().contains("S00003")) { + //鍙兘鏌ョ湅鏈儴闂 +// paymentRequest.setDept(sysUser.getDept().getDeptName().trim()); + //鏌ョ湅鑷繁鐨 + paymentRequest.setEmployeeNo(sysUser.getUserCode()); + } + List list = paymentRequestService.selectPaymentRequestList(paymentRequest); + paymentRequestComponent.buildList(list); + return getDataTable(list); + } + + @RequiresPermissions("system:paymentRequest:view") + @GetMapping("/todo") + public String paymentRequestToDo() { + return prefix + "/paymentRequestToDo"; + } + + + /** + * 鎴戠殑寰呭姙 + */ + @RequiresPermissions("system:paymentRequest:list") + @PostMapping("/list/todo") + @ResponseBody + public TableDataInfo listToDo(PaymentRequest paymentRequest) { + SysUser sysUser = ShiroUtils.getSysUser(); + startPage(); + if (!sysUser.isAdmin()) { + paymentRequest.setSendToCode(ShiroUtils.getSysUser().getUserCode()); + } + List list = paymentRequestService.selectPaymentRequestList(paymentRequest); + paymentRequestComponent.buildList(list); + return getDataTable(list); + } + + @RequiresPermissions("system:paymentRequest:view") + @GetMapping("/do") + public String paymentRequestDo() { + return prefix + "/paymentRequestDo"; + } + + /** + * 鎴戠殑宸插姙 + */ + @RequiresPermissions("system:paymentRequest:list") + @PostMapping("/list/do") + @ResponseBody + public TableDataInfo listDo(PaymentRequest paymentRequest) { + SysUser sysUser = ShiroUtils.getSysUser(); + if (!sysUser.isAdmin()) { + paymentRequest.setHandlesCode(sysUser.getUserCode()); + } + startPage(); + List list = paymentRequestService.selectPaymentRequestList(paymentRequest); + paymentRequestComponent.buildList(list); + return getDataTable(list); + } + + /** + * 鎴戠殑鍒涘缓 + */ + @RequiresPermissions("system:paymentRequest:view") + @GetMapping("/create") + public String requisitionCreate() { + return prefix + "/paymentRequestCreate"; + } + + @RequiresPermissions("system:paymentRequest:list") + @PostMapping("/list/create") + @ResponseBody + public TableDataInfo listCreate(PaymentRequest paymentRequest) { + SysUser sysUser = ShiroUtils.getSysUser(); + if (!sysUser.isAdmin()) { + paymentRequest.setEmployeeNo(ShiroUtils.getSysUser().getUserCode()); + } + startPage(); + List list = paymentRequestService.selectPaymentRequestList(paymentRequest); + paymentRequestComponent.buildList(list); + return getDataTable(list); + } + + /** + * 鎴戠殑鑽夌ǹ + */ + @RequiresPermissions("system:paymentRequest:view") + @GetMapping("/draft") + public String paymentRequestDraft() { + return prefix + "/paymentRequestDraft"; + } + + /** + * 鎴戠殑鑽夌ǹ + */ + @RequiresPermissions("system:paymentRequest:list") + @PostMapping("/list/draft") + @ResponseBody + public TableDataInfo listDraft(PaymentRequest paymentRequest) { + SysUser sysUser = ShiroUtils.getSysUser(); + if (!sysUser.isAdmin()) { + paymentRequest.setEmployeeNo(ShiroUtils.getSysUser().getUserCode()); + } + startPage(); + List list = paymentRequestService.selectPaymentRequestListDraft(paymentRequest); + paymentRequestComponent.buildList(list); + return getDataTable(list); + } + + /** + * 瀵煎嚭璇锋鍗曞垪琛 + */ + @RequiresPermissions("system:paymentRequest:export") + @Log(title = "璇锋鍗", businessType = BusinessType.EXPORT) + @PostMapping("/export") + @ResponseBody + public AjaxResult export(PaymentRequest paymentRequest) + { + List list = paymentRequestService.selectPaymentRequestList(paymentRequest); + ExcelUtil util = new ExcelUtil(PaymentRequest.class); + return util.exportExcel(list, "璇锋鍗曟暟鎹"); + } + + /** + * 鏂板璇锋鍗 + */ + @GetMapping("/add") + public String add(ModelMap mmap) + { + SysUser sysUser = ShiroUtils.getSysUser(); + PaymentAccount paymentAccount = new PaymentAccount(); + paymentAccount.setCreateBy(sysUser.getUserCode()); + mmap.put("user", sysUser); + mmap.put("projectCode", CacheUtils.get(getCacheName(Constants.ZT_WGCPRORELEASE_CACHE), getCacheKey(Constants.ZT_WGCPRORELEASE_KEY,"proCode"))); + return prefix + "/add"; + } + + /** + * 鏂板淇濆瓨璇锋鍗 + */ + @RequiresPermissions("system:paymentRequest:add") + @Log(title = "璇锋鍗", businessType = BusinessType.INSERT) + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(@RequestBody PaymentRequest paymentRequest) + { + return paymentRequestService.insertPaymentRequest(paymentRequest,getSysUser()); + } + + /** + * 鏌ヨ鏀舵浜轰俊鎭 + * + * @return + */ + @GetMapping("/selectPaymentInfo") + public String selectPaymentInfo() { + return prefix + "/paymentInfoList"; + } + + /** + * 鏌ヨ鏀舵浜轰俊鎭 + * + * @return + */ + @PostMapping("/selectPaymentInfoList") + @ResponseBody + public TableDataInfo selectPaymentInfoList(PaymentAccount paymentAccount) { + //payee鏈夊间唬琛ㄧ偣鍑荤殑鍏ㄦ枃鎼滅储 + if (StringUtils.isEmpty(paymentAccount.getPayee())) { + if (!getSysUser().isAdmin()) { + paymentAccount.setCreateBy(getSysUser().getUserCode()); + } + } + startPage(); + List payeeList = paymentAccountService.selectPaymentAccountList(paymentAccount); + return getDataTable(payeeList); + } + + /** + * 淇敼璇锋鍗 + */ + @RequiresPermissions("system:paymentRequest:edit") + @GetMapping("/edit/{id}") + public String edit(@PathVariable("id") Long id, ModelMap mmap) + { + PaymentRequest paymentRequest = paymentRequestService.selectPaymentRequestById(id); + PaymentAccount paymentAccount = new PaymentAccount(); + paymentAccount.setParentId(id); + PaymentRequestDt1 paymentRequestDt1 = new PaymentRequestDt1(); + paymentRequestDt1.setRequestId(id); + List paymentRequestDt1List = paymentRequestDt1Service.selectPaymentRequestDt1List(paymentRequestDt1); + //鍘嗗彶浠樻璐﹀彿淇℃伅 + PaymentAccount paymentAccounts = new PaymentAccount(); + paymentAccounts.setCreateBy(paymentRequest.getCreateByCode()); + mmap.put("payeeList", paymentAccountService.selectPaymentAccountList(paymentAccounts)); + mmap.put("paymentRequest", paymentRequest); + mmap.put("paymentRequestDt1List", paymentRequestDt1List); + mmap.put("projectCode", CacheUtils.get(getCacheName(Constants.ZT_WGCPRORELEASE_CACHE), getCacheKey(Constants.ZT_WGCPRORELEASE_KEY,"proCode"))); + return prefix + "/edit"; + } + + /** + * 淇敼淇濆瓨璇锋鍗 + */ + @RequiresPermissions("system:paymentRequest:edit") + @Log(title = "璇锋鍗", businessType = BusinessType.UPDATE) + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(@RequestBody PaymentRequest paymentRequest) + { + return paymentRequestService.updatePaymentRequest(paymentRequest); + } + + /** + * 澶嶅埗璇锋 + */ + @GetMapping("/copy/{id}") + public String copy(@PathVariable("id") Long id, ModelMap mmap) { + PaymentRequest paymentRequest = paymentRequestService.selectPaymentRequestById(id); + PaymentAccount paymentAccount = new PaymentAccount(); + paymentAccount.setParentId(id); + PaymentRequestDt1 paymentRequestDt1 = new PaymentRequestDt1(); + paymentRequestDt1.setRequestId(id); + List paymentRequestDt1List = paymentRequestDt1Service.selectPaymentRequestDt1List(paymentRequestDt1); + PaymentAccount paymentAccounts = new PaymentAccount(); + paymentAccounts.setCreateBy(paymentRequest.getCreateByCode()); + //鍘嗗彶浠樻璐﹀彿淇℃伅 + mmap.put("payeeList", paymentAccountService.selectPaymentAccountList(paymentAccounts)); + mmap.put("paymentRequest", paymentRequest); + mmap.put("paymentRequestDt1List", paymentRequestDt1List); + mmap.put("projectCode", CacheUtils.get(getCacheName(Constants.ZT_WGCPRORELEASE_CACHE), getCacheKey(Constants.ZT_WGCPRORELEASE_KEY,"proCode"))); + return prefix + "/addCopy"; + } + + /** + * 杩涜鎻愪氦 + */ + @Log(title = "璇锋鍗曟彁浜", businessType = BusinessType.OTHER) + @GetMapping("/start/submit") + @ResponseBody + public AjaxResult startSubmit(@RequestParam("id") Long id) { + + PaymentRequest paymentRequest = paymentRequestService.selectPaymentRequestById(id); + if(!getSysUser().isAdmin()&&!Objects.equals(paymentRequest.getSendToCode(),getSysUser().getUserCode())){ + throw new GlobalException("鎻愪氦澶辫触锛佸彧鍏佽鐢宠浜烘搷浣溿"); + } + SysUser sysUser = getSysUser(); + return paymentRequestService.submitProcess(id, sysUser); + } + + /** + * 杩涘叆瀹℃牳椤甸潰 + */ + @GetMapping("/review/{id}") + public String review(@PathVariable("id") Long id, ModelMap mmap) { + PaymentRequest paymentRequest = paymentRequestService.selectPaymentRequestById(id); + PaymentAccount paymentAccount = new PaymentAccount(); + paymentAccount.setParentId(id); + SysUser user = new SysUser(); + user.setStatus("0"); + List userList = iSysUserService.selectUserList(user); + Iterator iterator = userList.iterator(); + while (iterator.hasNext()) { + SysUser next = iterator.next(); + //涓嶆槸S寮澶翠汉鍛 + if (StringUtils.isEmpty(next.getUserCode())) { + iterator.remove(); + } else if (!Objects.equals(next.getUserCode().substring(0, 1), "S")) { + iterator.remove(); + } + } +// mmap.put("userList", userList); + PaymentRequestDt1 paymentRequestDt1 = new PaymentRequestDt1(); + paymentRequestDt1.setRequestId(id); + List paymentRequestDt1List = paymentRequestDt1Service.selectPaymentRequestDt1List(paymentRequestDt1); + paymentRequestComponent.approvalProgress(paymentRequest); + mmap.put("paymentRequest", paymentRequest); + mmap.put("paymentRequestDt1List", paymentRequestDt1List); + ProcessFlow processFlow = new ProcessFlow(); + processFlow.setOrderId(id); + processFlow.setOrderType(OrderTypes.PAYMENT_REQUEST.getCode()); + List lists = processFlowService.selectProcessFlowListByOrderId(id,OrderTypes.PAYMENT_REQUEST.getCode()); + mmap.put("lists", lists); +// mmap.put("progressbar", paymentRequestComponent.approvalProgress(lists, toBeReviewed, paymentRequest)); + FormFile formFile = new FormFile(); + formFile.setFileType(FormFileConstants.PAYMENTREQUEST); + formFile.setParentId(id); + List formFiles = formFileService.selectFormFileList(formFile); + mmap.put("listFile", formFiles); + return prefix + "/review"; + } + /** + * 鍒犻櫎璇锋鍗 + */ + @RequiresPermissions("system:paymentRequest:remove") + @Log(title = "璇锋鍗", businessType = BusinessType.DELETE) + @PostMapping( "/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + return toAjax(paymentRequestService.deletePaymentRequestByIds(ids)); + } + + /** + * 閫氱敤瀹℃牳鎻愪氦 + * + * @param paymentAuditResults 瀹℃牳淇℃伅 + * @return + */ + @Log(title = "璇锋鍗曞鏍告彁浜", businessType = BusinessType.OTHER) + @PostMapping("/supervisor/auditSubmit") + @ResponseBody + public AjaxResult paymentRequestAuditSubmit(@RequestBody PaymentAuditResults paymentAuditResults) { + try { + forReview(paymentAuditResults.getPaymentRequestId()); + paymentRequestService.auditSubmit(paymentAuditResults, getSysUser(),null); + } catch (GlobalException businessException){ + return error(businessException.getMessage()); + } catch (Exception e){ + log.error("瀹℃牳鎻愪氦璇锋鍗曞嚭閿,閿欒鍘熷洜--->", e); + return error("鎿嶄綔澶辫触锛屽彂鐢熸湭鐭ュ紓甯革紝璇蜂繚瀛樻埅鍥撅紝鍦ㄧ郴缁熷伐鍗曟ā鍧楀彂璧封滃伐浣滄祦瀹℃壒绯荤粺鈥濆伐鍗曞弽棣堛"); + } + return success(); + } + + @GetMapping(value = {"/filePage/{type}/{flag}","/filePage/{id}/{type}/{flag}"}) + public String filePage(@PathVariable(value = "id",required = false) Long id, @PathVariable("type") Integer type, + @PathVariable("flag") Boolean flag, ModelMap mmap) + { + mmap.put("paymentRequestId", id); + //鏂囦欢绫诲瀷 11浣跨敤鏂囨。, 1璇疯喘鍗曢檮浠 + mmap.put("type", type); + mmap.put("flag", flag); + //妯$増涓嶅厑璁告櫘閫氱敤鎴峰垹闄 + if (Objects.equals(FormFileConstants.PAYMENTREQUEST_TEMPLATE, type)){ + if (getSysUser().isAdmin()){ + mmap.put("flag", true); + } else { + mmap.put("flag", false); + } + } + return prefix + "/filePage"; + } + + /** + * 鏌ヨfilePage椤甸潰鏁版嵁 + */ + /** + * 鏌ヨ鏂囦欢鍒楄〃 + */ + @PostMapping("/filePageList") + @ResponseBody + public TableDataInfo filePage(@RequestParam(value = "paymentRequestId",required = false) Long paymentRequestId, + @RequestParam("type") Integer type) + { + return getDataTable(paymentRequestService.selectFormFile(paymentRequestId, type)); + } + + +// @GetMapping("/downloadFile") +// public void downloadFile(@RequestParam("fileName") String fileName, @RequestParam("filePath") String filePath, HttpServletRequest request, HttpServletResponse response) +// { +//// FileDownloadUtils.resourceDownload(filePath, fileName, request, response); +// } + + + /** + * 璇锋鍗曢檮浠跺垹闄 + * @param id + * @param file + * @param paymentRequestId + * @return + */ + @Log(title = "璇锋鍗曢檮浠跺垹闄", businessType = BusinessType.UPDATE) + @GetMapping("/remove/file") + @ResponseBody + @Transactional(rollbackFor = Exception.class) + public AjaxResult removeFile(String id, String file, Long paymentRequestId) { + return null; + } + + /** + * 杩涘叆鏂板闄勪欢椤甸潰 + */ + @GetMapping("/addFile/{id}") + public String forFaReportUpload(@PathVariable("id") Long id, ModelMap mmap) { + mmap.put("paymentRequestId", id); + return prefix + "/addFile"; + } + /** + * 涓婁紶鏂囦欢 + */ + @PostMapping("/addFile/save") + @ResponseBody + public AjaxResult addFileSave(@RequestParam("file") MultipartFile file, @RequestParam("paymentRequestId") Long paymentRequestId) throws IOException { + return success(); + } + + /** + * 鏌ョ湅鐩稿叧妯℃澘 + * + * @return + */ + @GetMapping("/templatePage") + public String templatePage() { + return prefix + "/templatePage"; + } + + /** + * 鐩稿叧妯℃澘鍒楄〃 + */ + @PostMapping("/templateList") + @ResponseBody + public TableDataInfo templatePageList(FormFile formFile) { + formFile.setFileType(11); + startPage(); + List list = formFileService.selectFormFileList(formFile); + return getDataTable(list); + } + + /** + * 杩涘叆鏂板妯℃澘椤甸潰 + */ + @GetMapping("/addTemplate") + public String forTemplateUpload(ModelMap mmap) { + return prefix + "/addTemplate"; + } + + /** + * 鏂板鐩稿叧妯℃澘 + */ + /* @Log(title = "璇锋鍗曟ā鐗堟柊澧", businessType = BusinessType.INSERT) + @PostMapping("/addTemplate/save") + @ResponseBody + public AjaxResult addtemplateSave(@RequestParam("file") MultipartFile file) throws IOException { + String filePath = RuoYiConfig.getUploadPath(); + String fileName = file.getOriginalFilename().replaceAll(" ","").replaceAll("&",""); + String suffix = fileName.substring(fileName.lastIndexOf(".")); +// String filePath1 = FileUploadUtils.upload(filePath, file,suffix); + PaymentRequestFile paymentRequestFile = new PaymentRequestFile(); + paymentRequestFile.setType(2); +// paymentRequestFile.setFile(filePath1); + paymentRequestFile.setFileName(fileName); + iPaymentRequestFileService.insertPaymentRequestFile(paymentRequestFile); + return toAjax(true); + }*/ + + /** + * 鍒犻櫎鐩稿叧妯℃澘 + */ + @RequiresPermissions("system:paymentRequest:templateOperation") + @Log(title = "璇锋鍗曟ā鐗堝垹闄", businessType = BusinessType.UPDATE) + @GetMapping("/remove/templateFile") + @ResponseBody + public AjaxResult removeTemplate(Long id) { + FormFile formFile = formFileService.selectFormFileById(id); +// PaymentRequestFile paymentRequestFile = iPaymentRequestFileService.selectPaymentRequestFileById(id); + String filePath = RuoYiConfig.getUploadPath(); + boolean b = FileUtils.deleteFile(filePath + formFile.getFilePath()); + if (b) { + formFileService.deleteFormFileByIds(id.toString()); +// iPaymentRequestFileService.deletePaymentRequestFileByIds(id.toString()); + return success("鍒犻櫎鎴愬姛"); + } else { + return error("鍒犻櫎澶辫触"); + } + } + + @GetMapping("/downloadFileDescription") + public void downloadFileDescription(HttpServletRequest request, HttpServletResponse response) + throws Exception { + FormFile formFile = new FormFile(); + formFile.setFileType(11); + List formFiles = formFileService.selectFormFileList(formFile); + String filePath = formFiles.get(0).getFilePath(); + String fileName = formFiles.get(0).getFileName(); + try + { + if (!FileUtils.checkAllowDownload(filePath)) + { + throw new Exception(StringUtils.format("璧勬簮鏂囦欢({})闈炴硶锛屼笉鍏佽涓嬭浇銆 ", filePath)); + } + // 鏈湴璧勬簮璺緞 + String localPath = RuoYiConfig.getUploadPath(); + // 鏁版嵁搴撹祫婧愬湴鍧 + String downloadPath = localPath + StringUtils.substringAfter(filePath, Constants.RESOURCE_PREFIX) + filePath; + // 涓嬭浇鍚嶇О + String downloadName = StringUtils.substringAfterLast(downloadPath, "/"); + if(StringUtils.isNotEmpty(fileName)){ + downloadName = fileName; + } + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); + FileUtils.setAttachmentResponseHeader(response, downloadName); + FileUtils.writeBytes(downloadPath, response.getOutputStream()); + } + catch (Exception e) + { + log.error("涓嬭浇鏂囦欢澶辫触", e); + } + } + + /** + * 璇︽儏椤 + */ + @GetMapping("/detail/{id}/{type}") + public String deatil(@PathVariable("id") Long id, @PathVariable("type") Integer type, ModelMap mmap) { + PaymentRequest paymentRequest = paymentRequestService.selectPaymentRequestById(id); + PaymentAccount paymentAccount = new PaymentAccount(); + paymentAccount.setParentId(id); + PaymentRequestDt1 paymentRequestDt1 = new PaymentRequestDt1(); + paymentRequestDt1.setRequestId(id); + List paymentRequestDt1List = paymentRequestDt1Service.selectPaymentRequestDt1List(paymentRequestDt1); + paymentRequestComponent.approvalProgress(paymentRequest); + mmap.put("paymentRequest", paymentRequest); + mmap.put("paymentRequestDt1List", paymentRequestDt1List); + ProcessFlow processFlow = new ProcessFlow(); + processFlow.setOrderId(id); + processFlow.setOrderType(OrderTypes.PAYMENT_REQUEST.getCode()); + List lists = processFlowService.selectProcessFlowListByOrderId(id,OrderTypes.PAYMENT_REQUEST.getCode()); + mmap.put("lists", lists); + FormFile formFile = new FormFile(); + formFile.setFileType(FormFileConstants.PAYMENTREQUEST); + formFile.setParentId(id); + List formFiles = formFileService.selectFormFileList(formFile); + mmap.put("listFile", formFiles); + mmap.put("isClose", "0"); + + //闄堟诲鏍告殏鏃朵笂浼犲鎵规埅鍥炬寜閽 + List collect = lists.stream().filter(pf -> (Objects.equals(paymentRequest.getEmployeeNo(), getSysUser().getUserCode()) + || getSysUser().isAdmin()) && Objects.equals(pf.getCreateByCode(), "S00001") + && StringUtils.isNull(pf.getAuditResult())).collect(Collectors.toList()); + if (StringUtils.isNotEmpty(collect) && Objects.equals(collect.get(0).getStatus(), paymentRequest.getStatus())){ + mmap.put("isClose", "1"); + } + if (Objects.equals(type, 2)){ + //灞曠ず瀹℃壒鎴浘 + if (paymentRequest.getStatus() == 21 && StringUtils.isNotEmpty(paymentRequest.getCloseFile())) { + String url = paymentRequest.getCloseFile(); + if (url.contains(".jpg") || url.contains(".png")) { + mmap.put("url", url); + } + } + return prefix + "/detailPDF"; + } else { + return prefix + "/detail"; + } + } + + /** + * 璇锋鍗曟挙鍥 + * + * @param id 璇锋鍗昳d + * @return + */ + @GetMapping("/withdrawal") + @ResponseBody + public AjaxResult Withdrawal(Long id) { + return paymentRequestService.WithdrawalOfInitiation(id); + } + + + /** + * 涓婁紶绛炬牳鎴浘椤甸潰 + * @param id 璇锋鍗昳d + * @param mmap + * @return + */ + @RequiresPermissions("system:paymentRequest:edit") + @GetMapping("/addClosePaymentRequestFile/{paymentRequestId}") + public String forAddClosePaymentRequestFileUpload(@PathVariable("paymentRequestId") String id, ModelMap mmap) + { + mmap.put("paymentRequestId", id); + return prefix + "/closePaymentRequestFile"; + } + /** + * 涓婁紶绛炬牳鎴浘 + * @param file 鏂囦欢 + * @param paymentRequestIds 璇锋鍗昳d + * @return + * @throws IOException + */ + @RequiresPermissions("system:paymentRequest:edit") + @PostMapping("/addClosePaymentRequestFile/save") + @ResponseBody + public AjaxResult addClosePaymentRequestFileSave(@RequestParam("file") MultipartFile file, + @RequestParam("paymentRequestId") String paymentRequestIds, + @RequestParam("type") Integer type) { + return paymentRequestService.closePaymentRequestFile(file, paymentRequestIds, type, ShiroUtils.getSysUser()); + + } + + /** + * 涓嬭浇鎴浘鍑瘉 + * @param id 璇锋鍗昳d + * @param resource 鏂囦欢鍦板潃 + * @param request + * @param response + * @throws Exception + */ + @GetMapping("/download/ClosePaymentRequestFile") + public void downloadClosePaymentRequestFile(@RequestParam("id") Long id, @RequestParam("resource") String resource, + HttpServletRequest request, HttpServletResponse response)throws Exception + { + + } + + /** + * 楠岃瘉褰撳墠鐢ㄦ埛鏈夋棤瀹℃牳鏉冮檺 + * @param id 璇锋鍗昳d + */ + public void forReview(Long id) { + PaymentRequest paymentRequest = paymentRequestService.selectPaymentRequestById(id); + if (!Objects.equals(paymentRequest.getSendToCode(),getSysUser().getUserCode()) && + !getSysUser().isAdmin() && !paymentRequest.getSendToCode().contains(getSysUser().getUserCode())) { + throw new GlobalException("宸茬粡绛炬牳瀹屾垚锛岃绛炬牳涓嬩竴鍗"); + } + } + + /** + * 鏇存敼寰呭鏍镐汉 + * @param paymentRequestId + * @return + */ + @RequiresPermissions("system:paymentRequest:changeReviewer") + @PostMapping("/changeReviewer") + @ResponseBody + public AjaxResult changeReviewer(@RequestParam("paymentRequestId") Long paymentRequestId, + @RequestParam("sendToCode") String sendToCode){ + PaymentRequest paymentRequest = new PaymentRequest(); + paymentRequest.setId(paymentRequestId); + paymentRequest.setSendToCode(sendToCode); + paymentRequestService.updatePaymentRequest(paymentRequest); + return success(); + } + + /** + * 鎵归噺瀹℃牳鐣岄潰 + * @param ids + * @param map + * @return + */ + @GetMapping("/batchReview/{ids}") + public String batchReview(@PathVariable("ids") String ids, ModelMap map){ + map.put("ids", ids); + return prefix + "/batchReview"; + } + + /** + * 鎵归噺瀹℃牳 + * @param auditResults 瀹℃牳淇℃伅 + * @return + */ + @PostMapping("/batchReview") + @ResponseBody + public AjaxResult batchReview(@RequestBody PaymentAuditResults auditResults){ + return success(paymentRequestService.paymentRequestBatchReview(auditResults, getSysUser())); + } + + /** + * 鍒犻櫎浠樻璐﹀彿淇℃伅 + * @param ids + * @return + */ + @PostMapping("/remove/paymentAccount") + @ResponseBody + public AjaxResult removePaymentAccountInfo(String ids){ + return toAjax(paymentAccountService.deletePaymentAccountByIds(ids)); + } + + /** + * 鍙戦佸姞鎬ラ偖浠 + * @param id + * @return + */ + @PostMapping("/expedited") + @ResponseBody + public AjaxResult expedited(@RequestParam("id") Long id) { + paymentRequestComponent.sendExpeditedEmail(id); + return success(); + } + + + + /** + * 涓婁紶姹囨昏〃 + * @return + */ + @RequiresPermissions("system:paymentRequest:view") + @GetMapping("/summary") + public String summary(){ + return prefix + "/summary"; + } + + /** + * 涓婁紶姹囨昏〃 + * @return + */ + @PostMapping("/summaryTable") + @ResponseBody + public AjaxResult summaryTable(@RequestParam("file") MultipartFile file, @RequestParam("paymentDate")String paymentDate){ + return paymentRequestComponent.summaryTable(file, paymentDate); + } + + @GetMapping("/importSummaryTemplate") + @ResponseBody + public AjaxResult importSummaryTemplate() + { + + PaymentRequestFile paymentRequestFile = new PaymentRequestFile(); + paymentRequestFile.setType(2); + List list = iPaymentRequestFileService.selectPaymentRequestFileList(paymentRequestFile); + PaymentRequestFile file = list.get(list.size() - 1); + AjaxResult result = new AjaxResult(); + result.put("code", 0); + result.put("fileName", file.getFileName()); + result.put("filePath", file.getFile()); + return result; + } + + /** + * 涓婁紶鏄庣粏琛 + * @return + */ + @RequiresPermissions("system:paymentRequest:view") + @GetMapping("/uploadDetail") + public String uploadDetail(){ + return prefix + "/uploadDetail"; + } + + + /** + * TODO + * 涓婁紶鏄庣粏琛 + * @return + */ + @PostMapping("/uploadDetailTable") + @ResponseBody + public AjaxResult uploadDetailTable(@RequestParam("file") MultipartFile file, @RequestParam("deptCode")String deptCode){ + return paymentRequestComponent.uploadDetailTable(file,deptCode); + } + + @GetMapping("/importUploadDetailTemplate") + @ResponseBody + public AjaxResult importUploadDetailTemplate() + { + ExcelUtil util = new ExcelUtil<>(PaymentRequestDt1Dto.class); + return util.importTemplateExcel("涓婁紶鏄庣粏琛"); + } + + /** + * 寮傛璁$畻閲戦 + * @return + */ + @PostMapping("/calculateTheAmount") + @ResponseBody + public AjaxResult calculateTheAmount(@RequestBody PaymentRequest paymentRequest){ + AjaxResult result = new AjaxResult(); + result.put("code", 0); + result.put("data", paymentRequestComponent.calculateTheAmount(paymentRequest)); + return result; + } + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/PetitionController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/PetitionController.java new file mode 100644 index 000000000..a68fbd905 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/PetitionController.java @@ -0,0 +1,1220 @@ +package com.ruoyi.web.controller.system; + + + +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.constant.FormFileConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.PageDomain; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.page.TableSupport; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.enums.OrderTypes; +import com.ruoyi.common.enums.PetitionStatus; +import com.ruoyi.common.exception.GlobalException; +import com.ruoyi.common.utils.ShiroUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.file.FileUploadUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.component.petition.PetitionComponent; +import com.ruoyi.system.domain.FormFile; +import com.ruoyi.system.domain.ProcessFlow; +import com.ruoyi.system.domain.petition.Petition; +import com.ruoyi.system.domain.petition.PetitionFile; +import com.ruoyi.system.domain.petition.PetitionSign; +import com.ruoyi.system.dto.petition.PetitionDto; +import com.ruoyi.system.mapper.SysUserMapper; +import com.ruoyi.system.service.IProcessFlowService; +import com.ruoyi.system.service.ISysUserService; +import com.ruoyi.system.service.petition.IPetitionFileService; +import com.ruoyi.system.service.petition.IPetitionService; +import com.ruoyi.system.service.petition.IPetitionSignService; +import io.swagger.annotations.Api; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URLEncoder; +import java.util.*; + +/** + * 绛惧憟瀹℃壒 淇℃伅鎿嶄綔澶勭悊 + * + * @author lxp + * @date 2020-07-09 + */ + @Api("鍙傛暟閰嶇疆") +@Controller +@RequestMapping("/system/petition") +public class PetitionController extends BaseController +{ + + private static final Logger log = LoggerFactory.getLogger(PetitionController.class); + + private String prefix = "system/petition"; + + @Autowired + private IPetitionService petitionService; + + @Autowired + private ISysUserService userService; + +// @Autowired +// private IPetitionLogService petitionLogService; + + @Autowired + private IProcessFlowService processFlowService; + + @Autowired + private IPetitionFileService petitionFileService; + +// @Autowired +// private IPetitionAddauditService petitionAddauditService; + + @Autowired + private IPetitionSignService petitionSignService; + +// @Autowired +// private IPetitionTrialService petitionTrialService; + + @Autowired + private PetitionComponent petitionComponent; + + @Autowired + private SysUserMapper userMapper; + + + private static final Integer FLAG_HIDDEN=0; + private static final Integer FLAG_SHOW=1; + + @RequiresPermissions("system:petition:view") + @RequestMapping() + public String petition() + { + return prefix + "/petition"; + } + + /** + * 鏌ヨ鎵鏈夌鍛堝鎵瑰垪琛 + */ + @RequiresPermissions("system:petition:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(Petition petition) + { + startPage(); + SysUser sysUser = ShiroUtils.getSysUser(); + String loginName = sysUser.getLoginName(); + //绠$悊鍛樻煡鐪嬫墍鏈 + if (getSysUser().isAdmin()){ +// petition.setTypeType(2); + }else{ + petition.setSid(sysUser.getLoginName()); + } + petition.setFlag(FLAG_SHOW); + List list = petitionService.selectPetitionList(petition); + petitionComponent.buildList(list); + return getDataTable(list); + } + /** + * 鎴戠殑宸插姙 + */ + @GetMapping("/did") + public String did() + { + return prefix + "/petitionDid"; + } + + /** + * 鏌ヨ鎴戠殑宸插姙鍒楄〃 + */ + @RequiresPermissions("system:petition:list") + @PostMapping("/list/Did") + @ResponseBody + public TableDataInfo Did(Petition petition) + { + startPage(); +// petition.setFormSta(PetitionStatus.TODO.value()); + petition.setHandlesCode(getSysUser().getUserCode()); + petition.setFlag(FLAG_SHOW); + List list=petitionService.selectPetitionList(petition); + petitionComponent.buildList(list); + return getDataTable(list); + } + + /** + * 鎴戠殑寰呭姙 + */ + @GetMapping("/todo") + public String todo() + { + return prefix + "/petitionTodo"; + } + /** + * 鏌ヨ鎴戠殑寰呭姙鍒楄〃 + */ + @RequiresPermissions("system:petition:list") + @PostMapping("/list/Todo") + @ResponseBody + public TableDataInfo Todo(Petition petition) + { + startPage(); + petition.setFormSta(PetitionStatus.TODO.value()); + petition.setFromSendto(getSysUser().getUserCode()); + petition.setFlag(FLAG_SHOW); + List list=petitionService.selectPetitionList(petition); + petitionComponent.buildList(list); + return getDataTable(list); + } + + /** + * 鎴戠殑鍙戣捣 + */ + @GetMapping("/create") + public String create() + { + return prefix + "/petitionCreate"; + } + /** + * 鏌ヨ鎴戠殑鍙戣捣鍒楄〃 + */ + @RequiresPermissions("system:petition:list") + @PostMapping("/list/create") + @ResponseBody + public TableDataInfo petitionCreate(Petition petition) + { + startPage(); + String loginName = getSysUser().getLoginName(); + if (!getSysUser().isAdmin()){ + petition.setCreatBy(loginName); + } + petition.setFlag(FLAG_SHOW); + List list=petitionService.selectPetitionList(petition); + petitionComponent.buildList(list); + return getDataTable(list); + } + + /** + * 瀵煎嚭绛惧憟瀹℃壒鍒楄〃 + */ + @RequiresPermissions("system:petition:export") + @PostMapping("/export") + @ResponseBody + public AjaxResult export(Petition petition) + { + List list = petitionService.selectPetitionList(petition); + ExcelUtil util = new ExcelUtil(Petition.class); + return util.exportExcel(list, "petition"); + } + + /** + * 鏂板绛惧憟瀹℃壒 + */ + @GetMapping("/add") + public String add() + { + return prefix + "/add"; + } + + /** + * 鏂板淇濆瓨绛惧憟瀹℃壒 + */ + @RequiresPermissions("system:petition:add") + @Log(title = "绛惧憟瀹℃壒", businessType = BusinessType.INSERT) + @PostMapping("/add") + @ResponseBody + public AjaxResult add(@RequestBody PetitionDto petitionDto) { + Petition petition = petitionDto.getPetition(); + try { + SysUser sysUser = getSysUser(); + petition.setCreatBy(sysUser.getLoginName()); + petition.setCreatDate(new Date()); + petition.setFlag(FLAG_SHOW); + Long aLong = petitionService.insertPetition(petitionDto,sysUser); + this.submit(aLong); +// buildAttribute(petition.getId(), OrderTypes.PETITION.getCode()); + } catch (GlobalException businessException) { + return error(businessException.getMessage()); + } catch (Exception e) { + log.error("淇濆瓨鐢靛瓙绛惧憟鍑洪敊,閿欒鍘熷洜--->", e); + return error("鎿嶄綔澶辫触锛屽彂鐢熸湭鐭ュ紓甯革紝璇蜂繚瀛樻埅鍥撅紝鍦ㄧ郴缁熷伐鍗曟ā鍧楀彂璧封滃伐浣滄祦瀹℃壒绯荤粺鈥濆伐鍗曞弽棣堛"); + } + return success(petition.getId().toString()); + } + + /** + * 淇敼绛惧憟瀹℃壒 + */ + @GetMapping("/edit/{id}") + public String edit(@PathVariable("id") Long id, ModelMap mmap) + { + Petition petition = petitionService.selectPetitionById(id); + PetitionSign petitionSign=new PetitionSign(); + petitionSign.setPetitionId(id); + List petitionSigns = petitionSignService.selectPetitionSignList(petitionSign); + mmap.put("petition", petition); + mmap.put("petitionSigns",petitionSigns); + petitionComponent.buildCheckBox(petition); + mmap.put("typeMaps", petition.getParams()); + return prefix + "/edit"; + } + + /** + * 淇敼淇濆瓨绛惧憟瀹℃壒 + */ + @RequiresPermissions("system:petition:edit") + @Log(title = "绛惧憟瀹℃壒", businessType = BusinessType.UPDATE) + @PostMapping("/edit") + @ResponseBody + public AjaxResult edit(@RequestBody Petition petition) + { + try { + SysUser sysUser = getSysUser(); + petition.setUpdateBy(sysUser.getLoginName()); + petition.setUpdateDate(new Date()); +// buildAttribute(petition.getId(), OrderTypes.PETITION.value()); + petitionService.updatePetition(petition); + } catch (GlobalException businessException) { + return error(businessException.getMessage()); + } catch (Exception e) { + log.error("淇敼鐢靛瓙绛惧憟鍑洪敊,閿欒鍘熷洜--->", e); + return error("鎿嶄綔澶辫触锛屽彂鐢熸湭鐭ュ紓甯革紝璇蜂繚瀛樻埅鍥撅紝鍦ㄧ郴缁熷伐鍗曟ā鍧楀彂璧封滃伐浣滄祦瀹℃壒绯荤粺鈥濆伐鍗曞弽棣堛"); + } + return success(); + } + + /** + * 閫昏緫鍒犻櫎绛惧憟瀹℃壒 + */ + @RequiresPermissions("system:petition:removeLogic") + @Log(title = "绛惧憟瀹℃壒", businessType = BusinessType.DELETE) + @PostMapping( "/removeLogic") + @ResponseBody + public AjaxResult removeLogic(Long id) + { + Petition petition = petitionService.selectPetitionById(id); + petition.setFlag(FLAG_HIDDEN); + + return toAjax(petitionService.updatePetition(petition)); + } + + /** + * 绠$悊鍛樺垹闄ょ鍛堝鎵 + */ + @RequiresPermissions("system:petition:remove") + @Log(title = "绛惧憟瀹℃壒", businessType = BusinessType.DELETE) + @PostMapping( "/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + return toAjax(petitionService.deletePetitionByIds(ids)); + } + + /** + * 鑷姩鏌ヨ鍛樺伐缂栧彿鏌ヨ + */ + @PostMapping("/getMessage") + @ResponseBody + public AjaxResult getMessage() { + SysUser sysUser = getSysUser(); + //姝e紡 + SysUser user = userService.selectUserByLoginName(sysUser.getLoginName()); + if (StringUtils.isNull(user)) { + return error(AjaxResult.Type.ERROR, "2333"); + } + SysUser manager= null; + //鏌ヨ鐩存帴涓荤 + String zgsid = user.getZgsid(); + //鏌ヨ浠g涓荤 + String agentsid = user.getPurchasesid(); + if (StringUtils.isNotEmpty(agentsid)){ + manager=userService.selectUserByLoginName(agentsid); + }else{ + manager=userService.selectUserByLoginName(zgsid); + } + Map map = new HashMap<>(); + map.put("applyname",user.getUserName()); + map.put("dept",user.getDept().getDeptName().trim()); + map.put("company",user.getOffices()); + map.put("sid",user.getLoginName()); + map.put("deptmanagerSid",manager.getLoginName()); + map.put("deptmanager",manager.getUserName()); + return AjaxResult.success("",map); + } + /** + * 鎵嬪姩鏌ヨ鍛樺伐缂栧彿鏌ヨ + */ + + @GetMapping("/getMessage/{sid}") + @ResponseBody + public AjaxResult getMessage(@PathVariable("sid") String sid) { + SysUser user =new SysUser(); + if (StringUtils.isEmpty(sid)){ + SysUser sysUser = getSysUser(); + //姝e紡 + user = userService.selectUserByLoginName(sysUser.getLoginName()); + //娴嬭瘯 + //user = userService.selectUserByLoginName("S01221"); + }else{ + user = userService.selectUserByLoginName(sid); + } + if(user == null){ + return error(AjaxResult.Type.ERROR,"2333"); + } + SysUser manager= null; + //鏌ヨ鐩存帴涓荤 + String zgsid = user.getZgsid(); + //鏌ヨ浠g涓荤 + String agentsid = user.getPurchasesid(); + if (StringUtils.isNotEmpty(agentsid)){ + manager=userService.selectUserByLoginName(agentsid); + }else{ + manager=userService.selectUserByLoginName(zgsid); + } + + Map map = new HashMap<>(); + map.put("applyname",user.getUserName()); + map.put("dept",user.getDept().getDeptName().trim()); + map.put("company",user.getOffices()); + map.put("deptmanagerSid",manager.getLoginName()); + map.put("deptmanager",manager.getUserName()); + return AjaxResult.success("",map); + } + + + /** + * 璇︽儏 + */ + @RequiresPermissions("system:petition:detail") + @GetMapping("/detail/{id}/{type}") + public String detail(@PathVariable("id") Long id,@PathVariable("type") Integer type, ModelMap mmap) + { + Petition petition = petitionService.selectPetitionById(id); + PetitionSign p=new PetitionSign(); + p.setPetitionId(id); + p.setSignType(3); + List petitionAddaudits = petitionSignService.selectPetitionSignList(p); + PetitionSign ps=new PetitionSign(); + ps.setPetitionId(id); + ps.setSignType(1); + List petitionSigns = petitionSignService.selectPetitionSignList(ps); + + PetitionSign pt=new PetitionSign(); + pt.setPetitionId(id); + pt.setSignType(2); + List petitionTrialList = petitionSignService.selectPetitionSignList(pt); + + petitionComponent.buildCheckBox(petition); + + mmap.put("petition", petition); + mmap.put("petitionAddaudits",petitionAddaudits); + mmap.put("petitionSigns",petitionSigns); + mmap.put("petitionTrialList",petitionTrialList); + + mmap.put("petitionFiles", petitionService.selectFormFile(id, FormFileConstants.PETITION)); + mmap.put("typeMaps", petition.getParams()); + SysUser user = ShiroUtils.getSysUser(); + if (petition.getCreatBy().equals(user.getLoginName())){ + mmap.put("isClose", "1"); + } + if (Objects.equals(type, 2)){ + //灞曠ず瀹℃壒鎴浘 + return prefix + "/detailPDF"; + } else { + return prefix + "/detail"; + } + } + + /** + * 杩涘叆filePage椤甸潰 + */ + @GetMapping("/filePage/{id}") + public String filePage(@PathVariable("id") Long id, ModelMap mmap) + { + mmap.put("petitionId", id); + Petition petition = petitionService.selectPetitionById(id); + mmap.put("petition", petition); + return prefix + "/filePage"; + } + + /** + * 鏌ヨfilePage椤甸潰鏁版嵁 + */ + @PostMapping("/filePageList") + @ResponseBody + public TableDataInfo filePageList(@RequestParam("petitionId") Long petitionId) + { + List petitionFiles = petitionService.selectFormFile(petitionId, FormFileConstants.PETITION); + return getDataTable(petitionFiles); + } + /** + * 杩涘叆鏂板闄勪欢椤甸潰 + */ + @RequiresPermissions("system:petition:edit") + @GetMapping("/addFile/{id}") + public String addFile(@PathVariable("id") Long id, ModelMap mmap) + { + mmap.put("petitionId", id); + return prefix + "/addFile"; + } +// /** +// * 鏂板淇濆瓨闄勪欢 +// */ +// @RequiresPermissions("system:petition:add") +// @Log(title = "绛惧憟鏂囦欢", businessType = BusinessType.INSERT) +// @PostMapping("/addFile") +// @ResponseBody +// public AjaxResult addFile(@RequestParam("id") Long id, @RequestParam("file") MultipartFile[] files) { +// Integer i = null; +// try { +// String filePath = RuoYiConfig.getUploadPath(); +// List petitionFileList = new ArrayList<>(); +// for (MultipartFile multipartFile: files) { +// PetitionFile petitionFile = new PetitionFile(); +// String fileName = multipartFile.getOriginalFilename().replaceAll(" ","").replaceAll("&",""); +// String suffix = fileName.substring(fileName.lastIndexOf(".")); +// String uploadPath = FileUploadUtils.upload(filePath, multipartFile,suffix); +// petitionFile.setAssociationId(id); +// petitionFile.setType(1); +// petitionFile.setFile(uploadPath);//瀛樺偍 +// petitionFile.setFileName(fileName);//鏂囦欢鍚 +// petitionFileList.add(petitionFile); +// } +//// buildAttribute(id, OrderTypes.PETITION.value()); +// i = petitionService.insertRequisitionFile(petitionFileList); +// } catch (GlobalException businessException) { +// return error(businessException.getMessage()); +// } catch (Exception e) { +// log.error("淇濆瓨鐢靛瓙绛惧憟闄勪欢鍑洪敊,閿欒鍘熷洜--->", e); +// return error("鎿嶄綔澶辫触锛屽彂鐢熸湭鐭ュ紓甯革紝璇蜂繚瀛樻埅鍥撅紝鍦ㄧ郴缁熷伐鍗曟ā鍧楀彂璧封滃伐浣滄祦瀹℃壒绯荤粺鈥濆伐鍗曞弽棣堛"); +// } +// return success(i.toString()); +// } +// /** +// * 涓婁紶淇濆瓨闄勪欢 +// */ +// @RequiresPermissions("system:petition:add") +// @Log(title = "绛惧憟鏂囦欢", businessType = BusinessType.INSERT) +// @PostMapping("/addFile/save") +// @ResponseBody +// public AjaxResult save(@RequestParam("petitionId") Long id, @RequestParam("file") MultipartFile[] files) throws IOException { +// String filePath = RuoYiConfig.getUploadPath(); +// List petitionFileList = new ArrayList<>(); +// for (MultipartFile multipartFile: files) { +// PetitionFile petitionFile = new PetitionFile(); +// String fileName = multipartFile.getOriginalFilename().replaceAll(" ","").replaceAll("&",""); +// String suffix = fileName.substring(fileName.lastIndexOf(".")); +// String uploadPath = FileUploadUtils.upload(filePath, multipartFile,suffix); +// petitionFile.setAssociationId(id); +// petitionFile.setType(1); +// petitionFile.setFile(uploadPath);//瀛樺偍 +// petitionFile.setFileName(fileName);//鏂囦欢鍚 +// petitionFileList.add(petitionFile); +// } +//// buildAttribute(id, OrderTypes.PETITION.value()); +// return toAjax(petitionService.insertRequisitionFile(petitionFileList)); +// } + + +// @Log(title = "涓嬭浇鏂囦欢", businessType = BusinessType.OTHER) +// @GetMapping("/downloadFile") +// public void downloadFile(@RequestParam("id") Long id, @RequestParam("resource") String resource, HttpServletRequest request, HttpServletResponse response) +// throws Exception +// { +// PetitionFile petitionFile =new PetitionFile(); +// petitionFile.setId(id); +// petitionFile.setFile(resource); +// List petitionFiles = petitionFileService.selectPetitionFileList(petitionFile); +// String filePath = petitionFiles.get(0).getFile(); +// String fileName = petitionFiles.get(0).getFileName(); +//// buildAttribute(id, OrderTypes.PETITION.value()); +// FileDownloadUtils.resourceDownload(filePath,fileName,request,response); +// } + + /** + * 鍒犻櫎閲岄潰鐨勬枃浠 + */ + @Log(title = "鍒犻櫎鏂囦欢", businessType = BusinessType.UPDATE) + @GetMapping("/removeFile") + @ResponseBody + public AjaxResult removeFile(String id,Long requisitionId) + { + petitionFileService.deletePetitionFileByIds(id); +// buildAttribute(requisitionId, OrderTypes.PETITION.value()); + return success(); + } + + /** + * 寮鍚鎵规祦绋 + * 1 鎻愪氦琛ㄥ崟 + */ + /** + * 鎻愪氦琛ㄥ崟 + */ + @RequiresPermissions("system:petition:sub") + @Log(title = "绛惧憟瀹℃壒鍗", businessType = BusinessType.UPDATE) + @GetMapping("/submit") + @ResponseBody + public AjaxResult submit(@RequestParam("id") Long id) + { + try { + SysUser sysUser = getSysUser(); + petitionService.submit(id,sysUser); +// buildAttribute(id, OrderTypes.PETITION.value()); + } catch (GlobalException businessException) { + return error(businessException.getMessage()); + } catch (Exception e) { + log.error("鎻愪氦鐢靛瓙绛惧憟鍑洪敊,閿欒鍘熷洜--->", e); + return error("鎿嶄綔澶辫触锛屽彂鐢熸湭鐭ュ紓甯革紝璇蜂繚瀛樻埅鍥撅紝鍦ㄧ郴缁熷伐鍗曟ā鍧楀彂璧封滃伐浣滄祦瀹℃壒绯荤粺鈥濆伐鍗曞弽棣堛"); + } + return success(id.toString()); + } + /** + * 杩涘叆瀹℃牳鐣岄潰 + */ + @RequiresPermissions("system:petition:audit") + @GetMapping("/audit/{id}") + public String auditFW(@PathVariable("id") Long id, ModelMap mmap) + { + List petitionFiles = petitionService.selectFormFile(id, FormFileConstants.PETITION); + mmap.put("petitionFiles", petitionFiles); + Petition petition = petitionService.selectPetitionById(id); + Integer status = petition.getStatus(); + + //鍔犵浜哄憳鍒楄〃 + PetitionSign p=new PetitionSign(); + p.setPetitionId(id); + p.setSignType(3); + List petitionAddaudits = petitionSignService.selectPetitionSignList(p); + petitionComponent.buildCheckBox(petition); + + + //鏍稿噯浜哄憳鍒楄〃 + PetitionSign ps=new PetitionSign(); + ps.setPetitionId(id); + ps.setSignType(1); + List petitionSigns = petitionSignService.selectPetitionSignList(ps); + + //浼氬浜哄憳鍒楄〃 + PetitionSign pt=new PetitionSign(); + pt.setPetitionId(id); + pt.setSignType(2); + List petitionTrialList = petitionSignService.selectPetitionSignList(pt); + + if (status.equals(PetitionStatus.WAIT_LAW.value())){ + mmap.put("petition", petition); + mmap.put("petitionAddaudits",petitionAddaudits); + mmap.put("typeMaps", petition.getParams()); + mmap.put("petitionSigns",petitionSigns); + mmap.put("petitionTrialList",petitionTrialList); + return prefix + "/auditFW"; + }else if (status.equals(PetitionStatus.WAIT_MANAGER.value())){ + mmap.put("petition", petition); + mmap.put("petitionAddaudits",petitionAddaudits); + mmap.put("typeMaps", petition.getParams()); + mmap.put("petitionSigns",petitionSigns); + mmap.put("petitionTrialList",petitionTrialList); + return prefix + "/auditManager"; + }else if (status.equals(PetitionStatus.WAIT_HR.value())){ + mmap.put("petition", petition); + mmap.put("petitionAddaudits",petitionAddaudits); + mmap.put("typeMaps", petition.getParams()); + mmap.put("petitionSigns",petitionSigns); + mmap.put("petitionTrialList",petitionTrialList); + return prefix + "/auditHR"; + }else if (status.equals(PetitionStatus.WAIT_FC_MANAGER.value())){ + mmap.put("petition", petition); + mmap.put("petitionAddaudits",petitionAddaudits); + mmap.put("typeMaps", petition.getParams()); + mmap.put("petitionSigns",petitionSigns); + mmap.put("petitionTrialList",petitionTrialList); + return prefix + "/auditcw"; + }else if (status.equals(PetitionStatus.C_WAIT_AUDIT.value())){ + mmap.put("petition", petition); + mmap.put("petitionAddaudits",petitionAddaudits); + mmap.put("typeMaps", petition.getParams()); + mmap.put("petitionSigns",petitionSigns); + mmap.put("petitionTrialList",petitionTrialList); + return prefix + "/auditAC"; + } + else if (status.equals(PetitionStatus.WAIT_GM.value())){ + mmap.put("petition", petition); + mmap.put("petitionAddaudits",petitionAddaudits); + mmap.put("typeMaps", petition.getParams()); + mmap.put("petitionSigns",petitionSigns); + mmap.put("petitionTrialList",petitionTrialList); + return prefix + "/auditGM"; + }else if (status.equals(PetitionStatus.WAIT_CFCO_MANAGER.value())){ + mmap.put("petition", petition); + mmap.put("petitionAddaudits",petitionAddaudits); + mmap.put("typeMaps", petition.getParams()); + mmap.put("petitionSigns",petitionSigns); + mmap.put("petitionTrialList",petitionTrialList); + return prefix + "/auditcwManager"; + }else { + mmap.put("petition", petition); + mmap.put("petitionAddaudits",petitionAddaudits); + mmap.put("petitionSigns",petitionSigns); + mmap.put("petitionFiles", petitionFiles); + mmap.put("typeMaps", petition.getParams()); + mmap.put("petitionTrialList",petitionTrialList); + return prefix + "/detail"; + } + } + + /** + * 娉曞姟瀹℃牳缁撴灉鎻愪氦 + */ + @RequiresPermissions("system:petition:audit") + @Log(title = "绛惧憟瀹℃壒娉曞姟瀹℃牳缁撴灉", businessType = BusinessType.UPDATE) + @PostMapping("/auditFW") + @ResponseBody + public AjaxResult auditFw(@RequestBody PetitionDto petitionDto) + { + try { + SysUser sysUser = getSysUser(); + petitionService.updateFwAudit(petitionDto,sysUser); +// buildAttribute(petitionDto.getPetition().getId(), OrderTypes.PETITION.value()); + } catch (GlobalException businessException) { + return error(businessException.getMessage()); + } catch (Exception e) { + log.error("娉曞姟瀹℃牳鐢靛瓙绛惧憟鍑洪敊,閿欒鍘熷洜--->", e); + return error("鎿嶄綔澶辫触锛屽彂鐢熸湭鐭ュ紓甯革紝璇蜂繚瀛樻埅鍥撅紝鍦ㄧ郴缁熷伐鍗曟ā鍧楀彂璧封滃伐浣滄祦瀹℃壒绯荤粺鈥濆伐鍗曞弽棣堛"); + } + return success(); + } + + /** + * 鍔犵浜哄憳瀹℃牳鐣岄潰 + */ + @RequiresPermissions("system:petition:audit") + @GetMapping("/addaudit/{id}") + public String adddaudit(@PathVariable("id") Long id, ModelMap mmap) + { + Petition petition = petitionService.selectPetitionById(id); + PetitionSign petitionAddaudit=new PetitionSign(); + petitionAddaudit.setPetitionId(id); + petitionAddaudit.setSignType(3); + List petitionAddaudits = petitionSignService.selectPetitionSignList(petitionAddaudit); + mmap.put("petition", petition); + mmap.put("petitionAddaudits",petitionAddaudits); + + List petitionFiles = petitionService.selectFormFile(id, FormFileConstants.PETITION); + mmap.put("petitionFiles", petitionFiles); + + //鏍稿噯浜哄憳鍒楄〃 + PetitionSign ps=new PetitionSign(); + ps.setPetitionId(id); + ps.setSignType(1); + List petitionSigns = petitionSignService.selectPetitionSignList(ps); + mmap.put("petitionSigns",petitionSigns); + + //浼氬浜哄憳鍒楄〃 + PetitionSign pt=new PetitionSign(); + pt.setPetitionId(id); + pt.setSignType(2); + List petitionTrialList = petitionSignService.selectPetitionSignList(pt); + mmap.put("petitionTrialList",petitionTrialList); + + petitionComponent.buildCheckBox(petition); + mmap.put("typeMaps", petition.getParams()); + return prefix + "/addAudit"; + } + + /** + * 鍔犵瀹℃牳缁撴灉鎻愪氦 + */ + @RequiresPermissions("system:petition:audit") + @Log(title = "绛惧憟瀹℃壒娉曞姟瀹℃牳缁撴灉", businessType = BusinessType.UPDATE) + @PostMapping("/addaudit") + @ResponseBody + public AjaxResult addaudit(@RequestBody PetitionDto petitionDto) + { + try { + SysUser sysUser = getSysUser(); + petitionService.updateaddAudit(petitionDto,sysUser); +// buildAttribute(petitionDto.getPetition().getId(), OrderTypes.PETITION.value()); + } catch (GlobalException businessException) { + return error(businessException.getMessage()); + } catch (Exception e) { + log.error("鍔犵瀹℃牳鐢靛瓙绛惧憟鍑洪敊,閿欒鍘熷洜--->", e); + return error("鎿嶄綔澶辫触锛屽彂鐢熸湭鐭ュ紓甯革紝璇蜂繚瀛樻埅鍥撅紝鍦ㄧ郴缁熷伐鍗曟ā鍧楀彂璧封滃伐浣滄祦瀹℃壒绯荤粺鈥濆伐鍗曞弽棣堛"); + } + return success(); + } + + + + + /** + * 涓荤瀹℃牳缁撴灉鎻愪氦 + */ + @RequiresPermissions("system:petition:audit") + @Log(title = "绛惧憟瀹℃壒涓荤瀹℃牳缁撴灉", businessType = BusinessType.UPDATE) + @PostMapping("/auditManager") + @ResponseBody + public AjaxResult auditSave(@RequestBody PetitionDto petitionDto) + { + try { + SysUser sysUser = getSysUser(); + Integer i=petitionService.updateAudit(petitionDto,sysUser); +// buildAttribute(petitionDto.getPetition().getId(), OrderTypes.PETITION.value()); + } catch (GlobalException businessException) { + return error(businessException.getMessage()); + } catch (Exception e) { + log.error("涓荤瀹℃牳鐢靛瓙绛惧憟鍑洪敊,閿欒鍘熷洜--->", e); + return error("鎿嶄綔澶辫触锛屽彂鐢熸湭鐭ュ紓甯革紝璇蜂繚瀛樻埅鍥撅紝鍦ㄧ郴缁熷伐鍗曟ā鍧楀彂璧封滃伐浣滄祦瀹℃壒绯荤粺鈥濆伐鍗曞弽棣堛"); + } + return success(); + } + + + /** + * HR瀹℃牳缁撴灉鎻愪氦 + */ + @RequiresPermissions("system:petition:auditHR") + @Log(title = "绛惧憟瀹℃壒HR瀹℃牳缁撴灉", businessType = BusinessType.UPDATE) + @PostMapping("/auditHR") + @ResponseBody + public AjaxResult auditHR(@RequestBody PetitionDto petitionDto) + { + try { + SysUser sysUser = getSysUser(); + Integer i=petitionService.updateAuditHR(petitionDto,sysUser); +// buildAttribute(petitionDto.getPetition().getId(), OrderTypes.PETITION.value()); + } catch (GlobalException businessException) { + return error(businessException.getMessage()); + } catch (Exception e) { + log.error("HR瀹℃牳鐢靛瓙绛惧憟鍑洪敊,閿欒鍘熷洜--->", e); + return error("鎿嶄綔澶辫触锛屽彂鐢熸湭鐭ュ紓甯革紝璇蜂繚瀛樻埅鍥撅紝鍦ㄧ郴缁熷伐鍗曟ā鍧楀彂璧封滃伐浣滄祦瀹℃壒绯荤粺鈥濆伐鍗曞弽棣堛"); + } + return success(); + } + + /** + * 璐㈠姟鎬昏处瀹℃牳缁撴灉鎻愪氦 + */ + @RequiresPermissions("system:petition:auditcw") + @Log(title = "绛惧憟瀹℃壒璐㈠姟瀹℃牳缁撴灉", businessType = BusinessType.UPDATE) + @PostMapping("/auditcw") + @ResponseBody + public AjaxResult auditcw(@RequestBody PetitionDto petitionDto) + { + try { + SysUser sysUser = getSysUser(); + petitionService.updateAuditcw(petitionDto,sysUser); +// buildAttribute(petitionDto.getPetition().getId(), OrderTypes.PETITION.value()); + } catch (GlobalException businessException) { + return error(businessException.getMessage()); + } catch (Exception e) { + log.error("璐㈠姟鎬昏处瀹℃牳鐢靛瓙绛惧憟鍑洪敊,閿欒鍘熷洜--->", e); + return error("鎿嶄綔澶辫触锛屽彂鐢熸湭鐭ュ紓甯革紝璇蜂繚瀛樻埅鍥撅紝鍦ㄧ郴缁熷伐鍗曟ā鍧楀彂璧封滃伐浣滄祦瀹℃壒绯荤粺鈥濆伐鍗曞弽棣堛"); + } + return success(); + } + /** + * 璐㈠姟缁忕悊瀹℃牳缁撴灉鎻愪氦 + */ + @RequiresPermissions("system:petition:audit") + @Log(title = "绛惧憟瀹℃壒璐㈠姟瀹℃牳缁撴灉", businessType = BusinessType.UPDATE) + @PostMapping("/auditcwManager") + @ResponseBody + public AjaxResult auditcwManager(@RequestBody PetitionDto petitionDto) + { + try { + SysUser sysUser = getSysUser(); + Integer i=petitionService.updateAuditcwManager(petitionDto,sysUser); +// buildAttribute(petitionDto.getPetition().getId(), OrderTypes.PETITION.value()); + } catch (GlobalException businessException) { + return error(businessException.getMessage()); + } catch (Exception e) { + log.error("璐㈠姟缁忕悊瀹℃牳鐢靛瓙绛惧憟鍑洪敊,閿欒鍘熷洜--->", e); + return error("鎿嶄綔澶辫触锛屽彂鐢熸湭鐭ュ紓甯革紝璇蜂繚瀛樻埅鍥撅紝鍦ㄧ郴缁熷伐鍗曟ā鍧楀彂璧封滃伐浣滄祦瀹℃壒绯荤粺鈥濆伐鍗曞弽棣堛"); + } + return success(); + } + /** + * 瀹℃牳浜哄鏍哥粨鏋滄彁浜 + */ + @RequiresPermissions("system:petition:audit") + @Log(title = "绛惧憟瀹℃壒瀹℃牳浜哄鏍哥粨鏋", businessType = BusinessType.UPDATE) + @PostMapping("/auditAC") + @ResponseBody + public AjaxResult auditAC(@RequestBody PetitionDto petitionDto) + { + try { + SysUser sysUser = getSysUser(); + Integer i=petitionService.updateAuditAC(petitionDto,sysUser); +// buildAttribute(petitionDto.getPetition().getId(), OrderTypes.PETITION.value()); + } catch (GlobalException businessException) { + return error(businessException.getMessage()); + } catch (Exception e) { + log.error("瀹℃牳浜哄鏍哥數瀛愮鍛堝嚭閿,閿欒鍘熷洜--->", e); + return error("鎿嶄綔澶辫触锛屽彂鐢熸湭鐭ュ紓甯革紝璇蜂繚瀛樻埅鍥撅紝鍦ㄧ郴缁熷伐鍗曟ā鍧楀彂璧封滃伐浣滄祦瀹℃壒绯荤粺鈥濆伐鍗曞弽棣堛"); + } + return success(); + } + + /** + * 鏍稿噯浜哄鏍哥粨鏋滄彁浜 + */ + @RequiresPermissions("system:petition:auditGM") + @Log(title = "绛惧憟瀹℃壒鎬荤粡鐞嗗鏍哥粨鏋", businessType = BusinessType.UPDATE) + @PostMapping("/auditGM") + @ResponseBody + public AjaxResult auditGM(@RequestBody PetitionDto petitionDto) + { + try { + SysUser sysUser = getSysUser(); + Integer i=petitionService.updateAuditGM(petitionDto,sysUser); +// buildAttribute(petitionDto.getPetition().getId(), OrderTypes.PETITION.value()); + } catch (GlobalException businessException) { + return error(businessException.getMessage()); + } catch (Exception e) { + log.error("鏍稿噯浜哄鏍哥數瀛愮鍛堝嚭閿,閿欒鍘熷洜--->", e); + return error("鎿嶄綔澶辫触锛屽彂鐢熸湭鐭ュ紓甯革紝璇蜂繚瀛樻埅鍥撅紝鍦ㄧ郴缁熷伐鍗曟ā鍧楀彂璧封滃伐浣滄祦瀹℃壒绯荤粺鈥濆伐鍗曞弽棣堛"); + } + return success(); + } + + + + /** + * 鏂板鏍稿噯浜哄鏍哥晫闈 + */ + @RequiresPermissions("system:petition:audit") + @GetMapping("/auditOtherGM/{id}") + public String auditOtherGM(@PathVariable("id") Long id, ModelMap mmap) + { + Petition petition = petitionService.selectPetitionById(id); + mmap.put("petition", petition); + PetitionSign ps=new PetitionSign(); + ps.setPetitionId(id); + ps.setSignType(1); + List petitionSigns = petitionSignService.selectPetitionSignList(ps); + mmap.put("petitionSigns",petitionSigns); + + PetitionSign pt=new PetitionSign(); + pt.setPetitionId(id); + pt.setSignType(2); + List petitionTrialList = petitionSignService.selectPetitionSignList(pt); + mmap.put("petitionTrialList",petitionTrialList); + + List petitionFiles = petitionService.selectFormFile(id, FormFileConstants.PETITION); + mmap.put("petitionFiles", petitionFiles); + + + //鍔犵浜哄憳鍒楄〃 + PetitionSign p=new PetitionSign(); + p.setPetitionId(id); + p.setSignType(3); + List petitionAddaudits = petitionSignService.selectPetitionSignList(p); + mmap.put("petitionAddaudits",petitionAddaudits); + + petitionComponent.buildCheckBox(petition); + mmap.put("typeMaps", petition.getParams()); + + return prefix + "/addSign"; + } + + + /** + * 鏂板鏍稿噯浜哄鏍哥粨鏋滄彁浜 + */ + @RequiresPermissions("system:petition:audit") + @Log(title = "绛惧憟瀹℃壒鏂板鏍稿噯浜哄鏍哥粨鏋", businessType = BusinessType.UPDATE) + @PostMapping("/addSign") + @ResponseBody + public AjaxResult addSign(@RequestBody PetitionDto petitionDto) + { + try { + SysUser sysUser = getSysUser(); + Integer i=petitionService.updateaddSign(petitionDto,sysUser); +// buildAttribute(petitionDto.getPetition().getId(), OrderTypes.PETITION.value()); + } catch (GlobalException businessException) { + return error(businessException.getMessage()); + } catch (Exception e) { + log.error("鏂板鏍稿噯浜哄鏍哥數瀛愮鍛堝嚭閿,閿欒鍘熷洜--->", e); + return error("鎿嶄綔澶辫触锛屽彂鐢熸湭鐭ュ紓甯革紝璇蜂繚瀛樻埅鍥撅紝鍦ㄧ郴缁熷伐鍗曟ā鍧楀彂璧封滃伐浣滄祦瀹℃壒绯荤粺鈥濆伐鍗曞弽棣堛"); + } + return success(); + } + + /** + * 鏂板浼氬浜哄鏍哥晫闈 + */ + @RequiresPermissions("system:petition:audit") + @GetMapping("/auditOtherPT/{id}") + public String auditOtherPT(@PathVariable("id") Long id, ModelMap mmap) + { + Petition petition = petitionService.selectPetitionById(id); + PetitionSign ps=new PetitionSign(); + ps.setPetitionId(id); + ps.setSignType(1); + List petitionSigns = petitionSignService.selectPetitionSignList(ps); + mmap.put("petitionSigns",petitionSigns); + + mmap.put("petition", petition); + PetitionSign pt=new PetitionSign(); + pt.setPetitionId(id); + pt.setSignType(2); + List petitionTrialList = petitionSignService.selectPetitionSignList(pt); + mmap.put("petitionTrialList",petitionTrialList); + + List petitionFiles = petitionService.selectFormFile(id, FormFileConstants.PETITION); + mmap.put("petitionFiles", petitionFiles); + + + //鍔犵浜哄憳鍒楄〃 + PetitionSign p=new PetitionSign(); + p.setPetitionId(id); + p.setSignType(3); + List petitionAddaudits = petitionSignService.selectPetitionSignList(p); + mmap.put("petitionAddaudits",petitionAddaudits); + + petitionComponent.buildCheckBox(petition); + mmap.put("typeMaps", petition.getParams()); + + return prefix + "/addTrial"; + } + + + /** + * 鏂板浼氬浜哄鏍哥粨鏋滄彁浜 + * @param petitionDto + * @return + */ + @RequiresPermissions("system:petition:audit") + @Log(title = "绛惧憟瀹℃壒鏂板浼氬浜哄鏍哥粨鏋", businessType = BusinessType.UPDATE) + @PostMapping("/addTrial") + @ResponseBody + public AjaxResult addTrial(@RequestBody PetitionDto petitionDto) + { + try { + SysUser sysUser = getSysUser(); + Integer i=petitionService.updateaddTrial(petitionDto,sysUser); +// buildAttribute(petitionDto.getPetition().getId(), OrderTypes.PETITION.value()); + } catch (GlobalException businessException) { + return error(businessException.getMessage()); + } catch (Exception e) { + log.error("浼氬浜哄鏍哥數瀛愮鍛堝嚭閿,閿欒鍘熷洜--->", e); + return error("鎿嶄綔澶辫触锛屽彂鐢熸湭鐭ュ紓甯革紝璇蜂繚瀛樻埅鍥撅紝鍦ㄧ郴缁熷伐鍗曟ā鍧楀彂璧封滃伐浣滄祦瀹℃壒绯荤粺鈥濆伐鍗曞弽棣堛"); + } + return success(); + } + + /** + * 杩涘叆瀹℃壒鍘嗗彶椤甸潰 + */ + @RequestMapping("/audithistory/{id}") + public String auditHistory(@PathVariable("id") Long id, ModelMap mmap) + { + mmap.put("id", id); + return prefix + "/audithistory"; + } + + /** + * 瀹℃壒鍘嗗彶鐩稿叧鏁版嵁 + */ + @PostMapping("/auditHistoryList") + @ResponseBody + public TableDataInfo auditHistoryList(ProcessFlow processFlow) { + processFlow.setOrderId(processFlow.getOrderId()); + startPage(); + List list = processFlowService.selectProcessFlowList(processFlow); + return getDataTable(list); + } + + +// @Log(title = "瀵煎嚭PDF", businessType = BusinessType.OTHER) +// @GetMapping("/exportPDF/{id}") +// public void exportPDF(@PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response) { +// ArrayList arrayList = new ArrayList<>(); +// Page page = null; +// Browser browser = null; +// String uuid = UUID.randomUUID().toString(); +// //鐢熸垚pdf蹇呴』鍦ㄦ棤鍘樺ご妯″紡涓嬫墠鑳界敓鏁 +// String path = "D:\\puppeteer\\node_modules\\puppeteer\\.local-chromium\\win64-782078\\chrome-win\\chrome.exe"; +// LaunchOptions options = new LaunchOptionsBuilder().withArgs(arrayList).withHeadless(true).withExecutablePath(path).build(); +// arrayList.add("--no-sandbox"); +// arrayList.add("--disable-setuid-sandbox"); +// try { +// browser = Puppeteer.launch(options); +// page = browser.newPage(); +// page.goTo("http://127.0.0.1:8060/api/system/petitionApp/detail/"+ id +"?secret=122acdsdbgfdgffdddd"); +// PDFOptions pdfOptions = new PDFOptions(); +// page.setDefaultTimeout(1000); +// pdfOptions.setPath("E:\\java\\pdfDownload\\" + uuid + ".pdf"); +// pdfOptions.setFormat("a4"); +// page.pdf(pdfOptions); +// }catch (Exception e){ +// log.error("鐢靛瓙绛惧憟鐢熸垚PDF椤甸潰澶辫触,閿欒濡備笅--->",e); +// throw new GlobalException("鐢熸垚PDF椤甸潰澶辫触锛佽绋嶅悗閲嶈瘯銆"); +// }finally { +// if (StringUtils.isNotNull(page)) { +// try { +// page.close(); +// }catch (Exception e){ +// log.error("鐢靛瓙绛惧憟鐢熸垚PDF椤甸潰澶辫触,閿欒濡備笅--->",e); +// throw new GlobalException("鐢熸垚PDF椤甸潰澶辫触锛佽绋嶅悗閲嶈瘯銆"); +// } +// } +// if (StringUtils.isNotNull(browser)) { +// browser.close(); +// } +// } +// +// String url = "E:\\java\\pdfDownload\\" + uuid + ".pdf"; +// File fileurl = new File(url); +// try{ +// //鏍规嵁鏉′欢寰楀埌鏂囦欢璺緞 +//// System.out.println("===========鏂囦欢璺緞==========="+fileurl); +// //灏嗘枃浠惰鍏ユ枃浠舵祦 +// InputStream inStream = new FileInputStream(fileurl); +// //鑾峰緱娴忚鍣ㄤ唬鐞嗕俊鎭 +// final String userAgent = request.getHeader("USER-AGENT"); +// //鍒ゆ柇娴忚鍣ㄤ唬鐞嗗苟鍒嗗埆璁剧疆鍝嶅簲缁欐祻瑙堝櫒鐨勭紪鐮佹牸寮 +// String finalFileName = null; +// if(StringUtils.contains(userAgent, "MSIE")|| StringUtils.contains(userAgent,"Trident")){//IE娴忚鍣 +// finalFileName = URLEncoder.encode("Petition.pdf","UTF8"); +// System.out.println("IE娴忚鍣"); +// }else if(StringUtils.contains(userAgent, "Mozilla")){//google,鐏嫄娴忚鍣 +// finalFileName = new String("Petition.pdf".getBytes(), "ISO8859-1"); +// }else{ +// finalFileName = URLEncoder.encode("Petition.pdf","UTF8");//鍏朵粬娴忚鍣 +// } +// //璁剧疆HTTP鍝嶅簲澶 +// response.reset();//閲嶇疆 鍝嶅簲澶 +// response.setContentType("application/x-download");//鍛婄煡娴忚鍣ㄤ笅杞芥枃浠讹紝鑰屼笉鏄洿鎺ユ墦寮锛屾祻瑙堝櫒榛樿涓烘墦寮 +// response.addHeader("Content-Disposition" ,"attachment;filename=\"" +finalFileName+ "\"");//涓嬭浇鏂囦欢鐨勫悕绉 +// +// // 寰幆鍙栧嚭娴佷腑鐨勬暟鎹 +// byte[] b = new byte[1024]; +// int len; +// while ((len = inStream.read(b)) > 0){ +// response.getOutputStream().write(b, 0, len); +// } +// inStream.close(); +// response.getOutputStream().close(); +// }catch(Exception e) { +// log.error("鐢靛瓙绛惧憟涓嬭浇PDF椤甸潰澶辫触,閿欒濡備笅--->",e); +// throw new GlobalException("鎵撳嵃PDF澶辫触锛岃淇濆瓨鎴浘锛屽湪绯荤粺宸ュ崟妯″潡鍙戣捣鈥滃伐浣滄祦瀹℃壒绯荤粺鈥濆伐鍗曞弽棣堛"); +// } +// fileurl.delete(); +// } + + //鑷姩琛ュ叏鎼滅储妗 + @GetMapping("/getAlluser") + @ResponseBody + public AjaxResult getAlluser(SysUser u){ + List users = userService.selectUserList(u); + List value=new ArrayList<>(); + for (SysUser user : users) { + String userName = user.getUserName(); + value.add(userName); + } + AjaxResult ajaxResult=new AjaxResult(); + ajaxResult.put("value",value); + return ajaxResult; + } + + + /** + * 鎻愪氦琛ㄥ崟 + */ + @PostMapping("/revent") + @ResponseBody + public AjaxResult revent(@RequestParam("id") Long id, @RequestParam("cancelRemark") String cancelRemark) + { + try { + SysUser sysUser = ShiroUtils.getSysUser(); + petitionService.WithdrawalOfInitiation(id,cancelRemark,sysUser); + } catch (GlobalException businessException) { + return error(businessException.getMessage()); + } catch (Exception e) { + log.error("鎻愪氦鐢靛瓙绛惧憟鍑洪敊,閿欒鍘熷洜--->", e); + return error("鎿嶄綔澶辫触锛屽彂鐢熸湭鐭ュ紓甯革紝璇蜂繚瀛樻埅鍥撅紝鍦ㄧ郴缁熷伐鍗曟ā鍧楀彂璧封滃伐浣滄祦瀹℃壒绯荤粺鈥濆伐鍗曞弽棣堛"); + } + return success(id.toString()); + } + + /** + * 杩涘叆鎾ゅ洖椤甸潰 + * @param id + * @param mmap + * @return + */ + @GetMapping("/cancel/{id}") + public String forCancel(@PathVariable("id") Long id, ModelMap mmap) + { + mmap.put("id", id); + return prefix + "/cancel"; + } + + /** + * 杩涘叆瀹℃壒鎴浘鏂板闄勪欢椤甸潰 + */ + @RequiresPermissions("system:petition:edit") + @GetMapping("/addCloseFile/{id}") + public String addCloseFile(@PathVariable("id") Long id, ModelMap mmap) + { + mmap.put("petitionId", id); + return prefix + "/addCloseFile"; + } + + /** + * 涓婁紶瀹℃壒鎴浘 + * @param file 鏂囦欢 + * @param petitionId 璇锋鍗昳d + * @return + * @throws IOException + */ + @RequiresPermissions("system:petition:edit") + @PostMapping("/addCloseFile/save") + @ResponseBody + public AjaxResult addClosePaymentRequestFileSave(@RequestParam("file") MultipartFile file, + @RequestParam("petitionId") long petitionId) { + try { + petitionService.insertPetitionFile(file, petitionId, ShiroUtils.getSysUser()); + } catch (GlobalException businessException) { + return error(businessException.getMessage()); + } catch (Exception e) { + log.error("鐢靛瓙绛惧憟涓婁紶瀹℃壒鎴浘鍑洪敊,閿欒鍘熷洜--->", e); + return error("鎿嶄綔澶辫触锛屽彂鐢熸湭鐭ュ紓甯革紝璇蜂繚瀛樻埅鍥撅紝鍦ㄧ郴缁熷伐鍗曟ā鍧楀彂璧封滃伐浣滄祦瀹℃壒绯荤粺鈥濆伐鍗曞弽棣堛"); + } + return success(); + } + +// /** +// * 涓嬭浇鎴浘鍑瘉 +// * @param id 璇锋鍗昳d +// * @param request +// * @param response +// * @throws Exception +// */ +// @GetMapping("/download/ClosePaymentRequestFile") +// public void downloadClosePaymentRequestFile(@RequestParam("id") Long id, +// HttpServletRequest request, HttpServletResponse response)throws Exception +// { +// Petition petition= new Petition(); +// petition.setId(id); +// Petition petitions = petitionService.selectPetitionById(petition.getId()); +// String filePath = petitions.getCloseFile(); +// String fileName = petitions.getCloseFileName(); +// FileDownloadUtils.resourceDownload(filePath,fileName,request,response); +// } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/RequisitionController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/RequisitionController.java new file mode 100644 index 000000000..ec06058d1 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/RequisitionController.java @@ -0,0 +1,477 @@ +package com.ruoyi.web.controller.system; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import com.ruoyi.common.annotation.RepeatSubmit; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.FormFileConstants; +import com.ruoyi.common.core.domain.Ztree; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.enums.OrderTypes; +import com.ruoyi.common.enums.RequisitionStatus; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.CacheUtils; +import com.ruoyi.common.utils.ShiroUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.component.requisition.RequisitionComponent; +import com.ruoyi.system.domain.ProcessFlow; +import com.ruoyi.system.domain.requisition.Requisition; +import com.ruoyi.system.domain.requisition.RequisitionAuditResults; +import com.ruoyi.system.service.IProcessFlowService; +import com.ruoyi.system.service.requisition.IRequisitionService; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.*; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.core.page.TableDataInfo; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + + +/** + * 璇疯喘鍗旵ontroller + * + * @author SKaiL + * @date 2022-09-26 + */ +@Controller +@RequestMapping("/system/requisition") +public class RequisitionController extends BaseController +{ + private String prefix = "system/requisition"; + + @Autowired + private IRequisitionService requisitionService; + + @Autowired + private IProcessFlowService processFlowService; + + @Autowired + private RequisitionComponent requisitionComponent; + + @RequiresPermissions("system:requisition:view") + @GetMapping() + public String requisition() + { + return prefix + "/requisition"; + } + + /** + * 鏌ヨ璇疯喘鍗曞垪琛 + */ + @RequiresPermissions("system:requisition:listAll") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(Requisition requisition) + { + startPage(); + List list = requisitionService.selectRequisitionList(requisition); + return getDataTable(list); + } + + @RequiresPermissions("system:requisition:view") + @GetMapping("/create") + public String requisitionCreate() + { + return prefix + "/requisitionCreate"; + } + + /** + * 鎴戠殑鍒涘缓 + */ + @RequiresPermissions("system:requisition:list") + @PostMapping("/list/create") + @ResponseBody + public TableDataInfo listCreate(Requisition requisition) + { + SysUser sysUser = ShiroUtils.getSysUser(); + //璐㈠姟锛岀ń鏍稿拰绠$悊鍛樻煡鐪嬫墍鏈 + if (!sysUser.isAdmin()) { + requisition.setEmployeeNo(getSysUser().getUserCode()); + } + startPage(); + List list = requisitionService.selectRequisitionList(requisition); + return getDataTable(list); + } + + @GetMapping("/draft") + public String requisitionDraft() + { + return prefix + "/requisitionDraft"; + } + + /** + * 鎴戠殑鑽夌ǹ + */ + @PostMapping("/list/draft") + @ResponseBody + public TableDataInfo listDraft(Requisition requisition) + { + SysUser sysUser = ShiroUtils.getSysUser(); + //璐㈠姟锛岀ń鏍稿拰绠$悊鍛樻煡鐪嬫墍鏈 + if (!sysUser.isAdmin()) { + requisition.setEmployeeNo(getSysUser().getUserCode()); + } + startPage(); + List list = requisitionService.selectRequisitionListDraft(requisition); + return getDataTable(list); + } + + @RequiresPermissions("system:requisition:view") + @GetMapping("/todo") + public String requisitionTodo() + { + return prefix + "/requisitionToDo"; + } + + /** + * 鎴戠殑寰呭姙 + */ + @RequiresPermissions("system:requisition:list") + @PostMapping("/list/todo") + @ResponseBody + public TableDataInfo listToDo(Requisition requisition) + { + SysUser sysUser = ShiroUtils.getSysUser(); + if (!sysUser.isAdmin()) { + requisition.setSendToCode(getSysUser().getUserCode()); + } + startPage(); + List list = requisitionService.selectRequisitionList(requisition); + return getDataTable(list); + } + + @RequiresPermissions("system:requisition:view") + @GetMapping("/do") + public String requisitionDo() + { + return prefix + "/requisitionDo"; + } + + /** + * 鎴戠殑宸插姙 + */ + @RequiresPermissions("system:requisition:list") + @PostMapping("/list/do") + @ResponseBody + public TableDataInfo listDo(Requisition requisition) + { + requisition.setHandlesCode(ShiroUtils.getSysUser().getUserCode()); + startPage(); + List list = requisitionService.selectRequisitionList(requisition); + return getDataTable(list); + } + + /** + * 瀵煎嚭璇疯喘鍗曞垪琛 + */ + @RequiresPermissions("system:requisition:export") + @Log(title = "璇疯喘鍗", businessType = BusinessType.EXPORT) + @PostMapping("/export") + @ResponseBody + public AjaxResult export(Requisition requisition) + { + List list = requisitionService.selectRequisitionList(requisition); + ExcelUtil util = new ExcelUtil(Requisition.class); + return util.exportExcel(list, "璇疯喘鍗曟暟鎹"); + } + + /** + * 鏂板璇疯喘鍗 + */ + @GetMapping("/add") + public String add(ModelMap mmap) + { + mmap.put("user", getSysUser()); + String s = requisitionComponent.buildData(); + mmap.put("data", s); + mmap.put("projectCode", CacheUtils.get(Constants.ZT_WGCPRORELEASE_CACHE, Constants.ZT_WGCPRORELEASE_KEY + "proCode")); + return prefix + "/add"; + } + + /** + * 鏂板淇濆瓨璇疯喘鍗 + */ + @RequiresPermissions("system:requisition:add") + @Log(title = "璇疯喘鍗", businessType = BusinessType.INSERT) + @PostMapping("/add") + @ResponseBody + @RepeatSubmit + public AjaxResult addSave(@RequestBody Requisition requisition) + { + return success(requisitionService.insertRequisition(requisition, getSysUser())); + } + + /** + * 淇敼璇疯喘鍗 + */ + @RequiresPermissions("system:requisition:edit") + @GetMapping("/edit/{id}") + public String edit(@PathVariable("id") Long id, ModelMap mmap) + { + Requisition requisition = requisitionService.selectRequisitionById(id); + mmap.put("requisition", requisition); + String s = requisitionComponent.buildData(); + mmap.put("data", s); + mmap.put("projectCode", CacheUtils.get(Constants.ZT_WGCPRORELEASE_CACHE, Constants.ZT_WGCPRORELEASE_KEY + "proCode")); + return prefix + "/edit"; + } + + /** + * 淇敼淇濆瓨璇疯喘鍗 + */ + @RequiresPermissions("system:requisition:edit") + @Log(title = "璇疯喘鍗", businessType = BusinessType.UPDATE) + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(@RequestBody Requisition requisition) + { + return success(requisitionService.updateRequisition(requisition, getSysUser())); + } + + /** + * 鍒犻櫎璇疯喘鍗 + */ + @RequiresPermissions("system:requisition:remove") + @Log(title = "璇疯喘鍗", businessType = BusinessType.DELETE) + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + return toAjax(requisitionService.deleteRequisitionByIds(ids)); + } + + /** + * 璇疯喘鍗曟彁浜 + */ + @RequiresPermissions("system:requisition:add") + @Log(title = "璇疯喘鍗曚富", businessType = BusinessType.UPDATE) + @GetMapping("/submit") + @ResponseBody + @RepeatSubmit + public AjaxResult startSubmit(@RequestParam("id") Long requisitionId) throws ServiceException + { + SysUser sysUser = ShiroUtils.getSysUser(); + requisitionService.submit(requisitionId, sysUser); + return success(); + } + + @RequiresPermissions("system:requisition:edit") + @GetMapping(value = {"/addFile/{type}","/addFile/{id}/{type}"}) + public String forFaReportUpload(@PathVariable(value = "id",required = false) Long id, @PathVariable("type") Integer type, ModelMap mmap) + { + mmap.put("requisitionId", id); + //鏂囦欢绫诲瀷 22浣跨敤鏂囨。, 2璇疯喘鍗曢檮浠 + mmap.put("type", type); + return prefix + "/addFile"; + } + + @GetMapping(value = {"/filePage/{type}/{flag}","/filePage/{id}/{type}/{flag}"}) + public String filePage(@PathVariable(value = "id",required = false) Long id, @PathVariable("type") Integer type, + @PathVariable("flag") Boolean flag, ModelMap mmap) + { + mmap.put("requisitionId", id); + //鏂囦欢绫诲瀷 22浣跨敤鏂囨。, 2璇疯喘鍗曢檮浠 + mmap.put("type", type); + mmap.put("flag", flag); + //妯$増涓嶅厑璁告櫘閫氱敤鎴峰垹闄 + if (Objects.equals(FormFileConstants.REQUISTION_TEMPLATE, type)){ + if (getSysUser().isAdmin()){ + mmap.put("flag", true); + } else { + mmap.put("flag", false); + } + } + return prefix + "/filePage"; + } + + /** + * 鏌ヨ鏂囦欢鍒楄〃 + */ + @PostMapping("/filePageList") + @ResponseBody + public TableDataInfo filePage(@RequestParam(value = "requisitionId",required = false) Long requisitionId, + @RequestParam("type") Integer type) + { + return getDataTable(requisitionService.selectFormFile(requisitionId, type)); + } + + /** + * 璇︽儏椤 + */ + @GetMapping("/detail/{id}/{type}") + public String deatil(@PathVariable("id") Long id, @PathVariable("type") Integer type, ModelMap mmap) + { + Requisition requisition = requisitionService.selectRequisitionById(id); + requisitionComponent.approvalProgress(requisition); + mmap.put("requisition", requisition); + //瀹℃壒璁板綍 + List list = processFlowService.selectProcessFlowListByOrderId(id, OrderTypes.REQUISITION.getCode()); + mmap.put("lists", list); + mmap.put("listFile", requisitionService.selectFormFile(id, FormFileConstants.REQUISITION)); + mmap.put("isClose", "0"); + //闄堟诲鏍告殏鏃朵笂浼犲鎵规埅鍥炬寜閽 + List collect = list.stream().filter(pf -> (Objects.equals(requisition.getEmployeeNo(), getSysUser().getUserCode()) + || getSysUser().isAdmin()) && Objects.equals(pf.getCreateByCode(), "S00001") + && StringUtils.isNull(pf.getAuditResult())).collect(Collectors.toList()); + if (StringUtils.isNotEmpty(collect) && Objects.equals(collect.get(0).getStatus(), requisition.getStatus())){ + mmap.put("isClose", "1"); + } + if (Objects.equals(type, 2)){ + //灞曠ず瀹℃壒鎴浘 + if (requisition.getStatus() == 5 && StringUtils.isNotEmpty(requisition.getCloseFile())) { + String url = requisition.getCloseFile(); + if (url.contains(".jpg") || url.contains(".png")) { + mmap.put("url", url); + } + } + return prefix + "/detailPDF"; + } else { + return prefix + "/detail"; + } + } + + @GetMapping("/review/{id}") + @RequiresPermissions("system:requisition:review") + public String review(@PathVariable("id") Long id, ModelMap mmap) + { + Requisition requisition = requisitionService.selectRequisitionById(id); + requisitionComponent.approvalProgress(requisition); + mmap.put("requisition", requisition); + mmap.put("projectCode", CacheUtils.get(Constants.ZT_WGCPRORELEASE_CACHE, Constants.ZT_WGCPRORELEASE_KEY + "proCode")); + //瀹℃壒璁板綍 + List list = processFlowService.selectProcessFlowListByOrderId(id, OrderTypes.REQUISITION.getCode()); + mmap.put("lists", list); + mmap.put("listFile", requisitionService.selectFormFile(id, FormFileConstants.REQUISITION)); + Integer status = requisition.getStatus(); + if (status.equals(RequisitionStatus.DB_OFFER.getCode())) { + //璧勪骇绠$悊鍛樺拰閲囪喘浠h〃 + return prefix + "/assetReview"; + } else { + //鍏朵粬 + return prefix + "/review"; + } + } + + + /** + * 璇疯喘鍗曞鏍 + * @param auditResults + * @return + */ + @Log(title = "璇疯喘鍗曞鏍", businessType = BusinessType.OTHER) + @RequiresPermissions("system:requisition:review") + @PostMapping("/auditSubmit") + @ResponseBody + @RepeatSubmit + public AjaxResult auditSubmit(@RequestBody RequisitionAuditResults auditResults) throws ServiceException + { + return toAjax(requisitionService.auditSubmit(auditResults, getSysUser())); + } + + /** + * 鎾ゅ洖 + * + * @param id + * @return + */ + @GetMapping("/withdrawal") + @ResponseBody + public AjaxResult Withdrawal(Long id) + { + return toAjax(requisitionService.withdraw(id)); + } + + /** + * 涓婁紶瀹℃壒鎴浘鏂囦欢 + */ + @RequiresPermissions("system:requisition:edit") + @PostMapping("/addCloseRequisitionFile/save") + @ResponseBody + public AjaxResult addCloseRequisitionFileSave(@RequestParam("file") MultipartFile file, + @RequestParam("requisitionId") Long requisitionId) + { + return toAjax(requisitionService.closeRequisitionFile(file, requisitionId, getSysUser())); + } + + /** + * 鏍¢獙鏄惁瀹℃牳 + */ + @GetMapping("/forReview/{id}") + @ResponseBody + public AjaxResult forReview(@PathVariable("id") Long id) { + Requisition requisition = requisitionService.selectRequisitionById(id); + if(!ShiroUtils.getSysUser().isAdmin()&&!Objects.equals(requisition.getSendToCode(),ShiroUtils.getLoginName())){ + throw new ServiceException("宸茬粡绛炬牳瀹屾垚锛岃绛炬牳涓嬩竴鍗曘"); + } + return AjaxResult.success(); + } + + /** + * 浣跨敤璇存槑鐩稿叧鏂囨。涓嬭浇 + * @param request + * @param response + * @throws Exception + */ + @GetMapping("/downloadFileDescription/{type}") + public void downloadFileDescription(@PathVariable("type")Integer type, + HttpServletRequest request, HttpServletResponse response) + { + requisitionService.downloadFileDescription(type, response); + } + + /** + * 鎵归噺瀹℃牳鐣岄潰 + * @param ids + * @param map + * @return + */ + @GetMapping("/batchReview/{ids}") + public String batchReview(@PathVariable("ids") String ids, ModelMap map){ + map.put("ids", ids); + return prefix + "/batchReview"; + } + + /** + * 鎵归噺瀹℃牳 + * @param auditResults 瀹℃牳淇℃伅 + * @return + */ + @PostMapping("/batchReview") + @ResponseBody + public AjaxResult batchReview(@RequestBody RequisitionAuditResults auditResults){ + return success(requisitionService.requisitionBatchReview(auditResults, getSysUser())); + } + + @GetMapping("/forCodeNamePage/{index}") + public String getCodeName(@PathVariable("index") String index, ModelMap mmap) + { + mmap.put("index", index); + return prefix + "/doCodeNameTree"; + } + + /** + * 鍘傚晢姣旇浠蜂俊鎭 + * + * @return + */ + @GetMapping("/doCodeNameTreeData") + @ResponseBody + public List doCodeNameTreeData() + { + Object o = CacheUtils.get(Constants.SYS_SUPPLIER_CACHE, Constants.SYS_SUPPLIER_KEY); +// return JSONObject.parseArray((String) o, Ztree.class); + return StringUtils.cast(o); + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysCaptchaController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysCaptchaController.java new file mode 100644 index 000000000..739c46934 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysCaptchaController.java @@ -0,0 +1,92 @@ +package com.ruoyi.web.controller.system; + +import java.awt.image.BufferedImage; +import java.io.IOException; +import javax.annotation.Resource; +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.ModelAndView; +import com.google.code.kaptcha.Constants; +import com.google.code.kaptcha.Producer; +import com.ruoyi.common.core.controller.BaseController; + +/** + * 鍥剧墖楠岃瘉鐮侊紙鏀寔绠楁湳褰㈠紡锛 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/captcha") +public class SysCaptchaController extends BaseController +{ + @Resource(name = "captchaProducer") + private Producer captchaProducer; + + @Resource(name = "captchaProducerMath") + private Producer captchaProducerMath; + + /** + * 楠岃瘉鐮佺敓鎴 + */ + @GetMapping(value = "/captchaImage") + public ModelAndView getKaptchaImage(HttpServletRequest request, HttpServletResponse response) + { + ServletOutputStream out = null; + try + { + HttpSession session = request.getSession(); + response.setDateHeader("Expires", 0); + response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate"); + response.addHeader("Cache-Control", "post-check=0, pre-check=0"); + response.setHeader("Pragma", "no-cache"); + response.setContentType("image/jpeg"); + + String type = request.getParameter("type"); + String capStr = null; + String code = null; + BufferedImage bi = null; + if ("math".equals(type)) + { + String capText = captchaProducerMath.createText(); + capStr = capText.substring(0, capText.lastIndexOf("@")); + code = capText.substring(capText.lastIndexOf("@") + 1); + bi = captchaProducerMath.createImage(capStr); + } + else if ("char".equals(type)) + { + capStr = code = captchaProducer.createText(); + bi = captchaProducer.createImage(capStr); + } + session.setAttribute(Constants.KAPTCHA_SESSION_KEY, code); + out = response.getOutputStream(); + ImageIO.write(bi, "jpg", out); + out.flush(); + + } + catch (Exception e) + { + e.printStackTrace(); + } + finally + { + try + { + if (out != null) + { + out.close(); + } + } + catch (IOException e) + { + e.printStackTrace(); + } + } + return null; + } +} \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java new file mode 100644 index 000000000..03844de03 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java @@ -0,0 +1,158 @@ +package com.ruoyi.web.controller.system; + +import java.util.List; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.domain.SysConfig; +import com.ruoyi.system.service.ISysConfigService; + +/** + * 鍙傛暟閰嶇疆 淇℃伅鎿嶄綔澶勭悊 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/system/config") +public class SysConfigController extends BaseController +{ + private String prefix = "system/config"; + + @Autowired + private ISysConfigService configService; + + @RequiresPermissions("system:config:view") + @GetMapping() + public String config() + { + return prefix + "/config"; + } + + /** + * 鏌ヨ鍙傛暟閰嶇疆鍒楄〃 + */ + @RequiresPermissions("system:config:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(SysConfig config) + { + startPage(); + List list = configService.selectConfigList(config); + return getDataTable(list); + } + + @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:config:export") + @PostMapping("/export") + @ResponseBody + public AjaxResult export(SysConfig config) + { + List list = configService.selectConfigList(config); + ExcelUtil util = new ExcelUtil(SysConfig.class); + return util.exportExcel(list, "鍙傛暟鏁版嵁"); + } + + /** + * 鏂板鍙傛暟閰嶇疆 + */ + @GetMapping("/add") + public String add() + { + return prefix + "/add"; + } + + /** + * 鏂板淇濆瓨鍙傛暟閰嶇疆 + */ + @RequiresPermissions("system:config:add") + @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.INSERT) + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(@Validated SysConfig config) + { + if (UserConstants.CONFIG_KEY_NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) + { + return error("鏂板鍙傛暟'" + config.getConfigName() + "'澶辫触锛屽弬鏁伴敭鍚嶅凡瀛樺湪"); + } + config.setCreateBy(getLoginName()); + return toAjax(configService.insertConfig(config)); + } + + /** + * 淇敼鍙傛暟閰嶇疆 + */ + @RequiresPermissions("system:config:edit") + @GetMapping("/edit/{configId}") + public String edit(@PathVariable("configId") Long configId, ModelMap mmap) + { + mmap.put("config", configService.selectConfigById(configId)); + return prefix + "/edit"; + } + + /** + * 淇敼淇濆瓨鍙傛暟閰嶇疆 + */ + @RequiresPermissions("system:config:edit") + @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.UPDATE) + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(@Validated SysConfig config) + { + if (UserConstants.CONFIG_KEY_NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) + { + return error("淇敼鍙傛暟'" + config.getConfigName() + "'澶辫触锛屽弬鏁伴敭鍚嶅凡瀛樺湪"); + } + config.setUpdateBy(getLoginName()); + return toAjax(configService.updateConfig(config)); + } + + /** + * 鍒犻櫎鍙傛暟閰嶇疆 + */ + @RequiresPermissions("system:config:remove") + @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.DELETE) + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + configService.deleteConfigByIds(ids); + return success(); + } + + /** + * 鍒锋柊鍙傛暟缂撳瓨 + */ + @RequiresPermissions("system:config:remove") + @Log(title = "鍙傛暟绠$悊", businessType = BusinessType.CLEAN) + @GetMapping("/refreshCache") + @ResponseBody + public AjaxResult refreshCache() + { + configService.resetConfigCache(); + return success(); + } + + /** + * 鏍¢獙鍙傛暟閿悕 + */ + @PostMapping("/checkConfigKeyUnique") + @ResponseBody + public String checkConfigKeyUnique(SysConfig config) + { + return configService.checkConfigKeyUnique(config); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java new file mode 100644 index 000000000..d5fd3a827 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDeptController.java @@ -0,0 +1,187 @@ +package com.ruoyi.web.controller.system; + +import java.util.List; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.Ztree; +import com.ruoyi.common.core.domain.entity.SysDept; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.service.ISysDeptService; + +/** + * 閮ㄩ棬淇℃伅 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/system/dept") +public class SysDeptController extends BaseController +{ + private String prefix = "system/dept"; + + @Autowired + private ISysDeptService deptService; + + @RequiresPermissions("system:dept:view") + @GetMapping() + public String dept() + { + return prefix + "/dept"; + } + + @RequiresPermissions("system:dept:list") + @PostMapping("/list") + @ResponseBody + public List list(SysDept dept) + { + List deptList = deptService.selectDeptList(dept); + return deptList; + } + + /** + * 鏂板閮ㄩ棬 + */ + @GetMapping("/add/{parentId}") + public String add(@PathVariable("parentId") Long parentId, ModelMap mmap) + { + if (!getSysUser().isAdmin()) + { + parentId = getSysUser().getDeptId(); + } + mmap.put("dept", deptService.selectDeptById(parentId)); + return prefix + "/add"; + } + + /** + * 鏂板淇濆瓨閮ㄩ棬 + */ + @Log(title = "閮ㄩ棬绠$悊", businessType = BusinessType.INSERT) + @RequiresPermissions("system:dept:add") + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(@Validated SysDept dept) + { + if (UserConstants.DEPT_NAME_NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) + { + return error("鏂板閮ㄩ棬'" + dept.getDeptName() + "'澶辫触锛岄儴闂ㄥ悕绉板凡瀛樺湪"); + } + dept.setCreateBy(getLoginName()); + return toAjax(deptService.insertDept(dept)); + } + + /** + * 淇敼閮ㄩ棬 + */ + @RequiresPermissions("system:dept:edit") + @GetMapping("/edit/{deptId}") + public String edit(@PathVariable("deptId") Long deptId, ModelMap mmap) + { + deptService.checkDeptDataScope(deptId); + SysDept dept = deptService.selectDeptById(deptId); + if (StringUtils.isNotNull(dept) && 100L == deptId) + { + dept.setParentName("鏃"); + } + mmap.put("dept", dept); + return prefix + "/edit"; + } + + /** + * 淇敼淇濆瓨閮ㄩ棬 + */ + @Log(title = "閮ㄩ棬绠$悊", businessType = BusinessType.UPDATE) + @RequiresPermissions("system:dept:edit") + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(@Validated SysDept dept) + { + Long deptId = dept.getDeptId(); + deptService.checkDeptDataScope(deptId); + if (UserConstants.DEPT_NAME_NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) + { + return error("淇敼閮ㄩ棬'" + dept.getDeptName() + "'澶辫触锛岄儴闂ㄥ悕绉板凡瀛樺湪"); + } + else if (dept.getParentId().equals(deptId)) + { + return error("淇敼閮ㄩ棬'" + dept.getDeptName() + "'澶辫触锛屼笂绾ч儴闂ㄤ笉鑳芥槸鑷繁"); + } + else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0) + { + return AjaxResult.error("璇ラ儴闂ㄥ寘鍚湭鍋滅敤鐨勫瓙閮ㄩ棬锛"); + } + dept.setUpdateBy(getLoginName()); + return toAjax(deptService.updateDept(dept)); + } + + /** + * 鍒犻櫎 + */ + @Log(title = "閮ㄩ棬绠$悊", businessType = BusinessType.DELETE) + @RequiresPermissions("system:dept:remove") + @GetMapping("/remove/{deptId}") + @ResponseBody + public AjaxResult remove(@PathVariable("deptId") Long deptId) + { + if (deptService.selectDeptCount(deptId) > 0) + { + return AjaxResult.warn("瀛樺湪涓嬬骇閮ㄩ棬,涓嶅厑璁稿垹闄"); + } + if (deptService.checkDeptExistUser(deptId)) + { + return AjaxResult.warn("閮ㄩ棬瀛樺湪鐢ㄦ埛,涓嶅厑璁稿垹闄"); + } + deptService.checkDeptDataScope(deptId); + return toAjax(deptService.deleteDeptById(deptId)); + } + + /** + * 鏍¢獙閮ㄩ棬鍚嶇О + */ + @PostMapping("/checkDeptNameUnique") + @ResponseBody + public String checkDeptNameUnique(SysDept dept) + { + return deptService.checkDeptNameUnique(dept); + } + + /** + * 閫夋嫨閮ㄩ棬鏍 + * + * @param deptId 閮ㄩ棬ID + * @param excludeId 鎺掗櫎ID + */ + @GetMapping(value = { "/selectDeptTree/{deptId}", "/selectDeptTree/{deptId}/{excludeId}" }) + public String selectDeptTree(@PathVariable("deptId") Long deptId, + @PathVariable(value = "excludeId", required = false) Long excludeId, ModelMap mmap) + { + mmap.put("dept", deptService.selectDeptById(deptId)); + mmap.put("excludeId", excludeId); + return prefix + "/tree"; + } + + /** + * 鍔犺浇閮ㄩ棬鍒楄〃鏍戯紙鎺掗櫎涓嬬骇锛 + */ + @GetMapping("/treeData/{excludeId}") + @ResponseBody + public List treeDataExcludeChild(@PathVariable(value = "excludeId", required = false) Long excludeId) + { + SysDept dept = new SysDept(); + dept.setExcludeId(excludeId); + List ztrees = deptService.selectDeptTreeExcludeChild(dept); + return ztrees; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java new file mode 100644 index 000000000..610fd6b6b --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java @@ -0,0 +1,121 @@ +package com.ruoyi.web.controller.system; + +import java.util.List; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysDictData; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.service.ISysDictDataService; + +/** + * 鏁版嵁瀛楀吀淇℃伅 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/system/dict/data") +public class SysDictDataController extends BaseController +{ + private String prefix = "system/dict/data"; + + @Autowired + private ISysDictDataService dictDataService; + + @RequiresPermissions("system:dict:view") + @GetMapping() + public String dictData() + { + return prefix + "/data"; + } + + @PostMapping("/list") + @RequiresPermissions("system:dict:list") + @ResponseBody + public TableDataInfo list(SysDictData dictData) + { + startPage(); + List list = dictDataService.selectDictDataList(dictData); + return getDataTable(list); + } + + @Log(title = "瀛楀吀鏁版嵁", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:dict:export") + @PostMapping("/export") + @ResponseBody + public AjaxResult export(SysDictData dictData) + { + List list = dictDataService.selectDictDataList(dictData); + ExcelUtil util = new ExcelUtil(SysDictData.class); + return util.exportExcel(list, "瀛楀吀鏁版嵁"); + } + + /** + * 鏂板瀛楀吀绫诲瀷 + */ + @GetMapping("/add/{dictType}") + public String add(@PathVariable("dictType") String dictType, ModelMap mmap) + { + mmap.put("dictType", dictType); + return prefix + "/add"; + } + + /** + * 鏂板淇濆瓨瀛楀吀绫诲瀷 + */ + @Log(title = "瀛楀吀鏁版嵁", businessType = BusinessType.INSERT) + @RequiresPermissions("system:dict:add") + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(@Validated SysDictData dict) + { + dict.setCreateBy(getLoginName()); + return toAjax(dictDataService.insertDictData(dict)); + } + + /** + * 淇敼瀛楀吀绫诲瀷 + */ + @RequiresPermissions("system:dict:edit") + @GetMapping("/edit/{dictCode}") + public String edit(@PathVariable("dictCode") Long dictCode, ModelMap mmap) + { + mmap.put("dict", dictDataService.selectDictDataById(dictCode)); + return prefix + "/edit"; + } + + /** + * 淇敼淇濆瓨瀛楀吀绫诲瀷 + */ + @Log(title = "瀛楀吀鏁版嵁", businessType = BusinessType.UPDATE) + @RequiresPermissions("system:dict:edit") + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(@Validated SysDictData dict) + { + dict.setUpdateBy(getLoginName()); + return toAjax(dictDataService.updateDictData(dict)); + } + + @Log(title = "瀛楀吀鏁版嵁", businessType = BusinessType.DELETE) + @RequiresPermissions("system:dict:remove") + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + dictDataService.deleteDictDataByIds(ids); + return success(); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java new file mode 100644 index 000000000..93563e19a --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java @@ -0,0 +1,189 @@ +package com.ruoyi.web.controller.system; + +import java.util.List; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.Ztree; +import com.ruoyi.common.core.domain.entity.SysDictType; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.service.ISysDictTypeService; + +/** + * 鏁版嵁瀛楀吀淇℃伅 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/system/dict") +public class SysDictTypeController extends BaseController +{ + private String prefix = "system/dict/type"; + + @Autowired + private ISysDictTypeService dictTypeService; + + @RequiresPermissions("system:dict:view") + @GetMapping() + public String dictType() + { + return prefix + "/type"; + } + + @PostMapping("/list") + @RequiresPermissions("system:dict:list") + @ResponseBody + public TableDataInfo list(SysDictType dictType) + { + startPage(); + List list = dictTypeService.selectDictTypeList(dictType); + return getDataTable(list); + } + + @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:dict:export") + @PostMapping("/export") + @ResponseBody + public AjaxResult export(SysDictType dictType) + { + + List list = dictTypeService.selectDictTypeList(dictType); + ExcelUtil util = new ExcelUtil(SysDictType.class); + return util.exportExcel(list, "瀛楀吀绫诲瀷"); + } + + /** + * 鏂板瀛楀吀绫诲瀷 + */ + @GetMapping("/add") + public String add() + { + return prefix + "/add"; + } + + /** + * 鏂板淇濆瓨瀛楀吀绫诲瀷 + */ + @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.INSERT) + @RequiresPermissions("system:dict:add") + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(@Validated SysDictType dict) + { + if (UserConstants.DICT_TYPE_NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict))) + { + return error("鏂板瀛楀吀'" + dict.getDictName() + "'澶辫触锛屽瓧鍏哥被鍨嬪凡瀛樺湪"); + } + dict.setCreateBy(getLoginName()); + return toAjax(dictTypeService.insertDictType(dict)); + } + + /** + * 淇敼瀛楀吀绫诲瀷 + */ + @RequiresPermissions("system:dict:edit") + @GetMapping("/edit/{dictId}") + public String edit(@PathVariable("dictId") Long dictId, ModelMap mmap) + { + mmap.put("dict", dictTypeService.selectDictTypeById(dictId)); + return prefix + "/edit"; + } + + /** + * 淇敼淇濆瓨瀛楀吀绫诲瀷 + */ + @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.UPDATE) + @RequiresPermissions("system:dict:edit") + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(@Validated SysDictType dict) + { + if (UserConstants.DICT_TYPE_NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict))) + { + return error("淇敼瀛楀吀'" + dict.getDictName() + "'澶辫触锛屽瓧鍏哥被鍨嬪凡瀛樺湪"); + } + dict.setUpdateBy(getLoginName()); + return toAjax(dictTypeService.updateDictType(dict)); + } + + @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.DELETE) + @RequiresPermissions("system:dict:remove") + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + dictTypeService.deleteDictTypeByIds(ids); + return success(); + } + + /** + * 鍒锋柊瀛楀吀缂撳瓨 + */ + @RequiresPermissions("system:dict:remove") + @Log(title = "瀛楀吀绫诲瀷", businessType = BusinessType.CLEAN) + @GetMapping("/refreshCache") + @ResponseBody + public AjaxResult refreshCache() + { + dictTypeService.resetDictCache(); + return success(); + } + + /** + * 鏌ヨ瀛楀吀璇︾粏 + */ + @RequiresPermissions("system:dict:list") + @GetMapping("/detail/{dictId}") + public String detail(@PathVariable("dictId") Long dictId, ModelMap mmap) + { + mmap.put("dict", dictTypeService.selectDictTypeById(dictId)); + mmap.put("dictList", dictTypeService.selectDictTypeAll()); + return "system/dict/data/data"; + } + + /** + * 鏍¢獙瀛楀吀绫诲瀷 + */ + @PostMapping("/checkDictTypeUnique") + @ResponseBody + public String checkDictTypeUnique(SysDictType dictType) + { + return dictTypeService.checkDictTypeUnique(dictType); + } + + /** + * 閫夋嫨瀛楀吀鏍 + */ + @GetMapping("/selectDictTree/{columnId}/{dictType}") + public String selectDeptTree(@PathVariable("columnId") Long columnId, @PathVariable("dictType") String dictType, + ModelMap mmap) + { + mmap.put("columnId", columnId); + mmap.put("dict", dictTypeService.selectDictTypeByType(dictType)); + return prefix + "/tree"; + } + + /** + * 鍔犺浇瀛楀吀鍒楄〃鏍 + */ + @GetMapping("/treeData") + @ResponseBody + public List treeData() + { + List ztrees = dictTypeService.selectDictTree(new SysDictType()); + return ztrees; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysIndexController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysIndexController.java new file mode 100644 index 000000000..d582a246a --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysIndexController.java @@ -0,0 +1,283 @@ +package com.ruoyi.web.controller.system; + +import java.util.*; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; + +import com.ruoyi.common.enums.PetitionStatus; +import com.ruoyi.system.domain.paymentRequest.PaymentRequest; +import com.ruoyi.system.domain.petition.Petition; +import com.ruoyi.system.domain.requisition.Requisition; +import com.ruoyi.system.service.paymentRequest.IPaymentRequestService; +import com.ruoyi.system.service.petition.IPetitionService; +import com.ruoyi.system.service.requisition.IRequisitionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.constant.ShiroConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysMenu; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.utils.CookieUtils; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.shiro.service.SysPasswordService; +import com.ruoyi.system.service.ISysConfigService; +import com.ruoyi.system.service.ISysMenuService; + +/** + * 棣栭〉 涓氬姟澶勭悊 + * + * @author ruoyi + */ +@Controller +public class SysIndexController extends BaseController +{ + @Autowired + private ISysMenuService menuService; + + @Autowired + private ISysConfigService configService; + + @Autowired + private SysPasswordService passwordService; + + @Autowired + private IPaymentRequestService paymentRequestService; + + @Autowired + private IRequisitionService requisitionService; + + @Autowired + private IPetitionService petitionService; + + // 绯荤粺棣栭〉 + @GetMapping("/index") + public String index(ModelMap mmap) + { + // 鍙栬韩浠戒俊鎭 + SysUser user = getSysUser(); + // 鏍规嵁鐢ㄦ埛id鍙栧嚭鑿滃崟 + List menus = menuService.selectMenusByUser(user); + mmap.put("menus", menus); + mmap.put("user", user); + mmap.put("sideTheme", configService.selectConfigByKey("sys.index.sideTheme")); + mmap.put("skinName", configService.selectConfigByKey("sys.index.skinName")); + Boolean footer = Convert.toBool(configService.selectConfigByKey("sys.index.footer"), true); + Boolean tagsView = Convert.toBool(configService.selectConfigByKey("sys.index.tagsView"), true); + mmap.put("footer", footer); + mmap.put("tagsView", tagsView); + mmap.put("mainClass", contentMainClass(footer, tagsView)); + mmap.put("copyrightYear", RuoYiConfig.getCopyrightYear()); + mmap.put("demoEnabled", RuoYiConfig.isDemoEnabled()); + mmap.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate())); + mmap.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate())); + mmap.put("isMobile", ServletUtils.checkAgentIsMobile(ServletUtils.getRequest().getHeader("User-Agent"))); + + // 鑿滃崟瀵艰埅鏄剧ず椋庢牸 + String menuStyle = configService.selectConfigByKey("sys.index.menuStyle"); + // 绉诲姩绔紝榛樿浣垮乏渚у鑸彍鍗曪紝鍚﹀垯鍙栭粯璁ら厤缃 + String indexStyle = ServletUtils.checkAgentIsMobile(ServletUtils.getRequest().getHeader("User-Agent")) ? "index" : menuStyle; + + // 浼樺厛Cookie閰嶇疆瀵艰埅鑿滃崟 + Cookie[] cookies = ServletUtils.getRequest().getCookies(); + for (Cookie cookie : cookies) + { + if (StringUtils.isNotEmpty(cookie.getName()) && "nav-style".equalsIgnoreCase(cookie.getName())) + { + indexStyle = cookie.getValue(); + break; + } + } + String webIndex = "topnav".equalsIgnoreCase(indexStyle) ? "index-topnav" : "index"; + return webIndex; + } + + // 閿佸畾灞忓箷 + @GetMapping("/lockscreen") + public String lockscreen(ModelMap mmap) + { + mmap.put("user", getSysUser()); + ServletUtils.getSession().setAttribute(ShiroConstants.LOCK_SCREEN, true); + return "lock"; + } + + // 瑙i攣灞忓箷 + @PostMapping("/unlockscreen") + @ResponseBody + public AjaxResult unlockscreen(String password) + { + SysUser user = getSysUser(); + if (StringUtils.isNull(user)) + { + return AjaxResult.error("鏈嶅姟鍣ㄨ秴鏃讹紝璇烽噸鏂扮櫥褰"); + } + if (passwordService.matches(user, password)) + { + ServletUtils.getSession().removeAttribute(ShiroConstants.LOCK_SCREEN); + return AjaxResult.success(); + } + return AjaxResult.error("瀵嗙爜涓嶆纭紝璇烽噸鏂拌緭鍏ャ"); + } + + // 鍒囨崲涓婚 + @GetMapping("/system/switchSkin") + public String switchSkin() + { + return "skin"; + } + + // 鍒囨崲鑿滃崟 + @GetMapping("/system/menuStyle/{style}") + public void menuStyle(@PathVariable String style, HttpServletResponse response) + { + CookieUtils.setCookie(response, "nav-style", style); + } + + // 绯荤粺浠嬬粛 + @GetMapping("/system/main") + public String main(ModelMap mmap) + { + // 鍙栬韩浠戒俊鎭 + SysUser user = getSysUser(); + String userCode = user.getUserCode(); + if (Objects.equals(userCode, "S00001")){ + user.setUserName("闄堟"); + }else if (Objects.equals(userCode, "S00002")){ + user.setUserName("娓告"); + } + PaymentRequest paymentRequest = new PaymentRequest(); + Requisition requisition = new Requisition(); + Petition petition = new Petition(); +// Order order = new Order(); +// Mrpfrom mrpfrom = new Mrpfrom(); +// ItUserAuthorizationFrom itUserAuthorizationFrom = new ItUserAuthorizationFrom(); +// Function function = new Function(); +// TravelExpenseReimbursement travelExpenseReimbursement = new TravelExpenseReimbursement(); + //鑾峰彇璇锋鍗曟垜鐨勫緟鍔 + paymentRequest.setSendToCode(userCode); + List paymentRequestList = paymentRequestService.selectPaymentRequestList(paymentRequest); + //鑾峰彇璇疯喘鍗曟垜鐨勫緟鍔 + requisition.setSendToCode(userCode); + List requisitionList = requisitionService.selectRequisitionList(requisition); + //鑾峰彇鐢靛瓙绛惧憟鎴戠殑寰呭姙 + petition.setFormSta(PetitionStatus.TODO.value()); + petition.setFromSendto(userCode); + List petitionList = petitionService.selectPetitionList(petition); + //鑾峰彇鍑哄樊鎶ラ攢鍗曟垜鐨勫緟鍔 +// travelExpenseReimbursement.setSendToCode(userCode); +// List travelExpenseReimbursementList = travelExpenseReimbursementService.selectTravelExpenseReimbursementList(travelExpenseReimbursement); + //鑾峰彇鎴戠殑宸ュ崟 + /* List orderTypeIds = orderTypeService.selectOrderTypeIdsByEmail(user.getEmail()); + if(user.getDepartmentCode() != null && user.getDepartmentCode().contains("240")){ + //濡傛灉鏄痗ad閮ㄩ棬鐨勪汉锛岄偅涔堝氨鍙互鐪嬪埌鎵鏈夌殑cad鐨勫崟瀛 + OrderType orderType = new OrderType(); + orderType.setParentId(41L); + List orderTypes = orderTypeService.selectOrderTypeList(orderType); + List collect = orderTypes.stream().map(OrderType::getOrderTypeId).collect(Collectors.toList()); + orderTypeIds.addAll(collect); + List orderTypeIds1 = new ArrayList<>(); + for (Long l:orderTypeIds) { + if (!orderTypeIds1.contains(l)) { + orderTypeIds1.add(l); + } + } + orderTypeIds = orderTypeIds1; + } + order.setOrderStatus(0); + List orderList = orderService.selectOrderListByDefUser(user, order, orderTypeIds); + //杩囨护宸插叧闂殑鍗曞瓙 + long orderCount = orderList.stream().filter(o -> o.getOrderStatus() != -1).count(); + //鑾峰彇MRB琛ㄥ崟鎴戠殑寰呭姙 + List mrpfromList = mrpfromService.selectMyTodoMrpfrom(ShiroUtils.getSysUser().getUserName()); + Iterator iterator = mrpfromList.iterator(); + List idArr = new ArrayList<>(); + while (iterator.hasNext()) { + Long id = iterator.next().getId(); + idArr.add(id); + } + if (idArr.size() != 0) { + if (getSysUser().isAdmin()){ + mrpfromList = mrpfromService.selectMrpfromList(mrpfrom); + }else { + mrpfromList = mrpfromService.selectMyTodoMrpfromByIds(idArr); + } + } else { + startPage(); + List list = new ArrayList<>(); + list.add(Long.MAX_VALUE); + if (getSysUser().isAdmin()) { + mrpfromList = mrpfromService.selectMrpfromList(mrpfrom); + } else { + mrpfromList = mrpfromService.selectMyTodoMrpfromByIds(list); + } + } + //鑾峰彇鐢ㄦ埛璐﹀彿鏉冮檺鐢宠鍗曟垜鐨勫緟鍔 + itUserAuthorizationFrom.setSendToCode(userCode); + List itUserAuthorizationFromList = iItUserAuthorizationFromService.selectItUserAuthorizationFromList(itUserAuthorizationFrom); + //鑾峰彇绯荤粺鍔熻兘闇姹傚崟鎴戠殑寰呭姙 + function.setSendToCode(userCode); + List functionList = functionService.selectFunctionList(function);*/ + mmap.put("user", user); + mmap.put("version", RuoYiConfig.getVersion()); + mmap.put("paymentRequest", paymentRequestList.size()); + mmap.put("requisition", requisitionList.size()); + mmap.put("petition", petitionList.size()); + /*mmap.put("travelExpenseReimbursement", travelExpenseReimbursementList.size()); + mmap.put("order", orderCount); + mmap.put("mrpfrom", mrpfromList.size()); + mmap.put("itUserAuthorizationFrom", itUserAuthorizationFromList.size()); + mmap.put("function", functionList.size());*/ + return "main"; + } + + // content-main class + public String contentMainClass(Boolean footer, Boolean tagsView) + { + if (!footer && !tagsView) + { + return "tagsview-footer-hide"; + } + else if (!footer) + { + return "footer-hide"; + } + else if (!tagsView) + { + return "tagsview-hide"; + } + return StringUtils.EMPTY; + } + + // 妫鏌ュ垵濮嬪瘑鐮佹槸鍚︽彁閱掍慨鏀 + public boolean initPasswordIsModify(Date pwdUpdateDate) + { + Integer initPasswordModify = Convert.toInt(configService.selectConfigByKey("sys.account.initPasswordModify")); + return initPasswordModify != null && initPasswordModify == 1 && pwdUpdateDate == null; + } + + // 妫鏌ュ瘑鐮佹槸鍚﹁繃鏈 + public boolean passwordIsExpiration(Date pwdUpdateDate) + { + Integer passwordValidateDays = Convert.toInt(configService.selectConfigByKey("sys.account.passwordValidateDays")); + if (passwordValidateDays != null && passwordValidateDays > 0) + { + if (StringUtils.isNull(pwdUpdateDate)) + { + // 濡傛灉浠庢湭淇敼杩囧垵濮嬪瘑鐮侊紝鐩存帴鎻愰啋杩囨湡 + return true; + } + Date nowDate = DateUtils.getNowDate(); + return DateUtils.differentDaysByMillisecond(nowDate, pwdUpdateDate) > passwordValidateDays; + } + return false; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java new file mode 100644 index 000000000..d6b53a023 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java @@ -0,0 +1,176 @@ +package com.ruoyi.web.controller.system; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.enums.UserStatus; +import com.ruoyi.common.utils.ShiroUtils; +import com.ruoyi.framework.jwt.utils.JwtUtils; +import com.ruoyi.framework.shiro.service.SysPasswordService; +import com.ruoyi.system.service.ISysUserService; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.UsernamePasswordToken; +import org.apache.shiro.subject.Subject; +import org.apache.shiro.web.util.SavedRequest; +import org.apache.shiro.web.util.WebUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.*; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.web.service.ConfigService; + +/** + * 鐧诲綍楠岃瘉 + * + * @author ruoyi + */ +@Controller +public class SysLoginController extends BaseController +{ + /** + * 鏄惁寮鍚浣忔垜鍔熻兘 + */ + @Value("${shiro.rememberMe.enabled: false}") + private boolean rememberMe; + + @Autowired + private ISysUserService userService; + + @Autowired + private SysPasswordService passwordService; + + @Autowired + private ConfigService configService; + + @GetMapping("/login") + public String login(HttpServletRequest request, HttpServletResponse response, ModelMap mmap) + { + // 濡傛灉鏄疉jax璇锋眰锛岃繑鍥濲son瀛楃涓层 + if (ServletUtils.isAjaxRequest(request)) + { + return ServletUtils.renderString(response, "{\"code\":\"1\",\"msg\":\"鏈櫥褰曟垨鐧诲綍瓒呮椂銆傝閲嶆柊鐧诲綍\"}"); + } + // 鏄惁寮鍚浣忔垜 + mmap.put("isRemembered", rememberMe); + // 鏄惁寮鍚敤鎴锋敞鍐 + mmap.put("isAllowRegister", Convert.toBool(configService.getKey("sys.account.registerUser"), false)); + return "login"; + } + + @PostMapping("/login") + @ResponseBody + public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe) + { + UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe); + Subject subject = SecurityUtils.getSubject(); + try + { + SavedRequest savedRequest = (SavedRequest) ShiroUtils.getSession().getAttribute(WebUtils.SAVED_REQUEST_KEY); + subject.login(token); + String url = ""; + if (savedRequest != null && savedRequest.getRequestUrl() != null) { + if (savedRequest.getRequestUrl().contains("/redirect")) { + url = savedRequest.getRequestUrl().replace("/redirect", ""); + } + } + return success(url); + } + catch (AuthenticationException e) + { + String msg = "鐢ㄦ埛鎴栧瘑鐮侀敊璇"; + if (StringUtils.isNotEmpty(e.getMessage())) + { + msg = e.getMessage(); + } + return error(msg); + } + } + + @PostMapping("/jwt/login") + @ResponseBody + public AjaxResult jwtLogin(String username, String password) + { + if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) + { + return AjaxResult.error("璐﹀彿鍜屽瘑鐮佷笉鑳戒负绌!"); + } + + SysUser user = userService.selectUserByLoginName(username); + if (user == null) + { + return AjaxResult.error("鐢ㄦ埛涓嶅瓨鍦/瀵嗙爜閿欒!"); + } + + if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) + { + return AjaxResult.error("瀵逛笉璧凤紝鎮ㄧ殑璐﹀彿宸茶鍒犻櫎!"); + } + + if (UserStatus.DISABLE.getCode().equals(user.getStatus())) + { + return AjaxResult.error("鐢ㄦ埛宸插皝绂侊紝璇疯仈绯荤鐞嗗憳!"); + } + + if (!passwordService.matches(user, password)) + { + return AjaxResult.error("鐢ㄦ埛涓嶅瓨鍦/瀵嗙爜閿欒!"); + } + + String token = JwtUtils.createToken(username, user.getPassword()); + return AjaxResult.success("鐧诲綍鎴愬姛,璇峰Ε鍠勪繚绠℃偍鐨則oken淇℃伅").put("token", token); + } + + @GetMapping("/unauth") + public String unauth() + { + return "error/unauth"; + } + + /*@RequestMapping("api/get/jsessionid") + @ResponseBody + public AjaxResult getSessionId(@CookieValue("JSESSIONID") String sessionID) + { + System.out.println(sessionID); + return AjaxResult.success(sessionID); + } + + @RequestMapping("api/auto/login") + @ResponseBody + public AjaxResult autoLogin(@CookieValue("JSESSIONID") String sessionID) + { + String url = "http://192.168.5.8:8901/index.php?m=apiapp&f=scanLoginCheck"; + String param = "type=WO&seid=" + sessionID; + String httpRes = HttpUtils.sendPost(url, param).replaceAll("&",""); + Result result = JSONObject.parseObject(httpRes, Result.class); + if(result.getCode().equals(0)){ + String email = result.getData().getEmail(); + User user = iUserService.selectUserByEmail(email); + UserToken token = new UserToken(user.getLoginName(), LoginType.NOPASSWD); + Subject subject = SecurityUtils.getSubject(); + try + { + subject.login(token); + return success("鎵爜鎴愬姛"); + } + catch (AuthenticationException e) + { + String msg = "鎵爜鐧诲綍澶辫触"; + if (StringUtils.isNotEmpty(e.getMessage())) + { + msg = e.getMessage(); + } + return error(msg); + } + }else { + return error("鎵爜鐧诲綍澶辫触"); + } + }*/ +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java new file mode 100644 index 000000000..b019ce713 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java @@ -0,0 +1,198 @@ +package com.ruoyi.web.controller.system; + +import java.util.List; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.Ztree; +import com.ruoyi.common.core.domain.entity.SysMenu; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.ShiroUtils; +import com.ruoyi.framework.shiro.util.AuthorizationUtils; +import com.ruoyi.system.service.ISysMenuService; + +/** + * 鑿滃崟淇℃伅 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/system/menu") +public class SysMenuController extends BaseController +{ + private String prefix = "system/menu"; + + @Autowired + private ISysMenuService menuService; + + @RequiresPermissions("system:menu:view") + @GetMapping() + public String menu() + { + return prefix + "/menu"; + } + + @RequiresPermissions("system:menu:list") + @PostMapping("/list") + @ResponseBody + public List list(SysMenu menu) + { + Long userId = ShiroUtils.getUserId(); + List menuList = menuService.selectMenuList(menu, userId); + return menuList; + } + + /** + * 鍒犻櫎鑿滃崟 + */ + @Log(title = "鑿滃崟绠$悊", businessType = BusinessType.DELETE) + @RequiresPermissions("system:menu:remove") + @GetMapping("/remove/{menuId}") + @ResponseBody + public AjaxResult remove(@PathVariable("menuId") Long menuId) + { + if (menuService.selectCountMenuByParentId(menuId) > 0) + { + return AjaxResult.warn("瀛樺湪瀛愯彍鍗,涓嶅厑璁稿垹闄"); + } + if (menuService.selectCountRoleMenuByMenuId(menuId) > 0) + { + return AjaxResult.warn("鑿滃崟宸插垎閰,涓嶅厑璁稿垹闄"); + } + AuthorizationUtils.clearAllCachedAuthorizationInfo(); + return toAjax(menuService.deleteMenuById(menuId)); + } + + /** + * 鏂板 + */ + @GetMapping("/add/{parentId}") + public String add(@PathVariable("parentId") Long parentId, ModelMap mmap) + { + SysMenu menu = null; + if (0L != parentId) + { + menu = menuService.selectMenuById(parentId); + } + else + { + menu = new SysMenu(); + menu.setMenuId(0L); + menu.setMenuName("涓荤洰褰"); + } + mmap.put("menu", menu); + return prefix + "/add"; + } + + /** + * 鏂板淇濆瓨鑿滃崟 + */ + @Log(title = "鑿滃崟绠$悊", businessType = BusinessType.INSERT) + @RequiresPermissions("system:menu:add") + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(@Validated SysMenu menu) + { + if (UserConstants.MENU_NAME_NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu))) + { + return error("鏂板鑿滃崟'" + menu.getMenuName() + "'澶辫触锛岃彍鍗曞悕绉板凡瀛樺湪"); + } + menu.setCreateBy(getLoginName()); + AuthorizationUtils.clearAllCachedAuthorizationInfo(); + return toAjax(menuService.insertMenu(menu)); + } + + /** + * 淇敼鑿滃崟 + */ + @RequiresPermissions("system:menu:edit") + @GetMapping("/edit/{menuId}") + public String edit(@PathVariable("menuId") Long menuId, ModelMap mmap) + { + mmap.put("menu", menuService.selectMenuById(menuId)); + return prefix + "/edit"; + } + + /** + * 淇敼淇濆瓨鑿滃崟 + */ + @Log(title = "鑿滃崟绠$悊", businessType = BusinessType.UPDATE) + @RequiresPermissions("system:menu:edit") + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(@Validated SysMenu menu) + { + if (UserConstants.MENU_NAME_NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu))) + { + return error("淇敼鑿滃崟'" + menu.getMenuName() + "'澶辫触锛岃彍鍗曞悕绉板凡瀛樺湪"); + } + menu.setUpdateBy(getLoginName()); + AuthorizationUtils.clearAllCachedAuthorizationInfo(); + return toAjax(menuService.updateMenu(menu)); + } + + /** + * 閫夋嫨鑿滃崟鍥炬爣 + */ + @GetMapping("/icon") + public String icon() + { + return prefix + "/icon"; + } + + /** + * 鏍¢獙鑿滃崟鍚嶇О + */ + @PostMapping("/checkMenuNameUnique") + @ResponseBody + public String checkMenuNameUnique(SysMenu menu) + { + return menuService.checkMenuNameUnique(menu); + } + + /** + * 鍔犺浇瑙掕壊鑿滃崟鍒楄〃鏍 + */ + @GetMapping("/roleMenuTreeData") + @ResponseBody + public List roleMenuTreeData(SysRole role) + { + Long userId = ShiroUtils.getUserId(); + List ztrees = menuService.roleMenuTreeData(role, userId); + return ztrees; + } + + /** + * 鍔犺浇鎵鏈夎彍鍗曞垪琛ㄦ爲 + */ + @GetMapping("/menuTreeData") + @ResponseBody + public List menuTreeData() + { + Long userId = ShiroUtils.getUserId(); + List ztrees = menuService.menuTreeData(userId); + return ztrees; + } + + /** + * 閫夋嫨鑿滃崟鏍 + */ + @GetMapping("/selectMenuTree/{menuId}") + public String selectMenuTree(@PathVariable("menuId") Long menuId, ModelMap mmap) + { + mmap.put("menu", menuService.selectMenuById(menuId)); + return prefix + "/tree"; + } +} \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java new file mode 100644 index 000000000..93e1be902 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysNoticeController.java @@ -0,0 +1,113 @@ +package com.ruoyi.web.controller.system; + +import java.util.List; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.system.domain.SysNotice; +import com.ruoyi.system.service.ISysNoticeService; + +/** + * 鍏憡 淇℃伅鎿嶄綔澶勭悊 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/system/notice") +public class SysNoticeController extends BaseController +{ + private String prefix = "system/notice"; + + @Autowired + private ISysNoticeService noticeService; + + @RequiresPermissions("system:notice:view") + @GetMapping() + public String notice() + { + return prefix + "/notice"; + } + + /** + * 鏌ヨ鍏憡鍒楄〃 + */ + @RequiresPermissions("system:notice:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(SysNotice notice) + { + startPage(); + List list = noticeService.selectNoticeList(notice); + return getDataTable(list); + } + + /** + * 鏂板鍏憡 + */ + @GetMapping("/add") + public String add() + { + return prefix + "/add"; + } + + /** + * 鏂板淇濆瓨鍏憡 + */ + @RequiresPermissions("system:notice:add") + @Log(title = "閫氱煡鍏憡", businessType = BusinessType.INSERT) + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(@Validated SysNotice notice) + { + notice.setCreateBy(getLoginName()); + return toAjax(noticeService.insertNotice(notice)); + } + + /** + * 淇敼鍏憡 + */ + @RequiresPermissions("system:notice:edit") + @GetMapping("/edit/{noticeId}") + public String edit(@PathVariable("noticeId") Long noticeId, ModelMap mmap) + { + mmap.put("notice", noticeService.selectNoticeById(noticeId)); + return prefix + "/edit"; + } + + /** + * 淇敼淇濆瓨鍏憡 + */ + @RequiresPermissions("system:notice:edit") + @Log(title = "閫氱煡鍏憡", businessType = BusinessType.UPDATE) + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(@Validated SysNotice notice) + { + notice.setUpdateBy(getLoginName()); + return toAjax(noticeService.updateNotice(notice)); + } + + /** + * 鍒犻櫎鍏憡 + */ + @RequiresPermissions("system:notice:remove") + @Log(title = "閫氱煡鍏憡", businessType = BusinessType.DELETE) + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + return toAjax(noticeService.deleteNoticeByIds(ids)); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java new file mode 100644 index 000000000..2937300b9 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysPostController.java @@ -0,0 +1,163 @@ +package com.ruoyi.web.controller.system; + +import java.util.List; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.domain.SysPost; +import com.ruoyi.system.service.ISysPostService; + +/** + * 宀椾綅淇℃伅鎿嶄綔澶勭悊 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/system/post") +public class SysPostController extends BaseController +{ + private String prefix = "system/post"; + + @Autowired + private ISysPostService postService; + + @RequiresPermissions("system:post:view") + @GetMapping() + public String operlog() + { + return prefix + "/post"; + } + + @RequiresPermissions("system:post:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(SysPost post) + { + startPage(); + List list = postService.selectPostList(post); + return getDataTable(list); + } + + @Log(title = "宀椾綅绠$悊", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:post:export") + @PostMapping("/export") + @ResponseBody + public AjaxResult export(SysPost post) + { + List list = postService.selectPostList(post); + ExcelUtil util = new ExcelUtil(SysPost.class); + return util.exportExcel(list, "宀椾綅鏁版嵁"); + } + + @RequiresPermissions("system:post:remove") + @Log(title = "宀椾綅绠$悊", businessType = BusinessType.DELETE) + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + try + { + return toAjax(postService.deletePostByIds(ids)); + } + catch (Exception e) + { + return error(e.getMessage()); + } + } + + /** + * 鏂板宀椾綅 + */ + @GetMapping("/add") + public String add() + { + return prefix + "/add"; + } + + /** + * 鏂板淇濆瓨宀椾綅 + */ + @RequiresPermissions("system:post:add") + @Log(title = "宀椾綅绠$悊", businessType = BusinessType.INSERT) + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(@Validated SysPost post) + { + if (UserConstants.POST_NAME_NOT_UNIQUE.equals(postService.checkPostNameUnique(post))) + { + return error("鏂板宀椾綅'" + post.getPostName() + "'澶辫触锛屽矖浣嶅悕绉板凡瀛樺湪"); + } + else if (UserConstants.POST_CODE_NOT_UNIQUE.equals(postService.checkPostCodeUnique(post))) + { + return error("鏂板宀椾綅'" + post.getPostName() + "'澶辫触锛屽矖浣嶇紪鐮佸凡瀛樺湪"); + } + post.setCreateBy(getLoginName()); + return toAjax(postService.insertPost(post)); + } + + /** + * 淇敼宀椾綅 + */ + @RequiresPermissions("system:post:edit") + @GetMapping("/edit/{postId}") + public String edit(@PathVariable("postId") Long postId, ModelMap mmap) + { + mmap.put("post", postService.selectPostById(postId)); + return prefix + "/edit"; + } + + /** + * 淇敼淇濆瓨宀椾綅 + */ + @RequiresPermissions("system:post:edit") + @Log(title = "宀椾綅绠$悊", businessType = BusinessType.UPDATE) + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(@Validated SysPost post) + { + if (UserConstants.POST_NAME_NOT_UNIQUE.equals(postService.checkPostNameUnique(post))) + { + return error("淇敼宀椾綅'" + post.getPostName() + "'澶辫触锛屽矖浣嶅悕绉板凡瀛樺湪"); + } + else if (UserConstants.POST_CODE_NOT_UNIQUE.equals(postService.checkPostCodeUnique(post))) + { + return error("淇敼宀椾綅'" + post.getPostName() + "'澶辫触锛屽矖浣嶇紪鐮佸凡瀛樺湪"); + } + post.setUpdateBy(getLoginName()); + return toAjax(postService.updatePost(post)); + } + + /** + * 鏍¢獙宀椾綅鍚嶇О + */ + @PostMapping("/checkPostNameUnique") + @ResponseBody + public String checkPostNameUnique(SysPost post) + { + return postService.checkPostNameUnique(post); + } + + /** + * 鏍¢獙宀椾綅缂栫爜 + */ + @PostMapping("/checkPostCodeUnique") + @ResponseBody + public String checkPostCodeUnique(SysPost post) + { + return postService.checkPostCodeUnique(post); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java new file mode 100644 index 000000000..1feadef2f --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java @@ -0,0 +1,188 @@ +package com.ruoyi.web.controller.system; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.ShiroUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.file.FileUploadUtils; +import com.ruoyi.common.utils.file.MimeTypeUtils; +import com.ruoyi.framework.shiro.service.SysPasswordService; +import com.ruoyi.system.service.ISysUserService; + +/** + * 涓汉淇℃伅 涓氬姟澶勭悊 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/system/user/profile") +public class SysProfileController extends BaseController +{ + private static final Logger log = LoggerFactory.getLogger(SysProfileController.class); + + private String prefix = "system/user/profile"; + + @Autowired + private ISysUserService userService; + + @Autowired + private SysPasswordService passwordService; + + /** + * 涓汉淇℃伅 + */ + @GetMapping() + public String profile(ModelMap mmap) + { + SysUser user = getSysUser(); + mmap.put("user", user); + mmap.put("roleGroup", userService.selectUserRoleGroup(user.getUserId())); + mmap.put("postGroup", userService.selectUserPostGroup(user.getUserId())); + return prefix + "/profile"; + } + + @GetMapping("/checkPassword") + @ResponseBody + public boolean checkPassword(String password) + { + SysUser user = getSysUser(); + if (passwordService.matches(user, password)) + { + return true; + } + return false; + } + + @GetMapping("/resetPwd") + public String resetPwd(ModelMap mmap) + { + SysUser user = getSysUser(); + mmap.put("user", userService.selectUserById(user.getUserId())); + return prefix + "/resetPwd"; + } + + @Log(title = "閲嶇疆瀵嗙爜", businessType = BusinessType.UPDATE) + @PostMapping("/resetPwd") + @ResponseBody + public AjaxResult resetPwd(String oldPassword, String newPassword) + { + SysUser user = getSysUser(); + if (!passwordService.matches(user, oldPassword)) + { + return error("淇敼瀵嗙爜澶辫触锛屾棫瀵嗙爜閿欒"); + } + if (passwordService.matches(user, newPassword)) + { + return error("鏂板瘑鐮佷笉鑳戒笌鏃у瘑鐮佺浉鍚"); + } + user.setSalt(ShiroUtils.randomSalt()); + user.setPassword(passwordService.encryptPassword(user.getLoginName(), newPassword, user.getSalt())); + user.setPwdUpdateDate(DateUtils.getNowDate()); + if (userService.resetUserPwd(user) > 0) + { + setSysUser(userService.selectUserById(user.getUserId())); + return success(); + } + return error("淇敼瀵嗙爜寮傚父锛岃鑱旂郴绠$悊鍛"); + } + + /** + * 淇敼鐢ㄦ埛 + */ + @GetMapping("/edit") + public String edit(ModelMap mmap) + { + SysUser user = getSysUser(); + mmap.put("user", userService.selectUserById(user.getUserId())); + return prefix + "/edit"; + } + + /** + * 淇敼澶村儚 + */ + @GetMapping("/avatar") + public String avatar(ModelMap mmap) + { + SysUser user = getSysUser(); + mmap.put("user", userService.selectUserById(user.getUserId())); + return prefix + "/avatar"; + } + + /** + * 淇敼鐢ㄦ埛 + */ + @Log(title = "涓汉淇℃伅", businessType = BusinessType.UPDATE) + @PostMapping("/update") + @ResponseBody + public AjaxResult update(SysUser user) + { + SysUser currentUser = getSysUser(); + currentUser.setUserName(user.getUserName()); + currentUser.setEmail(user.getEmail()); + currentUser.setPhonenumber(user.getPhonenumber()); + currentUser.setSex(user.getSex()); + if (StringUtils.isNotEmpty(user.getPhonenumber()) + && UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(currentUser))) + { + return error("淇敼鐢ㄦ埛'" + currentUser.getLoginName() + "'澶辫触锛屾墜鏈哄彿鐮佸凡瀛樺湪"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) + && UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(currentUser))) + { + return error("淇敼鐢ㄦ埛'" + currentUser.getLoginName() + "'澶辫触锛岄偖绠辫处鍙峰凡瀛樺湪"); + } + if (userService.updateUserInfo(currentUser) > 0) + { + setSysUser(userService.selectUserById(currentUser.getUserId())); + return success(); + } + return error(); + } + + /** + * 淇濆瓨澶村儚 + */ + @Log(title = "涓汉淇℃伅", businessType = BusinessType.UPDATE) + @PostMapping("/updateAvatar") + @ResponseBody + public AjaxResult updateAvatar(@RequestParam("avatarfile") MultipartFile file) + { + SysUser currentUser = getSysUser(); + try + { + if (!file.isEmpty()) + { + String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION); + currentUser.setAvatar(avatar); + if (userService.updateUserInfo(currentUser) > 0) + { + setSysUser(userService.selectUserById(currentUser.getUserId())); + return success(); + } + } + return error(); + } + catch (Exception e) + { + log.error("淇敼澶村儚澶辫触锛", e); + return error(e.getMessage()); + } + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java new file mode 100644 index 000000000..e8dc001ab --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java @@ -0,0 +1,46 @@ +package com.ruoyi.web.controller.system; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.framework.shiro.service.SysRegisterService; +import com.ruoyi.system.service.ISysConfigService; + +/** + * 娉ㄥ唽楠岃瘉 + * + * @author ruoyi + */ +@Controller +public class SysRegisterController extends BaseController +{ + @Autowired + private SysRegisterService registerService; + + @Autowired + private ISysConfigService configService; + + @GetMapping("/register") + public String register() + { + return "register"; + } + + @PostMapping("/register") + @ResponseBody + public AjaxResult ajaxRegister(SysUser user) + { + if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) + { + return error("褰撳墠绯荤粺娌℃湁寮鍚敞鍐屽姛鑳斤紒"); + } + String msg = registerService.register(user); + return StringUtils.isEmpty(msg) ? success() : error(msg); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java new file mode 100644 index 000000000..a3e0033f4 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRoleController.java @@ -0,0 +1,323 @@ +package com.ruoyi.web.controller.system; + +import java.util.List; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.Ztree; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.framework.shiro.util.AuthorizationUtils; +import com.ruoyi.system.domain.SysUserRole; +import com.ruoyi.system.service.ISysDeptService; +import com.ruoyi.system.service.ISysRoleService; +import com.ruoyi.system.service.ISysUserService; + +/** + * 瑙掕壊淇℃伅 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/system/role") +public class SysRoleController extends BaseController +{ + private String prefix = "system/role"; + + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysUserService userService; + + @Autowired + private ISysDeptService deptService; + + @RequiresPermissions("system:role:view") + @GetMapping() + public String role() + { + return prefix + "/role"; + } + + @RequiresPermissions("system:role:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(SysRole role) + { + startPage(); + List list = roleService.selectRoleList(role); + return getDataTable(list); + } + + @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:role:export") + @PostMapping("/export") + @ResponseBody + public AjaxResult export(SysRole role) + { + List list = roleService.selectRoleList(role); + ExcelUtil util = new ExcelUtil(SysRole.class); + return util.exportExcel(list, "瑙掕壊鏁版嵁"); + } + + /** + * 鏂板瑙掕壊 + */ + @GetMapping("/add") + public String add() + { + return prefix + "/add"; + } + + /** + * 鏂板淇濆瓨瑙掕壊 + */ + @RequiresPermissions("system:role:add") + @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.INSERT) + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(@Validated SysRole role) + { + if (UserConstants.ROLE_NAME_NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) + { + return error("鏂板瑙掕壊'" + role.getRoleName() + "'澶辫触锛岃鑹插悕绉板凡瀛樺湪"); + } + else if (UserConstants.ROLE_KEY_NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role))) + { + return error("鏂板瑙掕壊'" + role.getRoleName() + "'澶辫触锛岃鑹叉潈闄愬凡瀛樺湪"); + } + role.setCreateBy(getLoginName()); + AuthorizationUtils.clearAllCachedAuthorizationInfo(); + return toAjax(roleService.insertRole(role)); + + } + + /** + * 淇敼瑙掕壊 + */ + @RequiresPermissions("system:role:edit") + @GetMapping("/edit/{roleId}") + public String edit(@PathVariable("roleId") Long roleId, ModelMap mmap) + { + roleService.checkRoleDataScope(roleId); + mmap.put("role", roleService.selectRoleById(roleId)); + return prefix + "/edit"; + } + + /** + * 淇敼淇濆瓨瑙掕壊 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.UPDATE) + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(@Validated SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + if (UserConstants.ROLE_NAME_NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) + { + return error("淇敼瑙掕壊'" + role.getRoleName() + "'澶辫触锛岃鑹插悕绉板凡瀛樺湪"); + } + else if (UserConstants.ROLE_KEY_NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role))) + { + return error("淇敼瑙掕壊'" + role.getRoleName() + "'澶辫触锛岃鑹叉潈闄愬凡瀛樺湪"); + } + role.setUpdateBy(getLoginName()); + AuthorizationUtils.clearAllCachedAuthorizationInfo(); + return toAjax(roleService.updateRole(role)); + } + + /** + * 瑙掕壊鍒嗛厤鏁版嵁鏉冮檺 + */ + @GetMapping("/authDataScope/{roleId}") + public String authDataScope(@PathVariable("roleId") Long roleId, ModelMap mmap) + { + mmap.put("role", roleService.selectRoleById(roleId)); + return prefix + "/dataScope"; + } + + /** + * 淇濆瓨瑙掕壊鍒嗛厤鏁版嵁鏉冮檺 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.UPDATE) + @PostMapping("/authDataScope") + @ResponseBody + public AjaxResult authDataScopeSave(SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + role.setUpdateBy(getLoginName()); + if (roleService.authDataScope(role) > 0) + { + setSysUser(userService.selectUserById(getUserId())); + return success(); + } + return error(); + } + + @RequiresPermissions("system:role:remove") + @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.DELETE) + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + return toAjax(roleService.deleteRoleByIds(ids)); + } + + /** + * 鏍¢獙瑙掕壊鍚嶇О + */ + @PostMapping("/checkRoleNameUnique") + @ResponseBody + public String checkRoleNameUnique(SysRole role) + { + return roleService.checkRoleNameUnique(role); + } + + /** + * 鏍¢獙瑙掕壊鏉冮檺 + */ + @PostMapping("/checkRoleKeyUnique") + @ResponseBody + public String checkRoleKeyUnique(SysRole role) + { + return roleService.checkRoleKeyUnique(role); + } + + /** + * 閫夋嫨鑿滃崟鏍 + */ + @GetMapping("/selectMenuTree") + public String selectMenuTree() + { + return prefix + "/tree"; + } + + /** + * 瑙掕壊鐘舵佷慨鏀 + */ + @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.UPDATE) + @RequiresPermissions("system:role:edit") + @PostMapping("/changeStatus") + @ResponseBody + public AjaxResult changeStatus(SysRole role) + { + roleService.checkRoleAllowed(role); + roleService.checkRoleDataScope(role.getRoleId()); + return toAjax(roleService.changeStatus(role)); + } + + /** + * 鍒嗛厤鐢ㄦ埛 + */ + @RequiresPermissions("system:role:edit") + @GetMapping("/authUser/{roleId}") + public String authUser(@PathVariable("roleId") Long roleId, ModelMap mmap) + { + mmap.put("role", roleService.selectRoleById(roleId)); + return prefix + "/authUser"; + } + + /** + * 鏌ヨ宸插垎閰嶇敤鎴疯鑹插垪琛 + */ + @RequiresPermissions("system:role:list") + @PostMapping("/authUser/allocatedList") + @ResponseBody + public TableDataInfo allocatedList(SysUser user) + { + startPage(); + List list = userService.selectAllocatedList(user); + return getDataTable(list); + } + + /** + * 鍙栨秷鎺堟潈 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.GRANT) + @PostMapping("/authUser/cancel") + @ResponseBody + public AjaxResult cancelAuthUser(SysUserRole userRole) + { + return toAjax(roleService.deleteAuthUser(userRole)); + } + + /** + * 鎵归噺鍙栨秷鎺堟潈 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.GRANT) + @PostMapping("/authUser/cancelAll") + @ResponseBody + public AjaxResult cancelAuthUserAll(Long roleId, String userIds) + { + return toAjax(roleService.deleteAuthUsers(roleId, userIds)); + } + + /** + * 閫夋嫨鐢ㄦ埛 + */ + @GetMapping("/authUser/selectUser/{roleId}") + public String selectUser(@PathVariable("roleId") Long roleId, ModelMap mmap) + { + mmap.put("role", roleService.selectRoleById(roleId)); + return prefix + "/selectUser"; + } + + /** + * 鏌ヨ鏈垎閰嶇敤鎴疯鑹插垪琛 + */ + @RequiresPermissions("system:role:list") + @PostMapping("/authUser/unallocatedList") + @ResponseBody + public TableDataInfo unallocatedList(SysUser user) + { + startPage(); + List list = userService.selectUnallocatedList(user); + return getDataTable(list); + } + + /** + * 鎵归噺閫夋嫨鐢ㄦ埛鎺堟潈 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "瑙掕壊绠$悊", businessType = BusinessType.GRANT) + @PostMapping("/authUser/selectAll") + @ResponseBody + public AjaxResult selectAuthUserAll(Long roleId, String userIds) + { + roleService.checkRoleDataScope(roleId); + return toAjax(roleService.insertAuthUsers(roleId, userIds)); + } + + /** + * 鍔犺浇瑙掕壊閮ㄩ棬锛堟暟鎹潈闄愶級鍒楄〃鏍 + */ + @RequiresPermissions("system:role:edit") + @GetMapping("/deptTreeData") + @ResponseBody + public List deptTreeData(SysRole role) + { + List ztrees = deptService.roleDeptTreeData(role); + return ztrees; + } +} \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java new file mode 100644 index 000000000..142e9a47c --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java @@ -0,0 +1,437 @@ +package com.ruoyi.web.controller.system; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.stream.Collectors; + +import com.ruoyi.common.utils.email.BootEmail; +import com.ruoyi.system.component.UserComponent; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.multipart.MultipartFile; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.UserConstants; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.Ztree; +import com.ruoyi.common.core.domain.entity.SysDept; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.text.Convert; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.ShiroUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.framework.shiro.service.SysPasswordService; +import com.ruoyi.framework.shiro.util.AuthorizationUtils; +import com.ruoyi.system.service.ISysDeptService; +import com.ruoyi.system.service.ISysPostService; +import com.ruoyi.system.service.ISysRoleService; +import com.ruoyi.system.service.ISysUserService; + +/** + * 鐢ㄦ埛淇℃伅 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/system/user") +public class SysUserController extends BaseController +{ + private String prefix = "system/user"; + + @Autowired + private ISysUserService userService; + + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysDeptService deptService; + + @Autowired + private ISysPostService postService; + + @Autowired + private SysPasswordService passwordService; + + @Autowired + private UserComponent userComponent; + + @RequiresPermissions("system:user:view") + @GetMapping() + public String user() + { + return prefix + "/user"; + } + + @RequiresPermissions("system:user:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(SysUser user) + { + startPage(); + List list = userService.selectUserList(user); + return getDataTable(list); + } + + @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:user:export") + @PostMapping("/export") + @ResponseBody + public AjaxResult export(SysUser user) + { + List list = userService.selectUserList(user); + ExcelUtil util = new ExcelUtil(SysUser.class); + return util.exportExcel(list, "鐢ㄦ埛鏁版嵁"); + } + + @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.IMPORT) + @RequiresPermissions("system:user:import") + @PostMapping("/importData") + @ResponseBody + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception + { + ExcelUtil util = new ExcelUtil(SysUser.class); + List userList = util.importExcel(file.getInputStream()); + String message = userService.importUser(userList, updateSupport, getLoginName()); + return AjaxResult.success(message); + } + + @RequiresPermissions("system:user:view") + @GetMapping("/importTemplate") + @ResponseBody + public AjaxResult importTemplate() + { + ExcelUtil util = new ExcelUtil(SysUser.class); + return util.importTemplateExcel("鐢ㄦ埛鏁版嵁"); + } + + /** + * 鏂板鐢ㄦ埛 + */ + @GetMapping("/add") + public String add(ModelMap mmap) + { + mmap.put("roles", roleService.selectRoleAll().stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + mmap.put("posts", postService.selectPostAll()); + return prefix + "/add"; + } + + /** + * 鏂板淇濆瓨鐢ㄦ埛 + */ + @RequiresPermissions("system:user:add") + @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.INSERT) + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(@Validated SysUser user) + { + if (UserConstants.USER_NAME_NOT_UNIQUE.equals(userService.checkLoginNameUnique(user.getLoginName()))) + { + return error("鏂板鐢ㄦ埛'" + user.getLoginName() + "'澶辫触锛岀櫥褰曡处鍙峰凡瀛樺湪"); + } + else if (StringUtils.isNotEmpty(user.getPhonenumber()) + && UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) + { + return error("鏂板鐢ㄦ埛'" + user.getLoginName() + "'澶辫触锛屾墜鏈哄彿鐮佸凡瀛樺湪"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) + && UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(user))) + { + return error("鏂板鐢ㄦ埛'" + user.getLoginName() + "'澶辫触锛岄偖绠辫处鍙峰凡瀛樺湪"); + } + user.setSalt(ShiroUtils.randomSalt()); + user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt())); + user.setCreateBy(getLoginName()); + return toAjax(userService.insertUser(user)); + } + + /** + * 淇敼鐢ㄦ埛 + */ + @RequiresPermissions("system:user:edit") + @GetMapping("/edit/{userId}") + public String edit(@PathVariable("userId") Long userId, ModelMap mmap) + { + userService.checkUserDataScope(userId); + List roles = roleService.selectRolesByUserId(userId); + mmap.put("user", userService.selectUserById(userId)); + mmap.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + mmap.put("posts", postService.selectPostsByUserId(userId)); + return prefix + "/edit"; + } + + /** + * 淇敼淇濆瓨鐢ㄦ埛 + */ + @RequiresPermissions("system:user:edit") + @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.UPDATE) + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(@Validated SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + if (StringUtils.isNotEmpty(user.getPhonenumber()) + && UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) + { + return error("淇敼鐢ㄦ埛'" + user.getLoginName() + "'澶辫触锛屾墜鏈哄彿鐮佸凡瀛樺湪"); + } + /*else if (StringUtils.isNotEmpty(user.getEmail()) + && UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(user))) + { + return error("淇敼鐢ㄦ埛'" + user.getLoginName() + "'澶辫触锛岄偖绠辫处鍙峰凡瀛樺湪"); + }*/ + user.setUpdateBy(getLoginName()); + AuthorizationUtils.clearAllCachedAuthorizationInfo(); + return toAjax(userService.updateUser(user)); + } + + @RequiresPermissions("system:user:resetPwd") + @GetMapping("/resetPwd/{userId}") + public String resetPwd(@PathVariable("userId") Long userId, ModelMap mmap) + { + mmap.put("user", userService.selectUserById(userId)); + return prefix + "/resetPwd"; + } + + @RequiresPermissions("system:user:resetPwd") + @Log(title = "閲嶇疆瀵嗙爜", businessType = BusinessType.UPDATE) + @PostMapping("/resetPwd") + @ResponseBody + public AjaxResult resetPwdSave(SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + user.setSalt(ShiroUtils.randomSalt()); + user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt())); + if (userService.resetUserPwd(user) > 0) + { + if (ShiroUtils.getUserId().longValue() == user.getUserId().longValue()) + { + setSysUser(userService.selectUserById(user.getUserId())); + } + return success(); + } + return error(); + } + + /** + * 杩涘叆鎺堟潈瑙掕壊椤 + */ + @GetMapping("/authRole/{userId}") + public String authRole(@PathVariable("userId") Long userId, ModelMap mmap) + { + SysUser user = userService.selectUserById(userId); + // 鑾峰彇鐢ㄦ埛鎵灞炵殑瑙掕壊鍒楄〃 + List roles = roleService.selectRolesByUserId(userId); + mmap.put("user", user); + mmap.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + return prefix + "/authRole"; + } + + /** + * 鐢ㄦ埛鎺堟潈瑙掕壊 + */ + @RequiresPermissions("system:user:edit") + @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.GRANT) + @PostMapping("/authRole/insertAuthRole") + @ResponseBody + public AjaxResult insertAuthRole(Long userId, Long[] roleIds) + { + userService.checkUserDataScope(userId); + userService.insertUserAuth(userId, roleIds); + AuthorizationUtils.clearAllCachedAuthorizationInfo(); + return success(); + } + + @RequiresPermissions("system:user:remove") + @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.DELETE) + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + if (ArrayUtils.contains(Convert.toLongArray(ids), getUserId())) + { + return error("褰撳墠鐢ㄦ埛涓嶈兘鍒犻櫎"); + } + return toAjax(userService.deleteUserByIds(ids)); + } + + /** + * 鏍¢獙鐢ㄦ埛鍚 + */ + @PostMapping("/checkLoginNameUnique") + @ResponseBody + public String checkLoginNameUnique(SysUser user) + { + return userService.checkLoginNameUnique(user.getLoginName()); + } + + /** + * 鏍¢獙鎵嬫満鍙风爜 + */ + @PostMapping("/checkPhoneUnique") + @ResponseBody + public String checkPhoneUnique(SysUser user) + { + return userService.checkPhoneUnique(user); + } + + /** + * 鏍¢獙email閭 + */ + @PostMapping("/checkEmailUnique") + @ResponseBody + public String checkEmailUnique(SysUser user) + { + return userService.checkEmailUnique(user); + } + + /** + * 鐢ㄦ埛鐘舵佷慨鏀 + */ + @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.UPDATE) + @RequiresPermissions("system:user:edit") + @PostMapping("/changeStatus") + @ResponseBody + public AjaxResult changeStatus(SysUser user) + { + userService.checkUserAllowed(user); + userService.checkUserDataScope(user.getUserId()); + return toAjax(userService.changeStatus(user)); + } + + /** + * 鍔犺浇閮ㄩ棬鍒楄〃鏍 + */ + @RequiresPermissions("system:user:list") + @GetMapping("/deptTreeData") + @ResponseBody + public List deptTreeData() + { + List ztrees = deptService.selectDeptTree(new SysDept()); + return ztrees; + } + + /** + * 閫夋嫨閮ㄩ棬鏍 + * + * @param deptId 閮ㄩ棬ID + */ + @RequiresPermissions("system:user:list") + @GetMapping("/selectDeptTree/{deptId}") + public String selectDeptTree(@PathVariable("deptId") Long deptId, ModelMap mmap) + { + mmap.put("dept", deptService.selectDeptById(deptId)); + return prefix + "/deptTree"; + } + + @Log(title = "閲嶇疆瀵嗙爜", businessType = BusinessType.UPDATE) + @GetMapping("/forgetPassword") + public String forgetPassword() + { + return "forgetPassword"; + } + + /** + * 閲嶇疆瀵嗙爜 + * @param userCode + * @param email + * @return + */ + @PostMapping("/sendForgetPassword") + @Log(title = "蹇樿瀵嗙爜骞堕噸缃", businessType = BusinessType.UPDATE) + @ResponseBody + public AjaxResult forgetPassword(String userCode, String email) + { + SysUser user = userService.selectUserByEmail(email); + if (user == null) { + return error("閭涓嶆纭紒"); + } + if (!userCode.equals(user.getUserCode())) { + return error("閭鍜屽伐鍙蜂笉鍖归厤锛"); + } + String newPassword = ""; + Random random = new Random(); + for (int i = 0; i < 8; i++) { + newPassword += String.valueOf(random.nextInt(10)); + } + user.setPassword(newPassword); + int result = userService.resetUserPwd(user); + if (result == 1) { + try { + BootEmail.sendSimpleMail(user.getEmail(), "閲嶇疆瀵嗙爜", "鎮ㄧ殑宸ュ崟绯荤粺瀵嗙爜宸茬粡閲嶇疆锛屾柊瀵嗙爜涓猴細"+newPassword); + } catch (Exception e) { + e.printStackTrace(); + } + return success("鏂扮殑瀵嗙爜宸插彂閫佽嚦鎮ㄧ殑閭锛岃娉ㄦ剰鏌ユ敹锛"); + } else { + return error("閲嶇疆澶辫触璇蜂笌绠$悊鍛樿仈绯伙紒"); + } + + } + + /** + * 鏌ョ湅鐢ㄦ埛淇℃伅 + */ + @GetMapping("/detail/{userId}") + public String detail(@PathVariable("userId") Long userId, ModelMap mmap) + { + SysUser user = userComponent.buildData(userService.selectUserById(userId)); + mmap.put("user", user); + mmap.put("roles", roleService.selectRolesByUserId(userId)); + mmap.put("posts", postService.selectPostsByUserId(userId)); + return prefix + "/detail"; + } + + /** + * 鏌ヨ鍦ㄨ亴鍛樺伐 + * + * @return + */ + @RequiresPermissions("system:user:allUserList") + @PostMapping("/allUserList") + @ResponseBody + public TableDataInfo allUserList() + { + List list = userService.selectAllUserList(); + return getDataTable(list); + } + + /** + * 鑾峰彇鍛樺伐淇℃伅 + * @param employeeNo + * @return + */ + @PostMapping("/getEmployeeNo/{employeeNo}") + @ResponseBody + public AjaxResult getEmployeeNo(@PathVariable("employeeNo") String employeeNo) { + SysUser user = userService.selectUserByLoginName(employeeNo.trim()); + if(user == null){ + return error(AjaxResult.Type.ERROR,"鏃犺鐢ㄦ埛"); + } + Map map = new HashMap<>(); + map.put("departmentCode",user.getDepartmentCode()); + map.put("userName",user.getUserName()); + map.put("dept",user.getDept().getDeptName().trim()); + map.put("office",user.getOffices()); + map.put("bankName",user.getBankName()); + map.put("accountNumber",user.getBankNumber()); + return AjaxResult.success("",map); + } + +} \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/BuildController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/BuildController.java new file mode 100644 index 000000000..4d3c1287a --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/BuildController.java @@ -0,0 +1,26 @@ +package com.ruoyi.web.controller.tool; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import com.ruoyi.common.core.controller.BaseController; + +/** + * build 琛ㄥ崟鏋勫缓 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/tool/build") +public class BuildController extends BaseController +{ + private String prefix = "tool/build"; + + @RequiresPermissions("tool:build:view") + @GetMapping() + public String build() + { + return prefix + "/build"; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/SwaggerController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/SwaggerController.java new file mode 100644 index 000000000..de2ae6c53 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/SwaggerController.java @@ -0,0 +1,24 @@ +package com.ruoyi.web.controller.tool; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import com.ruoyi.common.core.controller.BaseController; + +/** + * swagger 鎺ュ彛 + * + * @author ruoyi + */ +@Controller +@RequestMapping("/tool/swagger") +public class SwaggerController extends BaseController +{ + @RequiresPermissions("tool:swagger:view") + @GetMapping() + public String index() + { + return redirect("/swagger-ui/index.html"); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java new file mode 100644 index 000000000..b4f6bac74 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java @@ -0,0 +1,183 @@ +package com.ruoyi.web.controller.tool; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.utils.StringUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import io.swagger.annotations.ApiOperation; + +/** + * swagger 鐢ㄦ埛娴嬭瘯鏂规硶 + * + * @author ruoyi + */ +@Api("鐢ㄦ埛淇℃伅绠$悊") +@RestController +@RequestMapping("/test/user") +public class TestController extends BaseController +{ + private final static Map users = new LinkedHashMap(); + { + users.put(1, new UserEntity(1, "admin", "admin123", "15888888888")); + users.put(2, new UserEntity(2, "ry", "admin123", "15666666666")); + } + + @ApiOperation("鑾峰彇鐢ㄦ埛鍒楄〃") + @GetMapping("/list") + public R> userList() + { + List userList = new ArrayList(users.values()); + return R.ok(userList); + } + + @ApiOperation("鑾峰彇鐢ㄦ埛璇︾粏") + @ApiImplicitParam(name = "userId", value = "鐢ㄦ埛ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class) + @GetMapping("/{userId}") + public R getUser(@PathVariable Integer userId) + { + if (!users.isEmpty() && users.containsKey(userId)) + { + return R.ok(users.get(userId)); + } + else + { + return R.fail("鐢ㄦ埛涓嶅瓨鍦"); + } + } + + @ApiOperation("鏂板鐢ㄦ埛") + @ApiImplicitParams({ + @ApiImplicitParam(name = "userId", value = "鐢ㄦ埛id", dataType = "Integer", dataTypeClass = Integer.class), + @ApiImplicitParam(name = "username", value = "鐢ㄦ埛鍚嶇О", dataType = "String", dataTypeClass = String.class), + @ApiImplicitParam(name = "password", value = "鐢ㄦ埛瀵嗙爜", dataType = "String", dataTypeClass = String.class), + @ApiImplicitParam(name = "mobile", value = "鐢ㄦ埛鎵嬫満", dataType = "String", dataTypeClass = String.class) + }) + @PostMapping("/save") + public R save(UserEntity user) + { + if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) + { + return R.fail("鐢ㄦ埛ID涓嶈兘涓虹┖"); + } + users.put(user.getUserId(), user); + return R.ok(); + } + + @ApiOperation("鏇存柊鐢ㄦ埛") + @PutMapping("/update") + public R update(@RequestBody UserEntity user) + { + if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) + { + return R.fail("鐢ㄦ埛ID涓嶈兘涓虹┖"); + } + if (users.isEmpty() || !users.containsKey(user.getUserId())) + { + return R.fail("鐢ㄦ埛涓嶅瓨鍦"); + } + users.remove(user.getUserId()); + users.put(user.getUserId(), user); + return R.ok(); + } + + @ApiOperation("鍒犻櫎鐢ㄦ埛淇℃伅") + @ApiImplicitParam(name = "userId", value = "鐢ㄦ埛ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class) + @DeleteMapping("/{userId}") + public R delete(@PathVariable Integer userId) + { + if (!users.isEmpty() && users.containsKey(userId)) + { + users.remove(userId); + return R.ok(); + } + else + { + return R.fail("鐢ㄦ埛涓嶅瓨鍦"); + } + } +} + +@ApiModel(value = "UserEntity", description = "鐢ㄦ埛瀹炰綋") +class UserEntity +{ + @ApiModelProperty("鐢ㄦ埛ID") + private Integer userId; + + @ApiModelProperty("鐢ㄦ埛鍚嶇О") + private String username; + + @ApiModelProperty("鐢ㄦ埛瀵嗙爜") + private String password; + + @ApiModelProperty("鐢ㄦ埛鎵嬫満") + private String mobile; + + public UserEntity() + { + + } + + public UserEntity(Integer userId, String username, String password, String mobile) + { + this.userId = userId; + this.username = username; + this.password = password; + this.mobile = mobile; + } + + public Integer getUserId() + { + return userId; + } + + public void setUserId(Integer userId) + { + this.userId = userId; + } + + public String getUsername() + { + return username; + } + + public void setUsername(String username) + { + this.username = username; + } + + public String getPassword() + { + return password; + } + + public void setPassword(String password) + { + this.password = password; + } + + public String getMobile() + { + return mobile; + } + + public void setMobile(String mobile) + { + this.mobile = mobile; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java new file mode 100644 index 000000000..e18d2ccc2 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java @@ -0,0 +1,67 @@ +package com.ruoyi.web.core.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import com.ruoyi.common.config.RuoYiConfig; +import io.swagger.annotations.ApiOperation; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; + +/** + * Swagger2鐨勬帴鍙i厤缃 + * + * @author ruoyi + */ +@Configuration +public class SwaggerConfig +{ + /** 鏄惁寮鍚痵wagger */ + @Value("${swagger.enabled}") + private boolean enabled; + + /** + * 鍒涘缓API + */ + @Bean + public Docket createRestApi() + { + return new Docket(DocumentationType.OAS_30) + // 鏄惁鍚敤Swagger + .enable(enabled) + // 鐢ㄦ潵鍒涘缓璇PI鐨勫熀鏈俊鎭紝灞曠ず鍦ㄦ枃妗g殑椤甸潰涓紙鑷畾涔夊睍绀虹殑淇℃伅锛 + .apiInfo(apiInfo()) + // 璁剧疆鍝簺鎺ュ彛鏆撮湶缁橲wagger灞曠ず + .select() + // 鎵弿鎵鏈夋湁娉ㄨВ鐨刟pi锛岀敤杩欑鏂瑰紡鏇寸伒娲 + .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) + // 鎵弿鎸囧畾鍖呬腑鐨剆wagger娉ㄨВ + //.apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger")) + // 鎵弿鎵鏈 .apis(RequestHandlerSelectors.any()) + .paths(PathSelectors.any()) + .build(); + } + + /** + * 娣诲姞鎽樿淇℃伅 + */ + private ApiInfo apiInfo() + { + // 鐢ˋpiInfoBuilder杩涜瀹氬埗 + return new ApiInfoBuilder() + // 璁剧疆鏍囬 + .title("鏍囬锛氳嫢渚濈鐞嗙郴缁焈鎺ュ彛鏂囨。") + // 鎻忚堪 + .description("鎻忚堪锛氱敤浜庣鐞嗛泦鍥㈡棗涓嬪叕鍙哥殑浜哄憳淇℃伅,鍏蜂綋鍖呮嫭XXX,XXX妯″潡...") + // 浣滆呬俊鎭 + .contact(new Contact(RuoYiConfig.getName(), null, null)) + // 鐗堟湰 + .version("鐗堟湰鍙:" + RuoYiConfig.getVersion()) + .build(); + } +} diff --git a/ruoyi-admin/src/main/resources/application-druid.yml b/ruoyi-admin/src/main/resources/application-druid.yml new file mode 100644 index 000000000..bad12b88a --- /dev/null +++ b/ruoyi-admin/src/main/resources/application-druid.yml @@ -0,0 +1,74 @@ +# 鏁版嵁婧愰厤缃 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + druid: + # 涓诲簱鏁版嵁婧 + master: + # SKaiL娴嬭瘯搴 +# url: jdbc:mysql://10.0.7.57:3306/nj_workorder?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 +# username: root +# password: root + # 姝e紡搴 + url: jdbc:mysql://192.168.13.216:3306/workorder?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8 + username: root + password: Silergy1897 + # 浠庡簱鏁版嵁婧 + slave: + # 浠庢暟鎹簮寮鍏/榛樿鍏抽棴 + enabled: true + url: jdbc:mysql://192.168.5.31:3306/insidesales?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + username: optionapi + password: apiq1w2e3 + slave2: + # 浠庢暟鎹簮寮鍏/榛樿鍏抽棴 # 椤圭洰缂栧彿 + enabled: true + url: jdbc:mysql://192.168.5.16:3306/develop?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + username: develop + password: HSYSeLqxRQ7zwHDG + slave3: + # 浠庢暟鎹簮寮鍏/榛樿鍏抽棴 # 鍗曠偣鐧诲綍 + enabled: true + url: jdbc:mysql://192.168.5.16:3306/onlinelogin?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + username: onlinelogin + password: onlineloginq1w2 + # 鍒濆杩炴帴鏁 + initialSize: 5 + # 鏈灏忚繛鎺ユ睜鏁伴噺 + minIdle: 10 + # 鏈澶ц繛鎺ユ睜鏁伴噺 + maxActive: 20 + # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂 + maxWait: 60000 + # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣 + timeBetweenEvictionRunsMillis: 60000 + # 閰嶇疆涓涓繛鎺ュ湪姹犱腑鏈灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣 + minEvictableIdleTimeMillis: 300000 + # 閰嶇疆涓涓繛鎺ュ湪姹犱腑鏈澶х敓瀛樼殑鏃堕棿锛屽崟浣嶆槸姣 + maxEvictableIdleTimeMillis: 900000 + # 閰嶇疆妫娴嬭繛鎺ユ槸鍚︽湁鏁 + validationQuery: SELECT 1 FROM DUAL + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂 + allow: + url-pattern: /druid/* + # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮 + login-username: ruoyi + login-password: 123456 + filter: + stat: + enabled: true + # 鎱QL璁板綍 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/application-user.yml b/ruoyi-admin/src/main/resources/application-user.yml new file mode 100644 index 000000000..9bd035c8b --- /dev/null +++ b/ruoyi-admin/src/main/resources/application-user.yml @@ -0,0 +1,427 @@ +#璇锋鍗曠浉鍏冲鏍镐俊鎭 +PaymentRequest: + MAX_A4: 10000 + #B闈炵敓鎴愭ф敮鍑(鎸佺画鎬)-缁忕悊鏈澶ч噾棰 + MAX_B4: 5000 + #C闈炵敓鎴愭ф敮鍑(闈炴寔缁)-缁忕悊鏈澶ч噾棰 + MAX_C4: 2000 + #D宸梾璐-缁忕悊鏈澶ч噾棰 + MAX_D4: 600 + #E浜ら檯璐-缁忕悊鏈澶ч噾棰 + MAX_E4: 600 + + #A鐢熸垚鎬ф敮鍑-鎬荤洃鏈澶ч噾棰 + MAX_A3: 50000 + #B闈炵敓鎴愭ф敮鍑(鎸佺画鎬)-鎬荤洃鏈澶ч噾棰 + MAX_B3: 20000 + #C闈炵敓鎴愭ф敮鍑(闈炴寔缁)-鎬荤洃鏈澶ч噾棰 + MAX_C3: 10000 + #D宸梾璐-鎬荤洃鏈澶ч噾棰 + MAX_D3: 1000 + #E浜ら檯璐-鎬荤洃鏈澶ч噾棰 + MAX_E3: 1000 + + #A鐢熸垚鎬ф敮鍑-鎵ц鎬荤洃鏈澶ч噾棰 + MAX_A2: 100000 + #B闈炵敓鎴愭ф敮鍑(鎸佺画鎬)-鎵ц鎬荤洃鏈澶ч噾棰 + MAX_B2: 50000 + #C闈炵敓鎴愭ф敮鍑(闈炴寔缁)-鎵ц鎬荤洃鏈澶ч噾棰 + MAX_C2: 20000 + #D宸梾璐-鎵ц鎬荤洃鏈澶ч噾棰 + MAX_D2: 2000 + #E浜ら檯璐-鎵ц鎬荤洃鏈澶ч噾棰 + MAX_E2: 2000 + + #A鐢熸垚鎬ф敮鍑-鎬荤粡鐞嗘渶澶ч噾棰 + MAX_A1: 100000000000 + #B闈炵敓鎴愭ф敮鍑(鎸佺画鎬)-鎬荤粡鐞嗘渶澶ч噾棰 + MAX_B1: 100000000000 + #C闈炵敓鎴愭ф敮鍑(闈炴寔缁)-鎬荤粡鐞嗘渶澶ч噾棰 + MAX_C1: 100000000000 + #D宸梾璐-鎬荤粡鐞嗘渶澶ч噾棰 + MAX_D1: 100000000000 + #E浜ら檯璐-鎬荤粡鐞嗘渶澶ч噾棰 + MAX_E1: 100000000000 + + #闄堟伙紝鏍稿喅涓荤 + RULING1: S00001 + RULINGNAME1: 闄堟 + + #娓告伙紝鏍稿喅涓荤 + RULING2: S00002 + RULINGNAME2: 娓告 + + #鏉窞浼氳 + HZ_ACCOUNTING: S01880,S01209,S01127 + HZ_ACCOUNTING_NAME: 鏂借埅\椤逛繌淇奬璧佃幑鑾 + + #寮鏇糪鐭芥湜 浼氳 + KM_ACCOUNTING: S01034,S01132 + KM_ACCOUNTING_NAME: 鏂芥鏉嶾鑳¤姵娲 + + #鍗椾含浼氳 + NJ_ACCOUNTING: S01707 + NJ_ACCOUNTING_NAME: 姊呰壋 + + #鎴愰兘浼氳 + CD_ACCOUNTING: S00379 + CD_ACCOUNTING_NAME: 椹捣浜 + + #瑗垮畨浼氳 + XA_ACCOUNTING: S01522,S00379 + XA_ACCOUNTING_NAME: 闃庨洦棣╘椹捣浜 + + #涓婃捣\涓婃捣鐭藉姏鏉板井鐢靛瓙 浼氳 + SH_ACCOUNTING: S00610 + SH_ACCOUNTING_NAME: 浠樺┓ + + #鍗椾含棣欐腐浼氳 + NJXG_ACCOUNTING: S01296 + NJXG_ACCOUNTING_NAME: 鐜嬫櫠 + + #鍙版咕鐭藉姏鏉颁細璁 + TW_ACCOUNTING: S00671,S00356 + TW_ACCOUNTING_NAME: 榛冮泤閳碶闊撹┅钑 + + #棣欐腐\钀ㄦ懇浜 浼氳 + XG_ACCOUNTING: S01123 + XG_ACCOUNTING_NAME: 鏋椾匠鎬 + + #鍗椾含棣欐腐浼氳 + HF_ACCOUNTING: S01682 + HF_ACCOUNTING_NAME: 楂樼敎 + + #婢抽棬浼氳 + AM_ACCOUNTING: S00748 + AM_ACCOUNTING_NAME: 姹熷钀 + + #鏉窞鎬昏处 + HZ_GENERAL_LEDGER: S00152 + HZ_GENERAL_LEDGER_NAME: 鐜嬪 + + #寮鏇糪鐭芥湜 鎬昏处 + KM_GENERAL_LEDGER: S00600 + KM_GENERAL_LEDGER_NAME: 鍙跺皬浠 + + #鍗椾含鎬昏处 + NJ_GENERAL_LEDGER: S00467 + NJ_GENERAL_LEDGER_NAME: 寮犵幉 + + #鎴愰兘鎬昏处 + CD_GENERAL_LEDGER: S01175 + CD_GENERAL_LEDGER_NAME: 搴炴澀鑹 + + #瑗垮畨鎬昏处 + XA_GENERAL_LEDGER: S00969 + XA_GENERAL_LEDGER_NAME: 鐣呬僵鍗 + + #涓婃捣鎬昏处 + SH_GENERAL_LEDGER: S01175 + SH_GENERAL_LEDGER_NAME: 搴炴澀鑹 + + #涓婃捣鐭藉姏鏉板井鐢靛瓙 鎬昏处 + SHW_GENERAL_LEDGER: S01296 + SHW_GENERAL_LEDGER_NAME: 鐜嬫櫠 + + #鍗椾含棣欐腐 鎬昏处 + NJXG_GENERAL_LEDGER: S01141 + NJXG_GENERAL_LEDGER_NAME: 闄堜含鏅 + + #鍙版咕鎬昏处 + TW_GENERAL_LEDGER: S00356 + TW_GENERAL_LEDGER_NAME: 闊撹┅钑 + + #鍙版咕鎬昏处(鐗规畩澶勭悊) + TW_GENERAL_LEDGER1: S01175 + TW_GENERAL_LEDGER1_NAME: 搴炴澀鑹 + + #棣欐腐\钀ㄦ懇浜 鎬昏处 + XG_GENERAL_LEDGER: S01175 + XG_GENERAL_LEDGER_NAME: 搴炴澀鑹 + + #鍚堣偉鎬昏处 + HF_GENERAL_LEDGER: S01175 + HF_GENERAL_LEDGER_NAME: 搴炴澀鑹 + + #婢抽棬鎬昏处 + AM_GENERAL_LEDGER: S01175 + AM_GENERAL_LEDGER_NAME: 搴炴澀鑹 + + +#璇疯喘鍗曠浉鍏冲鏍镐俊鎭 +Requisition: + #缁忕悊鏈澶ч噾棰 + MAX_4: 2000 + #鎬荤洃鏈澶ч噾棰 + MAX_3: 10000 + #鎵ц鎬荤洃鏈澶ч噾棰 + MAX_2: 20000 + #鎬荤粡鐞嗘渶澶ч噾棰 + MAX_1: 100000000000 + + #鏉窞 + hzBoss: S00002 + hzBossName: 娓告 + + #鍗椾含 鍗椾含棣欐腐 涓婃捣鐭藉姏鏉板井鐢靛瓙 + shBoss: S00001 + shBossName: 闄堟 + + #hr 閫変簡345鐨3涓夐」灏辫鍒拌繖姹囨诲鎵 + hrPrincipal: S00038 + hrPrincipalName: 鍛ㄥ⿻ + + #鏉窞 鍔炲叕璁惧 鍔炲叕瀹跺叿绫 鍙跺弻鍙 + deptDevice: S00245 + deptDeviceName: 鍙跺弻鍙 + + #鏉窞 瀹為獙瀹ゅ浐璧勭被 + laboratoryDevice: S00058 + laboratoryDeviceName: 闊﹀噷鍗 + + #鏉窞 鑰楁潗绫 鐜嬬嚂 + costDevice: S01194 + costDeviceName: 鐜嬬嚂 + + #鏉窞 鏂板憳宸ュ叆鑱宧r鍙朵附涓借繘琛岀鏍(鍙朵附涓戒紤鍋,鏀逛负瀹夋檽濞) + hrAssets: S01716 + hrAssetsName: 瀹夋檽濞 + + + #------------------ 鍙版咕璧勪骇绠$悊鍛/閲囪喘浠h〃 ------------------# + #it妗岄潰涓汉鐢佃剳 缃楅潚鏉 + itTwDevice: S00349 + itTwDeviceName: 缇呴潚鏉 + + + #------------------ 鍗椾含璧勪骇绠$悊鍛 ------------------# + #it妗岄潰涓汉鐢佃剳 + itNjDevice: S01183 + itNjDeviceName: 璧垫櫠 + + #娴嬭瘯璁惧\鍏冨櫒浠 闄堜紡鍕 + testNJDevice: S00154 + testNJDeviceName: 闄堜紡鍕 + + #鍔炲叕瀹跺叿绫籠瀹為獙瀹ゅ浐璧勭被\鑰楁潗 褰姵 + deptNJDevice: S01182 + deptNJDeviceName: 褰姵 + + #宸ョ▼ 鎴庣幉 + engineeringNJ: S00269 + engineeringNJName: 鎴庣幉 + + + #------------------ 瑗垮畨璧勪骇绠$悊鍛 ------------------# + #it妗岄潰涓汉鐢佃剳 + itXaDevice: S01425 + itXaDeviceName: 鍒樻棴鏋 + + + #------------------ 鍚堣偉璧勪骇绠$悊鍛 ------------------# + hfDevice: S01861 + hfDeviceName: 璧佃幑 + + + #------------------ 鏉窞閲囪喘缁忕悊 ------------------# + hzZhangLi: S01679 + hzZhangLiName: 寮犱附 + + + #------------------ 婢抽棬閲囪喘缁忕悊 ------------------# + amFinanceAssets: S01737 + amFinanceAssetsName: 鏉庡啲姊 + + + #------------------ 棰勭畻绠$悊浜哄憳 ------------------# + financeAssets: budget + financeAssetsName: 鐜嬫櫠 + + + #------------------ 璐㈠姟棰勭畻缁忕悊 ------------------# + budgetManager: budget_manager + budgetManagerName: 闄堜含鏅 + + + #------------------ 鍚勫湴鍖烘昏处 ------------------# + #鏉窞鎬昏处 + hzZg: S00152 + hzZgName: 鐜嬪 + #corp鎬昏处 + corpZg: S00600 + corpZgName: 鍙跺皬浠 + #瑗垮畨鎬昏处 + xaZg: S00969 + xaZgName: 鐣呬僵鍗 + #鎴愰兘鎬昏处 + cdZg: S00379 + cdZgName: 椹捣浜 + #/涓婃捣鎬昏处 + shZg: S00610 + shZgName: 浠樺┓ + #闊╁浗鎬昏处 + hgZg: S00748 + hgZgName: 姹熷钀 + #缇庡浗鎬昏处 + mgZg: S01123 + mgZgName: 鏋椾匠鎬 + #钀ㄦ懇浜氭昏处 + smyZg: S01123 + smyZgName: 鏋椾匠鎬 + #鍗板害鎬昏处 + ydZg: S01123 + ydZgName: 鏋椾匠鎬 + #鏃ユ湰鎬昏处 + rbZg: S01123 + rbZgName: 鏋椾匠鎬 + #棣欐腐鎬昏处 + xgZg: S01123 + xgZgName: 鏋椾匠鎬 + #鍙版咕鐭藉姏鏉版昏处 + twZg: S00356 + twZgName: 闊╄瘲钑 + #鍗椾含鎬昏处 + njZg: S00467 + njZgName: 寮犵幉 + #鑺儀i鎬昏处 + pxZg: S00467 + pxZgName: 寮犵幉 + #鍗椾含棣欐腐鎬昏处 + njXgZg: S01296 + njXgZgName: 鐜嬫櫠 + #xi鏈涙昏处 + xwZg: S00107 + xwZgName: 寰愯帀濞 + #鍚堣偉鎬昏处 + hfZg: S01682 + hfZgName: 楂樼敎 + #婢抽棬鎬昏处 + amZg: S00748 + amZgName: 姹熷钀 + + + #------------------ 鍚勫湴鍖鸿储鍔$粡鐞 ------------------# + #鏉窞 鍚堣偉 婢抽棬 搴炴澀鑹 + hzJL: S01175 + hzJlName: 搴炴澀鑹 + #鍗椾含缁忕悊 闄堜含鏅 + njJl: S01141 + njJlName: 闄堜含鏅 + +#鐢ㄦ埛璐﹀彿鏉冮檺鐢宠鍗 +itUserAuthorizationFrom: + #纭欢 + HZit: S00262,S01110 + NJit: S01183 + TWit: S00349 + #杞欢 + itEAS: S00110,S00248,S00623 + +#绯荤粺鍔熻兘闇姹傚崟 +function: + # itmanager鐨刢ode + itManagerCode: S00110 + # it鎬荤洃 + itDirectorCode: S01686 + # 鎬荤粡鐞 + generalManager: S00002 + +#鐢靛瓙绛惧憟 +petition: + #HR娌堢濡 + hrSKR: S00774 + #HR鍙跺弻鍙 + hrYSS: S00245 + #HR鍙朵附涓 + hrYLL: S00137 + #HR闊﹀噷鍗 + hrWLH: S00058 + #鍛ㄥ⿻ + hrZJ : S00038 + #HR鐜嬬嚂 + hrWY: S01194 + #榛冨鏅 + sealHYC: S00308 + #鎴庣幉 + sealRL: S00269 + #鐧芥案姹 + sealBYJ: S00111 + #鐜嬪崜浜 + sealWZY: S00112 + #椹捣浜 + sealMHY: S00379 + #闄堝悰 + sealCJ: S00025 + #瀹佸崜 + sealNZ: S01181 + #鐜嬮(缃楁濮d紤鍋) + fwLMJ: S01423 + #fwLMJ: S00716 + #璐㈠姟缁忕悊搴炴澀鐕 + cwPHY: S01175 + #璐㈠姟缁忕悊闄堜含鏅 + cwCJJ: S01141 + #璐㈠姟鐜嬪 + cwWN: S00152 + #璐㈠姟寰愪附濞 + cwXLJ: S00107 + #璐㈠姟鐣呬僵鍗 + cwCPH: S00969 + #璐㈠姟灏硅█ + cwYY: S00176 + #璐㈠姟鏋椾匠鎬 + cwLJY: S01123 + #璐㈠姟闊撹┅钑 + cwHSH: S00356 + #璐㈠姟寮犵幉 + cwZL: S00467 + #璐㈠姟澶忔櫠 + cwXJ: S01164 + #corp娼樺啝鍛 + cwPGC: S00108 + #corp 闄堢粛浼 + cwCSW: S01151 + #涓婃捣鐜嬭彶 + cwWF: S01109 + #涓婃捣浠樺┓ + cwFT: S00610 + #鍙跺皬浠 + cwYXX: S00600 + #鐜嬫櫠 + cwWJ: S01296 + #楂樼敎 + cwGT: S01682 + #鏉庡啲姊 + cwLDM: S01737 + + + + +money: + # 璇疯喘鍗曢渶瑕佹牳鍐崇殑閲戦 + purchase: 10000 + #it璁惧鏅撶惇鍝 + itDevice: S00262 + #娴嬭瘯绀句繚鏈卞啺濞 + testDevice: S00099 + #hr璐熻矗浜猴紝閫変簡345鐨3涓夐」灏辫鍒拌繖姹囨诲鎵 + hrPrincipal: S00038 + #鍔炲叕璁惧鍙跺弻鍙 鍔炲叕瀹跺叿绫 + deptDevice: S00245 + #鍔炲叕璁惧闊﹀噷鍗 瀹為獙瀹ゅ浐璧勭被 + laboratoryDevice: S00058 + #鍔炲叕璁惧娌堢濡 鑰楁潗绫 + costDevice: S00774 + #璐㈠姟璧勪骇绠$悊浜哄憳 + financeAssets: S01192 + #鏂板憳宸ュ叆鑱宧r鍙朵附涓借繘琛岀鏍 + hrAssets: S00137 + #宸ョ▼鏄粍閽 + engineering: S00386 + #鏉窞boss + hzBoss: S00002 + + +errMsg: + email1: kailun.shi@silergycorp.com + email2: shiyang.zhuo@silergycorp.com,sensen.li@silergycorp.com \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml new file mode 100644 index 000000000..2336cbdad --- /dev/null +++ b/ruoyi-admin/src/main/resources/application.yml @@ -0,0 +1,161 @@ +# 椤圭洰鐩稿叧閰嶇疆 +ruoyi: + # 鍚嶇О + name: WorkOrder + # 鐗堟湰 + version: 4.7.5 + # 鐗堟潈骞翠唤 + copyrightYear: 2022 + # 瀹炰緥婕旂ず寮鍏 + demoEnabled: false + # 鏂囦欢璺緞 绀轰緥锛 Windows閰嶇疆D:/ruoyi/uploadPath锛孡inux閰嶇疆 /home/ruoyi/uploadPath锛 + profile: /opt/java/uploadPath + # 鑾峰彇ip鍦板潃寮鍏 + addressEnabled: false + +# 寮鍙戠幆澧冮厤缃 +server: + # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负80 + port: 8060 + servlet: + # 搴旂敤鐨勮闂矾寰 + context-path: / + tomcat: + # tomcat鐨刄RI缂栫爜 + uri-encoding: UTF-8 + # 杩炴帴鏁版弧鍚庣殑鎺掗槦鏁帮紝榛樿涓100 + accept-count: 1000 + threads: + # tomcat鏈澶х嚎绋嬫暟锛岄粯璁や负200 + max: 800 + # Tomcat鍚姩鍒濆鍖栫殑绾跨▼鏁帮紝榛樿鍊10 + min-spare: 100 + +# 鏃ュ織閰嶇疆 +logging: + level: + com.ruoyi: debug + org.springframework: warn + +# 鐢ㄦ埛閰嶇疆 +user: + password: + # 瀵嗙爜閿欒{maxRetryCount}娆¢攣瀹10鍒嗛挓 + maxRetryCount: 5 + +# Spring閰嶇疆 +spring: + # 妯℃澘寮曟搸 + thymeleaf: + mode: HTML + encoding: utf-8 + # 绂佺敤缂撳瓨 + cache: false + # 璧勬簮淇℃伅 + messages: + # 鍥介檯鍖栬祫婧愭枃浠惰矾寰 + basename: static/i18n/messages + jackson: + time-zone: GMT+8 + date-format: yyyy-MM-dd HH:mm:ss + profiles: + active: druid,user + # 鏂囦欢涓婁紶 + servlet: + multipart: + # 鍗曚釜鏂囦欢澶у皬 + max-file-size: 10MB + # 璁剧疆鎬讳笂浼犵殑鏂囦欢澶у皬 + max-request-size: 20MB + # 鏈嶅姟妯″潡 + devtools: + restart: + # 鐑儴缃插紑鍏 + enabled: true + # 閭欢妯″潡 + mail: + host: mailhz.silergycorp.com + username: webmaster + password: QQ!!rat18971897 + default-encoding: UTF-8 + port: 465 + properties: + mail: + smtp: + ssl: + trust: mailhz.silergycorp.com + socketFactory: + class: javax.net.ssl.SSLSocketFactory + port: 465 + auth: true + starttls: + enable: true + required: true + +# MyBatis +mybatis: + # 鎼滅储鎸囧畾鍖呭埆鍚 + typeAliasesPackage: com.ruoyi.**.domain + # 閰嶇疆mapper鐨勬壂鎻忥紝鎵惧埌鎵鏈夌殑mapper.xml鏄犲皠鏂囦欢 + mapperLocations: classpath*:mapper/**/*Mapper.xml + # 鍔犺浇鍏ㄥ眬鐨勯厤缃枃浠 + configLocation: classpath:mybatis/mybatis-config.xml + +# PageHelper鍒嗛〉鎻掍欢 +pagehelper: + helperDialect: mysql + supportMethodsArguments: true + params: count=countSql + +# Shiro +shiro: + user: + # 鐧诲綍鍦板潃 + loginUrl: /login + # 鏉冮檺璁よ瘉澶辫触鍦板潃 + unauthorizedUrl: /unauth + # 棣栭〉鍦板潃 + indexUrl: /index + # 楠岃瘉鐮佸紑鍏 + captchaEnabled: false + # 楠岃瘉鐮佺被鍨 math 鏁扮粍璁$畻 char 瀛楃 + captchaType: math + cookie: + # 璁剧疆Cookie鐨勫煙鍚 榛樿绌猴紝鍗冲綋鍓嶈闂殑鍩熷悕 + domain: + # 璁剧疆cookie鐨勬湁鏁堣闂矾寰 + path: / + # 璁剧疆HttpOnly灞炴 + httpOnly: true + # 璁剧疆Cookie鐨勮繃鏈熸椂闂达紝澶╀负鍗曚綅 + maxAge: 30 + # 璁剧疆瀵嗛挜锛屽姟蹇呬繚鎸佸敮涓鎬э紙鐢熸垚鏂瑰紡锛岀洿鎺ユ嫹璐濆埌main杩愯鍗冲彲锛塀ase64.encodeToString(CipherUtils.generateNewKey(128, "AES").getEncoded()) 锛堥粯璁ゅ惎鍔ㄧ敓鎴愰殢鏈虹閽ワ紝闅忔満绉橀挜浼氬鑷翠箣鍓嶅鎴风RememberMe Cookie鏃犳晥锛屽璁剧疆鍥哄畾绉橀挜RememberMe Cookie鍒欐湁鏁堬級 + cipherKey: + session: + # Session瓒呮椂鏃堕棿锛-1浠h〃姘镐笉杩囨湡锛堥粯璁30鍒嗛挓锛 + expireTime: 30 + # 鍚屾session鍒版暟鎹簱鐨勫懆鏈燂紙榛樿1鍒嗛挓锛 + dbSyncPeriod: 1 + # 鐩搁殧澶氫箙妫鏌ヤ竴娆ession鐨勬湁鏁堟э紝榛樿灏辨槸10鍒嗛挓 + validationInterval: 10 + # 鍚屼竴涓敤鎴锋渶澶т細璇濇暟锛屾瘮濡2鐨勬剰鎬濇槸鍚屼竴涓处鍙峰厑璁告渶澶氬悓鏃朵袱涓汉鐧诲綍锛堥粯璁-1涓嶉檺鍒讹級 + maxSession: -1 + # 韪㈠嚭涔嬪墠鐧诲綍鐨/涔嬪悗鐧诲綍鐨勭敤鎴凤紝榛樿韪㈠嚭涔嬪墠鐧诲綍鐨勭敤鎴 + kickoutAfter: false + rememberMe: + # 鏄惁寮鍚浣忔垜 + enabled: true + +# 闃叉XSS鏀诲嚮 +xss: + # 杩囨护寮鍏 + enabled: true + # 鎺掗櫎閾炬帴锛堝涓敤閫楀彿鍒嗛殧锛 + excludes: /system/notice/* + # 鍖归厤閾炬帴 + urlPatterns: /system/*,/monitor/*,/tool/* + +# Swagger閰嶇疆 +swagger: + # 鏄惁寮鍚痵wagger + enabled: true diff --git a/ruoyi-admin/src/main/resources/banner.txt b/ruoyi-admin/src/main/resources/banner.txt new file mode 100644 index 000000000..840ee8609 --- /dev/null +++ b/ruoyi-admin/src/main/resources/banner.txt @@ -0,0 +1,24 @@ +Application Version: ${ruoyi.version} +Spring Boot Version: ${spring-boot.version} +//////////////////////////////////////////////////////////////////// +// _ooOoo_ // +// o8888888o // +// 88" . "88 // +// (| ^_^ |) // +// O\ = /O // +// ____/`---'\____ // +// .' \\| |// `. // +// / \\||| : |||// \ // +// / _||||| -:- |||||- \ // +// | | \\\ - /// | | // +// | \_| ''\---/'' | | // +// \ .-\__ `-` ___/-. / // +// ___`. .' /--.--\ `. . ___ // +// ."" '< `.___\_<|>_/___.' >'"". // +// | | : `- \`.;`\ _ /`;.`/ - ` : | | // +// \ \ `-. \_ __\ /__ _/ .-` / / // +// ========`-.____`-.___\_____/___.-`____.-'======== // +// `=---=' // +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // +// 浣涚淇濅綉 姘镐笉瀹曟満 姘告棤BUG // +//////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/ehcache/ehcache-shiro.xml b/ruoyi-admin/src/main/resources/ehcache/ehcache-shiro.xml new file mode 100644 index 000000000..83fef1978 --- /dev/null +++ b/ruoyi-admin/src/main/resources/ehcache/ehcache-shiro.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/logback.xml b/ruoyi-admin/src/main/resources/logback.xml new file mode 100644 index 000000000..473d50807 --- /dev/null +++ b/ruoyi-admin/src/main/resources/logback.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/sys-info.log + + + + ${log.path}/sys-info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/sys-error.log + + + + ${log.path}/sys-error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + ${log.path}/sys-user.log + + + ${log.path}/sys-user.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml b/ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml new file mode 100644 index 000000000..ac47c038e --- /dev/null +++ b/ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/beautifyhtml/beautifyhtml.js b/ruoyi-admin/src/main/resources/static/ajax/libs/beautifyhtml/beautifyhtml.js new file mode 100644 index 000000000..ea69dece1 --- /dev/null +++ b/ruoyi-admin/src/main/resources/static/ajax/libs/beautifyhtml/beautifyhtml.js @@ -0,0 +1,617 @@ +/*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */ +/* + + The MIT License (MIT) + + Copyright (c) 2007-2013 Einar Lielmanis and contributors. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + + Style HTML +--------------- + + Written by Nochum Sossonko, (nsossonko@hotmail.com) + + Based on code initially developed by: Einar Lielmanis, + http://jsbeautifier.org/ + + Usage: + style_html(html_source); + + style_html(html_source, options); + + The options are: + indent_size (default 4) 鈥 indentation size, + indent_char (default space) 鈥 character to indent with, + max_char (default 250) - maximum amount of characters per line (0 = disable) + brace_style (default "collapse") - "collapse" | "expand" | "end-expand" + put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line. + unformatted (defaults to inline tags) - list of tags, that shouldn't be reformatted + indent_scripts (default normal) - "keep"|"separate"|"normal" + + e.g. + + style_html(html_source, { + 'indent_size': 2, + 'indent_char': ' ', + 'max_char': 78, + 'brace_style': 'expand', + 'unformatted': ['a', 'sub', 'sup', 'b', 'i', 'u'] + }); +*/ + +(function() { + + function style_html(html_source, options, js_beautify, css_beautify) { + //Wrapper function to invoke all the necessary constructors and deal with the output. + + var multi_parser, + indent_size, + indent_character, + max_char, + brace_style, + unformatted; + + options = options || {}; + indent_size = options.indent_size || 4; + indent_character = options.indent_char || ' '; + brace_style = options.brace_style || 'collapse'; + max_char = options.max_char === 0 ? Infinity : options.max_char || 250; + unformatted = options.unformatted || ['a', 'span', 'bdo', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'sub', 'sup', 'tt', 'i', 'b', 'big', 'small', 'u', 's', 'strike', 'font', 'ins', 'del', 'pre', 'address', 'dt', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6']; + + function Parser() { + + this.pos = 0; //Parser position + this.token = ''; + this.current_mode = 'CONTENT'; //reflects the current Parser mode: TAG/CONTENT + this.tags = { //An object to hold tags, their position, and their parent-tags, initiated with default values + parent: 'parent1', + parentcount: 1, + parent1: '' + }; + this.tag_type = ''; + this.token_text = this.last_token = this.last_text = this.token_type = ''; + + this.Utils = { //Uilities made available to the various functions + whitespace: "\n\r\t ".split(''), + single_token: 'br,input,link,meta,!doctype,basefont,base,area,hr,wbr,param,img,isindex,?xml,embed,?php,?,?='.split(','), //all the single tags for HTML + extra_liners: 'head,body,/html'.split(','), //for tags that need a line of whitespace before them + in_array: function (what, arr) { + for (var i=0; i= this.input.length) { + return content.length?content.join(''):['', 'TK_EOF']; + } + + input_char = this.input.charAt(this.pos); + this.pos++; + this.line_char_count++; + + if (this.Utils.in_array(input_char, this.Utils.whitespace)) { + if (content.length) { + space = true; + } + this.line_char_count--; + continue; //don't want to insert unnecessary space + } + else if (space) { + if (this.line_char_count >= this.max_char) { //insert a line when the max_char is reached + content.push('\n'); + for (var i=0; i', 'igm'); + reg_match.lastIndex = this.pos; + var reg_array = reg_match.exec(this.input); + var end_script = reg_array?reg_array.index:this.input.length; //absolute end of script + if(this.pos < end_script) { //get everything in between the script tags + content = this.input.substring(this.pos, end_script); + this.pos = end_script; + } + return content; + }; + + this.record_tag = function (tag){ //function to record a tag and its parent in this.tags Object + if (this.tags[tag + 'count']) { //check for the existence of this tag type + this.tags[tag + 'count']++; + this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level + } + else { //otherwise initialize this tag type + this.tags[tag + 'count'] = 1; + this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level + } + this.tags[tag + this.tags[tag + 'count'] + 'parent'] = this.tags.parent; //set the parent (i.e. in the case of a div this.tags.div1parent) + this.tags.parent = tag + this.tags[tag + 'count']; //and make this the current parent (i.e. in the case of a div 'div1') + }; + + this.retrieve_tag = function (tag) { //function to retrieve the opening tag to the corresponding closer + if (this.tags[tag + 'count']) { //if the openener is not in the Object we ignore it + var temp_parent = this.tags.parent; //check to see if it's a closable tag. + while (temp_parent) { //till we reach '' (the initial value); + if (tag + this.tags[tag + 'count'] === temp_parent) { //if this is it use it + break; + } + temp_parent = this.tags[temp_parent + 'parent']; //otherwise keep on climbing up the DOM Tree + } + if (temp_parent) { //if we caught something + this.indent_level = this.tags[tag + this.tags[tag + 'count']]; //set the indent_level accordingly + this.tags.parent = this.tags[temp_parent + 'parent']; //and set the current parent + } + delete this.tags[tag + this.tags[tag + 'count'] + 'parent']; //delete the closed tags parent reference... + delete this.tags[tag + this.tags[tag + 'count']]; //...and the tag itself + if (this.tags[tag + 'count'] === 1) { + delete this.tags[tag + 'count']; + } + else { + this.tags[tag + 'count']--; + } + } + }; + + this.get_tag = function (peek) { //function to get a full tag and parse its type + var input_char = '', + content = [], + comment = '', + space = false, + tag_start, tag_end, + orig_pos = this.pos, + orig_line_char_count = this.line_char_count; + + peek = peek !== undefined ? peek : false; + + do { + if (this.pos >= this.input.length) { + if (peek) { + this.pos = orig_pos; + this.line_char_count = orig_line_char_count; + } + return content.length?content.join(''):['', 'TK_EOF']; + } + + input_char = this.input.charAt(this.pos); + this.pos++; + this.line_char_count++; + + if (this.Utils.in_array(input_char, this.Utils.whitespace)) { //don't want to insert unnecessary space + space = true; + this.line_char_count--; + continue; + } + + if (input_char === "'" || input_char === '"') { + if (!content[1] || content[1] !== '!') { //if we're in a comment strings don't get treated specially + input_char += this.get_unformatted(input_char); + space = true; + } + } + + if (input_char === '=') { //no space before = + space = false; + } + + if (content.length && content[content.length-1] !== '=' && input_char !== '>' && space) { + //no space after = or before > + if (this.line_char_count >= this.max_char) { + this.print_newline(false, content); + this.line_char_count = 0; + } + else { + content.push(' '); + this.line_char_count++; + } + space = false; + } + if (input_char === '<') { + tag_start = this.pos - 1; + } + content.push(input_char); //inserts character at-a-time (or string) + } while (input_char !== '>'); + + var tag_complete = content.join(''); + var tag_index; + if (tag_complete.indexOf(' ') !== -1) { //if there's whitespace, thats where the tag name ends + tag_index = tag_complete.indexOf(' '); + } + else { //otherwise go with the tag ending + tag_index = tag_complete.indexOf('>'); + } + var tag_check = tag_complete.substring(1, tag_index).toLowerCase(); + if (tag_complete.charAt(tag_complete.length-2) === '/' || + this.Utils.in_array(tag_check, this.Utils.single_token)) { //if this tag name is a single tag type (either in the list or has a closing /) + if ( ! peek) { + this.tag_type = 'SINGLE'; + } + } + else if (tag_check === 'script') { //for later script handling + if ( ! peek) { + this.record_tag(tag_check); + this.tag_type = 'SCRIPT'; + } + } + else if (tag_check === 'style') { //for future style handling (for now it justs uses get_content) + if ( ! peek) { + this.record_tag(tag_check); + this.tag_type = 'STYLE'; + } + } + else if (this.is_unformatted(tag_check, unformatted)) { // do not reformat the "unformatted" tags + comment = this.get_unformatted('', tag_complete); //...delegate to get_unformatted function + content.push(comment); + // Preserve collapsed whitespace either before or after this tag. + if (tag_start > 0 && this.Utils.in_array(this.input.charAt(tag_start - 1), this.Utils.whitespace)){ + content.splice(0, 0, this.input.charAt(tag_start - 1)); + } + tag_end = this.pos - 1; + if (this.Utils.in_array(this.input.charAt(tag_end + 1), this.Utils.whitespace)){ + content.push(this.input.charAt(tag_end + 1)); + } + this.tag_type = 'SINGLE'; + } + else if (tag_check.charAt(0) === '!') { //peek for so... + comment = this.get_unformatted('-->', tag_complete); //...delegate to get_unformatted + content.push(comment); + } + if ( ! peek) { + this.tag_type = 'START'; + } + } + else if (tag_check.indexOf('[endif') !== -1) {//peek for ', tag_complete); + content.push(comment); + this.tag_type = 'SINGLE'; + } + } + else if ( ! peek) { + if (tag_check.charAt(0) === '/') { //this tag is a double tag so check for tag-ending + this.retrieve_tag(tag_check.substring(1)); //remove it and all ancestors + this.tag_type = 'END'; + } + else { //otherwise it's a start-tag + this.record_tag(tag_check); //push it on the tag stack + this.tag_type = 'START'; + } + if (this.Utils.in_array(tag_check, this.Utils.extra_liners)) { //check if this double needs an extra line + this.print_newline(true, this.output); + } + } + + if (peek) { + this.pos = orig_pos; + this.line_char_count = orig_line_char_count; + } + + return content.join(''); //returns fully formatted tag + }; + + this.get_unformatted = function (delimiter, orig_tag) { //function to return unformatted content in its entirety + + if (orig_tag && orig_tag.toLowerCase().indexOf(delimiter) !== -1) { + return ''; + } + var input_char = ''; + var content = ''; + var space = true; + do { + + if (this.pos >= this.input.length) { + return content; + } + + input_char = this.input.charAt(this.pos); + this.pos++; + + if (this.Utils.in_array(input_char, this.Utils.whitespace)) { + if (!space) { + this.line_char_count--; + continue; + } + if (input_char === '\n' || input_char === '\r') { + content += '\n'; + /* Don't change tab indention for unformatted blocks. If using code for html editing, this will greatly affect
 tags if they are specified in the 'unformatted array'
+                for (var i=0; i]*>\s*$/);
+
+            // if next_tag comes back but is not an isolated tag, then
+            // let's treat the 'a' tag as having content
+            // and respect the unformatted option
+            if (!tag || this.Utils.in_array(tag, unformatted)){
+                return true;
+            } else {
+                return false;
+            }
+        };
+
+        this.printer = function (js_source, indent_character, indent_size, max_char, brace_style) { //handles input/output and some other printing functions
+
+          this.input = js_source || ''; //gets the input for the Parser
+          this.output = [];
+          this.indent_character = indent_character;
+          this.indent_string = '';
+          this.indent_size = indent_size;
+          this.brace_style = brace_style;
+          this.indent_level = 0;
+          this.max_char = max_char;
+          this.line_char_count = 0; //count to see if max_char was exceeded
+
+          for (var i=0; i 0) {
+              this.indent_level--;
+            }
+          };
+        };
+        return this;
+      }
+
+      /*_____________________--------------------_____________________*/
+
+      multi_parser = new Parser(); //wrapping functions Parser
+      multi_parser.printer(html_source, indent_character, indent_size, max_char, brace_style); //initialize starting values
+
+      while (true) {
+          var t = multi_parser.get_token();
+          multi_parser.token_text = t[0];
+          multi_parser.token_type = t[1];
+
+        if (multi_parser.token_type === 'TK_EOF') {
+          break;
+        }
+
+        switch (multi_parser.token_type) {
+          case 'TK_TAG_START':
+            multi_parser.print_newline(false, multi_parser.output);
+            multi_parser.print_token(multi_parser.token_text);
+            multi_parser.indent();
+            multi_parser.current_mode = 'CONTENT';
+            break;
+          case 'TK_TAG_STYLE':
+          case 'TK_TAG_SCRIPT':
+            multi_parser.print_newline(false, multi_parser.output);
+            multi_parser.print_token(multi_parser.token_text);
+            multi_parser.current_mode = 'CONTENT';
+            break;
+          case 'TK_TAG_END':
+            //Print new line only if the tag has no content and has child
+            if (multi_parser.last_token === 'TK_CONTENT' && multi_parser.last_text === '') {
+                var tag_name = multi_parser.token_text.match(/\w+/)[0];
+                var tag_extracted_from_last_output = multi_parser.output[multi_parser.output.length -1].match(/<\s*(\w+)/);
+                if (tag_extracted_from_last_output === null || tag_extracted_from_last_output[1] !== tag_name) {
+                    multi_parser.print_newline(true, multi_parser.output);
+                }
+            }
+            multi_parser.print_token(multi_parser.token_text);
+            multi_parser.current_mode = 'CONTENT';
+            break;
+          case 'TK_TAG_SINGLE':
+            // Don't add a newline before elements that should remain unformatted.
+            var tag_check = multi_parser.token_text.match(/^\s*<([a-z]+)/i);
+            if (!tag_check || !multi_parser.Utils.in_array(tag_check[1], unformatted)){
+                multi_parser.print_newline(false, multi_parser.output);
+            }
+            multi_parser.print_token(multi_parser.token_text);
+            multi_parser.current_mode = 'CONTENT';
+            break;
+          case 'TK_CONTENT':
+            if (multi_parser.token_text !== '') {
+              multi_parser.print_token(multi_parser.token_text);
+            }
+            multi_parser.current_mode = 'TAG';
+            break;
+          case 'TK_STYLE':
+          case 'TK_SCRIPT':
+            if (multi_parser.token_text !== '') {
+              multi_parser.output.push('\n');
+              var text = multi_parser.token_text,
+                  _beautifier,
+                  script_indent_level = 1;
+              if (multi_parser.token_type === 'TK_SCRIPT') {
+                _beautifier = typeof js_beautify === 'function' && js_beautify;
+              } else if (multi_parser.token_type === 'TK_STYLE') {
+                _beautifier = typeof css_beautify === 'function' && css_beautify;
+              }
+
+              if (options.indent_scripts === "keep") {
+                script_indent_level = 0;
+              } else if (options.indent_scripts === "separate") {
+                script_indent_level = -multi_parser.indent_level;
+              }
+
+              var indentation = multi_parser.get_full_indent(script_indent_level);
+              if (_beautifier) {
+                // call the Beautifier if avaliable
+                text = _beautifier(text.replace(/^\s*/, indentation), options);
+              } else {
+                // simply indent the string otherwise
+                var white = text.match(/^\s*/)[0];
+                var _level = white.match(/[^\n\r]*$/)[0].split(multi_parser.indent_string).length - 1;
+                var reindent = multi_parser.get_full_indent(script_indent_level -_level);
+                text = text.replace(/^\s*/, indentation)
+                       .replace(/\r\n|\r|\n/g, '\n' + reindent)
+                       .replace(/\s*$/, '');
+              }
+              if (text) {
+                multi_parser.print_token(text);
+                multi_parser.print_newline(true, multi_parser.output);
+              }
+            }
+            multi_parser.current_mode = 'TAG';
+            break;
+        }
+        multi_parser.last_token = multi_parser.token_type;
+        multi_parser.last_text = multi_parser.token_text;
+      }
+      return multi_parser.output.join('');
+    }
+
+    // If we're running a web page and don't have either of the above, add our one global
+    window.html_beautify = function(html_source, options) {
+        return style_html(html_source, options, window.js_beautify, window.css_beautify);
+    };
+
+}());
diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/blockUI/jquery.blockUI.js b/ruoyi-admin/src/main/resources/static/ajax/libs/blockUI/jquery.blockUI.js
new file mode 100644
index 000000000..552613d96
--- /dev/null
+++ b/ruoyi-admin/src/main/resources/static/ajax/libs/blockUI/jquery.blockUI.js
@@ -0,0 +1,620 @@
+锘/*!
+ * jQuery blockUI plugin
+ * Version 2.70.0-2014.11.23
+ * Requires jQuery v1.7 or later
+ *
+ * Examples at: http://malsup.com/jquery/block/
+ * Copyright (c) 2007-2013 M. Alsup
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * Thanks to Amir-Hossein Sobhi for some excellent contributions!
+ */
+
+;(function() {
+/*jshint eqeqeq:false curly:false latedef:false */
+"use strict";
+
+	function setup($) {
+		$.fn._fadeIn = $.fn.fadeIn;
+
+		var noOp = $.noop || function() {};
+
+		// this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle
+		// confusing userAgent strings on Vista)
+		var msie = /MSIE/.test(navigator.userAgent);
+		var ie6  = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent);
+		var mode = document.documentMode || 0;
+		var setExpr = $.isFunction( document.createElement('div').style.setExpression );
+
+		// global $ methods for blocking/unblocking the entire page
+		$.blockUI   = function(opts) { install(window, opts); };
+		$.unblockUI = function(opts) { remove(window, opts); };
+
+		// convenience method for quick growl-like notifications  (http://www.google.com/search?q=growl)
+		$.growlUI = function(title, message, timeout, onClose) {
+			var $m = $('
'); + if (title) $m.append('

'+title+'

'); + if (message) $m.append('

'+message+'

'); + if (timeout === undefined) timeout = 3000; + + // Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications + var callBlock = function(opts) { + opts = opts || {}; + + $.blockUI({ + message: $m, + fadeIn : typeof opts.fadeIn !== 'undefined' ? opts.fadeIn : 700, + fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000, + timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout, + centerY: false, + showOverlay: false, + onUnblock: onClose, + css: $.blockUI.defaults.growlCSS + }); + }; + + callBlock(); + var nonmousedOpacity = $m.css('opacity'); + $m.mouseover(function() { + callBlock({ + fadeIn: 0, + timeout: 30000 + }); + + var displayBlock = $('.blockMsg'); + displayBlock.stop(); // cancel fadeout if it has started + displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency + }).mouseout(function() { + $('.blockMsg').fadeOut(1000); + }); + // End konapun additions + }; + + // plugin method for blocking element content + $.fn.block = function(opts) { + if ( this[0] === window ) { + $.blockUI( opts ); + return this; + } + var fullOpts = $.extend({}, $.blockUI.defaults, opts || {}); + this.each(function() { + var $el = $(this); + if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked')) + return; + $el.unblock({ fadeOut: 0 }); + }); + + return this.each(function() { + if ($.css(this,'position') == 'static') { + this.style.position = 'relative'; + $(this).data('blockUI.static', true); + } + this.style.zoom = 1; // force 'hasLayout' in ie + install(this, opts); + }); + }; + + // plugin method for unblocking element content + $.fn.unblock = function(opts) { + if ( this[0] === window ) { + $.unblockUI( opts ); + return this; + } + return this.each(function() { + remove(this, opts); + }); + }; + + $.blockUI.version = 2.70; // 2nd generation blocking at no extra cost! + + // override these in your code to change the default behavior and style + $.blockUI.defaults = { + // message displayed when blocking (use null for no message) + message: '
鍔犺浇涓......
', + + title: null, // title string; only used when theme == true + draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded) + + theme: false, // set to true to use with jQuery UI themes + + // styles for the message when blocking; if you wish to disable + // these and use an external stylesheet then do this in your code: + // $.blockUI.defaults.css = {}; + css: { + padding: 0, + margin: 0, + width: '30%', + top: '40%', + left: '35%', + textAlign: 'center', + color: '#000', + border: '0px', + backgroundColor:'transparent', + cursor: 'wait' + }, + + // minimal style set used when themes are used + themedCSS: { + width: '30%', + top: '40%', + left: '35%' + }, + + // styles for the overlay + overlayCSS: { + backgroundColor: '#000', + opacity: 0.6, + cursor: 'wait' + }, + + // style to replace wait cursor before unblocking to correct issue + // of lingering wait cursor + cursorReset: 'default', + + // styles applied when using $.growlUI + growlCSS: { + width: '350px', + top: '10px', + left: '', + right: '10px', + border: 'none', + padding: '5px', + opacity: 0.6, + cursor: 'default', + color: '#fff', + backgroundColor: '#000', + '-webkit-border-radius':'10px', + '-moz-border-radius': '10px', + 'border-radius': '10px' + }, + + // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w + // (hat tip to Jorge H. N. de Vasconcelos) + /*jshint scripturl:true */ + iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank', + + // force usage of iframe in non-IE browsers (handy for blocking applets) + forceIframe: false, + + // z-index for the blocking overlay + baseZ: 1000, + + // set these to true to have the message automatically centered + centerX: true, // <-- only effects element blocking (page block controlled via css above) + centerY: true, + + // allow body element to be stetched in ie6; this makes blocking look better + // on "short" pages. disable if you wish to prevent changes to the body height + allowBodyStretch: true, + + // enable if you want key and mouse events to be disabled for content that is blocked + bindEvents: true, + + // be default blockUI will supress tab navigation from leaving blocking content + // (if bindEvents is true) + constrainTabKey: true, + + // fadeIn time in millis; set to 0 to disable fadeIn on block + fadeIn: 200, + + // fadeOut time in millis; set to 0 to disable fadeOut on unblock + fadeOut: 400, + + // time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock + timeout: 0, + + // disable if you don't want to show the overlay + showOverlay: true, + + // if true, focus will be placed in the first available input field when + // page blocking + focusInput: true, + + // elements that can receive focus + focusableElements: ':input:enabled:visible', + + // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity) + // no longer needed in 2012 + // applyPlatformOpacityRules: true, + + // callback method invoked when fadeIn has completed and blocking message is visible + onBlock: null, + + // callback method invoked when unblocking has completed; the callback is + // passed the element that has been unblocked (which is the window object for page + // blocks) and the options that were passed to the unblock call: + // onUnblock(element, options) + onUnblock: null, + + // callback method invoked when the overlay area is clicked. + // setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used. + onOverlayClick: null, + + // don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493 + quirksmodeOffsetHack: 4, + + // class name of the message block + blockMsgClass: 'blockMsg', + + // if it is already blocked, then ignore it (don't unblock and reblock) + ignoreIfBlocked: false + }; + + // private data and functions follow... + + var pageBlock = null; + var pageBlockEls = []; + + function install(el, opts) { + var css, themedCSS; + var full = (el == window); + var msg = (opts && opts.message !== undefined ? opts.message : undefined); + opts = $.extend({}, $.blockUI.defaults, opts || {}); + + if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked')) + return; + + opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {}); + css = $.extend({}, $.blockUI.defaults.css, opts.css || {}); + if (opts.onOverlayClick) + opts.overlayCSS.cursor = 'pointer'; + + themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {}); + msg = msg === undefined ? opts.message : msg; + + // remove the current block (if there is one) + if (full && pageBlock) + remove(window, {fadeOut:0}); + + // if an existing element is being used as the blocking content then we capture + // its current place in the DOM (and current display style) so we can restore + // it when we unblock + if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) { + var node = msg.jquery ? msg[0] : msg; + var data = {}; + $(el).data('blockUI.history', data); + data.el = node; + data.parent = node.parentNode; + data.display = node.style.display; + data.position = node.style.position; + if (data.parent) + data.parent.removeChild(node); + } + + $(el).data('blockUI.onUnblock', opts.onUnblock); + var z = opts.baseZ; + + // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform; + // layer1 is the iframe layer which is used to supress bleed through of underlying content + // layer2 is the overlay layer which has opacity and a wait cursor (by default) + // layer3 is the message content that is displayed while blocking + var lyr1, lyr2, lyr3, s; + if (msie || opts.forceIframe) + lyr1 = $(''); + else + lyr1 = $(''); + + if (opts.theme) + lyr2 = $(''); + else + lyr2 = $(''); + + if (opts.theme && full) { + s = ''; + } + else if (opts.theme) { + s = ''; + } + else if (full) { + s = ''; + } + else { + s = ''; + } + lyr3 = $(s); + + // if we have a message, style it + if (msg) { + if (opts.theme) { + lyr3.css(themedCSS); + lyr3.addClass('ui-widget-content'); + } + else + lyr3.css(css); + } + + // style the overlay + if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/) + lyr2.css(opts.overlayCSS); + lyr2.css('position', full ? 'fixed' : 'absolute'); + + // make iframe layer transparent in IE + if (msie || opts.forceIframe) + lyr1.css('opacity',0.0); + + //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el); + var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el); + $.each(layers, function() { + this.appendTo($par); + }); + + if (opts.theme && opts.draggable && $.fn.draggable) { + lyr3.draggable({ + handle: '.ui-dialog-titlebar', + cancel: 'li' + }); + } + + // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling) + var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0); + if (ie6 || expr) { + // give body 100% height + if (full && opts.allowBodyStretch && $.support.boxModel) + $('html,body').css('height','100%'); + + // fix ie6 issue when blocked element has a border width + if ((ie6 || !$.support.boxModel) && !full) { + var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth'); + var fixT = t ? '(0 - '+t+')' : 0; + var fixL = l ? '(0 - '+l+')' : 0; + } + + // simulate fixed position + $.each(layers, function(i,o) { + var s = o[0].style; + s.position = 'absolute'; + if (i < 2) { + if (full) + s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"'); + else + s.setExpression('height','this.parentNode.offsetHeight + "px"'); + if (full) + s.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"'); + else + s.setExpression('width','this.parentNode.offsetWidth + "px"'); + if (fixL) s.setExpression('left', fixL); + if (fixT) s.setExpression('top', fixT); + } + else if (opts.centerY) { + if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"'); + s.marginTop = 0; + } + else if (!opts.centerY && full) { + var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0; + var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"'; + s.setExpression('top',expression); + } + }); + } + + // show the message + if (msg) { + if (opts.theme) + lyr3.find('.ui-widget-content').append(msg); + else + lyr3.append(msg); + if (msg.jquery || msg.nodeType) + $(msg).show(); + } + + if ((msie || opts.forceIframe) && opts.showOverlay) + lyr1.show(); // opacity is zero + if (opts.fadeIn) { + var cb = opts.onBlock ? opts.onBlock : noOp; + var cb1 = (opts.showOverlay && !msg) ? cb : noOp; + var cb2 = msg ? cb : noOp; + if (opts.showOverlay) + lyr2._fadeIn(opts.fadeIn, cb1); + if (msg) + lyr3._fadeIn(opts.fadeIn, cb2); + } + else { + if (opts.showOverlay) + lyr2.show(); + if (msg) + lyr3.show(); + if (opts.onBlock) + opts.onBlock.bind(lyr3)(); + } + + // bind key and mouse events + bind(1, el, opts); + + if (full) { + pageBlock = lyr3[0]; + pageBlockEls = $(opts.focusableElements,pageBlock); + if (opts.focusInput) + setTimeout(focus, 20); + } + else + center(lyr3[0], opts.centerX, opts.centerY); + + if (opts.timeout) { + // auto-unblock + var to = setTimeout(function() { + if (full) + $.unblockUI(opts); + else + $(el).unblock(opts); + }, opts.timeout); + $(el).data('blockUI.timeout', to); + } + } + + // remove the block + function remove(el, opts) { + var count; + var full = (el == window); + var $el = $(el); + var data = $el.data('blockUI.history'); + var to = $el.data('blockUI.timeout'); + if (to) { + clearTimeout(to); + $el.removeData('blockUI.timeout'); + } + opts = $.extend({}, $.blockUI.defaults, opts || {}); + bind(0, el, opts); // unbind events + + if (opts.onUnblock === null) { + opts.onUnblock = $el.data('blockUI.onUnblock'); + $el.removeData('blockUI.onUnblock'); + } + + var els; + if (full) // crazy selector to handle odd field errors in ie6/7 + els = $('body').children().filter('.blockUI').add('body > .blockUI'); + else + els = $el.find('>.blockUI'); + + // fix cursor issue + if ( opts.cursorReset ) { + if ( els.length > 1 ) + els[1].style.cursor = opts.cursorReset; + if ( els.length > 2 ) + els[2].style.cursor = opts.cursorReset; + } + + if (full) + pageBlock = pageBlockEls = null; + + if (opts.fadeOut) { + count = els.length; + els.stop().fadeOut(opts.fadeOut, function() { + if ( --count === 0) + reset(els,data,opts,el); + }); + } + else + reset(els, data, opts, el); + } + + // move blocking element back into the DOM where it started + function reset(els,data,opts,el) { + var $el = $(el); + if ( $el.data('blockUI.isBlocked') ) + return; + + els.each(function(i,o) { + // remove via DOM calls so we don't lose event handlers + if (this.parentNode) + this.parentNode.removeChild(this); + }); + + if (data && data.el) { + data.el.style.display = data.display; + data.el.style.position = data.position; + data.el.style.cursor = 'default'; // #59 + if (data.parent) + data.parent.appendChild(data.el); + $el.removeData('blockUI.history'); + } + + if ($el.data('blockUI.static')) { + $el.css('position', 'static'); // #22 + } + + if (typeof opts.onUnblock == 'function') + opts.onUnblock(el,opts); + + // fix issue in Safari 6 where block artifacts remain until reflow + var body = $(document.body), w = body.width(), cssW = body[0].style.width; + body.width(w-1).width(w); + body[0].style.width = cssW; + } + + // bind/unbind the handler + function bind(b, el, opts) { + var full = el == window, $el = $(el); + + // don't bother unbinding if there is nothing to unbind + if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked'))) + return; + + $el.data('blockUI.isBlocked', b); + + // don't bind events when overlay is not in use or if bindEvents is false + if (!full || !opts.bindEvents || (b && !opts.showOverlay)) + return; + + // bind anchors and inputs for mouse and key events + var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove'; + if (b) + $(document).bind(events, opts, handler); + else + $(document).unbind(events, handler); + + // former impl... + // var $e = $('a,:input'); + // b ? $e.bind(events, opts, handler) : $e.unbind(events, handler); + } + + // event handler to suppress keyboard/mouse events when blocking + function handler(e) { + // allow tab navigation (conditionally) + if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) { + if (pageBlock && e.data.constrainTabKey) { + var els = pageBlockEls; + var fwd = !e.shiftKey && e.target === els[els.length-1]; + var back = e.shiftKey && e.target === els[0]; + if (fwd || back) { + setTimeout(function(){focus(back);},10); + return false; + } + } + } + var opts = e.data; + var target = $(e.target); + if (target.hasClass('blockOverlay') && opts.onOverlayClick) + opts.onOverlayClick(e); + + // allow events within the message content + if (target.parents('div.' + opts.blockMsgClass).length > 0) + return true; + + // allow events for content that is not being blocked + return target.parents().children().filter('div.blockUI').length === 0; + } + + function focus(back) { + if (!pageBlockEls) + return; + var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0]; + if (e) + e.focus(); + } + + function center(el, x, y) { + var p = el.parentNode, s = el.style; + var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth'); + var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth'); + if (x) s.left = l > 0 ? (l+'px') : '0'; + if (y) s.top = t > 0 ? (t+'px') : '0'; + } + + function sz(el, p) { + return parseInt($.css(el,p),10)||0; + } + + } + + + /*global define:true */ + if (typeof define === 'function' && define.amd && define.amd.jQuery) { + define(['jquery'], setup); + } else { + setup(jQuery); + } + +})(); \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.css b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.css new file mode 100644 index 000000000..0f27a5f5b --- /dev/null +++ b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.css @@ -0,0 +1,671 @@ +/*! + * bootstrap-fileinput v5.2.4 + * http://plugins.krajee.com/file-input + * + * Krajee default styling for bootstrap-fileinput. + * + * Author: Kartik Visweswaran + * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com + * + * Licensed under the BSD-3-Clause + * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md + */ + +.file-loading input[type=file], +input[type=file].file-loading { + width: 0; + height: 0; +} + +.file-no-browse { + position: absolute; + left: 50%; + bottom: 20%; + width: 1px; + height: 1px; + font-size: 0; + opacity: 0; + border: none; + background: none; + outline: none; + box-shadow: none; +} + +.kv-hidden, +.file-caption-icon, +.file-zoom-dialog .modal-header:before, +.file-zoom-dialog .modal-header:after, +.file-input-new .file-preview, +.file-input-new .close, +.file-input-new .glyphicon-file, +.file-input-new .fileinput-remove-button, +.file-input-new .fileinput-upload-button, +.file-input-new .no-browse .input-group-btn, +.file-input-ajax-new .fileinput-remove-button, +.file-input-ajax-new .fileinput-upload-button, +.file-input-ajax-new .no-browse .input-group-btn, +.hide-content .kv-file-content, +.is-locked .fileinput-upload-button, +.is-locked .fileinput-remove-button { + display: none; +} + +.btn-file input[type=file], +.file-caption-icon, +.file-preview .fileinput-remove, +.krajee-default .file-thumb-progress, +.file-zoom-dialog .btn-navigate, +.file-zoom-dialog .floating-buttons { + position: absolute; +} + +.file-caption-icon .kv-caption-icon { + line-height: inherit; +} + +.file-input, +.file-loading:before, +.btn-file, +.file-caption, +.file-preview, +.krajee-default.file-preview-frame, +.krajee-default .file-thumbnail-footer, +.file-zoom-dialog .modal-dialog { + position: relative; +} + +.file-error-message pre, +.file-error-message ul, +.krajee-default .file-actions, +.krajee-default .file-other-error { + text-align: left; +} + +.file-error-message pre, +.file-error-message ul { + margin: 0; +} + +.krajee-default .file-drag-handle, +.krajee-default .file-upload-indicator { + float: left; + margin-top: 10px; + width: 16px; + height: 16px; +} + +.file-thumb-progress .progress, +.file-thumb-progress .progress-bar { + font-family: Verdana, Helvetica, sans-serif; + font-size: 0.7rem; +} + +.krajee-default .file-thumb-progress .progress, +.kv-upload-progress .progress { + background-color: #ccc; +} + +.krajee-default .file-caption-info, +.krajee-default .file-size-info { + display: block; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + width: 160px; + height: 15px; + margin: auto; +} + +.file-zoom-content > .file-object.type-video, +.file-zoom-content > .file-object.type-flash, +.file-zoom-content > .file-object.type-image { + max-width: 100%; + max-height: 100%; + width: auto; +} + +.file-zoom-content > .file-object.type-video, +.file-zoom-content > .file-object.type-flash { + height: 100%; +} + +.file-zoom-content > .file-object.type-pdf, +.file-zoom-content > .file-object.type-html, +.file-zoom-content > .file-object.type-text, +.file-zoom-content > .file-object.type-default { + width: 100%; +} + +.file-loading:before { + content: " Loading..."; + display: inline-block; + padding-left: 20px; + line-height: 16px; + font-size: 13px; + font-variant: small-caps; + color: #999; + background: transparent url(loading.gif) top left no-repeat; +} + +.file-object { + margin: 0 0 -5px 0; + padding: 0; +} + +.btn-file { + overflow: hidden; +} + +.btn-file input[type=file] { + top: 0; + left: 0; + min-width: 100%; + min-height: 100%; + text-align: right; + opacity: 0; + background: none repeat scroll 0 0 transparent; + cursor: inherit; + display: block; +} + +.btn-file ::-ms-browse { + font-size: 10000px; + width: 100%; + height: 100%; +} + +.file-caption.icon-visible .file-caption-icon { + display: inline-block; +} + +.file-caption.icon-visible .file-caption-name { + padding-left: 25px; +} + +.file-caption.icon-visible > .input-group-lg .file-caption-name { + padding-left: 30px; +} + +.file-caption.icon-visible > .input-group-sm .file-caption-name { + padding-left: 22px; +} + +.file-caption-name:not(.file-caption-disabled) { + background-color: transparent; +} + +.file-caption-name.file-processing { + font-style: italic; + border-color: #bbb; + opacity: 0.5; +} + +.file-caption-icon { + padding: 7px 5px; + left: 4px; +} + +.input-group-lg .file-caption-icon { + font-size: 1.25rem; +} + +.input-group-sm .file-caption-icon { + font-size: 0.875rem; + padding: 0.25rem; +} + +.file-error-message { + color: #a94442; + background-color: #f2dede; + margin: 5px; + border: 1px solid #ebccd1; + border-radius: 4px; + padding: 15px; +} + +.file-error-message pre { + margin: 5px 0; +} + +.file-caption-disabled { + background-color: #eee; + cursor: not-allowed; + opacity: 1; +} + +.file-preview { + border-radius: 5px; + border: 1px solid #ddd; + padding: 8px; + width: 100%; + margin-bottom: 5px; +} + +.file-preview .btn-xs { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} + +.file-preview .fileinput-remove { + top: 1px; + right: 1px; + line-height: 10px; +} + +.file-preview .clickable { + cursor: pointer; +} + +.file-preview-image { + font: 40px Impact, Charcoal, sans-serif; + color: #008000; + width: auto; + height: auto; + max-width: 100%; + max-height: 100%; +} + +.krajee-default.file-preview-frame { + margin: 8px; + border: 1px solid rgba(0, 0, 0, 0.2); + box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2); + padding: 6px; + float: left; + text-align: center; +} + +.krajee-default.file-preview-frame .kv-file-content { + width: 213px; + height: 160px; +} + +.krajee-default .file-preview-other-frame { + display: flex; + align-items: center; + justify-content: center; +} + +.krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered { + width: 400px; +} + +.krajee-default.file-preview-frame[data-template="audio"] .kv-file-content { + width: 240px; + height: 55px; +} + +.krajee-default.file-preview-frame .file-thumbnail-footer { + height: 70px; +} + +.krajee-default.file-preview-frame:not(.file-preview-error):hover { + border: 1px solid rgba(0, 0, 0, 0.3); + box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.4); +} + +.krajee-default .file-preview-text { + color: #428bca; + border: 1px solid #ddd; + outline: none; + resize: none; +} + +.krajee-default .file-preview-html { + border: 1px solid #ddd; +} + +.krajee-default .file-other-icon { + font-size: 6em; + line-height: 1; +} + +.krajee-default .file-footer-buttons { + float: right; +} + +.krajee-default .file-footer-caption { + display: block; + text-align: center; + padding-top: 4px; + font-size: 11px; + color: #777; + margin-bottom: 30px; +} + +.file-upload-stats { + font-size: 10px; + text-align: center; + width: 100%; +} + +.kv-upload-progress .file-upload-stats { + font-size: 12px; + margin: -10px 0 5px; +} + +.krajee-default .file-preview-error { + opacity: 0.65; + box-shadow: none; +} + +.krajee-default .file-thumb-progress { + top: 37px; + left: 0; + right: 0; +} + +.krajee-default.kvsortable-ghost { + background: #e1edf7; + border: 2px solid #a1abff; +} + +.krajee-default .file-preview-other:hover { + opacity: 0.8; +} + +.krajee-default .file-preview-frame:not(.file-preview-error) .file-footer-caption:hover { + color: #000; +} + +.kv-upload-progress .progress { + height: 20px; + margin: 10px 0; + overflow: hidden; +} + +.kv-upload-progress .progress-bar { + height: 20px; + font-family: Verdana, Helvetica, sans-serif; +} + + +/*noinspection CssOverwrittenProperties*/ + +.file-zoom-dialog .file-other-icon { + font-size: 22em; + font-size: 50vmin; +} + +.file-zoom-dialog .modal-dialog { + width: auto; +} + +.file-zoom-dialog .modal-header { + display: flex; + align-items: center; + justify-content: space-between; +} + +.file-zoom-dialog .btn-navigate { + margin: 0 0.1rem; + padding: 0; + font-size: 1.2rem; + width: 2.4rem; + height: 2.4rem; + top: 50%; + border-radius: 50%; + text-align:center; +} + +.btn-navigate * { + width: auto; +} + +.file-zoom-dialog .floating-buttons { + top: 5px; + right: 10px; +} + +.file-zoom-dialog .btn-kv-prev { + left: 0; +} + +.file-zoom-dialog .btn-kv-next { + right: 0; +} + +.file-zoom-dialog .kv-zoom-caption { + max-width: 50%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.file-zoom-dialog .kv-zoom-header { + padding: 0.5rem; +} + +.file-zoom-dialog .kv-zoom-body { + padding: 0.25rem 0.5rem 0.25rem 0; +} + +.file-zoom-dialog .kv-zoom-description { + position: absolute; + opacity: 0.8; + font-size: 0.8rem; + background-color: #1a1a1a; + padding: 1rem; + text-align: center; + border-radius: 0.5rem; + color: #fff; + left: 15%; + right: 15%; + bottom: 15%; +} + +.file-zoom-dialog .kv-desc-hide { + float: right; + color: #fff; + padding: 0 0.1rem; + background: none; + border: none; +} + +.file-zoom-dialog .kv-desc-hide:hover { + opacity: 0.7; +} + +.file-zoom-dialog .kv-desc-hide:focus { + opacity: 0.9; +} + +.file-input-new .no-browse .form-control { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} + +.file-input-ajax-new .no-browse .form-control { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} + +.file-caption { + width: 100%; + position: relative; +} + +.file-thumb-loading { + background: transparent url(loading.gif) no-repeat scroll center center content-box !important; +} + +.file-drop-zone { + border: 1px dashed #aaa; + min-height: 260px; + border-radius: 4px; + text-align: center; + vertical-align: middle; + margin: 12px 15px 12px 12px; + padding: 5px; +} + +.file-drop-zone.clickable:hover { + border: 2px dashed #999; +} + +.file-drop-zone.clickable:focus { + border: 2px solid #5acde2; +} + +.file-drop-zone .file-preview-thumbnails { + cursor: default; +} + +.file-drop-zone-title { + color: #aaa; + font-size: 1.6em; + text-align: center; + padding: 85px 10px; + cursor: default; +} + +.file-highlighted { + border: 2px dashed #999 !important; + background-color: #eee; +} + +.file-uploading { + background: url(loading-sm.gif) no-repeat center bottom 10px; + opacity: 0.65; +} + +.file-zoom-fullscreen .modal-dialog { + min-width: 100%; + margin: 0; +} + +.file-zoom-fullscreen .modal-content { + border-radius: 0; + box-shadow: none; + min-height: 100vh; +} + +.file-zoom-fullscreen .kv-zoom-body { + overflow-y: auto; +} + +.floating-buttons { + z-index: 3000; +} + +.floating-buttons .btn-kv { + margin-left: 3px; + z-index: 3000; +} + +.kv-zoom-actions .btn-kv { + margin-left: 3px; +} + +.file-zoom-content { + text-align: center; + white-space: nowrap; + min-height: 300px; +} + +.file-zoom-content:hover { + background: transparent; +} + +.file-zoom-content > * { + display: inline-block; + vertical-align: middle; +} + +.file-zoom-content .kv-spacer { + height: 100%; +} + +.file-zoom-content .file-preview-image { + max-height: 100%; +} + +.file-zoom-content .file-preview-video { + max-height: 100%; +} + +.file-zoom-content > .file-object.type-image { + height: auto; + min-height: inherit; +} + +.file-zoom-content > .file-object.type-audio { + width: auto; + height: 30px; +} + +@media (min-width: 576px) { + .file-zoom-dialog .modal-dialog { + max-width: 500px; + } +} + +@media (min-width: 992px) { + .file-zoom-dialog .modal-lg { + max-width: 800px; + } +} + +@media (max-width: 767px) { + .file-preview-thumbnails { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + } + + .file-zoom-dialog .modal-header { + flex-direction: column; + } +} + +@media (max-width: 350px) { + .krajee-default.file-preview-frame:not([data-template="audio"]) .kv-file-content { + width: 160px; + } +} + +@media (max-width: 420px) { + .krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered { + width: 100%; + } +} + +.file-loading[dir=rtl]:before { + background: transparent url(loading.gif) top right no-repeat; + padding-left: 0; + padding-right: 20px; +} + +.clickable .file-drop-zone-title { + cursor: pointer; +} + +.file-sortable .file-drag-handle:hover { + opacity: 0.7; +} + +.file-sortable .file-drag-handle { + cursor: grab; + opacity: 1; +} + +.file-grabbing, +.file-grabbing * { + cursor: not-allowed !important; +} + +.file-grabbing .file-preview-thumbnails * { + cursor: grabbing !important; +} + +.file-preview-frame.sortable-chosen { + background-color: #d9edf7; + border-color: #17a2b8; + box-shadow: none !important; +} + +.file-preview .kv-zoom-cache { + display: none; +} \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.js b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.js new file mode 100644 index 000000000..f52cf3d79 --- /dev/null +++ b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.js @@ -0,0 +1,6404 @@ +/*! + * bootstrap-fileinput v5.2.4 + * http://plugins.krajee.com/file-input + * + * Author: Kartik Visweswaran + * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com + * + * Licensed under the BSD-3-Clause + * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md + */ +(function (factory) { + 'use strict'; + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else { + if (typeof module === 'object' && module.exports) { + //noinspection NpmUsedModulesInstalled + module.exports = factory(require('jquery')); + } else { + factory(window.jQuery); + } + } +}(function ($) { + 'use strict'; + $.fn.fileinputLocales = {}; + $.fn.fileinputThemes = {}; + if (!$.fn.fileinputBsVersion) { + $.fn.fileinputBsVersion = (window.Alert && window.Alert.VERSION) || + (window.bootstrap && window.bootstrap.Alert && bootstrap.Alert.VERSION) || '3.x.x'; + } + String.prototype.setTokens = function (replacePairs) { + var str = this.toString(), key, re; + for (key in replacePairs) { + if (replacePairs.hasOwnProperty(key)) { + re = new RegExp('\{' + key + '\}', 'g'); + str = str.replace(re, replacePairs[key]); + } + } + return str; + }; + + if (!Array.prototype.flatMap) { // polyfill flatMap + Array.prototype.flatMap = function (lambda) { + return [].concat(this.map(lambda)); + }; + } + + if (!document.currentScript) { + document.currentScript = function() { + var scripts = document.getElementsByTagName('script'); + return scripts[scripts.length - 1]; + }(); + } + + var $h, FileInput, getLoadingUrl = function () { + var src = document.currentScript.src, srcPath = src.substring(0, src.lastIndexOf("/")); + return srcPath + '/loading.gif' + }; + + // fileinput helper object for all global variables and internal helper methods + $h = { + FRAMES: '.kv-preview-thumb', + SORT_CSS: 'file-sortable', + INIT_FLAG: 'init-', + ZOOM_VAR: getLoadingUrl() + '?kvTemp__2873389129__=', // used to prevent 404 errors in URL parsing + OBJECT_PARAMS: '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n', + DEFAULT_PREVIEW: '
\n' + + '{previewFileIcon}\n' + + '
', + MODAL_ID: 'kvFileinputModal', + MODAL_EVENTS: ['show', 'shown', 'hide', 'hidden', 'loaded'], + logMessages: { + ajaxError: '{status}: {error}. Error Details: {text}.', + badDroppedFiles: 'Error scanning dropped files!', + badExifParser: 'Error loading the piexif.js library. {details}', + badInputType: 'The input "type" must be set to "file" for initializing the "bootstrap-fileinput" plugin.', + exifWarning: 'To avoid this warning, either set "autoOrientImage" to "false" OR ensure you have loaded ' + + 'the "piexif.js" library correctly on your page before the "fileinput.js" script.', + invalidChunkSize: 'Invalid upload chunk size: "{chunkSize}". Resumable uploads are disabled.', + invalidThumb: 'Invalid thumb frame with id: "{id}".', + noResumableSupport: 'The browser does not support resumable or chunk uploads.', + noUploadUrl: 'The "uploadUrl" is not set. Ajax uploads and resumable uploads have been disabled.', + retryStatus: 'Retrying upload for chunk # {chunk} for {filename}... retry # {retry}.', + chunkQueueError: 'Could not push task to ajax pool for chunk index # {index}.', + resumableMaxRetriesReached: 'Maximum resumable ajax retries ({n}) reached.', + resumableRetryError: 'Could not retry the resumable request (try # {n})... aborting.', + resumableAborting: 'Aborting / cancelling the resumable request.', + resumableRequestError: 'Error processing resumable request. {msg}' + + }, + objUrl: window.URL || window.webkitURL, + isBs: function (ver) { + var chk = $.trim(($.fn.fileinputBsVersion || '') + ''); + ver = parseInt(ver, 10); + if (!chk) { + return ver === 4; + } + return ver === parseInt(chk.charAt(0), 10); + + }, + defaultButtonCss: function (fill) { + return 'btn-default btn-' + (fill ? '' : 'outline-') + 'secondary'; + }, + now: function () { + return new Date().getTime(); + }, + round: function (num) { + num = parseFloat(num); + return isNaN(num) ? 0 : Math.floor(Math.round(num)); + }, + getArray: function (obj) { + var i, arr = [], len = obj && obj.length || 0; + for (i = 0; i < len; i++) { + arr.push(obj[i]); + } + return arr; + }, + getFileRelativePath: function (file) { + /** @namespace file.relativePath */ + /** @namespace file.webkitRelativePath */ + return String(file.newPath || file.relativePath || file.webkitRelativePath || $h.getFileName(file) || null); + + }, + getFileId: function (file, generateFileId) { + var relativePath = $h.getFileRelativePath(file); + if (typeof generateFileId === 'function') { + return generateFileId(file); + } + if (!file) { + return null; + } + if (!relativePath) { + return null; + } + return (file.size + '_' + encodeURIComponent(relativePath).replace(/%/g, '_')); + }, + getFrameSelector: function (id, selector) { + selector = selector || ''; + return '[id="' + id + '"]' + selector; + }, + getZoomSelector: function (id, selector) { + return $h.getFrameSelector('zoom-' + id, selector); + }, + getFrameElement: function ($element, id, selector) { + return $element.find($h.getFrameSelector(id, selector)); + }, + getZoomElement: function ($element, id, selector) { + return $element.find($h.getZoomSelector(id, selector)); + }, + getElapsed: function (seconds) { + var delta = seconds, out = '', result = {}, structure = { + year: 31536000, + month: 2592000, + week: 604800, // uncomment row to ignore + day: 86400, // feel free to add your own row + hour: 3600, + minute: 60, + second: 1 + }; + $h.getObjectKeys(structure).forEach(function (key) { + result[key] = Math.floor(delta / structure[key]); + delta -= result[key] * structure[key]; + }); + $.each(result, function (key, value) { + if (value > 0) { + out += (out ? ' ' : '') + value + key.substring(0, 1); + } + }); + return out; + }, + debounce: function (func, delay) { + var inDebounce; + return function () { + var args = arguments, context = this; + clearTimeout(inDebounce); + inDebounce = setTimeout(function () { + func.apply(context, args); + }, delay); + }; + }, + stopEvent: function (e) { + e.stopPropagation(); + e.preventDefault(); + }, + getFileName: function (file) { + /** @namespace file.fileName */ + return file ? (file.fileName || file.name || '') : ''; // some confusion in different versions of Firefox + }, + createObjectURL: function (data) { + if ($h.objUrl && $h.objUrl.createObjectURL && data) { + return $h.objUrl.createObjectURL(data); + } + return ''; + }, + revokeObjectURL: function (data) { + if ($h.objUrl && $h.objUrl.revokeObjectURL && data) { + $h.objUrl.revokeObjectURL(data); + } + }, + compare: function (input, str, exact) { + return input !== undefined && (exact ? input === str : input.match(str)); + }, + isIE: function (ver) { + var div, status; + // check for IE versions < 11 + if (navigator.appName !== 'Microsoft Internet Explorer') { + return false; + } + if (ver === 10) { + return new RegExp('msie\\s' + ver, 'i').test(navigator.userAgent); + } + div = document.createElement('div'); + div.innerHTML = ''; + status = div.getElementsByTagName('i').length; + document.body.appendChild(div); + div.parentNode.removeChild(div); + return status; + }, + canOrientImage: function ($el) { + var $img = $(document.createElement('img')).css({width: '1px', height: '1px'}).insertAfter($el), + flag = $img.css('image-orientation'); + $img.remove(); + return !!flag; + }, + canAssignFilesToInput: function () { + var input = document.createElement('input'); + try { + input.type = 'file'; + input.files = null; + return true; + } catch (err) { + return false; + } + }, + getDragDropFolders: function (items) { + var i, item, len = items ? items.length : 0, folders = 0; + if (len > 0 && items[0].webkitGetAsEntry()) { + for (i = 0; i < len; i++) { + item = items[i].webkitGetAsEntry(); + if (item && item.isDirectory) { + folders++; + } + } + } + return folders; + }, + initModal: function ($modal) { + var $body = $('body'); + if ($body.length) { + $modal.appendTo($body); + } + }, + isFunction: function (v) { + return typeof v === 'function'; + }, + isEmpty: function (value, trim) { + if (value === undefined || value === null || value === '') { + return true; + } + if ($h.isString(value) && trim) { + return $.trim(value) === ''; + } + if ($h.isArray(value)) { + return value.length === 0; + } + if ($.isPlainObject(value) && $.isEmptyObject(value)) { + return true + } + return false; + }, + isArray: function (a) { + return Array.isArray(a) || Object.prototype.toString.call(a) === '[object Array]'; + }, + isString: function (a) { + return Object.prototype.toString.call(a) === '[object String]'; + }, + ifSet: function (needle, haystack, def) { + def = def || ''; + return (haystack && typeof haystack === 'object' && needle in haystack) ? haystack[needle] : def; + }, + cleanArray: function (arr) { + if (!(arr instanceof Array)) { + arr = []; + } + return arr.filter(function (e) { + return (e !== undefined && e !== null); + }); + }, + spliceArray: function (arr, index, reverseOrder) { + var i, j = 0, out = [], newArr; + if (!(arr instanceof Array)) { + return []; + } + newArr = $.extend(true, [], arr); + if (reverseOrder) { + newArr.reverse(); + } + for (i = 0; i < newArr.length; i++) { + if (i !== index) { + out[j] = newArr[i]; + j++; + } + } + if (reverseOrder) { + out.reverse(); + } + return out; + }, + getNum: function (num, def) { + def = def || 0; + if (typeof num === 'number') { + return num; + } + if (typeof num === 'string') { + num = parseFloat(num); + } + return isNaN(num) ? def : num; + }, + hasFileAPISupport: function () { + return !!(window.File && window.FileReader); + }, + hasDragDropSupport: function () { + var div = document.createElement('div'); + /** @namespace div.draggable */ + /** @namespace div.ondragstart */ + /** @namespace div.ondrop */ + return !$h.isIE(9) && + (div.draggable !== undefined || (div.ondragstart !== undefined && div.ondrop !== undefined)); + }, + hasFileUploadSupport: function () { + return $h.hasFileAPISupport() && window.FormData; + }, + hasBlobSupport: function () { + try { + return !!window.Blob && Boolean(new Blob()); + } catch (e) { + return false; + } + }, + hasArrayBufferViewSupport: function () { + try { + return new Blob([new Uint8Array(100)]).size === 100; + } catch (e) { + return false; + } + }, + hasResumableUploadSupport: function () { + /** @namespace Blob.prototype.webkitSlice */ + /** @namespace Blob.prototype.mozSlice */ + return $h.hasFileUploadSupport() && $h.hasBlobSupport() && $h.hasArrayBufferViewSupport() && + (!!Blob.prototype.webkitSlice || !!Blob.prototype.mozSlice || !!Blob.prototype.slice || false); + }, + dataURI2Blob: function (dataURI) { + var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || + window.MSBlobBuilder, canBlob = $h.hasBlobSupport(), byteStr, arrayBuffer, intArray, i, mimeStr, bb, + canProceed = (canBlob || BlobBuilder) && window.atob && window.ArrayBuffer && window.Uint8Array; + if (!canProceed) { + return null; + } + if (dataURI.split(',')[0].indexOf('base64') >= 0) { + byteStr = atob(dataURI.split(',')[1]); + } else { + byteStr = decodeURIComponent(dataURI.split(',')[1]); + } + arrayBuffer = new ArrayBuffer(byteStr.length); + intArray = new Uint8Array(arrayBuffer); + for (i = 0; i < byteStr.length; i += 1) { + intArray[i] = byteStr.charCodeAt(i); + } + mimeStr = dataURI.split(',')[0].split(':')[1].split(';')[0]; + if (canBlob) { + return new Blob([$h.hasArrayBufferViewSupport() ? intArray : arrayBuffer], {type: mimeStr}); + } + bb = new BlobBuilder(); + bb.append(arrayBuffer); + return bb.getBlob(mimeStr); + }, + arrayBuffer2String: function (buffer) { + if (window.TextDecoder) { + return new TextDecoder('utf-8').decode(buffer); + } + var array = Array.prototype.slice.apply(new Uint8Array(buffer)), out = '', i = 0, len, c, char2, char3; + len = array.length; + while (i < len) { + c = array[i++]; + switch (c >> 4) { // jshint ignore:line + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + // 0xxxxxxx + out += String.fromCharCode(c); + break; + case 12: + case 13: + // 110x xxxx 10xx xxxx + char2 = array[i++]; + out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F)); // jshint ignore:line + break; + case 14: + // 1110 xxxx 10xx xxxx 10xx xxxx + char2 = array[i++]; + char3 = array[i++]; + out += String.fromCharCode(((c & 0x0F) << 12) | // jshint ignore:line + ((char2 & 0x3F) << 6) | // jshint ignore:line + ((char3 & 0x3F) << 0)); // jshint ignore:line + break; + } + } + return out; + }, + isHtml: function (str) { + var a = document.createElement('div'); + a.innerHTML = str; + for (var c = a.childNodes, i = c.length; i--;) { + if (c[i].nodeType === 1) { + return true; + } + } + return false; + }, + isSvg: function (str) { + return str.match(/^\s*<\?xml/i) && (str.match(/' + str + '')); + }, + uniqId: function () { + return (new Date().getTime() + Math.floor(Math.random() * Math.pow(10, 15))).toString(36); + }, + cspBuffer: { + CSP_ATTRIB: 'data-csp-01928735', // a randomly named temporary attribute to store the CSP elem id + domElementsStyles: {}, + stash: function (htmlString) { + var self = this, outerDom = $.parseHTML('
' + htmlString + '
'), $el = $(outerDom); + $el.find('[style]').each(function (key, elem) { + var $elem = $(elem), styleDeclaration = $elem[0].style, id = $h.uniqId(), styles = {}; + if (styleDeclaration && styleDeclaration.length) { + $(styleDeclaration).each(function () { + styles[this] = styleDeclaration[this]; + }); + self.domElementsStyles[id] = styles; + $elem.removeAttr('style').attr(self.CSP_ATTRIB, id); + } + }); + $el.filter('*').removeAttr('style'); // make sure all style attr are removed + var values = Object.values ? Object.values(outerDom) : Object.keys(outerDom).map(function (itm) { + return outerDom[itm]; + }); + return values.flatMap(function (elem) { + return elem.innerHTML; + }).join(''); + }, + apply: function (domElement) { + var self = this, $el = $(domElement); + $el.find('[' + self.CSP_ATTRIB + ']').each(function (key, elem) { + var $elem = $(elem), id = $elem.attr(self.CSP_ATTRIB), styles = self.domElementsStyles[id]; + if (styles) { + $elem.css(styles); + } + $elem.removeAttr(self.CSP_ATTRIB); + }); + self.domElementsStyles = {}; + } + }, + setHtml: function ($elem, htmlString) { + var buf = $h.cspBuffer; + $elem.html(buf.stash(htmlString)); + buf.apply($elem); + return $elem; + }, + htmlEncode: function (str, undefVal) { + if (str === undefined) { + return undefVal || null; + } + return str.replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); + }, + replaceTags: function (str, tags) { + var out = str; + if (!tags) { + return out; + } + $.each(tags, function (key, value) { + if (typeof value === 'function') { + value = value(); + } + out = out.split(key).join(value); + }); + return out; + }, + cleanMemory: function ($thumb) { + var data = $thumb.is('img') ? $thumb.attr('src') : $thumb.find('source').attr('src'); + $h.revokeObjectURL(data); + }, + findFileName: function (filePath) { + var sepIndex = filePath.lastIndexOf('/'); + if (sepIndex === -1) { + sepIndex = filePath.lastIndexOf('\\'); + } + return filePath.split(filePath.substring(sepIndex, sepIndex + 1)).pop(); + }, + checkFullScreen: function () { + return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || + document.msFullscreenElement; + }, + toggleFullScreen: function (maximize) { + var doc = document, de = doc.documentElement, isFullScreen = $h.checkFullScreen(); + if (de && maximize && !isFullScreen) { + if (de.requestFullscreen) { + de.requestFullscreen(); + } else { + if (de.msRequestFullscreen) { + de.msRequestFullscreen(); + } else { + if (de.mozRequestFullScreen) { + de.mozRequestFullScreen(); + } else { + if (de.webkitRequestFullscreen) { + de.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); + } + } + } + } + } else { + if (isFullScreen) { + if (doc.exitFullscreen) { + doc.exitFullscreen(); + } else { + if (doc.msExitFullscreen) { + doc.msExitFullscreen(); + } else { + if (doc.mozCancelFullScreen) { + doc.mozCancelFullScreen(); + } else { + if (doc.webkitExitFullscreen) { + doc.webkitExitFullscreen(); + } + } + } + } + } + } + }, + moveArray: function (arr, oldIndex, newIndex, reverseOrder) { + var newArr = $.extend(true, [], arr); + if (reverseOrder) { + newArr.reverse(); + } + if (newIndex >= newArr.length) { + var k = newIndex - newArr.length; + while ((k--) + 1) { + newArr.push(undefined); + } + } + newArr.splice(newIndex, 0, newArr.splice(oldIndex, 1)[0]); + if (reverseOrder) { + newArr.reverse(); + } + return newArr; + }, + closeButton: function (css) { + css = ($h.isBs(5) ? 'btn-close' : 'close') + (css ? ' ' + css : ''); + return ''; + }, + getRotation: function (value) { + switch (value) { + case 2: + return 'rotateY(180deg)'; + case 3: + return 'rotate(180deg)'; + case 4: + return 'rotate(180deg) rotateY(180deg)'; + case 5: + return 'rotate(270deg) rotateY(180deg)'; + case 6: + return 'rotate(90deg)'; + case 7: + return 'rotate(90deg) rotateY(180deg)'; + case 8: + return 'rotate(270deg)'; + default: + return ''; + } + }, + setTransform: function (el, val) { + if (!el) { + return; + } + el.style.transform = val; + el.style.webkitTransform = val; + el.style['-moz-transform'] = val; + el.style['-ms-transform'] = val; + el.style['-o-transform'] = val; + }, + getObjectKeys: function (obj) { + var keys = []; + if (obj) { + $.each(obj, function (key) { + keys.push(key); + }); + } + return keys; + }, + getObjectSize: function (obj) { + return $h.getObjectKeys(obj).length; + }, + /** + * Small dependency injection for the task manager + * https://gist.github.com/fearphage/4341799 + */ + whenAll: function (array) { + var s = [].slice, resolveValues = arguments.length === 1 && $h.isArray(array) ? array : s.call(arguments), + deferred = $.Deferred(), i, failed = 0, value, length = resolveValues.length, + remaining = length, rejectContexts, rejectValues, resolveContexts, updateFunc; + rejectContexts = rejectValues = resolveContexts = Array(length); + updateFunc = function (index, contexts, values) { + return function () { + if (values !== resolveValues) { + failed++; + } + deferred.notifyWith(contexts[index] = this, values[index] = s.call(arguments)); + if (!(--remaining)) { + deferred[(!failed ? 'resolve' : 'reject') + 'With'](contexts, values); + } + }; + }; + for (i = 0; i < length; i++) { + if ((value = resolveValues[i]) && $.isFunction(value.promise)) { + value.promise() + .done(updateFunc(i, resolveContexts, resolveValues)) + .fail(updateFunc(i, rejectContexts, rejectValues)); + } else { + deferred.notifyWith(this, value); + --remaining; + } + } + if (!remaining) { + deferred.resolveWith(resolveContexts, resolveValues); + } + return deferred.promise(); + } + }; + FileInput = function (element, options) { + var self = this; + self.$element = $(element); + self.$parent = self.$element.parent(); + if (!self._validate()) { + return; + } + self.isPreviewable = $h.hasFileAPISupport(); + self.isIE9 = $h.isIE(9); + self.isIE10 = $h.isIE(10); + if (self.isPreviewable || self.isIE9) { + self._init(options); + self._listen(); + } + self.$element.removeClass('file-loading'); + }; + + FileInput.prototype = { + constructor: FileInput, + _cleanup: function () { + var self = this; + self.reader = null; + self.clearFileStack(); + self.fileBatchCompleted = true; + self.isError = false; + self.isDuplicateError = false; + self.isPersistentError = false; + self.cancelling = false; + self.paused = false; + self.lastProgress = 0; + self._initAjax(); + }, + _isAborted: function () { + var self = this; + return self.cancelling || self.paused; + }, + _initAjax: function () { + var self = this, tm = self.taskManager = { + pool: {}, + addPool: function (id) { + return (tm.pool[id] = new tm.TasksPool(id)); + }, + getPool: function (id) { + return tm.pool[id]; + }, + addTask: function (id, logic) { // add standalone task directly from task manager + return new tm.Task(id, logic); + }, + TasksPool: function (id) { + var tp = this; + tp.id = id; + tp.cancelled = false; + tp.cancelledDeferrer = $.Deferred(); + tp.tasks = {}; + tp.addTask = function (id, logic) { + return (tp.tasks[id] = new tm.Task(id, logic)); + }; + tp.size = function () { + return $h.getObjectSize(tp.tasks); + }; + tp.run = function (maxThreads) { + var i = 0, failed = false, task, tasksList = $h.getObjectKeys(tp.tasks).map(function (key) { + return tp.tasks[key]; + }), tasksDone = [], deferred = $.Deferred(), enqueue, callback; + + if (tp.cancelled) { + tp.cancelledDeferrer.resolve(); + return deferred.reject(); + } + // if run all at once + if (!maxThreads) { + var tasksDeferredList = $h.getObjectKeys(tp.tasks).map(function (key) { + return tp.tasks[key].deferred; + }); + // when all are done + $h.whenAll(tasksDeferredList).done(function () { + var argv = $h.getArray(arguments); + if (!tp.cancelled) { + deferred.resolve.apply(null, argv); + tp.cancelledDeferrer.reject(); + } else { + deferred.reject.apply(null, argv); + tp.cancelledDeferrer.resolve(); + } + }).fail(function () { + var argv = $h.getArray(arguments); + deferred.reject.apply(null, argv); + if (!tp.cancelled) { + tp.cancelledDeferrer.reject(); + } else { + tp.cancelledDeferrer.resolve(); + } + }); + // run all tasks + $.each(tp.tasks, function (id) { + task = tp.tasks[id]; + task.run(); + }); + return deferred; + } + enqueue = function (task) { + $.when(task.deferred) + .fail(function () { + failed = true; + callback.apply(null, arguments); + }) + .always(callback); + }; + callback = function () { + var argv = $h.getArray(arguments); + // notify a task just ended + deferred.notify(argv); + tasksDone.push(argv); + if (tp.cancelled) { + deferred.reject.apply(null, tasksDone); + tp.cancelledDeferrer.resolve(); + return; + } + if (tasksDone.length === tp.size()) { + if (failed) { + deferred.reject.apply(null, tasksDone); + } else { + deferred.resolve.apply(null, tasksDone); + } + } + // if there are any tasks remaining + if (tasksList.length) { + task = tasksList.shift(); + enqueue(task); + task.run(); + } + }; + // run the first "maxThreads" tasks + while (tasksList.length && i++ < maxThreads) { + task = tasksList.shift(); + enqueue(task); + task.run(); + } + return deferred; + }; + tp.cancel = function () { + tp.cancelled = true; + return tp.cancelledDeferrer; + }; + }, + Task: function (id, logic) { + var tk = this; + tk.id = id; + tk.deferred = $.Deferred(); + tk.logic = logic; + tk.context = null; + tk.run = function () { + var argv = $h.getArray(arguments); + argv.unshift(tk.deferred); // add deferrer as first argument + logic.apply(tk.context, argv); // run task + return tk.deferred; // return deferrer + }; + tk.runWithContext = function (context) { + tk.context = context; + return tk.run(); + }; + } + }; + self.ajaxQueue = []; + self.ajaxRequests = []; + self.ajaxAborted = false; + }, + _init: function (options, refreshMode) { + var self = this, f, $el = self.$element, $cont, t, tmp; + self.options = options; + self.canOrientImage = $h.canOrientImage($el); + $.each(options, function (key, value) { + switch (key) { + case 'minFileCount': + case 'maxFileCount': + case 'maxTotalFileCount': + case 'minFileSize': + case 'maxFileSize': + case 'maxFilePreviewSize': + case 'resizeQuality': + case 'resizeIfSizeMoreThan': + case 'progressUploadThreshold': + case 'initialPreviewCount': + case 'zoomModalHeight': + case 'minImageHeight': + case 'maxImageHeight': + case 'minImageWidth': + case 'maxImageWidth': + case 'bytesToKB': + self[key] = $h.getNum(value); + break; + default: + self[key] = value; + break; + } + }); + if (!self.bytesToKB || self.bytesToKB <= 0) { + self.bytesToKB = 1024; + } + if (self.errorCloseButton === undefined) { + self.errorCloseButton = $h.closeButton('kv-error-close' + ($h.isBs(5) ? ' float-end' : '')); + } + if (self.maxTotalFileCount > 0 && self.maxTotalFileCount < self.maxFileCount) { + self.maxTotalFileCount = self.maxFileCount; + } + if (self.rtl) { // swap buttons for rtl + tmp = self.previewZoomButtonIcons.prev; + self.previewZoomButtonIcons.prev = self.previewZoomButtonIcons.next; + self.previewZoomButtonIcons.next = tmp; + } + // validate chunk threads to not exceed maxAjaxThreads + if (!isNaN(self.maxAjaxThreads) && self.maxAjaxThreads < self.resumableUploadOptions.maxThreads) { + self.resumableUploadOptions.maxThreads = self.maxAjaxThreads; + } + self._initFileManager(); + if (typeof self.autoOrientImage === 'function') { + self.autoOrientImage = self.autoOrientImage(); + } + if (typeof self.autoOrientImageInitial === 'function') { + self.autoOrientImageInitial = self.autoOrientImageInitial(); + } + if (!refreshMode) { + self._cleanup(); + } + self.duplicateErrors = []; + self.$form = $el.closest('form'); + self._initTemplateDefaults(); + self.uploadFileAttr = !$h.isEmpty($el.attr('name')) ? $el.attr('name') : 'file_data'; + t = self._getLayoutTemplate('progress'); + self.progressTemplate = t.replace('{class}', self.progressClass); + self.progressInfoTemplate = t.replace('{class}', self.progressInfoClass); + self.progressPauseTemplate = t.replace('{class}', self.progressPauseClass); + self.progressCompleteTemplate = t.replace('{class}', self.progressCompleteClass); + self.progressErrorTemplate = t.replace('{class}', self.progressErrorClass); + self.isDisabled = $el.attr('disabled') || $el.attr('readonly'); + if (self.isDisabled) { + $el.attr('disabled', true); + } + self.isClickable = self.browseOnZoneClick && self.showPreview && + (self.dropZoneEnabled || !$h.isEmpty(self.defaultPreviewContent)); + self.isAjaxUpload = $h.hasFileUploadSupport() && !$h.isEmpty(self.uploadUrl); + self.dropZoneEnabled = $h.hasDragDropSupport() && self.dropZoneEnabled; + if (!self.isAjaxUpload) { + self.dropZoneEnabled = self.dropZoneEnabled && $h.canAssignFilesToInput(); + } + self.slug = typeof options.slugCallback === 'function' ? options.slugCallback : self._slugDefault; + self.mainTemplate = self.showCaption ? self._getLayoutTemplate('main1') : self._getLayoutTemplate('main2'); + self.captionTemplate = self._getLayoutTemplate('caption'); + self.previewGenericTemplate = self._getPreviewTemplate('generic'); + if (!self.imageCanvas && self.resizeImage && (self.maxImageWidth || self.maxImageHeight)) { + self.imageCanvas = document.createElement('canvas'); + self.imageCanvasContext = self.imageCanvas.getContext('2d'); + } + if ($h.isEmpty($el.attr('id'))) { + $el.attr('id', $h.uniqId()); + } + self.namespace = '.fileinput_' + $el.attr('id').replace(/-/g, '_'); + if (self.$container === undefined) { + self.$container = self._createContainer(); + } else { + self._refreshContainer(); + } + $cont = self.$container; + self.$dropZone = $cont.find('.file-drop-zone'); + self.$progress = $cont.find('.kv-upload-progress'); + self.$btnUpload = $cont.find('.fileinput-upload'); + self.$captionContainer = $h.getElement(options, 'elCaptionContainer', $cont.find('.file-caption')); + self.$caption = $h.getElement(options, 'elCaptionText', $cont.find('.file-caption-name')); + if (!$h.isEmpty(self.msgPlaceholder)) { + f = $el.attr('multiple') ? self.filePlural : self.fileSingle; + self.$caption.attr('placeholder', self.msgPlaceholder.replace('{files}', f)); + } + self.$captionIcon = self.$captionContainer.find('.file-caption-icon'); + self.$previewContainer = $h.getElement(options, 'elPreviewContainer', $cont.find('.file-preview')); + self.$preview = $h.getElement(options, 'elPreviewImage', $cont.find('.file-preview-thumbnails')); + self.$previewStatus = $h.getElement(options, 'elPreviewStatus', $cont.find('.file-preview-status')); + self.$errorContainer = $h.getElement(options, 'elErrorContainer', + self.$previewContainer.find('.kv-fileinput-error')); + self._validateDisabled(); + if (!$h.isEmpty(self.msgErrorClass)) { + $h.addCss(self.$errorContainer, self.msgErrorClass); + } + if (!refreshMode) { + self._resetErrors(); + self.$errorContainer.hide(); + self.previewInitId = 'thumb-' + $el.attr('id'); + self._initPreviewCache(); + self._initPreview(true); + self._initPreviewActions(); + if (self.$parent.hasClass('file-loading')) { + self.$container.insertBefore(self.$parent); + self.$parent.remove(); + } + } else { + if (!self._errorsExist()) { + self.$errorContainer.hide(); + } + } + self._setFileDropZoneTitle(); + if ($el.attr('disabled')) { + self.disable(); + } + self._initZoom(); + if (self.hideThumbnailContent) { + $h.addCss(self.$preview, 'hide-content'); + } + }, + _initFileManager: function () { + var self = this; + self.uploadStartTime = $h.now(); + self.fileManager = { + stack: {}, + filesProcessed: [], + errors: [], + loadedImages: {}, + totalImages: 0, + totalFiles: null, + totalSize: null, + uploadedSize: 0, + stats: {}, + bpsLog: [], + bps: 0, + initStats: function (id) { + var data = {started: $h.now()}; + if (id) { + self.fileManager.stats[id] = data; + } else { + self.fileManager.stats = data; + } + }, + getUploadStats: function (id, loaded, total) { + var fm = self.fileManager, + started = id ? fm.stats[id] && fm.stats[id].started || $h.now() : self.uploadStartTime, + elapsed = ($h.now() - started) / 1000, bps = Math.ceil(elapsed ? loaded / elapsed : 0), + pendingBytes = total - loaded, out, delay = fm.bpsLog.length ? self.bitrateUpdateDelay : 0; + setTimeout(function () { + var i, j = 0, n = 0, len, beg; + fm.bpsLog.push(bps); + fm.bpsLog.sort(function (a, b) { + return a - b; + }); + len = fm.bpsLog.length; + beg = len > 10 ? len - 10 : Math.ceil(len / 2); + for (i = len; i > beg; i--) { + n = parseFloat(fm.bpsLog[i]); + j++; + } + fm.bps = (j > 0 ? n / j : 0) * 64; + }, delay); + out = { + fileId: id, + started: started, + elapsed: elapsed, + loaded: loaded, + total: total, + bps: fm.bps, + bitrate: self._getSize(fm.bps, self.bitRateUnits), + pendingBytes: pendingBytes + }; + if (id) { + fm.stats[id] = out; + } else { + fm.stats = out; + } + return out; + }, + exists: function (id) { + return $.inArray(id, self.fileManager.getIdList()) !== -1; + }, + count: function () { + return self.fileManager.getIdList().length; + }, + total: function () { + var fm = self.fileManager; + if (!fm.totalFiles) { + fm.totalFiles = fm.count(); + } + return fm.totalFiles; + }, + getTotalSize: function () { + var fm = self.fileManager; + if (fm.totalSize) { + return fm.totalSize; + } + fm.totalSize = 0; + $.each(self.getFileStack(), function (id, f) { + var size = parseFloat(f.size); + fm.totalSize += isNaN(size) ? 0 : size; + }); + return fm.totalSize; + }, + add: function (file, id) { + if (!id) { + id = self.fileManager.getId(file); + } + if (!id) { + return; + } + self.fileManager.stack[id] = { + file: file, + name: $h.getFileName(file), + relativePath: $h.getFileRelativePath(file), + size: file.size, + nameFmt: self._getFileName(file, ''), + sizeFmt: self._getSize(file.size) + }; + }, + remove: function ($thumb) { + var id = self._getThumbFileId($thumb); + self.fileManager.removeFile(id); + }, + removeFile: function (id) { + var fm = self.fileManager; + if (!id) { + return; + } + delete fm.stack[id]; + delete fm.loadedImages[id]; + }, + move: function (idFrom, idTo) { + var result = {}, stack = self.fileManager.stack; + if (!idFrom && !idTo || idFrom === idTo) { + return; + } + $.each(stack, function (k, v) { + if (k !== idFrom) { + result[k] = v; + } + if (k === idTo) { + result[idFrom] = stack[idFrom]; + } + }); + self.fileManager.stack = result; + }, + list: function () { + var files = []; + $.each(self.getFileStack(), function (k, v) { + if (v && v.file) { + files.push(v.file); + } + }); + return files; + }, + isPending: function (id) { + return $.inArray(id, self.fileManager.filesProcessed) === -1 && self.fileManager.exists(id); + }, + isProcessed: function () { + var filesProcessed = true, fm = self.fileManager; + $.each(self.getFileStack(), function (id) { + if (fm.isPending(id)) { + filesProcessed = false; + } + }); + return filesProcessed; + }, + clear: function () { + var fm = self.fileManager; + self.isDuplicateError = false; + self.isPersistentError = false; + fm.totalFiles = null; + fm.totalSize = null; + fm.uploadedSize = 0; + fm.stack = {}; + fm.errors = []; + fm.filesProcessed = []; + fm.stats = {}; + fm.bpsLog = []; + fm.bps = 0; + fm.clearImages(); + }, + clearImages: function () { + self.fileManager.loadedImages = {}; + self.fileManager.totalImages = 0; + }, + addImage: function (id, config) { + self.fileManager.loadedImages[id] = config; + }, + removeImage: function (id) { + delete self.fileManager.loadedImages[id]; + }, + getImageIdList: function () { + return $h.getObjectKeys(self.fileManager.loadedImages); + }, + getImageCount: function () { + return self.fileManager.getImageIdList().length; + }, + getId: function (file) { + return self._getFileId(file); + }, + getIndex: function (id) { + return self.fileManager.getIdList().indexOf(id); + }, + getThumb: function (id) { + var $thumb = null; + self._getThumbs().each(function () { + var $t = $(this); + if (self._getThumbFileId($t) === id) { + $thumb = $t; + } + }); + return $thumb; + }, + getThumbIndex: function ($thumb) { + var id = self._getThumbFileId($thumb); + return self.fileManager.getIndex(id); + }, + getIdList: function () { + return $h.getObjectKeys(self.fileManager.stack); + }, + getFile: function (id) { + return self.fileManager.stack[id] || null; + }, + getFileName: function (id, fmt) { + var file = self.fileManager.getFile(id); + if (!file) { + return ''; + } + return fmt ? (file.nameFmt || '') : file.name || ''; + }, + getFirstFile: function () { + var ids = self.fileManager.getIdList(), id = ids && ids.length ? ids[0] : null; + return self.fileManager.getFile(id); + }, + setFile: function (id, file) { + if (self.fileManager.getFile(id)) { + self.fileManager.stack[id].file = file; + } else { + self.fileManager.add(file, id); + } + }, + setProcessed: function (id) { + self.fileManager.filesProcessed.push(id); + }, + getProgress: function () { + var total = self.fileManager.total(), filesProcessed = self.fileManager.filesProcessed.length; + if (!total) { + return 0; + } + return Math.ceil(filesProcessed / total * 100); + + }, + setProgress: function (id, pct) { + var f = self.fileManager.getFile(id); + if (!isNaN(pct) && f) { + f.progress = pct; + } + } + }; + }, + _setUploadData: function (fd, config) { + var self = this; + $.each(config, function (key, value) { + var param = self.uploadParamNames[key] || key; + if ($h.isArray(value)) { + fd.append(param, value[0], value[1]); + } else { + fd.append(param, value); + } + }); + }, + _initResumableUpload: function () { + var self = this, opts = self.resumableUploadOptions, logs = $h.logMessages, rm, fm = self.fileManager; + if (!self.enableResumableUpload) { + return; + } + if (opts.fallback !== false && typeof opts.fallback !== 'function') { + opts.fallback = function (s) { + s._log(logs.noResumableSupport); + s.enableResumableUpload = false; + }; + } + if (!$h.hasResumableUploadSupport() && opts.fallback !== false) { + opts.fallback(self); + return; + } + if (!self.uploadUrl && self.enableResumableUpload) { + self._log(logs.noUploadUrl); + self.enableResumableUpload = false; + return; + + } + opts.chunkSize = parseFloat(opts.chunkSize); + if (opts.chunkSize <= 0 || isNaN(opts.chunkSize)) { + self._log(logs.invalidChunkSize, {chunkSize: opts.chunkSize}); + self.enableResumableUpload = false; + return; + } + rm = self.resumableManager = { + init: function (id, f, index) { + rm.logs = []; + rm.stack = []; + rm.error = ''; + rm.id = id; + rm.file = f.file; + rm.fileName = f.name; + rm.fileIndex = index; + rm.completed = false; + rm.lastProgress = 0; + if (self.showPreview) { + rm.$thumb = fm.getThumb(id) || null; + rm.$progress = rm.$btnDelete = null; + if (rm.$thumb && rm.$thumb.length) { + rm.$progress = rm.$thumb.find('.file-thumb-progress'); + rm.$btnDelete = rm.$thumb.find('.kv-file-remove'); + } + } + rm.chunkSize = opts.chunkSize * self.bytesToKB; + rm.chunkCount = rm.getTotalChunks(); + }, + setAjaxError: function (jqXHR, textStatus, errorThrown, isTest) { + if (jqXHR.responseJSON && jqXHR.responseJSON.error) { + errorThrown = jqXHR.responseJSON.error.toString(); + } + if (!isTest) { + rm.error = errorThrown; + } + if (opts.showErrorLog) { + self._log(logs.ajaxError, { + status: jqXHR.status, + error: errorThrown, + text: jqXHR.responseText || '' + }); + } + }, + reset: function () { + rm.stack = []; + rm.chunksProcessed = {}; + }, + setProcessed: function (status) { + var id = rm.id, msg, $thumb = rm.$thumb, $prog = rm.$progress, hasThumb = $thumb && $thumb.length, + params = {id: hasThumb ? $thumb.attr('id') : '', index: fm.getIndex(id), fileId: id}, tokens, + skipErrorsAndProceed = self.resumableUploadOptions.skipErrorsAndProceed; + rm.completed = true; + rm.lastProgress = 0; + if (hasThumb) { + $thumb.removeClass('file-uploading'); + } + if (status === 'success') { + fm.uploadedSize += rm.file.size; + if (self.showPreview) { + self._setProgress(101, $prog); + self._setThumbStatus($thumb, 'Success'); + self._initUploadSuccess(rm.chunksProcessed[id].data, $thumb); + } + fm.removeFile(id); + delete rm.chunksProcessed[id]; + self._raise('fileuploaded', [params.id, params.index, params.fileId]); + if (fm.isProcessed()) { + self._setProgress(101); + } + } else { + if (status !== 'cancel') { + if (self.showPreview) { + self._setThumbStatus($thumb, 'Error'); + self._setPreviewError($thumb, true); + self._setProgress(101, $prog, self.msgProgressError); + self._setProgress(101, self.$progress, self.msgProgressError); + self.cancelling = !skipErrorsAndProceed; + } + if (!self.$errorContainer.find('li[data-file-id="' + params.fileId + '"]').length) { + tokens = {file: rm.fileName, max: opts.maxRetries, error: rm.error}; + msg = self.msgResumableUploadRetriesExceeded.setTokens(tokens); + $.extend(params, tokens); + self._showFileError(msg, params, 'filemaxretries'); + if (skipErrorsAndProceed) { + fm.removeFile(id); + delete rm.chunksProcessed[id]; + if (fm.isProcessed()) { + self._setProgress(101); + } + } + } + } + } + if (fm.isProcessed()) { + rm.reset(); + } + }, + check: function () { + var status = true; + $.each(rm.logs, function (index, value) { + if (!value) { + status = false; + return false; + } + }); + }, + processedResumables: function () { + var logs = rm.logs, i, count = 0; + if (!logs || !logs.length) { + return 0; + } + for (i = 0; i < logs.length; i++) { + if (logs[i] === true) { + count++; + } + } + return count; + }, + getUploadedSize: function () { + var size = rm.processedResumables() * rm.chunkSize; + return size > rm.file.size ? rm.file.size : size; + }, + getTotalChunks: function () { + var chunkSize = parseFloat(rm.chunkSize); + if (!isNaN(chunkSize) && chunkSize > 0) { + return Math.ceil(rm.file.size / chunkSize); + } + return 0; + }, + getProgress: function () { + var chunksProcessed = rm.processedResumables(), total = rm.chunkCount; + if (total === 0) { + return 0; + } + return Math.ceil(chunksProcessed / total * 100); + }, + checkAborted: function (intervalId) { + if (self._isAborted()) { + clearInterval(intervalId); + self.unlock(); + } + }, + upload: function () { + var ids = fm.getIdList(), flag = 'new', intervalId; + intervalId = setInterval(function () { + var id; + rm.checkAborted(intervalId); + if (flag === 'new') { + self.lock(); + flag = 'processing'; + id = ids.shift(); + fm.initStats(id); + if (fm.stack[id]) { + rm.init(id, fm.stack[id], fm.getIndex(id)); + rm.processUpload(); + } + } + if (!fm.isPending(id) && rm.completed) { + flag = 'new'; + } + if (fm.isProcessed()) { + var $initThumbs = self.$preview.find('.file-preview-initial'); + if ($initThumbs.length) { + $h.addCss($initThumbs, $h.SORT_CSS); + self._initSortable(); + } + clearInterval(intervalId); + self._clearFileInput(); + self.unlock(); + setTimeout(function () { + var data = self.previewCache.data; + if (data) { + self.initialPreview = data.content; + self.initialPreviewConfig = data.config; + self.initialPreviewThumbTags = data.tags; + } + self._raise('filebatchuploadcomplete', [ + self.initialPreview, + self.initialPreviewConfig, + self.initialPreviewThumbTags, + self._getExtraData() + ]); + }, self.processDelay); + } + }, self.processDelay); + }, + uploadResumable: function () { + var i, pool, tm = self.taskManager, total = rm.chunkCount; + pool = tm.addPool(rm.id); + for (i = 0; i < total; i++) { + rm.logs[i] = !!(rm.chunksProcessed[rm.id] && rm.chunksProcessed[rm.id][i]); + if (!rm.logs[i]) { + rm.pushAjax(i, 0); + } + } + pool.run(opts.maxThreads) + .done(function () { + rm.setProcessed('success'); + }) + .fail(function () { + rm.setProcessed(pool.cancelled ? 'cancel' : 'error'); + }); + }, + processUpload: function () { + var fd, f, id = rm.id, fnBefore, fnSuccess, fnError, fnComplete, outData; + if (!opts.testUrl) { + rm.uploadResumable(); + return; + } + fd = new FormData(); + f = fm.stack[id]; + self._setUploadData(fd, { + fileId: id, + fileName: f.fileName, + fileSize: f.size, + fileRelativePath: f.relativePath, + chunkSize: rm.chunkSize, + chunkCount: rm.chunkCount + }); + fnBefore = function (jqXHR) { + outData = self._getOutData(fd, jqXHR); + self._raise('filetestbeforesend', [id, fm, rm, outData]); + }; + fnSuccess = function (data, textStatus, jqXHR) { + outData = self._getOutData(fd, jqXHR, data); + var pNames = self.uploadParamNames, chunksUploaded = pNames.chunksUploaded || 'chunksUploaded', + params = [id, fm, rm, outData]; + if (!data[chunksUploaded] || !$h.isArray(data[chunksUploaded])) { + self._raise('filetesterror', params); + } else { + if (!rm.chunksProcessed[id]) { + rm.chunksProcessed[id] = {}; + } + $.each(data[chunksUploaded], function (key, index) { + rm.logs[index] = true; + rm.chunksProcessed[id][index] = true; + }); + rm.chunksProcessed[id].data = data; + self._raise('filetestsuccess', params); + } + rm.uploadResumable(); + }; + fnError = function (jqXHR, textStatus, errorThrown) { + outData = self._getOutData(fd, jqXHR); + self._raise('filetestajaxerror', [id, fm, rm, outData]); + rm.setAjaxError(jqXHR, textStatus, errorThrown, true); + rm.uploadResumable(); + }; + fnComplete = function () { + self._raise('filetestcomplete', [id, fm, rm, self._getOutData(fd)]); + }; + self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, fd, id, rm.fileIndex, opts.testUrl); + }, + pushAjax: function (index, retry) { + var tm = self.taskManager, pool = tm.getPool(rm.id); + pool.addTask(pool.size() + 1, function (deferrer) { + // use fifo chunk stack + var arr = rm.stack.shift(), index; + index = arr[0]; + if (!rm.chunksProcessed[rm.id] || !rm.chunksProcessed[rm.id][index]) { + rm.sendAjax(index, arr[1], deferrer); + } else { + self._log(logs.chunkQueueError, {index: index}); + } + }); + rm.stack.push([index, retry]); + }, + sendAjax: function (index, retry, deferrer) { + var f, chunkSize = rm.chunkSize, id = rm.id, file = rm.file, $thumb = rm.$thumb, + msgs = $h.logMessages, $btnDelete = rm.$btnDelete, logError = function (msg, tokens) { + if (tokens) { + msg = msg.setTokens(tokens); + } + msg = msgs.resumableRequestError.setTokens({msg: msg}); + self._log(msg); + deferrer.reject(msg); + }; + if (rm.chunksProcessed[id] && rm.chunksProcessed[id][index]) { + return; + } + if (retry > opts.maxRetries) { + logError(msgs.resumableMaxRetriesReached, {n: opts.maxRetries}); + rm.setProcessed('error'); + return; + } + var fd, outData, fnBefore, fnSuccess, fnError, fnComplete, slice = file.slice ? 'slice' : + (file.mozSlice ? 'mozSlice' : (file.webkitSlice ? 'webkitSlice' : 'slice')), + blob = file[slice](chunkSize * index, chunkSize * (index + 1)); + fd = new FormData(); + f = fm.stack[id]; + self._setUploadData(fd, { + chunkCount: rm.chunkCount, + chunkIndex: index, + chunkSize: chunkSize, + chunkSizeStart: chunkSize * index, + fileBlob: [blob, rm.fileName], + fileId: id, + fileName: rm.fileName, + fileRelativePath: f.relativePath, + fileSize: file.size, + retryCount: retry + }); + if (rm.$progress && rm.$progress.length) { + rm.$progress.show(); + } + fnBefore = function (jqXHR) { + outData = self._getOutData(fd, jqXHR); + if (self.showPreview) { + if (!$thumb.hasClass('file-preview-success')) { + self._setThumbStatus($thumb, 'Loading'); + $h.addCss($thumb, 'file-uploading'); + } + $btnDelete.attr('disabled', true); + } + self._raise('filechunkbeforesend', [id, index, retry, fm, rm, outData]); + }; + fnSuccess = function (data, textStatus, jqXHR) { + if (self._isAborted()) { + logError(msgs.resumableAborting); + return; + } + outData = self._getOutData(fd, jqXHR, data); + var paramNames = self.uploadParamNames, chunkIndex = paramNames.chunkIndex || 'chunkIndex', + params = [id, index, retry, fm, rm, outData]; + if (data.error) { + if (opts.showErrorLog) { + self._log(logs.retryStatus, { + retry: retry + 1, + filename: rm.fileName, + chunk: index + }); + } + self._raise('filechunkerror', params); + rm.pushAjax(index, retry + 1); + rm.error = data.error; + logError(data.error); + } else { + rm.logs[data[chunkIndex]] = true; + if (!rm.chunksProcessed[id]) { + rm.chunksProcessed[id] = {}; + } + rm.chunksProcessed[id][data[chunkIndex]] = true; + rm.chunksProcessed[id].data = data; + deferrer.resolve.call(null, data); + self._raise('filechunksuccess', params); + rm.check(); + } + }; + fnError = function (jqXHR, textStatus, errorThrown) { + if (self._isAborted()) { + logError(msgs.resumableAborting); + return; + } + outData = self._getOutData(fd, jqXHR); + rm.setAjaxError(jqXHR, textStatus, errorThrown); + self._raise('filechunkajaxerror', [id, index, retry, fm, rm, outData]); + rm.pushAjax(index, retry + 1); // push another task + logError(msgs.resumableRetryError, {n: retry - 1}); // resolve the current task + }; + fnComplete = function () { + if (!self._isAborted()) { + self._raise('filechunkcomplete', [id, index, retry, fm, rm, self._getOutData(fd)]); + } + }; + self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, fd, id, rm.fileIndex); + } + }; + rm.reset(); + }, + _initTemplateDefaults: function () { + var self = this, tMain1, tMain2, tPreview, tFileIcon, tClose, tCaption, tBtnDefault, tBtnLink, tBtnBrowse, + tModalMain, tModal, tProgress, tSize, tFooter, tActions, tActionDelete, tActionUpload, tActionDownload, + tActionZoom, tActionDrag, tIndicator, tTagBef, tTagBef1, tTagBef2, tTagAft, tGeneric, tHtml, tImage, + tText, tOffice, tGdocs, tVideo, tAudio, tFlash, tObject, tPdf, tOther, tStyle, tZoomCache, vDefaultDim, + tStats, tModalLabel, tDescClose, renderObject = function (type, mime) { + return '\n' + $h.DEFAULT_PREVIEW + '\n\n'; + }, defBtnCss1 = 'btn btn-sm btn-kv ' + $h.defaultButtonCss(); + tMain1 = '{preview}\n' + + '
\n' + + '
\n' + + '
\n' + + ' {caption}\n\n' + + ($h.isBs(5) ? '' : '
\n') + + ' {remove}\n' + + ' {cancel}\n' + + ' {pause}\n' + + ' {upload}\n' + + ' {browse}\n' + + ($h.isBs(5) ? '' : '
\n') + + '
' + '
'; + tMain2 = '{preview}\n
\n
\n' + + '{remove}\n{cancel}\n{upload}\n{browse}\n'; + tPreview = '
\n' + + ' {close}' + + '
\n' + + '
\n' + + '
\n' + + '
\n' + + '
\n' + + '
\n' + + '
'; + tClose = $h.closeButton('fileinput-remove'); + tFileIcon = ''; + // noinspection HtmlUnknownAttribute + tCaption = '\n'; + //noinspection HtmlUnknownAttribute + tBtnDefault = ''; + //noinspection HtmlUnknownTarget,HtmlUnknownAttribute + tBtnLink = '{icon} {label}'; + //noinspection HtmlUnknownAttribute + tBtnBrowse = '
{icon} {label}
'; + tModalLabel = $h.MODAL_ID + 'Label'; + tModalMain = ''; + tModal = '\n'; + tDescClose = ''; + tProgress = '
\n' + + '
\n' + + ' {status}\n' + + '
\n' + + '
{stats}'; + tStats = '
' + + '{pendingTime} ' + + '{uploadSpeed}' + + '
'; + tSize = ' ({sizeText})'; + tFooter = ''; + tActions = '
\n' + + ' \n' + + '
\n' + + '{drag}\n' + + '
'; + //noinspection HtmlUnknownAttribute + tActionDelete = '\n'; + tActionUpload = ''; + tActionDownload = '{downloadIcon}'; + tActionZoom = ''; + tActionDrag = '{dragIcon}'; + tIndicator = '
{indicator}
'; + tTagBef = '
\n'; + tTagBef2 = tTagBef + ' title="{caption}">
\n'; + tTagAft = '
{footer}\n{zoomCache}
\n'; + tGeneric = '{content}\n'; + tStyle = ' {style}'; + tHtml = renderObject('html', 'text/html'); + tText = renderObject('text', 'text/plain;charset=UTF-8'); + tPdf = renderObject('pdf', 'application/pdf'); + tImage = '{alt}\n'; + tOffice = ''; + tGdocs = ''; + tVideo = '\n'; + tAudio = '\n'; + tFlash = '\n'; + tObject = '\n' + '\n' + + $h.OBJECT_PARAMS + ' ' + $h.DEFAULT_PREVIEW + '\n\n'; + tOther = '
\n' + $h.DEFAULT_PREVIEW + '\n
\n'; + tZoomCache = '
{zoomContent}
'; + vDefaultDim = {width: '100%', height: '100%', 'min-height': '480px'}; + if (self._isPdfRendered()) { + tPdf = self.pdfRendererTemplate.replace('{renderer}', self._encodeURI(self.pdfRendererUrl)); + } + self.defaults = { + layoutTemplates: { + main1: tMain1, + main2: tMain2, + preview: tPreview, + close: tClose, + fileIcon: tFileIcon, + caption: tCaption, + modalMain: tModalMain, + modal: tModal, + descriptionClose: tDescClose, + progress: tProgress, + stats: tStats, + size: tSize, + footer: tFooter, + indicator: tIndicator, + actions: tActions, + actionDelete: tActionDelete, + actionUpload: tActionUpload, + actionDownload: tActionDownload, + actionZoom: tActionZoom, + actionDrag: tActionDrag, + btnDefault: tBtnDefault, + btnLink: tBtnLink, + btnBrowse: tBtnBrowse, + zoomCache: tZoomCache + }, + previewMarkupTags: { + tagBefore1: tTagBef1, + tagBefore2: tTagBef2, + tagAfter: tTagAft + }, + previewContentTemplates: { + generic: tGeneric, + html: tHtml, + image: tImage, + text: tText, + office: tOffice, + gdocs: tGdocs, + video: tVideo, + audio: tAudio, + flash: tFlash, + object: tObject, + pdf: tPdf, + other: tOther + }, + allowedPreviewTypes: ['image', 'html', 'text', 'video', 'audio', 'flash', 'pdf', 'object'], + previewTemplates: {}, + previewSettings: { + image: {width: 'auto', height: 'auto', 'max-width': '100%', 'max-height': '100%'}, + html: {width: '213px', height: '160px'}, + text: {width: '213px', height: '160px'}, + office: {width: '213px', height: '160px'}, + gdocs: {width: '213px', height: '160px'}, + video: {width: '213px', height: '160px'}, + audio: {width: '100%', height: '30px'}, + flash: {width: '213px', height: '160px'}, + object: {width: '213px', height: '160px'}, + pdf: {width: '100%', height: '160px', 'position': 'relative'}, + other: {width: '213px', height: '160px'} + }, + previewSettingsSmall: { + image: {width: 'auto', height: 'auto', 'max-width': '100%', 'max-height': '100%'}, + html: {width: '100%', height: '160px'}, + text: {width: '100%', height: '160px'}, + office: {width: '100%', height: '160px'}, + gdocs: {width: '100%', height: '160px'}, + video: {width: '100%', height: 'auto'}, + audio: {width: '100%', height: '30px'}, + flash: {width: '100%', height: 'auto'}, + object: {width: '100%', height: 'auto'}, + pdf: {width: '100%', height: '160px'}, + other: {width: '100%', height: '160px'} + }, + previewZoomSettings: { + image: {width: 'auto', height: 'auto', 'max-width': '100%', 'max-height': '100%'}, + html: vDefaultDim, + text: vDefaultDim, + office: {width: '100%', height: '100%', 'max-width': '100%', 'min-height': '480px'}, + gdocs: {width: '100%', height: '100%', 'max-width': '100%', 'min-height': '480px'}, + video: {width: 'auto', height: '100%', 'max-width': '100%'}, + audio: {width: '100%', height: '30px'}, + flash: {width: 'auto', height: '480px'}, + object: {width: 'auto', height: '100%', 'max-width': '100%', 'min-height': '480px'}, + pdf: vDefaultDim, + other: {width: 'auto', height: '100%', 'min-height': '480px'} + }, + mimeTypeAliases: { + 'video/quicktime': 'video/mp4' + }, + fileTypeSettings: { + image: function (vType, vName) { + return ($h.compare(vType, 'image.*') && !$h.compare(vType, /(tiff?|wmf)$/i) || + $h.compare(vName, /\.(gif|png|jpe?g)$/i)); + }, + html: function (vType, vName) { + return $h.compare(vType, 'text/html') || $h.compare(vName, /\.(htm|html)$/i); + }, + office: function (vType, vName) { + return $h.compare(vType, /(word|excel|powerpoint|office)$/i) || + $h.compare(vName, /\.(docx?|xlsx?|pptx?|pps|potx?)$/i); + }, + gdocs: function (vType, vName) { + return $h.compare(vType, /(word|excel|powerpoint|office|iwork-pages|tiff?)$/i) || + $h.compare(vName, + /\.(docx?|xlsx?|pptx?|pps|potx?|rtf|ods|odt|pages|ai|dxf|ttf|tiff?|wmf|e?ps)$/i); + }, + text: function (vType, vName) { + return $h.compare(vType, 'text.*') || $h.compare(vName, /\.(xml|javascript)$/i) || + $h.compare(vName, /\.(txt|md|nfo|ini|json|php|js|css)$/i); + }, + video: function (vType, vName) { + return $h.compare(vType, 'video.*') && ($h.compare(vType, /(ogg|mp4|mp?g|mov|webm|3gp)$/i) || + $h.compare(vName, /\.(og?|mp4|webm|mp?g|mov|3gp)$/i)); + }, + audio: function (vType, vName) { + return $h.compare(vType, 'audio.*') && ($h.compare(vName, /(ogg|mp3|mp?g|wav)$/i) || + $h.compare(vName, /\.(og?|mp3|mp?g|wav)$/i)); + }, + flash: function (vType, vName) { + return $h.compare(vType, 'application/x-shockwave-flash', true) || $h.compare(vName, + /\.(swf)$/i); + }, + pdf: function (vType, vName) { + return $h.compare(vType, 'application/pdf', true) || $h.compare(vName, /\.(pdf)$/i); + }, + object: function () { + return true; + }, + other: function () { + return true; + } + }, + fileActionSettings: { + showRemove: true, + showUpload: true, + showDownload: true, + showZoom: true, + showDrag: true, + removeIcon: '', + removeClass: defBtnCss1, + removeErrorClass: 'btn btn-sm btn-kv btn-danger', + removeTitle: 'Remove file', + uploadIcon: '', + uploadClass: defBtnCss1, + uploadTitle: 'Upload file', + uploadRetryIcon: '', + uploadRetryTitle: 'Retry upload', + downloadIcon: '', + downloadClass: defBtnCss1, + downloadTitle: 'Download file', + zoomIcon: '', + zoomClass: defBtnCss1, + zoomTitle: 'View Details', + dragIcon: '', + dragClass: 'text-primary', + dragTitle: 'Move / Rearrange', + dragSettings: {}, + indicatorNew: '', + indicatorSuccess: '', + indicatorError: '', + indicatorLoading: '', + indicatorPaused: '', + indicatorNewTitle: 'Not uploaded yet', + indicatorSuccessTitle: 'Uploaded', + indicatorErrorTitle: 'Upload Error', + indicatorLoadingTitle: 'Uploading …', + indicatorPausedTitle: 'Upload Paused' + } + }; + $.each(self.defaults, function (key, setting) { + if (key === 'allowedPreviewTypes') { + if (self.allowedPreviewTypes === undefined) { + self.allowedPreviewTypes = setting; + } + return; + } + self[key] = $.extend(true, {}, setting, self[key]); + }); + self._initPreviewTemplates(); + }, + _initPreviewTemplates: function () { + var self = this, tags = self.previewMarkupTags, tagBef, tagAft = tags.tagAfter; + $.each(self.previewContentTemplates, function (key, value) { + if ($h.isEmpty(self.previewTemplates[key])) { + tagBef = tags.tagBefore2; + if (key === 'generic' || key === 'image') { + tagBef = tags.tagBefore1; + } + if (self._isPdfRendered() && key === 'pdf') { + tagBef = tagBef.replace('kv-file-content', 'kv-file-content kv-pdf-rendered'); + } + self.previewTemplates[key] = tagBef + value + tagAft; + } + }); + }, + _initPreviewCache: function () { + var self = this; + self.previewCache = { + data: {}, + init: function () { + var content = self.initialPreview; + if (content.length > 0 && !$h.isArray(content)) { + content = content.split(self.initialPreviewDelimiter); + } + self.previewCache.data = { + content: content, + config: self.initialPreviewConfig, + tags: self.initialPreviewThumbTags + }; + }, + count: function (skipNull) { + if (!self.previewCache.data || !self.previewCache.data.content) { + return 0; + } + if (skipNull) { + var chk = self.previewCache.data.content.filter(function (n) { + return n !== null; + }); + return chk.length; + } + return self.previewCache.data.content.length; + }, + get: function (i, isDisabled) { + var ind = $h.INIT_FLAG + i, data = self.previewCache.data, config = data.config[i], + content = data.content[i], out, $tmp, cat, ftr, + fname, ftype, frameClass, asData = $h.ifSet('previewAsData', config, self.initialPreviewAsData), + a = config ? {title: config.title || null, alt: config.alt || null} : {title: null, alt: null}, + parseTemplate = function (cat, dat, fname, ftype, ftr, ind, fclass, t) { + var fc = ' file-preview-initial ' + $h.SORT_CSS + (fclass ? ' ' + fclass : ''), + id = self.previewInitId + '-' + ind, + fileId = config && config.fileId || id; + /** @namespace config.zoomData */ + return self._generatePreviewTemplate(cat, dat, fname, ftype, id, fileId, false, null, fc, + ftr, ind, t, a, config && config.zoomData || dat); + }; + if (!content || !content.length) { + return ''; + } + isDisabled = isDisabled === undefined ? true : isDisabled; + cat = $h.ifSet('type', config, self.initialPreviewFileType || 'generic'); + fname = $h.ifSet('filename', config, $h.ifSet('caption', config)); + ftype = $h.ifSet('filetype', config, cat); + ftr = self.previewCache.footer(i, isDisabled, (config && config.size || null)); + frameClass = $h.ifSet('frameClass', config); + if (asData) { + out = parseTemplate(cat, content, fname, ftype, ftr, ind, frameClass); + } else { + out = parseTemplate('generic', content, fname, ftype, ftr, ind, frameClass, cat) + .setTokens({'content': data.content[i]}); + } + if (data.tags.length && data.tags[i]) { + out = $h.replaceTags(out, data.tags[i]); + } + /** @namespace config.frameAttr */ + if (!$h.isEmpty(config) && !$h.isEmpty(config.frameAttr)) { + $tmp = $h.createElement(out); + $tmp.find('.file-preview-initial').attr(config.frameAttr); + out = $tmp.html(); + $tmp.remove(); + } + return out; + }, + clean: function (data) { + data.content = $h.cleanArray(data.content); + data.config = $h.cleanArray(data.config); + data.tags = $h.cleanArray(data.tags); + self.previewCache.data = data; + }, + add: function (content, config, tags, append) { + var data = self.previewCache.data, index; + if (!content || !content.length) { + return 0; + } + index = content.length - 1; + if (!$h.isArray(content)) { + content = content.split(self.initialPreviewDelimiter); + } + if (append && data.content) { + index = data.content.push(content[0]) - 1; + data.config[index] = config; + data.tags[index] = tags; + } else { + data.content = content; + data.config = config; + data.tags = tags; + } + self.previewCache.clean(data); + return index; + }, + set: function (content, config, tags, append) { + var data = self.previewCache.data, i, chk; + if (!content || !content.length) { + return; + } + if (!$h.isArray(content)) { + content = content.split(self.initialPreviewDelimiter); + } + chk = content.filter(function (n) { + return n !== null; + }); + if (!chk.length) { + return; + } + if (data.content === undefined) { + data.content = []; + } + if (data.config === undefined) { + data.config = []; + } + if (data.tags === undefined) { + data.tags = []; + } + if (append) { + for (i = 0; i < content.length; i++) { + if (content[i]) { + data.content.push(content[i]); + } + } + for (i = 0; i < config.length; i++) { + if (config[i]) { + data.config.push(config[i]); + } + } + for (i = 0; i < tags.length; i++) { + if (tags[i]) { + data.tags.push(tags[i]); + } + } + } else { + data.content = content; + data.config = config; + data.tags = tags; + } + self.previewCache.clean(data); + }, + unset: function (index) { + var chk = self.previewCache.count(), rev = self.reversePreviewOrder; + if (!chk) { + return; + } + if (chk === 1) { + self.previewCache.data.content = []; + self.previewCache.data.config = []; + self.previewCache.data.tags = []; + self.initialPreview = []; + self.initialPreviewConfig = []; + self.initialPreviewThumbTags = []; + return; + } + self.previewCache.data.content = $h.spliceArray(self.previewCache.data.content, index, rev); + self.previewCache.data.config = $h.spliceArray(self.previewCache.data.config, index, rev); + self.previewCache.data.tags = $h.spliceArray(self.previewCache.data.tags, index, rev); + var data = $.extend(true, {}, self.previewCache.data); + self.previewCache.clean(data); + }, + out: function () { + var html = '', caption, len = self.previewCache.count(), i, content; + if (len === 0) { + return {content: '', caption: ''}; + } + for (i = 0; i < len; i++) { + content = self.previewCache.get(i); + html = self.reversePreviewOrder ? (content + html) : (html + content); + } + caption = self._getMsgSelected(len); + return {content: html, caption: caption}; + }, + footer: function (i, isDisabled, size) { + var data = self.previewCache.data || {}; + if ($h.isEmpty(data.content)) { + return ''; + } + if ($h.isEmpty(data.config) || $h.isEmpty(data.config[i])) { + data.config[i] = {}; + } + isDisabled = isDisabled === undefined ? true : isDisabled; + var config = data.config[i], caption = $h.ifSet('caption', config), a, + width = $h.ifSet('width', config, 'auto'), url = $h.ifSet('url', config, false), + key = $h.ifSet('key', config, null), fileId = $h.ifSet('fileId', config, null), + fs = self.fileActionSettings, initPreviewShowDel = self.initialPreviewShowDelete || false, + downloadInitialUrl = !self.initialPreviewDownloadUrl ? '' : + self.initialPreviewDownloadUrl + '?key=' + key + (fileId ? '&fileId=' + fileId : ''), + dUrl = config.downloadUrl || downloadInitialUrl, + dFil = config.filename || config.caption || '', + initPreviewShowDwl = !!(dUrl), + sDel = $h.ifSet('showRemove', config, initPreviewShowDel), + sDwl = $h.ifSet('showDownload', config, $h.ifSet('showDownload', fs, initPreviewShowDwl)), + sZm = $h.ifSet('showZoom', config, $h.ifSet('showZoom', fs, true)), + sDrg = $h.ifSet('showDrag', config, $h.ifSet('showDrag', fs, true)), + dis = (url === false) && isDisabled; + sDwl = sDwl && config.downloadUrl !== false && !!dUrl; + a = self._renderFileActions(config, false, sDwl, sDel, sZm, sDrg, dis, url, key, true, dUrl, dFil); + return self._getLayoutTemplate('footer').setTokens({ + 'progress': self._renderThumbProgress(), + 'actions': a, + 'caption': caption, + 'size': self._getSize(size), + 'width': width, + 'indicator': '' + }); + } + }; + self.previewCache.init(); + }, + _isPdfRendered: function () { + var self = this, useLib = self.usePdfRenderer, + flag = typeof useLib === 'function' ? useLib() : !!useLib; + return flag && self.pdfRendererUrl; + }, + _handler: function ($el, event, callback) { + var self = this, ns = self.namespace, ev = event.split(' ').join(ns + ' ') + ns; + if (!$el || !$el.length) { + return; + } + $el.off(ev).on(ev, callback); + }, + _encodeURI: function (vUrl) { + var self = this; + return self.encodeUrl ? encodeURI(vUrl) : vUrl; + }, + _log: function (msg, tokens) { + var self = this, id = self.$element.attr('id'); + if (!self.showConsoleLogs) { + return; + } + if (id) { + msg = '"' + id + '": ' + msg; + } + msg = 'bootstrap-fileinput: ' + msg; + if (typeof tokens === 'object') { + msg = msg.setTokens(tokens); + } + if (window.console && typeof window.console.log !== 'undefined') { + window.console.log(msg); + } else { + window.alert(msg); + } + }, + _validate: function () { + var self = this, status = self.$element.attr('type') === 'file'; + if (!status) { + self._log($h.logMessages.badInputType); + } + return status; + }, + _errorsExist: function () { + var self = this, $err, $errList = self.$errorContainer.find('li'); + if ($errList.length) { + return true; + } + $err = $h.createElement(self.$errorContainer.html()); + $err.find('.kv-error-close').remove(); + $err.find('ul').remove(); + return !!$.trim($err.text()).length; + }, + _errorHandler: function (evt, caption) { + var self = this, err = evt.target.error, showError = function (msg) { + self._showError(msg.replace('{name}', caption)); + }; + /** @namespace err.NOT_FOUND_ERR */ + /** @namespace err.SECURITY_ERR */ + /** @namespace err.NOT_READABLE_ERR */ + if (err.code === err.NOT_FOUND_ERR) { + showError(self.msgFileNotFound); + } else { + if (err.code === err.SECURITY_ERR) { + showError(self.msgFileSecured); + } else { + if (err.code === err.NOT_READABLE_ERR) { + showError(self.msgFileNotReadable); + } else { + if (err.code === err.ABORT_ERR) { + showError(self.msgFilePreviewAborted); + } else { + showError(self.msgFilePreviewError); + } + } + } + } + }, + _addError: function (msg) { + var self = this, $error = self.$errorContainer; + if (msg && $error.length) { + $h.setHtml($error, self.errorCloseButton + msg); + self._handler($error.find('.kv-error-close'), 'click', function () { + setTimeout(function () { + if (self.showPreview && !self.getFrames().length) { + self.clear(); + } + $error.fadeOut('slow'); + }, self.processDelay); + }); + } + }, + _setValidationError: function (css) { + var self = this; + css = (css ? css + ' ' : '') + 'has-error'; + self.$container.removeClass(css).addClass('has-error'); + $h.addCss(self.$caption, 'is-invalid'); + }, + _resetErrors: function (fade) { + var self = this, $error = self.$errorContainer, history = self.resumableUploadOptions.retainErrorHistory; + if (self.isPersistentError || (self.enableResumableUpload && history)) { + return; + } + self.isError = false; + self.$container.removeClass('has-error'); + self.$caption.removeClass('is-invalid is-valid file-processing'); + $error.html(''); + if (fade) { + $error.fadeOut('slow'); + } else { + $error.hide(); + } + }, + _showFolderError: function (folders) { + var self = this, $error = self.$errorContainer, msg; + if (!folders) { + return; + } + if (!self.isAjaxUpload) { + self._clearFileInput(); + } + msg = self.msgFoldersNotAllowed.replace('{n}', folders); + self._addError(msg); + self._setValidationError(); + $error.fadeIn(self.fadeDelay); + self._raise('filefoldererror', [folders, msg]); + }, + _showFileError: function (msg, params, event) { + var self = this, $error = self.$errorContainer, ev = event || 'fileuploaderror', + fId = params && params.fileId || '', e = params && params.id ? + '
  • ' + msg + '
  • ' : '
  • ' + msg + '
  • '; + + if ($error.find('ul').length === 0) { + self._addError('
      ' + e + '
    '); + } else { + $error.find('ul').append(e); + } + $error.fadeIn(self.fadeDelay); + self._raise(ev, [params, msg]); + self._setValidationError('file-input-new'); + return true; + }, + _showError: function (msg, params, event) { + var self = this, $error = self.$errorContainer, ev = event || 'fileerror'; + params = params || {}; + params.reader = self.reader; + self._addError(msg); + $error.fadeIn(self.fadeDelay); + self._raise(ev, [params, msg]); + if (!self.isAjaxUpload) { + self._clearFileInput(); + } + self._setValidationError('file-input-new'); + self.$btnUpload.attr('disabled', true); + return true; + }, + _noFilesError: function (params) { + var self = this, label = self.minFileCount > 1 ? self.filePlural : self.fileSingle, + msg = self.msgFilesTooLess.replace('{n}', self.minFileCount).replace('{files}', label), + $error = self.$errorContainer; + msg = '
  • ' + msg + '
  • '; + if ($error.find('ul').length === 0) { + self._addError('
      ' + msg + '
    '); + } else { + $error.find('ul').append(msg); + } + self.isError = true; + self._updateFileDetails(0); + $error.fadeIn(self.fadeDelay); + self._raise('fileerror', [params, msg]); + self._clearFileInput(); + self._setValidationError(); + }, + _parseError: function (operation, jqXHR, errorThrown, fileName) { + /** @namespace jqXHR.responseJSON */ + var self = this, errMsg = $.trim(errorThrown + ''), textPre, errText, text; + errText = jqXHR.responseJSON && jqXHR.responseJSON.error ? jqXHR.responseJSON.error.toString() : ''; + text = errText ? errText : jqXHR.responseText; + if (self.cancelling && self.msgUploadAborted) { + errMsg = self.msgUploadAborted; + } + if (self.showAjaxErrorDetails && text) { + if (errText) { + errMsg = $.trim(errText + ''); + } else { + text = $.trim(text.replace(/\n\s*\n/g, '\n')); + textPre = text.length ? '
    ' + text + '
    ' : ''; + errMsg += errMsg ? textPre : text; + } + } + if (!errMsg) { + errMsg = self.msgAjaxError.replace('{operation}', operation); + } + self.cancelling = false; + return fileName ? '' + fileName + ': ' + errMsg : errMsg; + }, + _parseFileType: function (type, name) { + var self = this, isValid, vType, cat, i, types = self.allowedPreviewTypes || []; + if (type === 'application/text-plain') { + return 'text'; + } + for (i = 0; i < types.length; i++) { + cat = types[i]; + isValid = self.fileTypeSettings[cat]; + vType = isValid(type, name) ? cat : ''; + if (!$h.isEmpty(vType)) { + return vType; + } + } + return 'other'; + }, + _getPreviewIcon: function (fname) { + var self = this, ext, out = null; + if (fname && fname.indexOf('.') > -1) { + ext = fname.split('.').pop(); + if (self.previewFileIconSettings) { + out = self.previewFileIconSettings[ext] || self.previewFileIconSettings[ext.toLowerCase()] || null; + } + if (self.previewFileExtSettings) { + $.each(self.previewFileExtSettings, function (key, func) { + if (self.previewFileIconSettings[key] && func(ext)) { + out = self.previewFileIconSettings[key]; + //noinspection UnnecessaryReturnStatementJS + return; + } + }); + } + } + return out || self.previewFileIcon; + }, + _parseFilePreviewIcon: function (content, fname) { + var self = this, icn = self._getPreviewIcon(fname), out = content; + if (out.indexOf('{previewFileIcon}') > -1) { + out = out.setTokens({'previewFileIconClass': self.previewFileIconClass, 'previewFileIcon': icn}); + } + return out; + }, + _raise: function (event, params) { + var self = this, e = $.Event(event); + if (params !== undefined) { + self.$element.trigger(e, params); + } else { + self.$element.trigger(e); + } + var out = e.result, isAborted = out === false; + if (e.isDefaultPrevented() || isAborted) { + return false; + } + if (e.type === 'filebatchpreupload' && (out || isAborted)) { + self.ajaxAborted = out; + return false; + } + switch (event) { + // ignore these events + case 'filebatchuploadcomplete': + case 'filebatchuploadsuccess': + case 'fileuploaded': + case 'fileclear': + case 'filecleared': + case 'filereset': + case 'fileerror': + case 'filefoldererror': + case 'fileuploaderror': + case 'filebatchuploaderror': + case 'filedeleteerror': + case 'filecustomerror': + case 'filesuccessremove': + break; + // receive data response via `filecustomerror` event` + default: + if (!self.ajaxAborted) { + self.ajaxAborted = out; + } + break; + } + return true; + }, + _listenFullScreen: function (isFullScreen) { + var self = this, $modal = self.$modal, $btnFull, $btnBord; + if (!$modal || !$modal.length) { + return; + } + $btnFull = $modal && $modal.find('.btn-kv-fullscreen'); + $btnBord = $modal && $modal.find('.btn-kv-borderless'); + if (!$btnFull.length || !$btnBord.length) { + return; + } + $btnFull.removeClass('active').attr('aria-pressed', 'false'); + $btnBord.removeClass('active').attr('aria-pressed', 'false'); + if (isFullScreen) { + $btnFull.addClass('active').attr('aria-pressed', 'true'); + } else { + $btnBord.addClass('active').attr('aria-pressed', 'true'); + } + if ($modal.hasClass('file-zoom-fullscreen')) { + self._maximizeZoomDialog(); + } else { + if (isFullScreen) { + self._maximizeZoomDialog(); + } else { + $btnBord.removeClass('active').attr('aria-pressed', 'false'); + } + } + }, + _listen: function () { + var self = this, $el = self.$element, $form = self.$form, $cont = self.$container, fullScreenEv; + self._handler($el, 'click', function (e) { + self._initFileSelected(); + if ($el.hasClass('file-no-browse')) { + if ($el.data('zoneClicked')) { + $el.data('zoneClicked', false); + } else { + e.preventDefault(); + } + } + }); + self._handler($el, 'change', $.proxy(self._change, self)); + self._handler(self.$caption, 'paste', $.proxy(self.paste, self)); + if (self.showBrowse) { + self._handler(self.$btnFile, 'click', $.proxy(self._browse, self)); + self._handler(self.$btnFile, 'keypress', function (e) { + var keycode = e.keyCode || e.which + if (keycode === 13) { + $el.trigger('click'); + self._browse(e); + } + }); + } + self._handler($cont.find('.fileinput-remove:not([disabled])'), 'click', $.proxy(self.clear, self)); + self._handler($cont.find('.fileinput-cancel'), 'click', $.proxy(self.cancel, self)); + self._handler($cont.find('.fileinput-pause'), 'click', $.proxy(self.pause, self)); + self._initDragDrop(); + self._handler($form, 'reset', $.proxy(self.clear, self)); + if (!self.isAjaxUpload) { + self._handler($form, 'submit', $.proxy(self._submitForm, self)); + } + self._handler(self.$container.find('.fileinput-upload'), 'click', $.proxy(self._uploadClick, self)); + self._handler($(window), 'resize', function () { + self._listenFullScreen(screen.width === window.innerWidth && screen.height === window.innerHeight); + }); + fullScreenEv = 'webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange'; + self._handler($(document), fullScreenEv, function () { + self._listenFullScreen($h.checkFullScreen()); + }); + self.$caption.on('focus', function () { + self.$captionContainer.focus(); + }); + self._autoFitContent(); + self._initClickable(); + self._refreshPreview(); + }, + _autoFitContent: function () { + var width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth, + self = this, config = width < 400 ? (self.previewSettingsSmall || self.defaults.previewSettingsSmall) : + (self.previewSettings || self.defaults.previewSettings), sel; + $.each(config, function (cat, settings) { + sel = '.file-preview-frame .file-preview-' + cat; + self.$preview.find(sel + '.kv-preview-data,' + sel + ' .kv-preview-data').css(settings); + }); + }, + _scanDroppedItems: function (item, files, path) { + path = path || ''; + var self = this, i, dirReader, readDir, errorHandler = function (e) { + self._log($h.logMessages.badDroppedFiles); + self._log(e); + }; + if (item.isFile) { + item.file(function (file) { + if (path) { + file.newPath = path + file.name; + } + files.push(file); + }, errorHandler); + } else { + if (item.isDirectory) { + dirReader = item.createReader(); + readDir = function () { + dirReader.readEntries(function (entries) { + if (entries && entries.length > 0) { + for (i = 0; i < entries.length; i++) { + self._scanDroppedItems(entries[i], files, path + item.name + '/'); + } + // recursively call readDir() again, since browser can only handle first 100 entries. + readDir(); + } + return null; + }, errorHandler); + }; + readDir(); + } + } + + }, + _initDragDrop: function () { + var self = this, $zone = self.$dropZone; + if (self.dropZoneEnabled && self.showPreview) { + self._handler($zone, 'dragenter dragover', $.proxy(self._zoneDragEnter, self)); + self._handler($zone, 'dragleave', $.proxy(self._zoneDragLeave, self)); + self._handler($zone, 'drop', $.proxy(self._zoneDrop, self)); + self._handler($(document), 'dragenter dragover drop', self._zoneDragDropInit); + } + }, + _zoneDragDropInit: function (e) { + e.stopPropagation(); + e.preventDefault(); + }, + _zoneDragEnter: function (e) { + var self = this, dt = e.originalEvent.dataTransfer, hasFiles = $.inArray('Files', dt.types) > -1; + self._zoneDragDropInit(e); + if (self.isDisabled || !hasFiles) { + dt.effectAllowed = 'none'; + dt.dropEffect = 'none'; + return; + } + dt.dropEffect = 'copy'; + if (self._raise('fileDragEnter', {'sourceEvent': e, 'files': dt.types.Files})) { + $h.addCss(self.$dropZone, 'file-highlighted'); + } + }, + _zoneDragLeave: function (e) { + var self = this; + self._zoneDragDropInit(e); + if (self.isDisabled) { + return; + } + if (self._raise('fileDragLeave', {'sourceEvent': e})) { + self.$dropZone.removeClass('file-highlighted'); + } + + }, + _dropFiles: function (e, files) { + var self = this, $el = self.$element; + if (!self.isAjaxUpload) { + self.changeTriggered = true; + $el.get(0).files = files; + setTimeout(function () { + self.changeTriggered = false; + $el.trigger('change' + self.namespace); + }, self.processDelay); + } else { + self._change(e, files); + } + self.$dropZone.removeClass('file-highlighted'); + }, + _zoneDrop: function (e) { + /** @namespace e.originalEvent.dataTransfer */ + var self = this, i, $el = self.$element, dt = e.originalEvent.dataTransfer, + files = dt.files, items = dt.items, folders = $h.getDragDropFolders(items); + e.preventDefault(); + if (self.isDisabled || $h.isEmpty(files)) { + return; + } + if (!self._raise('fileDragDrop', {'sourceEvent': e, 'files': files})) { + return; + } + if (folders > 0) { + if (!self.isAjaxUpload) { + self._showFolderError(folders); + return; + } + files = []; + for (i = 0; i < items.length; i++) { + var item = items[i].webkitGetAsEntry(); + if (item) { + self._scanDroppedItems(item, files); + } + } + setTimeout(function () { + self._dropFiles(e, files); + }, 500); + } else { + self._dropFiles(e, files); + } + }, + _uploadClick: function (e) { + var self = this, $btn = self.$container.find('.fileinput-upload'), $form, + isEnabled = !$btn.hasClass('disabled') && $h.isEmpty($btn.attr('disabled')); + if (e && e.isDefaultPrevented()) { + return; + } + if (!self.isAjaxUpload) { + if (isEnabled && $btn.attr('type') !== 'submit') { + $form = $btn.closest('form'); + // downgrade to normal form submit if possible + if ($form.length) { + $form.trigger('submit'); + } + e.preventDefault(); + } + return; + } + e.preventDefault(); + if (isEnabled) { + self.upload(); + } + }, + _submitForm: function () { + var self = this; + return self._isFileSelectionValid() && !self._abort({}); + }, + _clearPreview: function () { + var self = this, + $thumbs = self.showUploadedThumbs ? self.getFrames(':not(.file-preview-success)') : self.getFrames(); + $thumbs.each(function () { + var $thumb = $(this); + $thumb.remove(); + }); + if (!self.getFrames().length || !self.showPreview) { + self._resetUpload(); + } + self._validateDefaultPreview(); + }, + _initSortable: function () { + var self = this, $el = self.$preview, settings, selector = '.' + $h.SORT_CSS, $cont, $body = $('body'), + $html = $('html'), rev = self.reversePreviewOrder, Sortable = window.Sortable, beginGrab, endGrab; + if (!Sortable || $el.find(selector).length === 0) { + return; + } + $cont = $body.length ? $body : ($html.length ? $html : self.$container); + beginGrab = function () { + $cont.addClass('file-grabbing'); + }; + endGrab = function () { + $cont.removeClass('file-grabbing'); + }; + settings = { + handle: '.drag-handle-init', + dataIdAttr: 'data-fileid', + animation: 600, + draggable: selector, + scroll: false, + forceFallback: true, + onChoose: beginGrab, + onStart: beginGrab, + onUnchoose: endGrab, + onEnd: endGrab, + onSort: function (e) { + var oldIndex = e.oldIndex, newIndex = e.newIndex, i = 0, len = self.initialPreviewConfig.length, + exceedsLast = len > 0 && newIndex >= len, $item = $(e.item), $first; + if (exceedsLast) { + newIndex = len - 1; + } + self.initialPreview = $h.moveArray(self.initialPreview, oldIndex, newIndex, rev); + self.initialPreviewConfig = $h.moveArray(self.initialPreviewConfig, oldIndex, newIndex, rev); + self.previewCache.init(); + self.getFrames('.file-preview-initial').each(function () { + $(this).attr('data-fileindex', $h.INIT_FLAG + i); + i++; + }); + if (exceedsLast) { + $first = self.getFrames(':not(.file-preview-initial):first'); + if ($first.length) { + $item.slideUp(function () { + $item.insertBefore($first).slideDown(); + }); + } + } + self._raise('filesorted', { + previewId: $item.attr('id'), + 'oldIndex': oldIndex, + 'newIndex': newIndex, + stack: self.initialPreviewConfig + }); + }, + }; + $.extend(true, settings, self.fileActionSettings.dragSettings); + if (self.sortable) { + self.sortable.destroy(); + } + self.sortable = Sortable.create($el[0], settings); + }, + _setPreviewContent: function (content) { + var self = this; + $h.setHtml(self.$preview, content); + self._autoFitContent(); + }, + _initPreviewImageOrientations: function () { + var self = this, i = 0, canOrientImage = self.canOrientImage; + if (!self.autoOrientImageInitial && !canOrientImage) { + return; + } + self.getFrames('.file-preview-initial').each(function () { + var $thumb = $(this), $img, $zoomImg, id, config = self.initialPreviewConfig[i]; + /** @namespace config.exif */ + if (config && config.exif && config.exif.Orientation) { + id = $thumb.attr('id'); + $img = $thumb.find('>.kv-file-content img'); + $zoomImg = self._getZoom(id, ' >.kv-file-content img'); + if (canOrientImage) { + $img.css('image-orientation', (self.autoOrientImageInitial ? 'from-image' : 'none')); + } else { + self.setImageOrientation($img, $zoomImg, config.exif.Orientation, $thumb); + } + } + i++; + }); + }, + _initPreview: function (isInit) { + var self = this, cap = self.initialCaption || '', out; + if (!self.previewCache.count(true)) { + self._clearPreview(); + if (isInit) { + self._setCaption(cap); + } else { + self._initCaption(); + } + return; + } + out = self.previewCache.out(); + cap = isInit && self.initialCaption ? self.initialCaption : out.caption; + self._setPreviewContent(out.content); + self._setInitThumbAttr(); + self._setCaption(cap); + self._initSortable(); + if (!$h.isEmpty(out.content)) { + self.$container.removeClass('file-input-new'); + } + self._initPreviewImageOrientations(); + }, + _getZoomButton: function (type) { + var self = this, label = self.previewZoomButtonIcons[type], css = self.previewZoomButtonClasses[type], + title = ' title="' + (self.previewZoomButtonTitles[type] || '') + '" ', tag = $h.isBs(5) ? 'bs-' : '', + params = title + (type === 'close' ? ' data-' + tag + 'dismiss="modal" aria-hidden="true"' : ''); + if (type === 'fullscreen' || type === 'borderless' || type === 'toggleheader') { + params += ' data-toggle="button" aria-pressed="false" autocomplete="off"'; + } + return ''; + }, + _getModalContent: function () { + var self = this; + return self._getLayoutTemplate('modal').setTokens({ + 'rtl': self.rtl ? ' kv-rtl' : '', + 'zoomFrameClass': self.frameClass, + 'prev': self._getZoomButton('prev'), + 'next': self._getZoomButton('next'), + 'toggleheader': self._getZoomButton('toggleheader'), + 'fullscreen': self._getZoomButton('fullscreen'), + 'borderless': self._getZoomButton('borderless'), + 'close': self._getZoomButton('close') + }); + }, + _listenModalEvent: function (event) { + var self = this, $modal = self.$modal, getParams = function (e) { + return { + sourceEvent: e, + previewId: $modal.data('previewId'), + modal: $modal + }; + }; + $modal.on(event + '.bs.modal', function (e) { + if (e.namespace !== 'bs.modal') { + return; + } + var $btnFull = $modal.find('.btn-fullscreen'), $btnBord = $modal.find('.btn-borderless'); + if ($modal.data('fileinputPluginId') === self.$element.attr('id')) { + self._raise('filezoom' + event, getParams(e)); + } + if (event === 'shown') { + $btnBord.removeClass('active').attr('aria-pressed', 'false'); + $btnFull.removeClass('active').attr('aria-pressed', 'false'); + if ($modal.hasClass('file-zoom-fullscreen')) { + self._maximizeZoomDialog(); + if ($h.checkFullScreen()) { + $btnFull.addClass('active').attr('aria-pressed', 'true'); + } else { + $btnBord.addClass('active').attr('aria-pressed', 'true'); + } + } + } + }); + }, + _initZoom: function () { + var self = this, $dialog, modalMain = self._getLayoutTemplate('modalMain'), modalId = '#' + $h.MODAL_ID; + modalMain = self._setTabIndex('modal', modalMain); + if (!self.showPreview) { + return; + } + self.$modal = $(modalId); + if (!self.$modal || !self.$modal.length) { + $dialog = $h.createElement($h.cspBuffer.stash(modalMain)).insertAfter(self.$container); + self.$modal = $(modalId).insertBefore($dialog); + $h.cspBuffer.apply(self.$modal); + $dialog.remove(); + } + $h.initModal(self.$modal); + self.$modal.html($h.cspBuffer.stash(self._getModalContent())); + $h.cspBuffer.apply(self.$modal); + $.each($h.MODAL_EVENTS, function (key, event) { + self._listenModalEvent(event); + }); + }, + _initZoomButtons: function () { + var self = this, previewId = self.$modal.data('previewId') || '', $first, $last, + thumbs = self.getFrames().toArray(), len = thumbs.length, $prev = self.$modal.find('.btn-kv-prev'), + $next = self.$modal.find('.btn-kv-next'); + if (thumbs.length < 2) { + $prev.hide(); + $next.hide(); + return; + } else { + $prev.show(); + $next.show(); + } + if (!len) { + return; + } + $first = $(thumbs[0]); + $last = $(thumbs[len - 1]); + $prev.removeAttr('disabled'); + $next.removeAttr('disabled'); + if (self.reversePreviewOrder) { + [$prev, $next] = [$next, $prev]; // swap + } + if ($first.length && $first.attr('id') === previewId) { + $prev.attr('disabled', true); + } + if ($last.length && $last.attr('id') === previewId) { + $next.attr('disabled', true); + } + }, + _maximizeZoomDialog: function () { + var self = this, $modal = self.$modal, $head = $modal.find('.modal-header:visible'), + $foot = $modal.find('.modal-footer:visible'), $body = $modal.find('.kv-zoom-body'), + h = $(window).height(), diff = 0; + $modal.addClass('file-zoom-fullscreen'); + if ($head && $head.length) { + h -= $head.outerHeight(true); + } + if ($foot && $foot.length) { + h -= $foot.outerHeight(true); + } + if ($body && $body.length) { + diff = $body.outerHeight(true) - $body.height(); + h -= diff; + } + $modal.find('.kv-zoom-body').height(h); + }, + _resizeZoomDialog: function (fullScreen) { + var self = this, $modal = self.$modal, $btnFull = $modal.find('.btn-kv-fullscreen'), + $btnBord = $modal.find('.btn-kv-borderless'); + if ($modal.hasClass('file-zoom-fullscreen')) { + $h.toggleFullScreen(false); + if (!fullScreen) { + if (!$btnFull.hasClass('active')) { + $modal.removeClass('file-zoom-fullscreen'); + self.$modal.find('.kv-zoom-body').css('height', self.zoomModalHeight); + } else { + $btnFull.removeClass('active').attr('aria-pressed', 'false'); + } + } else { + if (!$btnFull.hasClass('active')) { + $modal.removeClass('file-zoom-fullscreen'); + self._resizeZoomDialog(true); + if ($btnBord.hasClass('active')) { + $btnBord.removeClass('active').attr('aria-pressed', 'false'); + } + } + } + } else { + if (!fullScreen) { + self._maximizeZoomDialog(); + return; + } + $h.toggleFullScreen(true); + } + $modal.focus(); + }, + _setZoomContent: function ($frame, navigate) { + var self = this, $content, tmplt, body, title, $body, $dataEl, config, previewId = $frame.attr('id'), + $zoomPreview = self._getZoom(previewId), $modal = self.$modal, $tmp, desc, $desc, + $btnFull = $modal.find('.btn-kv-fullscreen'), $btnBord = $modal.find('.btn-kv-borderless'), cap, size, + $btnTogh = $modal.find('.btn-kv-toggleheader'), dir = navigate === 'prev' ? 'Left' : 'Right', + slideIn = 'slideIn' + dir, slideOut = 'slideOut' + dir, parsed, zoomData = $frame.data('zoom'); + if (zoomData) { + zoomData = decodeURIComponent(zoomData); + parsed = $zoomPreview.html().replace($h.ZOOM_VAR, '').setTokens({zoomData: zoomData}); + $zoomPreview.html(parsed); + $frame.data('zoom', ''); + $zoomPreview.attr('data-zoom', zoomData); + } + tmplt = $zoomPreview.attr('data-template') || 'generic'; + $content = $zoomPreview.find('.kv-file-content'); + body = $content.length ? '\n' + $content.html() : ''; + cap = $frame.data('caption') || self.msgZoomModalHeading; + size = $frame.data('size') || ''; + desc = $frame.data('description') || ''; + $modal.find('.kv-zoom-caption').attr('title', cap).html(cap); + $modal.find('.kv-zoom-size').html(size); + $desc = $modal.find('.kv-zoom-description').hide(); + if (desc) { + if (self.showDescriptionClose) { + desc = self._getLayoutTemplate('descriptionClose').setTokens({ + closeIcon: self.previewZoomButtonIcons.close + }) + '' + desc; + } + $desc.show().html(desc); + if (self.showDescriptionClose) { + self._handler($modal.find('.kv-desc-hide'), 'click', function () { + $(this).parent().fadeOut('fast', function () { + $modal.focus(); + }); + }); + } + } + $body = $modal.find('.kv-zoom-body'); + $modal.removeClass('kv-single-content'); + if (navigate) { + $tmp = $body.addClass('file-thumb-loading').clone().insertAfter($body); + $h.setHtml($body, body).hide(); + $tmp.fadeOut('fast', function () { + $body.fadeIn('fast', function () { + $body.removeClass('file-thumb-loading'); + }); + $tmp.remove(); + }); + } else { + $h.setHtml($body, body); + } + config = self.previewZoomSettings[tmplt]; + if (config) { + $dataEl = $body.find('.kv-preview-data'); + $h.addCss($dataEl, 'file-zoom-detail'); + $.each(config, function (key, value) { + $dataEl.css(key, value); + if (($dataEl.attr('width') && key === 'width') || ($dataEl.attr('height') && key === 'height')) { + $dataEl.removeAttr(key); + } + }); + } + $modal.data('previewId', previewId); + self._handler($modal.find('.btn-kv-prev'), 'click', function () { + self._zoomSlideShow('prev', previewId); + }); + self._handler($modal.find('.btn-kv-next'), 'click', function () { + self._zoomSlideShow('next', previewId); + }); + self._handler($btnFull, 'click', function () { + self._resizeZoomDialog(true); + }); + self._handler($btnBord, 'click', function () { + self._resizeZoomDialog(false); + }); + self._handler($btnTogh, 'click', function () { + var $header = $modal.find('.modal-header'), $floatBar = $modal.find('.floating-buttons'), + ht, $actions = $header.find('.kv-zoom-actions'), resize = function (height) { + var $body = self.$modal.find('.kv-zoom-body'), h = self.zoomModalHeight; + if ($modal.hasClass('file-zoom-fullscreen')) { + h = $body.outerHeight(true); + if (!height) { + h = h - $header.outerHeight(true); + } + } + $body.css('height', height ? h + height : h); + }; + if ($header.is(':visible')) { + ht = $header.outerHeight(true); + $header.slideUp('slow', function () { + $actions.find('.btn').appendTo($floatBar); + resize(ht); + }); + } else { + $floatBar.find('.btn').appendTo($actions); + $header.slideDown('slow', function () { + resize(); + }); + } + $modal.focus(); + }); + self._handler($modal, 'keydown', function (e) { + var key = e.which || e.keyCode, delay = self.processDelay + 1, $prev = $(this).find('.btn-kv-prev'), + $next = $(this).find('.btn-kv-next'), vId = $(this).data('previewId'), vPrevKey, vNextKey; + [vPrevKey, vNextKey] = self.rtl ? [39, 37] : [37, 39]; + $.each({prev: [$prev, vPrevKey], next: [$next, vNextKey]}, function (direction, config) { + var $btn = config[0], vKey = config[1]; + if (key === vKey && $btn.length) { + $modal.focus(); + if (!$btn.attr('disabled')) { + $btn.focus(); + self._zoomSlideShow(direction, vId); + setTimeout(function () { + if ($btn.attr('disabled')) { + $modal.focus(); + } + }, delay); + } + } + }); + }); + }, + _showModal: function ($frame) { + var self = this, $modal = self.$modal, bs5Modal; + if (!$frame || !$frame.length) { + return; + } + $h.initModal($modal); + $h.setHtml($modal, self._getModalContent()); + self._setZoomContent($frame); + $modal.data({backdrop: false}); + //$modal.data('fileinputPluginId', self.$element.attr('id')); + $modal.modal('show'); + self._initZoomButtons(); + }, + _zoomPreview: function ($btn) { + var self = this, $frame; + if (!$btn.length) { + throw 'Cannot zoom to detailed preview!'; + } + $frame = $btn.closest($h.FRAMES); + self._showModal($frame); + }, + _zoomSlideShow: function (dir, previewId) { + var self = this, $btn = self.$modal.find('.kv-zoom-actions .btn-kv-' + dir), $targFrame, i, $thumb, + thumbsData = self.getFrames().toArray(), thumbs = [], len = thumbsData.length, out; + if (self.reversePreviewOrder) { + dir = dir === 'prev' ? 'next' : 'prev'; + } + if ($btn.attr('disabled')) { + return; + } + for (i = 0; i < len; i++) { + $thumb = $(thumbsData[i]); + if ($thumb && $thumb.length && $thumb.find('.kv-file-zoom:visible').length) { + thumbs.push(thumbsData[i]); + } + } + len = thumbs.length; + for (i = 0; i < len; i++) { + if ($(thumbs[i]).attr('id') === previewId) { + out = dir === 'prev' ? i - 1 : i + 1; + break; + } + } + if (out < 0 || out >= len || !thumbs[out]) { + return; + } + $targFrame = $(thumbs[out]); + if ($targFrame.length) { + self._setZoomContent($targFrame, dir); + } + self._initZoomButtons(); + self._raise('filezoom' + dir, {'previewId': previewId, modal: self.$modal}); + }, + _initZoomButton: function () { + var self = this; + self.$preview.find('.kv-file-zoom').each(function () { + var $el = $(this); + self._handler($el, 'click', function () { + self._zoomPreview($el); + }); + }); + }, + _inputFileCount: function () { + return this.$element[0].files.length; + }, + _refreshPreview: function () { + var self = this, files; + if ((!self._inputFileCount() && !self.isAjaxUpload) || !self.showPreview || !self.isPreviewable) { + return; + } + if (self.isAjaxUpload) { + if (self.fileManager.count() > 0) { + files = $.extend(true, {}, self.getFileList()); + self.fileManager.clear(); + self._clearFileInput(); + } else { + files = self.$element[0].files; + } + } else { + files = self.$element[0].files; + } + if (files && files.length) { + self.readFiles(files); + self._setFileDropZoneTitle(); + } + }, + _clearObjects: function ($el) { + $el.find('video audio').each(function () { + this.pause(); + $(this).remove(); + }); + $el.find('img object div').each(function () { + $(this).remove(); + }); + }, + _clearFileInput: function () { + var self = this, $el = self.$element, $srcFrm, $tmpFrm, $tmpEl; + if (!self._inputFileCount()) { + return; + } + $srcFrm = $el.closest('form'); + $tmpFrm = $(document.createElement('form')); + $tmpEl = $(document.createElement('div')); + $el.before($tmpEl); + if ($srcFrm.length) { + $srcFrm.after($tmpFrm); + } else { + $tmpEl.after($tmpFrm); + } + $tmpFrm.append($el).trigger('reset'); + $tmpEl.before($el).remove(); + $tmpFrm.remove(); + }, + _resetUpload: function () { + var self = this; + self.uploadStartTime = $h.now(); + self.uploadCache = []; + self.$btnUpload.removeAttr('disabled'); + self._setProgress(0); + self._hideProgress(); + self._resetErrors(false); + self._initAjax(); + self.fileManager.clearImages(); + self._resetCanvas(); + if (self.overwriteInitial) { + self.initialPreview = []; + self.initialPreviewConfig = []; + self.initialPreviewThumbTags = []; + self.previewCache.data = { + content: [], + config: [], + tags: [] + }; + } + }, + _resetCanvas: function () { + var self = this; + if (self.imageCanvas && self.imageCanvasContext) { + self.imageCanvasContext.clearRect(0, 0, self.imageCanvas.width, self.imageCanvas.height); + } + }, + _hasInitialPreview: function () { + var self = this; + return !self.overwriteInitial && self.previewCache.count(true); + }, + _resetPreview: function () { + var self = this, out, cap, $div, hasSuc = self.showUploadedThumbs, hasErr = !self.removeFromPreviewOnError, + includeProcessed = (hasSuc || hasErr) && self.isDuplicateError; + if (self.previewCache.count(true)) { + out = self.previewCache.out(); + if (includeProcessed) { + $div = $h.createElement('').insertAfter(self.$container); + self.getFrames().each(function () { + var $thumb = $(this); + if ((hasSuc && $thumb.hasClass('file-preview-success')) || + (hasErr && $thumb.hasClass('file-preview-error'))) { + $div.append($thumb); + } + }); + } + self._setPreviewContent(out.content); + self._setInitThumbAttr(); + cap = self.initialCaption ? self.initialCaption : out.caption; + self._setCaption(cap); + if (includeProcessed) { + $div.contents().appendTo(self.$preview); + $div.remove(); + } + } else { + self._clearPreview(); + self._initCaption(); + } + if (self.showPreview) { + self._initZoom(); + self._initSortable(); + } + self.isDuplicateError = false; + }, + _clearDefaultPreview: function () { + var self = this; + self.$preview.find('.file-default-preview').remove(); + }, + _validateDefaultPreview: function () { + var self = this; + if (!self.showPreview || $h.isEmpty(self.defaultPreviewContent)) { + return; + } + self._setPreviewContent('
    ' + self.defaultPreviewContent + '
    '); + self.$container.removeClass('file-input-new'); + self._initClickable(); + }, + _resetPreviewThumbs: function (isAjax) { + var self = this, out; + if (isAjax) { + self._clearPreview(); + self.clearFileStack(); + return; + } + if (self._hasInitialPreview()) { + out = self.previewCache.out(); + self._setPreviewContent(out.content); + self._setInitThumbAttr(); + self._setCaption(out.caption); + self._initPreviewActions(); + } else { + self._clearPreview(); + } + }, + _getLayoutTemplate: function (t) { + var self = this, template = self.layoutTemplates[t]; + if ($h.isEmpty(self.customLayoutTags)) { + return template; + } + return $h.replaceTags(template, self.customLayoutTags); + }, + _getPreviewTemplate: function (t) { + var self = this, templates = self.previewTemplates, template = templates[t] || templates.other; + if ($h.isEmpty(self.customPreviewTags)) { + return template; + } + return $h.replaceTags(template, self.customPreviewTags); + }, + _getOutData: function (formdata, jqXHR, responseData, filesData) { + var self = this; + jqXHR = jqXHR || {}; + responseData = responseData || {}; + filesData = filesData || self.fileManager.list(); + return { + formdata: formdata, + files: filesData, + filenames: self.filenames, + filescount: self.getFilesCount(), + extra: self._getExtraData(), + response: responseData, + reader: self.reader, + jqXHR: jqXHR + }; + }, + _getMsgSelected: function (n, processing) { + var self = this, strFiles = n === 1 ? self.fileSingle : self.filePlural; + return n > 0 ? self.msgSelected.replace('{n}', n).replace('{files}', strFiles) : + (processing ? self.msgProcessing : self.msgNoFilesSelected); + }, + _getFrame: function (id, skipWarning) { + var self = this, $frame = $h.getFrameElement(self.$preview, id); + if (self.showPreview && !skipWarning && !$frame.length) { + self._log($h.logMessages.invalidThumb, {id: id}); + } + return $frame; + }, + _getZoom: function (id, selector) { + var self = this, $frame = $h.getZoomElement(self.$preview, id, selector); + if (self.showPreview && !$frame.length) { + self._log($h.logMessages.invalidThumb, {id: id}); + } + return $frame; + }, + _getThumbs: function (css) { + css = css || ''; + return this.getFrames(':not(.file-preview-initial)' + css); + }, + _getThumbId: function (fileId) { + var self = this; + return self.previewInitId + '-' + fileId; + }, + _getExtraData: function (fileId, index) { + var self = this, data = self.uploadExtraData; + if (typeof self.uploadExtraData === 'function') { + data = self.uploadExtraData(fileId, index); + } + return data; + }, + _initXhr: function (xhrobj, fileId) { + var self = this, fm = self.fileManager, func = function (event) { + var pct = 0, total = event.total, loaded = event.loaded || event.position, + stats = fm.getUploadStats(fileId, loaded, total); + /** @namespace event.lengthComputable */ + if (event.lengthComputable && !self.enableResumableUpload) { + pct = $h.round(loaded / total * 100); + } + if (fileId) { + self._setFileUploadStats(fileId, pct, stats); + } else { + self._setProgress(pct, null, null, self._getStats(stats)); + } + self._raise('fileajaxprogress', [stats]); + }; + if (xhrobj.upload) { + if (self.progressDelay) { + func = $h.debounce(func, self.progressDelay); + } + xhrobj.upload.addEventListener('progress', func, false); + } + return xhrobj; + }, + _initAjaxSettings: function () { + var self = this; + self._ajaxSettings = $.extend(true, {}, self.ajaxSettings); + self._ajaxDeleteSettings = $.extend(true, {}, self.ajaxDeleteSettings); + }, + _mergeAjaxCallback: function (funcName, srcFunc, type) { + var self = this, settings = self._ajaxSettings, flag = self.mergeAjaxCallbacks, targFunc; + if (type === 'delete') { + settings = self._ajaxDeleteSettings; + flag = self.mergeAjaxDeleteCallbacks; + } + targFunc = settings[funcName]; + if (flag && typeof targFunc === 'function') { + if (flag === 'before') { + settings[funcName] = function () { + targFunc.apply(this, arguments); + srcFunc.apply(this, arguments); + }; + } else { + settings[funcName] = function () { + srcFunc.apply(this, arguments); + targFunc.apply(this, arguments); + }; + } + } else { + settings[funcName] = srcFunc; + } + }, + _ajaxSubmit: function (fnBefore, fnSuccess, fnComplete, fnError, formdata, fileId, index, vUrl) { + var self = this, settings, defaults, data, ajaxTask; + if (!self._raise('filepreajax', [formdata, fileId, index])) { + return; + } + formdata.append('initialPreview', JSON.stringify(self.initialPreview)); + formdata.append('initialPreviewConfig', JSON.stringify(self.initialPreviewConfig)); + formdata.append('initialPreviewThumbTags', JSON.stringify(self.initialPreviewThumbTags)); + self._initAjaxSettings(); + self._mergeAjaxCallback('beforeSend', fnBefore); + self._mergeAjaxCallback('success', fnSuccess); + self._mergeAjaxCallback('complete', fnComplete); + self._mergeAjaxCallback('error', fnError); + vUrl = vUrl || self.uploadUrlThumb || self.uploadUrl; + if (typeof vUrl === 'function') { + vUrl = vUrl(); + } + data = self._getExtraData(fileId, index) || {}; + if (typeof data === 'object') { + $.each(data, function (key, value) { + formdata.append(key, value); + }); + } + defaults = { + xhr: function () { + var xhrobj = $.ajaxSettings.xhr(); + return self._initXhr(xhrobj, fileId); + }, + url: self._encodeURI(vUrl), + type: 'POST', + dataType: 'json', + data: formdata, + cache: false, + processData: false, + contentType: false + }; + settings = $.extend(true, {}, defaults, self._ajaxSettings); + ajaxTask = self.taskManager.addTask(fileId + '-' + index, function () { + var self = this.self, config, xhr; + config = self.ajaxQueue.shift(); + xhr = $.ajax(config); + self.ajaxRequests.push(xhr); + }); + self.ajaxQueue.push(settings); + ajaxTask.runWithContext({self: self}); + }, + _mergeArray: function (prop, content) { + var self = this, arr1 = $h.cleanArray(self[prop]), arr2 = $h.cleanArray(content); + self[prop] = arr1.concat(arr2); + }, + _initUploadSuccess: function (out, $thumb, allFiles) { + var self = this, append, data, index, $div, content, config, tags, id, i; + if (!self.showPreview || typeof out !== 'object' || $.isEmptyObject(out)) { + self._resetCaption(); + return; + } + if (out.initialPreview !== undefined && out.initialPreview.length > 0) { + self.hasInitData = true; + content = out.initialPreview || []; + config = out.initialPreviewConfig || []; + tags = out.initialPreviewThumbTags || []; + append = out.append === undefined || out.append; + if (content.length > 0 && !$h.isArray(content)) { + content = content.split(self.initialPreviewDelimiter); + } + if (content.length) { + self._mergeArray('initialPreview', content); + self._mergeArray('initialPreviewConfig', config); + self._mergeArray('initialPreviewThumbTags', tags); + } + if ($thumb !== undefined) { + if (!allFiles) { + index = self.previewCache.add(content[0], config[0], tags[0], append); + data = self.previewCache.get(index, false); + $div = $h.createElement(data).hide().appendTo($thumb); + $thumb.fadeOut('slow', function () { + var $newThumb = $div.find('> .file-preview-frame'); + if ($newThumb && $newThumb.length) { + $newThumb.insertBefore($thumb).fadeIn('slow').css('display:inline-block'); + } + self._initPreviewActions(); + self._clearFileInput(); + $thumb.remove(); + $div.remove(); + self._initSortable(); + }); + } else { + id = $thumb.attr('id'); + i = self._getUploadCacheIndex(id); + if (i !== null) { + self.uploadCache[i] = { + id: id, + content: content[0], + config: config[0] || [], + tags: tags[0] || [], + append: append + }; + } + } + } else { + self.previewCache.set(content, config, tags, append); + self._initPreview(); + self._initPreviewActions(); + } + } + self._resetCaption(); + }, + _getUploadCacheIndex: function (id) { + var self = this, i, len = self.uploadCache.length, config; + for (i = 0; i < len; i++) { + config = self.uploadCache[i]; + if (config.id === id) { + return i; + } + } + return null; + }, + _initSuccessThumbs: function () { + var self = this; + if (!self.showPreview) { + return; + } + setTimeout(function () { + self._getThumbs($h.FRAMES + '.file-preview-success').each(function () { + var $thumb = $(this), $remove = $thumb.find('.kv-file-remove'); + $remove.removeAttr('disabled'); + self._handler($remove, 'click', function () { + var id = $thumb.attr('id'), + out = self._raise('filesuccessremove', [id, $thumb.attr('data-fileindex')]); + $h.cleanMemory($thumb); + if (out === false) { + return; + } + self.$caption.attr('title', ''); + $thumb.fadeOut('slow', function () { + var fm = self.fileManager; + $thumb.remove(); + if (!self.getFrames().length) { + self.reset(); + } + }); + }); + }); + }, self.processDelay); + }, + _updateInitialPreview: function () { + var self = this, u = self.uploadCache; + if (self.showPreview) { + $.each(u, function (key, setting) { + self.previewCache.add(setting.content, setting.config, setting.tags, setting.append); + }); + if (self.hasInitData) { + self._initPreview(); + self._initPreviewActions(); + } + } + }, + _getThumbFileId: function ($thumb) { + var self = this; + if (self.showPreview && $thumb !== undefined) { + return $thumb.attr('data-fileid'); + } + return null; + }, + _getThumbFile: function ($thumb) { + var self = this, id = self._getThumbFileId($thumb); + return id ? self.fileManager.getFile(id) : null; + }, + _uploadSingle: function (i, id, isBatch) { + var self = this, fm = self.fileManager, count = fm.count(), formdata = new FormData(), outData, + previewId = self._getThumbId(id), $thumb, chkComplete, $btnUpload, $btnDelete, + hasPostData = count > 0 || !$.isEmptyObject(self.uploadExtraData), uploadFailed, $prog, fnBefore, + errMsg, fnSuccess, fnComplete, fnError, updateUploadLog, op = self.ajaxOperations.uploadThumb, + fileObj = fm.getFile(id), params = {id: previewId, index: i, fileId: id}, + fileName = self.fileManager.getFileName(id, true); + if (self.enableResumableUpload) { // not enabled for resumable uploads + return; + } + if (self.showPreview) { + $thumb = fm.getThumb(id); + $prog = $thumb.find('.file-thumb-progress'); + $btnUpload = $thumb.find('.kv-file-upload'); + $btnDelete = $thumb.find('.kv-file-remove'); + $prog.show(); + } + if (count === 0 || !hasPostData || (self.showPreview && $btnUpload && $btnUpload.hasClass('disabled')) || + self._abort(params)) { + return; + } + updateUploadLog = function () { + if (!uploadFailed) { + fm.removeFile(id); + } else { + fm.errors.push(id); + } + fm.setProcessed(id); + if (fm.isProcessed()) { + self.fileBatchCompleted = true; + chkComplete(); + } + }; + chkComplete = function () { + var $initThumbs; + if (!self.fileBatchCompleted) { + return; + } + setTimeout(function () { + var triggerReset = fm.count() === 0, errCount = fm.errors.length; + self._updateInitialPreview(); + self.unlock(triggerReset); + if (triggerReset) { + self._clearFileInput(); + } + $initThumbs = self.$preview.find('.file-preview-initial'); + if (self.uploadAsync && $initThumbs.length) { + $h.addCss($initThumbs, $h.SORT_CSS); + self._initSortable(); + } + self._raise('filebatchuploadcomplete', [fm.stack, self._getExtraData()]); + if (!self.retryErrorUploads || errCount === 0) { + fm.clear(); + } + self._setProgress(101); + self.ajaxAborted = false; + }, self.processDelay); + }; + fnBefore = function (jqXHR) { + outData = self._getOutData(formdata, jqXHR); + fm.initStats(id); + self.fileBatchCompleted = false; + if (!isBatch) { + self.ajaxAborted = false; + } + if (self.showPreview) { + if (!$thumb.hasClass('file-preview-success')) { + self._setThumbStatus($thumb, 'Loading'); + $h.addCss($thumb, 'file-uploading'); + } + $btnUpload.attr('disabled', true); + $btnDelete.attr('disabled', true); + } + if (!isBatch) { + self.lock(); + } + if (fm.errors.indexOf(id) !== -1) { + delete fm.errors[id]; + } + self._raise('filepreupload', [outData, previewId, i, self._getThumbFileId($thumb)]); + $.extend(true, params, outData); + if (self._abort(params)) { + jqXHR.abort(); + if (!isBatch) { + self._setThumbStatus($thumb, 'New'); + $thumb.removeClass('file-uploading'); + $btnUpload.removeAttr('disabled'); + $btnDelete.removeAttr('disabled'); + } + self._setProgressCancelled(); + } + }; + fnSuccess = function (data, textStatus, jqXHR) { + var pid = self.showPreview && $thumb.attr('id') ? $thumb.attr('id') : previewId; + outData = self._getOutData(formdata, jqXHR, data); + $.extend(true, params, outData); + setTimeout(function () { + if ($h.isEmpty(data) || $h.isEmpty(data.error)) { + if (self.showPreview) { + self._setThumbStatus($thumb, 'Success'); + $btnUpload.hide(); + self._initUploadSuccess(data, $thumb, isBatch); + self._setProgress(101, $prog); + } + self._raise('fileuploaded', [outData, pid, i, self._getThumbFileId($thumb)]); + if (!isBatch) { + self.fileManager.remove($thumb); + } else { + updateUploadLog(); + } + } else { + uploadFailed = true; + errMsg = self._parseError(op, jqXHR, self.msgUploadError, self.fileManager.getFileName(id)); + self._showFileError(errMsg, params); + self._setPreviewError($thumb, true); + if (!self.retryErrorUploads) { + $btnUpload.hide(); + } + if (isBatch) { + updateUploadLog(); + } + self._setProgress(101, self._getFrame(pid).find('.file-thumb-progress'), + self.msgUploadError); + } + }, self.processDelay); + }; + fnComplete = function () { + if (self.showPreview) { + $btnUpload.removeAttr('disabled'); + $btnDelete.removeAttr('disabled'); + $thumb.removeClass('file-uploading'); + } + if (!isBatch) { + self.unlock(false); + self._clearFileInput(); + } else { + chkComplete(); + } + self._initSuccessThumbs(); + }; + fnError = function (jqXHR, textStatus, errorThrown) { + errMsg = self._parseError(op, jqXHR, errorThrown, self.fileManager.getFileName(id)); + uploadFailed = true; + setTimeout(function () { + var $prog; + if (isBatch) { + updateUploadLog(); + } + self.fileManager.setProgress(id, 100); + self._setPreviewError($thumb, true); + if (!self.retryErrorUploads) { + $btnUpload.hide(); + } + $.extend(true, params, self._getOutData(formdata, jqXHR)); + self._setProgress(101, self.$progress, self.msgAjaxProgressError.replace('{operation}', op)); + $prog = self.showPreview && $thumb ? $thumb.find('.file-thumb-progress') : ''; + self._setProgress(101, $prog, self.msgUploadError); + self._showFileError(errMsg, params); + }, self.processDelay); + }; + self._setFileData(formdata, fileObj.file, fileName, id); + self._setUploadData(formdata, {fileId: id}); + self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, formdata, id, i); + }, + _setFileData: function (formdata, file, fileName, fileId) { + var self = this, preProcess = self.preProcessUpload; + if (preProcess && typeof preProcess === 'function') { + formdata.append(self.uploadFileAttr, preProcess(fileId, file)); + } else { + formdata.append(self.uploadFileAttr, file, fileName); + } + }, + _checkBatchPreupload: function (outData, jqXHR) { + var self = this, out = self._raise('filebatchpreupload', [outData]); + if (out) { + return true; + } + self._abort(outData); + if (jqXHR) { + jqXHR.abort(); + } + self._getThumbs().each(function () { + var $thumb = $(this), $btnUpload = $thumb.find('.kv-file-upload'), + $btnDelete = $thumb.find('.kv-file-remove'); + if ($thumb.hasClass('file-preview-loading')) { + self._setThumbStatus($thumb, 'New'); + $thumb.removeClass('file-uploading'); + } + $btnUpload.removeAttr('disabled'); + $btnDelete.removeAttr('disabled'); + }); + self._setProgressCancelled(); + return false; + }, + _uploadBatch: function () { + var self = this, fm = self.fileManager, total = fm.total(), params = {}, fnBefore, fnSuccess, fnError, + fnComplete, hasPostData = total > 0 || !$.isEmptyObject(self.uploadExtraData), errMsg, + setAllUploaded, formdata = new FormData(), op = self.ajaxOperations.uploadBatch; + if (total === 0 || !hasPostData || self._abort(params)) { + return; + } + setAllUploaded = function () { + self.fileManager.clear(); + self._clearFileInput(); + }; + fnBefore = function (jqXHR) { + self.lock(); + fm.initStats(); + var outData = self._getOutData(formdata, jqXHR); + self.ajaxAborted = false; + if (self.showPreview) { + self._getThumbs().each(function () { + var $thumb = $(this), $btnUpload = $thumb.find('.kv-file-upload'), + $btnDelete = $thumb.find('.kv-file-remove'); + if (!$thumb.hasClass('file-preview-success')) { + self._setThumbStatus($thumb, 'Loading'); + $h.addCss($thumb, 'file-uploading'); + } + $btnUpload.attr('disabled', true); + $btnDelete.attr('disabled', true); + }); + } + self._checkBatchPreupload(outData, jqXHR); + }; + fnSuccess = function (data, textStatus, jqXHR) { + /** @namespace data.errorkeys */ + var outData = self._getOutData(formdata, jqXHR, data), key = 0, + $thumbs = self._getThumbs(':not(.file-preview-success)'), + keys = $h.isEmpty(data) || $h.isEmpty(data.errorkeys) ? [] : data.errorkeys; + + if ($h.isEmpty(data) || $h.isEmpty(data.error)) { + self._raise('filebatchuploadsuccess', [outData]); + setAllUploaded(); + if (self.showPreview) { + $thumbs.each(function () { + var $thumb = $(this); + self._setThumbStatus($thumb, 'Success'); + $thumb.removeClass('file-uploading'); + $thumb.find('.kv-file-upload').hide().removeAttr('disabled'); + }); + self._initUploadSuccess(data); + } else { + self.reset(); + } + self._setProgress(101); + } else { + if (self.showPreview) { + $thumbs.each(function () { + var $thumb = $(this); + $thumb.removeClass('file-uploading'); + $thumb.find('.kv-file-upload').removeAttr('disabled'); + $thumb.find('.kv-file-remove').removeAttr('disabled'); + if (keys.length === 0 || $.inArray(key, keys) !== -1) { + self._setPreviewError($thumb, true); + if (!self.retryErrorUploads) { + $thumb.find('.kv-file-upload').hide(); + self.fileManager.remove($thumb); + } + } else { + $thumb.find('.kv-file-upload').hide(); + self._setThumbStatus($thumb, 'Success'); + self.fileManager.remove($thumb); + } + if (!$thumb.hasClass('file-preview-error') || self.retryErrorUploads) { + key++; + } + }); + self._initUploadSuccess(data); + } + errMsg = self._parseError(op, jqXHR, self.msgUploadError); + self._showFileError(errMsg, outData, 'filebatchuploaderror'); + self._setProgress(101, self.$progress, self.msgUploadError); + } + }; + fnComplete = function () { + self.unlock(); + self._initSuccessThumbs(); + self._clearFileInput(); + self._raise('filebatchuploadcomplete', [self.fileManager.stack, self._getExtraData()]); + }; + fnError = function (jqXHR, textStatus, errorThrown) { + var outData = self._getOutData(formdata, jqXHR); + errMsg = self._parseError(op, jqXHR, errorThrown); + self._showFileError(errMsg, outData, 'filebatchuploaderror'); + self.uploadFileCount = total - 1; + if (!self.showPreview) { + return; + } + self._getThumbs().each(function () { + var $thumb = $(this); + $thumb.removeClass('file-uploading'); + if (self._getThumbFile($thumb)) { + self._setPreviewError($thumb); + } + }); + self._getThumbs().removeClass('file-uploading'); + self._getThumbs(' .kv-file-upload').removeAttr('disabled'); + self._getThumbs(' .kv-file-delete').removeAttr('disabled'); + self._setProgress(101, self.$progress, self.msgAjaxProgressError.replace('{operation}', op)); + }; + var ctr = 0; + $.each(self.fileManager.stack, function (key, data) { + if (!$h.isEmpty(data.file)) { + self._setFileData(formdata, data.file, (data.nameFmt || ('untitled_' + ctr)), key); + } + ctr++; + }); + self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, formdata); + }, + _uploadExtraOnly: function () { + var self = this, params = {}, fnBefore, fnSuccess, fnComplete, fnError, formdata = new FormData(), errMsg, + op = self.ajaxOperations.uploadExtra; + fnBefore = function (jqXHR) { + self.lock(); + var outData = self._getOutData(formdata, jqXHR); + self._setProgress(50); + params.data = outData; + params.xhr = jqXHR; + self._checkBatchPreupload(outData, jqXHR); + }; + fnSuccess = function (data, textStatus, jqXHR) { + var outData = self._getOutData(formdata, jqXHR, data); + if ($h.isEmpty(data) || $h.isEmpty(data.error)) { + self._raise('filebatchuploadsuccess', [outData]); + self._clearFileInput(); + self._initUploadSuccess(data); + self._setProgress(101); + } else { + errMsg = self._parseError(op, jqXHR, self.msgUploadError); + self._showFileError(errMsg, outData, 'filebatchuploaderror'); + } + }; + fnComplete = function () { + self.unlock(); + self._clearFileInput(); + self._raise('filebatchuploadcomplete', [self.fileManager.stack, self._getExtraData()]); + }; + fnError = function (jqXHR, textStatus, errorThrown) { + var outData = self._getOutData(formdata, jqXHR); + errMsg = self._parseError(op, jqXHR, errorThrown); + params.data = outData; + self._showFileError(errMsg, outData, 'filebatchuploaderror'); + self._setProgress(101, self.$progress, self.msgAjaxProgressError.replace('{operation}', op)); + }; + self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, formdata); + }, + _deleteFileIndex: function ($frame) { + var self = this, ind = $frame.attr('data-fileindex'), rev = self.reversePreviewOrder; + if (ind.substring(0, 5) === $h.INIT_FLAG) { + ind = parseInt(ind.replace($h.INIT_FLAG, '')); + self.initialPreview = $h.spliceArray(self.initialPreview, ind, rev); + self.initialPreviewConfig = $h.spliceArray(self.initialPreviewConfig, ind, rev); + self.initialPreviewThumbTags = $h.spliceArray(self.initialPreviewThumbTags, ind, rev); + self.getFrames().each(function () { + var $nFrame = $(this), nInd = $nFrame.attr('data-fileindex'); + if (nInd.substring(0, 5) === $h.INIT_FLAG) { + nInd = parseInt(nInd.replace($h.INIT_FLAG, '')); + if (nInd > ind) { + nInd--; + $nFrame.attr('data-fileindex', $h.INIT_FLAG + nInd); + } + } + }); + } + }, + _resetCaption: function () { + var self = this; + setTimeout(function () { + var cap = '', n, chk = self.previewCache.count(true), len = self.fileManager.count(), file, + incomplete = ':not(.file-preview-success):not(.file-preview-error)', cfg, + hasThumb = self.showPreview && self.getFrames(incomplete).length; + if (len === 0 && chk === 0 && !hasThumb) { + self.reset(); + } else { + n = chk + len; + if (n > 1) { + cap = self._getMsgSelected(n); + } else { + if (len === 0) { + cfg = self.initialPreviewConfig[0]; + cap = ''; + if (cfg) { + cap = cfg.caption || cfg.filename || '' + } + if (!cap) { + cap = self._getMsgSelected(n); + } + } else { + file = self.fileManager.getFirstFile(); + cap = file ? file.nameFmt : '_'; + } + } + self._setCaption(cap); + } + }, self.processDelay); + }, + _initFileActions: function () { + var self = this; + if (!self.showPreview) { + return; + } + self._initZoomButton(); + self.getFrames(' .kv-file-remove').each(function () { + var $el = $(this), $frame = $el.closest($h.FRAMES), hasError, id = $frame.attr('id'), + ind = $frame.attr('data-fileindex'), status, fm = self.fileManager; + self._handler($el, 'click', function () { + status = self._raise('filepreremove', [id, ind]); + if (status === false || !self._validateMinCount()) { + return false; + } + hasError = $frame.hasClass('file-preview-error'); + $h.cleanMemory($frame); + $frame.fadeOut('slow', function () { + self.fileManager.remove($frame); + self._clearObjects($frame); + $frame.remove(); + if (id && hasError) { + self.$errorContainer.find('li[data-thumb-id="' + id + '"]').fadeOut('fast', function () { + $(this).remove(); + if (!self._errorsExist()) { + self._resetErrors(); + } + }); + } + self._clearFileInput(); + self._resetCaption(); + self._raise('fileremoved', [id, ind]); + }); + }); + }); + self.getFrames(' .kv-file-upload').each(function () { + var $el = $(this); + self._handler($el, 'click', function () { + var $frame = $el.closest($h.FRAMES), fileId = self._getThumbFileId($frame); + self._hideProgress(); + if ($frame.hasClass('file-preview-error') && !self.retryErrorUploads) { + return; + } + self._uploadSingle(self.fileManager.getIndex(fileId), fileId, false); + }); + }); + }, + _initPreviewActions: function () { + var self = this, $preview = self.$preview, deleteExtraData = self.deleteExtraData || {}, + btnRemove = $h.FRAMES + ' .kv-file-remove', settings = self.fileActionSettings, + origClass = settings.removeClass, errClass = settings.removeErrorClass, + resetProgress = function () { + var hasFiles = self.isAjaxUpload ? self.previewCache.count(true) : self._inputFileCount(); + if (!self.getFrames().length && !hasFiles) { + self._setCaption(''); + self.reset(); + self.initialCaption = ''; + } else { + self._resetCaption(); + } + }; + self._initZoomButton(); + $preview.find(btnRemove).each(function () { + var $el = $(this), vUrl = $el.data('url') || self.deleteUrl, vKey = $el.data('key'), errMsg, fnBefore, + fnSuccess, fnError, op = self.ajaxOperations.deleteThumb; + if ($h.isEmpty(vUrl) || vKey === undefined) { + return; + } + if (typeof vUrl === 'function') { + vUrl = vUrl(); + } + var $frame = $el.closest($h.FRAMES), cache = self.previewCache.data, settings, params, config, + fileName, extraData, index = $frame.attr('data-fileindex'); + index = parseInt(index.replace($h.INIT_FLAG, '')); + config = $h.isEmpty(cache.config) && $h.isEmpty(cache.config[index]) ? null : cache.config[index]; + extraData = $h.isEmpty(config) || $h.isEmpty(config.extra) ? deleteExtraData : config.extra; + fileName = config && (config.filename || config.caption) || ''; + if (typeof extraData === 'function') { + extraData = extraData(); + } + params = {id: $el.attr('id'), key: vKey, extra: extraData}; + fnBefore = function (jqXHR) { + self.ajaxAborted = false; + self._raise('filepredelete', [vKey, jqXHR, extraData]); + if (self._abort()) { + jqXHR.abort(); + } else { + $el.removeClass(errClass); + $h.addCss($frame, 'file-uploading'); + $h.addCss($el, 'disabled ' + origClass); + } + }; + fnSuccess = function (data, textStatus, jqXHR) { + var n, cap; + if (!$h.isEmpty(data) && !$h.isEmpty(data.error)) { + params.jqXHR = jqXHR; + params.response = data; + errMsg = self._parseError(op, jqXHR, self.msgDeleteError, fileName); + self._showFileError(errMsg, params, 'filedeleteerror'); + $frame.removeClass('file-uploading'); + $el.removeClass('disabled ' + origClass).addClass(errClass); + resetProgress(); + return; + } + $frame.removeClass('file-uploading').addClass('file-deleted'); + $frame.fadeOut('slow', function () { + index = parseInt(($frame.attr('data-fileindex')).replace($h.INIT_FLAG, '')); + self.previewCache.unset(index); + self._deleteFileIndex($frame); + n = self.previewCache.count(true); + cap = n > 0 ? self._getMsgSelected(n) : ''; + self._setCaption(cap); + self._raise('filedeleted', [vKey, jqXHR, extraData]); + self._clearObjects($frame); + $frame.remove(); + resetProgress(); + }); + }; + fnError = function (jqXHR, textStatus, errorThrown) { + var errMsg = self._parseError(op, jqXHR, errorThrown, fileName); + params.jqXHR = jqXHR; + params.response = {}; + self._showFileError(errMsg, params, 'filedeleteerror'); + $frame.removeClass('file-uploading'); + $el.removeClass('disabled ' + origClass).addClass(errClass); + resetProgress(); + }; + self._initAjaxSettings(); + self._mergeAjaxCallback('beforeSend', fnBefore, 'delete'); + self._mergeAjaxCallback('success', fnSuccess, 'delete'); + self._mergeAjaxCallback('error', fnError, 'delete'); + settings = $.extend(true, {}, { + url: self._encodeURI(vUrl), + type: 'POST', + dataType: 'json', + data: $.extend(true, {}, {key: vKey}, extraData) + }, self._ajaxDeleteSettings); + self._handler($el, 'click', function () { + if (!self._validateMinCount()) { + return false; + } + self.ajaxAborted = false; + self._raise('filebeforedelete', [vKey, extraData]); + if (self.ajaxAborted instanceof Promise) { + self.ajaxAborted.then(function (result) { + if (!result) { + $.ajax(settings); + } + }); + } else { + if (!self.ajaxAborted) { + $.ajax(settings); + } + } + }); + }); + }, + _hideFileIcon: function () { + var self = this; + if (self.overwriteInitial) { + self.$captionContainer.removeClass('icon-visible'); + } + }, + _showFileIcon: function () { + var self = this; + $h.addCss(self.$captionContainer, 'icon-visible'); + }, + _getSize: function (bytes, sizes) { + var self = this, size = parseFloat(bytes), i, func = self.fileSizeGetter, out; + if (!$.isNumeric(bytes) || !$.isNumeric(size)) { + return ''; + } + if (typeof func === 'function') { + out = func(size); + } else { + if (size === 0) { + out = '0.00 B'; + } else { + if (!sizes) { + sizes = self.sizeUnits; + } + i = Math.floor(Math.log(size) / Math.log(self.bytesToKB)); + out = (size / Math.pow(self.bytesToKB, i)).toFixed(2) + ' ' + sizes[i]; + } + } + return self._getLayoutTemplate('size').replace('{sizeText}', out); + }, + _getFileType: function (ftype) { + var self = this; + return self.mimeTypeAliases[ftype] || ftype; + }, + _generatePreviewTemplate: function ( + cat, + data, + fname, + ftype, + previewId, + fileId, + isError, + size, + frameClass, + foot, + ind, + templ, + attrs, + zoomData + ) { + var self = this, caption = self.slug(fname), prevContent, zoomContent = '', styleAttribs = '', + screenW = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth, + config, title = caption, alt = caption, typeCss = 'type-default', getContent, + footer = foot || self._renderFileFooter(cat, caption, size, 'auto', isError), + forcePrevIcon = self.preferIconicPreview, forceZoomIcon = self.preferIconicZoomPreview, + newCat = forcePrevIcon ? 'other' : cat; + config = screenW < 400 ? (self.previewSettingsSmall[newCat] || self.defaults.previewSettingsSmall[newCat]) : + (self.previewSettings[newCat] || self.defaults.previewSettings[newCat]); + if (config) { + $.each(config, function (key, val) { + styleAttribs += key + ':' + val + ';'; + }); + } + getContent = function (vCat, vData, zoom, frameCss, vZoomData) { + var id = zoom ? 'zoom-' + previewId : previewId, tmplt = self._getPreviewTemplate(vCat), + css = (frameClass || '') + ' ' + frameCss, tokens; + if (self.frameClass) { + css = self.frameClass + ' ' + css; + } + if (zoom) { + css = css.replace(' ' + $h.SORT_CSS, ''); + } + tmplt = self._parseFilePreviewIcon(tmplt, fname); + if (cat === 'object' && !ftype) { + $.each(self.defaults.fileTypeSettings, function (key, func) { + if (key === 'object' || key === 'other') { + return; + } + if (func(fname, ftype)) { + typeCss = 'type-' + key; + } + }); + } + if (!$h.isEmpty(attrs)) { + if (attrs.title !== undefined && attrs.title !== null) { + title = attrs.title; + } + if (attrs.alt !== undefined && attrs.alt !== null) { + title = attrs.alt; + } + } + tokens = { + 'previewId': id, + 'caption': caption, + 'title': title, + 'alt': alt, + 'frameClass': css, + 'type': self._getFileType(ftype), + 'fileindex': ind, + 'fileid': fileId || '', + 'typeCss': typeCss, + 'footer': footer, + 'data': vData, +// 'data': zoom && vZoomData ? $h.ZOOM_VAR + '{zoomData}' : vData, + 'template': templ || cat, + 'style': styleAttribs ? 'style="' + styleAttribs + '"' : '', + 'zoomData': vZoomData ? encodeURIComponent(vZoomData) : '' + }; + if (zoom) { + tokens.zoomCache = ''; + tokens.zoomData = '{zoomData}'; + } + return tmplt.setTokens(tokens); + }; + ind = ind || previewId.slice(previewId.lastIndexOf('-') + 1); + if (self.fileActionSettings.showZoom) { + zoomContent = getContent((forceZoomIcon ? 'other' : cat), data, true, 'kv-zoom-thumb', zoomData); + } + zoomContent = '\n' + self._getLayoutTemplate('zoomCache').replace('{zoomContent}', zoomContent); + if (typeof self.sanitizeZoomCache === 'function') { + zoomContent = self.sanitizeZoomCache(zoomContent); + } + prevContent = getContent((forcePrevIcon ? 'other' : cat), data, false, 'kv-preview-thumb', zoomData); + return prevContent.setTokens({zoomCache: zoomContent}); + }, + _addToPreview: function ($preview, content) { + var self = this, $el; + content = $h.cspBuffer.stash(content); + $el = self.reversePreviewOrder ? $preview.prepend(content) : $preview.append(content); + $h.cspBuffer.apply($preview); + return $el; + }, + _previewDefault: function (file, isDisabled) { + var self = this, $preview = self.$preview; + if (!self.showPreview) { + return; + } + var fname = $h.getFileName(file), ftype = file ? file.type : '', content, size = file.size || 0, + caption = self._getFileName(file, ''), isError = isDisabled === true && !self.isAjaxUpload, + data = $h.createObjectURL(file), fileId = self.fileManager.getId(file), + previewId = self._getThumbId(fileId); + self._clearDefaultPreview(); + content = self._generatePreviewTemplate('other', data, fname, ftype, previewId, fileId, isError, size); + self._addToPreview($preview, content); + self._setThumbAttr(previewId, caption, size); + if (isDisabled === true && self.isAjaxUpload) { + self._setThumbStatus(self._getFrame(previewId), 'Error'); + } + }, + _previewFile: function (i, file, theFile, data, fileInfo) { + if (!this.showPreview) { + return; + } + var self = this, fname = $h.getFileName(file), ftype = fileInfo.type, caption = fileInfo.name, + cat = self._parseFileType(ftype, fname), content, $preview = self.$preview, fsize = file.size || 0, + iData = cat === 'image' ? theFile.target.result : data, fm = self.fileManager, + fileId = fm.getId(file), previewId = self._getThumbId(fileId); + /** @namespace window.DOMPurify */ + content = self._generatePreviewTemplate(cat, iData, fname, ftype, previewId, fileId, false, fsize); + self._clearDefaultPreview(); + self._addToPreview($preview, content); + var $thumb = self._getFrame(previewId); + self._validateImageOrientation($thumb.find('img'), file, previewId, fileId, caption, ftype, fsize, iData); + self._setThumbAttr(previewId, caption, fsize); + self._initSortable(); + }, + _setThumbAttr: function (id, caption, size, description) { + var self = this, $frame = self._getFrame(id); + if ($frame.length) { + size = size && size > 0 ? self._getSize(size) : ''; + $frame.data({'caption': caption, 'size': size, 'description': description || ''}); + } + }, + _setInitThumbAttr: function () { + var self = this, data = self.previewCache.data, len = self.previewCache.count(true), config, + caption, size, description, previewId; + if (len === 0) { + return; + } + for (var i = 0; i < len; i++) { + config = data.config[i]; + previewId = self.previewInitId + '-' + $h.INIT_FLAG + i; + caption = $h.ifSet('caption', config, $h.ifSet('filename', config)); + size = $h.ifSet('size', config); + description = $h.ifSet('description', config); + self._setThumbAttr(previewId, caption, size, description); + } + }, + _slugDefault: function (text) { + // noinspection RegExpRedundantEscape + return $h.isEmpty(text, true) ? '' : String(text).replace(/[\[\]\/\{}:;#%=\(\)\*\+\?\\\^\$\|<>&"']/g, '_'); + }, + _updateFileDetails: function (numFiles) { + var self = this, $el = self.$element, label, n, log, nFiles, file, + name = ($h.isIE(9) && $h.findFileName($el.val())) || ($el[0].files[0] && $el[0].files[0].name); + if (!name && self.fileManager.count() > 0) { + file = self.fileManager.getFirstFile(); + label = file.nameFmt; + } else { + label = name ? self.slug(name) : '_'; + } + n = self.isAjaxUpload ? self.fileManager.count() : numFiles; + nFiles = self.previewCache.count(true) + n; + log = n === 1 ? label : self._getMsgSelected(nFiles, !self.isAjaxUpload && !self.isError); + if (self.isError) { + self.$previewContainer.removeClass('file-thumb-loading'); + self._initCapStatus(); + self.$previewStatus.html(''); + self.$captionContainer.removeClass('icon-visible'); + } else { + self._showFileIcon(); + } + self._setCaption(log, self.isError); + self.$container.removeClass('file-input-new file-input-ajax-new'); + self._raise('fileselect', [numFiles, label]); + if (self.previewCache.count(true)) { + self._initPreviewActions(); + } + }, + _setThumbStatus: function ($thumb, status) { + var self = this; + if (!self.showPreview) { + return; + } + var icon = 'indicator' + status, msg = icon + 'Title', + css = 'file-preview-' + status.toLowerCase(), + $indicator = $thumb.find('.file-upload-indicator'), + config = self.fileActionSettings; + $thumb.removeClass('file-preview-success file-preview-error file-preview-paused file-preview-loading'); + if (status === 'Success') { + $thumb.find('.file-drag-handle').remove(); + } + $h.setHtml($indicator, config[icon]); + $indicator.attr('title', config[msg]); + $thumb.addClass(css); + if (status === 'Error' && !self.retryErrorUploads) { + $thumb.find('.kv-file-upload').attr('disabled', true); + } + }, + _setProgressCancelled: function () { + var self = this; + self._setProgress(101, self.$progress, self.msgCancelled); + }, + _setProgress: function (p, $el, error, stats) { + var self = this; + $el = $el || self.$progress; + if (!$el.length) { + return; + } + var pct = Math.min(p, 100), out, pctLimit = self.progressUploadThreshold, + t = p <= 100 ? self.progressTemplate : self.progressCompleteTemplate, + template = pct < 100 ? self.progressTemplate : + (error ? (self.paused ? self.progressPauseTemplate : self.progressErrorTemplate) : t); + if (p >= 100) { + stats = ''; + } + if (!$h.isEmpty(template)) { + if (pctLimit && pct > pctLimit && p <= 100) { + out = template.setTokens({'percent': pctLimit, 'status': self.msgUploadThreshold}); + } else { + out = template.setTokens({'percent': pct, 'status': (p > 100 ? self.msgUploadEnd : pct + '%')}); + } + stats = stats || ''; + out = out.setTokens({stats: stats}); + $h.setHtml($el, out); + if (error) { + $h.setHtml($el.find('[role="progressbar"]'), error); + } + } + }, + _hasFiles: function () { + var el = this.$element[0]; + return !!(el && el.files && el.files.length); + }, + _setFileDropZoneTitle: function () { + var self = this, $zone = self.$container.find('.file-drop-zone'), title = self.dropZoneTitle, strFiles; + if (self.isClickable) { + strFiles = $h.isEmpty(self.$element.attr('multiple')) ? self.fileSingle : self.filePlural; + title += self.dropZoneClickTitle.replace('{files}', strFiles); + } + $zone.find('.' + self.dropZoneTitleClass).remove(); + if (!self.showPreview || $zone.length === 0 || self.fileManager.count() > 0 || !self.dropZoneEnabled || + self.previewCache.count() > 0 || (!self.isAjaxUpload && self._hasFiles())) { + return; + } + if ($zone.find($h.FRAMES).length === 0 && $h.isEmpty(self.defaultPreviewContent)) { + $zone.prepend('
    ' + title + '
    '); + } + self.$container.removeClass('file-input-new'); + $h.addCss(self.$container, 'file-input-ajax-new'); + }, + _getStats: function (stats) { + var self = this, pendingTime, t; + if (!self.showUploadStats || !stats || !stats.bitrate) { + return ''; + } + t = self._getLayoutTemplate('stats'); + pendingTime = (!stats.elapsed || !stats.bps) ? self.msgCalculatingTime : + self.msgPendingTime.setTokens({time: $h.getElapsed(Math.ceil(stats.pendingBytes / stats.bps))}); + + return t.setTokens({ + uploadSpeed: stats.bitrate, + pendingTime: pendingTime + }); + }, + _setResumableProgress: function (pct, stats, $thumb) { + var self = this, rm = self.resumableManager, obj = $thumb ? rm : self, + $prog = $thumb ? $thumb.find('.file-thumb-progress') : null; + if (obj.lastProgress === 0) { + obj.lastProgress = pct; + } + if (pct < obj.lastProgress) { + pct = obj.lastProgress; + } + self._setProgress(pct, $prog, null, self._getStats(stats)); + obj.lastProgress = pct; + }, + _toggleResumableProgress: function (template, message) { + var self = this, $progress = self.$progress; + if ($progress && $progress.length) { + $h.setHtml($progress, template.setTokens({ + percent: 101, + status: message, + stats: '' + })); + } + }, + _setFileUploadStats: function (id, pct, stats) { + var self = this, $prog = self.$progress; + if (!self.showPreview && (!$prog || !$prog.length)) { + return; + } + var fm = self.fileManager, rm = self.resumableManager, $thumb = fm.getThumb(id), pctTot, + totUpSize = 0, totSize = fm.getTotalSize(), totStats = $.extend(true, {}, stats); + if (self.enableResumableUpload) { + var loaded = stats.loaded, currUplSize = rm.getUploadedSize(), currTotSize = rm.file.size, totLoaded; + loaded += currUplSize; + totLoaded = fm.uploadedSize + loaded; + pct = $h.round(100 * loaded / currTotSize); + stats.pendingBytes = currTotSize - currUplSize; + self._setResumableProgress(pct, stats, $thumb); + pctTot = Math.floor(100 * totLoaded / totSize); + totStats.pendingBytes = totSize - totLoaded; + self._setResumableProgress(pctTot, totStats); + } else { + fm.setProgress(id, pct); + $prog = $thumb && $thumb.length ? $thumb.find('.file-thumb-progress') : null; + self._setProgress(pct, $prog, null, self._getStats(stats)); + $.each(fm.stats, function (id, cfg) { + totUpSize += cfg.loaded; + }); + totStats.pendingBytes = totSize - totUpSize; + pctTot = $h.round(totUpSize / totSize * 100); + self._setProgress(pctTot, null, null, self._getStats(totStats)); + } + }, + _validateMinCount: function () { + var self = this, len = self.isAjaxUpload ? self.fileManager.count() : self._inputFileCount(); + if (self.validateInitialCount && self.minFileCount > 0 && self._getFileCount(len - 1) < self.minFileCount) { + self._noFilesError({}); + return false; + } + return true; + }, + _getFileCount: function (fileCount, includeInitial) { + var self = this, addCount = 0; + if (includeInitial === undefined) { + includeInitial = self.validateInitialCount && !self.overwriteInitial; + } + if (includeInitial) { + addCount = self.previewCache.count(true); + fileCount += addCount; + } + return fileCount; + }, + _getFileId: function (file) { + return $h.getFileId(file, this.generateFileId); + }, + _getFileName: function (file, defaultValue) { + var self = this, fileName = $h.getFileName(file); + return fileName ? self.slug(fileName) : defaultValue; + }, + _getFileNames: function (skipNull) { + var self = this; + return self.filenames.filter(function (n) { + return (skipNull ? n !== undefined : n !== undefined && n !== null); + }); + }, + _setPreviewError: function ($thumb, keepFile) { + var self = this, removeFrame = self.removeFromPreviewOnError && !self.retryErrorUploads; + if (!keepFile || removeFrame) { + self.fileManager.remove($thumb); + } + if (!self.showPreview) { + return; + } + if (removeFrame) { + $thumb.remove(); + return; + } else { + self._setThumbStatus($thumb, 'Error'); + } + self._refreshUploadButton($thumb); + }, + _refreshUploadButton: function ($thumb) { + var self = this, $btn = $thumb.find('.kv-file-upload'), cfg = self.fileActionSettings, + icon = cfg.uploadIcon, title = cfg.uploadTitle; + if (!$btn.length) { + return; + } + if (self.retryErrorUploads) { + icon = cfg.uploadRetryIcon; + title = cfg.uploadRetryTitle; + } + $btn.attr('title', title); + $h.setHtml($btn, icon); + }, + _checkDimensions: function (i, chk, $img, $thumb, fname, type, params) { + var self = this, msg, dim, tag = chk === 'Small' ? 'min' : 'max', limit = self[tag + 'Image' + type], + $imgEl, isValid; + if ($h.isEmpty(limit) || !$img.length) { + return; + } + $imgEl = $img[0]; + dim = (type === 'Width') ? $imgEl.naturalWidth || $imgEl.width : $imgEl.naturalHeight || $imgEl.height; + isValid = chk === 'Small' ? dim >= limit : dim <= limit; + if (isValid) { + return; + } + msg = self['msgImage' + type + chk].setTokens({'name': fname, 'size': limit}); + self._showFileError(msg, params); + self._setPreviewError($thumb); + }, + _getExifObj: function (data) { + var self = this, exifObj, error = $h.logMessages.exifWarning; + if (data.slice(0, 23) !== 'data:image/jpeg;base64,' && data.slice(0, 22) !== 'data:image/jpg;base64,') { + exifObj = null; + return; + } + try { + exifObj = window.piexif ? window.piexif.load(data) : null; + } catch (err) { + exifObj = null; + error = err && err.message || ''; + } + if (!exifObj) { + self._log($h.logMessages.badExifParser, {details: error}); + } + return exifObj; + }, + setImageOrientation: function ($img, $zoomImg, value, $thumb) { + var self = this, invalidImg = !$img || !$img.length, invalidZoomImg = !$zoomImg || !$zoomImg.length, $mark, + isHidden = false, $div, zoomOnly = invalidImg && $thumb && $thumb.attr('data-template') === 'image', ev; + if (invalidImg && invalidZoomImg) { + return; + } + ev = 'load.fileinputimageorient'; + if (zoomOnly) { + $img = $zoomImg; + $zoomImg = null; + $img.css(self.previewSettings.image); + $div = $(document.createElement('div')).appendTo($thumb.find('.kv-file-content')); + $mark = $(document.createElement('span')).insertBefore($img); + $img.css('visibility', 'hidden').removeClass('file-zoom-detail').appendTo($div); + } else { + isHidden = !$img.is(':visible'); + } + $img.off(ev).on(ev, function () { + if (isHidden) { + self.$preview.removeClass('hide-content'); + $thumb.find('.kv-file-content').css('visibility', 'hidden'); + } + var img = $img[0], zoomImg = $zoomImg && $zoomImg.length ? $zoomImg[0] : null, + h = img.offsetHeight, w = img.offsetWidth, r = $h.getRotation(value); + if (isHidden) { + $thumb.find('.kv-file-content').css('visibility', 'visible'); + self.$preview.addClass('hide-content'); + } + $img.data('orientation', value); + if (zoomImg) { + $zoomImg.data('orientation', value); + } + if (value < 5) { + $h.setTransform(img, r); + $h.setTransform(zoomImg, r); + return; + } + var offsetAngle = Math.atan(w / h), origFactor = Math.sqrt(Math.pow(h, 2) + Math.pow(w, 2)), + scale = !origFactor ? 1 : (h / Math.cos(Math.PI / 2 + offsetAngle)) / origFactor, + s = ' scale(' + Math.abs(scale) + ')'; + $h.setTransform(img, r + s); + $h.setTransform(zoomImg, r + s); + if (zoomOnly) { + $img.css('visibility', 'visible').insertAfter($mark).addClass('file-zoom-detail'); + $mark.remove(); + $div.remove(); + } + }); + }, + _validateImageOrientation: function ($img, file, previewId, fileId, caption, ftype, fsize, iData) { + var self = this, exifObj = null, value, autoOrientImage = self.autoOrientImage, selector; + if (self.canOrientImage) { + $img.css('image-orientation', (autoOrientImage ? 'from-image' : 'none')); + self._validateImage(previewId, fileId, caption, ftype, fsize, iData, exifObj); + return; + } + selector = $h.getZoomSelector(previewId, ' img'); + exifObj = autoOrientImage ? self._getExifObj(iData) : null; + value = exifObj ? exifObj['0th'][piexif.ImageIFD.Orientation] : null; // jshint ignore:line + if (!value) { + self._validateImage(previewId, fileId, caption, ftype, fsize, iData, exifObj); + return; + } + self.setImageOrientation($img, $(selector), value, self._getFrame(previewId)); + self._raise('fileimageoriented', {'$img': $img, 'file': file}); + self._validateImage(previewId, fileId, caption, ftype, fsize, iData, exifObj); + }, + _validateImage: function (previewId, fileId, fname, ftype, fsize, iData, exifObj) { + var self = this, $preview = self.$preview, params, w1, w2, $thumb = self._getFrame(previewId), + i = $thumb.attr('data-fileindex'), $img = $thumb.find('img'); + fname = fname || 'Untitled'; + $img.one('load', function () { + w1 = $thumb.width(); + w2 = $preview.width(); + if (w1 > w2) { + $img.css('width', '100%'); + } + params = {ind: i, id: previewId, fileId: fileId}; + self._checkDimensions(i, 'Small', $img, $thumb, fname, 'Width', params); + self._checkDimensions(i, 'Small', $img, $thumb, fname, 'Height', params); + if (!self.resizeImage) { + self._checkDimensions(i, 'Large', $img, $thumb, fname, 'Width', params); + self._checkDimensions(i, 'Large', $img, $thumb, fname, 'Height', params); + } + self._raise('fileimageloaded', [previewId]); + self.fileManager.addImage(fileId, { + ind: i, + img: $img, + thumb: $thumb, + pid: previewId, + typ: ftype, + siz: fsize, + validated: false, + imgData: iData, + exifObj: exifObj + }); + $thumb.data('exif', exifObj); + self._validateAllImages(); + }).one('error', function () { + self._raise('fileimageloaderror', [previewId]); + }); + }, + _validateAllImages: function () { + var self = this, counter = {val: 0}, numImgs = self.fileManager.getImageCount(), fsize, + minSize = self.resizeIfSizeMoreThan; + if (numImgs !== self.fileManager.totalImages) { + return; + } + self._raise('fileimagesloaded'); + if (!self.resizeImage) { + return; + } + $.each(self.fileManager.loadedImages, function (id, config) { + if (!config.validated) { + fsize = config.siz; + if (fsize && fsize > minSize * self.bytesToKB) { + self._getResizedImage(id, config, counter, numImgs); + } + config.validated = true; + } + }); + }, + _getResizedImage: function (id, config, counter, numImgs) { + var self = this, img = $(config.img)[0], width = img.naturalWidth, height = img.naturalHeight, blob, + ratio = 1, maxWidth = self.maxImageWidth || width, maxHeight = self.maxImageHeight || height, + isValidImage = !!(width && height), chkWidth, chkHeight, canvas = self.imageCanvas, dataURI, + context = self.imageCanvasContext, type = config.typ, pid = config.pid, ind = config.ind, + $thumb = config.thumb, throwError, msg, exifObj = config.exifObj, exifStr, file, params, evParams; + throwError = function (msg, params, ev) { + if (self.isAjaxUpload) { + self._showFileError(msg, params, ev); + } else { + self._showError(msg, params, ev); + } + self._setPreviewError($thumb); + }; + file = self.fileManager.getFile(id); + params = {id: pid, 'index': ind, fileId: id}; + evParams = [id, pid, ind]; + if (!file || !isValidImage || (width <= maxWidth && height <= maxHeight)) { + if (isValidImage && file) { + self._raise('fileimageresized', evParams); + } + counter.val++; + if (counter.val === numImgs) { + self._raise('fileimagesresized'); + } + if (!isValidImage) { + throwError(self.msgImageResizeError, params, 'fileimageresizeerror'); + return; + } + } + type = type || self.resizeDefaultImageType; + chkWidth = width > maxWidth; + chkHeight = height > maxHeight; + if (self.resizePreference === 'width') { + ratio = chkWidth ? maxWidth / width : (chkHeight ? maxHeight / height : 1); + } else { + ratio = chkHeight ? maxHeight / height : (chkWidth ? maxWidth / width : 1); + } + self._resetCanvas(); + width *= ratio; + height *= ratio; + canvas.width = width; + canvas.height = height; + try { + context.drawImage(img, 0, 0, width, height); + dataURI = canvas.toDataURL(type, self.resizeQuality); + if (exifObj) { + exifStr = window.piexif.dump(exifObj); + dataURI = window.piexif.insert(exifStr, dataURI); + } + blob = $h.dataURI2Blob(dataURI); + self.fileManager.setFile(id, blob); + self._raise('fileimageresized', evParams); + counter.val++; + if (counter.val === numImgs) { + self._raise('fileimagesresized', [undefined, undefined]); + } + if (!(blob instanceof Blob)) { + throwError(self.msgImageResizeError, params, 'fileimageresizeerror'); + } + } catch (err) { + counter.val++; + if (counter.val === numImgs) { + self._raise('fileimagesresized', [undefined, undefined]); + } + msg = self.msgImageResizeException.replace('{errors}', err.message); + throwError(msg, params, 'fileimageresizeexception'); + } + }, + _showProgress: function () { + var self = this; + if (self.$progress && self.$progress.length) { + self.$progress.show(); + } + }, + _hideProgress: function () { + var self = this; + if (self.$progress && self.$progress.length) { + self.$progress.hide(); + } + }, + _initBrowse: function ($container) { + var self = this, $el = self.$element; + if (self.showBrowse) { + self.$btnFile = $container.find('.btn-file').append($el); + } else { + $el.appendTo($container).attr('tabindex', -1); + $h.addCss($el, 'file-no-browse'); + } + }, + _initClickable: function () { + var self = this, $zone, $tmpZone; + if (!self.isClickable) { + return; + } + $zone = self.$dropZone; + if (!self.isAjaxUpload) { + $tmpZone = self.$preview.find('.file-default-preview'); + if ($tmpZone.length) { + $zone = $tmpZone; + } + } + + $h.addCss($zone, 'clickable'); + $zone.attr('tabindex', -1); + self._handler($zone, 'click', function (e) { + var $tar = $(e.target); + if (!self.$errorContainer.is(':visible') && (!$tar.parents( + '.file-preview-thumbnails').length || $tar.parents( + '.file-default-preview').length)) { + self.$element.data('zoneClicked', true).trigger('click'); + $zone.blur(); + } + }); + }, + _initCaption: function () { + var self = this, cap = self.initialCaption || ''; + if (self.overwriteInitial || $h.isEmpty(cap)) { + self.$caption.val(''); + return false; + } + self._setCaption(cap); + return true; + }, + _setCaption: function (content, isError) { + var self = this, title, out, icon, n, cap, file; + if (!self.$caption.length) { + return; + } + self.$captionContainer.removeClass('icon-visible'); + if (isError) { + title = $('
    ' + self.msgValidationError + '
    ').text(); + n = self.fileManager.count(); + if (n) { + file = self.fileManager.getFirstFile(); + cap = n === 1 && file ? file.nameFmt : self._getMsgSelected(n); + } else { + cap = self._getMsgSelected(self.msgNo); + } + out = $h.isEmpty(content) ? cap : content; + icon = '' + self.msgValidationErrorIcon + ''; + } else { + if ($h.isEmpty(content)) { + self.$caption.attr('title', ''); + return; + } + title = $('
    ' + content + '
    ').text(); + out = title; + icon = self._getLayoutTemplate('fileIcon'); + } + self.$captionContainer.addClass('icon-visible'); + self.$caption.attr('title', title).val(out); + $h.setHtml(self.$captionIcon, icon); + }, + _createContainer: function () { + var self = this, attribs = {'class': 'file-input file-input-new' + (self.rtl ? ' kv-rtl' : '')}, + $container = $h.createElement($h.cspBuffer.stash(self._renderMain())); + $h.cspBuffer.apply($container); + $container.insertBefore(self.$element).attr(attribs); + self._initBrowse($container); + if (self.theme) { + $container.addClass('theme-' + self.theme); + } + return $container; + }, + _refreshContainer: function () { + var self = this, $container = self.$container, $el = self.$element; + $el.insertAfter($container); + $h.setHtml($container, self._renderMain()); + self._initBrowse($container); + self._validateDisabled(); + }, + _validateDisabled: function () { + var self = this; + self.$caption.attr({readonly: self.isDisabled}); + }, + _setTabIndex: function (type, html) { + var self = this, index = self.tabIndexConfig[type]; + return html.setTokens({ + tabIndexConfig: index === undefined || index === null ? '' : 'tabindex="' + index + '"' + }); + }, + _renderMain: function () { + var self = this, + dropCss = self.dropZoneEnabled ? ' file-drop-zone' : 'file-drop-disabled', + close = !self.showClose ? '' : self._getLayoutTemplate('close'), + preview = !self.showPreview ? '' : self._getLayoutTemplate('preview') + .setTokens({'class': self.previewClass, 'dropClass': dropCss}), + css = self.isDisabled ? self.captionClass + ' file-caption-disabled' : self.captionClass, + caption = self.captionTemplate.setTokens({'class': css + ' kv-fileinput-caption'}); + caption = self._setTabIndex('caption', caption); + return self.mainTemplate.setTokens({ + 'class': self.mainClass + (!self.showBrowse && self.showCaption ? ' no-browse' : ''), + 'inputGroupClass': self.inputGroupClass, + 'preview': preview, + 'close': close, + 'caption': caption, + 'upload': self._renderButton('upload'), + 'remove': self._renderButton('remove'), + 'cancel': self._renderButton('cancel'), + 'pause': self._renderButton('pause'), + 'browse': self._renderButton('browse') + }); + + }, + _renderButton: function (type) { + var self = this, tmplt = self._getLayoutTemplate('btnDefault'), css = self[type + 'Class'], + title = self[type + 'Title'], icon = self[type + 'Icon'], label = self[type + 'Label'], + status = self.isDisabled ? ' disabled' : '', btnType = 'button'; + switch (type) { + case 'remove': + if (!self.showRemove) { + return ''; + } + break; + case 'cancel': + if (!self.showCancel) { + return ''; + } + css += ' kv-hidden'; + break; + case 'pause': + if (!self.showPause) { + return ''; + } + css += ' kv-hidden'; + break; + case 'upload': + if (!self.showUpload) { + return ''; + } + if (self.isAjaxUpload && !self.isDisabled) { + tmplt = self._getLayoutTemplate('btnLink').replace('{href}', self.uploadUrl); + } else { + btnType = 'submit'; + } + break; + case 'browse': + if (!self.showBrowse) { + return ''; + } + tmplt = self._getLayoutTemplate('btnBrowse'); + break; + default: + return ''; + } + tmplt = self._setTabIndex(type, tmplt); + + css += type === 'browse' ? ' btn-file' : ' fileinput-' + type + ' fileinput-' + type + '-button'; + if (!$h.isEmpty(label)) { + label = ' ' + label + ''; + } + return tmplt.setTokens({ + 'type': btnType, 'css': css, 'title': title, 'status': status, 'icon': icon, 'label': label + }); + }, + _renderThumbProgress: function () { + var self = this; + return '
    ' + + self.progressInfoTemplate.setTokens({percent: 101, status: self.msgUploadBegin, stats: ''}) + + '
    '; + }, + _renderFileFooter: function (cat, caption, size, width, isError) { + var self = this, config = self.fileActionSettings, rem = config.showRemove, drg = config.showDrag, + upl = config.showUpload, zoom = config.showZoom, out, params, + template = self._getLayoutTemplate('footer'), tInd = self._getLayoutTemplate('indicator'), + ind = isError ? config.indicatorError : config.indicatorNew, + title = isError ? config.indicatorErrorTitle : config.indicatorNewTitle, + indicator = tInd.setTokens({'indicator': ind, 'indicatorTitle': title}); + size = self._getSize(size); + params = {type: cat, caption: caption, size: size, width: width, progress: '', indicator: indicator}; + if (self.isAjaxUpload) { + params.progress = self._renderThumbProgress(); + params.actions = self._renderFileActions(params, upl, false, rem, zoom, drg, false, false, false); + } else { + params.actions = self._renderFileActions(params, false, false, false, zoom, drg, false, false, false); + } + out = template.setTokens(params); + out = $h.replaceTags(out, self.previewThumbTags); + return out; + }, + _renderFileActions: function ( + cfg, + showUpl, + showDwn, + showDel, + showZoom, + showDrag, + disabled, + url, + key, + isInit, + dUrl, + dFile + ) { + var self = this; + if (!cfg.type && isInit) { + cfg.type = 'image'; + } + if (self.enableResumableUpload) { + showUpl = false; + } else { + if (typeof showUpl === 'function') { + showUpl = showUpl(cfg); + } + } + if (typeof showDwn === 'function') { + showDwn = showDwn(cfg); + } + if (typeof showDel === 'function') { + showDel = showDel(cfg); + } + if (typeof showZoom === 'function') { + showZoom = showZoom(cfg); + } + if (typeof showDrag === 'function') { + showDrag = showDrag(cfg); + } + if (!showUpl && !showDwn && !showDel && !showZoom && !showDrag) { + return ''; + } + var vUrl = url === false ? '' : ' data-url="' + url + '"', btnZoom = '', btnDrag = '', css, + vKey = key === false ? '' : ' data-key="' + key + '"', btnDelete = '', btnUpload = '', btnDownload = '', + template = self._getLayoutTemplate('actions'), config = self.fileActionSettings, + otherButtons = self.otherActionButtons.setTokens({'dataKey': vKey, 'key': key}), + removeClass = disabled ? config.removeClass + ' disabled' : config.removeClass; + if (showDel) { + btnDelete = self._getLayoutTemplate('actionDelete').setTokens({ + 'removeClass': removeClass, + 'removeIcon': config.removeIcon, + 'removeTitle': config.removeTitle, + 'dataUrl': vUrl, + 'dataKey': vKey, + 'key': key + }); + } + if (showUpl) { + btnUpload = self._getLayoutTemplate('actionUpload').setTokens({ + 'uploadClass': config.uploadClass, + 'uploadIcon': config.uploadIcon, + 'uploadTitle': config.uploadTitle + }); + } + if (showDwn) { + btnDownload = self._getLayoutTemplate('actionDownload').setTokens({ + 'downloadClass': config.downloadClass, + 'downloadIcon': config.downloadIcon, + 'downloadTitle': config.downloadTitle, + 'downloadUrl': dUrl || self.initialPreviewDownloadUrl + }); + btnDownload = btnDownload.setTokens({'filename': dFile, 'key': key}); + } + if (showZoom) { + btnZoom = self._getLayoutTemplate('actionZoom').setTokens({ + 'zoomClass': config.zoomClass, + 'zoomIcon': config.zoomIcon, + 'zoomTitle': config.zoomTitle + }); + } + if (showDrag && isInit) { + css = 'drag-handle-init ' + config.dragClass; + btnDrag = self._getLayoutTemplate('actionDrag').setTokens({ + 'dragClass': css, + 'dragTitle': config.dragTitle, + 'dragIcon': config.dragIcon + }); + } + return template.setTokens({ + 'delete': btnDelete, + 'upload': btnUpload, + 'download': btnDownload, + 'zoom': btnZoom, + 'drag': btnDrag, + 'other': otherButtons + }); + }, + _browse: function (e) { + var self = this; + if (e && e.isDefaultPrevented() || !self._raise('filebrowse')) { + return; + } + if (self.isError && !self.isAjaxUpload) { + self.clear(); + } + if (self.focusCaptionOnBrowse) { + self.$captionContainer.focus(); + } + }, + _change: function (e) { + var self = this; + $(document.body).off('focusin.fileinput focusout.fileinput'); + if (self.changeTriggered) { + return; + } + self._setLoading('show'); + var $el = self.$element, isDragDrop = arguments.length > 1, isAjaxUpload = self.isAjaxUpload, + tfiles, files = isDragDrop ? arguments[1] : $el[0].files, ctr = self.fileManager.count(), + total, initCount, len, isSingleUpl = $h.isEmpty($el.attr('multiple')), + maxCount = !isAjaxUpload && isSingleUpl ? 1 : self.maxFileCount, maxTotCount = self.maxTotalFileCount, + inclAll = maxTotCount > 0 && maxTotCount > maxCount, flagSingle = (isSingleUpl && ctr > 0), + throwError = function (mesg, file, previewId, index) { + var p1 = $.extend(true, {}, self._getOutData(null, {}, {}, files), {id: previewId, index: index}), + p2 = {id: previewId, index: index, file: file, files: files}; + self.isPersistentError = true; + self._setLoading('hide'); + return isAjaxUpload ? self._showFileError(mesg, p1) : self._showError(mesg, p2); + }, + maxCountCheck = function (n, m, all) { + var msg = all ? self.msgTotalFilesTooMany : self.msgFilesTooMany; + msg = msg.replace('{m}', m).replace('{n}', n); + self.isError = throwError(msg, null, null, null); + self.$captionContainer.removeClass('icon-visible'); + self._setCaption('', true); + self.$container.removeClass('file-input-new file-input-ajax-new'); + }; + self.reader = null; + self._resetUpload(); + self._hideFileIcon(); + if (self.dropZoneEnabled) { + self.$container.find('.file-drop-zone .' + self.dropZoneTitleClass).remove(); + } + if (!isAjaxUpload) { + if (e.target && e.target.files === undefined) { + files = e.target.value ? [{name: e.target.value.replace(/^.+\\/, '')}] : []; + } else { + files = e.target.files || {}; + } + } + tfiles = files; + if ($h.isEmpty(tfiles) || tfiles.length === 0) { + if (!isAjaxUpload) { + self.clear(); + } + self._raise('fileselectnone'); + return; + } + self._resetErrors(); + len = tfiles.length; + initCount = isAjaxUpload ? (self.fileManager.count() + len) : len; + total = self._getFileCount(initCount, inclAll ? false : undefined); + if (maxCount > 0 && total > maxCount) { + if (!self.autoReplace || len > maxCount) { + maxCountCheck((self.autoReplace && len > maxCount ? len : total), maxCount); + return; + } + if (total > maxCount) { + self._resetPreviewThumbs(isAjaxUpload); + } + } else { + if (inclAll) { + total = self._getFileCount(initCount, true); + if (maxTotCount > 0 && total > maxTotCount) { + if (!self.autoReplace || len > maxCount) { + maxCountCheck((self.autoReplace && len > maxTotCount ? len : total), maxTotCount, true); + return; + } + if (total > maxCount) { + self._resetPreviewThumbs(isAjaxUpload); + } + } + } + if (!isAjaxUpload || flagSingle) { + self._resetPreviewThumbs(false); + if (flagSingle) { + self.clearFileStack(); + } + } else { + if (isAjaxUpload && ctr === 0 && (!self.previewCache.count(true) || self.overwriteInitial)) { + self._resetPreviewThumbs(true); + } + } + } + self.readFiles(tfiles); + self._setLoading('hide'); + }, + _abort: function (params) { + var self = this, data; + if (self.ajaxAborted && typeof self.ajaxAborted === 'object' && self.ajaxAborted.message !== undefined) { + data = $.extend(true, {}, self._getOutData(null), params); + data.abortData = self.ajaxAborted.data || {}; + data.abortMessage = self.ajaxAborted.message; + self._setProgress(101, self.$progress, self.msgCancelled); + self._showFileError(self.ajaxAborted.message, data, 'filecustomerror'); + self.cancel(); + self.unlock(); + return true; + } + return !!self.ajaxAborted; + }, + _resetFileStack: function () { + var self = this, i = 0; + self._getThumbs().each(function () { + var $thumb = $(this), ind = $thumb.attr('data-fileindex'), pid = $thumb.attr('id'); + if (ind === '-1' || ind === -1) { + return; + } + if (!self._getThumbFile($thumb)) { + $thumb.attr({'data-fileindex': i}); + i++; + } else { + $thumb.attr({'data-fileindex': '-1'}); + } + self._getZoom(pid).attr({ + 'data-fileindex': $thumb.attr('data-fileindex') + }); + }); + }, + _isFileSelectionValid: function (cnt) { + var self = this; + cnt = cnt || 0; + if (self.required && !self.getFilesCount()) { + self.$errorContainer.html(''); + self._showFileError(self.msgFileRequired); + return false; + } + if (self.minFileCount > 0 && self._getFileCount(cnt) < self.minFileCount) { + self._noFilesError({}); + return false; + } + return true; + }, + _canPreview: function (file) { + var self = this; + if (!file || !self.showPreview || !self.$preview || !self.$preview.length) { + return false; + } + var name = file.name || '', type = file.type || '', size = (file.size || 0) / self.bytesToKB, + cat = self._parseFileType(type, name), allowedTypes, allowedMimes, allowedExts, skipPreview, + types = self.allowedPreviewTypes, mimes = self.allowedPreviewMimeTypes, + exts = self.allowedPreviewExtensions || [], dTypes = self.disabledPreviewTypes, + dMimes = self.disabledPreviewMimeTypes, dExts = self.disabledPreviewExtensions || [], + maxSize = self.maxFilePreviewSize && parseFloat(self.maxFilePreviewSize) || 0, + expAllExt = new RegExp('\\.(' + exts.join('|') + ')$', 'i'), + expDisExt = new RegExp('\\.(' + dExts.join('|') + ')$', 'i'); + allowedTypes = !types || types.indexOf(cat) !== -1; + allowedMimes = !mimes || mimes.indexOf(type) !== -1; + allowedExts = !exts.length || $h.compare(name, expAllExt); + skipPreview = (dTypes && dTypes.indexOf(cat) !== -1) || (dMimes && dMimes.indexOf(type) !== -1) || + (dExts.length && $h.compare(name, expDisExt)) || (maxSize && !isNaN(maxSize) && size > maxSize); + return !skipPreview && (allowedTypes || allowedMimes || allowedExts); + }, + addToStack: function (file, id) { + this.fileManager.add(file, id); + }, + clearFileStack: function () { + var self = this; + self.fileManager.clear(); + self._initResumableUpload(); + if (self.enableResumableUpload) { + if (self.showPause === null) { + self.showPause = true; + } + if (self.showCancel === null) { + self.showCancel = false; + } + } else { + self.showPause = false; + if (self.showCancel === null) { + self.showCancel = true; + } + } + return self.$element; + }, + getFileStack: function () { + return this.fileManager.stack; + }, + getFileList: function () { + return this.fileManager.list(); + }, + getFilesSize: function () { + return this.fileManager.getTotalSize(); + }, + getFilesCount: function (includeInitial) { + var self = this, len = self.isAjaxUpload ? self.fileManager.count() : self._inputFileCount(); + if (includeInitial) { + len += self.previewCache.count(true); + } + return self._getFileCount(len); + }, + _initCapStatus: function (status) { + var self = this, $cap = self.$caption; + $cap.removeClass('is-valid file-processing'); + if (!status) { + return; + } + if (status === 'processing') { + $cap.addClass('file-processing'); + } else { + $cap.addClass('is-valid'); + } + }, + _setLoading: function (type) { + var self = this; + self.$previewStatus.html(type === 'hide' ? '' : self.msgProcessing); + self.$container.removeClass('file-thumb-loading'); + self._initCapStatus(type === 'hide' ? '' : 'processing'); + if (type !== 'hide') { + if (self.dropZoneEnabled) { + self.$container.find('.file-drop-zone .' + self.dropZoneTitleClass).remove(); + } + self.$container.addClass('file-thumb-loading'); + } + }, + _initFileSelected: function () { + var self = this, $el = self.$element, $body = $(document.body), ev = 'focusin.fileinput focusout.fileinput'; + if ($body.length) { + $body.off(ev).on('focusout.fileinput', function () { + self._setLoading('show'); + }).on('focusin.fileinput', function () { + setTimeout(function () { + if (!$el.val()) { + self._setLoading('hide'); + self._setFileDropZoneTitle(); + } + $body.off(ev); + }, 2500); + }); + } else { + self._setLoading('hide'); + } + }, + readFiles: function (files) { + this.reader = new FileReader(); + var self = this, reader = self.reader, $container = self.$previewContainer, + $status = self.$previewStatus, msgLoading = self.msgLoading, msgProgress = self.msgProgress, + previewInitId = self.previewInitId, numFiles = files.length, settings = self.fileTypeSettings, + readFile, fileTypes = self.allowedFileTypes, typLen = fileTypes ? fileTypes.length : 0, + fileExt = self.allowedFileExtensions, strExt = $h.isEmpty(fileExt) ? '' : fileExt.join(', '), + throwError = function (msg, file, previewId, index, fileId) { + var $thumb, p1 = $.extend(true, {}, self._getOutData(null, {}, {}, files), + {id: previewId, index: index, fileId: fileId}), + p2 = {id: previewId, index: index, fileId: fileId, file: file, files: files}; + self._previewDefault(file, true); + $thumb = self._getFrame(previewId, true); + self._setLoading('hide'); + if (self.isAjaxUpload) { + setTimeout(function () { + readFile(index + 1); + }, self.processDelay); + } else { + self.unlock(); + numFiles = 0; + } + if (self.removeFromPreviewOnError && $thumb.length) { + $thumb.remove(); + } else { + self._initFileActions(); + $thumb.find('.kv-file-upload').remove(); + } + self.isPersistentError = true; + self.isError = self.isAjaxUpload ? self._showFileError(msg, p1) : self._showError(msg, p2); + self._updateFileDetails(numFiles); + }; + self.fileManager.clearImages(); + $.each(files, function (key, file) { + var func = self.fileTypeSettings.image; + if (func && func(file.type)) { + self.fileManager.totalImages++; + } + }); + readFile = function (i) { + var $error = self.$errorContainer, errors, fm = self.fileManager; + if (i >= numFiles) { + self.unlock(); + if (self.duplicateErrors.length) { + errors = '
  • ' + self.duplicateErrors.join('
  • ') + '
  • '; + if ($error.find('ul').length === 0) { + $h.setHtml($error, self.errorCloseButton + '
      ' + errors + '
    '); + } else { + $error.find('ul').append(errors); + } + $error.fadeIn(self.fadeDelay); + self._handler($error.find('.kv-error-close'), 'click', function () { + $error.fadeOut(self.fadeDelay); + }); + self.duplicateErrors = []; + } + if (self.isAjaxUpload) { + self._raise('filebatchselected', [fm.stack]); + if (fm.count() === 0 && !self.isError) { + self.reset(); + } + } else { + self._raise('filebatchselected', [files]); + } + $container.removeClass('file-thumb-loading'); + self._initCapStatus('valid'); + $status.html(''); + return; + } + self.lock(true); + var file = files[i], id = self._getFileId(file), previewId = previewInitId + '-' + id, fSizeKB, j, msg, + fnImage = settings.image, typ, chk, typ1, typ2, + caption = self._getFileName(file, ''), fileSize = (file && file.size || 0) / self.bytesToKB, + fileExtExpr = '', previewData = $h.createObjectURL(file), fileCount = 0, + strTypes = '', fileId, canLoad, fileReaderAborted = false, + func, knownTypes = 0, isImage, txtFlag, processFileLoaded = function () { + var isImageResized = !!fm.loadedImages[id], msg = msgProgress.setTokens({ + 'index': i + 1, + 'files': numFiles, + 'percent': 50, + 'name': caption + }); + setTimeout(function () { + $status.html(msg); + self._updateFileDetails(numFiles); + readFile(i + 1); + }, self.processDelay); + if (self._raise('fileloaded', [file, previewId, id, i, reader]) && self.isAjaxUpload) { + if (!isImageResized) { + fm.add(file); + } + } else { + if (isImageResized) { + fm.removeFile(id); + } + } + }; + if (!file) { + return; + } + fileId = fm.getId(file); + if (typLen > 0) { + for (j = 0; j < typLen; j++) { + typ1 = fileTypes[j]; + typ2 = self.msgFileTypes[typ1] || typ1; + strTypes += j === 0 ? typ2 : ', ' + typ2; + } + } + if (caption === false) { + readFile(i + 1); + return; + } + if (caption.length === 0) { + msg = self.msgInvalidFileName.replace('{name}', $h.htmlEncode($h.getFileName(file), '[unknown]')); + throwError(msg, file, previewId, i, fileId); + return; + } + if (!$h.isEmpty(fileExt)) { + fileExtExpr = new RegExp('\\.(' + fileExt.join('|') + ')$', 'i'); + } + fSizeKB = fileSize.toFixed(2); + if (self.isAjaxUpload && fm.exists(fileId) || self._getFrame(previewId, true).length) { + var p2 = {id: previewId, index: i, fileId: fileId, file: file, files: files}; + msg = self.msgDuplicateFile.setTokens({name: caption, size: fSizeKB}); + if (self.isAjaxUpload) { + self.duplicateErrors.push(msg); + self.isDuplicateError = true; + self._raise('fileduplicateerror', [file, fileId, caption, fSizeKB, previewId, i]); + readFile(i + 1); + self._updateFileDetails(numFiles); + } else { + self._showError(msg, p2); + self.unlock(); + numFiles = 0; + self._clearFileInput(); + self.reset(); + self._updateFileDetails(numFiles); + } + return; + } + if (self.maxFileSize > 0 && fileSize > self.maxFileSize) { + msg = self.msgSizeTooLarge.setTokens({ + 'name': caption, + 'size': fSizeKB, + 'maxSize': self.maxFileSize + }); + throwError(msg, file, previewId, i, fileId); + return; + } + if (self.minFileSize !== null && fileSize <= $h.getNum(self.minFileSize)) { + msg = self.msgSizeTooSmall.setTokens({ + 'name': caption, + 'size': fSizeKB, + 'minSize': self.minFileSize + }); + throwError(msg, file, previewId, i, fileId); + return; + } + if (!$h.isEmpty(fileTypes) && $h.isArray(fileTypes)) { + for (j = 0; j < fileTypes.length; j += 1) { + typ = fileTypes[j]; + func = settings[typ]; + fileCount += !func || (typeof func !== 'function') ? 0 : (func(file.type, + $h.getFileName(file)) ? 1 : 0); + } + if (fileCount === 0) { + msg = self.msgInvalidFileType.setTokens({name: caption, types: strTypes}); + throwError(msg, file, previewId, i, fileId); + return; + } + } + if (fileCount === 0 && !$h.isEmpty(fileExt) && $h.isArray(fileExt) && !$h.isEmpty(fileExtExpr)) { + chk = $h.compare(caption, fileExtExpr); + fileCount += $h.isEmpty(chk) ? 0 : chk.length; + if (fileCount === 0) { + msg = self.msgInvalidFileExtension.setTokens({name: caption, extensions: strExt}); + throwError(msg, file, previewId, i, fileId); + return; + } + } + if (!self._canPreview(file)) { + canLoad = self.isAjaxUpload && self._raise('filebeforeload', [file, i, reader]); + if (self.isAjaxUpload && canLoad) { + fm.add(file); + } + if (self.showPreview && canLoad) { + $container.addClass('file-thumb-loading'); + self._initCapStatus('processing'); + self._previewDefault(file); + self._initFileActions(); + } + setTimeout(function () { + if (canLoad) { + self._updateFileDetails(numFiles); + } + readFile(i + 1); + self._raise('fileloaded', [file, previewId, id, i]); + }, 10); + return; + } + isImage = fnImage(file.type, caption); + $status.html(msgLoading.replace('{index}', i + 1).replace('{files}', numFiles)); + $container.addClass('file-thumb-loading'); + self._initCapStatus('processing'); + reader.onerror = function (evt) { + self._errorHandler(evt, caption); + }; + reader.onload = function (theFile) { + var hex, fileInfo, uint, byte, bytes = [], contents, mime, readImage = function () { + var newReader = new FileReader(); + newReader.onerror = function (theFileNew) { + self._errorHandler(theFileNew, caption); + }; + newReader.onload = function (theFileNew) { + if (self.isAjaxUpload && !self._raise('filebeforeload', [file, i, reader])) { + fileReaderAborted = true; + self._resetCaption(); + reader.abort(); + $status.html(''); + $container.removeClass('file-thumb-loading'); + self._initCapStatus('valid'); + self.enable(); + return; + } + self._previewFile(i, file, theFileNew, previewData, fileInfo); + self._initFileActions(); + processFileLoaded(); + }; + newReader.readAsDataURL(file); + }; + fileInfo = {'name': caption, 'type': file.type}; + $.each(settings, function (k, f) { + if (k !== 'object' && k !== 'other' && typeof f === 'function' && f(file.type, caption)) { + knownTypes++; + } + }); + if (knownTypes === 0) { // auto detect mime types from content if no known file types detected + uint = new Uint8Array(theFile.target.result); + for (j = 0; j < uint.length; j++) { + byte = uint[j].toString(16); + bytes.push(byte); + } + hex = bytes.join('').toLowerCase().substring(0, 8); + mime = $h.getMimeType(hex, '', ''); + if ($h.isEmpty(mime)) { // look for ascii text content + contents = $h.arrayBuffer2String(reader.result); + mime = $h.isSvg(contents) ? 'image/svg+xml' : $h.getMimeType(hex, contents, file.type); + } + fileInfo = {'name': caption, 'type': mime}; + isImage = fnImage(mime, ''); + if (isImage) { + readImage(txtFlag); + return; + } + } + if (self.isAjaxUpload && !self._raise('filebeforeload', [file, i, reader])) { + fileReaderAborted = true; + self._resetCaption(); + reader.abort(); + $status.html(''); + $container.removeClass('file-thumb-loading'); + self._initCapStatus('valid'); + self.enable(); + return; + } + self._previewFile(i, file, theFile, previewData, fileInfo); + self._initFileActions(); + processFileLoaded(); + }; + reader.onprogress = function (data) { + if (data.lengthComputable) { + var fact = (data.loaded / data.total) * 100, progress = Math.ceil(fact); + msg = msgProgress.setTokens({ + 'index': i + 1, + 'files': numFiles, + 'percent': progress, + 'name': caption + }); + setTimeout(function () { + if (!fileReaderAborted) { + $status.html(msg); + } + }, self.processDelay); + } + }; + if (isImage) { + reader.readAsDataURL(file); + } else { + reader.readAsArrayBuffer(file); + } + }; + + readFile(0); + self._updateFileDetails(numFiles); + }, + lock: function (selectMode) { + var self = this, $container = self.$container; + self._resetErrors(); + self.disable(); + if (!selectMode && self.showCancel) { + $container.find('.fileinput-cancel').show(); + } + if (!selectMode && self.showPause) { + $container.find('.fileinput-pause').show(); + } + self._initCapStatus('processing'); + self._raise('filelock', [self.fileManager.stack, self._getExtraData()]); + return self.$element; + }, + unlock: function (reset) { + var self = this, $container = self.$container; + if (reset === undefined) { + reset = true; + } + self.enable(); + $container.removeClass('is-locked'); + if (self.showCancel) { + $container.find('.fileinput-cancel').hide(); + } + if (self.showPause) { + $container.find('.fileinput-pause').hide(); + } + if (reset) { + self._resetFileStack(); + } + self._initCapStatus(); + self._raise('fileunlock', [self.fileManager.stack, self._getExtraData()]); + return self.$element; + }, + resume: function () { + var self = this, fm = self.fileManager, flag = false, rm = self.resumableManager; + fm.bpsLog = []; + fm.bps = 0; + if (!self.enableResumableUpload) { + return self.$element; + } + if (self.paused) { + self._toggleResumableProgress(self.progressPauseTemplate, self.msgUploadResume); + } else { + flag = true; + } + self.paused = false; + if (flag) { + self._toggleResumableProgress(self.progressInfoTemplate, self.msgUploadBegin); + } + setTimeout(function () { + rm.upload(); + }, self.processDelay); + return self.$element; + }, + paste: function (e) { + var self = this, ev = e.originalEvent, files = ev.clipboardData && ev.clipboardData.files || null; + if (files) { + self._dropFiles(e, files); + } + return self.$element; + }, + pause: function () { + var self = this, rm = self.resumableManager, xhr = self.ajaxRequests, len = xhr.length, i, + pct = rm.getProgress(), actions = self.fileActionSettings, tm = self.taskManager, + pool = tm.getPool(rm.id); + if (!self.enableResumableUpload) { + return self.$element; + } else { + if (pool) { + pool.cancel(); + } + } + self._raise('fileuploadpaused', [self.fileManager, rm]); + if (len > 0) { + for (i = 0; i < len; i += 1) { + self.paused = true; + xhr[i].abort(); + } + } + if (self.showPreview) { + self._getThumbs().each(function () { + var $thumb = $(this), t = self._getLayoutTemplate('stats'), stats, + $indicator = $thumb.find('.file-upload-indicator'); + $thumb.removeClass('file-uploading'); + if ($indicator.attr('title') === actions.indicatorLoadingTitle) { + self._setThumbStatus($thumb, 'Paused'); + stats = t.setTokens({pendingTime: self.msgPaused, uploadSpeed: ''}); + self.paused = true; + self._setProgress(pct, $thumb.find('.file-thumb-progress'), pct + '%', stats); + } + if (!self._getThumbFile($thumb)) { + $thumb.find('.kv-file-remove').removeClass('disabled').removeAttr('disabled'); + } + }); + } + self._setProgress(101, self.$progress, self.msgPaused); + return self.$element; + }, + cancel: function () { + var self = this, xhr = self.ajaxRequests, + rm = self.resumableManager, tm = self.taskManager, + pool = rm ? tm.getPool(rm.id) : undefined, len = xhr.length, i; + + if (self.enableResumableUpload && pool) { + pool.cancel().done(function () { + self._setProgressCancelled(); + }); + rm.reset(); + self._raise('fileuploadcancelled', [self.fileManager, rm]); + } else { + self._raise('fileuploadcancelled', [self.fileManager]); + } + self._initAjax(); + if (len > 0) { + for (i = 0; i < len; i += 1) { + self.cancelling = true; + xhr[i].abort(); + } + } + self._getThumbs().each(function () { + var $thumb = $(this), $prog = $thumb.find('.file-thumb-progress'); + $thumb.removeClass('file-uploading'); + self._setProgress(0, $prog); + $prog.hide(); + if (!self._getThumbFile($thumb)) { + $thumb.find('.kv-file-upload').removeClass('disabled').removeAttr('disabled'); + $thumb.find('.kv-file-remove').removeClass('disabled').removeAttr('disabled'); + } + self.unlock(); + }); + setTimeout(function () { + self._setProgressCancelled(); + }, self.processDelay); + return self.$element; + }, + clear: function () { + var self = this, cap; + if (!self._raise('fileclear')) { + return; + } + self.$btnUpload.removeAttr('disabled'); + self._getThumbs().find('video,audio,img').each(function () { + $h.cleanMemory($(this)); + }); + self._clearFileInput(); + self._resetUpload(); + self.clearFileStack(); + self.isDuplicateError = false; + self.isPersistentError = false; + self._resetErrors(true); + if (self._hasInitialPreview()) { + self._showFileIcon(); + self._resetPreview(); + self._initPreviewActions(); + self.$container.removeClass('file-input-new'); + } else { + self._getThumbs().each(function () { + self._clearObjects($(this)); + }); + if (self.isAjaxUpload) { + self.previewCache.data = {}; + } + self.$preview.html(''); + cap = (!self.overwriteInitial && self.initialCaption.length > 0) ? self.initialCaption : ''; + self.$caption.attr('title', '').val(cap); + $h.addCss(self.$container, 'file-input-new'); + self._validateDefaultPreview(); + } + if (self.$container.find($h.FRAMES).length === 0) { + if (!self._initCaption()) { + self.$captionContainer.removeClass('icon-visible'); + } + } + self._hideFileIcon(); + if (self.focusCaptionOnClear) { + self.$captionContainer.focus(); + } + self._setFileDropZoneTitle(); + self._raise('filecleared'); + return self.$element; + }, + reset: function () { + var self = this; + if (!self._raise('filereset')) { + return; + } + self.lastProgress = 0; + self._resetPreview(); + self.$container.find('.fileinput-filename').text(''); + $h.addCss(self.$container, 'file-input-new'); + if (self.getFrames().length) { + self.$container.removeClass('file-input-new'); + } + self.clearFileStack(); + self._setFileDropZoneTitle(); + return self.$element; + }, + disable: function () { + var self = this, $container = self.$container; + self.isDisabled = true; + self._raise('filedisabled'); + self.$element.attr('disabled', 'disabled'); + $container.addClass('is-locked'); + $h.addCss($container.find('.btn-file'), 'disabled'); + $container.find('.kv-fileinput-caption').addClass('file-caption-disabled'); + $container.find('.fileinput-remove, .fileinput-upload, .file-preview-frame button') + .attr('disabled', true); + self._initDragDrop(); + return self.$element; + }, + enable: function () { + var self = this, $container = self.$container; + self.isDisabled = false; + self._raise('fileenabled'); + self.$element.removeAttr('disabled'); + $container.removeClass('is-locked'); + $container.find('.kv-fileinput-caption').removeClass('file-caption-disabled'); + $container.find('.fileinput-remove, .fileinput-upload, .file-preview-frame button') + .removeAttr('disabled'); + $container.find('.btn-file').removeClass('disabled'); + self._initDragDrop(); + return self.$element; + }, + upload: function () { + var self = this, fm = self.fileManager, totLen = fm.count(), i, outData, + hasExtraData = !$.isEmptyObject(self._getExtraData()); + fm.bpsLog = []; + fm.bps = 0; + if (!self.isAjaxUpload || self.isDisabled || !self._isFileSelectionValid(totLen)) { + return; + } + self.lastProgress = 0; + self._resetUpload(); + if (totLen === 0 && !hasExtraData) { + self._showFileError(self.msgUploadEmpty); + return; + } + self.cancelling = false; + self._showProgress(); + self.lock(); + if (totLen === 0 && hasExtraData) { + self._setProgress(2); + self._uploadExtraOnly(); + return; + } + if (self.enableResumableUpload) { + return self.resume(); + } + if (self.uploadAsync || self.enableResumableUpload) { + outData = self._getOutData(null); + if (!self._checkBatchPreupload(outData)) { + return; + } + self.fileBatchCompleted = false; + self.uploadCache = []; + $.each(self.getFileStack(), function (id) { + var previewId = self._getThumbId(id); + self.uploadCache.push({id: previewId, content: null, config: null, tags: null, append: true}); + }); + self.$preview.find('.file-preview-initial').removeClass($h.SORT_CSS); + self._initSortable(); + } + self._setProgress(2); + self.hasInitData = false; + if (self.uploadAsync) { + i = 0; + $.each(self.getFileStack(), function (id) { + self._uploadSingle(i, id, true); + i++; + }); + return; + } + self._uploadBatch(); + return self.$element; + }, + destroy: function () { + var self = this, $form = self.$form, $cont = self.$container, $el = self.$element, ns = self.namespace; + $(document).off(ns); + $(window).off(ns); + if ($form && $form.length) { + $form.off(ns); + } + if (self.isAjaxUpload) { + self._clearFileInput(); + } + self._cleanup(); + self._initPreviewCache(); + $el.insertBefore($cont).off(ns).removeData(); + $cont.off().remove(); + return $el; + }, + refresh: function (options) { + var self = this, $el = self.$element; + if (typeof options !== 'object' || $h.isEmpty(options)) { + options = self.options; + } else { + options = $.extend(true, {}, self.options, options); + } + self._init(options, true); + self._listen(); + return $el; + }, + zoom: function (frameId) { + var self = this, $frame = self._getFrame(frameId); + self._showModal($frame); + }, + getExif: function (frameId) { + var self = this, $frame = self._getFrame(frameId); + return $frame && $frame.data('exif') || null; + }, + getFrames: function (cssFilter) { + var self = this, $frames; + cssFilter = cssFilter || ''; + $frames = self.$preview.find($h.FRAMES + cssFilter); + if (self.reversePreviewOrder) { + $frames = $($frames.get().reverse()); + } + return $frames; + }, + getPreview: function () { + var self = this; + return { + content: self.initialPreview, + config: self.initialPreviewConfig, + tags: self.initialPreviewThumbTags + }; + } + }; + + $.fn.fileinput = function (option) { + if (!$h.hasFileAPISupport() && !$h.isIE(9)) { + return; + } + var args = Array.apply(null, arguments), retvals = []; + args.shift(); + this.each(function () { + var self = $(this), data = self.data('fileinput'), options = typeof option === 'object' && option, + theme = options.theme || self.data('theme'), l = {}, t = {}, + lang = options.language || self.data('language') || $.fn.fileinput.defaults.language || 'en', opt; + if (!data) { + if (theme) { + t = $.fn.fileinputThemes[theme] || {}; + } + if (lang !== 'en' && !$h.isEmpty($.fn.fileinputLocales[lang])) { + l = $.fn.fileinputLocales[lang] || {}; + } + opt = $.extend(true, {}, $.fn.fileinput.defaults, t, $.fn.fileinputLocales.en, l, options, self.data()); + data = new FileInput(this, opt); + self.data('fileinput', data); + } + + if (typeof option === 'string') { + retvals.push(data[option].apply(data, args)); + } + }); + switch (retvals.length) { + case 0: + return this; + case 1: + return retvals[0]; + default: + return retvals; + } + }; + + var IFRAME_ATTRIBS = 'class="kv-preview-data file-preview-pdf" src="{renderer}?file={data}" {style}', + defBtnCss1 = 'btn btn-sm btn-kv ' + $h.defaultButtonCss(), defBtnCss2 = 'btn ' + $h.defaultButtonCss(true); + + $.fn.fileinput.defaults = { + language: 'zh', + bytesToKB: 1024, + showCaption: true, + showBrowse: true, + showPreview: true, + showRemove: true, + showUpload: true, + showUploadStats: true, + showCancel: null, + showPause: null, + showClose: true, + showUploadedThumbs: true, + showConsoleLogs: false, + browseOnZoneClick: false, + autoReplace: false, + showDescriptionClose: true, + autoOrientImage: function () { // applicable for JPEG images only and non ios safari + var ua = window.navigator.userAgent, webkit = !!ua.match(/WebKit/i), + iOS = !!ua.match(/iP(od|ad|hone)/i), iOSSafari = iOS && webkit && !ua.match(/CriOS/i); + return !iOSSafari; + }, + autoOrientImageInitial: true, + required: false, + rtl: false, + hideThumbnailContent: false, + encodeUrl: true, + focusCaptionOnBrowse: true, + focusCaptionOnClear: true, + generateFileId: null, + previewClass: '', + captionClass: '', + frameClass: 'krajee-default', + mainClass: '', + inputGroupClass: '', + mainTemplate: null, + fileSizeGetter: null, + initialCaption: '', + initialPreview: [], + initialPreviewDelimiter: '*$$*', + initialPreviewAsData: false, + initialPreviewFileType: 'image', + initialPreviewConfig: [], + initialPreviewThumbTags: [], + previewThumbTags: {}, + initialPreviewShowDelete: true, + initialPreviewDownloadUrl: '', + removeFromPreviewOnError: false, + deleteUrl: '', + deleteExtraData: {}, + overwriteInitial: true, + sanitizeZoomCache: function (content) { + var $container = $h.createElement(content); + $container.find('input,textarea,select,datalist,form,.file-thumbnail-footer').remove(); + return $container.html(); + }, + previewZoomButtonIcons: { + prev: '', + next: '', + toggleheader: '', + fullscreen: '', + borderless: '', + close: '' + }, + previewZoomButtonClasses: { + prev: 'btn btn-default btn-outline-secondary btn-navigate', + next: 'btn btn-default btn-outline-secondary btn-navigate', + toggleheader: defBtnCss1, + fullscreen: defBtnCss1, + borderless: defBtnCss1, + close: defBtnCss1 + }, + previewTemplates: {}, + previewContentTemplates: {}, + preferIconicPreview: false, + preferIconicZoomPreview: false, + allowedFileTypes: null, + allowedFileExtensions: null, + allowedPreviewTypes: undefined, + allowedPreviewMimeTypes: null, + allowedPreviewExtensions: null, + disabledPreviewTypes: undefined, + disabledPreviewExtensions: ['msi', 'exe', 'com', 'zip', 'rar', 'app', 'vb', 'scr'], + disabledPreviewMimeTypes: null, + defaultPreviewContent: null, + customLayoutTags: {}, + customPreviewTags: {}, + previewFileIcon: '', + previewFileIconClass: 'file-other-icon', + previewFileIconSettings: {}, + previewFileExtSettings: {}, + buttonLabelClass: 'hidden-xs', + browseIcon: ' ', + browseClass: 'btn btn-primary', + removeIcon: '', + removeClass: defBtnCss2, + cancelIcon: '', + cancelClass: defBtnCss2, + pauseIcon: '', + pauseClass: defBtnCss2, + uploadIcon: '', + uploadClass: defBtnCss2, + uploadUrl: null, + uploadUrlThumb: null, + uploadAsync: true, + uploadParamNames: { + chunkCount: 'chunkCount', + chunkIndex: 'chunkIndex', + chunkSize: 'chunkSize', + chunkSizeStart: 'chunkSizeStart', + chunksUploaded: 'chunksUploaded', + fileBlob: 'fileBlob', + fileId: 'fileId', + fileName: 'fileName', + fileRelativePath: 'fileRelativePath', + fileSize: 'fileSize', + retryCount: 'retryCount' + }, + maxAjaxThreads: 5, + fadeDelay: 800, + processDelay: 100, + bitrateUpdateDelay: 500, + queueDelay: 10, // must be lesser than process delay + progressDelay: 0, // must be lesser than process delay + enableResumableUpload: false, + resumableUploadOptions: { + fallback: null, + testUrl: null, // used for checking status of chunks/ files previously / partially uploaded + chunkSize: 2048, // in KB + maxThreads: 4, + maxRetries: 3, + showErrorLog: true, + retainErrorHistory: true, // display complete error history always unless user explicitly resets upload + skipErrorsAndProceed: false // when set to true, files with errors will be skipped and upload will continue with other files + }, + uploadExtraData: {}, + zoomModalHeight: 480, + minImageWidth: null, + minImageHeight: null, + maxImageWidth: null, + maxImageHeight: null, + resizeImage: false, + resizePreference: 'width', + resizeQuality: 0.92, + resizeDefaultImageType: 'image/jpeg', + resizeIfSizeMoreThan: 0, // in KB + minFileSize: -1, + maxFileSize: 0, + maxFilePreviewSize: 25600, // 25 MB + minFileCount: 0, + maxFileCount: 0, + maxTotalFileCount: 0, + validateInitialCount: false, + msgValidationErrorClass: 'text-danger', + msgValidationErrorIcon: ' ', + msgErrorClass: 'file-error-message', + progressThumbClass: 'progress-bar progress-bar-striped active progress-bar-animated', + progressClass: 'progress-bar bg-success progress-bar-success progress-bar-striped active progress-bar-animated', + progressInfoClass: 'progress-bar bg-info progress-bar-info progress-bar-striped active progress-bar-animated', + progressCompleteClass: 'progress-bar bg-success progress-bar-success', + progressPauseClass: 'progress-bar bg-primary progress-bar-primary progress-bar-striped active progress-bar-animated', + progressErrorClass: 'progress-bar bg-danger progress-bar-danger', + progressUploadThreshold: 99, + previewFileType: 'image', + elCaptionContainer: null, + elCaptionText: null, + elPreviewContainer: null, + elPreviewImage: null, + elPreviewStatus: null, + elErrorContainer: null, + errorCloseButton: undefined, + slugCallback: null, + dropZoneEnabled: true, + dropZoneTitleClass: 'file-drop-zone-title', + fileActionSettings: {}, + otherActionButtons: '', + textEncoding: 'UTF-8', + preProcessUpload: null, + ajaxSettings: {}, + ajaxDeleteSettings: {}, + showAjaxErrorDetails: true, + mergeAjaxCallbacks: false, + mergeAjaxDeleteCallbacks: false, + retryErrorUploads: true, + reversePreviewOrder: false, + usePdfRenderer: function () { + var isIE11 = !!window.MSInputMethodContext && !!document.documentMode; + return !!navigator.userAgent.match(/(iPod|iPhone|iPad|Android)/i) || isIE11; + }, + pdfRendererUrl: '', + pdfRendererTemplate: '', + tabIndexConfig: { + browse: 500, + remove: 500, + upload: 500, + cancel: null, + pause: null, + modal: -1 + } + }; + + // noinspection HtmlUnknownAttribute + $.fn.fileinputLocales.en = { + sizeUnits: ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'], + bitRateUnits: ['B/s', 'KB/s', 'MB/s', 'GB/s', 'TB/s', 'PB/s', 'EB/s', 'ZB/s', 'YB/s'], + fileSingle: 'file', + filePlural: 'files', + browseLabel: 'Browse …', + removeLabel: 'Remove', + removeTitle: 'Clear all unprocessed files', + cancelLabel: 'Cancel', + cancelTitle: 'Abort ongoing upload', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', + uploadLabel: 'Upload', + uploadTitle: 'Upload selected files', + msgNo: 'No', + msgNoFilesSelected: 'No files selected', + msgCancelled: 'Cancelled', + msgPaused: 'Paused', + msgPlaceholder: 'Select {files} ...', + msgZoomModalHeading: 'Detailed Preview', + msgFileRequired: 'You must select a file to upload.', + msgSizeTooSmall: 'File "{name}" ({size} KB) is too small and must be larger than {minSize} KB.', + msgSizeTooLarge: 'File "{name}" ({size} KB) exceeds maximum allowed upload size of {maxSize} KB.', + msgFilesTooLess: 'You must select at least {n} {files} to upload.', + msgFilesTooMany: 'Number of files selected for upload ({n}) exceeds maximum allowed limit of {m}.', + msgTotalFilesTooMany: 'You can upload a maximum of {m} files ({n} files detected).', + msgFileNotFound: 'File "{name}" not found!', + msgFileSecured: 'Security restrictions prevent reading the file "{name}".', + msgFileNotReadable: 'File "{name}" is not readable.', + msgFilePreviewAborted: 'File preview aborted for "{name}".', + msgFilePreviewError: 'An error occurred while reading the file "{name}".', + msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".', + msgInvalidFileType: 'Invalid type for file "{name}". Only "{types}" files are supported.', + msgInvalidFileExtension: 'Invalid extension for file "{name}". Only "{extensions}" files are supported.', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'The file upload was aborted', + msgUploadThreshold: 'Processing …', + msgUploadBegin: 'Initializing …', + msgUploadEnd: 'Done', + msgUploadResume: 'Resuming upload …', + msgUploadEmpty: 'No valid data available for upload.', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', + msgValidationError: 'Validation Error', + msgLoading: 'Loading file {index} of {files} …', + msgProgress: 'Loading file {index} of {files} - {name} - {percent}% completed.', + msgSelected: '{n} {files} selected', + msgProcessing: 'Processing ...', + msgFoldersNotAllowed: 'Drag & drop files only! {n} folder(s) dropped were skipped.', + msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.', + msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.', + msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.', + msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.', + msgImageResizeError: 'Could not get the image dimensions to resize.', + msgImageResizeException: 'Error while resizing the image.
    {errors}
    ', + msgAjaxError: 'Something went wrong with the {operation} operation. Please try again later!', + msgAjaxProgressError: '{operation} failed', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond {max} retries for file {file}! Error Details:
    {error}
    ', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', + ajaxOperations: { + deleteThumb: 'file delete', + uploadThumb: 'file upload', + uploadBatch: 'batch file upload', + uploadExtra: 'form data upload' + }, + dropZoneTitle: 'Drag & drop files here …', + dropZoneClickTitle: '
    (or click to select {files})', + previewZoomButtonTitles: { + prev: 'View previous file', + next: 'View next file', + toggleheader: 'Toggle header', + fullscreen: 'Toggle full screen', + borderless: 'Toggle borderless mode', + close: 'Close detailed preview' + } + }; + + $.fn.fileinputLocales.zh = { + sizeUnits: ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'], + bitRateUnits: ['B/s', 'KB/s', 'MB/s', 'GB/s', 'TB/s', 'PB/s', 'EB/s', 'ZB/s', 'YB/s'], + fileSingle: '鏂囦欢', + filePlural: '涓枃浠', + browseLabel: '閫夋嫨 …', + removeLabel: '绉婚櫎', + removeTitle: '娓呴櫎閫変腑鏂囦欢', + cancelLabel: '鍙栨秷', + cancelTitle: '鍙栨秷杩涜涓殑涓婁紶', + pauseLabel: '鏆傚仠', + pauseTitle: '鏆傚仠涓婁紶', + uploadLabel: '涓婁紶', + uploadTitle: '涓婁紶閫変腑鏂囦欢', + msgNo: '娌℃湁', + msgNoFilesSelected: '鏈夋嫨鏂囦欢', + msgPaused: '宸叉殏鍋', + msgCancelled: '鍙栨秷', + msgPlaceholder: '閫夋嫨 {files} ...', + msgZoomModalHeading: '璇︾粏棰勮', + msgFileRequired: '蹇呴』閫夋嫨涓涓枃浠朵笂浼.', + msgSizeTooSmall: '鏂囦欢 "{name}" ({size} KB) 蹇呴』澶т簬闄愬畾澶у皬 {minSize} KB.', + msgSizeTooLarge: '鏂囦欢 "{name}" ({size} KB) 瓒呰繃浜嗗厑璁稿ぇ灏 {maxSize} KB.', + msgFilesTooLess: '浣犲繀椤婚夋嫨鏈灏 {n} {files} 鏉ヤ笂浼. ', + msgFilesTooMany: '閫夋嫨鐨勪笂浼犳枃浠朵釜鏁 ({n}) 瓒呭嚭鏈澶ф枃浠剁殑闄愬埗涓暟 {m}.', + msgTotalFilesTooMany: '浣犳渶澶氬彲浠ヤ笂浼 {m} 涓枃浠 (褰撳墠鏈{n} 涓枃浠).', + msgFileNotFound: '鏂囦欢 "{name}" 鏈壘鍒!', + msgFileSecured: '瀹夊叏闄愬埗锛屼负浜嗛槻姝㈣鍙栨枃浠 "{name}".', + msgFileNotReadable: '鏂囦欢 "{name}" 涓嶅彲璇.', + msgFilePreviewAborted: '鍙栨秷 "{name}" 鐨勯瑙.', + msgFilePreviewError: '璇诲彇 "{name}" 鏃跺嚭鐜颁簡涓涓敊璇.', + msgInvalidFileName: '鏂囦欢鍚 "{name}" 鍖呭惈闈炴硶瀛楃.', + msgInvalidFileType: '涓嶆纭殑绫诲瀷 "{name}". 鍙敮鎸 "{types}" 绫诲瀷鐨勬枃浠.', + msgInvalidFileExtension: '涓嶆纭殑鏂囦欢鎵╁睍鍚 "{name}". 鍙敮鎸 "{extensions}" 鐨勬枃浠舵墿灞曞悕.', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: '璇ユ枃浠朵笂浼犺涓', + msgUploadThreshold: '澶勭悊涓 …', + msgUploadBegin: '姝e湪鍒濆鍖 …', + msgUploadEnd: '瀹屾垚', + msgUploadResume: '缁х画涓婁紶 …', + msgUploadEmpty: '鏃犳晥鐨勬枃浠朵笂浼.', + msgUploadError: '涓婁紶鍑洪敊', + msgDeleteError: '鍒犻櫎鍑洪敊', + msgProgressError: '涓婁紶鍑洪敊', + msgValidationError: '楠岃瘉閿欒', + msgLoading: '鍔犺浇绗 {index} 鏂囦欢 鍏 {files} …', + msgProgress: '鍔犺浇绗 {index} 鏂囦欢 鍏 {files} - {name} - {percent}% 瀹屾垚.', + msgSelected: '{n} {files} 閫変腑', + msgProcessing: '澶勭悊涓 ...', + msgFoldersNotAllowed: '鍙敮鎸佹嫋鎷芥枃浠! 璺宠繃 {n} 鎷栨嫿鐨勬枃浠跺す.', + msgImageWidthSmall: '鍥惧儚鏂囦欢鐨"{name}"鐨勫搴﹀繀椤绘槸鑷冲皯{size}鍍忕礌.', + msgImageHeightSmall: '鍥惧儚鏂囦欢鐨"{name}"鐨勯珮搴﹀繀椤昏嚦灏戜负{size}鍍忕礌.', + msgImageWidthLarge: '鍥惧儚鏂囦欢"{name}"鐨勫搴︿笉鑳借秴杩噞size}鍍忕礌.', + msgImageHeightLarge: '鍥惧儚鏂囦欢"{name}"鐨勯珮搴︿笉鑳借秴杩噞size}鍍忕礌.', + msgImageResizeError: '鏃犳硶鑾峰彇鐨勫浘鍍忓昂瀵歌皟鏁淬', + msgImageResizeException: '璋冩暣鍥惧儚澶у皬鏃跺彂鐢熼敊璇
    {errors}
    ', + msgAjaxError: '{operation} 鍙戠敓閿欒. 璇烽噸璇!', + msgAjaxProgressError: '{operation} 澶辫触', + msgDuplicateFile: '鏂囦欢 "{name}",澶у皬 "{size} KB" 宸茬粡琚変腑.蹇界暐鐩稿悓鐨勬枃浠.', + msgResumableUploadRetriesExceeded: '鏂囦欢 {file} 涓婁紶澶辫触瓒呰繃 {max} 娆¢噸璇 ! 閿欒璇︽儏:
    {error}
    ', + msgPendingTime: '{time} 鍓╀綑', + msgCalculatingTime: '璁$畻鍓╀綑鏃堕棿', + ajaxOperations: { + deleteThumb: '鍒犻櫎鏂囦欢', + uploadThumb: '涓婁紶鏂囦欢', + uploadBatch: '鎵归噺涓婁紶', + uploadExtra: '琛ㄥ崟鏁版嵁涓婁紶' + }, + dropZoneTitle: '鎷栨嫿鏂囦欢鍒拌繖閲 …
    鏀寔澶氭枃浠跺悓鏃朵笂浼', + dropZoneClickTitle: '
    (鎴栫偣鍑粄files}鎸夐挳閫夋嫨鏂囦欢)', + fileActionSettings: { + removeTitle: '鍒犻櫎鏂囦欢', + uploadTitle: '涓婁紶鏂囦欢', + downloadTitle: '涓嬭浇鏂囦欢', + uploadRetryTitle: '閲嶈瘯', + zoomTitle: '鏌ョ湅璇︽儏', + dragTitle: '绉诲姩 / 閲嶇疆', + indicatorNewTitle: '娌℃湁涓婁紶', + indicatorSuccessTitle: '涓婁紶', + indicatorErrorTitle: '涓婁紶閿欒', + indicatorPausedTitle: '涓婁紶宸叉殏鍋', + indicatorLoadingTitle: '涓婁紶 …' + }, + previewZoomButtonTitles: { + prev: '棰勮涓婁竴涓枃浠', + next: '棰勮涓嬩竴涓枃浠', + toggleheader: '缂╂斁', + fullscreen: '鍏ㄥ睆', + borderless: '鏃犺竟鐣屾ā寮', + close: '鍏抽棴褰撳墠棰勮' + } + }; + + $.fn.fileinput.Constructor = FileInput; + + /** + * Convert automatically file inputs with class 'file' into a bootstrap fileinput control. + */ + $(document).ready(function () { + var $input = $('input.file[type=file]'); + if ($input.length) { + $input.fileinput(); + } + }); +})); diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.min.css b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.min.css new file mode 100644 index 000000000..8865aec99 --- /dev/null +++ b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.min.css @@ -0,0 +1,12 @@ +/*! + * bootstrap-fileinput v5.2.4 + * http://plugins.krajee.com/file-input + * + * Krajee default styling for bootstrap-fileinput. + * + * Author: Kartik Visweswaran + * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com + * + * Licensed under the BSD-3-Clause + * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md + */.btn-file input[type=file],.file-caption-icon,.file-no-browse,.file-preview .fileinput-remove,.file-zoom-dialog .btn-navigate,.file-zoom-dialog .floating-buttons,.krajee-default .file-thumb-progress{position:absolute}.file-loading input[type=file],input[type=file].file-loading{width:0;height:0}.file-no-browse{left:50%;bottom:20%;width:1px;height:1px;font-size:0;opacity:0;border:none;background:0 0;outline:0;box-shadow:none}.file-caption-icon,.file-input-ajax-new .fileinput-remove-button,.file-input-ajax-new .fileinput-upload-button,.file-input-ajax-new .no-browse .input-group-btn,.file-input-new .close,.file-input-new .file-preview,.file-input-new .fileinput-remove-button,.file-input-new .fileinput-upload-button,.file-input-new .glyphicon-file,.file-input-new .no-browse .input-group-btn,.file-zoom-dialog .modal-header:after,.file-zoom-dialog .modal-header:before,.hide-content .kv-file-content,.is-locked .fileinput-remove-button,.is-locked .fileinput-upload-button,.kv-hidden{display:none}.file-caption-icon .kv-caption-icon{line-height:inherit}.btn-file,.file-caption,.file-input,.file-loading:before,.file-preview,.file-zoom-dialog .modal-dialog,.krajee-default .file-thumbnail-footer,.krajee-default.file-preview-frame{position:relative}.file-error-message pre,.file-error-message ul,.krajee-default .file-actions,.krajee-default .file-other-error{text-align:left}.file-error-message pre,.file-error-message ul{margin:0}.krajee-default .file-drag-handle,.krajee-default .file-upload-indicator{float:left;margin-top:10px;width:16px;height:16px}.file-thumb-progress .progress,.file-thumb-progress .progress-bar{font-family:Verdana,Helvetica,sans-serif;font-size:.7rem}.krajee-default .file-thumb-progress .progress,.kv-upload-progress .progress{background-color:#ccc}.krajee-default .file-caption-info,.krajee-default .file-size-info{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:160px;height:15px;margin:auto}.file-zoom-content>.file-object.type-flash,.file-zoom-content>.file-object.type-image,.file-zoom-content>.file-object.type-video{max-width:100%;max-height:100%;width:auto}.file-zoom-content>.file-object.type-flash,.file-zoom-content>.file-object.type-video{height:100%}.file-zoom-content>.file-object.type-default,.file-zoom-content>.file-object.type-html,.file-zoom-content>.file-object.type-pdf,.file-zoom-content>.file-object.type-text{width:100%}.file-loading:before{content:" Loading...";display:inline-block;padding-left:20px;line-height:16px;font-size:13px;font-variant:small-caps;color:#999;background:url(loading.gif) top left no-repeat}.file-object{margin:0 0 -5px;padding:0}.btn-file{overflow:hidden}.btn-file input[type=file]{top:0;left:0;min-width:100%;min-height:100%;text-align:right;opacity:0;background:none;cursor:inherit;display:block}.btn-file ::-ms-browse{font-size:10000px;width:100%;height:100%}.file-caption.icon-visible .file-caption-icon{display:inline-block}.file-caption.icon-visible .file-caption-name{padding-left:25px;}.file-caption.icon-visible>.input-group-lg .file-caption-name{padding-left:30px;}.file-caption.icon-visible>.input-group-sm .file-caption-name{padding-left:22px;}.file-caption-name:not(.file-caption-disabled){background-color:transparent}.file-caption-name.file-processing{font-style:italic;border-color:#bbb;opacity:.5}.file-caption-icon{padding:7px 5px;left:4px}.input-group-lg .file-caption-icon{font-size:1.25rem}.input-group-sm .file-caption-icon{font-size:.875rem;padding:.25rem}.file-error-message{color:#a94442;background-color:#f2dede;margin:5px;border:1px solid #ebccd1;border-radius:4px;padding:15px}.file-error-message pre{margin:5px 0}.file-caption-disabled{background-color:#eee;cursor:not-allowed;opacity:1}.file-preview{border-radius:5px;border:1px solid #ddd;padding:8px;width:100%;margin-bottom:5px}.file-preview .btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.file-preview .fileinput-remove{top:1px;right:1px;line-height:10px}.file-preview .clickable{cursor:pointer}.file-preview-image{font:40px Impact,Charcoal,sans-serif;color:green;width:auto;height:auto;max-width:100%;max-height:100%}.krajee-default.file-preview-frame{margin:8px;border:1px solid rgba(0,0,0,.2);box-shadow:0 0 10px 0 rgba(0,0,0,.2);padding:6px;float:left;text-align:center}.krajee-default.file-preview-frame .kv-file-content{width:213px;height:160px}.krajee-default .file-preview-other-frame{display:flex;align-items:center;justify-content:center}.krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered{width:400px}.krajee-default.file-preview-frame[data-template=audio] .kv-file-content{width:240px;height:55px}.krajee-default.file-preview-frame .file-thumbnail-footer{height:70px}.krajee-default.file-preview-frame:not(.file-preview-error):hover{border:1px solid rgba(0,0,0,.3);box-shadow:0 0 10px 0 rgba(0,0,0,.4)}.krajee-default .file-preview-text{color:#428bca;border:1px solid #ddd;outline:0;resize:none}.krajee-default .file-preview-html{border:1px solid #ddd}.krajee-default .file-other-icon{font-size:6em;line-height:1}.krajee-default .file-footer-buttons{float:right}.krajee-default .file-footer-caption{display:block;text-align:center;padding-top:4px;font-size:11px;color:#777;margin-bottom:30px}.file-upload-stats{font-size:10px;text-align:center;width:100%}.kv-upload-progress .file-upload-stats{font-size:12px;margin:-10px 0 5px}.krajee-default .file-preview-error{opacity:.65;box-shadow:none}.krajee-default .file-thumb-progress{top:37px;left:0;right:0}.krajee-default.kvsortable-ghost{background:#e1edf7;border:2px solid #a1abff}.krajee-default .file-preview-other:hover{opacity:.8}.krajee-default .file-preview-frame:not(.file-preview-error) .file-footer-caption:hover{color:#000}.kv-upload-progress .progress{height:20px;margin:10px 0;overflow:hidden}.kv-upload-progress .progress-bar{height:20px;font-family:Verdana,Helvetica,sans-serif}.file-zoom-dialog .file-other-icon{font-size:22em;font-size:50vmin}.file-zoom-dialog .modal-dialog{width:auto}.file-zoom-dialog .modal-header{display:flex;align-items:center;justify-content:space-between}.file-zoom-dialog .btn-navigate{margin:0 .1rem;padding:0;font-size:1.2rem;width:2.4rem;height:2.4rem;top:50%;border-radius:50%;text-align:center}.btn-navigate *{width:auto}.file-zoom-dialog .floating-buttons{top:5px;right:10px}.file-zoom-dialog .btn-kv-prev{left:0}.file-zoom-dialog .btn-kv-next{right:0}.file-zoom-dialog .kv-zoom-caption{max-width:50%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.file-zoom-dialog .kv-zoom-header{padding:.5rem}.file-zoom-dialog .kv-zoom-body{padding:.25rem .5rem .25rem 0}.file-zoom-dialog .kv-zoom-description{position:absolute;opacity:.8;font-size:.8rem;background-color:#1a1a1a;padding:1rem;text-align:center;border-radius:.5rem;color:#fff;left:15%;right:15%;bottom:15%}.file-zoom-dialog .kv-desc-hide{float:right;color:#fff;padding:0 .1rem;background:0 0;border:none}.file-zoom-dialog .kv-desc-hide:hover{opacity:.7}.file-zoom-dialog .kv-desc-hide:focus{opacity:.9}.file-input-ajax-new .no-browse .form-control,.file-input-new .no-browse .form-control{border-top-right-radius:4px;border-bottom-right-radius:4px}.file-caption{width:100%;position:relative}.file-thumb-loading{background:url(loading.gif) center center no-repeat content-box!important}.file-drop-zone{border:1px dashed #aaa;min-height:260px;border-radius:4px;text-align:center;vertical-align:middle;margin:12px 15px 12px 12px;padding:5px}.file-drop-zone.clickable:hover{border:2px dashed #999}.file-drop-zone.clickable:focus{border:2px solid #5acde2}.file-drop-zone .file-preview-thumbnails{cursor:default}.file-drop-zone-title{color:#aaa;font-size:1.6em;text-align:center;padding:85px 10px;cursor:default}.file-highlighted{border:2px dashed #999!important;background-color:#eee}.file-uploading{background:url(loading-sm.gif) center bottom 10px no-repeat;opacity:.65}.file-zoom-fullscreen .modal-dialog{min-width:100%;margin:0}.file-zoom-fullscreen .modal-content{border-radius:0;box-shadow:none;min-height:100vh}.file-zoom-fullscreen .kv-zoom-body{overflow-y:auto}.floating-buttons{z-index:3000}.floating-buttons .btn-kv{margin-left:3px;z-index:3000}.kv-zoom-actions .btn-kv{margin-left:3px}.file-zoom-content{text-align:center;white-space:nowrap;min-height:300px}.file-zoom-content:hover{background:0 0}.file-zoom-content>*{display:inline-block;vertical-align:middle}.file-zoom-content .kv-spacer{height:100%}.file-zoom-content .file-preview-image,.file-zoom-content .file-preview-video{max-height:100%}.file-zoom-content>.file-object.type-image{height:auto;min-height:inherit}.file-zoom-content>.file-object.type-audio{width:auto;height:30px}@media (min-width:576px){.file-zoom-dialog .modal-dialog{max-width:500px}}@media (min-width:992px){.file-zoom-dialog .modal-lg{max-width:800px}}@media (max-width:767px){.file-preview-thumbnails{display:flex;justify-content:center;align-items:center;flex-direction:column}.file-zoom-dialog .modal-header{flex-direction:column}}@media (max-width:350px){.krajee-default.file-preview-frame:not([data-template=audio]) .kv-file-content{width:160px}}@media (max-width:420px){.krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered{width:100%}}.file-loading[dir=rtl]:before{background:url(loading.gif) top right no-repeat;padding-left:0;padding-right:20px}.clickable .file-drop-zone-title{cursor:pointer}.file-sortable .file-drag-handle:hover{opacity:.7}.file-sortable .file-drag-handle{cursor:grab;opacity:1}.file-grabbing,.file-grabbing *{cursor:not-allowed!important}.file-grabbing .file-preview-thumbnails *{cursor:grabbing!important}.file-preview-frame.sortable-chosen{background-color:#d9edf7;border-color:#17a2b8;box-shadow:none!important}.file-preview .kv-zoom-cache{display:none} \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.min.js b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.min.js new file mode 100644 index 000000000..c6c1d2d97 --- /dev/null +++ b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.min.js @@ -0,0 +1,11 @@ +/*! + * bootstrap-fileinput v5.2.4 + * http://plugins.krajee.com/file-input + * + * Author: Kartik Visweswaran + * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com + * + * Licensed under the BSD-3-Clause + * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md + */ +!function(e){"use strict";"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof module&&module.exports?module.exports=e(require("jquery")):e(window.jQuery)}(function(L){"use strict";L.fn.fileinputLocales={},L.fn.fileinputThemes={},L.fn.fileinputBsVersion||(L.fn.fileinputBsVersion=window.Alert&&window.Alert.VERSION||window.bootstrap&&window.bootstrap.Alert&&bootstrap.Alert.VERSION||"3.x.x"),String.prototype.setTokens=function(e){var t,i,a=this.toString();for(t in e)e.hasOwnProperty(t)&&(i=new RegExp("{"+t+"}","g"),a=a.replace(i,e[t]));return a},Array.prototype.flatMap||(Array.prototype.flatMap=function(e){return[].concat(this.map(e))}),document.currentScript||(document.currentScript=(i=document.getElementsByTagName("script"))[i.length-1]);var e,N={FRAMES:".kv-preview-thumb",SORT_CSS:"file-sortable",INIT_FLAG:"init-",ZOOM_VAR:(e=document.currentScript.src).substring(0,e.lastIndexOf("/"))+"/loading.gif?kvTemp__2873389129__=",OBJECT_PARAMS:'\n\n\n\n\n\n',DEFAULT_PREVIEW:'
    \n{previewFileIcon}\n
    ',MODAL_ID:"kvFileinputModal",MODAL_EVENTS:["show","shown","hide","hidden","loaded"],logMessages:{ajaxError:"{status}: {error}. Error Details: {text}.",badDroppedFiles:"Error scanning dropped files!",badExifParser:"Error loading the piexif.js library. {details}",badInputType:'The input "type" must be set to "file" for initializing the "bootstrap-fileinput" plugin.',exifWarning:'To avoid this warning, either set "autoOrientImage" to "false" OR ensure you have loaded the "piexif.js" library correctly on your page before the "fileinput.js" script.',invalidChunkSize:'Invalid upload chunk size: "{chunkSize}". Resumable uploads are disabled.',invalidThumb:'Invalid thumb frame with id: "{id}".',noResumableSupport:"The browser does not support resumable or chunk uploads.",noUploadUrl:'The "uploadUrl" is not set. Ajax uploads and resumable uploads have been disabled.',retryStatus:"Retrying upload for chunk # {chunk} for {filename}... retry # {retry}.",chunkQueueError:"Could not push task to ajax pool for chunk index # {index}.",resumableMaxRetriesReached:"Maximum resumable ajax retries ({n}) reached.",resumableRetryError:"Could not retry the resumable request (try # {n})... aborting.",resumableAborting:"Aborting / cancelling the resumable request.",resumableRequestError:"Error processing resumable request. {msg}"},objUrl:window.URL||window.webkitURL,isBs:function(e){var t=L.trim((L.fn.fileinputBsVersion||"")+"");return e=parseInt(e,10),t?e===parseInt(t.charAt(0),10):4===e},defaultButtonCss:function(e){return"btn-default btn-"+(e?"":"outline-")+"secondary"},now:function(){return(new Date).getTime()},round:function(e){return e=parseFloat(e),isNaN(e)?0:Math.floor(Math.round(e))},getArray:function(e){for(var t=[],i=e&&e.length||0,a=0;a >4){case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7:n+=String.fromCharCode(t);break;case 12:case 13:i=r[o++],n+=String.fromCharCode((31&t)<<6|63&i);break;case 14:i=r[o++],a=r[o++],n+=String.fromCharCode((15&t)<<12|(63&i)<<6|(63&a)<<0)}return n},isHtml:function(e){var t=document.createElement("div");t.innerHTML=e;for(var i=t.childNodes,a=i.length;a--;)if(1===i[a].nodeType)return!0;return!1},isSvg:function(e){return e.match(/^\s*<\?xml/i)&&(e.match(/"+e+""))},uniqId:function(){return((new Date).getTime()+Math.floor(Math.random()*Math.pow(10,15))).toString(36)},cspBuffer:{CSP_ATTRIB:"data-csp-01928735",domElementsStyles:{},stash:function(e){var n=this,t=L.parseHTML("
    "+e+"
    "),e=L(t);return e.find("[style]").each(function(e,t){var i=L(t),a=i[0].style,t=N.uniqId(),r={};a&&a.length&&(L(a).each(function(){r[this]=a[this]}),n.domElementsStyles[t]=r,i.removeAttr("style").attr(n.CSP_ATTRIB,t))}),e.filter("*").removeAttr("style"),(Object.values?Object.values(t):Object.keys(t).map(function(e){return t[e]})).flatMap(function(e){return e.innerHTML}).join("")},apply:function(e){var a=this;L(e).find("["+a.CSP_ATTRIB+"]").each(function(e,t){var i=L(t),t=i.attr(a.CSP_ATTRIB),t=a.domElementsStyles[t];t&&i.css(t),i.removeAttr(a.CSP_ATTRIB)}),a.domElementsStyles={}}},setHtml:function(e,t){var i=N.cspBuffer;return e.html(i.stash(t)),i.apply(e),e},htmlEncode:function(e,t){return void 0===e?t||null:e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")},replaceTags:function(e,t){var i=e;return t&&L.each(t,function(e,t){"function"==typeof t&&(t=t()),i=i.split(e).join(t)}),i},cleanMemory:function(e){e=(e.is("img")?e:e.find("source")).attr("src");N.revokeObjectURL(e)},findFileName:function(e){var t=e.lastIndexOf("/");return-1===t&&(t=e.lastIndexOf("\\")),e.split(e.substring(t,t+1)).pop()},checkFullScreen:function(){return document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement||document.msFullscreenElement},toggleFullScreen:function(e){var t=document,i=t.documentElement,a=N.checkFullScreen();i&&e&&!a?i.requestFullscreen?i.requestFullscreen():i.msRequestFullscreen?i.msRequestFullscreen():i.mozRequestFullScreen?i.mozRequestFullScreen():i.webkitRequestFullscreen&&i.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT):a&&(t.exitFullscreen?t.exitFullscreen():t.msExitFullscreen?t.msExitFullscreen():t.mozCancelFullScreen?t.mozCancelFullScreen():t.webkitExitFullscreen&&t.webkitExitFullscreen())},moveArray:function(e,t,i,a){var r=L.extend(!0,[],e);if(a&&r.reverse(),i>=r.length)for(var n=i-r.length;1+n--;)r.push(void 0);return r.splice(i,0,r.splice(t,1)[0]),a&&r.reverse(),r},closeButton:function(e){return'"},getRotation:function(e){switch(e){case 2:return"rotateY(180deg)";case 3:return"rotate(180deg)";case 4:return"rotate(180deg) rotateY(180deg)";case 5:return"rotate(270deg) rotateY(180deg)";case 6:return"rotate(90deg)";case 7:return"rotate(90deg) rotateY(180deg)";case 8:return"rotate(270deg)";default:return""}},setTransform:function(e,t){e&&(e.style.transform=t,e.style.webkitTransform=t,e.style["-moz-transform"]=t,e.style["-ms-transform"]=t,e.style["-o-transform"]=t)},getObjectKeys:function(e){var t=[];return e&&L.each(e,function(e){t.push(e)}),t},getObjectSize:function(e){return N.getObjectKeys(e).length},whenAll:function(e){for(var t,i,a,r=[].slice,n=1===arguments.length&&N.isArray(e)?e:r.call(arguments),o=L.Deferred(),s=0,l=n.length,d=l,c=i=a=Array(l),u=function(e,t,i){return function(){i!==n&&s++,o.notifyWith(t[e]=this,i[e]=r.call(arguments)),--d||o[(s?"reject":"resolve")+"With"](t,i)}},p=0;pg.file.size?g.file.size:e},getTotalChunks:function(){var e=parseFloat(g.chunkSize);return!isNaN(e)&&0h.maxRetries)return s(d.resumableMaxRetriesReached,{n:h.maxRetries}),void g.setProcessed("error");var c,u=t[t.slice?"slice":t.mozSlice?"mozSlice":t.webkitSlice?"webkitSlice":"slice"](e*r,e*(r+1)),p=new FormData,f=w.stack[l];m._setUploadData(p,{chunkCount:g.chunkCount,chunkIndex:r,chunkSize:e,chunkSizeStart:e*r,fileBlob:[u,g.fileName],fileId:l,fileName:g.fileName,fileRelativePath:f.relativePath,fileSize:t.size,retryCount:n}),g.$progress&&g.$progress.length&&g.$progress.show(),e=function(e){c=m._getOutData(p,e),m.showPreview&&(i.hasClass("file-preview-success")||(m._setThumbStatus(i,"Loading"),N.addCss(i,"file-uploading")),a.attr("disabled",!0)),m._raise("filechunkbeforesend",[l,r,n,w,g,c])},u=function(e,t,i){var a;m._isAborted()?s(d.resumableAborting):(c=m._getOutData(p,i,e),a=m.uploadParamNames.chunkIndex||"chunkIndex",i=[l,r,n,w,g,c],e.error?(h.showErrorLog&&m._log(v.retryStatus,{retry:n+1,filename:g.fileName,chunk:r}),m._raise("filechunkerror",i),g.pushAjax(r,n+1),g.error=e.error,s(e.error)):(g.logs[e[a]]=!0,g.chunksProcessed[l]||(g.chunksProcessed[l]={}),g.chunksProcessed[l][e[a]]=!0,g.chunksProcessed[l].data=e,o.resolve.call(null,e),m._raise("filechunksuccess",i),g.check()))},f=function(e,t,i){m._isAborted()?s(d.resumableAborting):(c=m._getOutData(p,e),g.setAjaxError(e,t,i),m._raise("filechunkajaxerror",[l,r,n,w,g,c]),g.pushAjax(r,n+1),s(d.resumableRetryError,{n:n-1}))},t=function(){m._isAborted()||m._raise("filechunkcomplete",[l,r,n,w,g,m._getOutData(p)])},m._ajaxSubmit(e,u,t,f,p,l,g.fileIndex)}}}).reset());h.fallback(m)}},_initTemplateDefaults:function(){var i=this,e=function(e,t){return'\n"+N.DEFAULT_PREVIEW+"\n\n"},t="btn btn-sm btn-kv "+N.defaultButtonCss(),a='{preview}\n
    \n
    \n
    \n {caption}\n\n'+(N.isBs(5)?"":'
    \n')+" {remove}\n {cancel}\n {pause}\n {upload}\n {browse}\n"+(N.isBs(5)?"":"
    \n")+"
    ",r=N.closeButton("fileinput-remove"),n=N.MODAL_ID+"Label",o='',s='\n',l=" {style}",d=e("html","text/html"),c=e("text","text/plain;charset=UTF-8"),u=e("pdf","application/pdf"),p='{alt}\n",f='",g='",m='\n",h='\x3c!--suppress ALL --\x3e\n",v='\n",n='\n\n'+N.OBJECT_PARAMS+" "+N.DEFAULT_PREVIEW+"\n\n",w='
    \n"+N.DEFAULT_PREVIEW+"\n
    \n",e={width:"100%",height:"100%","min-height":"480px"};i._isPdfRendered()&&(u=i.pdfRendererTemplate.replace("{renderer}",i._encodeURI(i.pdfRendererUrl))),i.defaults={layoutTemplates:{main1:a,main2:'{preview}\n
    \n
    \n{remove}\n{cancel}\n{upload}\n{browse}\n',preview:'
    \n {close}
    \n
    \n
    \n
    \n
    \n
    \n
    ',close:r,fileIcon:'',caption:'\n',modalMain:o,modal:s,descriptionClose:'',progress:'
    \n
    \n {status}\n
    \n
    {stats}',stats:'
    {pendingTime} {uploadSpeed}
    ',size:" ({sizeText})",footer:'',indicator:'
    {indicator}
    ',actions:'
    \n \n
    \n{drag}\n
    ',actionDelete:'\n',actionUpload:'',actionDownload:'{downloadIcon}',actionZoom:'',actionDrag:'{dragIcon}',btnDefault:'',btnLink:'{icon} {label}',btnBrowse:'
    {icon} {label}
    ',zoomCache:'
    {zoomContent}
    '},previewMarkupTags:{tagBefore1:'
    \n',tagBefore2:'
    \n',tagAfter:"
    {footer}\n{zoomCache}
    \n"},previewContentTemplates:{generic:"{content}\n",html:d,image:p,text:c,office:f,gdocs:g,video:m,audio:h,flash:v,object:n,pdf:u,other:w},allowedPreviewTypes:["image","html","text","video","audio","flash","pdf","object"],previewTemplates:{},previewSettings:{image:{width:"auto",height:"auto","max-width":"100%","max-height":"100%"},html:{width:"213px",height:"160px"},text:{width:"213px",height:"160px"},office:{width:"213px",height:"160px"},gdocs:{width:"213px",height:"160px"},video:{width:"213px",height:"160px"},audio:{width:"100%",height:"30px"},flash:{width:"213px",height:"160px"},object:{width:"213px",height:"160px"},pdf:{width:"100%",height:"160px",position:"relative"},other:{width:"213px",height:"160px"}},previewSettingsSmall:{image:{width:"auto",height:"auto","max-width":"100%","max-height":"100%"},html:{width:"100%",height:"160px"},text:{width:"100%",height:"160px"},office:{width:"100%",height:"160px"},gdocs:{width:"100%",height:"160px"},video:{width:"100%",height:"auto"},audio:{width:"100%",height:"30px"},flash:{width:"100%",height:"auto"},object:{width:"100%",height:"auto"},pdf:{width:"100%",height:"160px"},other:{width:"100%",height:"160px"}},previewZoomSettings:{image:{width:"auto",height:"auto","max-width":"100%","max-height":"100%"},html:e,text:e,office:{width:"100%",height:"100%","max-width":"100%","min-height":"480px"},gdocs:{width:"100%",height:"100%","max-width":"100%","min-height":"480px"},video:{width:"auto",height:"100%","max-width":"100%"},audio:{width:"100%",height:"30px"},flash:{width:"auto",height:"480px"},object:{width:"auto",height:"100%","max-width":"100%","min-height":"480px"},pdf:e,other:{width:"auto",height:"100%","min-height":"480px"}},mimeTypeAliases:{"video/quicktime":"video/mp4"},fileTypeSettings:{image:function(e,t){return N.compare(e,"image.*")&&!N.compare(e,/(tiff?|wmf)$/i)||N.compare(t,/\.(gif|png|jpe?g)$/i)},html:function(e,t){return N.compare(e,"text/html")||N.compare(t,/\.(htm|html)$/i)},office:function(e,t){return N.compare(e,/(word|excel|powerpoint|office)$/i)||N.compare(t,/\.(docx?|xlsx?|pptx?|pps|potx?)$/i)},gdocs:function(e,t){return N.compare(e,/(word|excel|powerpoint|office|iwork-pages|tiff?)$/i)||N.compare(t,/\.(docx?|xlsx?|pptx?|pps|potx?|rtf|ods|odt|pages|ai|dxf|ttf|tiff?|wmf|e?ps)$/i)},text:function(e,t){return N.compare(e,"text.*")||N.compare(t,/\.(xml|javascript)$/i)||N.compare(t,/\.(txt|md|nfo|ini|json|php|js|css)$/i)},video:function(e,t){return N.compare(e,"video.*")&&(N.compare(e,/(ogg|mp4|mp?g|mov|webm|3gp)$/i)||N.compare(t,/\.(og?|mp4|webm|mp?g|mov|3gp)$/i))},audio:function(e,t){return N.compare(e,"audio.*")&&(N.compare(t,/(ogg|mp3|mp?g|wav)$/i)||N.compare(t,/\.(og?|mp3|mp?g|wav)$/i))},flash:function(e,t){return N.compare(e,"application/x-shockwave-flash",!0)||N.compare(t,/\.(swf)$/i)},pdf:function(e,t){return N.compare(e,"application/pdf",!0)||N.compare(t,/\.(pdf)$/i)},object:function(){return!0},other:function(){return!0}},fileActionSettings:{showRemove:!0,showUpload:!0,showDownload:!0,showZoom:!0,showDrag:!0,removeIcon:'',removeClass:t,removeErrorClass:"btn btn-sm btn-kv btn-danger",removeTitle:"Remove file",uploadIcon:'',uploadClass:t,uploadTitle:"Upload file",uploadRetryIcon:'',uploadRetryTitle:"Retry upload",downloadIcon:'',downloadClass:t,downloadTitle:"Download file",zoomIcon:'',zoomClass:t,zoomTitle:"View Details",dragIcon:'',dragClass:"text-primary",dragTitle:"Move / Rearrange",dragSettings:{},indicatorNew:'',indicatorSuccess:'',indicatorError:'',indicatorLoading:'',indicatorPaused:'',indicatorNewTitle:"Not uploaded yet",indicatorSuccessTitle:"Uploaded",indicatorErrorTitle:"Upload Error",indicatorLoadingTitle:"Uploading …",indicatorPausedTitle:"Upload Paused"}},L.each(i.defaults,function(e,t){"allowedPreviewTypes"!==e?i[e]=L.extend(!0,{},t,i[e]):void 0===i.allowedPreviewTypes&&(i.allowedPreviewTypes=t)}),i._initPreviewTemplates()},_initPreviewTemplates:function(){var i,a=this,r=a.previewMarkupTags,n=r.tagAfter;L.each(a.previewContentTemplates,function(e,t){N.isEmpty(a.previewTemplates[e])&&(i=r.tagBefore2,"generic"!==e&&"image"!==e||(i=r.tagBefore1),a._isPdfRendered()&&"pdf"===e&&(i=i.replace("kv-file-content","kv-file-content kv-pdf-rendered")),a.previewTemplates[e]=i+t+n)})},_initPreviewCache:function(){var f=this;f.previewCache={data:{},init:function(){var e=f.initialPreview;0'+e+"":"
  • "+e+"
  • ";return 0===r.find("ul").length?a._addError("
      "+i+"
    "):r.find("ul").append(i),r.fadeIn(a.fadeDelay),a._raise(n,[t,e]),a._setValidationError("file-input-new"),!0},_showError:function(e,t,i){var a=this,r=a.$errorContainer,i=i||"fileerror";return(t=t||{}).reader=a.reader,a._addError(e),r.fadeIn(a.fadeDelay),a._raise(i,[t,e]),a.isAjaxUpload||a._clearFileInput(),a._setValidationError("file-input-new"),a.$btnUpload.attr("disabled",!0),!0},_noFilesError:function(e){var t=this,i=1"+a+"";0===i.find("ul").length?t._addError("
      "+a+"
    "):i.find("ul").append(a),t.isError=!0,t._updateFileDetails(0),i.fadeIn(t.fadeDelay),t._raise("fileerror",[e,a]),t._clearFileInput(),t._setValidationError()},_parseError:function(e,t,i,a){var r=this,n=L.trim(i+""),i=t.responseJSON&&t.responseJSON.error?t.responseJSON.error.toString():"",t=i||t.responseText;return r.cancelling&&r.msgUploadAborted&&(n=r.msgUploadAborted),r.showAjaxErrorDetails&&t&&(i?n=L.trim(i+""):(i=(t=L.trim(t.replace(/\n\s*\n/g,"\n"))).length?"
    "+t+"
    ":"",n+=n?i:t)),n=n||r.msgAjaxError.replace("{operation}",e),r.cancelling=!1,a?""+a+": "+n:n},_parseFileType:function(e,t){var i,a,r=this.allowedPreviewTypes||[];if("application/text-plain"===e)return"text";for(a=0;a.kv-file-content img"),t=r._getZoom(t," >.kv-file-content img"),o?e.css("image-orientation",r.autoOrientImageInitial?"from-image":"none"):r.setImageOrientation(e,t,a.exif.Orientation,i)),n++})},_initPreview:function(e){var t,i=this,a=i.initialCaption||"";if(!i.previewCache.count(!0))return i._clearPreview(),void(e?i._setCaption(a):i._initCaption());t=i.previewCache.out(),a=e&&i.initialCaption?i.initialCaption:t.caption,i._setPreviewContent(t.content),i._setInitThumbAttr(),i._setCaption(a),i._initSortable(),N.isEmpty(t.content)||i.$container.removeClass("file-input-new"),i._initPreviewImageOrientations()},_getZoomButton:function(e){var t=this.previewZoomButtonIcons[e],i=this.previewZoomButtonClasses[e],a=' title="'+(this.previewZoomButtonTitles[e]||"")+'" ',r=N.isBs(5)?"bs-":"",r=a+("close"===e?" data-"+r+'dismiss="modal" aria-hidden="true"':"");return"fullscreen"!==e&&"borderless"!==e&&"toggleheader"!==e||(r+=' data-toggle="button" aria-pressed="false" autocomplete="off"'),'"},_getModalContent:function(){var e=this;return e._getLayoutTemplate("modal").setTokens({rtl:e.rtl?" kv-rtl":"",zoomFrameClass:e.frameClass,prev:e._getZoomButton("prev"),next:e._getZoomButton("next"),toggleheader:e._getZoomButton("toggleheader"),fullscreen:e._getZoomButton("fullscreen"),borderless:e._getZoomButton("borderless"),close:e._getZoomButton("close")})},_listenModalEvent:function(a){var r=this,n=r.$modal;n.on(a+".bs.modal",function(e){var t,i;"bs.modal"===e.namespace&&(t=n.find(".btn-fullscreen"),i=n.find(".btn-borderless"),n.data("fileinputPluginId")===r.$element.attr("id")&&r._raise("filezoom"+a,{sourceEvent:e,previewId:n.data("previewId"),modal:n}),"shown"===a&&(i.removeClass("active").attr("aria-pressed","false"),t.removeClass("active").attr("aria-pressed","false"),n.hasClass("file-zoom-fullscreen")&&(r._maximizeZoomDialog(),(N.checkFullScreen()?t:i).addClass("active").attr("aria-pressed","true"))))})},_initZoom:function(){var i=this,e=i._getLayoutTemplate("modalMain"),t="#"+N.MODAL_ID,e=i._setTabIndex("modal",e);i.showPreview&&(i.$modal=L(t),i.$modal&&i.$modal.length||(e=N.createElement(N.cspBuffer.stash(e)).insertAfter(i.$container),i.$modal=L(t).insertBefore(e),N.cspBuffer.apply(i.$modal),e.remove()),N.initModal(i.$modal),i.$modal.html(N.cspBuffer.stash(i._getModalContent())),N.cspBuffer.apply(i.$modal),L.each(N.MODAL_EVENTS,function(e,t){i._listenModalEvent(t)}))},_initZoomButtons:function(){var e,t=this,i=t.$modal.data("previewId")||"",a=t.getFrames().toArray(),r=a.length,n=t.$modal.find(".btn-kv-prev"),o=t.$modal.find(".btn-kv-next");if(a.length<2)return n.hide(),void o.hide();n.show(),o.show(),r&&(e=L(a[0]),r=L(a[r-1]),n.removeAttr("disabled"),o.removeAttr("disabled"),t.reversePreviewOrder&&([n,o]=[o,n]),e.length&&e.attr("id")===i&&n.attr("disabled",!0),r.length&&r.attr("id")===i&&o.attr("disabled",!0))},_maximizeZoomDialog:function(){var e=this.$modal,t=e.find(".modal-header:visible"),i=e.find(".modal-footer:visible"),a=e.find(".kv-zoom-body"),r=L(window).height();e.addClass("file-zoom-fullscreen"),t&&t.length&&(r-=t.outerHeight(!0)),i&&i.length&&(r-=i.outerHeight(!0)),a&&a.length&&(r-=a.outerHeight(!0)-a.height()),e.find(".kv-zoom-body").height(r)},_resizeZoomDialog:function(e){var t=this,i=t.$modal,a=i.find(".btn-kv-fullscreen"),r=i.find(".btn-kv-borderless");if(i.hasClass("file-zoom-fullscreen"))N.toggleFullScreen(!1),e?a.hasClass("active")||(i.removeClass("file-zoom-fullscreen"),t._resizeZoomDialog(!0),r.hasClass("active")&&r.removeClass("active").attr("aria-pressed","false")):a.hasClass("active")?a.removeClass("active").attr("aria-pressed","false"):(i.removeClass("file-zoom-fullscreen"),t.$modal.find(".kv-zoom-body").css("height",t.zoomModalHeight));else{if(!e)return void t._maximizeZoomDialog();N.toggleFullScreen(!0)}i.focus()},_setZoomContent:function(e,t){var i,a,r,n,o,s=this,l=e.attr("id"),d=s._getZoom(l),c=s.$modal,u=c.find(".btn-kv-fullscreen"),p=c.find(".btn-kv-borderless"),f=c.find(".btn-kv-toggleheader"),g=e.data("zoom");g&&(g=decodeURIComponent(g),o=d.html().replace(N.ZOOM_VAR,"").setTokens({zoomData:g}),d.html(o),e.data("zoom",""),d.attr("data-zoom",g)),n=d.attr("data-template")||"generic",g=(o=d.find(".kv-file-content")).length?'\n'+o.html():"",d=e.data("caption")||s.msgZoomModalHeading,o=e.data("size")||"",e=e.data("description")||"",c.find(".kv-zoom-caption").attr("title",d).html(d),c.find(".kv-zoom-size").html(o),o=c.find(".kv-zoom-description").hide(),e&&(s.showDescriptionClose&&(e=s._getLayoutTemplate("descriptionClose").setTokens({closeIcon:s.previewZoomButtonIcons.close})+""+e),o.show().html(e),s.showDescriptionClose&&s._handler(c.find(".kv-desc-hide"),"click",function(){L(this).parent().fadeOut("fast",function(){c.focus()})})),i=c.find(".kv-zoom-body"),c.removeClass("kv-single-content"),t?(r=i.addClass("file-thumb-loading").clone().insertAfter(i),N.setHtml(i,g).hide(),r.fadeOut("fast",function(){i.fadeIn("fast",function(){i.removeClass("file-thumb-loading")}),r.remove()})):N.setHtml(i,g),(n=s.previewZoomSettings[n])&&(a=i.find(".kv-preview-data"),N.addCss(a,"file-zoom-detail"),L.each(n,function(e,t){a.css(e,t),(a.attr("width")&&"width"===e||a.attr("height")&&"height"===e)&&a.removeAttr(e)})),c.data("previewId",l),s._handler(c.find(".btn-kv-prev"),"click",function(){s._zoomSlideShow("prev",l)}),s._handler(c.find(".btn-kv-next"),"click",function(){s._zoomSlideShow("next",l)}),s._handler(u,"click",function(){s._resizeZoomDialog(!0)}),s._handler(p,"click",function(){s._resizeZoomDialog(!1)}),s._handler(f,"click",function(){function e(e){var t=s.$modal.find(".kv-zoom-body"),i=s.zoomModalHeight;c.hasClass("file-zoom-fullscreen")&&(i=t.outerHeight(!0),e||(i-=a.outerHeight(!0))),t.css("height",e?i+e:i)}var t,a=c.find(".modal-header"),i=c.find(".floating-buttons"),r=a.find(".kv-zoom-actions");a.is(":visible")?(t=a.outerHeight(!0),a.slideUp("slow",function(){r.find(".btn").appendTo(i),e(t)})):(i.find(".btn").appendTo(r),a.slideDown("slow",function(){e()})),c.focus()}),s._handler(c,"keydown",function(e){var t,a=e.which||e.keyCode,r=s.processDelay+1,i=L(this).find(".btn-kv-prev"),n=L(this).find(".btn-kv-next"),o=L(this).data("previewId");[t,e]=s.rtl?[39,37]:[37,39],L.each({prev:[i,t],next:[n,e]},function(e,t){var i=t[0],t=t[1];a===t&&i.length&&(c.focus(),i.attr("disabled")||(i.focus(),s._zoomSlideShow(e,o),setTimeout(function(){i.attr("disabled")&&c.focus()},r)))})})},_showModal:function(e){var t=this.$modal;e&&e.length&&(N.initModal(t),N.setHtml(t,this._getModalContent()),this._setZoomContent(e),t.data({backdrop:!1}),t.modal("show"),this._initZoomButtons())},_zoomPreview:function(e){if(!e.length)throw"Cannot zoom to detailed preview!";e=e.closest(N.FRAMES),this._showModal(e)},_zoomSlideShow:function(e,t){var i,a,r,n=this,o=n.$modal.find(".kv-zoom-actions .btn-kv-"+e),s=n.getFrames().toArray(),l=[],d=s.length;if(n.reversePreviewOrder&&(e="prev"===e?"next":"prev"),!o.attr("disabled")){for(i=0;i'+e.defaultPreviewContent+"
    "),e.$container.removeClass("file-input-new"),e._initClickable())},_resetPreviewThumbs:function(e){var t=this;if(e)return t._clearPreview(),void t.clearFileStack();t._hasInitialPreview()?(e=t.previewCache.out(),t._setPreviewContent(e.content),t._setInitThumbAttr(),t._setCaption(e.caption),t._initPreviewActions()):t._clearPreview()},_getLayoutTemplate:function(e){e=this.layoutTemplates[e];return N.isEmpty(this.customLayoutTags)?e:N.replaceTags(e,this.customLayoutTags)},_getPreviewTemplate:function(e){var t=this.previewTemplates,t=t[e]||t.other;return N.isEmpty(this.customPreviewTags)?t:N.replaceTags(t,this.customPreviewTags)},_getOutData:function(e,t,i,a){var r=this;return t=t||{},i=i||{},{formdata:e,files:a=a||r.fileManager.list(),filenames:r.filenames,filescount:r.getFilesCount(),extra:r._getExtraData(),response:i,reader:r.reader,jqXHR:t}},_getMsgSelected:function(e,t){var i=this,a=1===e?i.fileSingle:i.filePlural;return 0 .file-preview-frame");e&&e.length&&e.insertBefore(t).fadeIn("slow").css("display:inline-block"),l._initPreviewActions(),l._clearFileInput(),t.remove(),a.remove(),l._initSortable()})):(l.previewCache.set(r,n,o,e),l._initPreview(),l._initPreviewActions())),l._resetCaption()},_getUploadCacheIndex:function(e){for(var t=this.uploadCache.length,i=0;i&"']/g,"_")},_updateFileDetails:function(e){var t=this,i=t.$element,a=N.isIE(9)&&N.findFileName(i.val())||i[0].files[0]&&i[0].files[0].name,r=!a&&0'+a+"
    "),t.$container.removeClass("file-input-new"),N.addCss(t.$container,"file-input-ajax-new"))},_getStats:function(e){var t,i;return this.showUploadStats&&e&&e.bitrate?(i=this._getLayoutTemplate("stats"),t=e.elapsed&&e.bps?this.msgPendingTime.setTokens({time:N.getElapsed(Math.ceil(e.pendingBytes/e.bps))}):this.msgCalculatingTime,i.setTokens({uploadSpeed:e.bitrate,pendingTime:t})):""},_setResumableProgress:function(e,t,i){var a=this.resumableManager,a=i?a:this,i=i?i.find(".file-thumb-progress"):null;0===a.lastProgress&&(a.lastProgress=e),eo*a.bytesToKB&&a._getResizedImage(e,t,r,n),t.validated=!0)}))},_getResizedImage:function(e,t,i,a){var r,n,o=this,s=L(t.img)[0],l=s.naturalWidth,d=s.naturalHeight,c=1,u=o.maxImageWidth||l,p=o.maxImageHeight||d,f=!(!l||!d),g=o.imageCanvas,m=o.imageCanvasContext,h=t.typ,v=t.pid,w=t.ind,b=t.thumb,_=t.exifObj,C=function(e,t,i){o.isAjaxUpload?o._showFileError(e,t,i):o._showError(e,t,i),o._setPreviewError(b)},t=o.fileManager.getFile(e),y={id:v,index:w,fileId:e},x=[e,v,w];if(t&&f&&!(l<=u&&d<=p)||(f&&t&&o._raise("fileimageresized",x),i.val++,i.val===a&&o._raise("fileimagesresized"),f)){h=h||o.resizeDefaultImageType,t=u"+n.msgValidationError+"
    ").text(),r=(a=n.fileManager.count())?(r=n.fileManager.getFirstFile(),1===a&&r?r.nameFmt:n._getMsgSelected(a)):n._getMsgSelected(n.msgNo),a=N.isEmpty(e)?r:e,r=''+n.msgValidationErrorIcon+"";else{if(N.isEmpty(e))return void n.$caption.attr("title","");a=i=L("
    "+e+"
    ").text(),r=n._getLayoutTemplate("fileIcon")}n.$captionContainer.addClass("icon-visible"),n.$caption.attr("title",i).val(a),N.setHtml(n.$captionIcon,r)}},_createContainer:function(){var e=this,t={class:"file-input file-input-new"+(e.rtl?" kv-rtl":"")},i=N.createElement(N.cspBuffer.stash(e._renderMain()));return N.cspBuffer.apply(i),i.insertBefore(e.$element).attr(t),e._initBrowse(i),e.theme&&i.addClass("theme-"+e.theme),i},_refreshContainer:function(){var e=this,t=e.$container;e.$element.insertAfter(t),N.setHtml(t,e._renderMain()),e._initBrowse(t),e._validateDisabled()},_validateDisabled:function(){this.$caption.attr({readonly:this.isDisabled})},_setTabIndex:function(e,t){e=this.tabIndexConfig[e];return t.setTokens({tabIndexConfig:null==e?"":'tabindex="'+e+'"'})},_renderMain:function(){var e=this,t=e.dropZoneEnabled?" file-drop-zone":"file-drop-disabled",i=e.showClose?e._getLayoutTemplate("close"):"",a=e.showPreview?e._getLayoutTemplate("preview").setTokens({class:e.previewClass,dropClass:t}):"",t=e.isDisabled?e.captionClass+" file-caption-disabled":e.captionClass,t=e.captionTemplate.setTokens({class:t+" kv-fileinput-caption"}),t=e._setTabIndex("caption",t);return e.mainTemplate.setTokens({class:e.mainClass+(!e.showBrowse&&e.showCaption?" no-browse":""),inputGroupClass:e.inputGroupClass,preview:a,close:i,caption:t,upload:e._renderButton("upload"),remove:e._renderButton("remove"),cancel:e._renderButton("cancel"),pause:e._renderButton("pause"),browse:e._renderButton("browse")})},_renderButton:function(e){var t=this,i=t._getLayoutTemplate("btnDefault"),a=t[e+"Class"],r=t[e+"Title"],n=t[e+"Icon"],o=t[e+"Label"],s=t.isDisabled?" disabled":"",l="button";switch(e){case"remove":if(!t.showRemove)return"";break;case"cancel":if(!t.showCancel)return"";a+=" kv-hidden";break;case"pause":if(!t.showPause)return"";a+=" kv-hidden";break;case"upload":if(!t.showUpload)return"";t.isAjaxUpload&&!t.isDisabled?i=t._getLayoutTemplate("btnLink").replace("{href}",t.uploadUrl):l="submit";break;case"browse":if(!t.showBrowse)return"";i=t._getLayoutTemplate("btnBrowse");break;default:return""}return i=t._setTabIndex(e,i),a+="browse"===e?" btn-file":" fileinput-"+e+" fileinput-"+e+"-button",N.isEmpty(o)||(o=' '+o+""),i.setTokens({type:l,css:a,title:r,status:s,icon:n,label:o})},_renderThumbProgress:function(){return'
    '+this.progressInfoTemplate.setTokens({percent:101,status:this.msgUploadBegin,stats:""})+"
    "},_renderFileFooter:function(e,t,i,a,r){var n=this,o=n.fileActionSettings,s=o.showRemove,l=o.showDrag,d=o.showUpload,c=o.showZoom,u=n._getLayoutTemplate("footer"),p=n._getLayoutTemplate("indicator"),f=r?o.indicatorError:o.indicatorNew,o=r?o.indicatorErrorTitle:o.indicatorNewTitle,o=p.setTokens({indicator:f,indicatorTitle:o}),o={type:e,caption:t,size:i=n._getSize(i),width:a,progress:"",indicator:o};return n.isAjaxUpload?(o.progress=n._renderThumbProgress(),o.actions=n._renderFileActions(o,d,!1,s,c,l,!1,!1,!1)):o.actions=n._renderFileActions(o,!1,!1,!1,c,l,!1,!1,!1),o=u.setTokens(o),o=N.replaceTags(o,n.previewThumbTags)},_renderFileActions:function(e,t,i,a,r,n,o,s,l,d,c,u){var p=this;if(!e.type&&d&&(e.type="image"),p.enableResumableUpload?t=!1:"function"==typeof t&&(t=t(e)),"function"==typeof i&&(i=i(e)),"function"==typeof a&&(a=a(e)),"function"==typeof r&&(r=r(e)),"function"==typeof n&&(n=n(e)),!(t||i||a||r||n))return"";var f=!1===s?"":' data-url="'+s+'"',g="",m="",h=!1===l?"":' data-key="'+l+'"',v="",w="",b="",_=p._getLayoutTemplate("actions"),e=p.fileActionSettings,s=p.otherActionButtons.setTokens({dataKey:h,key:l}),o=o?e.removeClass+" disabled":e.removeClass;return a&&(v=p._getLayoutTemplate("actionDelete").setTokens({removeClass:o,removeIcon:e.removeIcon,removeTitle:e.removeTitle,dataUrl:f,dataKey:h,key:l})),t&&(w=p._getLayoutTemplate("actionUpload").setTokens({uploadClass:e.uploadClass,uploadIcon:e.uploadIcon,uploadTitle:e.uploadTitle})),i&&(b=(b=p._getLayoutTemplate("actionDownload").setTokens({downloadClass:e.downloadClass,downloadIcon:e.downloadIcon,downloadTitle:e.downloadTitle,downloadUrl:c||p.initialPreviewDownloadUrl})).setTokens({filename:u,key:l})),r&&(g=p._getLayoutTemplate("actionZoom").setTokens({zoomClass:e.zoomClass,zoomIcon:e.zoomIcon,zoomTitle:e.zoomTitle})),n&&d&&(d="drag-handle-init "+e.dragClass,m=p._getLayoutTemplate("actionDrag").setTokens({dragClass:d,dragTitle:e.dragTitle,dragIcon:e.dragIcon})),_.setTokens({delete:v,upload:w,download:b,zoom:g,drag:m,other:s})},_browse:function(e){var t=this;e&&e.isDefaultPrevented()||!t._raise("filebrowse")||(t.isError&&!t.isAjaxUpload&&t.clear(),t.focusCaptionOnBrowse&&t.$captionContainer.focus())},_change:function(e){var n=this;if(L(document.body).off("focusin.fileinput focusout.fileinput"),!n.changeTriggered){n._setLoading("show");var t=n.$element,i=1
  • ")+"
  • ",0===e.find("ul").length?N.setHtml(e,S.errorCloseButton+"
      "+x+"
    "):e.find("ul").append(x),e.fadeIn(S.fadeDelay),S._handler(e.find(".kv-error-close"),"click",function(){e.fadeOut(S.fadeDelay)}),S.duplicateErrors=[]),S.isAjaxUpload?(S._raise("filebatchselected",[i.stack]),0!==i.count()||S.isError||S.reset()):S._raise("filebatchselected",[P]),I.removeClass("file-thumb-loading"),S._initCapStatus("valid"),void A.html("");S.lock(!0);function c(){var e=!!i.loadedImages[s],t=D.setTokens({index:d+1,files:j,percent:50,name:m});setTimeout(function(){A.html(t),S._updateFileDetails(j),k(d+1)},S.processDelay),S._raise("fileloaded",[f,l,s,d,E])&&S.isAjaxUpload?e||i.add(f):e&&i.removeFile(s)}var t,u,a,r,n,o,p,f=P[d],s=S._getFileId(f),l=U+"-"+s,g=M.image,m=S._getFileName(f,""),h=(f&&f.size||0)/S.bytesToKB,v="",w=N.createObjectURL(f),b=0,_="",C=!1,y=0;if(f){if(r=i.getId(f),0S.maxFileSize)return T=S.msgSizeTooLarge.setTokens({name:m,size:t,maxSize:S.maxFileSize}),void F(T,f,l,d,r);if(null!==S.minFileSize&&h<=N.getNum(S.minFileSize))return T=S.msgSizeTooSmall.setTokens({name:m,size:t,minSize:S.minFileSize}),void F(T,f,l,d,r);if(!N.isEmpty($)&&N.isArray($)){for(u=0;u<$.length;u+=1)o=$[u],b+=(o=M[o])&&"function"==typeof o&&o(f.type,N.getFileName(f))?1:0;if(0===b)return T=S.msgInvalidFileType.setTokens({name:m,types:_}),void F(T,f,l,d,r)}return 0!==b||N.isEmpty(R)||!N.isArray(R)||N.isEmpty(v)||(v=N.compare(m,v),0!==(b+=N.isEmpty(v)?0:v.length))?S._canPreview(f)?(p=g(f.type,m),A.html(z.replace("{index}",d+1).replace("{files}",j)),I.addClass("file-thumb-loading"),S._initCapStatus("processing"),E.onerror=function(e){S._errorHandler(e,m)},E.onload=function(e){var t,i,a,r,n,o,s=[],l={name:m,type:f.type};if(L.each(M,function(e,t){"object"!==e&&"other"!==e&&"function"==typeof t&&t(f.type,m)&&y++}),0===y){for(i=new Uint8Array(e.target.result),u=0;u',next:'',toggleheader:'',fullscreen:'',borderless:'',close:''},previewZoomButtonClasses:{prev:"btn btn-default btn-outline-secondary btn-navigate",next:"btn btn-default btn-outline-secondary btn-navigate",toggleheader:t,fullscreen:t,borderless:t,close:t},previewTemplates:{},previewContentTemplates:{},preferIconicPreview:!1,preferIconicZoomPreview:!1,allowedFileTypes:null,allowedFileExtensions:null,allowedPreviewTypes:void 0,allowedPreviewMimeTypes:null,allowedPreviewExtensions:null,disabledPreviewTypes:void 0,disabledPreviewExtensions:["msi","exe","com","zip","rar","app","vb","scr"],disabledPreviewMimeTypes:null,defaultPreviewContent:null,customLayoutTags:{},customPreviewTags:{},previewFileIcon:'',previewFileIconClass:"file-other-icon",previewFileIconSettings:{},previewFileExtSettings:{},buttonLabelClass:"hidden-xs",browseIcon:' ',browseClass:"btn btn-primary",removeIcon:'',removeClass:i,cancelIcon:'',cancelClass:i,pauseIcon:'',pauseClass:i,uploadIcon:'',uploadClass:i,uploadUrl:null,uploadUrlThumb:null,uploadAsync:!0,uploadParamNames:{chunkCount:"chunkCount",chunkIndex:"chunkIndex",chunkSize:"chunkSize",chunkSizeStart:"chunkSizeStart",chunksUploaded:"chunksUploaded",fileBlob:"fileBlob",fileId:"fileId",fileName:"fileName",fileRelativePath:"fileRelativePath",fileSize:"fileSize",retryCount:"retryCount"},maxAjaxThreads:5,fadeDelay:800,processDelay:100,bitrateUpdateDelay:500,queueDelay:10,progressDelay:0,enableResumableUpload:!1,resumableUploadOptions:{fallback:null,testUrl:null,chunkSize:2048,maxThreads:4,maxRetries:3,showErrorLog:!0,retainErrorHistory:!0,skipErrorsAndProceed:!1},uploadExtraData:{},zoomModalHeight:480,minImageWidth:null,minImageHeight:null,maxImageWidth:null,maxImageHeight:null,resizeImage:!1,resizePreference:"width",resizeQuality:.92,resizeDefaultImageType:"image/jpeg",resizeIfSizeMoreThan:0,minFileSize:-1,maxFileSize:0,maxFilePreviewSize:25600,minFileCount:0,maxFileCount:0,maxTotalFileCount:0,validateInitialCount:!1,msgValidationErrorClass:"text-danger",msgValidationErrorIcon:' ',msgErrorClass:"file-error-message",progressThumbClass:"progress-bar progress-bar-striped active progress-bar-animated",progressClass:"progress-bar bg-success progress-bar-success progress-bar-striped active progress-bar-animated",progressInfoClass:"progress-bar bg-info progress-bar-info progress-bar-striped active progress-bar-animated",progressCompleteClass:"progress-bar bg-success progress-bar-success",progressPauseClass:"progress-bar bg-primary progress-bar-primary progress-bar-striped active progress-bar-animated",progressErrorClass:"progress-bar bg-danger progress-bar-danger",progressUploadThreshold:99,previewFileType:"image",elCaptionContainer:null,elCaptionText:null,elPreviewContainer:null,elPreviewImage:null,elPreviewStatus:null,elErrorContainer:null,errorCloseButton:void 0,slugCallback:null,dropZoneEnabled:!0,dropZoneTitleClass:"file-drop-zone-title",fileActionSettings:{},otherActionButtons:"",textEncoding:"UTF-8",preProcessUpload:null,ajaxSettings:{},ajaxDeleteSettings:{},showAjaxErrorDetails:!0,mergeAjaxCallbacks:!1,mergeAjaxDeleteCallbacks:!1,retryErrorUploads:!0,reversePreviewOrder:!1,usePdfRenderer:function(){var e=!!window.MSInputMethodContext&&!!document.documentMode;return!!navigator.userAgent.match(/(iPod|iPhone|iPad|Android)/i)||e},pdfRendererUrl:"",pdfRendererTemplate:'',tabIndexConfig:{browse:500,remove:500,upload:500,cancel:null,pause:null,modal:-1}},L.fn.fileinputLocales.en={sizeUnits:["B","KB","MB","GB","TB","PB","EB","ZB","YB"],bitRateUnits:["B/s","KB/s","MB/s","GB/s","TB/s","PB/s","EB/s","ZB/s","YB/s"],fileSingle:"file",filePlural:"files",browseLabel:"Browse …",removeLabel:"Remove",removeTitle:"Clear all unprocessed files",cancelLabel:"Cancel",cancelTitle:"Abort ongoing upload",pauseLabel:"Pause",pauseTitle:"Pause ongoing upload",uploadLabel:"Upload",uploadTitle:"Upload selected files",msgNo:"No",msgNoFilesSelected:"No files selected",msgCancelled:"Cancelled",msgPaused:"Paused",msgPlaceholder:"Select {files} ...",msgZoomModalHeading:"Detailed Preview",msgFileRequired:"You must select a file to upload.",msgSizeTooSmall:'File "{name}" ({size} KB) is too small and must be larger than {minSize} KB.',msgSizeTooLarge:'File "{name}" ({size} KB) exceeds maximum allowed upload size of {maxSize} KB.',msgFilesTooLess:"You must select at least {n} {files} to upload.",msgFilesTooMany:"Number of files selected for upload ({n}) exceeds maximum allowed limit of {m}.",msgTotalFilesTooMany:"You can upload a maximum of {m} files ({n} files detected).",msgFileNotFound:'File "{name}" not found!',msgFileSecured:'Security restrictions prevent reading the file "{name}".',msgFileNotReadable:'File "{name}" is not readable.',msgFilePreviewAborted:'File preview aborted for "{name}".',msgFilePreviewError:'An error occurred while reading the file "{name}".',msgInvalidFileName:'Invalid or unsupported characters in file name "{name}".',msgInvalidFileType:'Invalid type for file "{name}". Only "{types}" files are supported.',msgInvalidFileExtension:'Invalid extension for file "{name}". Only "{extensions}" files are supported.',msgFileTypes:{image:"image",html:"HTML",text:"text",video:"video",audio:"audio",flash:"flash",pdf:"PDF",object:"object"},msgUploadAborted:"The file upload was aborted",msgUploadThreshold:"Processing …",msgUploadBegin:"Initializing …",msgUploadEnd:"Done",msgUploadResume:"Resuming upload …",msgUploadEmpty:"No valid data available for upload.",msgUploadError:"Upload Error",msgDeleteError:"Delete Error",msgProgressError:"Error",msgValidationError:"Validation Error",msgLoading:"Loading file {index} of {files} …",msgProgress:"Loading file {index} of {files} - {name} - {percent}% completed.",msgSelected:"{n} {files} selected",msgProcessing:"Processing ...",msgFoldersNotAllowed:"Drag & drop files only! {n} folder(s) dropped were skipped.",msgImageWidthSmall:'Width of image file "{name}" must be at least {size} px.',msgImageHeightSmall:'Height of image file "{name}" must be at least {size} px.',msgImageWidthLarge:'Width of image file "{name}" cannot exceed {size} px.',msgImageHeightLarge:'Height of image file "{name}" cannot exceed {size} px.',msgImageResizeError:"Could not get the image dimensions to resize.",msgImageResizeException:"Error while resizing the image.
    {errors}
    ",msgAjaxError:"Something went wrong with the {operation} operation. Please try again later!",msgAjaxProgressError:"{operation} failed",msgDuplicateFile:'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.',msgResumableUploadRetriesExceeded:"Upload aborted beyond {max} retries for file {file}! Error Details:
    {error}
    ",msgPendingTime:"{time} remaining",msgCalculatingTime:"calculating time remaining",ajaxOperations:{deleteThumb:"file delete",uploadThumb:"file upload",uploadBatch:"batch file upload",uploadExtra:"form data upload"},dropZoneTitle:"Drag & drop files here …",dropZoneClickTitle:"
    (or click to select {files})",previewZoomButtonTitles:{prev:"View previous file",next:"View next file",toggleheader:"Toggle header",fullscreen:"Toggle full screen",borderless:"Toggle borderless mode",close:"Close detailed preview"}},L.fn.fileinputLocales.zh={sizeUnits:["B","KB","MB","GB","TB","PB","EB","ZB","YB"],bitRateUnits:["B/s","KB/s","MB/s","GB/s","TB/s","PB/s","EB/s","ZB/s","YB/s"],fileSingle:"鏂囦欢",filePlural:"涓枃浠",browseLabel:"閫夋嫨 …",removeLabel:"绉婚櫎",removeTitle:"娓呴櫎閫変腑鏂囦欢",cancelLabel:"鍙栨秷",cancelTitle:"鍙栨秷杩涜涓殑涓婁紶",pauseLabel:"鏆傚仠",pauseTitle:"鏆傚仠涓婁紶",uploadLabel:"涓婁紶",uploadTitle:"涓婁紶閫変腑鏂囦欢",msgNo:"娌℃湁",msgNoFilesSelected:"鏈夋嫨鏂囦欢",msgPaused:"宸叉殏鍋",msgCancelled:"鍙栨秷",msgPlaceholder:"閫夋嫨 {files} ...",msgZoomModalHeading:"璇︾粏棰勮",msgFileRequired:"蹇呴』閫夋嫨涓涓枃浠朵笂浼.",msgSizeTooSmall:'鏂囦欢 "{name}" ({size} KB) 蹇呴』澶т簬闄愬畾澶у皬 {minSize} KB.',msgSizeTooLarge:'鏂囦欢 "{name}" ({size} KB) 瓒呰繃浜嗗厑璁稿ぇ灏 {maxSize} KB.',msgFilesTooLess:"浣犲繀椤婚夋嫨鏈灏 {n} {files} 鏉ヤ笂浼. ",msgFilesTooMany:"閫夋嫨鐨勪笂浼犳枃浠朵釜鏁 ({n}) 瓒呭嚭鏈澶ф枃浠剁殑闄愬埗涓暟 {m}.",msgTotalFilesTooMany:"浣犳渶澶氬彲浠ヤ笂浼 {m} 涓枃浠 (褰撳墠鏈{n} 涓枃浠).",msgFileNotFound:'鏂囦欢 "{name}" 鏈壘鍒!',msgFileSecured:'瀹夊叏闄愬埗锛屼负浜嗛槻姝㈣鍙栨枃浠 "{name}".',msgFileNotReadable:'鏂囦欢 "{name}" 涓嶅彲璇.',msgFilePreviewAborted:'鍙栨秷 "{name}" 鐨勯瑙.',msgFilePreviewError:'璇诲彇 "{name}" 鏃跺嚭鐜颁簡涓涓敊璇.',msgInvalidFileName:'鏂囦欢鍚 "{name}" 鍖呭惈闈炴硶瀛楃.',msgInvalidFileType:'涓嶆纭殑绫诲瀷 "{name}". 鍙敮鎸 "{types}" 绫诲瀷鐨勬枃浠.',msgInvalidFileExtension:'涓嶆纭殑鏂囦欢鎵╁睍鍚 "{name}". 鍙敮鎸 "{extensions}" 鐨勬枃浠舵墿灞曞悕.',msgFileTypes:{image:"image",html:"HTML",text:"text",video:"video",audio:"audio",flash:"flash",pdf:"PDF",object:"object"},msgUploadAborted:"璇ユ枃浠朵笂浼犺涓",msgUploadThreshold:"澶勭悊涓 …",msgUploadBegin:"姝e湪鍒濆鍖 …",msgUploadEnd:"瀹屾垚",msgUploadResume:"缁х画涓婁紶 …",msgUploadEmpty:"鏃犳晥鐨勬枃浠朵笂浼.",msgUploadError:"涓婁紶鍑洪敊",msgDeleteError:"鍒犻櫎鍑洪敊",msgProgressError:"涓婁紶鍑洪敊",msgValidationError:"楠岃瘉閿欒",msgLoading:"鍔犺浇绗 {index} 鏂囦欢 鍏 {files} …",msgProgress:"鍔犺浇绗 {index} 鏂囦欢 鍏 {files} - {name} - {percent}% 瀹屾垚.",msgSelected:"{n} {files} 閫変腑",msgProcessing:"澶勭悊涓 ...",msgFoldersNotAllowed:"鍙敮鎸佹嫋鎷芥枃浠! 璺宠繃 {n} 鎷栨嫿鐨勬枃浠跺す.",msgImageWidthSmall:'鍥惧儚鏂囦欢鐨"{name}"鐨勫搴﹀繀椤绘槸鑷冲皯{size}鍍忕礌.',msgImageHeightSmall:'鍥惧儚鏂囦欢鐨"{name}"鐨勯珮搴﹀繀椤昏嚦灏戜负{size}鍍忕礌.',msgImageWidthLarge:'鍥惧儚鏂囦欢"{name}"鐨勫搴︿笉鑳借秴杩噞size}鍍忕礌.',msgImageHeightLarge:'鍥惧儚鏂囦欢"{name}"鐨勯珮搴︿笉鑳借秴杩噞size}鍍忕礌.',msgImageResizeError:"鏃犳硶鑾峰彇鐨勫浘鍍忓昂瀵歌皟鏁淬",msgImageResizeException:"璋冩暣鍥惧儚澶у皬鏃跺彂鐢熼敊璇
    {errors}
    ",msgAjaxError:"{operation} 鍙戠敓閿欒. 璇烽噸璇!",msgAjaxProgressError:"{operation} 澶辫触",msgDuplicateFile:'鏂囦欢 "{name}",澶у皬 "{size} KB" 宸茬粡琚変腑.蹇界暐鐩稿悓鐨勬枃浠.',msgResumableUploadRetriesExceeded:"鏂囦欢 {file} 涓婁紶澶辫触瓒呰繃 {max} 娆¢噸璇 ! 閿欒璇︽儏:
    {error}
    ",msgPendingTime:"{time} 鍓╀綑",msgCalculatingTime:"璁$畻鍓╀綑鏃堕棿",ajaxOperations:{deleteThumb:"鍒犻櫎鏂囦欢",uploadThumb:"涓婁紶鏂囦欢",uploadBatch:"鎵归噺涓婁紶",uploadExtra:"琛ㄥ崟鏁版嵁涓婁紶"},dropZoneTitle:"鎷栨嫿鏂囦欢鍒拌繖閲 …
    鏀寔澶氭枃浠跺悓鏃朵笂浼",dropZoneClickTitle:"
    (鎴栫偣鍑粄files}鎸夐挳閫夋嫨鏂囦欢)",fileActionSettings:{removeTitle:"鍒犻櫎鏂囦欢",uploadTitle:"涓婁紶鏂囦欢",downloadTitle:"涓嬭浇鏂囦欢",uploadRetryTitle:"閲嶈瘯",zoomTitle:"鏌ョ湅璇︽儏",dragTitle:"绉诲姩 / 閲嶇疆",indicatorNewTitle:"娌℃湁涓婁紶",indicatorSuccessTitle:"涓婁紶",indicatorErrorTitle:"涓婁紶閿欒",indicatorPausedTitle:"涓婁紶宸叉殏鍋",indicatorLoadingTitle:"涓婁紶 …"},previewZoomButtonTitles:{prev:"棰勮涓婁竴涓枃浠",next:"棰勮涓嬩竴涓枃浠",toggleheader:"缂╂斁",fullscreen:"鍏ㄥ睆",borderless:"鏃犺竟鐣屾ā寮",close:"鍏抽棴褰撳墠棰勮"}},L.fn.fileinput.Constructor=c,L(document).ready(function(){var e=L("input.file[type=file]");e.length&&e.fileinput()})}); \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/loading-sm.gif b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/loading-sm.gif new file mode 100644 index 000000000..44e3b7a0f Binary files /dev/null and b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/loading-sm.gif differ diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/loading.gif b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/loading.gif new file mode 100644 index 000000000..0ea146c02 Binary files /dev/null and b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/loading.gif differ diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.css b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.css new file mode 100644 index 000000000..34edabf85 --- /dev/null +++ b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.css @@ -0,0 +1,459 @@ +/*! + * Bootstrap-select v1.13.18 (https://developer.snapappointments.com/bootstrap-select) + * + * Copyright 2012-2020 SnapAppointments, LLC + * Licensed under MIT (https://github.com/snapappointments/bootstrap-select/blob/master/LICENSE) + */ + +@-webkit-keyframes bs-notify-fadeOut { + 0% { + opacity: 0.9; + } + 100% { + opacity: 0; + } +} +@-o-keyframes bs-notify-fadeOut { + 0% { + opacity: 0.9; + } + 100% { + opacity: 0; + } +} +@keyframes bs-notify-fadeOut { + 0% { + opacity: 0.9; + } + 100% { + opacity: 0; + } +} +select.bs-select-hidden, +.bootstrap-select > select.bs-select-hidden, +select.selectpicker { + display: none !important; +} +.bootstrap-select { + width: 220px \0; + /*IE9 and below*/ + vertical-align: middle; +} +.bootstrap-select > .dropdown-toggle { + position: relative; + width: 100%; + text-align: right; + white-space: nowrap; + display: -webkit-inline-box; + display: -webkit-inline-flex; + display: -ms-inline-flexbox; + display: inline-flex; + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + -ms-flex-pack: justify; + justify-content: space-between; +} +.bootstrap-select > .dropdown-toggle:after { + margin-top: -1px; +} +.bootstrap-select > .dropdown-toggle.bs-placeholder, +.bootstrap-select > .dropdown-toggle.bs-placeholder:hover, +.bootstrap-select > .dropdown-toggle.bs-placeholder:focus, +.bootstrap-select > .dropdown-toggle.bs-placeholder:active { + color: #999; +} +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary:hover, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary:hover, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success:hover, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger:hover, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info:hover, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark:hover, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary:focus, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary:focus, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success:focus, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger:focus, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info:focus, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark:focus, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary:active, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary:active, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success:active, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger:active, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info:active, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark:active { + color: rgba(255, 255, 255, 0.5); +} +.bootstrap-select > select { + position: absolute !important; + bottom: 0; + left: 50%; + display: block !important; + width: 0.5px !important; + height: 100% !important; + padding: 0 !important; + opacity: 0 !important; + border: none; + z-index: 0 !important; +} +.bootstrap-select > select.mobile-device { + top: 0; + left: 0; + display: block !important; + width: 100% !important; + z-index: 2 !important; +} +.has-error .bootstrap-select .dropdown-toggle, +.error .bootstrap-select .dropdown-toggle, +.bootstrap-select.is-invalid .dropdown-toggle, +.was-validated .bootstrap-select select:invalid + .dropdown-toggle { + border-color: #b94a48; +} +.bootstrap-select.is-valid .dropdown-toggle, +.was-validated .bootstrap-select select:valid + .dropdown-toggle { + border-color: #28a745; +} +.bootstrap-select.fit-width { + width: auto !important; +} +.bootstrap-select:not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn) { + width: 220px; +} +.bootstrap-select > select.mobile-device:focus + .dropdown-toggle, +.bootstrap-select .dropdown-toggle:focus { + outline: thin dotted #333333 !important; + outline: 5px auto -webkit-focus-ring-color !important; + outline-offset: -2px; +} +.bootstrap-select.form-control { + margin-bottom: 0; + padding: 0; + border: none; + height: auto; +} +:not(.input-group) > .bootstrap-select.form-control:not([class*="col-"]) { + width: 100%; +} +.bootstrap-select.form-control.input-group-btn { + float: none; + z-index: auto; +} +.form-inline .bootstrap-select, +.form-inline .bootstrap-select.form-control:not([class*="col-"]) { + width: auto; +} +.bootstrap-select:not(.input-group-btn), +.bootstrap-select[class*="col-"] { + float: none; + display: inline-block; + margin-left: 0; +} +.bootstrap-select.dropdown-menu-right, +.bootstrap-select[class*="col-"].dropdown-menu-right, +.row .bootstrap-select[class*="col-"].dropdown-menu-right { + float: right; +} +.form-inline .bootstrap-select, +.form-horizontal .bootstrap-select, +.form-group .bootstrap-select { + margin-bottom: 0; +} +.form-group-lg .bootstrap-select.form-control, +.form-group-sm .bootstrap-select.form-control { + padding: 0; +} +.form-group-lg .bootstrap-select.form-control .dropdown-toggle, +.form-group-sm .bootstrap-select.form-control .dropdown-toggle { + height: 100%; + font-size: inherit; + line-height: inherit; + border-radius: inherit; +} +.bootstrap-select.form-control-sm .dropdown-toggle, +.bootstrap-select.form-control-lg .dropdown-toggle { + font-size: inherit; + line-height: inherit; + border-radius: inherit; +} +.bootstrap-select.form-control-sm .dropdown-toggle { + padding: 0.25rem 0.5rem; +} +.bootstrap-select.form-control-lg .dropdown-toggle { + padding: 0.5rem 1rem; +} +.form-inline .bootstrap-select .form-control { + width: 100%; +} +.bootstrap-select.disabled, +.bootstrap-select > .disabled { + cursor: not-allowed; +} +.bootstrap-select.disabled:focus, +.bootstrap-select > .disabled:focus { + outline: none !important; +} +.bootstrap-select.bs-container { + position: absolute; + top: 0; + left: 0; + height: 0 !important; + padding: 0 !important; +} +.bootstrap-select.bs-container .dropdown-menu { + z-index: 1060; +} +.bootstrap-select .dropdown-toggle .filter-option { + position: static; + top: 0; + left: 0; + float: left; + height: 100%; + width: 100%; + text-align: left; + overflow: hidden; + -webkit-box-flex: 0; + -webkit-flex: 0 1 auto; + -ms-flex: 0 1 auto; + flex: 0 1 auto; +} +.bs3.bootstrap-select .dropdown-toggle .filter-option { + padding-right: inherit; +} +.input-group .bs3-has-addon.bootstrap-select .dropdown-toggle .filter-option { + position: absolute; + padding-top: inherit; + padding-bottom: inherit; + padding-left: inherit; + float: none; +} +.input-group .bs3-has-addon.bootstrap-select .dropdown-toggle .filter-option .filter-option-inner { + padding-right: inherit; +} +.bootstrap-select .dropdown-toggle .filter-option-inner-inner { + overflow: hidden; +} +.bootstrap-select .dropdown-toggle .filter-expand { + width: 0 !important; + float: left; + opacity: 0 !important; + overflow: hidden; +} +.bootstrap-select .dropdown-toggle .caret { + position: absolute; + top: 50%; + right: 12px; + margin-top: -2px; + vertical-align: middle; +} +.input-group .bootstrap-select.form-control .dropdown-toggle { + border-radius: inherit; +} +.bootstrap-select[class*="col-"] .dropdown-toggle { + width: 100%; +} +.bootstrap-select .dropdown-menu { + min-width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.bootstrap-select .dropdown-menu > .inner:focus { + outline: none !important; +} +.bootstrap-select .dropdown-menu.inner { + position: static; + float: none; + border: 0; + padding: 0; + margin: 0; + border-radius: 0; + -webkit-box-shadow: none; + box-shadow: none; +} +.bootstrap-select .dropdown-menu li { + position: relative; +} +.bootstrap-select .dropdown-menu li.active small { + color: rgba(255, 255, 255, 0.5) !important; +} +.bootstrap-select .dropdown-menu li.disabled a { + cursor: not-allowed; +} +.bootstrap-select .dropdown-menu li a { + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.bootstrap-select .dropdown-menu li a.opt { + position: relative; + padding-left: 2.25em; +} +.bootstrap-select .dropdown-menu li a span.check-mark { + display: none; +} +.bootstrap-select .dropdown-menu li a span.text { + display: inline-block; +} +.bootstrap-select .dropdown-menu li small { + padding-left: 0.5em; +} +.bootstrap-select .dropdown-menu .notify { + position: absolute; + bottom: 5px; + width: 96%; + margin: 0 2%; + min-height: 26px; + padding: 3px 5px; + background: #f5f5f5; + border: 1px solid #e3e3e3; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + pointer-events: none; + opacity: 0.9; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.bootstrap-select .dropdown-menu .notify.fadeOut { + -webkit-animation: 300ms linear 750ms forwards bs-notify-fadeOut; + -o-animation: 300ms linear 750ms forwards bs-notify-fadeOut; + animation: 300ms linear 750ms forwards bs-notify-fadeOut; +} +.bootstrap-select .no-results { + padding: 3px; + background: #f5f5f5; + margin: 0 5px; + white-space: nowrap; +} +.bootstrap-select.fit-width .dropdown-toggle .filter-option { + position: static; + display: inline; + padding: 0; +} +.bootstrap-select.fit-width .dropdown-toggle .filter-option-inner, +.bootstrap-select.fit-width .dropdown-toggle .filter-option-inner-inner { + display: inline; +} +.bootstrap-select.fit-width .dropdown-toggle .bs-caret:before { + content: '\00a0'; +} +.bootstrap-select.fit-width .dropdown-toggle .caret { + position: static; + top: auto; + margin-top: -1px; +} +.bootstrap-select.show-tick .dropdown-menu .selected span.check-mark { + position: absolute; + display: inline-block; + right: 15px; + top: 5px; +} +.bootstrap-select.show-tick .dropdown-menu li a span.text { + margin-right: 34px; +} +.bootstrap-select .bs-ok-default:after { + content: ''; + display: block; + width: 0.5em; + height: 1em; + border-style: solid; + border-width: 0 0.26em 0.26em 0; + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; + -webkit-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); +} +.bootstrap-select.show-menu-arrow.open > .dropdown-toggle, +.bootstrap-select.show-menu-arrow.show > .dropdown-toggle { + z-index: 1061; +} +.bootstrap-select.show-menu-arrow .dropdown-toggle .filter-option:before { + content: ''; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid rgba(204, 204, 204, 0.2); + position: absolute; + bottom: -4px; + left: 9px; + display: none; +} +.bootstrap-select.show-menu-arrow .dropdown-toggle .filter-option:after { + content: ''; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid white; + position: absolute; + bottom: -4px; + left: 10px; + display: none; +} +.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle .filter-option:before { + bottom: auto; + top: -4px; + border-top: 7px solid rgba(204, 204, 204, 0.2); + border-bottom: 0; +} +.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle .filter-option:after { + bottom: auto; + top: -4px; + border-top: 6px solid white; + border-bottom: 0; +} +.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle .filter-option:before { + right: 12px; + left: auto; +} +.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle .filter-option:after { + right: 13px; + left: auto; +} +.bootstrap-select.show-menu-arrow.open > .dropdown-toggle .filter-option:before, +.bootstrap-select.show-menu-arrow.show > .dropdown-toggle .filter-option:before, +.bootstrap-select.show-menu-arrow.open > .dropdown-toggle .filter-option:after, +.bootstrap-select.show-menu-arrow.show > .dropdown-toggle .filter-option:after { + display: block; +} +.bs-searchbox, +.bs-actionsbox, +.bs-donebutton { + padding: 4px 8px; +} +.bs-actionsbox { + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.bs-actionsbox .btn-group button { + width: 50%; +} +.bs-donebutton { + float: left; + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.bs-donebutton .btn-group button { + width: 100%; +} +.bs-searchbox + .bs-actionsbox { + padding: 0 8px 4px; +} +.bs-searchbox .form-control { + margin-bottom: 0; + width: 100%; + float: none; +} diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.js b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.js new file mode 100644 index 000000000..d25d751dd --- /dev/null +++ b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.js @@ -0,0 +1,3247 @@ +/*! + * Bootstrap-select v1.13.18 (https://developer.snapappointments.com/bootstrap-select) + * + * Copyright 2012-2020 SnapAppointments, LLC + * Licensed under MIT (https://github.com/snapappointments/bootstrap-select/blob/master/LICENSE) + */ + +(function (root, factory) { + if (root === undefined && window !== undefined) root = window; + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module unless amdModuleId is set + define(["jquery"], function (a0) { + return (factory(a0)); + }); + } else if (typeof module === 'object' && module.exports) { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(require("jquery")); + } else { + factory(root["jQuery"]); + } +}(this, function (jQuery) { + +(function ($) { + 'use strict'; + + var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']; + + var uriAttrs = [ + 'background', + 'cite', + 'href', + 'itemtype', + 'longdesc', + 'poster', + 'src', + 'xlink:href' + ]; + + var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i; + + var DefaultWhitelist = { + // Global attributes allowed on any supplied element below. + '*': ['class', 'dir', 'id', 'lang', 'role', 'tabindex', 'style', ARIA_ATTRIBUTE_PATTERN], + a: ['target', 'href', 'title', 'rel'], + area: [], + b: [], + br: [], + col: [], + code: [], + div: [], + em: [], + hr: [], + h1: [], + h2: [], + h3: [], + h4: [], + h5: [], + h6: [], + i: [], + img: ['src', 'alt', 'title', 'width', 'height'], + li: [], + ol: [], + p: [], + pre: [], + s: [], + small: [], + span: [], + sub: [], + sup: [], + strong: [], + u: [], + ul: [] + } + + /** + * A pattern that recognizes a commonly useful subset of URLs that are safe. + * + * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts + */ + var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi; + + /** + * A pattern that matches safe data URLs. Only matches image, video and audio types. + * + * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts + */ + var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i; + + function allowedAttribute (attr, allowedAttributeList) { + var attrName = attr.nodeName.toLowerCase() + + if ($.inArray(attrName, allowedAttributeList) !== -1) { + if ($.inArray(attrName, uriAttrs) !== -1) { + return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN)) + } + + return true + } + + var regExp = $(allowedAttributeList).filter(function (index, value) { + return value instanceof RegExp + }) + + // Check if a regular expression validates the attribute. + for (var i = 0, l = regExp.length; i < l; i++) { + if (attrName.match(regExp[i])) { + return true + } + } + + return false + } + + function sanitizeHtml (unsafeElements, whiteList, sanitizeFn) { + if (sanitizeFn && typeof sanitizeFn === 'function') { + return sanitizeFn(unsafeElements); + } + + var whitelistKeys = Object.keys(whiteList); + + for (var i = 0, len = unsafeElements.length; i < len; i++) { + var elements = unsafeElements[i].querySelectorAll('*'); + + for (var j = 0, len2 = elements.length; j < len2; j++) { + var el = elements[j]; + var elName = el.nodeName.toLowerCase(); + + if (whitelistKeys.indexOf(elName) === -1) { + el.parentNode.removeChild(el); + + continue; + } + + var attributeList = [].slice.call(el.attributes); + var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []); + + for (var k = 0, len3 = attributeList.length; k < len3; k++) { + var attr = attributeList[k]; + + if (!allowedAttribute(attr, whitelistedAttributes)) { + el.removeAttribute(attr.nodeName); + } + } + } + } + } + + // Polyfill for browsers with no classList support + // Remove in v2 + if (!('classList' in document.createElement('_'))) { + (function (view) { + if (!('Element' in view)) return; + + var classListProp = 'classList', + protoProp = 'prototype', + elemCtrProto = view.Element[protoProp], + objCtr = Object, + classListGetter = function () { + var $elem = $(this); + + return { + add: function (classes) { + classes = Array.prototype.slice.call(arguments).join(' '); + return $elem.addClass(classes); + }, + remove: function (classes) { + classes = Array.prototype.slice.call(arguments).join(' '); + return $elem.removeClass(classes); + }, + toggle: function (classes, force) { + return $elem.toggleClass(classes, force); + }, + contains: function (classes) { + return $elem.hasClass(classes); + } + } + }; + + if (objCtr.defineProperty) { + var classListPropDesc = { + get: classListGetter, + enumerable: true, + configurable: true + }; + try { + objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); + } catch (ex) { // IE 8 doesn't support enumerable:true + // adding undefined to fight this issue https://github.com/eligrey/classList.js/issues/36 + // modernie IE8-MSW7 machine has IE8 8.0.6001.18702 and is affected + if (ex.number === undefined || ex.number === -0x7FF5EC54) { + classListPropDesc.enumerable = false; + objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); + } + } + } else if (objCtr[protoProp].__defineGetter__) { + elemCtrProto.__defineGetter__(classListProp, classListGetter); + } + }(window)); + } + + var testElement = document.createElement('_'); + + testElement.classList.add('c1', 'c2'); + + if (!testElement.classList.contains('c2')) { + var _add = DOMTokenList.prototype.add, + _remove = DOMTokenList.prototype.remove; + + DOMTokenList.prototype.add = function () { + Array.prototype.forEach.call(arguments, _add.bind(this)); + } + + DOMTokenList.prototype.remove = function () { + Array.prototype.forEach.call(arguments, _remove.bind(this)); + } + } + + testElement.classList.toggle('c3', false); + + // Polyfill for IE 10 and Firefox <24, where classList.toggle does not + // support the second argument. + if (testElement.classList.contains('c3')) { + var _toggle = DOMTokenList.prototype.toggle; + + DOMTokenList.prototype.toggle = function (token, force) { + if (1 in arguments && !this.contains(token) === !force) { + return force; + } else { + return _toggle.call(this, token); + } + }; + } + + testElement = null; + + // shallow array comparison + function isEqual (array1, array2) { + return array1.length === array2.length && array1.every(function (element, index) { + return element === array2[index]; + }); + }; + + // + if (!String.prototype.startsWith) { + (function () { + 'use strict'; // needed to support `apply`/`call` with `undefined`/`null` + var defineProperty = (function () { + // IE 8 only supports `Object.defineProperty` on DOM elements + try { + var object = {}; + var $defineProperty = Object.defineProperty; + var result = $defineProperty(object, object, object) && $defineProperty; + } catch (error) { + } + return result; + }()); + var toString = {}.toString; + var startsWith = function (search) { + if (this == null) { + throw new TypeError(); + } + var string = String(this); + if (search && toString.call(search) == '[object RegExp]') { + throw new TypeError(); + } + var stringLength = string.length; + var searchString = String(search); + var searchLength = searchString.length; + var position = arguments.length > 1 ? arguments[1] : undefined; + // `ToInteger` + var pos = position ? Number(position) : 0; + if (pos != pos) { // better `isNaN` + pos = 0; + } + var start = Math.min(Math.max(pos, 0), stringLength); + // Avoid the `indexOf` call if no match is possible + if (searchLength + start > stringLength) { + return false; + } + var index = -1; + while (++index < searchLength) { + if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) { + return false; + } + } + return true; + }; + if (defineProperty) { + defineProperty(String.prototype, 'startsWith', { + 'value': startsWith, + 'configurable': true, + 'writable': true + }); + } else { + String.prototype.startsWith = startsWith; + } + }()); + } + + if (!Object.keys) { + Object.keys = function ( + o, // object + k, // key + r // result array + ) { + // initialize object and result + r = []; + // iterate over object keys + for (k in o) { + // fill result array with non-prototypical keys + r.hasOwnProperty.call(o, k) && r.push(k); + } + // return result + return r; + }; + } + + if (HTMLSelectElement && !HTMLSelectElement.prototype.hasOwnProperty('selectedOptions')) { + Object.defineProperty(HTMLSelectElement.prototype, 'selectedOptions', { + get: function () { + return this.querySelectorAll(':checked'); + } + }); + } + + function getSelectedOptions (select, ignoreDisabled) { + var selectedOptions = select.selectedOptions, + options = [], + opt; + + if (ignoreDisabled) { + for (var i = 0, len = selectedOptions.length; i < len; i++) { + opt = selectedOptions[i]; + + if (!(opt.disabled || opt.parentNode.tagName === 'OPTGROUP' && opt.parentNode.disabled)) { + options.push(opt); + } + } + + return options; + } + + return selectedOptions; + } + + // much faster than $.val() + function getSelectValues (select, selectedOptions) { + var value = [], + options = selectedOptions || select.selectedOptions, + opt; + + for (var i = 0, len = options.length; i < len; i++) { + opt = options[i]; + + if (!(opt.disabled || opt.parentNode.tagName === 'OPTGROUP' && opt.parentNode.disabled)) { + value.push(opt.value); + } + } + + if (!select.multiple) { + return !value.length ? null : value[0]; + } + + return value; + } + + // set data-selected on select element if the value has been programmatically selected + // prior to initialization of bootstrap-select + // * consider removing or replacing an alternative method * + var valHooks = { + useDefault: false, + _set: $.valHooks.select.set + }; + + $.valHooks.select.set = function (elem, value) { + if (value && !valHooks.useDefault) $(elem).data('selected', true); + + return valHooks._set.apply(this, arguments); + }; + + var changedArguments = null; + + var EventIsSupported = (function () { + try { + new Event('change'); + return true; + } catch (e) { + return false; + } + })(); + + $.fn.triggerNative = function (eventName) { + var el = this[0], + event; + + if (el.dispatchEvent) { // for modern browsers & IE9+ + if (EventIsSupported) { + // For modern browsers + event = new Event(eventName, { + bubbles: true + }); + } else { + // For IE since it doesn't support Event constructor + event = document.createEvent('Event'); + event.initEvent(eventName, true, false); + } + + el.dispatchEvent(event); + } else if (el.fireEvent) { // for IE8 + event = document.createEventObject(); + event.eventType = eventName; + el.fireEvent('on' + eventName, event); + } else { + // fall back to jQuery.trigger + this.trigger(eventName); + } + }; + // + + function stringSearch (li, searchString, method, normalize) { + var stringTypes = [ + 'display', + 'subtext', + 'tokens' + ], + searchSuccess = false; + + for (var i = 0; i < stringTypes.length; i++) { + var stringType = stringTypes[i], + string = li[stringType]; + + if (string) { + string = string.toString(); + + // Strip HTML tags. This isn't perfect, but it's much faster than any other method + if (stringType === 'display') { + string = string.replace(/<[^>]+>/g, ''); + } + + if (normalize) string = normalizeToBase(string); + string = string.toUpperCase(); + + if (method === 'contains') { + searchSuccess = string.indexOf(searchString) >= 0; + } else { + searchSuccess = string.startsWith(searchString); + } + + if (searchSuccess) break; + } + } + + return searchSuccess; + } + + function toInteger (value) { + return parseInt(value, 10) || 0; + } + + // Borrowed from Lodash (_.deburr) + /** Used to map Latin Unicode letters to basic Latin letters. */ + var deburredLetters = { + // Latin-1 Supplement block. + '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', + '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', + '\xc7': 'C', '\xe7': 'c', + '\xd0': 'D', '\xf0': 'd', + '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', + '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', + '\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', + '\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', + '\xd1': 'N', '\xf1': 'n', + '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', + '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', + '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', + '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', + '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', + '\xc6': 'Ae', '\xe6': 'ae', + '\xde': 'Th', '\xfe': 'th', + '\xdf': 'ss', + // Latin Extended-A block. + '\u0100': 'A', '\u0102': 'A', '\u0104': 'A', + '\u0101': 'a', '\u0103': 'a', '\u0105': 'a', + '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C', + '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c', + '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd', + '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E', + '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e', + '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G', + '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g', + '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h', + '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I', + '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i', + '\u0134': 'J', '\u0135': 'j', + '\u0136': 'K', '\u0137': 'k', '\u0138': 'k', + '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L', + '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l', + '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N', + '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n', + '\u014c': 'O', '\u014e': 'O', '\u0150': 'O', + '\u014d': 'o', '\u014f': 'o', '\u0151': 'o', + '\u0154': 'R', '\u0156': 'R', '\u0158': 'R', + '\u0155': 'r', '\u0157': 'r', '\u0159': 'r', + '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S', + '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's', + '\u0162': 'T', '\u0164': 'T', '\u0166': 'T', + '\u0163': 't', '\u0165': 't', '\u0167': 't', + '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U', + '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u', + '\u0174': 'W', '\u0175': 'w', + '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y', + '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z', + '\u017a': 'z', '\u017c': 'z', '\u017e': 'z', + '\u0132': 'IJ', '\u0133': 'ij', + '\u0152': 'Oe', '\u0153': 'oe', + '\u0149': "'n", '\u017f': 's' + }; + + /** Used to match Latin Unicode letters (excluding mathematical operators). */ + var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g; + + /** Used to compose unicode character classes. */ + var rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboMarksExtendedRange = '\\u1ab0-\\u1aff', + rsComboMarksSupplementRange = '\\u1dc0-\\u1dff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange + rsComboMarksExtendedRange + rsComboMarksSupplementRange; + + /** Used to compose unicode capture groups. */ + var rsCombo = '[' + rsComboRange + ']'; + + /** + * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and + * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). + */ + var reComboMark = RegExp(rsCombo, 'g'); + + function deburrLetter (key) { + return deburredLetters[key]; + }; + + function normalizeToBase (string) { + string = string.toString(); + return string && string.replace(reLatin, deburrLetter).replace(reComboMark, ''); + } + + // List of HTML entities for escaping. + var escapeMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + + // Functions for escaping and unescaping strings to/from HTML interpolation. + var createEscaper = function (map) { + var escaper = function (match) { + return map[match]; + }; + // Regexes for identifying a key that needs to be escaped. + var source = '(?:' + Object.keys(map).join('|') + ')'; + var testRegexp = RegExp(source); + var replaceRegexp = RegExp(source, 'g'); + return function (string) { + string = string == null ? '' : '' + string; + return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; + }; + }; + + var htmlEscape = createEscaper(escapeMap); + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var keyCodeMap = { + 32: ' ', + 48: '0', + 49: '1', + 50: '2', + 51: '3', + 52: '4', + 53: '5', + 54: '6', + 55: '7', + 56: '8', + 57: '9', + 59: ';', + 65: 'A', + 66: 'B', + 67: 'C', + 68: 'D', + 69: 'E', + 70: 'F', + 71: 'G', + 72: 'H', + 73: 'I', + 74: 'J', + 75: 'K', + 76: 'L', + 77: 'M', + 78: 'N', + 79: 'O', + 80: 'P', + 81: 'Q', + 82: 'R', + 83: 'S', + 84: 'T', + 85: 'U', + 86: 'V', + 87: 'W', + 88: 'X', + 89: 'Y', + 90: 'Z', + 96: '0', + 97: '1', + 98: '2', + 99: '3', + 100: '4', + 101: '5', + 102: '6', + 103: '7', + 104: '8', + 105: '9' + }; + + var keyCodes = { + ESCAPE: 27, // KeyboardEvent.which value for Escape (Esc) key + ENTER: 13, // KeyboardEvent.which value for Enter key + SPACE: 32, // KeyboardEvent.which value for space key + TAB: 9, // KeyboardEvent.which value for tab key + ARROW_UP: 38, // KeyboardEvent.which value for up arrow key + ARROW_DOWN: 40 // KeyboardEvent.which value for down arrow key + } + + var version = { + success: false, + major: '3' + }; + + try { + version.full = ($.fn.dropdown.Constructor.VERSION || '').split(' ')[0].split('.'); + version.major = version.full[0]; + version.success = true; + } catch (err) { + // do nothing + } + + var selectId = 0; + + var EVENT_KEY = '.bs.select'; + + var classNames = { + DISABLED: 'disabled', + DIVIDER: 'divider', + SHOW: 'open', + DROPUP: 'dropup', + MENU: 'dropdown-menu', + MENURIGHT: 'dropdown-menu-right', + MENULEFT: 'dropdown-menu-left', + // to-do: replace with more advanced template/customization options + BUTTONCLASS: 'btn-default', + POPOVERHEADER: 'popover-title', + ICONBASE: 'glyphicon', + TICKICON: 'glyphicon-ok' + } + + var Selector = { + MENU: '.' + classNames.MENU + } + + var elementTemplates = { + div: document.createElement('div'), + span: document.createElement('span'), + i: document.createElement('i'), + subtext: document.createElement('small'), + a: document.createElement('a'), + li: document.createElement('li'), + whitespace: document.createTextNode('\u00A0'), + fragment: document.createDocumentFragment() + } + + elementTemplates.noResults = elementTemplates.li.cloneNode(false); + elementTemplates.noResults.className = 'no-results'; + + elementTemplates.a.setAttribute('role', 'option'); + elementTemplates.a.className = 'dropdown-item'; + + elementTemplates.subtext.className = 'text-muted'; + + elementTemplates.text = elementTemplates.span.cloneNode(false); + elementTemplates.text.className = 'text'; + + elementTemplates.checkMark = elementTemplates.span.cloneNode(false); + + var REGEXP_ARROW = new RegExp(keyCodes.ARROW_UP + '|' + keyCodes.ARROW_DOWN); + var REGEXP_TAB_OR_ESCAPE = new RegExp('^' + keyCodes.TAB + '$|' + keyCodes.ESCAPE); + + var generateOption = { + li: function (content, classes, optgroup) { + var li = elementTemplates.li.cloneNode(false); + + if (content) { + if (content.nodeType === 1 || content.nodeType === 11) { + li.appendChild(content); + } else { + li.innerHTML = content; + } + } + + if (typeof classes !== 'undefined' && classes !== '') li.className = classes; + if (typeof optgroup !== 'undefined' && optgroup !== null) li.classList.add('optgroup-' + optgroup); + + return li; + }, + + a: function (text, classes, inline) { + var a = elementTemplates.a.cloneNode(true); + + if (text) { + if (text.nodeType === 11) { + a.appendChild(text); + } else { + a.insertAdjacentHTML('beforeend', text); + } + } + + if (typeof classes !== 'undefined' && classes !== '') a.classList.add.apply(a.classList, classes.split(/\s+/)); + if (inline) a.setAttribute('style', inline); + + return a; + }, + + text: function (options, useFragment) { + var textElement = elementTemplates.text.cloneNode(false), + subtextElement, + iconElement; + + if (options.content) { + textElement.innerHTML = options.content; + } else { + textElement.textContent = options.text; + + if (options.icon) { + var whitespace = elementTemplates.whitespace.cloneNode(false); + + // need to use for icons in the button to prevent a breaking change + // note: switch to span in next major release + iconElement = (useFragment === true ? elementTemplates.i : elementTemplates.span).cloneNode(false); + iconElement.className = this.options.iconBase + ' ' + options.icon; + + elementTemplates.fragment.appendChild(iconElement); + elementTemplates.fragment.appendChild(whitespace); + } + + if (options.subtext) { + subtextElement = elementTemplates.subtext.cloneNode(false); + subtextElement.textContent = options.subtext; + textElement.appendChild(subtextElement); + } + } + + if (useFragment === true) { + while (textElement.childNodes.length > 0) { + elementTemplates.fragment.appendChild(textElement.childNodes[0]); + } + } else { + elementTemplates.fragment.appendChild(textElement); + } + + return elementTemplates.fragment; + }, + + label: function (options) { + var textElement = elementTemplates.text.cloneNode(false), + subtextElement, + iconElement; + + textElement.innerHTML = options.display; + + if (options.icon) { + var whitespace = elementTemplates.whitespace.cloneNode(false); + + iconElement = elementTemplates.span.cloneNode(false); + iconElement.className = this.options.iconBase + ' ' + options.icon; + + elementTemplates.fragment.appendChild(iconElement); + elementTemplates.fragment.appendChild(whitespace); + } + + if (options.subtext) { + subtextElement = elementTemplates.subtext.cloneNode(false); + subtextElement.textContent = options.subtext; + textElement.appendChild(subtextElement); + } + + elementTemplates.fragment.appendChild(textElement); + + return elementTemplates.fragment; + } + } + + function showNoResults (searchMatch, searchValue) { + if (!searchMatch.length) { + elementTemplates.noResults.innerHTML = this.options.noneResultsText.replace('{0}', '"' + htmlEscape(searchValue) + '"'); + this.$menuInner[0].firstChild.appendChild(elementTemplates.noResults); + } + } + + var Selectpicker = function (element, options) { + var that = this; + + // bootstrap-select has been initialized - revert valHooks.select.set back to its original function + if (!valHooks.useDefault) { + $.valHooks.select.set = valHooks._set; + valHooks.useDefault = true; + } + + this.$element = $(element); + this.$newElement = null; + this.$button = null; + this.$menu = null; + this.options = options; + this.selectpicker = { + main: {}, + search: {}, + current: {}, // current changes if a search is in progress + view: {}, + isSearching: false, + keydown: { + keyHistory: '', + resetKeyHistory: { + start: function () { + return setTimeout(function () { + that.selectpicker.keydown.keyHistory = ''; + }, 800); + } + } + } + }; + + this.sizeInfo = {}; + + // If we have no title yet, try to pull it from the html title attribute (jQuery doesnt' pick it up as it's not a + // data-attribute) + if (this.options.title === null) { + this.options.title = this.$element.attr('title'); + } + + // Format window padding + var winPad = this.options.windowPadding; + if (typeof winPad === 'number') { + this.options.windowPadding = [winPad, winPad, winPad, winPad]; + } + + // Expose public methods + this.val = Selectpicker.prototype.val; + this.render = Selectpicker.prototype.render; + this.refresh = Selectpicker.prototype.refresh; + this.setStyle = Selectpicker.prototype.setStyle; + this.selectAll = Selectpicker.prototype.selectAll; + this.deselectAll = Selectpicker.prototype.deselectAll; + this.destroy = Selectpicker.prototype.destroy; + this.remove = Selectpicker.prototype.remove; + this.show = Selectpicker.prototype.show; + this.hide = Selectpicker.prototype.hide; + + this.init(); + }; + + Selectpicker.VERSION = '1.13.18'; + + // part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both. + Selectpicker.DEFAULTS = { + noneSelectedText: 'Nothing selected', + noneResultsText: 'No results matched {0}', + countSelectedText: function (numSelected, numTotal) { + return (numSelected == 1) ? '{0} item selected' : '{0} items selected'; + }, + maxOptionsText: function (numAll, numGroup) { + return [ + (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)', + (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)' + ]; + }, + selectAllText: 'Select All', + deselectAllText: 'Deselect All', + doneButton: false, + doneButtonText: 'Close', + multipleSeparator: ', ', + styleBase: 'btn', + style: classNames.BUTTONCLASS, + size: 'auto', + title: null, + selectedTextFormat: 'values', + width: false, + container: false, + hideDisabled: false, + showSubtext: false, + showIcon: true, + showContent: true, + dropupAuto: true, + header: false, + liveSearch: false, + liveSearchPlaceholder: null, + liveSearchNormalize: false, + liveSearchStyle: 'contains', + actionsBox: false, + iconBase: classNames.ICONBASE, + tickIcon: classNames.TICKICON, + showTick: false, + template: { + caret: '' + }, + maxOptions: false, + mobile: false, + selectOnTab: false, + dropdownAlignRight: false, + windowPadding: 0, + virtualScroll: 600, + display: false, + sanitize: true, + sanitizeFn: null, + whiteList: DefaultWhitelist + }; + + Selectpicker.prototype = { + + constructor: Selectpicker, + + init: function () { + var that = this, + id = this.$element.attr('id'), + element = this.$element[0], + form = element.form; + + selectId++; + this.selectId = 'bs-select-' + selectId; + + element.classList.add('bs-select-hidden'); + + this.multiple = this.$element.prop('multiple'); + this.autofocus = this.$element.prop('autofocus'); + + if (element.classList.contains('show-tick')) { + this.options.showTick = true; + } + + this.$newElement = this.createDropdown(); + this.buildData(); + this.$element + .after(this.$newElement) + .prependTo(this.$newElement); + + // ensure select is associated with form element if it got unlinked after moving it inside newElement + if (form && element.form === null) { + if (!form.id) form.id = 'form-' + this.selectId; + element.setAttribute('form', form.id); + } + + this.$button = this.$newElement.children('button'); + this.$menu = this.$newElement.children(Selector.MENU); + this.$menuInner = this.$menu.children('.inner'); + this.$searchbox = this.$menu.find('input'); + + element.classList.remove('bs-select-hidden'); + + if (this.options.dropdownAlignRight === true) this.$menu[0].classList.add(classNames.MENURIGHT); + + if (typeof id !== 'undefined') { + this.$button.attr('data-id', id); + } + + this.checkDisabled(); + this.clickListener(); + + if (this.options.liveSearch) { + this.liveSearchListener(); + this.focusedParent = this.$searchbox[0]; + } else { + this.focusedParent = this.$menuInner[0]; + } + + this.setStyle(); + this.render(); + this.setWidth(); + if (this.options.container) { + this.selectPosition(); + } else { + this.$element.on('hide' + EVENT_KEY, function () { + if (that.isVirtual()) { + // empty menu on close + var menuInner = that.$menuInner[0], + emptyMenu = menuInner.firstChild.cloneNode(false); + + // replace the existing UL with an empty one - this is faster than $.empty() or innerHTML = '' + menuInner.replaceChild(emptyMenu, menuInner.firstChild); + menuInner.scrollTop = 0; + } + }); + } + this.$menu.data('this', this); + this.$newElement.data('this', this); + if (this.options.mobile) this.mobile(); + + this.$newElement.on({ + 'hide.bs.dropdown': function (e) { + that.$element.trigger('hide' + EVENT_KEY, e); + }, + 'hidden.bs.dropdown': function (e) { + that.$element.trigger('hidden' + EVENT_KEY, e); + }, + 'show.bs.dropdown': function (e) { + that.$element.trigger('show' + EVENT_KEY, e); + }, + 'shown.bs.dropdown': function (e) { + that.$element.trigger('shown' + EVENT_KEY, e); + } + }); + + if (element.hasAttribute('required')) { + this.$element.on('invalid' + EVENT_KEY, function () { + that.$button[0].classList.add('bs-invalid'); + + that.$element + .on('shown' + EVENT_KEY + '.invalid', function () { + that.$element + .val(that.$element.val()) // set the value to hide the validation message in Chrome when menu is opened + .off('shown' + EVENT_KEY + '.invalid'); + }) + .on('rendered' + EVENT_KEY, function () { + // if select is no longer invalid, remove the bs-invalid class + if (this.validity.valid) that.$button[0].classList.remove('bs-invalid'); + that.$element.off('rendered' + EVENT_KEY); + }); + + that.$button.on('blur' + EVENT_KEY, function () { + that.$element.trigger('focus').trigger('blur'); + that.$button.off('blur' + EVENT_KEY); + }); + }); + } + + setTimeout(function () { + that.buildList(); + that.$element.trigger('loaded' + EVENT_KEY); + }); + }, + + createDropdown: function () { + // Options + // If we are multiple or showTick option is set, then add the show-tick class + var showTick = (this.multiple || this.options.showTick) ? ' show-tick' : '', + multiselectable = this.multiple ? ' aria-multiselectable="true"' : '', + inputGroup = '', + autofocus = this.autofocus ? ' autofocus' : ''; + + if (version.major < 4 && this.$element.parent().hasClass('input-group')) { + inputGroup = ' input-group-btn'; + } + + // Elements + var drop, + header = '', + searchbox = '', + actionsbox = '', + donebutton = ''; + + if (this.options.header) { + header = + '
    ' + + '' + + this.options.header + + '
    '; + } + + if (this.options.liveSearch) { + searchbox = + ''; + } + + if (this.multiple && this.options.actionsBox) { + actionsbox = + '
    ' + + '
    ' + + '' + + '' + + '
    ' + + '
    '; + } + + if (this.multiple && this.options.doneButton) { + donebutton = + '
    ' + + '
    ' + + '' + + '
    ' + + '
    '; + } + + drop = + ''; + + return $(drop); + }, + + setPositionData: function () { + this.selectpicker.view.canHighlight = []; + this.selectpicker.view.size = 0; + this.selectpicker.view.firstHighlightIndex = false; + + for (var i = 0; i < this.selectpicker.current.data.length; i++) { + var li = this.selectpicker.current.data[i], + canHighlight = true; + + if (li.type === 'divider') { + canHighlight = false; + li.height = this.sizeInfo.dividerHeight; + } else if (li.type === 'optgroup-label') { + canHighlight = false; + li.height = this.sizeInfo.dropdownHeaderHeight; + } else { + li.height = this.sizeInfo.liHeight; + } + + if (li.disabled) canHighlight = false; + + this.selectpicker.view.canHighlight.push(canHighlight); + + if (canHighlight) { + this.selectpicker.view.size++; + li.posinset = this.selectpicker.view.size; + if (this.selectpicker.view.firstHighlightIndex === false) this.selectpicker.view.firstHighlightIndex = i; + } + + li.position = (i === 0 ? 0 : this.selectpicker.current.data[i - 1].position) + li.height; + } + }, + + isVirtual: function () { + return (this.options.virtualScroll !== false) && (this.selectpicker.main.elements.length >= this.options.virtualScroll) || this.options.virtualScroll === true; + }, + + createView: function (isSearching, setSize, refresh) { + var that = this, + scrollTop = 0, + active = [], + selected, + prevActive; + + this.selectpicker.isSearching = isSearching; + this.selectpicker.current = isSearching ? this.selectpicker.search : this.selectpicker.main; + + this.setPositionData(); + + if (setSize) { + if (refresh) { + scrollTop = this.$menuInner[0].scrollTop; + } else if (!that.multiple) { + var element = that.$element[0], + selectedIndex = (element.options[element.selectedIndex] || {}).liIndex; + + if (typeof selectedIndex === 'number' && that.options.size !== false) { + var selectedData = that.selectpicker.main.data[selectedIndex], + position = selectedData && selectedData.position; + + if (position) { + scrollTop = position - ((that.sizeInfo.menuInnerHeight + that.sizeInfo.liHeight) / 2); + } + } + } + } + + scroll(scrollTop, true); + + this.$menuInner.off('scroll.createView').on('scroll.createView', function (e, updateValue) { + if (!that.noScroll) scroll(this.scrollTop, updateValue); + that.noScroll = false; + }); + + function scroll (scrollTop, init) { + var size = that.selectpicker.current.elements.length, + chunks = [], + chunkSize, + chunkCount, + firstChunk, + lastChunk, + currentChunk, + prevPositions, + positionIsDifferent, + previousElements, + menuIsDifferent = true, + isVirtual = that.isVirtual(); + + that.selectpicker.view.scrollTop = scrollTop; + + chunkSize = Math.ceil(that.sizeInfo.menuInnerHeight / that.sizeInfo.liHeight * 1.5); // number of options in a chunk + chunkCount = Math.round(size / chunkSize) || 1; // number of chunks + + for (var i = 0; i < chunkCount; i++) { + var endOfChunk = (i + 1) * chunkSize; + + if (i === chunkCount - 1) { + endOfChunk = size; + } + + chunks[i] = [ + (i) * chunkSize + (!i ? 0 : 1), + endOfChunk + ]; + + if (!size) break; + + if (currentChunk === undefined && scrollTop - 1 <= that.selectpicker.current.data[endOfChunk - 1].position - that.sizeInfo.menuInnerHeight) { + currentChunk = i; + } + } + + if (currentChunk === undefined) currentChunk = 0; + + prevPositions = [that.selectpicker.view.position0, that.selectpicker.view.position1]; + + // always display previous, current, and next chunks + firstChunk = Math.max(0, currentChunk - 1); + lastChunk = Math.min(chunkCount - 1, currentChunk + 1); + + that.selectpicker.view.position0 = isVirtual === false ? 0 : (Math.max(0, chunks[firstChunk][0]) || 0); + that.selectpicker.view.position1 = isVirtual === false ? size : (Math.min(size, chunks[lastChunk][1]) || 0); + + positionIsDifferent = prevPositions[0] !== that.selectpicker.view.position0 || prevPositions[1] !== that.selectpicker.view.position1; + + if (that.activeIndex !== undefined) { + prevActive = that.selectpicker.main.elements[that.prevActiveIndex]; + active = that.selectpicker.main.elements[that.activeIndex]; + selected = that.selectpicker.main.elements[that.selectedIndex]; + + if (init) { + if (that.activeIndex !== that.selectedIndex) { + that.defocusItem(active); + } + that.activeIndex = undefined; + } + + if (that.activeIndex && that.activeIndex !== that.selectedIndex) { + that.defocusItem(selected); + } + } + + if (that.prevActiveIndex !== undefined && that.prevActiveIndex !== that.activeIndex && that.prevActiveIndex !== that.selectedIndex) { + that.defocusItem(prevActive); + } + + if (init || positionIsDifferent) { + previousElements = that.selectpicker.view.visibleElements ? that.selectpicker.view.visibleElements.slice() : []; + + if (isVirtual === false) { + that.selectpicker.view.visibleElements = that.selectpicker.current.elements; + } else { + that.selectpicker.view.visibleElements = that.selectpicker.current.elements.slice(that.selectpicker.view.position0, that.selectpicker.view.position1); + } + + that.setOptionStatus(); + + // if searching, check to make sure the list has actually been updated before updating DOM + // this prevents unnecessary repaints + if (isSearching || (isVirtual === false && init)) menuIsDifferent = !isEqual(previousElements, that.selectpicker.view.visibleElements); + + // if virtual scroll is disabled and not searching, + // menu should never need to be updated more than once + if ((init || isVirtual === true) && menuIsDifferent) { + var menuInner = that.$menuInner[0], + menuFragment = document.createDocumentFragment(), + emptyMenu = menuInner.firstChild.cloneNode(false), + marginTop, + marginBottom, + elements = that.selectpicker.view.visibleElements, + toSanitize = []; + + // replace the existing UL with an empty one - this is faster than $.empty() + menuInner.replaceChild(emptyMenu, menuInner.firstChild); + + for (var i = 0, visibleElementsLen = elements.length; i < visibleElementsLen; i++) { + var element = elements[i], + elText, + elementData; + + if (that.options.sanitize) { + elText = element.lastChild; + + if (elText) { + elementData = that.selectpicker.current.data[i + that.selectpicker.view.position0]; + + if (elementData && elementData.content && !elementData.sanitized) { + toSanitize.push(elText); + elementData.sanitized = true; + } + } + } + + menuFragment.appendChild(element); + } + + if (that.options.sanitize && toSanitize.length) { + sanitizeHtml(toSanitize, that.options.whiteList, that.options.sanitizeFn); + } + + if (isVirtual === true) { + marginTop = (that.selectpicker.view.position0 === 0 ? 0 : that.selectpicker.current.data[that.selectpicker.view.position0 - 1].position); + marginBottom = (that.selectpicker.view.position1 > size - 1 ? 0 : that.selectpicker.current.data[size - 1].position - that.selectpicker.current.data[that.selectpicker.view.position1 - 1].position); + + menuInner.firstChild.style.marginTop = marginTop + 'px'; + menuInner.firstChild.style.marginBottom = marginBottom + 'px'; + } else { + menuInner.firstChild.style.marginTop = 0; + menuInner.firstChild.style.marginBottom = 0; + } + + menuInner.firstChild.appendChild(menuFragment); + + // if an option is encountered that is wider than the current menu width, update the menu width accordingly + // switch to ResizeObserver with increased browser support + if (isVirtual === true && that.sizeInfo.hasScrollBar) { + var menuInnerInnerWidth = menuInner.firstChild.offsetWidth; + + if (init && menuInnerInnerWidth < that.sizeInfo.menuInnerInnerWidth && that.sizeInfo.totalMenuWidth > that.sizeInfo.selectWidth) { + menuInner.firstChild.style.minWidth = that.sizeInfo.menuInnerInnerWidth + 'px'; + } else if (menuInnerInnerWidth > that.sizeInfo.menuInnerInnerWidth) { + // set to 0 to get actual width of menu + that.$menu[0].style.minWidth = 0; + + var actualMenuWidth = menuInner.firstChild.offsetWidth; + + if (actualMenuWidth > that.sizeInfo.menuInnerInnerWidth) { + that.sizeInfo.menuInnerInnerWidth = actualMenuWidth; + menuInner.firstChild.style.minWidth = that.sizeInfo.menuInnerInnerWidth + 'px'; + } + + // reset to default CSS styling + that.$menu[0].style.minWidth = ''; + } + } + } + } + + that.prevActiveIndex = that.activeIndex; + + if (!that.options.liveSearch) { + that.$menuInner.trigger('focus'); + } else if (isSearching && init) { + var index = 0, + newActive; + + if (!that.selectpicker.view.canHighlight[index]) { + index = 1 + that.selectpicker.view.canHighlight.slice(1).indexOf(true); + } + + newActive = that.selectpicker.view.visibleElements[index]; + + that.defocusItem(that.selectpicker.view.currentActive); + + that.activeIndex = (that.selectpicker.current.data[index] || {}).index; + + that.focusItem(newActive); + } + } + + $(window) + .off('resize' + EVENT_KEY + '.' + this.selectId + '.createView') + .on('resize' + EVENT_KEY + '.' + this.selectId + '.createView', function () { + var isActive = that.$newElement.hasClass(classNames.SHOW); + + if (isActive) scroll(that.$menuInner[0].scrollTop); + }); + }, + + focusItem: function (li, liData, noStyle) { + if (li) { + liData = liData || this.selectpicker.main.data[this.activeIndex]; + var a = li.firstChild; + + if (a) { + a.setAttribute('aria-setsize', this.selectpicker.view.size); + a.setAttribute('aria-posinset', liData.posinset); + + if (noStyle !== true) { + this.focusedParent.setAttribute('aria-activedescendant', a.id); + li.classList.add('active'); + a.classList.add('active'); + } + } + } + }, + + defocusItem: function (li) { + if (li) { + li.classList.remove('active'); + if (li.firstChild) li.firstChild.classList.remove('active'); + } + }, + + setPlaceholder: function () { + var that = this, + updateIndex = false; + + if (this.options.title && !this.multiple) { + if (!this.selectpicker.view.titleOption) this.selectpicker.view.titleOption = document.createElement('option'); + + // this option doesn't create a new
  • element, but does add a new option at the start, + // so startIndex should increase to prevent having to check every option for the bs-title-option class + updateIndex = true; + + var element = this.$element[0], + selectTitleOption = false, + titleNotAppended = !this.selectpicker.view.titleOption.parentNode, + selectedIndex = element.selectedIndex, + selectedOption = element.options[selectedIndex], + navigation = window.performance && window.performance.getEntriesByType('navigation'), + // Safari doesn't support getEntriesByType('navigation') - fall back to performance.navigation + isNotBackForward = (navigation && navigation.length) ? navigation[0].type !== 'back_forward' : window.performance.navigation.type !== 2; + + if (titleNotAppended) { + // Use native JS to prepend option (faster) + this.selectpicker.view.titleOption.className = 'bs-title-option'; + this.selectpicker.view.titleOption.value = ''; + + // Check if selected or data-selected attribute is already set on an option. If not, select the titleOption option. + // the selected item may have been changed by user or programmatically before the bootstrap select plugin runs, + // if so, the select will have the data-selected attribute + selectTitleOption = !selectedOption || (selectedIndex === 0 && selectedOption.defaultSelected === false && this.$element.data('selected') === undefined); + } + + if (titleNotAppended || this.selectpicker.view.titleOption.index !== 0) { + element.insertBefore(this.selectpicker.view.titleOption, element.firstChild); + } + + // Set selected *after* appending to select, + // otherwise the option doesn't get selected in IE + // set using selectedIndex, as setting the selected attr to true here doesn't work in IE11 + if (selectTitleOption && isNotBackForward) { + element.selectedIndex = 0; + } else if (document.readyState !== 'complete') { + // if navigation type is back_forward, there's a chance the select will have its value set by BFCache + // wait for that value to be set, then run render again + window.addEventListener('pageshow', function () { + if (that.selectpicker.view.displayedValue !== element.value) that.render(); + }); + } + } + + return updateIndex; + }, + + buildData: function () { + var optionSelector = ':not([hidden]):not([data-hidden="true"])', + mainData = [], + optID = 0, + startIndex = this.setPlaceholder() ? 1 : 0; // append the titleOption if necessary and skip the first option in the loop + + if (this.options.hideDisabled) optionSelector += ':not(:disabled)'; + + var selectOptions = this.$element[0].querySelectorAll('select > *' + optionSelector); + + function addDivider (config) { + var previousData = mainData[mainData.length - 1]; + + // ensure optgroup doesn't create back-to-back dividers + if ( + previousData && + previousData.type === 'divider' && + (previousData.optID || config.optID) + ) { + return; + } + + config = config || {}; + config.type = 'divider'; + + mainData.push(config); + } + + function addOption (option, config) { + config = config || {}; + + config.divider = option.getAttribute('data-divider') === 'true'; + + if (config.divider) { + addDivider({ + optID: config.optID + }); + } else { + var liIndex = mainData.length, + cssText = option.style.cssText, + inlineStyle = cssText ? htmlEscape(cssText) : '', + optionClass = (option.className || '') + (config.optgroupClass || ''); + + if (config.optID) optionClass = 'opt ' + optionClass; + + config.optionClass = optionClass.trim(); + config.inlineStyle = inlineStyle; + config.text = option.textContent; + + config.content = option.getAttribute('data-content'); + config.tokens = option.getAttribute('data-tokens'); + config.subtext = option.getAttribute('data-subtext'); + config.icon = option.getAttribute('data-icon'); + + option.liIndex = liIndex; + + config.display = config.content || config.text; + config.type = 'option'; + config.index = liIndex; + config.option = option; + config.selected = !!option.selected; + config.disabled = config.disabled || !!option.disabled; + + mainData.push(config); + } + } + + function addOptgroup (index, selectOptions) { + var optgroup = selectOptions[index], + // skip placeholder option + previous = index - 1 < startIndex ? false : selectOptions[index - 1], + next = selectOptions[index + 1], + options = optgroup.querySelectorAll('option' + optionSelector); + + if (!options.length) return; + + var config = { + display: htmlEscape(optgroup.label), + subtext: optgroup.getAttribute('data-subtext'), + icon: optgroup.getAttribute('data-icon'), + type: 'optgroup-label', + optgroupClass: ' ' + (optgroup.className || '') + }, + headerIndex, + lastIndex; + + optID++; + + if (previous) { + addDivider({ optID: optID }); + } + + config.optID = optID; + + mainData.push(config); + + for (var j = 0, len = options.length; j < len; j++) { + var option = options[j]; + + if (j === 0) { + headerIndex = mainData.length - 1; + lastIndex = headerIndex + len; + } + + addOption(option, { + headerIndex: headerIndex, + lastIndex: lastIndex, + optID: config.optID, + optgroupClass: config.optgroupClass, + disabled: optgroup.disabled + }); + } + + if (next) { + addDivider({ optID: optID }); + } + } + + for (var len = selectOptions.length, i = startIndex; i < len; i++) { + var item = selectOptions[i]; + + if (item.tagName !== 'OPTGROUP') { + addOption(item, {}); + } else { + addOptgroup(i, selectOptions); + } + } + + this.selectpicker.main.data = this.selectpicker.current.data = mainData; + }, + + buildList: function () { + var that = this, + selectData = this.selectpicker.main.data, + mainElements = [], + widestOptionLength = 0; + + if ((that.options.showTick || that.multiple) && !elementTemplates.checkMark.parentNode) { + elementTemplates.checkMark.className = this.options.iconBase + ' ' + that.options.tickIcon + ' check-mark'; + elementTemplates.a.appendChild(elementTemplates.checkMark); + } + + function buildElement (item) { + var liElement, + combinedLength = 0; + + switch (item.type) { + case 'divider': + liElement = generateOption.li( + false, + classNames.DIVIDER, + (item.optID ? item.optID + 'div' : undefined) + ); + + break; + + case 'option': + liElement = generateOption.li( + generateOption.a( + generateOption.text.call(that, item), + item.optionClass, + item.inlineStyle + ), + '', + item.optID + ); + + if (liElement.firstChild) { + liElement.firstChild.id = that.selectId + '-' + item.index; + } + + break; + + case 'optgroup-label': + liElement = generateOption.li( + generateOption.label.call(that, item), + 'dropdown-header' + item.optgroupClass, + item.optID + ); + + break; + } + + item.element = liElement; + mainElements.push(liElement); + + // count the number of characters in the option - not perfect, but should work in most cases + if (item.display) combinedLength += item.display.length; + if (item.subtext) combinedLength += item.subtext.length; + // if there is an icon, ensure this option's width is checked + if (item.icon) combinedLength += 1; + + if (combinedLength > widestOptionLength) { + widestOptionLength = combinedLength; + + // guess which option is the widest + // use this when calculating menu width + // not perfect, but it's fast, and the width will be updating accordingly when scrolling + that.selectpicker.view.widestOption = mainElements[mainElements.length - 1]; + } + } + + for (var len = selectData.length, i = 0; i < len; i++) { + var item = selectData[i]; + + buildElement(item); + } + + this.selectpicker.main.elements = this.selectpicker.current.elements = mainElements; + }, + + findLis: function () { + return this.$menuInner.find('.inner > li'); + }, + + render: function () { + var that = this, + element = this.$element[0], + // ensure titleOption is appended and selected (if necessary) before getting selectedOptions + placeholderSelected = this.setPlaceholder() && element.selectedIndex === 0, + selectedOptions = getSelectedOptions(element, this.options.hideDisabled), + selectedCount = selectedOptions.length, + button = this.$button[0], + buttonInner = button.querySelector('.filter-option-inner-inner'), + multipleSeparator = document.createTextNode(this.options.multipleSeparator), + titleFragment = elementTemplates.fragment.cloneNode(false), + showCount, + countMax, + hasContent = false; + + button.classList.toggle('bs-placeholder', that.multiple ? !selectedCount : !getSelectValues(element, selectedOptions)); + + if (!that.multiple && selectedOptions.length === 1) { + that.selectpicker.view.displayedValue = getSelectValues(element, selectedOptions); + } + + if (this.options.selectedTextFormat === 'static') { + titleFragment = generateOption.text.call(this, { text: this.options.title }, true); + } else { + showCount = this.multiple && this.options.selectedTextFormat.indexOf('count') !== -1 && selectedCount > 1; + + // determine if the number of selected options will be shown (showCount === true) + if (showCount) { + countMax = this.options.selectedTextFormat.split('>'); + showCount = (countMax.length > 1 && selectedCount > countMax[1]) || (countMax.length === 1 && selectedCount >= 2); + } + + // only loop through all selected options if the count won't be shown + if (showCount === false) { + if (!placeholderSelected) { + for (var selectedIndex = 0; selectedIndex < selectedCount; selectedIndex++) { + if (selectedIndex < 50) { + var option = selectedOptions[selectedIndex], + thisData = this.selectpicker.main.data[option.liIndex], + titleOptions = {}; + + if (this.multiple && selectedIndex > 0) { + titleFragment.appendChild(multipleSeparator.cloneNode(false)); + } + + if (option.title) { + titleOptions.text = option.title; + } else if (thisData) { + if (thisData.content && that.options.showContent) { + titleOptions.content = thisData.content.toString(); + hasContent = true; + } else { + if (that.options.showIcon) { + titleOptions.icon = thisData.icon; + } + if (that.options.showSubtext && !that.multiple && thisData.subtext) titleOptions.subtext = ' ' + thisData.subtext; + titleOptions.text = option.textContent.trim(); + } + } + + titleFragment.appendChild(generateOption.text.call(this, titleOptions, true)); + } else { + break; + } + } + + // add ellipsis + if (selectedCount > 49) { + titleFragment.appendChild(document.createTextNode('...')); + } + } + } else { + var optionSelector = ':not([hidden]):not([data-hidden="true"]):not([data-divider="true"])'; + if (this.options.hideDisabled) optionSelector += ':not(:disabled)'; + + // If this is a multiselect, and selectedTextFormat is count, then show 1 of 2 selected, etc. + var totalCount = this.$element[0].querySelectorAll('select > option' + optionSelector + ', optgroup' + optionSelector + ' option' + optionSelector).length, + tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedCount, totalCount) : this.options.countSelectedText; + + titleFragment = generateOption.text.call(this, { + text: tr8nText.replace('{0}', selectedCount.toString()).replace('{1}', totalCount.toString()) + }, true); + } + } + + if (this.options.title == undefined) { + // use .attr to ensure undefined is returned if title attribute is not set + this.options.title = this.$element.attr('title'); + } + + // If the select doesn't have a title, then use the default, or if nothing is set at all, use noneSelectedText + if (!titleFragment.childNodes.length) { + titleFragment = generateOption.text.call(this, { + text: typeof this.options.title !== 'undefined' ? this.options.title : this.options.noneSelectedText + }, true); + } + + // strip all HTML tags and trim the result, then unescape any escaped tags + button.title = titleFragment.textContent.replace(/<[^>]*>?/g, '').trim(); + + if (this.options.sanitize && hasContent) { + sanitizeHtml([titleFragment], that.options.whiteList, that.options.sanitizeFn); + } + + buttonInner.innerHTML = ''; + buttonInner.appendChild(titleFragment); + + if (version.major < 4 && this.$newElement[0].classList.contains('bs3-has-addon')) { + var filterExpand = button.querySelector('.filter-expand'), + clone = buttonInner.cloneNode(true); + + clone.className = 'filter-expand'; + + if (filterExpand) { + button.replaceChild(clone, filterExpand); + } else { + button.appendChild(clone); + } + } + + this.$element.trigger('rendered' + EVENT_KEY); + }, + + /** + * @param [style] + * @param [status] + */ + setStyle: function (newStyle, status) { + var button = this.$button[0], + newElement = this.$newElement[0], + style = this.options.style.trim(), + buttonClass; + + if (this.$element.attr('class')) { + this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device|bs-select-hidden|validate\[.*\]/gi, '')); + } + + if (version.major < 4) { + newElement.classList.add('bs3'); + + if (newElement.parentNode.classList && newElement.parentNode.classList.contains('input-group') && + (newElement.previousElementSibling || newElement.nextElementSibling) && + (newElement.previousElementSibling || newElement.nextElementSibling).classList.contains('input-group-addon') + ) { + newElement.classList.add('bs3-has-addon'); + } + } + + if (newStyle) { + buttonClass = newStyle.trim(); + } else { + buttonClass = style; + } + + if (status == 'add') { + if (buttonClass) button.classList.add.apply(button.classList, buttonClass.split(' ')); + } else if (status == 'remove') { + if (buttonClass) button.classList.remove.apply(button.classList, buttonClass.split(' ')); + } else { + if (style) button.classList.remove.apply(button.classList, style.split(' ')); + if (buttonClass) button.classList.add.apply(button.classList, buttonClass.split(' ')); + } + }, + + liHeight: function (refresh) { + if (!refresh && (this.options.size === false || Object.keys(this.sizeInfo).length)) return; + + var newElement = elementTemplates.div.cloneNode(false), + menu = elementTemplates.div.cloneNode(false), + menuInner = elementTemplates.div.cloneNode(false), + menuInnerInner = document.createElement('ul'), + divider = elementTemplates.li.cloneNode(false), + dropdownHeader = elementTemplates.li.cloneNode(false), + li, + a = elementTemplates.a.cloneNode(false), + text = elementTemplates.span.cloneNode(false), + header = this.options.header && this.$menu.find('.' + classNames.POPOVERHEADER).length > 0 ? this.$menu.find('.' + classNames.POPOVERHEADER)[0].cloneNode(true) : null, + search = this.options.liveSearch ? elementTemplates.div.cloneNode(false) : null, + actions = this.options.actionsBox && this.multiple && this.$menu.find('.bs-actionsbox').length > 0 ? this.$menu.find('.bs-actionsbox')[0].cloneNode(true) : null, + doneButton = this.options.doneButton && this.multiple && this.$menu.find('.bs-donebutton').length > 0 ? this.$menu.find('.bs-donebutton')[0].cloneNode(true) : null, + firstOption = this.$element.find('option')[0]; + + this.sizeInfo.selectWidth = this.$newElement[0].offsetWidth; + + text.className = 'text'; + a.className = 'dropdown-item ' + (firstOption ? firstOption.className : ''); + newElement.className = this.$menu[0].parentNode.className + ' ' + classNames.SHOW; + newElement.style.width = 0; // ensure button width doesn't affect natural width of menu when calculating + if (this.options.width === 'auto') menu.style.minWidth = 0; + menu.className = classNames.MENU + ' ' + classNames.SHOW; + menuInner.className = 'inner ' + classNames.SHOW; + menuInnerInner.className = classNames.MENU + ' inner ' + (version.major === '4' ? classNames.SHOW : ''); + divider.className = classNames.DIVIDER; + dropdownHeader.className = 'dropdown-header'; + + text.appendChild(document.createTextNode('\u200b')); + + if (this.selectpicker.current.data.length) { + for (var i = 0; i < this.selectpicker.current.data.length; i++) { + var data = this.selectpicker.current.data[i]; + if (data.type === 'option') { + li = data.element; + break; + } + } + } else { + li = elementTemplates.li.cloneNode(false); + a.appendChild(text); + li.appendChild(a); + } + + dropdownHeader.appendChild(text.cloneNode(true)); + + if (this.selectpicker.view.widestOption) { + menuInnerInner.appendChild(this.selectpicker.view.widestOption.cloneNode(true)); + } + + menuInnerInner.appendChild(li); + menuInnerInner.appendChild(divider); + menuInnerInner.appendChild(dropdownHeader); + if (header) menu.appendChild(header); + if (search) { + var input = document.createElement('input'); + search.className = 'bs-searchbox'; + input.className = 'form-control'; + search.appendChild(input); + menu.appendChild(search); + } + if (actions) menu.appendChild(actions); + menuInner.appendChild(menuInnerInner); + menu.appendChild(menuInner); + if (doneButton) menu.appendChild(doneButton); + newElement.appendChild(menu); + + document.body.appendChild(newElement); + + var liHeight = li.offsetHeight, + dropdownHeaderHeight = dropdownHeader ? dropdownHeader.offsetHeight : 0, + headerHeight = header ? header.offsetHeight : 0, + searchHeight = search ? search.offsetHeight : 0, + actionsHeight = actions ? actions.offsetHeight : 0, + doneButtonHeight = doneButton ? doneButton.offsetHeight : 0, + dividerHeight = $(divider).outerHeight(true), + // fall back to jQuery if getComputedStyle is not supported + menuStyle = window.getComputedStyle ? window.getComputedStyle(menu) : false, + menuWidth = menu.offsetWidth, + $menu = menuStyle ? null : $(menu), + menuPadding = { + vert: toInteger(menuStyle ? menuStyle.paddingTop : $menu.css('paddingTop')) + + toInteger(menuStyle ? menuStyle.paddingBottom : $menu.css('paddingBottom')) + + toInteger(menuStyle ? menuStyle.borderTopWidth : $menu.css('borderTopWidth')) + + toInteger(menuStyle ? menuStyle.borderBottomWidth : $menu.css('borderBottomWidth')), + horiz: toInteger(menuStyle ? menuStyle.paddingLeft : $menu.css('paddingLeft')) + + toInteger(menuStyle ? menuStyle.paddingRight : $menu.css('paddingRight')) + + toInteger(menuStyle ? menuStyle.borderLeftWidth : $menu.css('borderLeftWidth')) + + toInteger(menuStyle ? menuStyle.borderRightWidth : $menu.css('borderRightWidth')) + }, + menuExtras = { + vert: menuPadding.vert + + toInteger(menuStyle ? menuStyle.marginTop : $menu.css('marginTop')) + + toInteger(menuStyle ? menuStyle.marginBottom : $menu.css('marginBottom')) + 2, + horiz: menuPadding.horiz + + toInteger(menuStyle ? menuStyle.marginLeft : $menu.css('marginLeft')) + + toInteger(menuStyle ? menuStyle.marginRight : $menu.css('marginRight')) + 2 + }, + scrollBarWidth; + + menuInner.style.overflowY = 'scroll'; + + scrollBarWidth = menu.offsetWidth - menuWidth; + + document.body.removeChild(newElement); + + this.sizeInfo.liHeight = liHeight; + this.sizeInfo.dropdownHeaderHeight = dropdownHeaderHeight; + this.sizeInfo.headerHeight = headerHeight; + this.sizeInfo.searchHeight = searchHeight; + this.sizeInfo.actionsHeight = actionsHeight; + this.sizeInfo.doneButtonHeight = doneButtonHeight; + this.sizeInfo.dividerHeight = dividerHeight; + this.sizeInfo.menuPadding = menuPadding; + this.sizeInfo.menuExtras = menuExtras; + this.sizeInfo.menuWidth = menuWidth; + this.sizeInfo.menuInnerInnerWidth = menuWidth - menuPadding.horiz; + this.sizeInfo.totalMenuWidth = this.sizeInfo.menuWidth; + this.sizeInfo.scrollBarWidth = scrollBarWidth; + this.sizeInfo.selectHeight = this.$newElement[0].offsetHeight; + + this.setPositionData(); + }, + + getSelectPosition: function () { + var that = this, + $window = $(window), + pos = that.$newElement.offset(), + $container = $(that.options.container), + containerPos; + + if (that.options.container && $container.length && !$container.is('body')) { + containerPos = $container.offset(); + containerPos.top += parseInt($container.css('borderTopWidth')); + containerPos.left += parseInt($container.css('borderLeftWidth')); + } else { + containerPos = { top: 0, left: 0 }; + } + + var winPad = that.options.windowPadding; + + this.sizeInfo.selectOffsetTop = pos.top - containerPos.top - $window.scrollTop(); + this.sizeInfo.selectOffsetBot = $window.height() - this.sizeInfo.selectOffsetTop - this.sizeInfo.selectHeight - containerPos.top - winPad[2]; + this.sizeInfo.selectOffsetLeft = pos.left - containerPos.left - $window.scrollLeft(); + this.sizeInfo.selectOffsetRight = $window.width() - this.sizeInfo.selectOffsetLeft - this.sizeInfo.selectWidth - containerPos.left - winPad[1]; + this.sizeInfo.selectOffsetTop -= winPad[0]; + this.sizeInfo.selectOffsetLeft -= winPad[3]; + }, + + setMenuSize: function (isAuto) { + this.getSelectPosition(); + + var selectWidth = this.sizeInfo.selectWidth, + liHeight = this.sizeInfo.liHeight, + headerHeight = this.sizeInfo.headerHeight, + searchHeight = this.sizeInfo.searchHeight, + actionsHeight = this.sizeInfo.actionsHeight, + doneButtonHeight = this.sizeInfo.doneButtonHeight, + divHeight = this.sizeInfo.dividerHeight, + menuPadding = this.sizeInfo.menuPadding, + menuInnerHeight, + menuHeight, + divLength = 0, + minHeight, + _minHeight, + maxHeight, + menuInnerMinHeight, + estimate, + isDropup; + + if (this.options.dropupAuto) { + // Get the estimated height of the menu without scrollbars. + // This is useful for smaller menus, where there might be plenty of room + // below the button without setting dropup, but we can't know + // the exact height of the menu until createView is called later + estimate = liHeight * this.selectpicker.current.elements.length + menuPadding.vert; + + isDropup = this.sizeInfo.selectOffsetTop - this.sizeInfo.selectOffsetBot > this.sizeInfo.menuExtras.vert && estimate + this.sizeInfo.menuExtras.vert + 50 > this.sizeInfo.selectOffsetBot; + + // ensure dropup doesn't change while searching (so menu doesn't bounce back and forth) + if (this.selectpicker.isSearching === true) { + isDropup = this.selectpicker.dropup; + } + + this.$newElement.toggleClass(classNames.DROPUP, isDropup); + this.selectpicker.dropup = isDropup; + } + + if (this.options.size === 'auto') { + _minHeight = this.selectpicker.current.elements.length > 3 ? this.sizeInfo.liHeight * 3 + this.sizeInfo.menuExtras.vert - 2 : 0; + menuHeight = this.sizeInfo.selectOffsetBot - this.sizeInfo.menuExtras.vert; + minHeight = _minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight; + menuInnerMinHeight = Math.max(_minHeight - menuPadding.vert, 0); + + if (this.$newElement.hasClass(classNames.DROPUP)) { + menuHeight = this.sizeInfo.selectOffsetTop - this.sizeInfo.menuExtras.vert; + } + + maxHeight = menuHeight; + menuInnerHeight = menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding.vert; + } else if (this.options.size && this.options.size != 'auto' && this.selectpicker.current.elements.length > this.options.size) { + for (var i = 0; i < this.options.size; i++) { + if (this.selectpicker.current.data[i].type === 'divider') divLength++; + } + + menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding.vert; + menuInnerHeight = menuHeight - menuPadding.vert; + maxHeight = menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight; + minHeight = menuInnerMinHeight = ''; + } + + this.$menu.css({ + 'max-height': maxHeight + 'px', + 'overflow': 'hidden', + 'min-height': minHeight + 'px' + }); + + this.$menuInner.css({ + 'max-height': menuInnerHeight + 'px', + 'overflow-y': 'auto', + 'min-height': menuInnerMinHeight + 'px' + }); + + // ensure menuInnerHeight is always a positive number to prevent issues calculating chunkSize in createView + this.sizeInfo.menuInnerHeight = Math.max(menuInnerHeight, 1); + + if (this.selectpicker.current.data.length && this.selectpicker.current.data[this.selectpicker.current.data.length - 1].position > this.sizeInfo.menuInnerHeight) { + this.sizeInfo.hasScrollBar = true; + this.sizeInfo.totalMenuWidth = this.sizeInfo.menuWidth + this.sizeInfo.scrollBarWidth; + } + + if (this.options.dropdownAlignRight === 'auto') { + this.$menu.toggleClass(classNames.MENURIGHT, this.sizeInfo.selectOffsetLeft > this.sizeInfo.selectOffsetRight && this.sizeInfo.selectOffsetRight < (this.sizeInfo.totalMenuWidth - selectWidth)); + } + + if (this.dropdown && this.dropdown._popper) this.dropdown._popper.update(); + }, + + setSize: function (refresh) { + this.liHeight(refresh); + + if (this.options.header) this.$menu.css('padding-top', 0); + + if (this.options.size !== false) { + var that = this, + $window = $(window); + + this.setMenuSize(); + + if (this.options.liveSearch) { + this.$searchbox + .off('input.setMenuSize propertychange.setMenuSize') + .on('input.setMenuSize propertychange.setMenuSize', function () { + return that.setMenuSize(); + }); + } + + if (this.options.size === 'auto') { + $window + .off('resize' + EVENT_KEY + '.' + this.selectId + '.setMenuSize' + ' scroll' + EVENT_KEY + '.' + this.selectId + '.setMenuSize') + .on('resize' + EVENT_KEY + '.' + this.selectId + '.setMenuSize' + ' scroll' + EVENT_KEY + '.' + this.selectId + '.setMenuSize', function () { + return that.setMenuSize(); + }); + } else if (this.options.size && this.options.size != 'auto' && this.selectpicker.current.elements.length > this.options.size) { + $window.off('resize' + EVENT_KEY + '.' + this.selectId + '.setMenuSize' + ' scroll' + EVENT_KEY + '.' + this.selectId + '.setMenuSize'); + } + } + + this.createView(false, true, refresh); + }, + + setWidth: function () { + var that = this; + + if (this.options.width === 'auto') { + requestAnimationFrame(function () { + that.$menu.css('min-width', '0'); + + that.$element.on('loaded' + EVENT_KEY, function () { + that.liHeight(); + that.setMenuSize(); + + // Get correct width if element is hidden + var $selectClone = that.$newElement.clone().appendTo('body'), + btnWidth = $selectClone.css('width', 'auto').children('button').outerWidth(); + + $selectClone.remove(); + + // Set width to whatever's larger, button title or longest option + that.sizeInfo.selectWidth = Math.max(that.sizeInfo.totalMenuWidth, btnWidth); + that.$newElement.css('width', that.sizeInfo.selectWidth + 'px'); + }); + }); + } else if (this.options.width === 'fit') { + // Remove inline min-width so width can be changed from 'auto' + this.$menu.css('min-width', ''); + this.$newElement.css('width', '').addClass('fit-width'); + } else if (this.options.width) { + // Remove inline min-width so width can be changed from 'auto' + this.$menu.css('min-width', ''); + this.$newElement.css('width', this.options.width); + } else { + // Remove inline min-width/width so width can be changed + this.$menu.css('min-width', ''); + this.$newElement.css('width', ''); + } + // Remove fit-width class if width is changed programmatically + if (this.$newElement.hasClass('fit-width') && this.options.width !== 'fit') { + this.$newElement[0].classList.remove('fit-width'); + } + }, + + selectPosition: function () { + this.$bsContainer = $('
    '); + + var that = this, + $container = $(this.options.container), + pos, + containerPos, + actualHeight, + getPlacement = function ($element) { + var containerPosition = {}, + // fall back to dropdown's default display setting if display is not manually set + display = that.options.display || ( + // Bootstrap 3 doesn't have $.fn.dropdown.Constructor.Default + $.fn.dropdown.Constructor.Default ? $.fn.dropdown.Constructor.Default.display + : false + ); + + that.$bsContainer.addClass($element.attr('class').replace(/form-control|fit-width/gi, '')).toggleClass(classNames.DROPUP, $element.hasClass(classNames.DROPUP)); + pos = $element.offset(); + + if (!$container.is('body')) { + containerPos = $container.offset(); + containerPos.top += parseInt($container.css('borderTopWidth')) - $container.scrollTop(); + containerPos.left += parseInt($container.css('borderLeftWidth')) - $container.scrollLeft(); + } else { + containerPos = { top: 0, left: 0 }; + } + + actualHeight = $element.hasClass(classNames.DROPUP) ? 0 : $element[0].offsetHeight; + + // Bootstrap 4+ uses Popper for menu positioning + if (version.major < 4 || display === 'static') { + containerPosition.top = pos.top - containerPos.top + actualHeight; + containerPosition.left = pos.left - containerPos.left; + } + + containerPosition.width = $element[0].offsetWidth; + + that.$bsContainer.css(containerPosition); + }; + + this.$button.on('click.bs.dropdown.data-api', function () { + if (that.isDisabled()) { + return; + } + + getPlacement(that.$newElement); + + that.$bsContainer + .appendTo(that.options.container) + .toggleClass(classNames.SHOW, !that.$button.hasClass(classNames.SHOW)) + .append(that.$menu); + }); + + $(window) + .off('resize' + EVENT_KEY + '.' + this.selectId + ' scroll' + EVENT_KEY + '.' + this.selectId) + .on('resize' + EVENT_KEY + '.' + this.selectId + ' scroll' + EVENT_KEY + '.' + this.selectId, function () { + var isActive = that.$newElement.hasClass(classNames.SHOW); + + if (isActive) getPlacement(that.$newElement); + }); + + this.$element.on('hide' + EVENT_KEY, function () { + that.$menu.data('height', that.$menu.height()); + that.$bsContainer.detach(); + }); + }, + + setOptionStatus: function (selectedOnly) { + var that = this; + + that.noScroll = false; + + if (that.selectpicker.view.visibleElements && that.selectpicker.view.visibleElements.length) { + for (var i = 0; i < that.selectpicker.view.visibleElements.length; i++) { + var liData = that.selectpicker.current.data[i + that.selectpicker.view.position0], + option = liData.option; + + if (option) { + if (selectedOnly !== true) { + that.setDisabled( + liData.index, + liData.disabled + ); + } + + that.setSelected( + liData.index, + option.selected + ); + } + } + } + }, + + /** + * @param {number} index - the index of the option that is being changed + * @param {boolean} selected - true if the option is being selected, false if being deselected + */ + setSelected: function (index, selected) { + var li = this.selectpicker.main.elements[index], + liData = this.selectpicker.main.data[index], + activeIndexIsSet = this.activeIndex !== undefined, + thisIsActive = this.activeIndex === index, + prevActive, + a, + // if current option is already active + // OR + // if the current option is being selected, it's NOT multiple, and + // activeIndex is undefined: + // - when the menu is first being opened, OR + // - after a search has been performed, OR + // - when retainActive is false when selecting a new option (i.e. index of the newly selected option is not the same as the current activeIndex) + keepActive = thisIsActive || (selected && !this.multiple && !activeIndexIsSet); + + liData.selected = selected; + + a = li.firstChild; + + if (selected) { + this.selectedIndex = index; + } + + li.classList.toggle('selected', selected); + + if (keepActive) { + this.focusItem(li, liData); + this.selectpicker.view.currentActive = li; + this.activeIndex = index; + } else { + this.defocusItem(li); + } + + if (a) { + a.classList.toggle('selected', selected); + + if (selected) { + a.setAttribute('aria-selected', true); + } else { + if (this.multiple) { + a.setAttribute('aria-selected', false); + } else { + a.removeAttribute('aria-selected'); + } + } + } + + if (!keepActive && !activeIndexIsSet && selected && this.prevActiveIndex !== undefined) { + prevActive = this.selectpicker.main.elements[this.prevActiveIndex]; + + this.defocusItem(prevActive); + } + }, + + /** + * @param {number} index - the index of the option that is being disabled + * @param {boolean} disabled - true if the option is being disabled, false if being enabled + */ + setDisabled: function (index, disabled) { + var li = this.selectpicker.main.elements[index], + a; + + this.selectpicker.main.data[index].disabled = disabled; + + a = li.firstChild; + + li.classList.toggle(classNames.DISABLED, disabled); + + if (a) { + if (version.major === '4') a.classList.toggle(classNames.DISABLED, disabled); + + if (disabled) { + a.setAttribute('aria-disabled', disabled); + a.setAttribute('tabindex', -1); + } else { + a.removeAttribute('aria-disabled'); + a.setAttribute('tabindex', 0); + } + } + }, + + isDisabled: function () { + return this.$element[0].disabled; + }, + + checkDisabled: function () { + if (this.isDisabled()) { + this.$newElement[0].classList.add(classNames.DISABLED); + this.$button.addClass(classNames.DISABLED).attr('aria-disabled', true); + } else { + if (this.$button[0].classList.contains(classNames.DISABLED)) { + this.$newElement[0].classList.remove(classNames.DISABLED); + this.$button.removeClass(classNames.DISABLED).attr('aria-disabled', false); + } + } + }, + + clickListener: function () { + var that = this, + $document = $(document); + + $document.data('spaceSelect', false); + + this.$button.on('keyup', function (e) { + if (/(32)/.test(e.keyCode.toString(10)) && $document.data('spaceSelect')) { + e.preventDefault(); + $document.data('spaceSelect', false); + } + }); + + this.$newElement.on('show.bs.dropdown', function () { + if (version.major > 3 && !that.dropdown) { + that.dropdown = that.$button.data('bs.dropdown'); + that.dropdown._menu = that.$menu[0]; + } + }); + + this.$button.on('click.bs.dropdown.data-api', function () { + if (!that.$newElement.hasClass(classNames.SHOW)) { + that.setSize(); + } + }); + + function setFocus () { + if (that.options.liveSearch) { + that.$searchbox.trigger('focus'); + } else { + that.$menuInner.trigger('focus'); + } + } + + function checkPopperExists () { + if (that.dropdown && that.dropdown._popper && that.dropdown._popper.state.isCreated) { + setFocus(); + } else { + requestAnimationFrame(checkPopperExists); + } + } + + this.$element.on('shown' + EVENT_KEY, function () { + if (that.$menuInner[0].scrollTop !== that.selectpicker.view.scrollTop) { + that.$menuInner[0].scrollTop = that.selectpicker.view.scrollTop; + } + + if (version.major > 3) { + requestAnimationFrame(checkPopperExists); + } else { + setFocus(); + } + }); + + // ensure posinset and setsize are correct before selecting an option via a click + this.$menuInner.on('mouseenter', 'li a', function (e) { + var hoverLi = this.parentElement, + position0 = that.isVirtual() ? that.selectpicker.view.position0 : 0, + index = Array.prototype.indexOf.call(hoverLi.parentElement.children, hoverLi), + hoverData = that.selectpicker.current.data[index + position0]; + + that.focusItem(hoverLi, hoverData, true); + }); + + this.$menuInner.on('click', 'li a', function (e, retainActive) { + var $this = $(this), + element = that.$element[0], + position0 = that.isVirtual() ? that.selectpicker.view.position0 : 0, + clickedData = that.selectpicker.current.data[$this.parent().index() + position0], + clickedIndex = clickedData.index, + prevValue = getSelectValues(element), + prevIndex = element.selectedIndex, + prevOption = element.options[prevIndex], + triggerChange = true; + + // Don't close on multi choice menu + if (that.multiple && that.options.maxOptions !== 1) { + e.stopPropagation(); + } + + e.preventDefault(); + + // Don't run if the select is disabled + if (!that.isDisabled() && !$this.parent().hasClass(classNames.DISABLED)) { + var option = clickedData.option, + $option = $(option), + state = option.selected, + $optgroup = $option.parent('optgroup'), + $optgroupOptions = $optgroup.find('option'), + maxOptions = that.options.maxOptions, + maxOptionsGrp = $optgroup.data('maxOptions') || false; + + if (clickedIndex === that.activeIndex) retainActive = true; + + if (!retainActive) { + that.prevActiveIndex = that.activeIndex; + that.activeIndex = undefined; + } + + if (!that.multiple) { // Deselect all others if not multi select box + if (prevOption) prevOption.selected = false; + option.selected = true; + that.setSelected(clickedIndex, true); + } else { // Toggle the one we have chosen if we are multi select. + option.selected = !state; + + that.setSelected(clickedIndex, !state); + that.focusedParent.focus(); + + if (maxOptions !== false || maxOptionsGrp !== false) { + var maxReached = maxOptions < getSelectedOptions(element).length, + maxReachedGrp = maxOptionsGrp < $optgroup.find('option:selected').length; + + if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) { + if (maxOptions && maxOptions == 1) { + element.selectedIndex = -1; + option.selected = true; + that.setOptionStatus(true); + } else if (maxOptionsGrp && maxOptionsGrp == 1) { + for (var i = 0; i < $optgroupOptions.length; i++) { + var _option = $optgroupOptions[i]; + _option.selected = false; + that.setSelected(_option.liIndex, false); + } + + option.selected = true; + that.setSelected(clickedIndex, true); + } else { + var maxOptionsText = typeof that.options.maxOptionsText === 'string' ? [that.options.maxOptionsText, that.options.maxOptionsText] : that.options.maxOptionsText, + maxOptionsArr = typeof maxOptionsText === 'function' ? maxOptionsText(maxOptions, maxOptionsGrp) : maxOptionsText, + maxTxt = maxOptionsArr[0].replace('{n}', maxOptions), + maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp), + $notify = $('
    '); + // If {var} is set in array, replace it + /** @deprecated */ + if (maxOptionsArr[2]) { + maxTxt = maxTxt.replace('{var}', maxOptionsArr[2][maxOptions > 1 ? 0 : 1]); + maxTxtGrp = maxTxtGrp.replace('{var}', maxOptionsArr[2][maxOptionsGrp > 1 ? 0 : 1]); + } + + option.selected = false; + + that.$menu.append($notify); + + if (maxOptions && maxReached) { + $notify.append($('
    ' + maxTxt + '
    ')); + triggerChange = false; + that.$element.trigger('maxReached' + EVENT_KEY); + } + + if (maxOptionsGrp && maxReachedGrp) { + $notify.append($('
    ' + maxTxtGrp + '
    ')); + triggerChange = false; + that.$element.trigger('maxReachedGrp' + EVENT_KEY); + } + + setTimeout(function () { + that.setSelected(clickedIndex, false); + }, 10); + + $notify[0].classList.add('fadeOut'); + + setTimeout(function () { + $notify.remove(); + }, 1050); + } + } + } + } + + if (!that.multiple || (that.multiple && that.options.maxOptions === 1)) { + that.$button.trigger('focus'); + } else if (that.options.liveSearch) { + that.$searchbox.trigger('focus'); + } + + // Trigger select 'change' + if (triggerChange) { + if (that.multiple || prevIndex !== element.selectedIndex) { + // $option.prop('selected') is current option state (selected/unselected). prevValue is the value of the select prior to being changed. + changedArguments = [option.index, $option.prop('selected'), prevValue]; + that.$element + .triggerNative('change'); + } + } + } + }); + + this.$menu.on('click', 'li.' + classNames.DISABLED + ' a, .' + classNames.POPOVERHEADER + ', .' + classNames.POPOVERHEADER + ' :not(.close)', function (e) { + if (e.currentTarget == this) { + e.preventDefault(); + e.stopPropagation(); + if (that.options.liveSearch && !$(e.target).hasClass('close')) { + that.$searchbox.trigger('focus'); + } else { + that.$button.trigger('focus'); + } + } + }); + + this.$menuInner.on('click', '.divider, .dropdown-header', function (e) { + e.preventDefault(); + e.stopPropagation(); + if (that.options.liveSearch) { + that.$searchbox.trigger('focus'); + } else { + that.$button.trigger('focus'); + } + }); + + this.$menu.on('click', '.' + classNames.POPOVERHEADER + ' .close', function () { + that.$button.trigger('click'); + }); + + this.$searchbox.on('click', function (e) { + e.stopPropagation(); + }); + + this.$menu.on('click', '.actions-btn', function (e) { + if (that.options.liveSearch) { + that.$searchbox.trigger('focus'); + } else { + that.$button.trigger('focus'); + } + + e.preventDefault(); + e.stopPropagation(); + + if ($(this).hasClass('bs-select-all')) { + that.selectAll(); + } else { + that.deselectAll(); + } + }); + + this.$button + .on('focus' + EVENT_KEY, function (e) { + var tabindex = that.$element[0].getAttribute('tabindex'); + + // only change when button is actually focused + if (tabindex !== undefined && e.originalEvent && e.originalEvent.isTrusted) { + // apply select element's tabindex to ensure correct order is followed when tabbing to the next element + this.setAttribute('tabindex', tabindex); + // set element's tabindex to -1 to allow for reverse tabbing + that.$element[0].setAttribute('tabindex', -1); + that.selectpicker.view.tabindex = tabindex; + } + }) + .on('blur' + EVENT_KEY, function (e) { + // revert everything to original tabindex + if (that.selectpicker.view.tabindex !== undefined && e.originalEvent && e.originalEvent.isTrusted) { + that.$element[0].setAttribute('tabindex', that.selectpicker.view.tabindex); + this.setAttribute('tabindex', -1); + that.selectpicker.view.tabindex = undefined; + } + }); + + this.$element + .on('change' + EVENT_KEY, function () { + that.render(); + that.$element.trigger('changed' + EVENT_KEY, changedArguments); + changedArguments = null; + }) + .on('focus' + EVENT_KEY, function () { + if (!that.options.mobile) that.$button[0].focus(); + }); + }, + + liveSearchListener: function () { + var that = this; + + this.$button.on('click.bs.dropdown.data-api', function () { + if (!!that.$searchbox.val()) { + that.$searchbox.val(''); + that.selectpicker.search.previousValue = undefined; + } + }); + + this.$searchbox.on('click.bs.dropdown.data-api focus.bs.dropdown.data-api touchend.bs.dropdown.data-api', function (e) { + e.stopPropagation(); + }); + + this.$searchbox.on('input propertychange', function () { + var searchValue = that.$searchbox[0].value; + + that.selectpicker.search.elements = []; + that.selectpicker.search.data = []; + + if (searchValue) { + var i, + searchMatch = [], + q = searchValue.toUpperCase(), + cache = {}, + cacheArr = [], + searchStyle = that._searchStyle(), + normalizeSearch = that.options.liveSearchNormalize; + + if (normalizeSearch) q = normalizeToBase(q); + + for (var i = 0; i < that.selectpicker.main.data.length; i++) { + var li = that.selectpicker.main.data[i]; + + if (!cache[i]) { + cache[i] = stringSearch(li, q, searchStyle, normalizeSearch); + } + + if (cache[i] && li.headerIndex !== undefined && cacheArr.indexOf(li.headerIndex) === -1) { + if (li.headerIndex > 0) { + cache[li.headerIndex - 1] = true; + cacheArr.push(li.headerIndex - 1); + } + + cache[li.headerIndex] = true; + cacheArr.push(li.headerIndex); + + cache[li.lastIndex + 1] = true; + } + + if (cache[i] && li.type !== 'optgroup-label') cacheArr.push(i); + } + + for (var i = 0, cacheLen = cacheArr.length; i < cacheLen; i++) { + var index = cacheArr[i], + prevIndex = cacheArr[i - 1], + li = that.selectpicker.main.data[index], + liPrev = that.selectpicker.main.data[prevIndex]; + + if (li.type !== 'divider' || (li.type === 'divider' && liPrev && liPrev.type !== 'divider' && cacheLen - 1 !== i)) { + that.selectpicker.search.data.push(li); + searchMatch.push(that.selectpicker.main.elements[index]); + } + } + + that.activeIndex = undefined; + that.noScroll = true; + that.$menuInner.scrollTop(0); + that.selectpicker.search.elements = searchMatch; + that.createView(true); + showNoResults.call(that, searchMatch, searchValue); + } else if (that.selectpicker.search.previousValue) { // for IE11 (#2402) + that.$menuInner.scrollTop(0); + that.createView(false); + } + + that.selectpicker.search.previousValue = searchValue; + }); + }, + + _searchStyle: function () { + return this.options.liveSearchStyle || 'contains'; + }, + + val: function (value) { + var element = this.$element[0]; + + if (typeof value !== 'undefined') { + var prevValue = getSelectValues(element); + + changedArguments = [null, null, prevValue]; + + this.$element + .val(value) + .trigger('changed' + EVENT_KEY, changedArguments); + + if (this.$newElement.hasClass(classNames.SHOW)) { + if (this.multiple) { + this.setOptionStatus(true); + } else { + var liSelectedIndex = (element.options[element.selectedIndex] || {}).liIndex; + + if (typeof liSelectedIndex === 'number') { + this.setSelected(this.selectedIndex, false); + this.setSelected(liSelectedIndex, true); + } + } + } + + this.render(); + + changedArguments = null; + + return this.$element; + } else { + return this.$element.val(); + } + }, + + changeAll: function (status) { + if (!this.multiple) return; + if (typeof status === 'undefined') status = true; + + var element = this.$element[0], + previousSelected = 0, + currentSelected = 0, + prevValue = getSelectValues(element); + + element.classList.add('bs-select-hidden'); + + for (var i = 0, data = this.selectpicker.current.data, len = data.length; i < len; i++) { + var liData = data[i], + option = liData.option; + + if (option && !liData.disabled && liData.type !== 'divider') { + if (liData.selected) previousSelected++; + option.selected = status; + if (status === true) currentSelected++; + } + } + + element.classList.remove('bs-select-hidden'); + + if (previousSelected === currentSelected) return; + + this.setOptionStatus(); + + changedArguments = [null, null, prevValue]; + + this.$element + .triggerNative('change'); + }, + + selectAll: function () { + return this.changeAll(true); + }, + + deselectAll: function () { + return this.changeAll(false); + }, + + toggle: function (e) { + e = e || window.event; + + if (e) e.stopPropagation(); + + this.$button.trigger('click.bs.dropdown.data-api'); + }, + + keydown: function (e) { + var $this = $(this), + isToggle = $this.hasClass('dropdown-toggle'), + $parent = isToggle ? $this.closest('.dropdown') : $this.closest(Selector.MENU), + that = $parent.data('this'), + $items = that.findLis(), + index, + isActive, + liActive, + activeLi, + offset, + updateScroll = false, + downOnTab = e.which === keyCodes.TAB && !isToggle && !that.options.selectOnTab, + isArrowKey = REGEXP_ARROW.test(e.which) || downOnTab, + scrollTop = that.$menuInner[0].scrollTop, + isVirtual = that.isVirtual(), + position0 = isVirtual === true ? that.selectpicker.view.position0 : 0; + + // do nothing if a function key is pressed + if (e.which >= 112 && e.which <= 123) return; + + isActive = that.$newElement.hasClass(classNames.SHOW); + + if ( + !isActive && + ( + isArrowKey || + (e.which >= 48 && e.which <= 57) || + (e.which >= 96 && e.which <= 105) || + (e.which >= 65 && e.which <= 90) + ) + ) { + that.$button.trigger('click.bs.dropdown.data-api'); + + if (that.options.liveSearch) { + that.$searchbox.trigger('focus'); + return; + } + } + + if (e.which === keyCodes.ESCAPE && isActive) { + e.preventDefault(); + that.$button.trigger('click.bs.dropdown.data-api').trigger('focus'); + } + + if (isArrowKey) { // if up or down + if (!$items.length) return; + + liActive = that.selectpicker.main.elements[that.activeIndex]; + index = liActive ? Array.prototype.indexOf.call(liActive.parentElement.children, liActive) : -1; + + if (index !== -1) { + that.defocusItem(liActive); + } + + if (e.which === keyCodes.ARROW_UP) { // up + if (index !== -1) index--; + if (index + position0 < 0) index += $items.length; + + if (!that.selectpicker.view.canHighlight[index + position0]) { + index = that.selectpicker.view.canHighlight.slice(0, index + position0).lastIndexOf(true) - position0; + if (index === -1) index = $items.length - 1; + } + } else if (e.which === keyCodes.ARROW_DOWN || downOnTab) { // down + index++; + if (index + position0 >= that.selectpicker.view.canHighlight.length) index = that.selectpicker.view.firstHighlightIndex; + + if (!that.selectpicker.view.canHighlight[index + position0]) { + index = index + 1 + that.selectpicker.view.canHighlight.slice(index + position0 + 1).indexOf(true); + } + } + + e.preventDefault(); + + var liActiveIndex = position0 + index; + + if (e.which === keyCodes.ARROW_UP) { // up + // scroll to bottom and highlight last option + if (position0 === 0 && index === $items.length - 1) { + that.$menuInner[0].scrollTop = that.$menuInner[0].scrollHeight; + + liActiveIndex = that.selectpicker.current.elements.length - 1; + } else { + activeLi = that.selectpicker.current.data[liActiveIndex]; + offset = activeLi.position - activeLi.height; + + updateScroll = offset < scrollTop; + } + } else if (e.which === keyCodes.ARROW_DOWN || downOnTab) { // down + // scroll to top and highlight first option + if (index === that.selectpicker.view.firstHighlightIndex) { + that.$menuInner[0].scrollTop = 0; + + liActiveIndex = that.selectpicker.view.firstHighlightIndex; + } else { + activeLi = that.selectpicker.current.data[liActiveIndex]; + offset = activeLi.position - that.sizeInfo.menuInnerHeight; + + updateScroll = offset > scrollTop; + } + } + + liActive = that.selectpicker.current.elements[liActiveIndex]; + + that.activeIndex = that.selectpicker.current.data[liActiveIndex].index; + + that.focusItem(liActive); + + that.selectpicker.view.currentActive = liActive; + + if (updateScroll) that.$menuInner[0].scrollTop = offset; + + if (that.options.liveSearch) { + that.$searchbox.trigger('focus'); + } else { + $this.trigger('focus'); + } + } else if ( + (!$this.is('input') && !REGEXP_TAB_OR_ESCAPE.test(e.which)) || + (e.which === keyCodes.SPACE && that.selectpicker.keydown.keyHistory) + ) { + var searchMatch, + matches = [], + keyHistory; + + e.preventDefault(); + + that.selectpicker.keydown.keyHistory += keyCodeMap[e.which]; + + if (that.selectpicker.keydown.resetKeyHistory.cancel) clearTimeout(that.selectpicker.keydown.resetKeyHistory.cancel); + that.selectpicker.keydown.resetKeyHistory.cancel = that.selectpicker.keydown.resetKeyHistory.start(); + + keyHistory = that.selectpicker.keydown.keyHistory; + + // if all letters are the same, set keyHistory to just the first character when searching + if (/^(.)\1+$/.test(keyHistory)) { + keyHistory = keyHistory.charAt(0); + } + + // find matches + for (var i = 0; i < that.selectpicker.current.data.length; i++) { + var li = that.selectpicker.current.data[i], + hasMatch; + + hasMatch = stringSearch(li, keyHistory, 'startsWith', true); + + if (hasMatch && that.selectpicker.view.canHighlight[i]) { + matches.push(li.index); + } + } + + if (matches.length) { + var matchIndex = 0; + + $items.removeClass('active').find('a').removeClass('active'); + + // either only one key has been pressed or they are all the same key + if (keyHistory.length === 1) { + matchIndex = matches.indexOf(that.activeIndex); + + if (matchIndex === -1 || matchIndex === matches.length - 1) { + matchIndex = 0; + } else { + matchIndex++; + } + } + + searchMatch = matches[matchIndex]; + + activeLi = that.selectpicker.main.data[searchMatch]; + + if (scrollTop - activeLi.position > 0) { + offset = activeLi.position - activeLi.height; + updateScroll = true; + } else { + offset = activeLi.position - that.sizeInfo.menuInnerHeight; + // if the option is already visible at the current scroll position, just keep it the same + updateScroll = activeLi.position > scrollTop + that.sizeInfo.menuInnerHeight; + } + + liActive = that.selectpicker.main.elements[searchMatch]; + + that.activeIndex = matches[matchIndex]; + + that.focusItem(liActive); + + if (liActive) liActive.firstChild.focus(); + + if (updateScroll) that.$menuInner[0].scrollTop = offset; + + $this.trigger('focus'); + } + } + + // Select focused option if "Enter", "Spacebar" or "Tab" (when selectOnTab is true) are pressed inside the menu. + if ( + isActive && + ( + (e.which === keyCodes.SPACE && !that.selectpicker.keydown.keyHistory) || + e.which === keyCodes.ENTER || + (e.which === keyCodes.TAB && that.options.selectOnTab) + ) + ) { + if (e.which !== keyCodes.SPACE) e.preventDefault(); + + if (!that.options.liveSearch || e.which !== keyCodes.SPACE) { + that.$menuInner.find('.active a').trigger('click', true); // retain active class + $this.trigger('focus'); + + if (!that.options.liveSearch) { + // Prevent screen from scrolling if the user hits the spacebar + e.preventDefault(); + // Fixes spacebar selection of dropdown items in FF & IE + $(document).data('spaceSelect', true); + } + } + } + }, + + mobile: function () { + // ensure mobile is set to true if mobile function is called after init + this.options.mobile = true; + this.$element[0].classList.add('mobile-device'); + }, + + refresh: function () { + // update options if data attributes have been changed + var config = $.extend({}, this.options, this.$element.data()); + this.options = config; + + this.checkDisabled(); + this.buildData(); + this.setStyle(); + this.render(); + this.buildList(); + this.setWidth(); + + this.setSize(true); + + this.$element.trigger('refreshed' + EVENT_KEY); + }, + + hide: function () { + this.$newElement.hide(); + }, + + show: function () { + this.$newElement.show(); + }, + + remove: function () { + this.$newElement.remove(); + this.$element.remove(); + }, + + destroy: function () { + this.$newElement.before(this.$element).remove(); + + if (this.$bsContainer) { + this.$bsContainer.remove(); + } else { + this.$menu.remove(); + } + + if (this.selectpicker.view.titleOption && this.selectpicker.view.titleOption.parentNode) { + this.selectpicker.view.titleOption.parentNode.removeChild(this.selectpicker.view.titleOption); + } + + this.$element + .off(EVENT_KEY) + .removeData('selectpicker') + .removeClass('bs-select-hidden selectpicker'); + + $(window).off(EVENT_KEY + '.' + this.selectId); + } + }; + + // SELECTPICKER PLUGIN DEFINITION + // ============================== + function Plugin (option) { + // get the args of the outer function.. + var args = arguments; + // The arguments of the function are explicitly re-defined from the argument list, because the shift causes them + // to get lost/corrupted in android 2.3 and IE9 #715 #775 + var _option = option; + + [].shift.apply(args); + + // if the version was not set successfully + if (!version.success) { + // try to retreive it again + try { + version.full = ($.fn.dropdown.Constructor.VERSION || '').split(' ')[0].split('.'); + } catch (err) { + // fall back to use BootstrapVersion if set + if (Selectpicker.BootstrapVersion) { + version.full = Selectpicker.BootstrapVersion.split(' ')[0].split('.'); + } else { + version.full = [version.major, '0', '0']; + + console.warn( + 'There was an issue retrieving Bootstrap\'s version. ' + + 'Ensure Bootstrap is being loaded before bootstrap-select and there is no namespace collision. ' + + 'If loading Bootstrap asynchronously, the version may need to be manually specified via $.fn.selectpicker.Constructor.BootstrapVersion.', + err + ); + } + } + + version.major = version.full[0]; + version.success = true; + } + + if (version.major === '4') { + // some defaults need to be changed if using Bootstrap 4 + // check to see if they have already been manually changed before forcing them to update + var toUpdate = []; + + if (Selectpicker.DEFAULTS.style === classNames.BUTTONCLASS) toUpdate.push({ name: 'style', className: 'BUTTONCLASS' }); + if (Selectpicker.DEFAULTS.iconBase === classNames.ICONBASE) toUpdate.push({ name: 'iconBase', className: 'ICONBASE' }); + if (Selectpicker.DEFAULTS.tickIcon === classNames.TICKICON) toUpdate.push({ name: 'tickIcon', className: 'TICKICON' }); + + classNames.DIVIDER = 'dropdown-divider'; + classNames.SHOW = 'show'; + classNames.BUTTONCLASS = 'btn-light'; + classNames.POPOVERHEADER = 'popover-header'; + classNames.ICONBASE = ''; + classNames.TICKICON = 'bs-ok-default'; + + for (var i = 0; i < toUpdate.length; i++) { + var option = toUpdate[i]; + Selectpicker.DEFAULTS[option.name] = classNames[option.className]; + } + } + + var value; + var chain = this.each(function () { + var $this = $(this); + if ($this.is('select')) { + var data = $this.data('selectpicker'), + options = typeof _option == 'object' && _option; + + if (!data) { + var dataAttributes = $this.data(); + + for (var dataAttr in dataAttributes) { + if (Object.prototype.hasOwnProperty.call(dataAttributes, dataAttr) && $.inArray(dataAttr, DISALLOWED_ATTRIBUTES) !== -1) { + delete dataAttributes[dataAttr]; + } + } + + var config = $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, dataAttributes, options); + config.template = $.extend({}, Selectpicker.DEFAULTS.template, ($.fn.selectpicker.defaults ? $.fn.selectpicker.defaults.template : {}), dataAttributes.template, options.template); + $this.data('selectpicker', (data = new Selectpicker(this, config))); + } else if (options) { + for (var i in options) { + if (Object.prototype.hasOwnProperty.call(options, i)) { + data.options[i] = options[i]; + } + } + } + + if (typeof _option == 'string') { + if (data[_option] instanceof Function) { + value = data[_option].apply(data, args); + } else { + value = data.options[_option]; + } + } + } + }); + + if (typeof value !== 'undefined') { + // noinspection JSUnusedAssignment + return value; + } else { + return chain; + } + } + + var old = $.fn.selectpicker; + $.fn.selectpicker = Plugin; + $.fn.selectpicker.Constructor = Selectpicker; + + // SELECTPICKER NO CONFLICT + // ======================== + $.fn.selectpicker.noConflict = function () { + $.fn.selectpicker = old; + return this; + }; + + // get Bootstrap's keydown event handler for either Bootstrap 4 or Bootstrap 3 + function keydownHandler () { + if ($.fn.dropdown) { + // wait to define until function is called in case Bootstrap isn't loaded yet + var bootstrapKeydown = $.fn.dropdown.Constructor._dataApiKeydownHandler || $.fn.dropdown.Constructor.prototype.keydown; + return bootstrapKeydown.apply(this, arguments); + } + } + + $(document) + .off('keydown.bs.dropdown.data-api') + .on('keydown.bs.dropdown.data-api', ':not(.bootstrap-select) > [data-toggle="dropdown"]', keydownHandler) + .on('keydown.bs.dropdown.data-api', ':not(.bootstrap-select) > .dropdown-menu', keydownHandler) + .on('keydown' + EVENT_KEY, '.bootstrap-select [data-toggle="dropdown"], .bootstrap-select [role="listbox"], .bootstrap-select .bs-searchbox input', Selectpicker.prototype.keydown) + .on('focusin.modal', '.bootstrap-select [data-toggle="dropdown"], .bootstrap-select [role="listbox"], .bootstrap-select .bs-searchbox input', function (e) { + e.stopPropagation(); + }); + + // SELECTPICKER DATA-API + // ===================== + $(window).on('load' + EVENT_KEY + '.data-api', function () { + $('.selectpicker').each(function () { + var $selectpicker = $(this); + Plugin.call($selectpicker, $selectpicker.data()); + }) + }); +})(jQuery); + + +})); diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.min.css b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.min.css new file mode 100644 index 000000000..8d0f049c8 --- /dev/null +++ b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.min.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap-select v1.13.18 (https://developer.snapappointments.com/bootstrap-select) + * + * Copyright 2012-2020 SnapAppointments, LLC + * Licensed under MIT (https://github.com/snapappointments/bootstrap-select/blob/master/LICENSE) + */@-webkit-keyframes bs-notify-fadeOut{0%{opacity:.9}100%{opacity:0}}@-o-keyframes bs-notify-fadeOut{0%{opacity:.9}100%{opacity:0}}@keyframes bs-notify-fadeOut{0%{opacity:.9}100%{opacity:0}}.bootstrap-select>select.bs-select-hidden,select.bs-select-hidden,select.selectpicker{display:none!important}.bootstrap-select{width:220px\0;vertical-align:middle}.bootstrap-select>.dropdown-toggle{position:relative;width:100%;text-align:right;white-space:nowrap;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.bootstrap-select>.dropdown-toggle:after{margin-top:-1px}.bootstrap-select>.dropdown-toggle.bs-placeholder,.bootstrap-select>.dropdown-toggle.bs-placeholder:active,.bootstrap-select>.dropdown-toggle.bs-placeholder:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder:hover{color:#999}.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-danger,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-danger:active,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-danger:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-danger:hover,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-dark,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-dark:active,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-dark:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-dark:hover,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-info,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-info:active,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-info:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-info:hover,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-primary,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-primary:active,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-primary:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-primary:hover,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-secondary,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-secondary:active,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-secondary:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-secondary:hover,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-success,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-success:active,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-success:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-success:hover{color:rgba(255,255,255,.5)}.bootstrap-select>select{position:absolute!important;bottom:0;left:50%;display:block!important;width:.5px!important;height:100%!important;padding:0!important;opacity:0!important;border:none;z-index:0!important}.bootstrap-select>select.mobile-device{top:0;left:0;display:block!important;width:100%!important;z-index:2!important}.bootstrap-select.is-invalid .dropdown-toggle,.error .bootstrap-select .dropdown-toggle,.has-error .bootstrap-select .dropdown-toggle,.was-validated .bootstrap-select select:invalid+.dropdown-toggle{border-color:#b94a48}.bootstrap-select.is-valid .dropdown-toggle,.was-validated .bootstrap-select select:valid+.dropdown-toggle{border-color:#28a745}.bootstrap-select.fit-width{width:auto!important}.bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn){width:220px}.bootstrap-select .dropdown-toggle:focus,.bootstrap-select>select.mobile-device:focus+.dropdown-toggle{outline:thin dotted #333!important;outline:5px auto -webkit-focus-ring-color!important;outline-offset:-2px}.bootstrap-select.form-control{margin-bottom:0;padding:0;border:none;height:auto}:not(.input-group)>.bootstrap-select.form-control:not([class*=col-]){width:100%}.bootstrap-select.form-control.input-group-btn{float:none;z-index:auto}.form-inline .bootstrap-select,.form-inline .bootstrap-select.form-control:not([class*=col-]){width:auto}.bootstrap-select:not(.input-group-btn),.bootstrap-select[class*=col-]{float:none;display:inline-block;margin-left:0}.bootstrap-select.dropdown-menu-right,.bootstrap-select[class*=col-].dropdown-menu-right,.row .bootstrap-select[class*=col-].dropdown-menu-right{float:right}.form-group .bootstrap-select,.form-horizontal .bootstrap-select,.form-inline .bootstrap-select{margin-bottom:0}.form-group-lg .bootstrap-select.form-control,.form-group-sm .bootstrap-select.form-control{padding:0}.form-group-lg .bootstrap-select.form-control .dropdown-toggle,.form-group-sm .bootstrap-select.form-control .dropdown-toggle{height:100%;font-size:inherit;line-height:inherit;border-radius:inherit}.bootstrap-select.form-control-lg .dropdown-toggle,.bootstrap-select.form-control-sm .dropdown-toggle{font-size:inherit;line-height:inherit;border-radius:inherit}.bootstrap-select.form-control-sm .dropdown-toggle{padding:.25rem .5rem}.bootstrap-select.form-control-lg .dropdown-toggle{padding:.5rem 1rem}.form-inline .bootstrap-select .form-control{width:100%}.bootstrap-select.disabled,.bootstrap-select>.disabled{cursor:not-allowed}.bootstrap-select.disabled:focus,.bootstrap-select>.disabled:focus{outline:0!important}.bootstrap-select.bs-container{position:absolute;top:0;left:0;height:0!important;padding:0!important}.bootstrap-select.bs-container .dropdown-menu{z-index:1060}.bootstrap-select .dropdown-toggle .filter-option{position:static;top:0;left:0;float:left;height:100%;width:100%;text-align:left;overflow:hidden;-webkit-box-flex:0;-webkit-flex:0 1 auto;-ms-flex:0 1 auto;flex:0 1 auto}.bs3.bootstrap-select .dropdown-toggle .filter-option{padding-right:inherit}.input-group .bs3-has-addon.bootstrap-select .dropdown-toggle .filter-option{position:absolute;padding-top:inherit;padding-bottom:inherit;padding-left:inherit;float:none}.input-group .bs3-has-addon.bootstrap-select .dropdown-toggle .filter-option .filter-option-inner{padding-right:inherit}.bootstrap-select .dropdown-toggle .filter-option-inner-inner{overflow:hidden}.bootstrap-select .dropdown-toggle .filter-expand{width:0!important;float:left;opacity:0!important;overflow:hidden}.bootstrap-select .dropdown-toggle .caret{position:absolute;top:50%;right:12px;margin-top:-2px;vertical-align:middle}.input-group .bootstrap-select.form-control .dropdown-toggle{border-radius:inherit}.bootstrap-select[class*=col-] .dropdown-toggle{width:100%}.bootstrap-select .dropdown-menu{min-width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select .dropdown-menu>.inner:focus{outline:0!important}.bootstrap-select .dropdown-menu.inner{position:static;float:none;border:0;padding:0;margin:0;border-radius:0;-webkit-box-shadow:none;box-shadow:none}.bootstrap-select .dropdown-menu li{position:relative}.bootstrap-select .dropdown-menu li.active small{color:rgba(255,255,255,.5)!important}.bootstrap-select .dropdown-menu li.disabled a{cursor:not-allowed}.bootstrap-select .dropdown-menu li a{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.bootstrap-select .dropdown-menu li a.opt{position:relative;padding-left:2.25em}.bootstrap-select .dropdown-menu li a span.check-mark{display:none}.bootstrap-select .dropdown-menu li a span.text{display:inline-block}.bootstrap-select .dropdown-menu li small{padding-left:.5em}.bootstrap-select .dropdown-menu .notify{position:absolute;bottom:5px;width:96%;margin:0 2%;min-height:26px;padding:3px 5px;background:#f5f5f5;border:1px solid #e3e3e3;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05);pointer-events:none;opacity:.9;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select .dropdown-menu .notify.fadeOut{-webkit-animation:.3s linear 750ms forwards bs-notify-fadeOut;-o-animation:.3s linear 750ms forwards bs-notify-fadeOut;animation:.3s linear 750ms forwards bs-notify-fadeOut}.bootstrap-select .no-results{padding:3px;background:#f5f5f5;margin:0 5px;white-space:nowrap}.bootstrap-select.fit-width .dropdown-toggle .filter-option{position:static;display:inline;padding:0}.bootstrap-select.fit-width .dropdown-toggle .filter-option-inner,.bootstrap-select.fit-width .dropdown-toggle .filter-option-inner-inner{display:inline}.bootstrap-select.fit-width .dropdown-toggle .bs-caret:before{content:'\00a0'}.bootstrap-select.fit-width .dropdown-toggle .caret{position:static;top:auto;margin-top:-1px}.bootstrap-select.show-tick .dropdown-menu .selected span.check-mark{position:absolute;display:inline-block;right:15px;top:5px}.bootstrap-select.show-tick .dropdown-menu li a span.text{margin-right:34px}.bootstrap-select .bs-ok-default:after{content:'';display:block;width:.5em;height:1em;border-style:solid;border-width:0 .26em .26em 0;-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.bootstrap-select.show-menu-arrow.open>.dropdown-toggle,.bootstrap-select.show-menu-arrow.show>.dropdown-toggle{z-index:1061}.bootstrap-select.show-menu-arrow .dropdown-toggle .filter-option:before{content:'';border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid rgba(204,204,204,.2);position:absolute;bottom:-4px;left:9px;display:none}.bootstrap-select.show-menu-arrow .dropdown-toggle .filter-option:after{content:'';border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;bottom:-4px;left:10px;display:none}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle .filter-option:before{bottom:auto;top:-4px;border-top:7px solid rgba(204,204,204,.2);border-bottom:0}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle .filter-option:after{bottom:auto;top:-4px;border-top:6px solid #fff;border-bottom:0}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle .filter-option:before{right:12px;left:auto}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle .filter-option:after{right:13px;left:auto}.bootstrap-select.show-menu-arrow.open>.dropdown-toggle .filter-option:after,.bootstrap-select.show-menu-arrow.open>.dropdown-toggle .filter-option:before,.bootstrap-select.show-menu-arrow.show>.dropdown-toggle .filter-option:after,.bootstrap-select.show-menu-arrow.show>.dropdown-toggle .filter-option:before{display:block}.bs-actionsbox,.bs-donebutton,.bs-searchbox{padding:4px 8px}.bs-actionsbox{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bs-actionsbox .btn-group button{width:50%}.bs-donebutton{float:left;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bs-donebutton .btn-group button{width:100%}.bs-searchbox+.bs-actionsbox{padding:0 8px 4px}.bs-searchbox .form-control{margin-bottom:0;width:100%;float:none} \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.min.js b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.min.js new file mode 100644 index 000000000..46cf10e9d --- /dev/null +++ b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.min.js @@ -0,0 +1,8 @@ +/*! + * Bootstrap-select v1.13.18 (https://developer.snapappointments.com/bootstrap-select) + * + * Copyright 2012-2020 SnapAppointments, LLC + * Licensed under MIT (https://github.com/snapappointments/bootstrap-select/blob/master/LICENSE) + */ + +!function(e,t){void 0===e&&void 0!==window&&(e=window),"function"==typeof define&&define.amd?define(["jquery"],function(e){return t(e)}):"object"==typeof module&&module.exports?module.exports=t(require("jquery")):t(e.jQuery)}(this,function(e){!function(P){"use strict";var d=["sanitize","whiteList","sanitizeFn"],r=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],e={"*":["class","dir","id","lang","role","tabindex","style",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},l=/^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi,a=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i;function v(e,t){var i=e.nodeName.toLowerCase();if(-1!==P.inArray(i,t))return-1===P.inArray(i,r)||Boolean(e.nodeValue.match(l)||e.nodeValue.match(a));for(var s=P(t).filter(function(e,t){return t instanceof RegExp}),n=0,o=s.length;n]+>/g,"")),s&&(a=w(a)),a=a.toUpperCase(),o="contains"===i?0<=a.indexOf(t):a.startsWith(t)))break}return o}function N(e){return parseInt(e,10)||0}P.fn.triggerNative=function(e){var t,i=this[0];i.dispatchEvent?(u?t=new Event(e,{bubbles:!0}):(t=document.createEvent("Event")).initEvent(e,!0,!1),i.dispatchEvent(t)):i.fireEvent?((t=document.createEventObject()).eventType=e,i.fireEvent("on"+e,t)):this.trigger(e)};var f={"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss","\u0100":"A","\u0102":"A","\u0104":"A","\u0101":"a","\u0103":"a","\u0105":"a","\u0106":"C","\u0108":"C","\u010a":"C","\u010c":"C","\u0107":"c","\u0109":"c","\u010b":"c","\u010d":"c","\u010e":"D","\u0110":"D","\u010f":"d","\u0111":"d","\u0112":"E","\u0114":"E","\u0116":"E","\u0118":"E","\u011a":"E","\u0113":"e","\u0115":"e","\u0117":"e","\u0119":"e","\u011b":"e","\u011c":"G","\u011e":"G","\u0120":"G","\u0122":"G","\u011d":"g","\u011f":"g","\u0121":"g","\u0123":"g","\u0124":"H","\u0126":"H","\u0125":"h","\u0127":"h","\u0128":"I","\u012a":"I","\u012c":"I","\u012e":"I","\u0130":"I","\u0129":"i","\u012b":"i","\u012d":"i","\u012f":"i","\u0131":"i","\u0134":"J","\u0135":"j","\u0136":"K","\u0137":"k","\u0138":"k","\u0139":"L","\u013b":"L","\u013d":"L","\u013f":"L","\u0141":"L","\u013a":"l","\u013c":"l","\u013e":"l","\u0140":"l","\u0142":"l","\u0143":"N","\u0145":"N","\u0147":"N","\u014a":"N","\u0144":"n","\u0146":"n","\u0148":"n","\u014b":"n","\u014c":"O","\u014e":"O","\u0150":"O","\u014d":"o","\u014f":"o","\u0151":"o","\u0154":"R","\u0156":"R","\u0158":"R","\u0155":"r","\u0157":"r","\u0159":"r","\u015a":"S","\u015c":"S","\u015e":"S","\u0160":"S","\u015b":"s","\u015d":"s","\u015f":"s","\u0161":"s","\u0162":"T","\u0164":"T","\u0166":"T","\u0163":"t","\u0165":"t","\u0167":"t","\u0168":"U","\u016a":"U","\u016c":"U","\u016e":"U","\u0170":"U","\u0172":"U","\u0169":"u","\u016b":"u","\u016d":"u","\u016f":"u","\u0171":"u","\u0173":"u","\u0174":"W","\u0175":"w","\u0176":"Y","\u0177":"y","\u0178":"Y","\u0179":"Z","\u017b":"Z","\u017d":"Z","\u017a":"z","\u017c":"z","\u017e":"z","\u0132":"IJ","\u0133":"ij","\u0152":"Oe","\u0153":"oe","\u0149":"'n","\u017f":"s"},m=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,g=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\u1ab0-\\u1aff\\u1dc0-\\u1dff]","g");function b(e){return f[e]}function w(e){return(e=e.toString())&&e.replace(m,b).replace(g,"")}var I,x,y,$,S=(I={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},x="(?:"+Object.keys(I).join("|")+")",y=RegExp(x),$=RegExp(x,"g"),function(e){return e=null==e?"":""+e,y.test(e)?e.replace($,E):e});function E(e){return I[e]}var C={32:" ",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",59:";",65:"A",66:"B",67:"C",68:"D",69:"E",70:"F",71:"G",72:"H",73:"I",74:"J",75:"K",76:"L",77:"M",78:"N",79:"O",80:"P",81:"Q",82:"R",83:"S",84:"T",85:"U",86:"V",87:"W",88:"X",89:"Y",90:"Z",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9"},A=27,L=13,D=32,H=9,B=38,R=40,M={success:!1,major:"3"};try{M.full=(P.fn.dropdown.Constructor.VERSION||"").split(" ")[0].split("."),M.major=M.full[0],M.success=!0}catch(e){}var U=0,j=".bs.select",V={DISABLED:"disabled",DIVIDER:"divider",SHOW:"open",DROPUP:"dropup",MENU:"dropdown-menu",MENURIGHT:"dropdown-menu-right",MENULEFT:"dropdown-menu-left",BUTTONCLASS:"btn-default",POPOVERHEADER:"popover-title",ICONBASE:"glyphicon",TICKICON:"glyphicon-ok"},F={MENU:"."+V.MENU},_={div:document.createElement("div"),span:document.createElement("span"),i:document.createElement("i"),subtext:document.createElement("small"),a:document.createElement("a"),li:document.createElement("li"),whitespace:document.createTextNode("\xa0"),fragment:document.createDocumentFragment()};_.noResults=_.li.cloneNode(!1),_.noResults.className="no-results",_.a.setAttribute("role","option"),_.a.className="dropdown-item",_.subtext.className="text-muted",_.text=_.span.cloneNode(!1),_.text.className="text",_.checkMark=_.span.cloneNode(!1);var G=new RegExp(B+"|"+R),q=new RegExp("^"+H+"$|"+A),K={li:function(e,t,i){var s=_.li.cloneNode(!1);return e&&(1===e.nodeType||11===e.nodeType?s.appendChild(e):s.innerHTML=e),void 0!==t&&""!==t&&(s.className=t),null!=i&&s.classList.add("optgroup-"+i),s},a:function(e,t,i){var s=_.a.cloneNode(!0);return e&&(11===e.nodeType?s.appendChild(e):s.insertAdjacentHTML("beforeend",e)),void 0!==t&&""!==t&&s.classList.add.apply(s.classList,t.split(/\s+/)),i&&s.setAttribute("style",i),s},text:function(e,t){var i,s,n=_.text.cloneNode(!1);if(e.content)n.innerHTML=e.content;else{if(n.textContent=e.text,e.icon){var o=_.whitespace.cloneNode(!1);(s=(!0===t?_.i:_.span).cloneNode(!1)).className=this.options.iconBase+" "+e.icon,_.fragment.appendChild(s),_.fragment.appendChild(o)}e.subtext&&((i=_.subtext.cloneNode(!1)).textContent=e.subtext,n.appendChild(i))}if(!0===t)for(;0'},maxOptions:!1,mobile:!1,selectOnTab:!1,dropdownAlignRight:!1,windowPadding:0,virtualScroll:600,display:!1,sanitize:!0,sanitizeFn:null,whiteList:e},Y.prototype={constructor:Y,init:function(){var i=this,e=this.$element.attr("id"),t=this.$element[0],s=t.form;U++,this.selectId="bs-select-"+U,t.classList.add("bs-select-hidden"),this.multiple=this.$element.prop("multiple"),this.autofocus=this.$element.prop("autofocus"),t.classList.contains("show-tick")&&(this.options.showTick=!0),this.$newElement=this.createDropdown(),this.buildData(),this.$element.after(this.$newElement).prependTo(this.$newElement),s&&null===t.form&&(s.id||(s.id="form-"+this.selectId),t.setAttribute("form",s.id)),this.$button=this.$newElement.children("button"),this.$menu=this.$newElement.children(F.MENU),this.$menuInner=this.$menu.children(".inner"),this.$searchbox=this.$menu.find("input"),t.classList.remove("bs-select-hidden"),!0===this.options.dropdownAlignRight&&this.$menu[0].classList.add(V.MENURIGHT),void 0!==e&&this.$button.attr("data-id",e),this.checkDisabled(),this.clickListener(),this.options.liveSearch?(this.liveSearchListener(),this.focusedParent=this.$searchbox[0]):this.focusedParent=this.$menuInner[0],this.setStyle(),this.render(),this.setWidth(),this.options.container?this.selectPosition():this.$element.on("hide"+j,function(){if(i.isVirtual()){var e=i.$menuInner[0],t=e.firstChild.cloneNode(!1);e.replaceChild(t,e.firstChild),e.scrollTop=0}}),this.$menu.data("this",this),this.$newElement.data("this",this),this.options.mobile&&this.mobile(),this.$newElement.on({"hide.bs.dropdown":function(e){i.$element.trigger("hide"+j,e)},"hidden.bs.dropdown":function(e){i.$element.trigger("hidden"+j,e)},"show.bs.dropdown":function(e){i.$element.trigger("show"+j,e)},"shown.bs.dropdown":function(e){i.$element.trigger("shown"+j,e)}}),t.hasAttribute("required")&&this.$element.on("invalid"+j,function(){i.$button[0].classList.add("bs-invalid"),i.$element.on("shown"+j+".invalid",function(){i.$element.val(i.$element.val()).off("shown"+j+".invalid")}).on("rendered"+j,function(){this.validity.valid&&i.$button[0].classList.remove("bs-invalid"),i.$element.off("rendered"+j)}),i.$button.on("blur"+j,function(){i.$element.trigger("focus").trigger("blur"),i.$button.off("blur"+j)})}),setTimeout(function(){i.buildList(),i.$element.trigger("loaded"+j)})},createDropdown:function(){var e=this.multiple||this.options.showTick?" show-tick":"",t=this.multiple?' aria-multiselectable="true"':"",i="",s=this.autofocus?" autofocus":"";M.major<4&&this.$element.parent().hasClass("input-group")&&(i=" input-group-btn");var n,o="",r="",l="",a="";return this.options.header&&(o='
    '+this.options.header+"
    "),this.options.liveSearch&&(r=''),this.multiple&&this.options.actionsBox&&(l='
    "),this.multiple&&this.options.doneButton&&(a='
    "),n='",P(n)},setPositionData:function(){this.selectpicker.view.canHighlight=[],this.selectpicker.view.size=0,this.selectpicker.view.firstHighlightIndex=!1;for(var e=0;e=this.options.virtualScroll||!0===this.options.virtualScroll},createView:function(N,e,t){var A,L,D=this,i=0,H=[];if(this.selectpicker.isSearching=N,this.selectpicker.current=N?this.selectpicker.search:this.selectpicker.main,this.setPositionData(),e)if(t)i=this.$menuInner[0].scrollTop;else if(!D.multiple){var s=D.$element[0],n=(s.options[s.selectedIndex]||{}).liIndex;if("number"==typeof n&&!1!==D.options.size){var o=D.selectpicker.main.data[n],r=o&&o.position;r&&(i=r-(D.sizeInfo.menuInnerHeight+D.sizeInfo.liHeight)/2)}}function l(e,t){var i,s,n,o,r,l,a,c,d=D.selectpicker.current.elements.length,h=[],p=!0,u=D.isVirtual();D.selectpicker.view.scrollTop=e,i=Math.ceil(D.sizeInfo.menuInnerHeight/D.sizeInfo.liHeight*1.5),s=Math.round(d/i)||1;for(var f=0;fd-1?0:D.selectpicker.current.data[d-1].position-D.selectpicker.current.data[D.selectpicker.view.position1-1].position,b.firstChild.style.marginTop=v+"px",b.firstChild.style.marginBottom=g+"px"):(b.firstChild.style.marginTop=0,b.firstChild.style.marginBottom=0),b.firstChild.appendChild(w),!0===u&&D.sizeInfo.hasScrollBar){var C=b.firstChild.offsetWidth;if(t&&CD.sizeInfo.selectWidth)b.firstChild.style.minWidth=D.sizeInfo.menuInnerInnerWidth+"px";else if(C>D.sizeInfo.menuInnerInnerWidth){D.$menu[0].style.minWidth=0;var O=b.firstChild.offsetWidth;O>D.sizeInfo.menuInnerInnerWidth&&(D.sizeInfo.menuInnerInnerWidth=O,b.firstChild.style.minWidth=D.sizeInfo.menuInnerInnerWidth+"px"),D.$menu[0].style.minWidth=""}}}if(D.prevActiveIndex=D.activeIndex,D.options.liveSearch){if(N&&t){var z,T=0;D.selectpicker.view.canHighlight[T]||(T=1+D.selectpicker.view.canHighlight.slice(1).indexOf(!0)),z=D.selectpicker.view.visibleElements[T],D.defocusItem(D.selectpicker.view.currentActive),D.activeIndex=(D.selectpicker.current.data[T]||{}).index,D.focusItem(z)}}else D.$menuInner.trigger("focus")}l(i,!0),this.$menuInner.off("scroll.createView").on("scroll.createView",function(e,t){D.noScroll||l(this.scrollTop,t),D.noScroll=!1}),P(window).off("resize"+j+"."+this.selectId+".createView").on("resize"+j+"."+this.selectId+".createView",function(){D.$newElement.hasClass(V.SHOW)&&l(D.$menuInner[0].scrollTop)})},focusItem:function(e,t,i){if(e){t=t||this.selectpicker.main.data[this.activeIndex];var s=e.firstChild;s&&(s.setAttribute("aria-setsize",this.selectpicker.view.size),s.setAttribute("aria-posinset",t.posinset),!0!==i&&(this.focusedParent.setAttribute("aria-activedescendant",s.id),e.classList.add("active"),s.classList.add("active")))}},defocusItem:function(e){e&&(e.classList.remove("active"),e.firstChild&&e.firstChild.classList.remove("active"))},setPlaceholder:function(){var e=this,t=!1;if(this.options.title&&!this.multiple){this.selectpicker.view.titleOption||(this.selectpicker.view.titleOption=document.createElement("option")),t=!0;var i=this.$element[0],s=!1,n=!this.selectpicker.view.titleOption.parentNode,o=i.selectedIndex,r=i.options[o],l=window.performance&&window.performance.getEntriesByType("navigation"),a=l&&l.length?"back_forward"!==l[0].type:2!==window.performance.navigation.type;n&&(this.selectpicker.view.titleOption.className="bs-title-option",this.selectpicker.view.titleOption.value="",s=!r||0===o&&!1===r.defaultSelected&&void 0===this.$element.data("selected")),!n&&0===this.selectpicker.view.titleOption.index||i.insertBefore(this.selectpicker.view.titleOption,i.firstChild),s&&a?i.selectedIndex=0:"complete"!==document.readyState&&window.addEventListener("pageshow",function(){e.selectpicker.view.displayedValue!==i.value&&e.render()})}return t},buildData:function(){var p=':not([hidden]):not([data-hidden="true"])',u=[],f=0,m=this.setPlaceholder()?1:0;this.options.hideDisabled&&(p+=":not(:disabled)");var e=this.$element[0].querySelectorAll("select > *"+p);function v(e){var t=u[u.length-1];t&&"divider"===t.type&&(t.optID||e.optID)||((e=e||{}).type="divider",u.push(e))}function g(e,t){if((t=t||{}).divider="true"===e.getAttribute("data-divider"),t.divider)v({optID:t.optID});else{var i=u.length,s=e.style.cssText,n=s?S(s):"",o=(e.className||"")+(t.optgroupClass||"");t.optID&&(o="opt "+o),t.optionClass=o.trim(),t.inlineStyle=n,t.text=e.textContent,t.content=e.getAttribute("data-content"),t.tokens=e.getAttribute("data-tokens"),t.subtext=e.getAttribute("data-subtext"),t.icon=e.getAttribute("data-icon"),e.liIndex=i,t.display=t.content||t.text,t.type="option",t.index=i,t.option=e,t.selected=!!e.selected,t.disabled=t.disabled||!!e.disabled,u.push(t)}}function t(e,t){var i=t[e],s=!(e-1 li")},render:function(){var e,t=this,i=this.$element[0],s=this.setPlaceholder()&&0===i.selectedIndex,n=O(i,this.options.hideDisabled),o=n.length,r=this.$button[0],l=r.querySelector(".filter-option-inner-inner"),a=document.createTextNode(this.options.multipleSeparator),c=_.fragment.cloneNode(!1),d=!1;if(r.classList.toggle("bs-placeholder",t.multiple?!o:!z(i,n)),t.multiple||1!==n.length||(t.selectpicker.view.displayedValue=z(i,n)),"static"===this.options.selectedTextFormat)c=K.text.call(this,{text:this.options.title},!0);else if(!1===(this.multiple&&-1!==this.options.selectedTextFormat.indexOf("count")&&1")).length&&o>e[1]||1===e.length&&2<=o))){if(!s){for(var h=0;h option"+m+", optgroup"+m+" option"+m).length,g="function"==typeof this.options.countSelectedText?this.options.countSelectedText(o,v):this.options.countSelectedText;c=K.text.call(this,{text:g.replace("{0}",o.toString()).replace("{1}",v.toString())},!0)}if(null==this.options.title&&(this.options.title=this.$element.attr("title")),c.childNodes.length||(c=K.text.call(this,{text:void 0!==this.options.title?this.options.title:this.options.noneSelectedText},!0)),r.title=c.textContent.replace(/<[^>]*>?/g,"").trim(),this.options.sanitize&&d&&W([c],t.options.whiteList,t.options.sanitizeFn),l.innerHTML="",l.appendChild(c),M.major<4&&this.$newElement[0].classList.contains("bs3-has-addon")){var b=r.querySelector(".filter-expand"),w=l.cloneNode(!0);w.className="filter-expand",b?r.replaceChild(w,b):r.appendChild(w)}this.$element.trigger("rendered"+j)},setStyle:function(e,t){var i,s=this.$button[0],n=this.$newElement[0],o=this.options.style.trim();this.$element.attr("class")&&this.$newElement.addClass(this.$element.attr("class").replace(/selectpicker|mobile-device|bs-select-hidden|validate\[.*\]/gi,"")),M.major<4&&(n.classList.add("bs3"),n.parentNode.classList&&n.parentNode.classList.contains("input-group")&&(n.previousElementSibling||n.nextElementSibling)&&(n.previousElementSibling||n.nextElementSibling).classList.contains("input-group-addon")&&n.classList.add("bs3-has-addon")),i=e?e.trim():o,"add"==t?i&&s.classList.add.apply(s.classList,i.split(" ")):"remove"==t?i&&s.classList.remove.apply(s.classList,i.split(" ")):(o&&s.classList.remove.apply(s.classList,o.split(" ")),i&&s.classList.add.apply(s.classList,i.split(" ")))},liHeight:function(e){if(e||!1!==this.options.size&&!Object.keys(this.sizeInfo).length){var t,i=_.div.cloneNode(!1),s=_.div.cloneNode(!1),n=_.div.cloneNode(!1),o=document.createElement("ul"),r=_.li.cloneNode(!1),l=_.li.cloneNode(!1),a=_.a.cloneNode(!1),c=_.span.cloneNode(!1),d=this.options.header&&0this.sizeInfo.menuExtras.vert&&l+this.sizeInfo.menuExtras.vert+50>this.sizeInfo.selectOffsetBot,!0===this.selectpicker.isSearching&&(a=this.selectpicker.dropup),this.$newElement.toggleClass(V.DROPUP,a),this.selectpicker.dropup=a),"auto"===this.options.size)n=3this.options.size){for(var b=0;bthis.sizeInfo.menuInnerHeight&&(this.sizeInfo.hasScrollBar=!0,this.sizeInfo.totalMenuWidth=this.sizeInfo.menuWidth+this.sizeInfo.scrollBarWidth),"auto"===this.options.dropdownAlignRight&&this.$menu.toggleClass(V.MENURIGHT,this.sizeInfo.selectOffsetLeft>this.sizeInfo.selectOffsetRight&&this.sizeInfo.selectOffsetRightthis.options.size&&i.off("resize"+j+"."+this.selectId+".setMenuSize scroll"+j+"."+this.selectId+".setMenuSize")}this.createView(!1,!0,e)},setWidth:function(){var i=this;"auto"===this.options.width?requestAnimationFrame(function(){i.$menu.css("min-width","0"),i.$element.on("loaded"+j,function(){i.liHeight(),i.setMenuSize();var e=i.$newElement.clone().appendTo("body"),t=e.css("width","auto").children("button").outerWidth();e.remove(),i.sizeInfo.selectWidth=Math.max(i.sizeInfo.totalMenuWidth,t),i.$newElement.css("width",i.sizeInfo.selectWidth+"px")})}):"fit"===this.options.width?(this.$menu.css("min-width",""),this.$newElement.css("width","").addClass("fit-width")):this.options.width?(this.$menu.css("min-width",""),this.$newElement.css("width",this.options.width)):(this.$menu.css("min-width",""),this.$newElement.css("width","")),this.$newElement.hasClass("fit-width")&&"fit"!==this.options.width&&this.$newElement[0].classList.remove("fit-width")},selectPosition:function(){this.$bsContainer=P('
    ');function e(e){var t={},i=r.options.display||!!P.fn.dropdown.Constructor.Default&&P.fn.dropdown.Constructor.Default.display;r.$bsContainer.addClass(e.attr("class").replace(/form-control|fit-width/gi,"")).toggleClass(V.DROPUP,e.hasClass(V.DROPUP)),s=e.offset(),l.is("body")?n={top:0,left:0}:((n=l.offset()).top+=parseInt(l.css("borderTopWidth"))-l.scrollTop(),n.left+=parseInt(l.css("borderLeftWidth"))-l.scrollLeft()),o=e.hasClass(V.DROPUP)?0:e[0].offsetHeight,(M.major<4||"static"===i)&&(t.top=s.top-n.top+o,t.left=s.left-n.left),t.width=e[0].offsetWidth,r.$bsContainer.css(t)}var s,n,o,r=this,l=P(this.options.container);this.$button.on("click.bs.dropdown.data-api",function(){r.isDisabled()||(e(r.$newElement),r.$bsContainer.appendTo(r.options.container).toggleClass(V.SHOW,!r.$button.hasClass(V.SHOW)).append(r.$menu))}),P(window).off("resize"+j+"."+this.selectId+" scroll"+j+"."+this.selectId).on("resize"+j+"."+this.selectId+" scroll"+j+"."+this.selectId,function(){r.$newElement.hasClass(V.SHOW)&&e(r.$newElement)}),this.$element.on("hide"+j,function(){r.$menu.data("height",r.$menu.height()),r.$bsContainer.detach()})},setOptionStatus:function(e){var t=this;if(t.noScroll=!1,t.selectpicker.view.visibleElements&&t.selectpicker.view.visibleElements.length)for(var i=0;i
    ');y[2]&&($=$.replace("{var}",y[2][1"+$+"
    ")),d=!1,C.$element.trigger("maxReached"+j)),g&&w&&(E.append(P("
    "+S+"
    ")),d=!1,C.$element.trigger("maxReachedGrp"+j)),setTimeout(function(){C.setSelected(r,!1)},10),E[0].classList.add("fadeOut"),setTimeout(function(){E.remove()},1050)}}}else c&&(c.selected=!1),h.selected=!0,C.setSelected(r,!0);!C.multiple||C.multiple&&1===C.options.maxOptions?C.$button.trigger("focus"):C.options.liveSearch&&C.$searchbox.trigger("focus"),d&&(!C.multiple&&a===s.selectedIndex||(T=[h.index,p.prop("selected"),l],C.$element.triggerNative("change")))}}),this.$menu.on("click","li."+V.DISABLED+" a, ."+V.POPOVERHEADER+", ."+V.POPOVERHEADER+" :not(.close)",function(e){e.currentTarget==this&&(e.preventDefault(),e.stopPropagation(),C.options.liveSearch&&!P(e.target).hasClass("close")?C.$searchbox.trigger("focus"):C.$button.trigger("focus"))}),this.$menuInner.on("click",".divider, .dropdown-header",function(e){e.preventDefault(),e.stopPropagation(),C.options.liveSearch?C.$searchbox.trigger("focus"):C.$button.trigger("focus")}),this.$menu.on("click","."+V.POPOVERHEADER+" .close",function(){C.$button.trigger("click")}),this.$searchbox.on("click",function(e){e.stopPropagation()}),this.$menu.on("click",".actions-btn",function(e){C.options.liveSearch?C.$searchbox.trigger("focus"):C.$button.trigger("focus"),e.preventDefault(),e.stopPropagation(),P(this).hasClass("bs-select-all")?C.selectAll():C.deselectAll()}),this.$button.on("focus"+j,function(e){var t=C.$element[0].getAttribute("tabindex");void 0!==t&&e.originalEvent&&e.originalEvent.isTrusted&&(this.setAttribute("tabindex",t),C.$element[0].setAttribute("tabindex",-1),C.selectpicker.view.tabindex=t)}).on("blur"+j,function(e){void 0!==C.selectpicker.view.tabindex&&e.originalEvent&&e.originalEvent.isTrusted&&(C.$element[0].setAttribute("tabindex",C.selectpicker.view.tabindex),this.setAttribute("tabindex",-1),C.selectpicker.view.tabindex=void 0)}),this.$element.on("change"+j,function(){C.render(),C.$element.trigger("changed"+j,T),T=null}).on("focus"+j,function(){C.options.mobile||C.$button[0].focus()})},liveSearchListener:function(){var u=this;this.$button.on("click.bs.dropdown.data-api",function(){u.$searchbox.val()&&(u.$searchbox.val(""),u.selectpicker.search.previousValue=void 0)}),this.$searchbox.on("click.bs.dropdown.data-api focus.bs.dropdown.data-api touchend.bs.dropdown.data-api",function(e){e.stopPropagation()}),this.$searchbox.on("input propertychange",function(){var e=u.$searchbox[0].value;if(u.selectpicker.search.elements=[],u.selectpicker.search.data=[],e){var t=[],i=e.toUpperCase(),s={},n=[],o=u._searchStyle(),r=u.options.liveSearchNormalize;r&&(i=w(i));for(var l=0;l=a.selectpicker.view.canHighlight.length&&(t=a.selectpicker.view.firstHighlightIndex),a.selectpicker.view.canHighlight[t+f]||(t=t+1+a.selectpicker.view.canHighlight.slice(t+f+1).indexOf(!0))),e.preventDefault();var m=f+t;e.which===B?0===f&&t===c.length-1?(a.$menuInner[0].scrollTop=a.$menuInner[0].scrollHeight,m=a.selectpicker.current.elements.length-1):d=(o=(n=a.selectpicker.current.data[m]).position-n.height)u+a.sizeInfo.menuInnerHeight),s=a.selectpicker.main.elements[v],a.activeIndex=b[x],a.focusItem(s),s&&s.firstChild.focus(),d&&(a.$menuInner[0].scrollTop=o),r.trigger("focus")}}i&&(e.which===D&&!a.selectpicker.keydown.keyHistory||e.which===L||e.which===H&&a.options.selectOnTab)&&(e.which!==D&&e.preventDefault(),a.options.liveSearch&&e.which===D||(a.$menuInner.find(".active a").trigger("click",!0),r.trigger("focus"),a.options.liveSearch||(e.preventDefault(),P(document).data("spaceSelect",!0))))}},mobile:function(){this.options.mobile=!0,this.$element[0].classList.add("mobile-device")},refresh:function(){var e=P.extend({},this.options,this.$element.data());this.options=e,this.checkDisabled(),this.buildData(),this.setStyle(),this.render(),this.buildList(),this.setWidth(),this.setSize(!0),this.$element.trigger("refreshed"+j)},hide:function(){this.$newElement.hide()},show:function(){this.$newElement.show()},remove:function(){this.$newElement.remove(),this.$element.remove()},destroy:function(){this.$newElement.before(this.$element).remove(),this.$bsContainer?this.$bsContainer.remove():this.$menu.remove(),this.selectpicker.view.titleOption&&this.selectpicker.view.titleOption.parentNode&&this.selectpicker.view.titleOption.parentNode.removeChild(this.selectpicker.view.titleOption),this.$element.off(j).removeData("selectpicker").removeClass("bs-select-hidden selectpicker"),P(window).off(j+"."+this.selectId)}};var J=P.fn.selectpicker;function Q(){if(P.fn.dropdown)return(P.fn.dropdown.Constructor._dataApiKeydownHandler||P.fn.dropdown.Constructor.prototype.keydown).apply(this,arguments)}P.fn.selectpicker=Z,P.fn.selectpicker.Constructor=Y,P.fn.selectpicker.noConflict=function(){return P.fn.selectpicker=J,this},P(document).off("keydown.bs.dropdown.data-api").on("keydown.bs.dropdown.data-api",':not(.bootstrap-select) > [data-toggle="dropdown"]',Q).on("keydown.bs.dropdown.data-api",":not(.bootstrap-select) > .dropdown-menu",Q).on("keydown"+j,'.bootstrap-select [data-toggle="dropdown"], .bootstrap-select [role="listbox"], .bootstrap-select .bs-searchbox input',Y.prototype.keydown).on("focusin.modal",'.bootstrap-select [data-toggle="dropdown"], .bootstrap-select [role="listbox"], .bootstrap-select .bs-searchbox input',function(e){e.stopPropagation()}),P(window).on("load"+j+".data-api",function(){P(".selectpicker").each(function(){var e=P(this);Z.call(e,e.data())})})}(e)}); \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/bootstrap-table.min.css b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/bootstrap-table.min.css new file mode 100644 index 000000000..7e150cf59 --- /dev/null +++ b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/bootstrap-table.min.css @@ -0,0 +1,6 @@ +/** + * @author zhixin wen + * version: 1.19.1 + * https://github.com/wenzhixin/bootstrap-table/ + */ +.bootstrap-table .fixed-table-toolbar::after{content:"";display:block;clear:both}.bootstrap-table .fixed-table-toolbar .bs-bars,.bootstrap-table .fixed-table-toolbar .columns,.bootstrap-table .fixed-table-toolbar .search{position:relative;margin-top:10px;margin-bottom:10px}.bootstrap-table .fixed-table-toolbar .columns .btn-group>.btn-group{display:inline-block;margin-left:-1px!important}.bootstrap-table .fixed-table-toolbar .columns .btn-group>.btn-group>.btn{border-radius:0}.bootstrap-table .fixed-table-toolbar .columns .btn-group>.btn-group:first-child>.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.bootstrap-table .fixed-table-toolbar .columns .btn-group>.btn-group:last-child>.btn{border-top-right-radius:4px;border-bottom-right-radius:4px}.bootstrap-table .fixed-table-toolbar .columns .dropdown-menu{text-align:left;max-height:300px;overflow:auto;-ms-overflow-style:scrollbar;z-index:1001}.bootstrap-table .fixed-table-toolbar .columns label{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.428571429}.bootstrap-table .fixed-table-toolbar .columns-left{margin-right:5px}.bootstrap-table .fixed-table-toolbar .columns-right{margin-left:5px}.bootstrap-table .fixed-table-toolbar .pull-right .dropdown-menu{right:0;left:auto}.bootstrap-table .fixed-table-container{position:relative;clear:both}.bootstrap-table .fixed-table-container .table{width:100%;margin-bottom:0!important}.bootstrap-table .fixed-table-container .table td,.bootstrap-table .fixed-table-container .table th{vertical-align:middle;box-sizing:border-box}.bootstrap-table .fixed-table-container .table thead th{vertical-align:bottom;padding:0;margin:0}.bootstrap-table .fixed-table-container .table thead th:focus{outline:0 solid transparent}.bootstrap-table .fixed-table-container .table thead th.detail{width:30px}.bootstrap-table .fixed-table-container .table thead th .th-inner{padding:.75rem;vertical-align:bottom;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.bootstrap-table .fixed-table-container .table thead th .sortable{cursor:pointer;background-position:right;background-repeat:no-repeat;padding-right:30px!important}.bootstrap-table .fixed-table-container .table thead th .both{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC")}.bootstrap-table .fixed-table-container .table thead th .asc{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBdqEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVoAADeemwtPcZI2wAAAABJRU5ErkJggg==")}.bootstrap-table .fixed-table-container .table thead th .desc{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWjYBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJzcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII= ")}.bootstrap-table .fixed-table-container .table tbody tr.selected td{background-color:rgba(0,0,0,.075)}.bootstrap-table .fixed-table-container .table tbody tr.no-records-found td{text-align:center}.bootstrap-table .fixed-table-container .table tbody tr .card-view{display:flex}.bootstrap-table .fixed-table-container .table tbody tr .card-view .card-view-title{font-weight:700;display:inline-block;min-width:30%;width:auto!important;text-align:left!important}.bootstrap-table .fixed-table-container .table tbody tr .card-view .card-view-value{width:100%!important}.bootstrap-table .fixed-table-container .table .bs-checkbox{text-align:center}.bootstrap-table .fixed-table-container .table .bs-checkbox label{margin-bottom:0}.bootstrap-table .fixed-table-container .table .bs-checkbox label input[type=checkbox],.bootstrap-table .fixed-table-container .table .bs-checkbox label input[type=radio]{margin:0 auto!important}.bootstrap-table .fixed-table-container .table.table-sm .th-inner{padding:.3rem}.bootstrap-table .fixed-table-container.fixed-height:not(.has-footer){border-bottom:1px solid #dee2e6}.bootstrap-table .fixed-table-container.fixed-height.has-card-view{border-top:1px solid #dee2e6;border-bottom:1px solid #dee2e6}.bootstrap-table .fixed-table-container.fixed-height .fixed-table-border{border-left:1px solid #dee2e6;border-right:1px solid #dee2e6}.bootstrap-table .fixed-table-container.fixed-height .table thead th{border-bottom:1px solid #dee2e6}.bootstrap-table .fixed-table-container.fixed-height .table-dark thead th{border-bottom:1px solid #32383e}.bootstrap-table .fixed-table-container .fixed-table-header{overflow:hidden}.bootstrap-table .fixed-table-container .fixed-table-body{overflow-x:auto;overflow-y:auto;height:100%}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading{align-items:center;background:#fff;display:flex;justify-content:center;position:absolute;bottom:0;width:100%;max-width:100%;z-index:1000;transition:visibility 0s,opacity .15s ease-in-out;opacity:0;visibility:hidden}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.open{visibility:visible;opacity:1}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap{align-items:baseline;display:flex;justify-content:center}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .loading-text{margin-right:6px}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap{align-items:center;display:flex;justify-content:center}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-dot,.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::after,.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::before{content:"";animation-duration:1.5s;animation-iteration-count:infinite;animation-name:LOADING;background:#212529;border-radius:50%;display:block;height:5px;margin:0 4px;opacity:0;width:5px}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-dot{animation-delay:.3s}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::after{animation-delay:.6s}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark{background:#212529}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-dot,.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-wrap::after,.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-wrap::before{background:#fff}.bootstrap-table .fixed-table-container .fixed-table-footer{overflow:hidden}.bootstrap-table .fixed-table-pagination::after{content:"";display:block;clear:both}.bootstrap-table .fixed-table-pagination>.pagination,.bootstrap-table .fixed-table-pagination>.pagination-detail{margin-top:10px;margin-bottom:10px}.bootstrap-table .fixed-table-pagination>.pagination-detail .pagination-info{line-height:34px;margin-right:5px}.bootstrap-table .fixed-table-pagination>.pagination-detail .page-list{display:inline-block}.bootstrap-table .fixed-table-pagination>.pagination-detail .page-list .btn-group{position:relative;display:inline-block;vertical-align:middle}.bootstrap-table .fixed-table-pagination>.pagination-detail .page-list .btn-group .dropdown-menu{margin-bottom:0}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination{margin:0}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination li.page-intermediate a{color:#c8c8c8}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination li.page-intermediate a::before{content:'\2B05'}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination li.page-intermediate a::after{content:'\27A1'}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination li.disabled a{pointer-events:none;cursor:default}.bootstrap-table.fullscreen{position:fixed;top:0;left:0;z-index:1050;width:100%!important;background:#fff;height:calc(100vh);overflow-y:scroll}.bootstrap-table.bootstrap4 .pagination-lg .page-link,.bootstrap-table.bootstrap5 .pagination-lg .page-link{padding:.5rem 1rem}.bootstrap-table.bootstrap5 .float-left{float:left}.bootstrap-table.bootstrap5 .float-right{float:right}div.fixed-table-scroll-inner{width:100%;height:200px}div.fixed-table-scroll-outer{top:0;left:0;visibility:hidden;width:200px;height:150px;overflow:hidden}@keyframes LOADING{0%{opacity:0}50%{opacity:1}to{opacity:0}} \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/bootstrap-table.min.js b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/bootstrap-table.min.js new file mode 100644 index 000000000..ac557c87a --- /dev/null +++ b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/bootstrap-table.min.js @@ -0,0 +1,6 @@ +/** + * @author zhixin wen + * version: 1.19.1 + * https://github.com/wenzhixin/bootstrap-table/ + */ +function getRememberRowIds(t,e){return $.isArray(t)?props=$.map(t,function(t){return t[e]}):props=[t[e]],props}function addRememberRow(t,e){var i=null==table.options.uniqueId?table.options.columns[1].field:table.options.uniqueId,n=getRememberRowIds(t,i);-1==$.inArray(e[i],n)&&(t[t.length]=e)}function removeRememberRow(t,e){var i=null==table.options.uniqueId?table.options.columns[1].field:table.options.uniqueId,n=getRememberRowIds(t,i),o=$.inArray(e[i],n);-1!=o&&t.splice(o,1)}!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],e):(t="undefined"!=typeof globalThis?globalThis:t||self,t.BootstrapTable=e(t.jQuery))}(this,function(t){function e(t){return t&&"object"==typeof t&&"default" in t?t:{"default":t}}function i(t){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function n(t,e){if(!(t instanceof e)){throw new TypeError("Cannot call a class as a function")}}function o(t,e){for(var i=0;it.length)&&(e=t.length);for(var i=0,n=Array(e);e>i;i++){n[i]=t[i]}return n}function p(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function g(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function v(t,e){var i;if("undefined"==typeof Symbol||null==t[Symbol.iterator]){if(Array.isArray(t)||(i=d(t))||e&&t&&"number"==typeof t.length){i&&(t=i);var n=0,o=function(){};return{s:o,n:function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,s=!0,r=!1;return{s:function(){i=t[Symbol.iterator]()},n:function(){var t=i.next();return s=t.done,t},e:function(t){r=!0,a=t},f:function(){try{s||null==i["return"]||i["return"]()}finally{if(r){throw a}}}}}function b(t,e){return e={exports:{}},t(e,e.exports),e.exports}function m(t,e){return RegExp(t,e)}var y=e(t),w="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},S=function(t){return t&&t.Math==Math&&t},x=S("object"==typeof globalThis&&globalThis)||S("object"==typeof window&&window)||S("object"==typeof self&&self)||S("object"==typeof w&&w)||function(){return this}()||Function("return this")(),k=function(t){try{return !!t()}catch(e){return !0}},O=!k(function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]}),T={}.propertyIsEnumerable,C=Object.getOwnPropertyDescriptor,P=C&&!T.call({1:2},1),I=P?function(t){var e=C(this,t);return !!e&&e.enumerable}:T,A={f:I},$=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}},R={}.toString,E=function(t){return R.call(t).slice(8,-1)},j="".split,_=k(function(){return !Object("z").propertyIsEnumerable(0)})?function(t){return"String"==E(t)?j.call(t,""):Object(t)}:Object,N=function(t){if(void 0==t){throw TypeError("Can't call method on "+t)}return t},F=function(t){return _(N(t))},D=function(t){return"object"==typeof t?null!==t:"function"==typeof t},V=function(t,e){if(!D(t)){return t}var i,n;if(e&&"function"==typeof(i=t.toString)&&!D(n=i.call(t))){return n}if("function"==typeof(i=t.valueOf)&&!D(n=i.call(t))){return n}if(!e&&"function"==typeof(i=t.toString)&&!D(n=i.call(t))){return n}throw TypeError("Can't convert object to primitive value")},B={}.hasOwnProperty,L=function(t,e){return B.call(t,e)},H=x.document,M=D(H)&&D(H.createElement),U=function(t){return M?H.createElement(t):{}},q=!O&&!k(function(){return 7!=Object.defineProperty(U("div"),"a",{get:function(){return 7}}).a}),z=Object.getOwnPropertyDescriptor,W=O?z:function(t,e){if(t=F(t),e=V(e,!0),q){try{return z(t,e)}catch(i){}}return L(t,e)?$(!A.f.call(t,e),t[e]):void 0},G={f:W},K=function(t){if(!D(t)){throw TypeError(t+" is not an object")}return t},Y=Object.defineProperty,X=O?Y:function(t,e,i){if(K(t),e=V(e,!0),K(i),q){try{return Y(t,e,i)}catch(n){}}if("get" in i||"set" in i){throw TypeError("Accessors not supported")}return"value" in i&&(t[e]=i.value),t},J={f:X},Q=O?function(t,e,i){return J.f(t,e,$(1,i))}:function(t,e,i){return t[e]=i,t},Z=function(t,e){try{Q(x,t,e)}catch(i){x[t]=e}return e},tt="__core-js_shared__",et=x[tt]||Z(tt,{}),it=et,nt=Function.toString;"function"!=typeof it.inspectSource&&(it.inspectSource=function(t){return nt.call(t)});var ot,at,st,rt=it.inspectSource,lt=x.WeakMap,ct="function"==typeof lt&&/native code/.test(rt(lt)),ht=b(function(t){(t.exports=function(t,e){return it[t]||(it[t]=void 0!==e?e:{})})("versions",[]).push({version:"3.10.1",mode:"global",copyright:"漏 2021 Denis Pushkarev (zloirock.ru)"})}),ut=0,dt=Math.random(),ft=function(t){return"Symbol("+((void 0===t?"":t)+"")+")_"+(++ut+dt).toString(36)},pt=ht("keys"),gt=function(t){return pt[t]||(pt[t]=ft(t))},vt={},bt=x.WeakMap,mt=function(t){return st(t)?at(t):ot(t,{})},yt=function(t){return function(e){var i;if(!D(e)||(i=at(e)).type!==t){throw TypeError("Incompatible receiver, "+t+" required")}return i}};if(ct){var wt=it.state||(it.state=new bt),St=wt.get,xt=wt.has,kt=wt.set;ot=function(t,e){return e.facade=t,kt.call(wt,t,e),e},at=function(t){return St.call(wt,t)||{}},st=function(t){return xt.call(wt,t)}}else{var Ot=gt("state");vt[Ot]=!0,ot=function(t,e){return e.facade=t,Q(t,Ot,e),e},at=function(t){return L(t,Ot)?t[Ot]:{}},st=function(t){return L(t,Ot)}}var Tt={set:ot,get:at,has:st,enforce:mt,getterFor:yt},Ct=b(function(t){var e=Tt.get,i=Tt.enforce,n=(String+"").split("String");(t.exports=function(t,e,o,a){var s,r=a?!!a.unsafe:!1,l=a?!!a.enumerable:!1,c=a?!!a.noTargetGet:!1;return"function"==typeof o&&("string"!=typeof e||L(o,"name")||Q(o,"name",e),s=i(o),s.source||(s.source=n.join("string"==typeof e?e:""))),t===x?void (l?t[e]=o:Z(e,o)):(r?!c&&t[e]&&(l=!0):delete t[e],void (l?t[e]=o:Q(t,e,o)))})(Function.prototype,"toString",function(){return"function"==typeof this&&e(this).source||rt(this)})}),Pt=x,It=function(t){return"function"==typeof t?t:void 0},At=function(t,e){return arguments.length<2?It(Pt[t])||It(x[t]):Pt[t]&&Pt[t][e]||x[t]&&x[t][e]},$t=Math.ceil,Rt=Math.floor,Et=function(t){return isNaN(t=+t)?0:(t>0?Rt:$t)(t)},jt=Math.min,_t=function(t){return t>0?jt(Et(t),9007199254740991):0},Nt=Math.max,Ft=Math.min,Dt=function(t,e){var i=Et(t);return 0>i?Nt(i+e,0):Ft(i,e)},Vt=function(t){return function(e,i,n){var o,a=F(e),s=_t(a.length),r=Dt(n,s);if(t&&i!=i){for(;s>r;){if(o=a[r++],o!=o){return !0}}}else{for(;s>r;r++){if((t||r in a)&&a[r]===i){return t||r||0}}}return !t&&-1}},Bt={includes:Vt(!0),indexOf:Vt(!1)},Lt=Bt.indexOf,Ht=function(t,e){var i,n=F(t),o=0,a=[];for(i in n){!L(vt,i)&&L(n,i)&&a.push(i)}for(;e.length>o;){L(n,i=e[o++])&&(~Lt(a,i)||a.push(i))}return a},Mt=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"],Ut=Mt.concat("length","prototype"),qt=Object.getOwnPropertyNames||function(t){return Ht(t,Ut)},zt={f:qt},Wt=Object.getOwnPropertySymbols,Gt={f:Wt},Kt=At("Reflect","ownKeys")||function(t){var e=zt.f(K(t)),i=Gt.f;return i?e.concat(i(t)):e},Yt=function(t,e){for(var i=Kt(e),n=J.f,o=G.f,a=0;a0&&(!a.multiline||a.multiline&&"\n"!==t[a.lastIndex-1])&&(l="(?: "+l+")",h=" "+h,c++),i=RegExp("^(?:"+l+")",r)),Pe&&(i=RegExp("^"+l+"$(?!\\s)",r)),Te&&(e=a.lastIndex),n=xe.call(s?i:a,h),s?n?(n.input=n.input.slice(c),n[0]=n[0].slice(c),n.index=a.lastIndex,a.lastIndex+=n[0].length):a.lastIndex=0:Te&&n&&(a.lastIndex=a.global?n.index+n[0].length:e),Pe&&n&&n.length>1&&ke.call(n[0],i,function(){for(o=1;o=74)&&($e=je.match(/Chrome\/(\d+)/),$e&&(Re=$e[1])));var De=Re&&+Re,Ve=!!Object.getOwnPropertySymbols&&!k(function(){return !Symbol.sham&&(Ee?38===De:De>37&&41>De)}),Be=Ve&&!Symbol.sham&&"symbol"==typeof Symbol.iterator,Le=ht("wks"),He=x.Symbol,Me=Be?He:He&&He.withoutSetter||ft,Ue=function(t){return(!L(Le,t)||!Ve&&"string"!=typeof Le[t])&&(Ve&&L(He,t)?Le[t]=He[t]:Le[t]=Me("Symbol."+t)),Le[t]},qe=Ue("species"),ze=!k(function(){var t=/./;return t.exec=function(){var t=[];return t.groups={a:"7"},t},"7"!=="".replace(t,"$")}),We=function(){return"$0"==="a".replace(/./,"$0")}(),Ge=Ue("replace"),Ke=function(){return/./[Ge]?""===/./[Ge]("a","$0"):!1}(),Ye=!k(function(){var t=/(?:)/,e=t.exec;t.exec=function(){return e.apply(this,arguments)};var i="ab".split(t);return 2!==i.length||"a"!==i[0]||"b"!==i[1]}),Xe=function(t,e,i,n){var o=Ue(t),a=!k(function(){var e={};return e[o]=function(){return 7},7!=""[t](e)}),s=a&&!k(function(){var e=!1,i=/a/;return"split"===t&&(i={},i.constructor={},i.constructor[qe]=function(){return i},i.flags="",i[o]=/./[o]),i.exec=function(){return e=!0,null},i[o](""),!e});if(!a||!s||"replace"===t&&(!ze||!We||Ke)||"split"===t&&!Ye){var r=/./[o],l=i(o,""[t],function(t,e,i,n,o){return e.exec===RegExp.prototype.exec?a&&!o?{done:!0,value:r.call(e,i,n)}:{done:!0,value:t.call(i,e,n)}:{done:!1}},{REPLACE_KEEPS_$0:We,REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE:Ke}),c=l[0],h=l[1];Ct(String.prototype,t,c),Ct(RegExp.prototype,o,2==e?function(t,e){return h.call(t,this,e)}:function(t){return h.call(t,this)})}n&&Q(RegExp.prototype[o],"sham",!0)},Je=Ue("match"),Qe=function(t){var e;return D(t)&&(void 0!==(e=t[Je])?!!e:"RegExp"==E(t))},Ze=function(t){if("function"!=typeof t){throw TypeError(t+" is not a function")}return t},ti=Ue("species"),ei=function(t,e){var i,n=K(t).constructor;return void 0===n||void 0==(i=K(n)[ti])?e:Ze(i)},ii=function(t){return function(e,i){var n,o,a=N(e)+"",s=Et(i),r=a.length;return 0>s||s>=r?t?"":void 0:(n=a.charCodeAt(s),55296>n||n>56319||s+1===r||(o=a.charCodeAt(s+1))<56320||o>57343?t?a.charAt(s):n:t?a.slice(s,s+2):(n-55296<<10)+(o-56320)+65536)}},ni={codeAt:ii(!1),charAt:ii(!0)},oi=ni.charAt,ai=function(t,e,i){return e+(i?oi(t,e).length:1)},si=function(t,e){var i=t.exec;if("function"==typeof i){var n=i.call(t,e);if("object"!=typeof n){throw TypeError("RegExp exec method returned something other than an Object or null")}return n}if("RegExp"!==E(t)){throw TypeError("RegExp#exec called on incompatible receiver")}return Ae.call(t,e)},ri=Se.UNSUPPORTED_Y,li=[].push,ci=Math.min,hi=4294967295;Xe("split",2,function(t,e,i){var n;return n="c"=="abbc".split(/(b)*/)[1]||4!="test".split(/(?:)/,-1).length||2!="ab".split(/(?:ab)*/).length||4!=".".split(/(.?)(.?)/).length||".".split(/()()/).length>1||"".split(/.?/).length?function(t,i){var n=N(this)+"",o=void 0===i?hi:i>>>0;if(0===o){return[]}if(void 0===t){return[n]}if(!Qe(t)){return e.call(n,t,o)}for(var a,s,r,l=[],c=(t.ignoreCase?"i":"")+(t.multiline?"m":"")+(t.unicode?"u":"")+(t.sticky?"y":""),h=0,u=RegExp(t.source,c+"g");(a=Ae.call(u,n))&&(s=u.lastIndex,!(s>h&&(l.push(n.slice(h,a.index)),a.length>1&&a.index=o)));){u.lastIndex===a.index&&u.lastIndex++}return h===n.length?(r||!u.test(""))&&l.push(""):l.push(n.slice(h)),l.length>o?l.slice(0,o):l}:"0".split(void 0,0).length?function(t,i){return void 0===t&&0===i?[]:e.call(this,t,i)}:e,[function(e,i){var o=N(this),a=void 0==e?void 0:e[t];return void 0!==a?a.call(e,o,i):n.call(o+"",e,i)},function(t,o){var a=i(n,t,this,o,n!==e);if(a.done){return a.value}var s=K(t),r=this+"",l=ei(s,RegExp),c=s.unicode,h=(s.ignoreCase?"i":"")+(s.multiline?"m":"")+(s.unicode?"u":"")+(ri?"g":"y"),u=new l(ri?"^(?:"+s.source+")":s,h),d=void 0===o?hi:o>>>0;if(0===d){return[]}if(0===r.length){return null===si(u,r)?[r]:[]}for(var f=0,p=0,g=[];ps;){i=o[s++],(!O||di.call(n,i))&&r.push(t?[i,n[i]]:n[i])}return r}},pi={entries:fi(!0),values:fi(!1)},gi=pi.entries;oe({target:"Object",stat:!0},{entries:function(t){return gi(t)}});var vi,bi=O?Object.defineProperties:function(t,e){K(t);for(var i,n=ui(e),o=n.length,a=0;o>a;){J.f(t,i=n[a++],e[i])}return t},mi=At("document","documentElement"),yi=">",wi="<",Si="prototype",xi="script",ki=gt("IE_PROTO"),Oi=function(){},Ti=function(t){return wi+xi+yi+t+wi+"/"+xi+yi},Ci=function(t){t.write(Ti("")),t.close();var e=t.parentWindow.Object;return t=null,e},Pi=function(){var t,e=U("iframe"),i="java"+xi+":";return e.style.display="none",mi.appendChild(e),e.src=i+"",t=e.contentWindow.document,t.open(),t.write(Ti("document.F=Object")),t.close(),t.F},Ii=function(){try{vi=document.domain&&new ActiveXObject("htmlfile")}catch(t){}Ii=vi?Ci(vi):Pi();for(var e=Mt.length;e--;){delete Ii[Si][Mt[e]]}return Ii()};vt[ki]=!0;var Ai=Object.create||function(t,e){var i;return null!==t?(Oi[Si]=K(t),i=new Oi,Oi[Si]=null,i[ki]=t):i=Ii(),void 0===e?i:bi(i,e)},$i=Ue("unscopables"),Ri=Array.prototype;void 0==Ri[$i]&&J.f(Ri,$i,{configurable:!0,value:Ai(null)});var Ei=function(t){Ri[$i][t]=!0},ji=Bt.includes;oe({target:"Array",proto:!0},{includes:function(t){return ji(this,t,arguments.length>1?arguments[1]:void 0)}}),Ei("includes");var _i=Array.isArray||function(t){return"Array"==E(t)},Ni=function(t){return Object(N(t))},Fi=function(t,e,i){var n=V(e);n in t?J.f(t,n,$(0,i)):t[n]=i},Di=Ue("species"),Vi=function(t,e){var i;return _i(t)&&(i=t.constructor,"function"!=typeof i||i!==Array&&!_i(i.prototype)?D(i)&&(i=i[Di],null===i&&(i=void 0)):i=void 0),new (void 0===i?Array:i)(0===e?0:e)},Bi=Ue("species"),Li=function(t){return De>=51||!k(function(){var e=[],i=e.constructor={};return i[Bi]=function(){return{foo:1}},1!==e[t](Boolean).foo})},Hi=Ue("isConcatSpreadable"),Mi=9007199254740991,Ui="Maximum allowed index exceeded",qi=De>=51||!k(function(){var t=[];return t[Hi]=!1,t.concat()[0]!==t}),zi=Li("concat"),Wi=function(t){if(!D(t)){return !1}var e=t[Hi];return void 0!==e?!!e:_i(t)},Gi=!qi||!zi;oe({target:"Array",proto:!0,forced:Gi},{concat:function(t){var e,i,n,o,a,s=Ni(this),r=Vi(s,0),l=0;for(e=-1,n=arguments.length;n>e;e++){if(a=-1===e?s:arguments[e],Wi(a)){if(o=_t(a.length),l+o>Mi){throw TypeError(Ui)}for(i=0;o>i;i++,l++){i in a&&Fi(r,l,a[i])}}else{if(l>=Mi){throw TypeError(Ui)}Fi(r,l++,a)}}return r.length=l,r}});var Ki=function(t,e,i){if(Ze(t),void 0===e){return t}switch(i){case 0:return function(){return t.call(e)};case 1:return function(i){return t.call(e,i)};case 2:return function(i,n){return t.call(e,i,n)};case 3:return function(i,n,o){return t.call(e,i,n,o)}}return function(){return t.apply(e,arguments)}},Yi=[].push,Xi=function(t){var e=1==t,i=2==t,n=3==t,o=4==t,a=6==t,s=7==t,r=5==t||a;return function(l,c,h,u){for(var d,f,p=Ni(l),g=_(p),v=Ki(c,h,3),b=_t(g.length),m=0,y=u||Vi,w=e?y(l,b):i||s?y(l,0):void 0;b>m;m++){if((r||m in g)&&(d=g[m],f=v(d,m,p),t)){if(e){w[m]=f}else{if(f){switch(t){case 3:return !0;case 5:return d;case 6:return m;case 2:Yi.call(w,d)}}else{switch(t){case 4:return !1;case 7:Yi.call(w,d)}}}}}return a?-1:n||o?o:w}},Ji={forEach:Xi(0),map:Xi(1),filter:Xi(2),some:Xi(3),every:Xi(4),find:Xi(5),findIndex:Xi(6),filterOut:Xi(7)},Qi=Ji.find,Zi="find",tn=!0;Zi in []&&Array(1)[Zi](function(){tn=!1}),oe({target:"Array",proto:!0,forced:tn},{find:function(t){return Qi(this,t,arguments.length>1?arguments[1]:void 0)}}),Ei(Zi);var en=function(t){if(Qe(t)){throw TypeError("The method doesn't accept regular expressions")}return t},nn=Ue("match"),on=function(t){var e=/./;try{"/./"[t](e)}catch(i){try{return e[nn]=!1,"/./"[t](e)}catch(n){}}return !1};oe({target:"String",proto:!0,forced:!on("includes")},{includes:function(t){return !!~(N(this)+"").indexOf(en(t),arguments.length>1?arguments[1]:void 0)}});var an={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0},sn=Ji.forEach,rn=pe("forEach"),ln=rn?[].forEach:function(t){return sn(this,t,arguments.length>1?arguments[1]:void 0)};for(var cn in an){var hn=x[cn],un=hn&&hn.prototype;if(un&&un.forEach!==ln){try{Q(un,"forEach",ln)}catch(dn){un.forEach=ln}}}var fn=he.trim,pn=x.parseFloat,gn=1/pn(ae+"-0")!==-(1/0),vn=gn?function(t){var e=fn(t+""),i=pn(e);return 0===i&&"-"==e.charAt(0)?-0:i}:pn;oe({global:!0,forced:parseFloat!=vn},{parseFloat:vn});var bn=Bt.indexOf,mn=[].indexOf,yn=!!mn&&1/[1].indexOf(1,-0)<0,wn=pe("indexOf");oe({target:"Array",proto:!0,forced:yn||!wn},{indexOf:function(t){return yn?mn.apply(this,arguments)||0:bn(this,t,arguments.length>1?arguments[1]:void 0)}});var Sn=[],xn=Sn.sort,kn=k(function(){Sn.sort(void 0)}),On=k(function(){Sn.sort(null)}),Tn=pe("sort"),Cn=kn||!On||!Tn;oe({target:"Array",proto:!0,forced:Cn},{sort:function(t){return void 0===t?xn.call(Ni(this)):xn.call(Ni(this),Ze(t))}});var Pn=Math.floor,In="".replace,An=/\$([$&'`]|\d{1,2}|<[^>]*>)/g,$n=/\$([$&'`]|\d{1,2})/g,Rn=function(t,e,i,n,o,a){var s=i+t.length,r=n.length,l=$n;return void 0!==o&&(o=Ni(o),l=An),In.call(a,l,function(a,l){var c;switch(l.charAt(0)){case"$":return"$";case"&":return t;case"`":return e.slice(0,i);case"'":return e.slice(s);case"<":c=o[l.slice(1,-1)];break;default:var h=+l;if(0===h){return a}if(h>r){var u=Pn(h/10);return 0===u?a:r>=u?void 0===n[u-1]?l.charAt(1):n[u-1]+l.charAt(1):a}c=n[h-1]}return void 0===c?"":c})},En=Math.max,jn=Math.min,_n=function(t){return void 0===t?t:t+""};Xe("replace",2,function(t,e,i,n){var o=n.REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE,a=n.REPLACE_KEEPS_$0,s=o?"$":"$0";return[function(i,n){var o=N(this),a=void 0==i?void 0:i[t];return void 0!==a?a.call(i,o,n):e.call(o+"",i,n)},function(t,n){if(!o&&a||"string"==typeof n&&-1===n.indexOf(s)){var r=i(e,t,this,n);if(r.done){return r.value}}var l=K(t),c=this+"",h="function"==typeof n;h||(n+="");var u=l.global;if(u){var d=l.unicode;l.lastIndex=0}for(var f=[];;){var p=si(l,c);if(null===p){break}if(f.push(p),!u){break}var g=p[0]+"";""===g&&(l.lastIndex=ai(c,_t(l.lastIndex),d))}for(var v="",b=0,m=0;m=b&&(v+=c.slice(b,w)+T,b=w+y.length)}return v+c.slice(b)}]});var Nn=Object.assign,Fn=Object.defineProperty,Dn=!Nn||k(function(){if(O&&1!==Nn({b:1},Nn(Fn({},"a",{enumerable:!0,get:function(){Fn(this,"b",{value:3,enumerable:!1})}}),{b:2})).b){return !0}var t={},e={},i=Symbol(),n="abcdefghijklmnopqrst";return t[i]=7,n.split("").forEach(function(t){e[t]=t}),7!=Nn({},t)[i]||ui(Nn({},e)).join("")!=n})?function(t,e){for(var i=Ni(t),n=arguments.length,o=1,a=Gt.f,s=A.f;n>o;){for(var r,l=_(arguments[o++]),c=a?ui(l).concat(a(l)):ui(l),h=c.length,u=0;h>u;){r=c[u++],(!O||s.call(l,r))&&(i[r]=l[r])}}return i}:Nn;oe({target:"Object",stat:!0,forced:Object.assign!==Dn},{assign:Dn});var Vn=Ji.filter,Bn=Li("filter");oe({target:"Array",proto:!0,forced:!Bn},{filter:function(t){return Vn(this,t,arguments.length>1?arguments[1]:void 0)}});var Ln=Object.is||function(t,e){return t===e?0!==t||1/t===1/e:t!=t&&e!=e};Xe("search",1,function(t,e,i){return[function(e){var i=N(this),n=void 0==e?void 0:e[t];return void 0!==n?n.call(e,i):RegExp(e)[t](i+"")},function(t){var n=i(e,t,this);if(n.done){return n.value}var o=K(t),a=this+"",s=o.lastIndex;Ln(s,0)||(o.lastIndex=0);var r=si(o,a);return Ln(o.lastIndex,s)||(o.lastIndex=s),null===r?-1:r.index}]});var Hn=he.trim,Mn=x.parseInt,Un=/^[+-]?0[Xx]/,qn=8!==Mn(ae+"08")||22!==Mn(ae+"0x16"),zn=qn?function(t,e){var i=Hn(t+"");return Mn(i,e>>>0||(Un.test(i)?16:10))}:Mn;oe({global:!0,forced:parseInt!=zn},{parseInt:zn});var Wn=Ji.map,Gn=Li("map");oe({target:"Array",proto:!0,forced:!Gn},{map:function(t){return Wn(this,t,arguments.length>1?arguments[1]:void 0)}});var Kn=Ji.findIndex,Yn="findIndex",Xn=!0;Yn in []&&Array(1)[Yn](function(){Xn=!1}),oe({target:"Array",proto:!0,forced:Xn},{findIndex:function(t){return Kn(this,t,arguments.length>1?arguments[1]:void 0)}}),Ei(Yn);var Jn=function(t){if(!D(t)&&null!==t){throw TypeError("Can't set "+(t+"")+" as a prototype")}return t},Qn=Object.setPrototypeOf||("__proto__" in {}?function(){var t,e=!1,i={};try{t=Object.getOwnPropertyDescriptor(Object.prototype,"__proto__").set,t.call(i,[]),e=i instanceof Array}catch(n){}return function(i,n){return K(i),Jn(n),e?t.call(i,n):i.__proto__=n,i}}():void 0),Zn=function(t,e,i){var n,o;return Qn&&"function"==typeof(n=e.constructor)&&n!==i&&D(o=n.prototype)&&o!==i.prototype&&Qn(t,o),t},to=Ue("species"),eo=function(t){var e=At(t),i=J.f;O&&e&&!e[to]&&i(e,to,{configurable:!0,get:function(){return this}})},io=J.f,no=zt.f,oo=Tt.set,ao=Ue("match"),so=x.RegExp,ro=so.prototype,lo=/a/g,co=/a/g,ho=new so(lo)!==lo,uo=Se.UNSUPPORTED_Y,fo=O&&ie("RegExp",!ho||uo||k(function(){return co[ao]=!1,so(lo)!=lo||so(co)==co||"/a/i"!=so(lo,"i")}));if(fo){for(var po=function(t,e){var i,n=this instanceof po,o=Qe(t),a=void 0===e;if(!n&&o&&t.constructor===po&&a){return t}ho?o&&!a&&(t=t.source):t instanceof po&&(a&&(e=me.call(t)),t=t.source),uo&&(i=!!e&&e.indexOf("y")>-1,i&&(e=e.replace(/y/g,"")));var s=Zn(ho?new so(t,e):so(t,e),n?this:ro,po);return uo&&i&&oo(s,{sticky:i}),s},go=(function(t){t in po||io(po,t,{configurable:!0,get:function(){return so[t]},set:function(e){so[t]=e}})}),vo=no(so),bo=0;vo.length>bo;){go(vo[bo++])}ro.constructor=po,po.prototype=ro,Ct(x,"RegExp",po)}eo("RegExp");var mo="toString",yo=RegExp.prototype,wo=yo[mo],So=k(function(){return"/a/b"!=wo.call({source:"a",flags:"b"})}),xo=wo.name!=mo;(So||xo)&&Ct(RegExp.prototype,mo,function(){var t=K(this),e=t.source+"",i=t.flags,n=(void 0===i&&t instanceof RegExp&&!("flags" in yo)?me.call(t):i)+"";return"/"+e+"/"+n},{unsafe:!0});var ko=Ue("toStringTag"),Oo={};Oo[ko]="z";var To=Oo+""=="[object z]",Co=Ue("toStringTag"),Po="Arguments"==E(function(){return arguments}()),Io=function(t,e){try{return t[e]}catch(i){}},Ao=To?E:function(t){var e,i,n;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(i=Io(e=Object(t),Co))?i:Po?E(e):"Object"==(n=E(e))&&"function"==typeof e.callee?"Arguments":n},$o=To?{}.toString:function(){return"[object "+Ao(this)+"]"};To||Ct(Object.prototype,"toString",$o,{unsafe:!0});var Ro=Li("slice"),Eo=Ue("species"),jo=[].slice,_o=Math.max;oe({target:"Array",proto:!0,forced:!Ro},{slice:function(t,e){var i,n,o,a=F(this),s=_t(a.length),r=Dt(t,s),l=Dt(void 0===e?s:e,s);if(_i(a)&&(i=a.constructor,"function"!=typeof i||i!==Array&&!_i(i.prototype)?D(i)&&(i=i[Eo],null===i&&(i=void 0)):i=void 0,i===Array||void 0===i)){return jo.call(a,r,l)}for(n=new (void 0===i?Array:i)(_o(l-r,0)),o=0;l>r;r++,o++){r in a&&Fi(n,o,a[r])}return n.length=o,n}});var No,Fo,Do,Vo=!k(function(){function t(){}return t.prototype.constructor=null,Object.getPrototypeOf(new t)!==t.prototype}),Bo=gt("IE_PROTO"),Lo=Object.prototype,Ho=Vo?Object.getPrototypeOf:function(t){return t=Ni(t),L(t,Bo)?t[Bo]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?Lo:null},Mo=Ue("iterator"),Uo=!1,qo=function(){return this};[].keys&&(Do=[].keys(),"next" in Do?(Fo=Ho(Ho(Do)),Fo!==Object.prototype&&(No=Fo)):Uo=!0);var zo=void 0==No||k(function(){var t={};return No[Mo].call(t)!==t});zo&&(No={}),L(No,Mo)||Q(No,Mo,qo);var Wo={IteratorPrototype:No,BUGGY_SAFARI_ITERATORS:Uo},Go=J.f,Ko=Ue("toStringTag"),Yo=function(t,e,i){t&&!L(t=i?t:t.prototype,Ko)&&Go(t,Ko,{configurable:!0,value:e})},Xo=Wo.IteratorPrototype,Jo=function(t,e,i){var n=e+" Iterator";return t.prototype=Ai(Xo,{next:$(1,i)}),Yo(t,n,!1),t},Qo=Wo.IteratorPrototype,Zo=Wo.BUGGY_SAFARI_ITERATORS,ta=Ue("iterator"),ea="keys",ia="values",na="entries",oa=function(){return this},aa=function(t,e,i,n,o,a,s){Jo(i,e,n);var r,l,c,h=function(t){if(t===o&&g){return g}if(!Zo&&t in f){return f[t]}switch(t){case ea:return function(){return new i(this,t)};case ia:return function(){return new i(this,t)};case na:return function(){return new i(this,t)}}return function(){return new i(this)}},u=e+" Iterator",d=!1,f=t.prototype,p=f[ta]||f["@@iterator"]||o&&f[o],g=!Zo&&p||h(o),v="Array"==e?f.entries||p:p;if(v&&(r=Ho(v.call(new t)),Qo!==Object.prototype&&r.next&&(Ho(r)!==Qo&&(Qn?Qn(r,Qo):"function"!=typeof r[ta]&&Q(r,ta,oa)),Yo(r,u,!0))),o==ia&&p&&p.name!==ia&&(d=!0,g=function(){return p.call(this)}),f[ta]!==g&&Q(f,ta,g),o){if(l={values:h(ia),keys:a?g:h(ea),entries:h(na)},s){for(c in l){!Zo&&!d&&c in f||Ct(f,c,l[c])}}else{oe({target:e,proto:!0,forced:Zo||d},l)}}return l},sa="Array Iterator",ra=Tt.set,la=Tt.getterFor(sa),ca=aa(Array,"Array",function(t,e){ra(this,{type:sa,target:F(t),index:0,kind:e})},function(){var t=la(this),e=t.target,i=t.kind,n=t.index++;return !e||n>=e.length?(t.target=void 0,{value:void 0,done:!0}):"keys"==i?{value:n,done:!1}:"values"==i?{value:e[n],done:!1}:{value:[n,e[n]],done:!1}},"values");Ei("keys"),Ei("values"),Ei("entries");var ha=Ue("iterator"),ua=Ue("toStringTag"),da=ca.values;for(var fa in an){var pa=x[fa],ga=pa&&pa.prototype;if(ga){if(ga[ha]!==da){try{Q(ga,ha,da)}catch(dn){ga[ha]=da}}if(ga[ua]||Q(ga,ua,fa),an[fa]){for(var va in ca){if(ga[va]!==ca[va]){try{Q(ga,va,ca[va])}catch(dn){ga[va]=ca[va]}}}}}}var ba=Li("splice"),ma=Math.max,ya=Math.min,wa=9007199254740991,Sa="Maximum allowed length exceeded";oe({target:"Array",proto:!0,forced:!ba},{splice:function(t,e){var i,n,o,a,s,r,l=Ni(this),c=_t(l.length),h=Dt(t,c),u=arguments.length;if(0===u?i=n=0:1===u?(i=0,n=c-h):(i=u-2,n=ya(ma(Et(e),0),c-h)),c+i-n>wa){throw TypeError(Sa)}for(o=Vi(l,n),a=0;n>a;a++){s=h+a,s in l&&Fi(o,a,l[s])}if(o.length=n,n>i){for(a=h;c-n>a;a++){s=a+n,r=a+i,s in l?l[r]=l[s]:delete l[r]}for(a=c;a>c-n+i;a--){delete l[a-1]}}else{if(i>n){for(a=c-n;a>h;a--){s=a+n-1,r=a+i-1,s in l?l[r]=l[s]:delete l[r]}}}for(a=0;i>a;a++){l[a+h]=arguments[a+2]}return l.length=c-n+i,o}});var xa=zt.f,ka=G.f,Oa=J.f,Ta=he.trim,Ca="Number",Pa=x[Ca],Ia=Pa.prototype,Aa=E(Ai(Ia))==Ca,$a=function(t){var e,i,n,o,a,s,r,l,c=V(t,!1);if("string"==typeof c&&c.length>2){if(c=Ta(c),e=c.charCodeAt(0),43===e||45===e){if(i=c.charCodeAt(2),88===i||120===i){return NaN}}else{if(48===e){switch(c.charCodeAt(1)){case 66:case 98:n=2,o=49;break;case 79:case 111:n=8,o=55;break;default:return +c}for(a=c.slice(2),s=a.length,r=0;s>r;r++){if(l=a.charCodeAt(r),48>l||l>o){return NaN}}return parseInt(a,n)}}}return +c};if(ie(Ca,!Pa(" 0o1")||!Pa("0b1")||Pa("+0x1"))){for(var Ra,Ea=function(t){var e=arguments.length<1?0:t,i=this;return i instanceof Ea&&(Aa?k(function(){Ia.valueOf.call(i)}):E(i)!=Ca)?Zn(new Pa($a(e)),i,Ea):$a(e)},ja=O?xa(Pa):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger,fromString,range".split(","),_a=0;ja.length>_a;_a++){L(Pa,Ra=ja[_a])&&!L(Ea,Ra)&&Oa(Ea,Ra,ka(Pa,Ra))}Ea.prototype=Ia,Ia.constructor=Ea,Ct(x,Ca,Ea)}var Na=[].reverse,Fa=[1,2];oe({target:"Array",proto:!0,forced:Fa+""==Fa.reverse()+""},{reverse:function(){return _i(this)&&(this.length=this.length),Na.call(this)}});var Da="1.19.1",Va=4;try{var Ba=y["default"].fn.dropdown.Constructor.VERSION;void 0!==Ba&&(Va=parseInt(Ba,10))}catch(La){}try{var Ha=bootstrap.Tooltip.VERSION;void 0!==Ha&&(Va=parseInt(Ha,10))}catch(La){}var Ma={3:{iconsPrefix:"glyphicon",icons:{paginationSwitchDown:"glyphicon-collapse-down icon-chevron-down",paginationSwitchUp:"glyphicon-collapse-up icon-chevron-up",refresh:"glyphicon-refresh icon-refresh",toggleOff:"glyphicon-list-alt icon-list-alt",toggleOn:"glyphicon-list-alt icon-list-alt",columns:"glyphicon-th icon-th",detailOpen:"glyphicon-plus icon-plus",detailClose:"glyphicon-minus icon-minus",fullscreen:"glyphicon-fullscreen",search:"glyphicon-search",clearSearch:"glyphicon-trash"},classes:{buttonsPrefix:"btn",buttons:"default",buttonsGroup:"btn-group",buttonsDropdown:"btn-group",pull:"pull",inputGroup:"input-group",inputPrefix:"input-",input:"form-control",paginationDropdown:"btn-group dropdown",dropup:"dropup",dropdownActive:"active",paginationActive:"active",buttonActive:"active"},html:{toolbarDropdown:['"],toolbarDropdownItem:'
  • ',toolbarDropdownSeparator:'
  • ',pageDropdown:['"],pageDropdownItem:'
    ',dropdownCaret:'',pagination:['
      ',"
    "],paginationItem:'
  • %s
  • ',icon:'',inputGroup:'
    %s%s
    ',searchInput:'',searchButton:'',searchClearButton:''}},4:{iconsPrefix:"fa",icons:{paginationSwitchDown:"fa-caret-square-down",paginationSwitchUp:"fa-caret-square-up",refresh:"fa-sync",toggleOff:"fa-toggle-off",toggleOn:"fa-toggle-on",columns:"fa-th-list",detailOpen:"fa-plus",detailClose:"fa-minus",fullscreen:"fa-arrows-alt",search:"fa-search",clearSearch:"fa-trash"},classes:{buttonsPrefix:"btn",buttons:"secondary",buttonsGroup:"btn-group",buttonsDropdown:"btn-group",pull:"float",inputGroup:"btn-group",inputPrefix:"form-control-",input:"form-control",paginationDropdown:"btn-group dropdown",dropup:"dropup",dropdownActive:"active",paginationActive:"active",buttonActive:"active"},html:{toolbarDropdown:['"],toolbarDropdownItem:'',pageDropdown:['"],pageDropdownItem:'%s',toolbarDropdownSeparator:'',dropdownCaret:'',pagination:['
      ',"
    "],paginationItem:'
  • %s
  • ',icon:'',inputGroup:'
    %s
    %s
    ',searchInput:'',searchButton:'',searchClearButton:''}},5:{iconsPrefix:"bi",icons:{paginationSwitchDown:"bi-caret-down-square",paginationSwitchUp:"bi-caret-up-square",refresh:"bi-arrow-clockwise",toggleOff:"bi-toggle-off",toggleOn:"bi-toggle-on",columns:"bi-list-ul",detailOpen:"bi-plus",detailClose:"bi-dash",fullscreen:"bi-arrows-move",search:"bi-search",clearSearch:"bi-trash"},classes:{buttonsPrefix:"btn",buttons:"secondary",buttonsGroup:"btn-group",buttonsDropdown:"btn-group",pull:"float",inputGroup:"btn-group",inputPrefix:"form-control-",input:"form-control",paginationDropdown:"btn-group dropdown",dropup:"dropup",dropdownActive:"active",paginationActive:"active",buttonActive:"active"},html:{dataToggle:"data-bs-toggle",toolbarDropdown:['"],toolbarDropdownItem:'',pageDropdown:['"],pageDropdownItem:'%s',toolbarDropdownSeparator:'',dropdownCaret:'',pagination:['
      ',"
    "],paginationItem:'
  • %s
  • ',icon:'',inputGroup:'
    %s%s
    ',searchInput:'',searchButton:'',searchClearButton:''}}}[Va],Ua={id:void 0,firstLoad:!0,height:void 0,classes:"table table-bordered table-hover",buttons:{},theadClasses:"",striped:!1,headerStyle:function(t){return{}},rowStyle:function(t,e){return{}},rowAttributes:function(t,e){return{}},undefinedText:"-",locale:void 0,virtualScroll:!1,virtualScrollItemHeight:void 0,sortable:!0,sortClass:void 0,silentSort:!0,sortName:void 0,sortOrder:void 0,sortReset:!1,sortStable:!1,rememberOrder:!1,serverSort:!0,customSort:void 0,columns:[[]],data:[],url:void 0,method:"get",cache:!0,contentType:"application/json",dataType:"json",ajax:void 0,ajaxOptions:{},queryParams:function(t){return t},queryParamsType:"limit",responseHandler:function(t){return t},totalField:"total",totalNotFilteredField:"totalNotFiltered",dataField:"rows",footerField:"footer",pagination:!1,paginationParts:["pageInfo","pageSize","pageList"],showExtendedPagination:!1,paginationLoop:!0,sidePagination:"client",totalRows:0,totalNotFiltered:0,pageNumber:1,pageSize:10,pageList:[10,25,50,100],paginationHAlign:"right",paginationVAlign:"bottom",paginationDetailHAlign:"left",paginationPreText:"‹",paginationNextText:"›",paginationSuccessivelySize:5,paginationPagesBySide:1,paginationUseIntermediate:!1,search:!1,searchHighlight:!1,searchOnEnterKey:!1,strictSearch:!1,regexSearch:!1,searchSelector:!1,visibleSearch:!1,showButtonIcons:!0,showButtonText:!1,showSearchButton:!1,showSearchClearButton:!1,trimOnSearch:!0,searchAlign:"right",searchTimeOut:500,searchText:"",customSearch:void 0,showHeader:!0,showFooter:!1,footerStyle:function(t){return{}},searchAccentNeutralise:!1,showColumns:!1,showSearch:!1,showPageGo:!1,showColumnsToggleAll:!1,showColumnsSearch:!1,minimumCountColumns:1,showPaginationSwitch:!1,showRefresh:!1,showToggle:!1,showFullscreen:!1,smartDisplay:!0,escape:!1,filterOptions:{filterAlgorithm:"and"},idField:void 0,selectItemName:"btSelectItem",clickToSelect:!1,ignoreClickToSelectOn:function(t){var e=t.tagName;return["A","BUTTON"].includes(e)},singleSelect:!1,checkboxHeader:!0,maintainMetaData:!1,multipleSelectRow:!1,uniqueId:void 0,cardView:!1,detailView:!1,detailViewIcon:!0,detailViewByClick:!1,detailViewAlign:"left",detailFormatter:function(t,e){return""},detailFilter:function(t,e){return !0},toolbar:void 0,toolbarAlign:"left",buttonsToolbar:void 0,buttonsAlign:"right",buttonsOrder:["search","paginationSwitch","refresh","toggle","fullscreen","columns"],buttonsPrefix:Ma.classes.buttonsPrefix,buttonsClass:Ma.classes.buttons,icons:Ma.icons,iconSize:void 0,iconsPrefix:Ma.iconsPrefix,loadingFontSize:"auto",loadingTemplate:function(t){return'\n '.concat(t,'\n \n \n ')},onAll:function(t,e){return !1},onClickCell:function(t,e,i,n){return !1},onDblClickCell:function(t,e,i,n){return !1},onClickRow:function(t,e){return !1},onDblClickRow:function(t,e){return !1},onSort:function(t,e){return !1},onCheck:function(t){return !1},onUncheck:function(t){return !1},onCheckAll:function(t){return !1},onUncheckAll:function(t){return !1},onCheckSome:function(t){return !1},onUncheckSome:function(t){return !1},onLoadSuccess:function(t){return !1},onLoadError:function(t){return !1},onColumnSwitch:function(t,e){return !1},onPageChange:function(t,e){return !1},onSearch:function(t){return !1},onShowSearch:function(){return !1},onToggle:function(t){return !1},onPreBody:function(t){return !1},onPostBody:function(){return !1},onPostHeader:function(){return !1},onPostFooter:function(){return !1},onExpandRow:function(t,e,i){return !1},onCollapseRow:function(t,e){return !1},onRefreshOptions:function(t){return !1},onRefresh:function(t){return !1},onResetView:function(){return !1},onScrollBody:function(){return !1},onTogglePagination:function(t){return !1}},qa={formatLoadingMessage:function(){return"Loading, please wait"},formatRecordsPerPage:function(t){return"".concat(t," rows per page")},formatShowingRows:function(t,e,i,n){return void 0!==n&&n>0&&n>i?"Showing ".concat(t," to ").concat(e," of ").concat(i," rows (filtered from ").concat(n," total rows)"):"Showing ".concat(t," to ").concat(e," of ").concat(i," rows")},formatSRPaginationPreText:function(){return"previous page"},formatSRPaginationPageText:function(t){return"to page ".concat(t)},formatSRPaginationNextText:function(){return"next page"},formatDetailPagination:function(t){return"Showing ".concat(t," rows")},formatSearch:function(){return"Search"},formatShowSearch:function(){return"Show Search"},formatPageGo:function(){return"Go"},formatClearSearch:function(){return"Clear Search"},formatNoMatches:function(){return"No matching records found"},formatPaginationSwitch:function(){return"Hide/Show pagination"},formatPaginationSwitchDown:function(){return"Show pagination"},formatPaginationSwitchUp:function(){return"Hide pagination"},formatRefresh:function(){return"Refresh"},formatToggle:function(){return"Toggle"},formatToggleOn:function(){return"Show card view"},formatToggleOff:function(){return"Hide card view"},formatColumns:function(){return"Columns"},formatColumnsToggleAll:function(){return"Toggle all"},formatFullscreen:function(){return"Fullscreen"},formatAllRows:function(){return"All"}},za={field:void 0,title:void 0,titleTooltip:void 0,"class":void 0,width:void 0,widthUnit:"px",rowspan:void 0,colspan:void 0,align:void 0,halign:void 0,falign:void 0,valign:void 0,cellStyle:void 0,radio:!1,checkbox:!1,checkboxEnabled:!0,clickToSelect:!0,showSelectTitle:!1,sortable:!1,sortName:void 0,order:"asc",sorter:void 0,visible:!0,ignore:!1,switchable:!0,cardVisible:!0,searchable:!0,formatter:void 0,footerFormatter:void 0,detailFormatter:void 0,searchFormatter:!0,searchHighlightFormatter:!1,escape:!1,events:void 0},Wa=["getOptions","refreshOptions","getData","getSelections","load","append","prepend","remove","removeAll","insertRow","updateRow","getRowByUniqueId","updateByUniqueId","removeByUniqueId","updateCell","updateCellByUniqueId","showRow","hideRow","getHiddenRows","showColumn","hideColumn","getVisibleColumns","getHiddenColumns","showAllColumns","hideAllColumns","mergeCells","checkAll","uncheckAll","checkInvert","check","uncheck","checkBy","uncheckBy","refresh","destroy","resetView","showLoading","hideLoading","togglePagination","toggleFullscreen","toggleView","resetSearch","filterBy","scrollTo","getScrollPosition","selectPage","prevPage","nextPage","toggleDetailView","expandRow","collapseRow","expandRowByUniqueId","collapseRowByUniqueId","expandAllRows","collapseAllRows","updateColumnTitle","updateFormatText"],Ga={"all.bs.table":"onAll","click-row.bs.table":"onClickRow","dbl-click-row.bs.table":"onDblClickRow","click-cell.bs.table":"onClickCell","dbl-click-cell.bs.table":"onDblClickCell","sort.bs.table":"onSort","check.bs.table":"onCheck","uncheck.bs.table":"onUncheck","check-all.bs.table":"onCheckAll","uncheck-all.bs.table":"onUncheckAll","check-some.bs.table":"onCheckSome","uncheck-some.bs.table":"onUncheckSome","load-success.bs.table":"onLoadSuccess","load-error.bs.table":"onLoadError","column-switch.bs.table":"onColumnSwitch","page-change.bs.table":"onPageChange","search.bs.table":"onSearch","toggle.bs.table":"onToggle","pre-body.bs.table":"onPreBody","post-body.bs.table":"onPostBody","post-header.bs.table":"onPostHeader","post-footer.bs.table":"onPostFooter","expand-row.bs.table":"onExpandRow","collapse-row.bs.table":"onCollapseRow","refresh-options.bs.table":"onRefreshOptions","reset-view.bs.table":"onResetView","refresh.bs.table":"onRefresh","scroll-body.bs.table":"onScrollBody","toggle-pagination.bs.table":"onTogglePagination","virtual-scroll.bs.table":"onVirtualScroll"};Object.assign(Ua,qa);var Ka={VERSION:Da,THEME:"bootstrap".concat(Va),CONSTANTS:Ma,DEFAULTS:Ua,COLUMN_DEFAULTS:za,METHODS:Wa,EVENTS:Ga,LOCALES:{en:qa,"en-US":qa}},Ya=k(function(){ui(1)});oe({target:"Object",stat:!0,forced:Ya},{keys:function(t){return ui(Ni(t))}}),Xe("match",1,function(t,e,i){return[function(e){var i=N(this),n=void 0==e?void 0:e[t];return void 0!==n?n.call(e,i):RegExp(e)[t](i+"")},function(t){var n=i(e,t,this);if(n.done){return n.value}var o=K(t),a=this+"";if(!o.global){return si(o,a)}var s=o.unicode;o.lastIndex=0;for(var r,l=[],c=0;null!==(r=si(o,a));){var h=r[0]+"";l[c]=h,""===h&&(o.lastIndex=ai(a,_t(o.lastIndex),s)),c++}return 0===c?null:l}]});var Xa=G.f,Ja="".startsWith,Qa=Math.min,Za=on("startsWith"),ts=!Za&&!!function(){var t=Xa(String.prototype,"startsWith");return t&&!t.writable}();oe({target:"String",proto:!0,forced:!ts&&!Za},{startsWith:function(t){var e=N(this)+"";en(t);var i=_t(Qa(arguments.length>1?arguments[1]:void 0,e.length)),n=t+"";return Ja?Ja.call(e,n,i):e.slice(i,i+n.length)===n}});var es=G.f,is="".endsWith,ns=Math.min,os=on("endsWith"),as=!os&&!!function(){var t=es(String.prototype,"endsWith");return t&&!t.writable}();oe({target:"String",proto:!0,forced:!as&&!os},{endsWith:function(t){var e=N(this)+"";en(t);var i=arguments.length>1?arguments[1]:void 0,n=_t(e.length),o=void 0===i?n:ns(_t(i),n),a=t+"";return is?is.call(e,a,o):e.slice(o-a.length,o)===a}});var ss={getSearchInput:function(t){return"string"==typeof t.options.searchSelector?y["default"](t.options.searchSelector):t.$toolbar.find(".search input")},sprintf:function(t){for(var e=arguments.length,i=Array(e>1?e-1:0),n=1;e>n;n++){i[n-1]=arguments[n]}var o=!0,a=0,s=t.replace(/%s/g,function(){var t=i[a++];return void 0===t?(o=!1,""):t});return o?s:""},isObject:function(t){return t instanceof Object&&!Array.isArray(t)},isEmptyObject:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return 0===Object.entries(t).length&&t.constructor===Object},isNumeric:function(t){return !isNaN(parseFloat(t))&&isFinite(t)},getFieldTitle:function(t,e){var i,n=v(t);try{for(n.s();!(i=n.n()).done;){var o=i.value;if(o.field===e){return o.title}}}catch(a){n.e(a)}finally{n.f()}return""},setFieldIndex:function(t){var e,i=0,n=[],o=v(t[0]);try{for(o.s();!(e=o.n()).done;){var a=e.value;i+=a.colspan||1}}catch(s){o.e(s)}finally{o.f()}for(var r=0;rl;l++){n[r][l]=!1}}for(var c=0;cb;b++){for(var m=0;p>m;m++){n[c+b][g+m]=!0}}}}catch(s){u.e(s)}finally{u.f()}}},normalizeAccent:function(t){return"string"!=typeof t?t:t.normalize("NFD").replace(/[\u0300-\u036f]/g,"")},updateFieldGroup:function(t){var e,i,n=(e=[]).concat.apply(e,r(t)),o=v(t);try{for(o.s();!(i=o.n()).done;){var a,s=i.value,l=v(s);try{for(l.s();!(a=l.n()).done;){var c=a.value;if(c.colspanGroup>1){for(var h=0,u=function(t){var e=n.find(function(e){return e.fieldIndex===t});e.visible&&h++},d=c.colspanIndex;d0}}}catch(f){l.e(f)}finally{l.f()}}}catch(f){o.e(f)}finally{o.f()}},getScrollBarWidth:function(){if(void 0===this.cachedWidth){var t=y["default"]("
    ").addClass("fixed-table-scroll-inner"),e=y["default"]("
    ").addClass("fixed-table-scroll-outer");e.append(t),y["default"]("body").append(e);var i=t[0].offsetWidth;e.css("overflow","scroll");var n=t[0].offsetWidth;i===n&&(n=e[0].clientWidth),e.remove(),this.cachedWidth=i-n}return this.cachedWidth},calculateObjectValue:function(t,e,n,o){var a=e;if("string"==typeof e){var s=e.split(".");if(s.length>1){a=window;var l,c=v(s);try{for(c.s();!(l=c.n()).done;){var h=l.value;a=a[h]}}catch(u){c.e(u)}finally{c.f()}}else{a=window[e]}}return null!==a&&"object"===i(a)?a:"function"==typeof a?a.apply(t,n||[]):!a&&"string"==typeof e&&this.sprintf.apply(this,[e].concat(r(n)))?this.sprintf.apply(this,[e].concat(r(n))):o},compareObjects:function(t,e,i){var n=Object.keys(t),o=Object.keys(e);if(i&&n.length!==o.length){return !1}for(var a=0,s=n;a/g,">").replace(/"/g,""").replace(/'/g,"'"):t},unescapeHTML:function(t){return t?(""+t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/'/g,"'"):t},getRealDataAttr:function(t){for(var e=0,i=Object.entries(t);etd,>th").each(function(n,a){for(var s=y["default"](a),l=+s.attr("colspan")||1,c=+s.attr("rowspan")||1,h=n;o[e]&&o[e][h];h++){}for(var u=h;h+l>u;u++){for(var d=e;e+c>d;d++){o[d]||(o[d]=[]),o[d][u]=!0}}var f=t[h].field;r[f]=s.html().trim(),r["_".concat(f,"_id")]=s.attr("id"),r["_".concat(f,"_class")]=s.attr("class"),r["_".concat(f,"_rowspan")]=s.attr("rowspan"),r["_".concat(f,"_colspan")]=s.attr("colspan"),r["_".concat(f,"_title")]=s.attr("title"),r["_".concat(f,"_data")]=i.getRealDataAttr(s.data()),r["_".concat(f,"_style")]=s.attr("style")}),n.push(r)}),n},sort:function(t,e,i,n,o,a){return(void 0===t||null===t)&&(t=""),(void 0===e||null===e)&&(e=""),n&&t===e&&(t=o,e=a),this.isNumeric(t)&&this.isNumeric(e)?(t=parseFloat(t),e=parseFloat(e),e>t?-1*i:t>e?i:0):t===e?0:("string"!=typeof t&&(t=""+t),-1===t.localeCompare(e)?-1*i:i)},getEventName:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return e=e||"".concat(+new Date).concat(~~(1000000*Math.random())),"".concat(t,"-").concat(e)},hasDetailViewIcon:function(t){return t.detailView&&t.detailViewIcon&&!t.cardView},getDetailViewIndexOffset:function(t){return this.hasDetailViewIcon(t)&&"right"!==t.detailViewAlign?1:0},checkAutoMergeCells:function(t){var e,i=v(t);try{for(i.s();!(e=i.n()).done;){for(var n=e.value,o=0,a=Object.keys(n);oo&&r++;for(var l=i;n>l;l++){t[l]&&s.push(t[l])}return{start:i,end:n,topOffset:o,bottomOffset:a,rowsAbove:r,rows:s}}},{key:"checkChanges",value:function(t,e){var i=e!==this.cache[t];return this.cache[t]=e,i}},{key:"getExtra",value:function(t,e){var i=document.createElement("tr");return i.className="virtual-scroll-".concat(t),e&&(i.style.height="".concat(e,"px")),i.outerHTML}}]),t}(),hs=function(){function e(t,i){n(this,e),this.options=i,this.$el=y["default"](t),this.$el_=this.$el.clone(),this.timeoutId_=0,this.timeoutFooter_=0}return a(e,[{key:"init",value:function(){this.initConstants(),this.initLocale(),this.initContainer(),this.initTable(),this.initHeader(),this.initData(),this.initHiddenRows(),this.initToolbar(),this.initPagination(),this.initBody(),this.initSearchText(),this.initServer()}},{key:"initConstants",value:function(){var t=this.options;this.constants=Ka.CONSTANTS,this.constants.theme=y["default"].fn.bootstrapTable.theme,this.constants.dataToggle=this.constants.html.dataToggle||"data-toggle";var e=t.buttonsPrefix?"".concat(t.buttonsPrefix,"-"):"";this.constants.buttonsClass=[t.buttonsPrefix,e+t.buttonsClass,ss.sprintf("".concat(e,"%s"),t.iconSize)].join(" ").trim(),this.buttons=ss.calculateObjectValue(this,t.buttons,[],{}),"object"!==i(this.buttons)&&(this.buttons={}),"string"==typeof t.icons&&(t.icons=ss.calculateObjectValue(null,t.icons))}},{key:"initLocale",value:function(){if(this.options.locale){var t=y["default"].fn.bootstrapTable.locales,i=this.options.locale.split(/-|_/);i[0]=i[0].toLowerCase(),i[1]&&(i[1]=i[1].toUpperCase());var n={};t[this.options.locale]?n=t[this.options.locale]:t[i.join("-")]?n=t[i.join("-")]:t[i[0]]&&(n=t[i[0]]);for(var o=0,a=Object.entries(n);o
    ':"",e=["bottom","both"].includes(this.options.paginationVAlign)?'
    ':"",i=ss.calculateObjectValue(this.options,this.options.loadingTemplate,[this.options.formatLoadingMessage()]);this.$container=y["default"]('\n
    \n
    \n ').concat(t,'\n
    \n
    \n
    \n
    \n ').concat(i,'\n
    \n
    \n \n
    \n ').concat(e,"\n
    \n ")),this.$container.insertAfter(this.$el),this.$tableContainer=this.$container.find(".fixed-table-container"),this.$tableHeader=this.$container.find(".fixed-table-header"),this.$tableBody=this.$container.find(".fixed-table-body"),this.$tableLoading=this.$container.find(".fixed-table-loading"),this.$tableFooter=this.$el.find("tfoot"),this.options.buttonsToolbar?this.$toolbar=y["default"]("body").find(this.options.buttonsToolbar):this.$toolbar=this.$container.find(".fixed-table-toolbar"),this.$pagination=this.$container.find(".fixed-table-pagination"),this.$tableBody.append(this.$el),this.$container.after('
    '),this.$el.addClass(this.options.classes),this.$tableLoading.addClass(this.options.classes),this.options.striped&&this.$el.addClass("table-striped"),this.options.height&&(this.$tableContainer.addClass("fixed-height"),this.options.showFooter&&this.$tableContainer.addClass("has-footer"),this.options.classes.split(" ").includes("table-bordered")&&(this.$tableBody.append('
    '),this.$tableBorder=this.$tableBody.find(".fixed-table-border"),this.$tableLoading.addClass("fixed-table-border")),this.$tableFooter=this.$container.find(".fixed-table-footer"))}},{key:"initTable",value:function(){var t=this,i=[];if(this.$header=this.$el.find(">thead"),this.$header.length?this.options.theadClasses&&this.$header.addClass(this.options.theadClasses):this.$header=y["default"]('')).appendTo(this.$el),this._headerTrClasses=[],this._headerTrStyles=[],this.$header.find("tr").each(function(e,n){var o=y["default"](n),a=[];o.find("th").each(function(t,e){var i=y["default"](e);void 0!==i.data("field")&&i.data("field","".concat(i.data("field"))),a.push(y["default"].extend({},{title:i.html(),"class":i.attr("class"),titleTooltip:i.attr("title"),rowspan:i.attr("rowspan")?+i.attr("rowspan"):void 0,colspan:i.attr("colspan")?+i.attr("colspan"):void 0},i.data()))}),i.push(a),o.attr("class")&&t._headerTrClasses.push(o.attr("class")),o.attr("style")&&t._headerTrStyles.push(o.attr("style"))}),Array.isArray(this.options.columns[0])||(this.options.columns=[this.options.columns]),this.options.columns=y["default"].extend(!0,[],i,this.options.columns),this.columns=[],this.fieldsColumnsIndex=[],ss.setFieldIndex(this.options.columns),this.options.columns.forEach(function(i,n){i.forEach(function(i,o){var a=y["default"].extend({},e.COLUMN_DEFAULTS,i);void 0!==a.fieldIndex&&(t.columns[a.fieldIndex]=a,t.fieldsColumnsIndex[a.field]=a.fieldIndex),t.options.columns[n][o]=a})}),!this.options.data.length){var n=ss.trToData(this.columns,this.$el.find(">tbody>tr"));n.length&&(this.options.data=n,this.fromHtml=!0)}this.options.pagination&&"server"!==this.options.sidePagination||(this.footerData=ss.trToData(this.columns,this.$el.find(">tfoot>tr"))),this.footerData&&this.$el.find("tfoot").html(""),!this.options.showFooter||this.options.cardView?this.$tableFooter.hide():this.$tableFooter.show()}},{key:"initHeader",value:function(){var t=this,e={},i=[];this.header={fields:[],styles:[],classes:[],formatters:[],detailFormatters:[],events:[],sorters:[],sortNames:[],cellStyles:[],searchables:[]},ss.updateFieldGroup(this.options.columns),this.options.columns.forEach(function(n,o){var a=[];a.push(""));var r="";if(0===o&&ss.hasDetailViewIcon(t.options)){var l=t.options.columns.length>1?' rowspan="'.concat(t.options.columns.length,'"'):"";r='\n
    \n ')}r&&"right"!==t.options.detailViewAlign&&a.push(r),n.forEach(function(i,n){var r=ss.sprintf(' class="%s"',i["class"]),l=i.widthUnit,c=parseFloat(i.width),h=ss.sprintf("text-align: %s; ",i.halign?i.halign:i.align),u=ss.sprintf("text-align: %s; ",i.align),d=ss.sprintf("vertical-align: %s; ",i.valign);if(d+=ss.sprintf("width: %s; ",!i.checkbox&&!i.radio||c?c?c+l:void 0:i.showSelectTitle?void 0:"36px"),void 0!==i.fieldIndex||i.visible){var f=ss.calculateObjectValue(null,t.options.headerStyle,[i]),p=[],g="";if(f&&f.css){for(var v=0,b=Object.entries(f.css);v0?" data-not-first-th":"",">"),a.push(ss.sprintf('
    ',t.options.sortable&&i.sortable?"sortable both":""));var S=t.options.escape?ss.escapeHTML(i.title):i.title,x=S;i.checkbox&&(S="",!t.options.singleSelect&&t.options.checkboxHeader&&(S=''),t.header.stateField=i.field),i.radio&&(S="",t.header.stateField=i.field),!S&&i.showSelectTitle&&(S+=x),a.push(S),a.push("
    "),a.push('
    '),a.push("
    "),a.push("")}}),r&&"right"===t.options.detailViewAlign&&a.push(r),a.push(""),a.length>3&&i.push(a.join(""))}),this.$header.html(i.join("")),this.$header.find("th[data-field]").each(function(t,i){y["default"](i).data(e[y["default"](i).data("field")])}),this.$container.off("click",".th-inner").on("click",".th-inner",function(e){var i=y["default"](e.currentTarget);return t.options.detailView&&!i.parent().hasClass("bs-checkbox")&&i.closest(".bootstrap-table")[0]!==t.$container[0]?!1:void (t.options.sortable&&i.parent().data().sortable&&t.onSort(e))});var n=ss.getEventName("resize.bootstrap-table",this.$el.attr("id"));y["default"](window).off(n),!this.options.showHeader||this.options.cardView?(this.$header.hide(),this.$tableHeader.hide(),this.$tableLoading.css("top",0)):(this.$header.show(),this.$tableHeader.show(),this.$tableLoading.css("top",this.$header.outerHeight()+1),this.getCaret(),y["default"](window).on(n,function(){return t.resetView()})),this.$selectAll=this.$header.find('[name="btSelectAll"]'),this.$selectAll.off("click").on("click",function(e){e.stopPropagation();var i=y["default"](e.currentTarget).prop("checked");t[i?"checkAll":"uncheckAll"](),t.updateSelected()})}},{key:"initData",value:function(t,e){"append"===e?this.options.data=this.options.data.concat(t):"prepend"===e?this.options.data=[].concat(t).concat(this.options.data):(t=t||ss.deepCopy(this.options.data),this.options.data=Array.isArray(t)?t:t[this.options.dataField]),this.data=r(this.options.data),this.options.sortReset&&(this.unsortedData=r(this.data)),"server"!==this.options.sidePagination&&this.initSort()}},{key:"initSort",value:function(){var t=this,e=this.options.sortName,i="desc"===this.options.sortOrder?-1:1,n=this.header.fields.indexOf(this.options.sortName),o=0;-1!==n?(this.options.sortStable&&this.data.forEach(function(t,e){t.hasOwnProperty("_position")||(t._position=e)}),this.options.customSort?ss.calculateObjectValue(this.options,this.options.customSort,[this.options.sortName,this.options.sortOrder,this.data]):this.data.sort(function(o,a){t.header.sortNames[n]&&(e=t.header.sortNames[n]);var s=ss.getItemField(o,e,t.options.escape),r=ss.getItemField(a,e,t.options.escape),l=ss.calculateObjectValue(t.header,t.header.sorters[n],[s,r,o,a]);return void 0!==l?t.options.sortStable&&0===l?i*(o._position-a._position):i*l:ss.sort(s,r,i,t.options.sortStable,o._position,a._position)}),void 0!==this.options.sortClass&&(clearTimeout(o),o=setTimeout(function(){t.$el.removeClass(t.options.sortClass);var e=t.$header.find('[data-field="'.concat(t.options.sortName,'"]')).index();t.$el.find("tr td:nth-child(".concat(e+1,")")).addClass(t.options.sortClass)},250))):this.options.sortReset&&(this.data=r(this.unsortedData))}},{key:"onSort",value:function(t){var e=t.type,i=t.currentTarget,n="keypress"===e?y["default"](i):y["default"](i).parent(),o=this.$header.find("th").eq(n.index());if(this.$header.add(this.$header_).find("span.order").remove(),this.options.sortName===n.data("field")){var a=this.options.sortOrder;void 0===a?this.options.sortOrder="asc":"asc"===a?this.options.sortOrder="desc":"desc"===this.options.sortOrder&&(this.options.sortOrder=this.options.sortReset?void 0:"asc"),void 0===this.options.sortOrder&&(this.options.sortName=void 0)}else{this.options.sortName=n.data("field"),this.options.rememberOrder?this.options.sortOrder="asc"===n.data("order")?"desc":"asc":this.options.sortOrder=this.columns[this.fieldsColumnsIndex[n.data("field")]].sortOrder||this.columns[this.fieldsColumnsIndex[n.data("field")]].order}return this.trigger("sort",this.options.sortName,this.options.sortOrder),n.add(o).data("order",this.options.sortOrder),this.getCaret(),"server"===this.options.sidePagination&&this.options.serverSort?(this.options.pageNumber=1,void this.initServer(this.options.silentSort)):(this.initSort(),void this.initBody())}},{key:"initToolbar",value:function(){var t,e=this,n=this.options,o=[],a=0,r=0;this.$toolbar.find(".bs-bars").children().length&&y["default"]("body").append(y["default"](n.toolbar)),this.$toolbar.html(""),("string"==typeof n.toolbar||"object"===i(n.toolbar))&&y["default"](ss.sprintf('
    ',this.constants.classes.pull,n.toolbarAlign)).appendTo(this.$toolbar).append(y["default"](n.toolbar)),o=['
    ')],"string"==typeof n.buttonsOrder&&(n.buttonsOrder=n.buttonsOrder.replace(/\[|\]| |'/g,"").split(",")),this.buttons=Object.assign(this.buttons,{search:{text:n.formatSearch(),icon:n.icons.search,render:!1,event:this.toggleShowSearch,attributes:{"aria-label":n.formatShowSearch(),title:n.formatShowSearch()}},paginationSwitch:{text:n.pagination?n.formatPaginationSwitchUp():n.formatPaginationSwitchDown(),icon:n.pagination?n.icons.paginationSwitchDown:n.icons.paginationSwitchUp,render:!1,event:this.togglePagination,attributes:{"aria-label":n.formatPaginationSwitch(),title:n.formatPaginationSwitch()}},refresh:{text:n.formatRefresh(),icon:n.icons.refresh,render:!1,event:this.refresh,attributes:{"aria-label":n.formatRefresh(),title:n.formatRefresh()}},toggle:{text:n.formatToggle(),icon:n.icons.toggleOff,render:!1,event:this.toggleView,attributes:{"aria-label":n.formatToggleOn(),title:n.formatToggleOn()}},fullscreen:{text:n.formatFullscreen(),icon:n.icons.fullscreen,render:!1,event:this.toggleFullscreen,attributes:{"aria-label":n.formatFullscreen(),title:n.formatFullscreen()}},columns:{render:!1,html:function X(){var X=[];if(X.push('
    \n \n ").concat(e.constants.html.toolbarDropdown[0])),n.showColumnsSearch&&(X.push(ss.sprintf(e.constants.html.toolbarDropdownItem,ss.sprintf('',e.constants.classes.input,n.formatSearch()))),X.push(e.constants.html.toolbarDropdownSeparator)),n.showColumnsToggleAll){var t=e.getVisibleColumns().length===e.columns.filter(function(t){return !e.isSelectionColumn(t)}).length;X.push(ss.sprintf(e.constants.html.toolbarDropdownItem,ss.sprintf(' %s',t?'checked="checked"':"",n.formatColumnsToggleAll()))),X.push(e.constants.html.toolbarDropdownSeparator)}var i=0;return e.columns.forEach(function(t){t.visible&&i++}),e.columns.forEach(function(t,o){if(!e.isSelectionColumn(t)&&(!n.cardView||t.cardVisible)&&!t.ignore){var a=t.visible?' checked="checked"':"",s=i<=n.minimumCountColumns&&a?' disabled="disabled"':"";t.switchable&&(X.push(ss.sprintf(e.constants.html.toolbarDropdownItem,ss.sprintf(' %s',t.field,o,a,s,t.title))),r++)}}),X.push(e.constants.html.toolbarDropdown[1],"
    "),X.join("")}}});for(var l={},c=0,h=Object.entries(this.buttons);c"}l[d]=p;var x="show".concat(d.charAt(0).toUpperCase()).concat(d.substring(1)),k=n[x];!(!f.hasOwnProperty("render")||f.hasOwnProperty("render")&&f.render)||void 0!==k&&k!==!0||(n[x]=!0),n.buttonsOrder.includes(d)||n.buttonsOrder.push(d)}var O,T=v(n.buttonsOrder);try{for(T.s();!(O=T.n()).done;){var C=O.value,P=n["show".concat(C.charAt(0).toUpperCase()).concat(C.substring(1))];P&&o.push(l[C])}}catch(I){T.e(I)}finally{T.f()}o.push("
    "),(this.showToolbar||o.length>2)&&this.$toolbar.append(o.join("")),n.showSearch&&this.$toolbar.find('button[name="showSearch"]').off("click").on("click",function(){return e.toggleShowSearch()});for(var A=0,$=Object.entries(this.buttons);A<$.length;A++){var R=s($[A],2),E=R[0],j=R[1];if(j.hasOwnProperty("event")){if("function"==typeof j.event||"string"==typeof j.event){var _=function(){var t="string"==typeof j.event?window[j.event]:j.event;return e.$toolbar.find('button[name="'.concat(E,'"]')).off("click").on("click",function(){return t.call(e)}),"continue"}();if("continue"===_){continue}}for(var N=function(){var t=s(D[F],2),i=t[0],n=t[1],o="string"==typeof n?window[n]:n;e.$toolbar.find('button[name="'.concat(E,'"]')).off(i).on(i,function(){return o.call(e)})},F=0,D=Object.entries(j.event);F'),W=z;if(n.showSearchButton||n.showSearchClearButton){var G=(n.showSearchButton?U:"")+(n.showSearchClearButton?q:"");W=n.search?ss.sprintf(this.constants.html.inputGroup,z,G):G}o.push(ss.sprintf('\n
    \n %s\n
    \n '),W)),this.$toolbar.append(o.join(""));var K=ss.getSearchInput(this);n.showSearchButton?(this.$toolbar.find(".search button[name=search]").off("click").on("click",function(){clearTimeout(a),a=setTimeout(function(){e.onSearch({currentTarget:K})},n.searchTimeOut)}),n.searchOnEnterKey&&M(K)):M(K),n.showSearchClearButton&&this.$toolbar.find(".search button[name=clearSearch]").click(function(){e.resetSearch()})}else{if("string"==typeof n.searchSelector){var Y=ss.getSearchInput(this);M(Y)}}}},{key:"onSearch",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.currentTarget,i=t.firedByInitSearchText,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:!0;if(void 0!==e&&y["default"](e).length&&n){var o=y["default"](e).val().trim();if(this.options.trimOnSearch&&y["default"](e).val()!==o&&y["default"](e).val(o),this.searchText===o){return}var a=ss.getSearchInput(this),s=e instanceof jQuery?e:y["default"](e);(s.is(a)||s.hasClass("search-input"))&&(this.searchText=o,this.options.searchText=o)}i||(this.options.pageNumber=1),this.initSearch(),i?"client"===this.options.sidePagination&&this.updatePagination():this.updatePagination(),this.trigger("search",this.searchText)}},{key:"initSearch",value:function(){var t=this;if(this.filterOptions=this.filterOptions||this.options.filterOptions,"server"!==this.options.sidePagination){if(this.options.customSearch){return this.data=ss.calculateObjectValue(this.options,this.options.customSearch,[this.options.data,this.searchText,this.filterColumns]),void (this.options.sortReset&&(this.unsortedData=r(this.data)))}var e=this.searchText&&(this.fromHtml?ss.escapeHTML(this.searchText):this.searchText),i=e?e.toLowerCase():"",n=ss.isEmptyObject(this.filterColumns)?null:this.filterColumns;this.options.searchAccentNeutralise&&(i=ss.normalizeAccent(i)),"function"==typeof this.filterOptions.filterAlgorithm?this.data=this.options.data.filter(function(e){return t.filterOptions.filterAlgorithm.apply(null,[e,n])}):"string"==typeof this.filterOptions.filterAlgorithm&&(this.data=n?this.options.data.filter(function(e){var i=t.filterOptions.filterAlgorithm;if("and"===i){for(var o in n){if(Array.isArray(n[o])&&!n[o].includes(e[o])||!Array.isArray(n[o])&&e[o]!==n[o]){return !1}}}else{if("or"===i){var a=!1;for(var s in n){(Array.isArray(n[s])&&n[s].includes(e[s])||!Array.isArray(n[s])&&e[s]===n[s])&&(a=!0)}return a}}return !0}):r(this.options.data));var o=this.getVisibleFields();this.data=i?this.data.filter(function(n,a){for(var s=0;s|=<|>=|>|<)(?:\s+)?(-?\d+)?|(-?\d+)?(\s+)?(<=|=>|=<|>=|>|<))/gm,f=d.exec(t.searchText),p=!1;if(f){var g=f[1]||"".concat(f[5],"l"),v=f[2]||f[3],b=parseInt(c,10),m=parseInt(v,10);switch(g){case">":case"m;break;case"<":case">l":p=m>b;break;case"<=":case"=<":case">=l":case"=>l":p=m>=b;break;case">=":case"=>":case"<=l":case"==m}}if(p||"".concat(c).toLowerCase().includes(i)){return !0}}}}return !1}):this.data,this.options.sortReset&&(this.unsortedData=r(this.data)),this.initSort()}}},{key:"initPagination",value:function(){var e=this,i=this.options;if(!i.pagination){return void this.$pagination.hide()}this.$pagination.show();var n,o,a,s,r,l,c,h=[],u=!1,d=this.getData({includeHiddenRows:!1}),f=i.pageList;if("string"==typeof f&&(f=f.replace(/\[|\]| /g,"").toLowerCase().split(",")),f=f.map(function(t){return"string"==typeof t?t.toLowerCase()===i.formatAllRows().toLowerCase()||["all","unlimited"].includes(t.toLowerCase())?i.formatAllRows():+t:t}),this.paginationParts=i.paginationParts,"string"==typeof this.paginationParts&&(this.paginationParts=this.paginationParts.replace(/\[|\]| |'/g,"").split(",")),"server"!==i.sidePagination&&(i.totalRows=d.length),this.totalPages=0,i.totalRows&&(i.pageSize===i.formatAllRows()&&(i.pageSize=i.totalRows,u=!0),this.totalPages=~~((i.totalRows-1)/i.pageSize)+1,i.totalPages=this.totalPages),this.totalPages>0&&i.pageNumber>this.totalPages&&(i.pageNumber=this.totalPages),this.pageFrom=(i.pageNumber-1)*i.pageSize+1,this.pageTo=i.pageNumber*i.pageSize,this.pageTo>i.totalRows&&(this.pageTo=i.totalRows),this.options.pagination&&"server"!==this.options.sidePagination&&(this.options.totalNotFiltered=this.options.data.length),this.options.showExtendedPagination||(this.options.totalNotFiltered=void 0),(this.paginationParts.includes("pageInfo")||this.paginationParts.includes("pageInfoShort")||this.paginationParts.includes("pageSize"))&&h.push('
    ')),this.paginationParts.includes("pageInfo")||this.paginationParts.includes("pageInfoShort")){var p=this.paginationParts.includes("pageInfoShort")?i.formatDetailPagination(i.totalRows):i.formatShowingRows(this.pageFrom,this.pageTo,i.totalRows,i.totalNotFiltered);h.push('\n '.concat(p,"\n "))}if(this.paginationParts.includes("pageSize")){h.push('
    ');var g=['
    \n \n ").concat(this.constants.html.pageDropdown[0])];f.forEach(function(t,n){if(!i.smartDisplay||0===n||f[n-1]")),h.push(i.formatRecordsPerPage(g.join("")))}if((this.paginationParts.includes("pageInfo")||this.paginationParts.includes("pageInfoShort")||this.paginationParts.includes("pageSize"))&&h.push("
    "),this.paginationParts.includes("pageList")){h.push('
    '),ss.sprintf(this.constants.html.pagination[0],ss.sprintf(" pagination-%s",i.iconSize)),ss.sprintf(this.constants.html.paginationItem," page-pre",i.formatSRPaginationPreText(),i.paginationPreText)),this.totalPagesthis.totalPages-o&&(o=o-(i.paginationSuccessivelySize-(this.totalPages-o))+1),1>o&&(o=1),a>this.totalPages&&(a=this.totalPages);var v=Math.round(i.paginationPagesBySide/2),b=function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return ss.sprintf(e.constants.html.paginationItem,n+(t===i.pageNumber?" ".concat(e.constants.classes.paginationActive):""),i.formatSRPaginationPageText(t),t)};if(o>1){var m=i.paginationPagesBySide;for(m>=o&&(m=o-1),n=1;m>=n;n++){h.push(b(n))}o-1===m+1?(n=o-1,h.push(b(n))):o-1>m&&(o-2*i.paginationPagesBySide>i.paginationPagesBySide&&i.paginationUseIntermediate?(n=Math.round((o-v)/2+v),h.push(b(n," page-intermediate"))):h.push(ss.sprintf(this.constants.html.paginationItem," page-first-separator disabled","","...")))}for(n=o;a>=n;n++){h.push(b(n))}if(this.totalPages>a){var y=this.totalPages-(i.paginationPagesBySide-1);for(a>=y&&(y=a+1),a+1===y-1?(n=a+1,h.push(b(n))):y>a+1&&(this.totalPages-a>2*i.paginationPagesBySide&&i.paginationUseIntermediate?(n=Math.round((this.totalPages-v-a)/2+a),h.push(b(n," page-intermediate"))):h.push(ss.sprintf(this.constants.html.paginationItem," page-last-separator disabled","","..."))),n=y;n<=this.totalPages;n++){h.push(b(n))}}h.push(ss.sprintf(this.constants.html.paginationItem," page-next",i.formatSRPaginationNextText(),i.paginationNextText)),h.push(this.constants.html.pagination[1],"
    ")}this.$pagination.html(h.join(""));var w=["bottom","both"].includes(i.paginationVAlign)?" ".concat(this.constants.classes.dropup):"";if(this.$pagination.last().find(".page-list > div").addClass(w),!i.onlyInfoPagination&&(s=this.$pagination.find(".page-list a"),r=this.$pagination.find(".page-pre"),l=this.$pagination.find(".page-next"),c=this.$pagination.find(".page-item").not(".page-next, .page-pre, .page-last-separator, .page-first-separator"),this.totalPages<=1&&this.$pagination.find("div.pagination").hide(),i.smartDisplay&&(f.length<2||i.totalRows<=f[0])&&this.$pagination.find("div.page-list").hide(),this.$pagination[this.getData().length?"show":"hide"](),i.paginationLoop||(1===i.pageNumber&&r.addClass("disabled"),i.pageNumber===this.totalPages&&l.addClass("disabled")),u&&(i.pageSize=i.formatAllRows()),s.off("click").on("click",function(t){return e.onPageListChange(t)}),r.off("click").on("click",function(t){return e.onPagePre(t)}),l.off("click").on("click",function(t){return e.onPageNext(t)}),c.off("click").on("click",function(t){return e.onPageNumber(t)}),this.options.showPageGo)){var S=this,x=this.$pagination.find("ul.pagination"),k=x.find("li.pageGo");k.length||(k=t('
  • '+ss.sprintf('',this.options.pageNumber)+('
  • ").appendTo(x),k.find("button").click(function(){var t=parseInt(k.find("input").val())||1;(1>t||t>S.options.totalPages)&&(t=1),S.selectPage(t)}))}}},{key:"updatePagination",value:function(t){t&&y["default"](t.currentTarget).hasClass("disabled")||(this.options.maintainMetaData||this.resetRows(),this.initPagination(),this.trigger("page-change",this.options.pageNumber,this.options.pageSize),"server"===this.options.sidePagination?this.initServer():this.initBody())}},{key:"onPageListChange",value:function(t){t.preventDefault();var e=y["default"](t.currentTarget);return e.parent().addClass(this.constants.classes.dropdownActive).siblings().removeClass(this.constants.classes.dropdownActive),this.options.pageSize=e.text().toUpperCase()===this.options.formatAllRows().toUpperCase()?this.options.formatAllRows():+e.text(),this.$toolbar.find(".page-size").text(this.options.pageSize),this.updatePagination(t),!1}},{key:"onPagePre",value:function(t){return y["default"](t.target).hasClass("disabled")?void 0:(t.preventDefault(),this.options.pageNumber-1===0?this.options.pageNumber=this.options.totalPages:this.options.pageNumber--,this.updatePagination(t),!1)}},{key:"onPageNext",value:function(t){return y["default"](t.target).hasClass("disabled")?void 0:(t.preventDefault(),this.options.pageNumber+1>this.options.totalPages?this.options.pageNumber=1:this.options.pageNumber++,this.updatePagination(t),!1)}},{key:"onPageNumber",value:function(t){return t.preventDefault(),this.options.pageNumber!==+y["default"](t.currentTarget).text()?(this.options.pageNumber=+y["default"](t.currentTarget).text(),this.updatePagination(t),!1):void 0}},{key:"initRow",value:function(t,e,n,o){var a=this,r=[],l={},c=[],h="",u={},d=[];if(!(ss.findIndex(this.hiddenRows,t)>-1)){if(l=ss.calculateObjectValue(this.options,this.options.rowStyle,[t,e],l),l&&l.css){for(var f=0,p=Object.entries(l.css);f"),this.options.cardView&&r.push('
    '));var I="";return ss.hasDetailViewIcon(this.options)&&(I="",ss.calculateObjectValue(null,this.options.detailFilter,[e,t])&&(I+='\n \n '.concat(ss.sprintf(this.constants.html.icon,this.options.iconsPrefix,this.options.icons.detailOpen),"\n \n ")),I+=""),I&&"right"!==this.options.detailViewAlign&&r.push(I),this.header.fields.forEach(function(i,n){var o="",l=ss.getItemField(t,i,a.options.escape),h="",u="",d={},f="",p=a.header.classes[n],g="",v="",b="",m="",y="",w="",S=a.columns[n];if((!a.fromHtml&&!a.autoMergeCells||void 0!==l||S.checkbox||S.radio)&&S.visible&&(!a.options.cardView||S.cardVisible)){if(S.escape&&(l=ss.escapeHTML(l)),c.concat([a.header.styles[n]]).length&&(v+="".concat(c.concat([a.header.styles[n]]).join("; "))),t["_".concat(i,"_style")]&&(v+="".concat(t["_".concat(i,"_style")])),v&&(g=' style="'.concat(v,'"')),t["_".concat(i,"_id")]&&(f=ss.sprintf(' id="%s"',t["_".concat(i,"_id")])),t["_".concat(i,"_class")]&&(p=ss.sprintf(' class="%s"',t["_".concat(i,"_class")])),t["_".concat(i,"_rowspan")]&&(m=ss.sprintf(' rowspan="%s"',t["_".concat(i,"_rowspan")])),t["_".concat(i,"_colspan")]&&(y=ss.sprintf(' colspan="%s"',t["_".concat(i,"_colspan")])),t["_".concat(i,"_title")]&&(w=ss.sprintf(' title="%s"',t["_".concat(i,"_title")])),d=ss.calculateObjectValue(a.header,a.header.cellStyles[n],[l,t,e,i],d),d.classes&&(p=' class="'.concat(d.classes,'"')),d.css){for(var x=[],k=0,O=Object.entries(d.css);k$1",R=h&&/<(?=.*? .*?\/ ?>|br|hr|input|!--|wbr)[a-z]+.*?>|<([a-z]+).*?<\/\1>/i.test(h);if(R){var E=(new DOMParser).parseFromString(""+h,"text/html").documentElement.textContent,j=E.replace(A,$);E=E.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),I=h.replace(RegExp("(>\\s*)(".concat(E,")(\\s*)"),"gm"),"$1".concat(j,"$3"))}else{I=(""+h).replace(A,$)}h=ss.calculateObjectValue(S,S.searchHighlightFormatter,[h,a.searchText],I)}if(t["_".concat(i,"_data")]&&!ss.isEmptyObject(t["_".concat(i,"_data")])){for(var _=0,N=Object.entries(t["_".concat(i,"_data")]);_'):'"))+'")+(a.header.formatters[n]&&"string"==typeof h?h:"")+(a.options.cardView?"
    ":""),t[a.header.stateField]=h===!0||!!l||h&&h.checked}else{if(a.options.cardView){var M=a.options.showHeader?'").concat(ss.getFieldTitle(a.columns,i),""):"";o='
    '.concat(M,'").concat(h,"
    "),a.options.smartDisplay&&""===h&&(o='
    ')}else{o="").concat(h,"")}}r.push(o)}}),I&&"right"===this.options.detailViewAlign&&r.push(I),this.options.cardView&&r.push("
    "),r.push(""),r.join("")}}},{key:"initBody",value:function(t,e){var i=this,n=this.getData();this.trigger("pre-body",n),this.$body=this.$el.find(">tbody"),this.$body.length||(this.$body=y["default"]("").appendTo(this.$el)),this.options.pagination&&"server"!==this.options.sidePagination||(this.pageFrom=1,this.pageTo=n.length);var o=[],a=y["default"](document.createDocumentFragment()),s=!1,r=[];this.autoMergeCells=ss.checkAutoMergeCells(n.slice(this.pageFrom-1,this.pageTo));for(var l=this.pageFrom-1;l tr[data-uniqueid="%s"][data-has-detail-view]',d)),p=f.next();p.is("tr.detail-view")&&(r.push(l),e&&d===e||(h+=p[0].outerHTML))}this.options.virtualScroll?o.push(h):a.append(h)}}s?this.options.virtualScroll?(this.virtualScroll&&this.virtualScroll.destroy(),this.virtualScroll=new cs({rows:o,fixedScroll:t,scrollEl:this.$tableBody[0],contentEl:this.$body[0],itemHeight:this.options.virtualScrollItemHeight,callback:function(t,e){i.fitHeader(),i.initBodyEvent(),i.trigger("virtual-scroll",t,e)}})):this.$body.html(a):this.$body.html(''.concat(ss.sprintf('%s',this.getVisibleFields().length+ss.getDetailViewIndexOffset(this.options),this.options.formatNoMatches()),"")),r.forEach(function(t){i.expandRow(t)}),t||this.scrollTo(0),this.initBodyEvent(),this.initFooter(),this.resetView(),this.updateSelected(),"server"!==this.options.sidePagination&&(this.options.totalRows=n.length),this.trigger("post-body",n)}},{key:"initBodyEvent",value:function(){var t=this;this.$body.find("> tr[data-index] > td").off("click dblclick").on("click dblclick",function(e){var i=y["default"](e.currentTarget),n=i.parent(),o=y["default"](e.target).parents(".card-views").children(),a=y["default"](e.target).parents(".card-view"),s=n.data("index"),r=t.data[s],l=t.options.cardView?o.index(a):i[0].cellIndex,c=t.getVisibleFields(),h=c[l-ss.getDetailViewIndexOffset(t.options)],u=t.columns[t.fieldsColumnsIndex[h]],d=ss.getItemField(r,h,t.options.escape);if(!i.find(".detail-icon").length){if(t.trigger("click"===e.type?"click-cell":"dbl-click-cell",h,d,r,i),t.trigger("click"===e.type?"click-row":"dbl-click-row",r,n,h),"click"===e.type&&t.options.clickToSelect&&u.clickToSelect&&!ss.calculateObjectValue(t.options,t.options.ignoreClickToSelectOn,[e.target])){var f=n.find(ss.sprintf('[name="%s"]',t.options.selectItemName));f.length&&f[0].click()}"click"===e.type&&t.options.detailViewByClick&&t.toggleDetailView(s,t.header.detailFormatters[t.fieldsColumnsIndex[h]])}}).off("mousedown").on("mousedown",function(e){t.multipleSelectRowCtrlKey=e.ctrlKey||e.metaKey,t.multipleSelectRowShiftKey=e.shiftKey}),this.$body.find("> tr[data-index] > td > .detail-icon").off("click").on("click",function(e){return e.preventDefault(),t.toggleDetailView(y["default"](e.currentTarget).parent().parent().data("index")),!1}),this.$selectItem=this.$body.find(ss.sprintf('[name="%s"]',this.options.selectItemName)),this.$selectItem.off("click").on("click",function(e){e.stopImmediatePropagation();var i=y["default"](e.currentTarget);t._toggleCheck(i.prop("checked"),i.data("index"))}),this.header.events.forEach(function(e,i){var n=e;if(n){"string"==typeof n&&(n=ss.calculateObjectValue(null,n));var o=t.header.fields[i],a=t.getVisibleFields().indexOf(o);if(-1!==a){a+=ss.getDetailViewIndexOffset(t.options);var s=function(e){if(!n.hasOwnProperty(e)){return"continue"}var i=n[e];t.$body.find(">tr:not(.no-records-found)").each(function(n,s){var r=y["default"](s),l=r.find(t.options.cardView?".card-views>.card-view":">td").eq(a),c=e.indexOf(" "),h=e.substring(0,c),u=e.substring(c+1);l.find(u).off(h).on(h,function(e){var n=r.data("index"),a=t.data[n],s=a[o];i.apply(t,[e,s,a,n])})})};for(var r in n){s(r)}}}})}},{key:"initServer",value:function(t,e,i){var n=this,o={},a=this.header.fields.indexOf(this.options.sortName),s={searchText:this.searchText,sortName:this.options.sortName,sortOrder:this.options.sortOrder};if(this.header.sortNames[a]&&(s.sortName=this.header.sortNames[a]),this.options.pagination&&"server"===this.options.sidePagination&&(s.pageSize=this.options.pageSize===this.options.formatAllRows()?this.options.totalRows:this.options.pageSize,s.pageNumber=this.options.pageNumber),!this.options.firstLoad&&!firstLoadTable.includes(this.options.id)){return void firstLoadTable.push(this.options.id)}if(i||this.options.url||this.options.ajax){if("limit"===this.options.queryParamsType&&(s={search:s.searchText,sort:s.sortName,order:s.sortOrder},this.options.pagination&&"server"===this.options.sidePagination&&(s.offset=this.options.pageSize===this.options.formatAllRows()?0:this.options.pageSize*(this.options.pageNumber-1),s.limit=this.options.pageSize,(0===s.limit||this.options.pageSize===this.options.formatAllRows())&&delete s.limit)),this.options.search&&"server"===this.options.sidePagination&&this.columns.filter(function(t){return !t.searchable}).length){s.searchable=[];var r,l=v(this.columns);try{for(l.s();!(r=l.n()).done;){var c=r.value;!c.checkbox&&c.searchable&&(this.options.visibleSearch&&c.visible||!this.options.visibleSearch)&&s.searchable.push(c.field)}}catch(h){l.e(h)}finally{l.f()}}if(ss.isEmptyObject(this.filterColumnsPartial)||(s.filter=JSON.stringify(this.filterColumnsPartial,null)),y["default"].extend(s,e||{}),o=ss.calculateObjectValue(this.options,this.options.queryParams,[s],o),o!==!1){t||this.showLoading();var u=y["default"].extend({},ss.calculateObjectValue(null,this.options.ajaxOptions),{type:this.options.method,url:i||this.options.url,data:"application/json"===this.options.contentType&&"post"===this.options.method?JSON.stringify(o):o,cache:this.options.cache,contentType:this.options.contentType,dataType:this.options.dataType,success:function(e,i,o){var a=ss.calculateObjectValue(n.options,n.options.responseHandler,[e,o],e);n.load(a),n.trigger("load-success",a,o&&o.status,o),t||n.hideLoading(),"server"===n.options.sidePagination&&n.options.pageNumber>1&&a[n.options.totalField]>0&&!a[n.options.dataField].length&&n.updatePagination()},error:function(e){if(e&&0===e.status&&n._xhrAbort){return void (n._xhrAbort=!1)}var i=[];"server"===n.options.sidePagination&&(i={},i[n.options.totalField]=0,i[n.options.dataField]=[]),n.load(i),n.trigger("load-error",e&&e.status,e),t||n.$tableLoading.hide()}});return this.options.ajax?ss.calculateObjectValue(this,this.options.ajax,[u],null):(this._xhr&&4!==this._xhr.readyState&&(this._xhrAbort=!0,this._xhr.abort()),this._xhr=y["default"].ajax(u)),o}}}},{key:"initSearchText",value:function(){if(this.options.search&&(this.searchText="",""!==this.options.searchText)){var t=ss.getSearchInput(this);t.val(this.options.searchText),this.onSearch({currentTarget:t,firedByInitSearchText:!0})}}},{key:"getCaret",value:function(){var t=this;this.$header.find("th").each(function(e,i){y["default"](i).find(".sortable").removeClass("desc asc").addClass(y["default"](i).data("field")===t.options.sortName?t.options.sortOrder:"both")})}},{key:"updateSelected",value:function(){var t=this.$selectItem.filter(":enabled").length&&this.$selectItem.filter(":enabled").length===this.$selectItem.filter(":enabled").filter(":checked").length;this.$selectAll.add(this.$selectAll_).prop("checked",t),this.$selectItem.each(function(t,e){y["default"](e).closest("tr")[y["default"](e).prop("checked")?"addClass":"removeClass"]("selected")})}},{key:"updateRows",value:function(){var t=this;this.$selectItem.each(function(e,i){t.data[y["default"](i).data("index")][t.header.stateField]=y["default"](i).prop("checked")})}},{key:"resetRows",value:function(){var t,e=v(this.data);try{for(e.s();!(t=e.n()).done;){var i=t.value;this.$selectAll.prop("checked",!1),this.$selectItem.prop("checked",!1),this.header.stateField&&(i[this.header.stateField]=!1)}}catch(n){e.e(n)}finally{e.f()}this.initHiddenRows()}},{key:"trigger",value:function(t){for(var i,n,o="".concat(t,".bs.table"),a=arguments.length,s=Array(a>1?a-1:0),r=1;a>r;r++){s[r-1]=arguments[r]}(i=this.options)[e.EVENTS[o]].apply(i,[].concat(s,[this])),this.$el.trigger(y["default"].Event(o,{sender:this}),s),(n=this.options).onAll.apply(n,[o].concat([].concat(s,[this]))),this.$el.trigger(y["default"].Event("all.bs.table",{sender:this}),[o,s])}},{key:"resetHeader",value:function(){var t=this;clearTimeout(this.timeoutId_),this.timeoutId_=setTimeout(function(){return t.fitHeader()},this.$el.is(":hidden")?100:0)}},{key:"fitHeader",value:function(){var t=this;if(this.$el.is(":hidden")){return void (this.timeoutId_=setTimeout(function(){return t.fitHeader()},100))}var e=this.$tableBody.get(0),i=e.scrollWidth>e.clientWidth&&e.scrollHeight>e.clientHeight+this.$header.outerHeight()?ss.getScrollBarWidth():0;this.$el.css("margin-top",-this.$header.outerHeight());var n=y["default"](":focus");if(n.length>0){var o=n.parents("th");if(o.length>0){var a=o.attr("data-field");if(void 0!==a){var s=this.$header.find("[data-field='".concat(a,"']"));s.length>0&&s.find(":input").addClass("focus-temp")}}}this.$header_=this.$header.clone(!0,!0),this.$selectAll_=this.$header_.find('[name="btSelectAll"]'),this.$tableHeader.css("margin-right",i).find("table").css("width",this.$el.outerWidth()).html("").attr("class",this.$el.attr("class")).append(this.$header_),this.$tableLoading.css("width",this.$el.outerWidth());var r=y["default"](".focus-temp:visible:eq(0)");r.length>0&&(r.focus(),this.$header.find(".focus-temp").removeClass("focus-temp")),this.$header.find("th[data-field]").each(function(e,i){t.$header_.find(ss.sprintf('th[data-field="%s"]',y["default"](i).data("field"))).data(y["default"](i).data())});for(var l=this.getVisibleFields(),c=this.$header_.find("th"),h=this.$body.find(">tr:not(.no-records-found,.virtual-scroll-top)").eq(0);h.length&&h.find('>td[colspan]:not([colspan="1"])').length;){h=h.next()}var u=h.find("> *").length;h.find("> *").each(function(e,i){var n=y["default"](i);if(ss.hasDetailViewIcon(t.options)&&(0===e&&"right"!==t.options.detailViewAlign||e===u-1&&"right"===t.options.detailViewAlign)){var o=c.filter(".detail"),a=o.innerWidth()-o.find(".fht-cell").width();return void o.find(".fht-cell").width(n.innerWidth()-a)}var s=e-ss.getDetailViewIndexOffset(t.options),r=t.$header_.find(ss.sprintf('th[data-field="%s"]',l[s]));r.length>1&&(r=y["default"](c[n[0].cellIndex]));var h=r.innerWidth()-r.find(".fht-cell").width();r.find(".fht-cell").width(n.innerWidth()-h)}),this.horizontalScroll(),this.trigger("post-header")}},{key:"initFooter",value:function(){if(this.options.showFooter&&!this.options.cardView){var t=this.getData(),e=[],i="";ss.hasDetailViewIcon(this.options)&&(i='
    '),i&&"right"!==this.options.detailViewAlign&&e.push(i);var n,o=v(this.columns);try{for(o.s();!(n=o.n()).done;){var a=n.value,r="",l="",c=[],h={},u=ss.sprintf(' class="%s"',a["class"]);if(a.visible&&(!(this.footerData&&this.footerData.length>0)||a.field in this.footerData[0])){if(this.options.cardView&&!a.cardVisible){return}if(r=ss.sprintf("text-align: %s; ",a.falign?a.falign:a.align),l=ss.sprintf("vertical-align: %s; ",a.valign),h=ss.calculateObjectValue(null,this.options.footerStyle,[a]),h&&h.css){for(var d=0,f=Object.entries(h.css);d0&&(m=this.footerData[0]["_".concat(a.field,"_colspan")]||0),m&&e.push(' colspan="'.concat(m,'" ')),e.push(">"),e.push('
    ');var y="";this.footerData&&this.footerData.length>0&&(y=this.footerData[0][a.field]||""),e.push(ss.calculateObjectValue(a,a.footerFormatter,[t,y],y)),e.push("
    "),e.push('
    '),e.push("
    "),e.push("")}}}catch(w){o.e(w)}finally{o.f()}i&&"right"===this.options.detailViewAlign&&e.push(i),this.options.height||this.$tableFooter.length||(this.$el.append(""),this.$tableFooter=this.$el.find("tfoot")),this.$tableFooter.find("tr").length||this.$tableFooter.html("
    "),this.$tableFooter.find("tr").html(e.join("")),this.trigger("post-footer",this.$tableFooter)}}},{key:"fitFooter",value:function(){var t=this;if(this.$el.is(":hidden")){return void setTimeout(function(){return t.fitFooter()},100)}var e=this.$tableBody.get(0),i=e.scrollWidth>e.clientWidth&&e.scrollHeight>e.clientHeight+this.$header.outerHeight()?ss.getScrollBarWidth():0;this.$tableFooter.css("margin-right",i).find("table").css("width",this.$el.outerWidth()).attr("class",this.$el.attr("class"));var n=this.$tableFooter.find("th"),o=this.$body.find(">tr:first-child:not(.no-records-found)");for(n.find(".fht-cell").width("auto");o.length&&o.find('>td[colspan]:not([colspan="1"])').length;){o=o.next()}var a=o.find("> *").length;o.find("> *").each(function(e,i){var o=y["default"](i);if(ss.hasDetailViewIcon(t.options)&&(0===e&&"left"===t.options.detailViewAlign||e===a-1&&"right"===t.options.detailViewAlign)){var s=n.filter(".detail"),r=s.innerWidth()-s.find(".fht-cell").width();return void s.find(".fht-cell").width(o.innerWidth()-r)}var l=n.eq(e),c=l.innerWidth()-l.find(".fht-cell").width();l.find(".fht-cell").width(o.innerWidth()-c)}),this.horizontalScroll()}},{key:"horizontalScroll",value:function(){var t=this;this.$tableBody.off("scroll").on("scroll",function(){var e=t.$tableBody.scrollLeft();t.options.showHeader&&t.options.height&&t.$tableHeader.scrollLeft(e),t.options.showFooter&&!t.options.cardView&&t.$tableFooter.scrollLeft(e),t.trigger("scroll-body",t.$tableBody)})}},{key:"getVisibleFields",value:function(){var t,e=[],i=v(this.header.fields);try{for(i.s();!(t=i.n()).done;){var n=t.value,o=this.columns[this.fieldsColumnsIndex[n]];o&&o.visible&&e.push(n)}}catch(a){i.e(a)}finally{i.f()}return e}},{key:"initHiddenRows",value:function(){this.hiddenRows=[]}},{key:"getOptions",value:function(){var t=y["default"].extend({},this.options);return delete t.data,y["default"].extend(!0,{},t)}},{key:"refreshOptions",value:function(t){ss.compareObjects(this.options,t,!0)||(this.options=y["default"].extend(this.options,t),this.trigger("refresh-options",this.options),this.destroy(),this.init())}},{key:"getData",value:function(t){var e=this,i=this.options.data;if(!(this.searchText||this.options.customSearch||void 0!==this.options.sortName||this.enableCustomSort)&&ss.isEmptyObject(this.filterColumns)&&ss.isEmptyObject(this.filterColumnsPartial)||t&&t.unfiltered||(i=this.data),t&&t.useCurrentPage&&(i=i.slice(this.pageFrom-1,this.pageTo)),t&&!t.includeHiddenRows){var n=this.getHiddenRows();i=i.filter(function(t){return -1===ss.findIndex(n,t)})}return t&&t.formatted&&i.forEach(function(t){for(var i=0,n=Object.entries(t);i=0;i--){var n=this.options.data[i];(n.hasOwnProperty(t.field)||"$index"===t.field)&&(!n.hasOwnProperty(t.field)&&"$index"===t.field&&t.values.includes(i)||t.values.includes(n[t.field]))&&(e++,this.options.data.splice(i,1))}e&&("server"===this.options.sidePagination&&(this.options.totalRows-=e,this.data=r(this.options.data)),this.initSearch(),this.initPagination(),this.initSort(),this.initBody(!0))}},{key:"removeAll",value:function(){this.options.data.length>0&&(this.options.data.splice(0,this.options.data.length),this.initSearch(),this.initPagination(),this.initBody(!0))}},{key:"insertRow",value:function(t){t.hasOwnProperty("index")&&t.hasOwnProperty("row")&&(this.options.data.splice(t.index,0,t.row),this.initSearch(),this.initPagination(),this.initSort(),this.initBody(!0))}},{key:"updateRow",value:function(t){var e,i=Array.isArray(t)?t:[t],n=v(i);try{for(n.s();!(e=n.n()).done;){var o=e.value;o.hasOwnProperty("index")&&o.hasOwnProperty("row")&&(o.hasOwnProperty("replace")&&o.replace?this.options.data[o.index]=o.row:y["default"].extend(this.options.data[o.index],o.row))}}catch(a){n.e(a)}finally{n.f()}this.initSearch(),this.initPagination(),this.initSort(),this.initBody(!0)}},{key:"getRowByUniqueId",value:function(t){var e,i,n,o=this.options.uniqueId,a=this.options.data.length,s=t,r=null;for(e=a-1;e>=0;e--){if(i=this.options.data[e],i.hasOwnProperty(o)){n=i[o]}else{if(!i._data||!i._data.hasOwnProperty(o)){continue}n=i._data[o]}if("string"==typeof n?s=""+s:"number"==typeof n&&(+n===n&&n%1===0?s=parseInt(s,10):n===+n&&0!==n&&(s=parseFloat(s))),n===s){r=i;break}}return r}},{key:"updateByUniqueId",value:function(t){var e,i=Array.isArray(t)?t:[t],n=null,o=v(i);try{for(o.s();!(e=o.n()).done;){var a=e.value;if(a.hasOwnProperty("id")&&a.hasOwnProperty("row")){var s=this.options.data.indexOf(this.getRowByUniqueId(a.id));-1!==s&&(a.hasOwnProperty("replace")&&a.replace?this.options.data[s]=a.row:y["default"].extend(this.options.data[s],a.row),n=a.id)}}}catch(r){o.e(r)}finally{o.f()}this.initSearch(),this.initPagination(),this.initSort(),this.initBody(!0,n)}},{key:"removeByUniqueId",value:function(t){var e=this.options.data.length,i=this.getRowByUniqueId(t);i&&this.options.data.splice(this.options.data.indexOf(i),1),e!==this.options.data.length&&("server"===this.options.sidePagination&&(this.options.totalRows-=1,this.data=r(this.options.data)),this.initSearch(),this.initPagination(),this.initBody(!0))}},{key:"updateCell",value:function(t){t.hasOwnProperty("index")&&t.hasOwnProperty("field")&&t.hasOwnProperty("value")&&(this.data[t.index][t.field]=t.value,t.reinit!==!1&&(this.initSort(),this.initBody(!0)))}},{key:"updateCellByUniqueId",value:function(t){var e=this,i=Array.isArray(t)?t:[t];i.forEach(function(t){var i=t.id,n=t.field,o=t.value,a=e.options.data.indexOf(e.getRowByUniqueId(i));-1!==a&&(e.options.data[a][n]=o)}),t.reinit!==!1&&(this.initSort(),this.initBody(!0))}},{key:"showRow",value:function(t){this._toggleRow(t,!0)}},{key:"hideRow",value:function(t){this._toggleRow(t,!1)}},{key:"_toggleRow",value:function(t,e){var i;if(t.hasOwnProperty("index")?i=this.getData()[t.index]:t.hasOwnProperty("uniqueId")&&(i=this.getRowByUniqueId(t.uniqueId)),i){var n=ss.findIndex(this.hiddenRows,i);e||-1!==n?e&&n>-1&&this.hiddenRows.splice(n,1):this.hiddenRows.push(i),this.initBody(!0),this.initPagination()}}},{key:"getHiddenRows",value:function(t){if(t){return this.initHiddenRows(),this.initBody(!0),void this.initPagination()}var e,i=this.getData(),n=[],o=v(i);try{for(o.s();!(e=o.n()).done;){var a=e.value;this.hiddenRows.includes(a)&&n.push(a)}}catch(s){o.e(s)}finally{o.f()}return this.hiddenRows=n,n}},{key:"showColumn",value:function(t){var e=this,i=Array.isArray(t)?t:[t];i.forEach(function(t){e._toggleColumn(e.fieldsColumnsIndex[t],!0,!0)})}},{key:"hideColumn",value:function(t){var e=this,i=Array.isArray(t)?t:[t];i.forEach(function(t){e._toggleColumn(e.fieldsColumnsIndex[t],!1,!0)})}},{key:"_toggleColumn",value:function(t,e,i){if(-1!==t&&this.columns[t].visible!==e&&(this.columns[t].visible=e,this.initHeader(),this.initSearch(),this.initPagination(),this.initBody(),this.options.showColumns)){var n=this.$toolbar.find('.keep-open input:not(".toggle-all")').prop("disabled",!1);i&&n.filter(ss.sprintf('[value="%s"]',t)).prop("checked",e),n.filter(":checked").length<=this.options.minimumCountColumns&&n.filter(":checked").prop("disabled",!0)}}},{key:"getVisibleColumns",value:function(){var t=this;return this.columns.filter(function(e){return e.visible&&!t.isSelectionColumn(e)})}},{key:"getHiddenColumns",value:function(){return this.columns.filter(function(t){var e=t.visible;return !e})}},{key:"isSelectionColumn",value:function(t){return t.radio||t.checkbox}},{key:"showAllColumns",value:function(){this._toggleAllColumns(!0)}},{key:"hideAllColumns",value:function(){this._toggleAllColumns(!1)}},{key:"_toggleAllColumns",value:function(t){var e,i=this,n=v(this.columns.slice().reverse());try{for(n.s();!(e=n.n()).done;){var o=e.value;if(o.switchable){if(!t&&this.options.showColumns&&this.getVisibleColumns().length===this.options.minimumCountColumns){continue}o.visible=t}}}catch(a){n.e(a)}finally{n.f()}if(this.initHeader(),this.initSearch(),this.initPagination(),this.initBody(),this.options.showColumns){var s=this.$toolbar.find('.keep-open input[type="checkbox"]:not(".toggle-all")').prop("disabled",!1);t?s.prop("checked",t):s.get().reverse().forEach(function(e){s.filter(":checked").length>i.options.minimumCountColumns&&y["default"](e).prop("checked",t)}),s.filter(":checked").length<=this.options.minimumCountColumns&&s.filter(":checked").prop("disabled",!0)}}},{key:"mergeCells",value:function(t){var e,i,n=t.index,o=this.getVisibleFields().indexOf(t.field),a=t.rowspan||1,s=t.colspan||1,r=this.$body.find(">tr[data-index]");o+=ss.getDetailViewIndexOffset(this.options);var l=r.eq(n).find(">td").eq(o);if(!(0>n||0>o||n>=this.data.length)){for(e=n;n+a>e;e++){for(i=o;o+s>i;i++){r.eq(e).find(">td").eq(i).hide()}}l.attr("rowspan",a).attr("colspan",s).show()}}},{key:"checkAll",value:function(){this._toggleCheckAll(!0)}},{key:"uncheckAll",value:function(){this._toggleCheckAll(!1)}},{key:"_toggleCheckAll",value:function(t){var e=this.getSelections();this.$selectAll.add(this.$selectAll_).prop("checked",t),this.$selectItem.filter(":enabled").prop("checked",t),this.updateRows(),this.updateSelected();var i=this.getSelections();return t?void this.trigger("check-all",i,e):void this.trigger("uncheck-all",i,e)}},{key:"checkInvert",value:function(){var t=this.$selectItem.filter(":enabled"),e=t.filter(":checked");t.each(function(t,e){y["default"](e).prop("checked",!y["default"](e).prop("checked"))}),this.updateRows(),this.updateSelected(),this.trigger("uncheck-some",e),e=this.getSelections(),this.trigger("check-some",e)}},{key:"check",value:function(t){this._toggleCheck(!0,t)}},{key:"uncheck",value:function(t){this._toggleCheck(!1,t)}},{key:"_toggleCheck",value:function(t,e){var i=this.$selectItem.filter('[data-index="'.concat(e,'"]')),n=this.data[e];if(i.is(":radio")||this.options.singleSelect||this.options.multipleSelectRow&&!this.multipleSelectRowCtrlKey&&!this.multipleSelectRowShiftKey){var o,a=v(this.options.data);try{for(a.s();!(o=a.n()).done;){var r=o.value;r[this.header.stateField]=!1}}catch(l){a.e(l)}finally{a.f()}this.$selectItem.filter(":checked").not(i).prop("checked",!1)}if(n[this.header.stateField]=t,this.options.multipleSelectRow){if(this.multipleSelectRowShiftKey&&this.multipleSelectRowLastSelectedIndex>=0){for(var c=this.multipleSelectRowLastSelectedIndexf;f++){this.data[f][this.header.stateField]=!0,this.$selectItem.filter('[data-index="'.concat(f,'"]')).prop("checked",!0)}}this.multipleSelectRowCtrlKey=!1,this.multipleSelectRowShiftKey=!1,this.multipleSelectRowLastSelectedIndex=t?e:-1}i.prop("checked",t),this.updateSelected(),this.trigger(t?"check":"uncheck",this.data[e],i)}},{key:"checkBy",value:function(t){this._toggleCheckBy(!0,t)}},{key:"uncheckBy",value:function(t){this._toggleCheckBy(!1,t)}},{key:"_toggleCheckBy",value:function(t,e){var i=this;if(e.hasOwnProperty("field")&&e.hasOwnProperty("values")){var n=[];this.data.forEach(function(o,a){if(!o.hasOwnProperty(e.field)){return !1}if(e.values.includes(o[e.field])){var s=i.$selectItem.filter(":enabled").filter(ss.sprintf('[data-index="%s"]',a)),r=e.hasOwnProperty("onlyCurrentPage")?e.onlyCurrentPage:!1;if(s=t?s.not(":checked"):s.filter(":checked"),!s.length&&r){return}s.prop("checked",t),o[i.header.stateField]=t,n.push(o),i.trigger(t?"check":"uncheck",o,s)}}),this.updateSelected(),this.trigger(t?"check-some":"uncheck-some",n)}}},{key:"refresh",value:function(t){t&&t.url&&(this.options.url=t.url),t&&t.pageNumber&&(this.options.pageNumber=t.pageNumber),t&&t.pageSize&&(this.options.pageSize=t.pageSize),table.rememberSelecteds={},table.rememberSelectedIds={},this.trigger("refresh",this.initServer(t&&t.silent,t&&t.query,t&&t.url))}},{key:"destroy",value:function(){this.$el.insertBefore(this.$container),y["default"](this.options.toolbar).insertBefore(this.$el),this.$container.next().remove(),this.$container.remove(),this.$el.html(this.$el_.html()).css("margin-top","0").attr("class",this.$el_.attr("class")||"")}},{key:"resetView",value:function(t){var e=0;if(t&&t.height&&(this.options.height=t.height),this.$tableContainer.toggleClass("has-card-view",this.options.cardView),!this.options.cardView&&this.options.showHeader&&this.options.height?(this.$tableHeader.show(),this.resetHeader(),e+=this.$header.outerHeight(!0)+1):(this.$tableHeader.hide(),this.trigger("post-header")),!this.options.cardView&&this.options.showFooter&&(this.$tableFooter.show(),this.fitFooter(),this.options.height&&(e+=this.$tableFooter.outerHeight(!0))),this.$container.hasClass("fullscreen")){this.$tableContainer.css("height",""),this.$tableContainer.css("width","")}else{if(this.options.height){this.$tableBorder&&(this.$tableBorder.css("width",""),this.$tableBorder.css("height",""));var i=this.$toolbar.outerHeight(!0),n=this.$pagination.outerHeight(!0),o=this.options.height-i-n,a=this.$tableBody.find(">table"),s=a.outerHeight();if(this.$tableContainer.css("height","".concat(o,"px")),this.$tableBorder&&a.is(":visible")){var r=o-s-2;this.$tableBody[0].scrollWidth-this.$tableBody.innerWidth()&&(r-=ss.getScrollBarWidth()),this.$tableBorder.css("width","".concat(a.outerWidth(),"px")),this.$tableBorder.css("height","".concat(r,"px"))}}}this.options.cardView?(this.$el.css("margin-top","0"),this.$tableContainer.css("padding-bottom","0"),this.$tableFooter.hide()):(this.getCaret(),this.$tableContainer.css("padding-bottom","".concat(e,"px"))),this.trigger("reset-view")}},{key:"showLoading",value:function(){this.$tableLoading.toggleClass("open",!0);var t=this.options.loadingFontSize;"auto"===this.options.loadingFontSize&&(t=0.04*this.$tableLoading.width(),t=Math.max(12,t),t=Math.min(32,t),t="".concat(t,"px")),this.$tableLoading.find(".loading-text").css("font-size",t)}},{key:"hideLoading",value:function(){this.$tableLoading.toggleClass("open",!1)}},{key:"toggleShowSearch",value:function(){this.$el.parents(".select-table").siblings().slideToggle()}},{key:"togglePagination",value:function(){this.options.pagination=!this.options.pagination;var t=this.options.showButtonIcons?this.options.pagination?this.options.icons.paginationSwitchDown:this.options.icons.paginationSwitchUp:"",e=this.options.showButtonText?this.options.pagination?this.options.formatPaginationSwitchUp():this.options.formatPaginationSwitchDown():"";this.$toolbar.find('button[name="paginationSwitch"]').html("".concat(ss.sprintf(this.constants.html.icon,this.options.iconsPrefix,t)," ").concat(e)),this.updatePagination(),this.trigger("toggle-pagination",this.options.pagination)}},{key:"toggleFullscreen",value:function(){this.$el.closest(".bootstrap-table").toggleClass("fullscreen"),this.resetView()}},{key:"toggleView",value:function(){this.options.cardView=!this.options.cardView,this.initHeader();var t=this.options.showButtonIcons?this.options.cardView?this.options.icons.toggleOn:this.options.icons.toggleOff:"",e=this.options.showButtonText?this.options.cardView?this.options.formatToggleOff():this.options.formatToggleOn():"";this.$toolbar.find('button[name="toggle"]').html("".concat(ss.sprintf(this.constants.html.icon,this.options.iconsPrefix,t)," ").concat(e)),this.initBody(),this.trigger("toggle",this.options.cardView)}},{key:"resetSearch",value:function(t){var e=ss.getSearchInput(this);e.val(t||""),this.onSearch({currentTarget:e})}},{key:"filterBy",value:function(t,e){this.filterOptions=ss.isEmptyObject(e)?this.options.filterOptions:y["default"].extend(this.options.filterOptions,e),this.filterColumns=ss.isEmptyObject(t)?{}:t,this.options.pageNumber=1,this.initSearch(),this.updatePagination()}},{key:"scrollTo",value:function o(t){var e={unit:"px",value:0};"object"===i(t)?e=Object.assign(e,t):"string"==typeof t&&"bottom"===t?e.value=this.$tableBody[0].scrollHeight:("string"==typeof t||"number"==typeof t)&&(e.value=t);var o=e.value;"rows"===e.unit&&(o=0,this.$body.find("> tr:lt(".concat(e.value,")")).each(function(t,e){o+=y["default"](e).outerHeight(!0)})),this.$tableBody.scrollTop(o)}},{key:"getScrollPosition",value:function(){return this.$tableBody.scrollTop()}},{key:"selectPage",value:function(t){t>0&&t<=this.options.totalPages&&(this.options.pageNumber=t,this.updatePagination())}},{key:"prevPage",value:function(){this.options.pageNumber>1&&(this.options.pageNumber--,this.updatePagination())}},{key:"nextPage",value:function(){this.options.pageNumber tr[data-index="%s"]',t));i.next().is("tr.detail-view")?this.collapseRow(t):this.expandRow(t,e),this.resetView()}},{key:"expandRow",value:function(t,e){var i=this.data[t],n=this.$body.find(ss.sprintf('> tr[data-index="%s"][data-has-detail-view]',t));if(this.options.detailViewIcon&&n.find("a.detail-icon").html(ss.sprintf(this.constants.html.icon,this.options.iconsPrefix,this.options.icons.detailClose)),!n.next().is("tr.detail-view")){n.after(ss.sprintf('',n.children("td").length));var o=n.next().find("td"),a=e||this.options.detailFormatter,s=ss.calculateObjectValue(this.options,a,[t,i,o],"");1===o.length&&o.append(s),this.trigger("expand-row",t,i,o)}}},{key:"expandRowByUniqueId",value:function(t){var e=this.getRowByUniqueId(t);e&&this.expandRow(this.data.indexOf(e))}},{key:"collapseRow",value:function(t){var e=this.data[t],i=this.$body.find(ss.sprintf('> tr[data-index="%s"][data-has-detail-view]',t));i.next().is("tr.detail-view")&&(this.options.detailViewIcon&&i.find("a.detail-icon").html(ss.sprintf(this.constants.html.icon,this.options.iconsPrefix,this.options.icons.detailOpen)),this.trigger("collapse-row",t,e,i.next()),i.next().remove())}},{key:"collapseRowByUniqueId",value:function(t){var e=this.getRowByUniqueId(t);e&&this.collapseRow(this.data.indexOf(e))}},{key:"expandAllRows",value:function(){for(var t=this.$body.find("> tr[data-index][data-has-detail-view]"),e=0;e tr[data-index][data-has-detail-view]"),e=0;e1?e-1:0),o=1;e>o;o++){n[o-1]=arguments[o]}var a;return this.each(function(e,o){var s=y["default"](o).data("bootstrap.table"),r=y["default"].extend({},hs.DEFAULTS,y["default"](o).data(),"object"===i(t)&&t);if("string"==typeof t){var l;if(!Ka.METHODS.includes(t)){throw Error("Unknown method: ".concat(t))}if(!s){return}a=(l=s)[t].apply(l,n),"destroy"===t&&y["default"](o).removeData("bootstrap.table")}s||(s=new y["default"].BootstrapTable(o,r),y["default"](o).data("bootstrap.table",s),s.init())}),void 0===a?this:a},y["default"].fn.bootstrapTable.Constructor=hs,y["default"].fn.bootstrapTable.theme=Ka.THEME,y["default"].fn.bootstrapTable.VERSION=Ka.VERSION,y["default"].fn.bootstrapTable.defaults=hs.DEFAULTS,y["default"].fn.bootstrapTable.columnDefaults=hs.COLUMN_DEFAULTS,y["default"].fn.bootstrapTable.events=hs.EVENTS,y["default"].fn.bootstrapTable.locales=hs.LOCALES,y["default"].fn.bootstrapTable.methods=hs.METHODS,y["default"].fn.bootstrapTable.utils=ss,y["default"](function(){y["default"]('[data-toggle="table"]').bootstrapTable()}),hs});var TABLE_EVENTS="all.bs.table click-cell.bs.table dbl-click-cell.bs.table click-row.bs.table dbl-click-row.bs.table sort.bs.table check.bs.table uncheck.bs.table onUncheck check-all.bs.table uncheck-all.bs.table check-some.bs.table uncheck-some.bs.table load-success.bs.table load-error.bs.table column-switch.bs.table page-change.bs.table search.bs.table toggle.bs.table show-search.bs.table expand-row.bs.table collapse-row.bs.table refresh-options.bs.table reset-view.bs.table refresh.bs.table",firstLoadTable=[],union=function(t,e){return $.isPlainObject(e)?addRememberRow(t,e):$.isArray(e)?$.each(e,function(e,i){$.isPlainObject(i)?addRememberRow(t,i):-1==$.inArray(i,t)&&(t[t.length]=i)}):-1==$.inArray(e,t)&&(t[t.length]=e),t},difference=function(t,e){if($.isPlainObject(e)){removeRememberRow(t,e)}else{if($.isArray(e)){$.each(e,function(e,i){if($.isPlainObject(i)){removeRememberRow(t,i)}else{var n=$.inArray(i,t);-1!=n&&t.splice(n,1)}})}else{var i=$.inArray(e,t);-1!=i&&t.splice(i,1)}}return t},_={union:union,difference:difference}; \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/auto-refresh/bootstrap-table-auto-refresh.js b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/auto-refresh/bootstrap-table-auto-refresh.js new file mode 100644 index 000000000..f1421856a --- /dev/null +++ b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/auto-refresh/bootstrap-table-auto-refresh.js @@ -0,0 +1,95 @@ +/** + * @author: Alec Fenichel + * @webSite: https://fenichelar.com + * @update: zhixin wen + */ + +var Utils = $.fn.bootstrapTable.utils + +$.extend($.fn.bootstrapTable.defaults, { + autoRefresh: false, + showAutoRefresh: true, + autoRefreshInterval: 60, + autoRefreshSilent: true, + autoRefreshStatus: true, + autoRefreshFunction: null +}) + +$.extend($.fn.bootstrapTable.defaults.icons, { + autoRefresh: { + bootstrap3: 'glyphicon-time icon-time', + bootstrap5: 'bi-clock', + materialize: 'access_time', + 'bootstrap-table': 'icon-clock' + }[$.fn.bootstrapTable.theme] || 'fa-clock' +}) + +$.extend($.fn.bootstrapTable.locales, { + formatAutoRefresh () { + return 'Auto Refresh' + } +}) + +$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales) + +$.BootstrapTable = class extends $.BootstrapTable { + init (...args) { + super.init(...args) + + if (this.options.autoRefresh && this.options.autoRefreshStatus) { + this.setupRefreshInterval() + } + } + + initToolbar (...args) { + if (this.options.autoRefresh) { + this.buttons = Object.assign(this.buttons, { + autoRefresh: { + html: ` + + `, + event: this.toggleAutoRefresh + } + }) + } + + super.initToolbar(...args) + } + + toggleAutoRefresh () { + if (this.options.autoRefresh) { + if (this.options.autoRefreshStatus) { + clearInterval(this.options.autoRefreshFunction) + this.$toolbar.find('>.columns .auto-refresh') + .removeClass(this.constants.classes.buttonActive) + } else { + this.setupRefreshInterval() + this.$toolbar.find('>.columns .auto-refresh') + .addClass(this.constants.classes.buttonActive) + } + this.options.autoRefreshStatus = !this.options.autoRefreshStatus + } + } + + destroy () { + if (this.options.autoRefresh && this.options.autoRefreshStatus) { + clearInterval(this.options.autoRefreshFunction) + } + + super.destroy() + } + + setupRefreshInterval () { + this.options.autoRefreshFunction = setInterval(() => { + if (!this.options.autoRefresh || !this.options.autoRefreshStatus) { + return + } + this.refresh({ silent: this.options.autoRefreshSilent }) + }, this.options.autoRefreshInterval * 1000) + } +} diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/columns/bootstrap-table-fixed-columns.js b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/columns/bootstrap-table-fixed-columns.js new file mode 100644 index 000000000..1cbb1934a --- /dev/null +++ b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/columns/bootstrap-table-fixed-columns.js @@ -0,0 +1,405 @@ +/** + * @author zhixin wen + */ + +var Utils = $.fn.bootstrapTable.utils + +// Reasonable defaults +const PIXEL_STEP = 10 +const LINE_HEIGHT = 40 +const PAGE_HEIGHT = 800 + +function normalizeWheel (event) { + let sX = 0 // spinX + let sY = 0 // spinY + let pX = 0 // pixelX + let pY = 0 // pixelY + + // Legacy + if ('detail' in event) { sY = event.detail } + if ('wheelDelta' in event) { sY = -event.wheelDelta / 120 } + if ('wheelDeltaY' in event) { sY = -event.wheelDeltaY / 120 } + if ('wheelDeltaX' in event) { sX = -event.wheelDeltaX / 120 } + + // side scrolling on FF with DOMMouseScroll + if ('axis' in event && event.axis === event.HORIZONTAL_AXIS) { + sX = sY + sY = 0 + } + + pX = sX * PIXEL_STEP + pY = sY * PIXEL_STEP + + if ('deltaY' in event) { pY = event.deltaY } + if ('deltaX' in event) { pX = event.deltaX } + + if ((pX || pY) && event.deltaMode) { + if (event.deltaMode === 1) { // delta in LINE units + pX *= LINE_HEIGHT + pY *= LINE_HEIGHT + } else { // delta in PAGE units + pX *= PAGE_HEIGHT + pY *= PAGE_HEIGHT + } + } + + // Fall-back if spin cannot be determined + if (pX && !sX) { sX = (pX < 1) ? -1 : 1 } + if (pY && !sY) { sY = (pY < 1) ? -1 : 1 } + + return { + spinX: sX, + spinY: sY, + pixelX: pX, + pixelY: pY + } +} + +$.extend($.fn.bootstrapTable.defaults, { + fixedColumns: false, + fixedNumber: 0, + fixedRightNumber: 0 +}) + +$.BootstrapTable = class extends $.BootstrapTable { + + fixedColumnsSupported () { + return this.options.fixedColumns && + !this.options.detailView && + !this.options.cardView + } + + initContainer () { + super.initContainer() + + if (!this.fixedColumnsSupported()) { + return + } + + if (this.options.fixedNumber) { + this.$tableContainer.append('
    ') + this.$fixedColumns = this.$tableContainer.find('.fixed-columns') + } + + if (this.options.fixedRightNumber) { + this.$tableContainer.append('
    ') + this.$fixedColumnsRight = this.$tableContainer.find('.fixed-columns-right') + } + } + + initBody (...args) { + super.initBody(...args) + + if (this.$fixedColumns && this.$fixedColumns.length) { + this.$fixedColumns.toggle(this.fixedColumnsSupported()) + } + if (this.$fixedColumnsRight && this.$fixedColumnsRight.length) { + this.$fixedColumnsRight.toggle(this.fixedColumnsSupported()) + } + + if (!this.fixedColumnsSupported()) { + return + } + + if (this.options.showHeader && this.options.height) { + return + } + + this.initFixedColumnsBody() + this.initFixedColumnsEvents() + } + + trigger (...args) { + super.trigger(...args) + + if (!this.fixedColumnsSupported()) { + return + } + + if (args[0] === 'post-header') { + this.initFixedColumnsHeader() + } else if (args[0] === 'scroll-body') { + if (this.needFixedColumns && this.options.fixedNumber) { + this.$fixedBody.scrollTop(this.$tableBody.scrollTop()) + } + + if (this.needFixedColumns && this.options.fixedRightNumber) { + this.$fixedBodyRight.scrollTop(this.$tableBody.scrollTop()) + } + } + } + + updateSelected () { + super.updateSelected() + + if (!this.fixedColumnsSupported()) { + return + } + + this.$tableBody.find('tr').each((i, el) => { + const $el = $(el) + const index = $el.data('index') + const classes = $el.attr('class') + + const inputSelector = `[name="${this.options.selectItemName}"]` + const $input = $el.find(inputSelector) + + if (typeof index === undefined) { + return + } + + const updateFixedBody = ($fixedHeader, $fixedBody) => { + const $tr = $fixedBody.find(`tr[data-index="${index}"]`) + + $tr.attr('class', classes) + + if ($input.length) { + $tr.find(inputSelector).prop('checked', $input.prop('checked')) + } + + if (this.$selectAll.length) { + $fixedHeader.add($fixedBody) + .find('[name="btSelectAll"]') + .prop('checked', this.$selectAll.prop('checked')) + } + } + + if (this.$fixedBody && this.options.fixedNumber) { + updateFixedBody(this.$fixedHeader, this.$fixedBody) + } + + if (this.$fixedBodyRight && this.options.fixedRightNumber) { + updateFixedBody(this.$fixedHeaderRight, this.$fixedBodyRight) + } + }) + } + + hideLoading () { + super.hideLoading() + + if (this.needFixedColumns && this.options.fixedNumber) { + this.$fixedColumns.find('.fixed-table-loading').hide() + } + + if (this.needFixedColumns && this.options.fixedRightNumber) { + this.$fixedColumnsRight.find('.fixed-table-loading').hide() + } + } + + initFixedColumnsHeader () { + if (this.options.height) { + this.needFixedColumns = this.$tableHeader.outerWidth(true) < this.$tableHeader.find('table').outerWidth(true) + } else { + this.needFixedColumns = this.$tableBody.outerWidth(true) < this.$tableBody.find('table').outerWidth(true) + } + + const initFixedHeader = ($fixedColumns, isRight) => { + $fixedColumns.find('.fixed-table-header').remove() + $fixedColumns.append(this.$tableHeader.clone(true)) + + $fixedColumns.css({ + width: this.getFixedColumnsWidth(isRight) + }) + return $fixedColumns.find('.fixed-table-header') + } + + if (this.needFixedColumns && this.options.fixedNumber) { + this.$fixedHeader = initFixedHeader(this.$fixedColumns) + this.$fixedHeader.css('margin-right', '') + } else if (this.$fixedColumns) { + this.$fixedColumns.html('').css('width', '') + } + + if (this.needFixedColumns && this.options.fixedRightNumber) { + this.$fixedHeaderRight = initFixedHeader(this.$fixedColumnsRight, true) + this.$fixedHeaderRight.scrollLeft(this.$fixedHeaderRight.find('table').width()) + } else if (this.$fixedColumnsRight) { + this.$fixedColumnsRight.html('').css('width', '') + } + + this.initFixedColumnsBody() + this.initFixedColumnsEvents() + } + + initFixedColumnsBody () { + const initFixedBody = ($fixedColumns, $fixedHeader) => { + $fixedColumns.find('.fixed-table-body').remove() + $fixedColumns.append(this.$tableBody.clone(true)) + $fixedColumns.find('.fixed-table-body table').removeAttr('id') + + const $fixedBody = $fixedColumns.find('.fixed-table-body') + + const tableBody = this.$tableBody.get(0) + const scrollHeight = tableBody.scrollWidth > tableBody.clientWidth ? + Utils.getScrollBarWidth() : 0 + const height = this.$tableContainer.outerHeight(true) - scrollHeight - 1 + + $fixedColumns.css({ + height + }) + + $fixedBody.css({ + height: height - $fixedHeader.height() + }) + + return $fixedBody + } + + if (this.needFixedColumns && this.options.fixedNumber) { + this.$fixedBody = initFixedBody(this.$fixedColumns, this.$fixedHeader) + } + + if (this.needFixedColumns && this.options.fixedRightNumber) { + this.$fixedBodyRight = initFixedBody(this.$fixedColumnsRight, this.$fixedHeaderRight) + this.$fixedBodyRight.scrollLeft(this.$fixedBodyRight.find('table').width()) + this.$fixedBodyRight.css('overflow-y', this.options.height ? 'auto' : 'hidden') + } + } + + getFixedColumnsWidth (isRight) { + let visibleFields = this.getVisibleFields() + let width = 0 + let fixedNumber = this.options.fixedNumber + let marginRight = 0 + + if (isRight) { + visibleFields = visibleFields.reverse() + fixedNumber = this.options.fixedRightNumber + marginRight = parseInt(this.$tableHeader.css('margin-right'), 10) + } + + for (let i = 0; i < fixedNumber; i++) { + width += this.$header.find(`th[data-field="${visibleFields[i]}"]`).outerWidth(true) + } + + return width + marginRight + 1 + } + + initFixedColumnsEvents () { + const toggleHover = (e, toggle) => { + const tr = `tr[data-index="${$(e.currentTarget).data('index')}"]` + let $trs = this.$tableBody.find(tr) + + if (this.$fixedBody) { + $trs = $trs.add(this.$fixedBody.find(tr)) + } + if (this.$fixedBodyRight) { + $trs = $trs.add(this.$fixedBodyRight.find(tr)) + } + + $trs.css('background-color', toggle ? $(e.currentTarget).css('background-color') : '') + } + + this.$tableBody.find('tr').hover(e => { + toggleHover(e, true) + }, e => { + toggleHover(e, false) + }) + + const isFirefox = typeof navigator !== 'undefined' && + navigator.userAgent.toLowerCase().indexOf('firefox') > -1 + const mousewheel = isFirefox ? 'DOMMouseScroll' : 'mousewheel' + const updateScroll = (e, fixedBody) => { + const normalized = normalizeWheel(e) + const deltaY = Math.ceil(normalized.pixelY) + const top = this.$tableBody.scrollTop() + deltaY + + if ( + deltaY < 0 && top > 0 || + deltaY > 0 && top < fixedBody.scrollHeight - fixedBody.clientHeight + ) { + e.preventDefault() + } + + this.$tableBody.scrollTop(top) + if (this.$fixedBody) { + this.$fixedBody.scrollTop(top) + } + if (this.$fixedBodyRight) { + this.$fixedBodyRight.scrollTop(top) + } + } + + if (this.needFixedColumns && this.options.fixedNumber) { + this.$fixedBody.find('tr').hover(e => { + toggleHover(e, true) + }, e => { + toggleHover(e, false) + }) + + this.$fixedBody[0].addEventListener(mousewheel, e => { + updateScroll(e, this.$fixedBody[0]) + }) + } + + if (this.needFixedColumns && this.options.fixedRightNumber) { + this.$fixedBodyRight.find('tr').hover(e => { + toggleHover(e, true) + }, e => { + toggleHover(e, false) + }) + + this.$fixedBodyRight.off('scroll').on('scroll', () => { + const top = this.$fixedBodyRight.scrollTop() + + this.$tableBody.scrollTop(top) + if (this.$fixedBody) { + this.$fixedBody.scrollTop(top) + } + }) + } + + if (this.options.filterControl) { + $(this.$fixedColumns).off('keyup change').on('keyup change', e => { + const $target = $(e.target) + const value = $target.val() + const field = $target.parents('th').data('field') + const $coreTh = this.$header.find(`th[data-field="${field}"]`) + + if ($target.is('input')) { + $coreTh.find('input').val(value) + } else if ($target.is('select')) { + const $select = $coreTh.find('select') + + $select.find('option[selected]').removeAttr('selected') + $select.find(`option[value="${value}"]`).attr('selected', true) + } + + this.triggerSearch() + }) + } + } + + renderStickyHeader () { + if (!this.options.stickyHeader) { + return + } + + this.$stickyContainer = this.$container.find('.sticky-header-container') + super.renderStickyHeader() + + if (this.needFixedColumns && this.options.fixedNumber) { + this.$fixedColumns.css('z-index', 101) + .find('.sticky-header-container') + .css('right', '') + .width(this.$fixedColumns.outerWidth()) + } + + if (this.needFixedColumns && this.options.fixedRightNumber) { + const $stickyHeaderContainerRight = this.$fixedColumnsRight.find('.sticky-header-container') + + this.$fixedColumnsRight.css('z-index', 101) + $stickyHeaderContainerRight.css('left', '') + .scrollLeft($stickyHeaderContainerRight.find('.table').outerWidth()) + .width(this.$fixedColumnsRight.outerWidth()) + } + } + + matchPositionX () { + if (!this.options.stickyHeader) { + return + } + + this.$stickyContainer.eq(0).scrollLeft(this.$tableBody.scrollLeft()) + } +} diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/custom-view/bootstrap-table-custom-view.js b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/custom-view/bootstrap-table-custom-view.js new file mode 100644 index 000000000..e9c978e8f --- /dev/null +++ b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/custom-view/bootstrap-table-custom-view.js @@ -0,0 +1,109 @@ +/** + * @author: Dustin Utecht + * @github: https://github.com/UtechtDustin + */ + +var Utils = $.fn.bootstrapTable.utils + +$.extend($.fn.bootstrapTable.defaults, { + customView: false, + showCustomView: false, + showCustomViewButton: false +}) + +$.extend($.fn.bootstrapTable.defaults.icons, { + customView: { + bootstrap3: 'glyphicon glyphicon-eye-open', + bootstrap5: 'bi-eye', + bootstrap4: 'fa fa-eye', + semantic: 'fa fa-eye', + foundation: 'fa fa-eye', + bulma: 'fa fa-eye', + materialize: 'remove_red_eye' + }[$.fn.bootstrapTable.theme] || 'fa-eye' +}) + +$.extend($.fn.bootstrapTable.defaults, { + onCustomViewPostBody () { + return false + }, + onCustomViewPreBody () { + return false + } +}) + +$.extend($.fn.bootstrapTable.locales, { + formatToggleCustomView () { + return 'Toggle custom view' + } +}) +$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales) + +$.fn.bootstrapTable.methods.push('toggleCustomView') + +$.extend($.fn.bootstrapTable.Constructor.EVENTS, { + 'custom-view-post-body.bs.table': 'onCustomViewPostBody', + 'custom-view-pre-body.bs.table': 'onCustomViewPreBody' +}) + +$.BootstrapTable = class extends $.BootstrapTable { + + init () { + this.showCustomView = this.options.showCustomView + + super.init() + } + + initToolbar (...args) { + if (this.options.customView && this.options.showCustomViewButton) { + this.buttons = Object.assign(this.buttons, { + customView: { + text: this.options.formatToggleCustomView(), + icon: this.options.icons.customView, + event: this.toggleCustomView, + attributes: { + 'aria-label': this.options.formatToggleCustomView(), + title: this.options.formatToggleCustomView() + } + } + }) + } + + super.initToolbar(...args) + } + + initBody () { + super.initBody() + + if (!this.options.customView) { + return + } + + const $table = this.$el + const $customViewContainer = this.$container.find('.fixed-table-custom-view') + + $table.hide() + $customViewContainer.hide() + if (!this.options.customView || !this.showCustomView) { + $table.show() + return + } + + const data = this.getData().slice(this.pageFrom - 1, this.pageTo) + const value = Utils.calculateObjectValue(this, this.options.customView, [data], '') + + this.trigger('custom-view-pre-body', data, value) + if ($customViewContainer.length === 1) { + $customViewContainer.show().html(value) + } else { + this.$tableBody.after(`
    ${value}
    `) + } + + this.trigger('custom-view-post-body', data, value) + } + + toggleCustomView () { + this.showCustomView = !this.showCustomView + this.initBody() + } +} diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/editable/bootstrap-editable.css b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/editable/bootstrap-editable.css new file mode 100644 index 000000000..7cd449720 --- /dev/null +++ b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/editable/bootstrap-editable.css @@ -0,0 +1,663 @@ +/*! X-editable - v1.5.1 +* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery +* http://github.com/vitalets/x-editable +* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */ +.editableform { + margin-bottom: 0; /* overwrites bootstrap margin */ +} + +.editableform .control-group { + margin-bottom: 0; /* overwrites bootstrap margin */ + white-space: nowrap; /* prevent wrapping buttons on new line */ + line-height: 20px; /* overwriting bootstrap line-height. See #133 */ +} + +/* + BS3 width:1005 for inputs breaks editable form in popup + See: https://github.com/vitalets/x-editable/issues/393 +*/ +.editableform .form-control { + width: auto; +} + +.editable-buttons { + display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */ + vertical-align: top; + margin-left: 7px; + /* inline-block emulation for IE7*/ + zoom: 1; + *display: inline; +} + +.editable-buttons.editable-buttons-bottom { + display: block; + margin-top: 7px; + margin-left: 0; +} + +.editable-input { + vertical-align: top; + display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */ + width: auto; /* bootstrap-responsive has width: 100% that breakes layout */ + white-space: normal; /* reset white-space decalred in parent*/ + /* display-inline emulation for IE7*/ + zoom: 1; + *display: inline; +} + +.editable-buttons .editable-cancel { + margin-left: 7px; +} + +/*for jquery-ui buttons need set height to look more pretty*/ +.editable-buttons button.ui-button-icon-only { + height: 24px; + width: 30px; +} + +.editableform-loading { + background: url('loading.gif') center center no-repeat; + height: 25px; + width: auto; + min-width: 25px; +} + +.editable-inline .editableform-loading { + background-position: left 5px; +} + + .editable-error-block { + max-width: 300px; + margin: 5px 0 0 0; + width: auto; + white-space: normal; +} + +/*add padding for jquery ui*/ +.editable-error-block.ui-state-error { + padding: 3px; +} + +.editable-error { + color: red; +} + +/* ---- For specific types ---- */ + +.editableform .editable-date { + padding: 0; + margin: 0; + float: left; +} + +/* move datepicker icon to center of add-on button. See https://github.com/vitalets/x-editable/issues/183 */ +.editable-inline .add-on .icon-th { + margin-top: 3px; + margin-left: 1px; +} + + +/* checklist vertical alignment */ +.editable-checklist label input[type="checkbox"], +.editable-checklist label span { + vertical-align: middle; + margin: 0; +} + +.editable-checklist label { + white-space: nowrap; +} + +/* set exact width of textarea to fit buttons toolbar */ +.editable-wysihtml5 { + width: 566px; + height: 250px; +} + +/* clear button shown as link in date inputs */ +.editable-clear { + clear: both; + font-size: 0.9em; + text-decoration: none; + text-align: right; +} + +/* IOS-style clear button for text inputs */ +.editable-clear-x { + background: url('clear.png') center center no-repeat; + display: block; + width: 13px; + height: 13px; + position: absolute; + opacity: 0.6; + z-index: 100; + + top: 50%; + right: 6px; + margin-top: -6px; + +} + +.editable-clear-x:hover { + opacity: 1; +} + +.editable-pre-wrapped { + white-space: pre-wrap; +} +.editable-container.editable-popup { + max-width: none !important; /* without this rule poshytip/tooltip does not stretch */ +} + +.editable-container.popover { + width: auto; /* without this rule popover does not stretch */ +} + +.editable-container.editable-inline { + display: inline-block; + vertical-align: middle; + width: auto; + /* inline-block emulation for IE7*/ + zoom: 1; + *display: inline; +} + +.editable-container.ui-widget { + font-size: inherit; /* jqueryui widget font 1.1em too big, overwrite it */ + z-index: 9990; /* should be less than select2 dropdown z-index to close dropdown first when click */ +} +.editable-click, +a.editable-click, +a.editable-click:hover { + text-decoration: none; + border-bottom: dashed 1px #0088cc; +} + +.editable-click.editable-disabled, +a.editable-click.editable-disabled, +a.editable-click.editable-disabled:hover { + color: #585858; + cursor: default; + border-bottom: none; +} + +.editable-empty, .editable-empty:hover, .editable-empty:focus{ + font-style: italic; + color: #DD1144; + /* border-bottom: none; */ + text-decoration: none; +} + +.editable-unsaved { + font-weight: bold; +} + +.editable-unsaved:after { +/* content: '*'*/ +} + +.editable-bg-transition { + -webkit-transition: background-color 1400ms ease-out; + -moz-transition: background-color 1400ms ease-out; + -o-transition: background-color 1400ms ease-out; + -ms-transition: background-color 1400ms ease-out; + transition: background-color 1400ms ease-out; +} + +/*see https://github.com/vitalets/x-editable/issues/139 */ +.form-horizontal .editable +{ + padding-top: 5px; + display:inline-block; +} + + +/*! + * Datepicker for Bootstrap + * + * Copyright 2012 Stefan Petre + * Improvements by Andrew Rowls + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + */ +.datepicker { + padding: 4px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + direction: ltr; + /*.dow { + border-top: 1px solid #ddd !important; + }*/ + +} +.datepicker-inline { + width: 220px; +} +.datepicker.datepicker-rtl { + direction: rtl; +} +.datepicker.datepicker-rtl table tr td span { + float: right; +} +.datepicker-dropdown { + top: 0; + left: 0; +} +.datepicker-dropdown:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: rgba(0, 0, 0, 0.2); + position: absolute; + top: -7px; + left: 6px; +} +.datepicker-dropdown:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + position: absolute; + top: -6px; + left: 7px; +} +.datepicker > div { + display: none; +} +.datepicker.days div.datepicker-days { + display: block; +} +.datepicker.months div.datepicker-months { + display: block; +} +.datepicker.years div.datepicker-years { + display: block; +} +.datepicker table { + margin: 0; +} +.datepicker td, +.datepicker th { + text-align: center; + width: 20px; + height: 20px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + border: none; +} +.table-striped .datepicker table tr td, +.table-striped .datepicker table tr th { + background-color: transparent; +} +.datepicker table tr td.day:hover { + background: #eeeeee; + cursor: pointer; +} +.datepicker table tr td.old, +.datepicker table tr td.new { + color: #999999; +} +.datepicker table tr td.disabled, +.datepicker table tr td.disabled:hover { + background: none; + color: #999999; + cursor: default; +} +.datepicker table tr td.today, +.datepicker table tr td.today:hover, +.datepicker table tr td.today.disabled, +.datepicker table tr td.today.disabled:hover { + background-color: #fde19a; + background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a); + background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a)); + background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a); + background-image: -o-linear-gradient(top, #fdd49a, #fdf59a); + background-image: linear-gradient(top, #fdd49a, #fdf59a); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0); + border-color: #fdf59a #fdf59a #fbed50; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + color: #000; +} +.datepicker table tr td.today:hover, +.datepicker table tr td.today:hover:hover, +.datepicker table tr td.today.disabled:hover, +.datepicker table tr td.today.disabled:hover:hover, +.datepicker table tr td.today:active, +.datepicker table tr td.today:hover:active, +.datepicker table tr td.today.disabled:active, +.datepicker table tr td.today.disabled:hover:active, +.datepicker table tr td.today.active, +.datepicker table tr td.today:hover.active, +.datepicker table tr td.today.disabled.active, +.datepicker table tr td.today.disabled:hover.active, +.datepicker table tr td.today.disabled, +.datepicker table tr td.today:hover.disabled, +.datepicker table tr td.today.disabled.disabled, +.datepicker table tr td.today.disabled:hover.disabled, +.datepicker table tr td.today[disabled], +.datepicker table tr td.today:hover[disabled], +.datepicker table tr td.today.disabled[disabled], +.datepicker table tr td.today.disabled:hover[disabled] { + background-color: #fdf59a; +} +.datepicker table tr td.today:active, +.datepicker table tr td.today:hover:active, +.datepicker table tr td.today.disabled:active, +.datepicker table tr td.today.disabled:hover:active, +.datepicker table tr td.today.active, +.datepicker table tr td.today:hover.active, +.datepicker table tr td.today.disabled.active, +.datepicker table tr td.today.disabled:hover.active { + background-color: #fbf069 \9; +} +.datepicker table tr td.today:hover:hover { + color: #000; +} +.datepicker table tr td.today.active:hover { + color: #fff; +} +.datepicker table tr td.range, +.datepicker table tr td.range:hover, +.datepicker table tr td.range.disabled, +.datepicker table tr td.range.disabled:hover { + background: #eeeeee; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.datepicker table tr td.range.today, +.datepicker table tr td.range.today:hover, +.datepicker table tr td.range.today.disabled, +.datepicker table tr td.range.today.disabled:hover { + background-color: #f3d17a; + background-image: -moz-linear-gradient(top, #f3c17a, #f3e97a); + background-image: -ms-linear-gradient(top, #f3c17a, #f3e97a); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a)); + background-image: -webkit-linear-gradient(top, #f3c17a, #f3e97a); + background-image: -o-linear-gradient(top, #f3c17a, #f3e97a); + background-image: linear-gradient(top, #f3c17a, #f3e97a); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0); + border-color: #f3e97a #f3e97a #edde34; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.datepicker table tr td.range.today:hover, +.datepicker table tr td.range.today:hover:hover, +.datepicker table tr td.range.today.disabled:hover, +.datepicker table tr td.range.today.disabled:hover:hover, +.datepicker table tr td.range.today:active, +.datepicker table tr td.range.today:hover:active, +.datepicker table tr td.range.today.disabled:active, +.datepicker table tr td.range.today.disabled:hover:active, +.datepicker table tr td.range.today.active, +.datepicker table tr td.range.today:hover.active, +.datepicker table tr td.range.today.disabled.active, +.datepicker table tr td.range.today.disabled:hover.active, +.datepicker table tr td.range.today.disabled, +.datepicker table tr td.range.today:hover.disabled, +.datepicker table tr td.range.today.disabled.disabled, +.datepicker table tr td.range.today.disabled:hover.disabled, +.datepicker table tr td.range.today[disabled], +.datepicker table tr td.range.today:hover[disabled], +.datepicker table tr td.range.today.disabled[disabled], +.datepicker table tr td.range.today.disabled:hover[disabled] { + background-color: #f3e97a; +} +.datepicker table tr td.range.today:active, +.datepicker table tr td.range.today:hover:active, +.datepicker table tr td.range.today.disabled:active, +.datepicker table tr td.range.today.disabled:hover:active, +.datepicker table tr td.range.today.active, +.datepicker table tr td.range.today:hover.active, +.datepicker table tr td.range.today.disabled.active, +.datepicker table tr td.range.today.disabled:hover.active { + background-color: #efe24b \9; +} +.datepicker table tr td.selected, +.datepicker table tr td.selected:hover, +.datepicker table tr td.selected.disabled, +.datepicker table tr td.selected.disabled:hover { + background-color: #9e9e9e; + background-image: -moz-linear-gradient(top, #b3b3b3, #808080); + background-image: -ms-linear-gradient(top, #b3b3b3, #808080); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#808080)); + background-image: -webkit-linear-gradient(top, #b3b3b3, #808080); + background-image: -o-linear-gradient(top, #b3b3b3, #808080); + background-image: linear-gradient(top, #b3b3b3, #808080); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3b3b3', endColorstr='#808080', GradientType=0); + border-color: #808080 #808080 #595959; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + color: #fff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.datepicker table tr td.selected:hover, +.datepicker table tr td.selected:hover:hover, +.datepicker table tr td.selected.disabled:hover, +.datepicker table tr td.selected.disabled:hover:hover, +.datepicker table tr td.selected:active, +.datepicker table tr td.selected:hover:active, +.datepicker table tr td.selected.disabled:active, +.datepicker table tr td.selected.disabled:hover:active, +.datepicker table tr td.selected.active, +.datepicker table tr td.selected:hover.active, +.datepicker table tr td.selected.disabled.active, +.datepicker table tr td.selected.disabled:hover.active, +.datepicker table tr td.selected.disabled, +.datepicker table tr td.selected:hover.disabled, +.datepicker table tr td.selected.disabled.disabled, +.datepicker table tr td.selected.disabled:hover.disabled, +.datepicker table tr td.selected[disabled], +.datepicker table tr td.selected:hover[disabled], +.datepicker table tr td.selected.disabled[disabled], +.datepicker table tr td.selected.disabled:hover[disabled] { + background-color: #808080; +} +.datepicker table tr td.selected:active, +.datepicker table tr td.selected:hover:active, +.datepicker table tr td.selected.disabled:active, +.datepicker table tr td.selected.disabled:hover:active, +.datepicker table tr td.selected.active, +.datepicker table tr td.selected:hover.active, +.datepicker table tr td.selected.disabled.active, +.datepicker table tr td.selected.disabled:hover.active { + background-color: #666666 \9; +} +.datepicker table tr td.active, +.datepicker table tr td.active:hover, +.datepicker table tr td.active.disabled, +.datepicker table tr td.active.disabled:hover { + background-color: #006dcc; + background-image: -moz-linear-gradient(top, #0088cc, #0044cc); + background-image: -ms-linear-gradient(top, #0088cc, #0044cc); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); + background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); + background-image: -o-linear-gradient(top, #0088cc, #0044cc); + background-image: linear-gradient(top, #0088cc, #0044cc); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0); + border-color: #0044cc #0044cc #002a80; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + color: #fff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.datepicker table tr td.active:hover, +.datepicker table tr td.active:hover:hover, +.datepicker table tr td.active.disabled:hover, +.datepicker table tr td.active.disabled:hover:hover, +.datepicker table tr td.active:active, +.datepicker table tr td.active:hover:active, +.datepicker table tr td.active.disabled:active, +.datepicker table tr td.active.disabled:hover:active, +.datepicker table tr td.active.active, +.datepicker table tr td.active:hover.active, +.datepicker table tr td.active.disabled.active, +.datepicker table tr td.active.disabled:hover.active, +.datepicker table tr td.active.disabled, +.datepicker table tr td.active:hover.disabled, +.datepicker table tr td.active.disabled.disabled, +.datepicker table tr td.active.disabled:hover.disabled, +.datepicker table tr td.active[disabled], +.datepicker table tr td.active:hover[disabled], +.datepicker table tr td.active.disabled[disabled], +.datepicker table tr td.active.disabled:hover[disabled] { + background-color: #0044cc; +} +.datepicker table tr td.active:active, +.datepicker table tr td.active:hover:active, +.datepicker table tr td.active.disabled:active, +.datepicker table tr td.active.disabled:hover:active, +.datepicker table tr td.active.active, +.datepicker table tr td.active:hover.active, +.datepicker table tr td.active.disabled.active, +.datepicker table tr td.active.disabled:hover.active { + background-color: #003399 \9; +} +.datepicker table tr td span { + display: block; + width: 23%; + height: 54px; + line-height: 54px; + float: left; + margin: 1%; + cursor: pointer; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.datepicker table tr td span:hover { + background: #eeeeee; +} +.datepicker table tr td span.disabled, +.datepicker table tr td span.disabled:hover { + background: none; + color: #999999; + cursor: default; +} +.datepicker table tr td span.active, +.datepicker table tr td span.active:hover, +.datepicker table tr td span.active.disabled, +.datepicker table tr td span.active.disabled:hover { + background-color: #006dcc; + background-image: -moz-linear-gradient(top, #0088cc, #0044cc); + background-image: -ms-linear-gradient(top, #0088cc, #0044cc); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); + background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); + background-image: -o-linear-gradient(top, #0088cc, #0044cc); + background-image: linear-gradient(top, #0088cc, #0044cc); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0); + border-color: #0044cc #0044cc #002a80; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + color: #fff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.datepicker table tr td span.active:hover, +.datepicker table tr td span.active:hover:hover, +.datepicker table tr td span.active.disabled:hover, +.datepicker table tr td span.active.disabled:hover:hover, +.datepicker table tr td span.active:active, +.datepicker table tr td span.active:hover:active, +.datepicker table tr td span.active.disabled:active, +.datepicker table tr td span.active.disabled:hover:active, +.datepicker table tr td span.active.active, +.datepicker table tr td span.active:hover.active, +.datepicker table tr td span.active.disabled.active, +.datepicker table tr td span.active.disabled:hover.active, +.datepicker table tr td span.active.disabled, +.datepicker table tr td span.active:hover.disabled, +.datepicker table tr td span.active.disabled.disabled, +.datepicker table tr td span.active.disabled:hover.disabled, +.datepicker table tr td span.active[disabled], +.datepicker table tr td span.active:hover[disabled], +.datepicker table tr td span.active.disabled[disabled], +.datepicker table tr td span.active.disabled:hover[disabled] { + background-color: #0044cc; +} +.datepicker table tr td span.active:active, +.datepicker table tr td span.active:hover:active, +.datepicker table tr td span.active.disabled:active, +.datepicker table tr td span.active.disabled:hover:active, +.datepicker table tr td span.active.active, +.datepicker table tr td span.active:hover.active, +.datepicker table tr td span.active.disabled.active, +.datepicker table tr td span.active.disabled:hover.active { + background-color: #003399 \9; +} +.datepicker table tr td span.old, +.datepicker table tr td span.new { + color: #999999; +} +.datepicker th.datepicker-switch { + width: 145px; +} +.datepicker thead tr:first-child th, +.datepicker tfoot tr th { + cursor: pointer; +} +.datepicker thead tr:first-child th:hover, +.datepicker tfoot tr th:hover { + background: #eeeeee; +} +.datepicker .cw { + font-size: 10px; + width: 12px; + padding: 0 2px 0 5px; + vertical-align: middle; +} +.datepicker thead tr:first-child th.cw { + cursor: default; + background-color: transparent; +} +.input-append.date .add-on i, +.input-prepend.date .add-on i { + display: block; + cursor: pointer; + width: 16px; + height: 16px; +} +.input-daterange input { + text-align: center; +} +.input-daterange input:first-child { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-daterange input:last-child { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-daterange .add-on { + display: inline-block; + width: auto; + min-width: 16px; + height: 18px; + padding: 4px 5px; + font-weight: normal; + line-height: 18px; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + vertical-align: middle; + background-color: #eeeeee; + border: 1px solid #ccc; + margin-left: -5px; + margin-right: -5px; +} \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/editable/bootstrap-editable.min.js b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/editable/bootstrap-editable.min.js new file mode 100644 index 000000000..e2703aee8 --- /dev/null +++ b/ruoyi-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/editable/bootstrap-editable.min.js @@ -0,0 +1,7 @@ +/*! X-editable - v1.5.1 +* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery +* http://github.com/vitalets/x-editable +* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */ +!function(a){"use strict";var b=function(b,c){this.options=a.extend({},a.fn.editableform.defaults,c),this.$div=a(b),this.options.scope||(this.options.scope=this)};b.prototype={constructor:b,initInput:function(){this.input=this.options.input,this.value=this.input.str2value(this.options.value),this.input.prerender()},initTemplate:function(){this.$form=a(a.fn.editableform.template)},initButtons:function(){var b=this.$form.find(".editable-buttons");b.append(a.fn.editableform.buttons),"bottom"===this.options.showbuttons&&b.addClass("editable-buttons-bottom")},render:function(){this.$loading=a(a.fn.editableform.loading),this.$div.empty().append(this.$loading),this.initTemplate(),this.options.showbuttons?this.initButtons():this.$form.find(".editable-buttons").remove(),this.showLoading(),this.isSaving=!1,this.$div.triggerHandler("rendering"),this.initInput(),this.$form.find("div.editable-input").append(this.input.$tpl),this.$div.append(this.$form),a.when(this.input.render()).then(a.proxy(function(){if(this.options.showbuttons||this.input.autosubmit(),this.$form.find(".editable-cancel").click(a.proxy(this.cancel,this)),this.input.error)this.error(this.input.error),this.$form.find(".editable-submit").attr("disabled",!0),this.input.$input.attr("disabled",!0),this.$form.submit(function(a){a.preventDefault()});else{this.error(!1),this.input.$input.removeAttr("disabled"),this.$form.find(".editable-submit").removeAttr("disabled");var b=null===this.value||void 0===this.value||""===this.value?this.options.defaultValue:this.value;this.input.value2input(b),this.$form.submit(a.proxy(this.submit,this))}this.$div.triggerHandler("rendered"),this.showForm(),this.input.postrender&&this.input.postrender()},this))},cancel:function(){this.$div.triggerHandler("cancel")},showLoading:function(){var a,b;this.$form?(a=this.$form.outerWidth(),b=this.$form.outerHeight(),a&&this.$loading.width(a),b&&this.$loading.height(b),this.$form.hide()):(a=this.$loading.parent().width(),a&&this.$loading.width(a)),this.$loading.show()},showForm:function(a){this.$loading.hide(),this.$form.show(),a!==!1&&this.input.activate(),this.$div.triggerHandler("show")},error:function(b){var c,d=this.$form.find(".control-group"),e=this.$form.find(".editable-error-block");if(b===!1)d.removeClass(a.fn.editableform.errorGroupClass),e.removeClass(a.fn.editableform.errorBlockClass).empty().hide();else{if(b){c=(""+b).split("\n");for(var f=0;f").text(c[f]).html();b=c.join("
    ")}d.addClass(a.fn.editableform.errorGroupClass),e.addClass(a.fn.editableform.errorBlockClass).html(b).show()}},submit:function(b){b.stopPropagation(),b.preventDefault();var c=this.input.input2value(),d=this.validate(c);if("object"===a.type(d)&&void 0!==d.newValue){if(c=d.newValue,this.input.value2input(c),"string"==typeof d.msg)return this.error(d.msg),this.showForm(),void 0}else if(d)return this.error(d),this.showForm(),void 0;if(!this.options.savenochange&&this.input.value2str(c)==this.input.value2str(this.value))return this.$div.triggerHandler("nochange"),void 0;var e=this.input.value2submit(c);this.isSaving=!0,a.when(this.save(e)).done(a.proxy(function(a){this.isSaving=!1;var b="function"==typeof this.options.success?this.options.success.call(this.options.scope,a,c):null;return b===!1?(this.error(!1),this.showForm(!1),void 0):"string"==typeof b?(this.error(b),this.showForm(),void 0):(b&&"object"==typeof b&&b.hasOwnProperty("newValue")&&(c=b.newValue),this.error(!1),this.value=c,this.$div.triggerHandler("save",{newValue:c,submitValue:e,response:a}),void 0)},this)).fail(a.proxy(function(a){this.isSaving=!1;var b;b="function"==typeof this.options.error?this.options.error.call(this.options.scope,a,c):"string"==typeof a?a:a.responseText||a.statusText||"Unknown error!",this.error(b),this.showForm()},this))},save:function(b){this.options.pk=a.fn.editableutils.tryParseJson(this.options.pk,!0);var c,d="function"==typeof this.options.pk?this.options.pk.call(this.options.scope):this.options.pk,e=!!("function"==typeof this.options.url||this.options.url&&("always"===this.options.send||"auto"===this.options.send&&null!==d&&void 0!==d));return e?(this.showLoading(),c={name:this.options.name||"",value:b,pk:d},"function"==typeof this.options.params?c=this.options.params.call(this.options.scope,c):(this.options.params=a.fn.editableutils.tryParseJson(this.options.params,!0),a.extend(c,this.options.params)),"function"==typeof this.options.url?this.options.url.call(this.options.scope,c):a.ajax(a.extend({url:this.options.url,data:c,type:"POST"},this.options.ajaxOptions))):void 0},validate:function(a){return void 0===a&&(a=this.value),"function"==typeof this.options.validate?this.options.validate.call(this.options.scope,a):void 0},option:function(a,b){a in this.options&&(this.options[a]=b),"value"===a&&this.setValue(b)},setValue:function(a,b){this.value=b?this.input.str2value(a):a,this.$form&&this.$form.is(":visible")&&this.input.value2input(this.value)}},a.fn.editableform=function(c){var d=arguments;return this.each(function(){var e=a(this),f=e.data("editableform"),g="object"==typeof c&&c;f||e.data("editableform",f=new b(this,g)),"string"==typeof c&&f[c].apply(f,Array.prototype.slice.call(d,1))})},a.fn.editableform.Constructor=b,a.fn.editableform.defaults={type:"text",url:null,params:null,name:null,pk:null,value:null,defaultValue:null,send:"auto",validate:null,success:null,error:null,ajaxOptions:null,showbuttons:!0,scope:null,savenochange:!1},a.fn.editableform.template='
    ',a.fn.editableform.loading='
    ',a.fn.editableform.buttons='',a.fn.editableform.errorGroupClass=null,a.fn.editableform.errorBlockClass="editable-error",a.fn.editableform.engine="jquery"}(window.jQuery),function(a){"use strict";a.fn.editableutils={inherit:function(a,b){var c=function(){};c.prototype=b.prototype,a.prototype=new c,a.prototype.constructor=a,a.superclass=b.prototype},setCursorPosition:function(a,b){if(a.setSelectionRange)a.setSelectionRange(b,b);else if(a.createTextRange){var c=a.createTextRange();c.collapse(!0),c.moveEnd("character",b),c.moveStart("character",b),c.select()}},tryParseJson:function(a,b){if("string"==typeof a&&a.length&&a.match(/^[\{\[].*[\}\]]$/))if(b)try{a=new Function("return "+a)()}catch(c){}finally{return a}else a=new Function("return "+a)();return a},sliceObj:function(b,c,d){var e,f,g={};if(!a.isArray(c)||!c.length)return g;for(var h=0;h").text(b).html()},itemsByValue:function(b,c,d){if(!c||null===b)return[];if("function"!=typeof d){var e=d||"value";d=function(a){return a[e]}}var f=a.isArray(b),g=[],h=this;return a.each(c,function(c,e){if(e.children)g=g.concat(h.itemsByValue(b,e.children,d));else if(f)a.grep(b,function(a){return a==(e&&"object"==typeof e?d(e):e)}).length&&g.push(e);else{var i=e&&"object"==typeof e?d(e):e;b==i&&g.push(e)}}),g},createInput:function(b){var c,d,e,f=b.type;return"date"===f&&("inline"===b.mode?a.fn.editabletypes.datefield?f="datefield":a.fn.editabletypes.dateuifield&&(f="dateuifield"):a.fn.editabletypes.date?f="date":a.fn.editabletypes.dateui&&(f="dateui"),"date"!==f||a.fn.editabletypes.date||(f="combodate")),"datetime"===f&&"inline"===b.mode&&(f="datetimefield"),"wysihtml5"!==f||a.fn.editabletypes[f]||(f="textarea"),"function"==typeof a.fn.editabletypes[f]?(c=a.fn.editabletypes[f],d=this.sliceObj(b,this.objectKeys(c.defaults)),e=new c(d)):(a.error("Unknown type: "+f),!1)},supportsTransitions:function(){var a=document.body||document.documentElement,b=a.style,c="transition",d=["Moz","Webkit","Khtml","O","ms"];if("string"==typeof b[c])return!0;c=c.charAt(0).toUpperCase()+c.substr(1);for(var e=0;e"),this.tip().is(this.innerCss)?this.tip().append(this.$form):this.tip().find(this.innerCss).append(this.$form),this.renderForm()},hide:function(a){if(this.tip()&&this.tip().is(":visible")&&this.$element.hasClass("editable-open")){if(this.$form.data("editableform").isSaving)return this.delayedHide={reason:a},void 0;this.delayedHide=!1,this.$element.removeClass("editable-open"),this.innerHide(),this.$element.triggerHandler("hidden",a||"manual")}},innerShow:function(){},innerHide:function(){},toggle:function(a){this.container()&&this.tip()&&this.tip().is(":visible")?this.hide():this.show(a)},setPosition:function(){},save:function(a,b){this.$element.triggerHandler("save",b),this.hide("save")},option:function(a,b){this.options[a]=b,a in this.containerOptions?(this.containerOptions[a]=b,this.setContainerOption(a,b)):(this.formOptions[a]=b,this.$form&&this.$form.editableform("option",a,b))},setContainerOption:function(a,b){this.call("option",a,b)},destroy:function(){this.hide(),this.innerDestroy(),this.$element.off("destroyed"),this.$element.removeData("editableContainer")},innerDestroy:function(){},closeOthers:function(b){a(".editable-open").each(function(c,d){if(d!==b&&!a(d).find(b).length){var e=a(d),f=e.data("editableContainer");f&&("cancel"===f.options.onblur?e.data("editableContainer").hide("onblur"):"submit"===f.options.onblur&&e.data("editableContainer").tip().find("form").submit())}})},activate:function(){this.tip&&this.tip().is(":visible")&&this.$form&&this.$form.data("editableform").input.activate()}},a.fn.editableContainer=function(d){var e=arguments;return this.each(function(){var f=a(this),g="editableContainer",h=f.data(g),i="object"==typeof d&&d,j="inline"===i.mode?c:b;h||f.data(g,h=new j(this,i)),"string"==typeof d&&h[d].apply(h,Array.prototype.slice.call(e,1))})},a.fn.editableContainer.Popup=b,a.fn.editableContainer.Inline=c,a.fn.editableContainer.defaults={value:null,placement:"top",autohide:!0,onblur:"cancel",anim:!1,mode:"popup"},jQuery.event.special.destroyed={remove:function(a){a.handler&&a.handler()}}}(window.jQuery),function(a){"use strict";a.extend(a.fn.editableContainer.Inline.prototype,a.fn.editableContainer.Popup.prototype,{containerName:"editableform",innerCss:".editable-inline",containerClass:"editable-container editable-inline",initContainer:function(){this.$tip=a(""),this.options.anim||(this.options.anim=0)},splitOptions:function(){this.containerOptions={},this.formOptions=this.options},tip:function(){return this.$tip},innerShow:function(){this.$element.hide(),this.tip().insertAfter(this.$element).show()},innerHide:function(){this.$tip.hide(this.options.anim,a.proxy(function(){this.$element.show(),this.innerDestroy()},this))},innerDestroy:function(){this.tip()&&this.tip().empty().remove()}})}(window.jQuery),function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.editable.defaults,c,a.fn.editableutils.getConfigData(this.$element)),this.options.selector?this.initLive():this.init(),this.options.highlight&&!a.fn.editableutils.supportsTransitions()&&(this.options.highlight=!1)};b.prototype={constructor:b,init:function(){var b,c=!1;if(this.options.name=this.options.name||this.$element.attr("id"),this.options.scope=this.$element[0],this.input=a.fn.editableutils.createInput(this.options),this.input){switch(void 0===this.options.value||null===this.options.value?(this.value=this.input.html2value(a.trim(this.$element.html())),c=!0):(this.options.value=a.fn.editableutils.tryParseJson(this.options.value,!0),this.value="string"==typeof this.options.value?this.input.str2value(this.options.value):this.options.value),this.$element.addClass("editable"),"textarea"===this.input.type&&this.$element.addClass("editable-pre-wrapped"),"manual"!==this.options.toggle?(this.$element.addClass("editable-click"),this.$element.on(this.options.toggle+".editable",a.proxy(function(a){if(this.options.disabled||a.preventDefault(),"mouseenter"===this.options.toggle)this.show();else{var b="click"!==this.options.toggle;this.toggle(b)}},this))):this.$element.attr("tabindex",-1),"function"==typeof this.options.display&&(this.options.autotext="always"),this.options.autotext){case"always":b=!0;break;case"auto":b=!a.trim(this.$element.text()).length&&null!==this.value&&void 0!==this.value&&!c;break;default:b=!1}a.when(b?this.render():!0).then(a.proxy(function(){this.options.disabled?this.disable():this.enable(),this.$element.triggerHandler("init",this)},this))}},initLive:function(){var b=this.options.selector;this.options.selector=!1,this.options.autotext="never",this.$element.on(this.options.toggle+".editable",b,a.proxy(function(b){var c=a(b.target);c.data("editable")||(c.hasClass(this.options.emptyclass)&&c.empty(),c.editable(this.options).trigger(b))},this))},render:function(a){return this.options.display!==!1?this.input.value2htmlFinal?this.input.value2html(this.value,this.$element[0],this.options.display,a):"function"==typeof this.options.display?this.options.display.call(this.$element[0],this.value,a):this.input.value2html(this.value,this.$element[0]):void 0},enable:function(){this.options.disabled=!1,this.$element.removeClass("editable-disabled"),this.handleEmpty(this.isEmpty),"manual"!==this.options.toggle&&"-1"===this.$element.attr("tabindex")&&this.$element.removeAttr("tabindex")},disable:function(){this.options.disabled=!0,this.hide(),this.$element.addClass("editable-disabled"),this.handleEmpty(this.isEmpty),this.$element.attr("tabindex",-1)},toggleDisabled:function(){this.options.disabled?this.enable():this.disable()},option:function(b,c){return b&&"object"==typeof b?(a.each(b,a.proxy(function(b,c){this.option(a.trim(b),c)},this)),void 0):(this.options[b]=c,"disabled"===b?c?this.disable():this.enable():("value"===b&&this.setValue(c),this.container&&this.container.option(b,c),this.input.option&&this.input.option(b,c),void 0))},handleEmpty:function(b){this.options.display!==!1&&(this.isEmpty=void 0!==b?b:"function"==typeof this.input.isEmpty?this.input.isEmpty(this.$element):""===a.trim(this.$element.html()),this.options.disabled?this.isEmpty&&(this.$element.empty(),this.options.emptyclass&&this.$element.removeClass(this.options.emptyclass)):this.isEmpty?(this.$element.html(this.options.emptytext),this.options.emptyclass&&this.$element.addClass(this.options.emptyclass)):this.options.emptyclass&&this.$element.removeClass(this.options.emptyclass))},show:function(b){if(!this.options.disabled){if(this.container){if(this.container.tip().is(":visible"))return}else{var c=a.extend({},this.options,{value:this.value,input:this.input});this.$element.editableContainer(c),this.$element.on("save.internal",a.proxy(this.save,this)),this.container=this.$element.data("editableContainer")}this.container.show(b)}},hide:function(){this.container&&this.container.hide()},toggle:function(a){this.container&&this.container.tip().is(":visible")?this.hide():this.show(a)},save:function(a,b){if(this.options.unsavedclass){var c=!1;c=c||"function"==typeof this.options.url,c=c||this.options.display===!1,c=c||void 0!==b.response,c=c||this.options.savenochange&&this.input.value2str(this.value)!==this.input.value2str(b.newValue),c?this.$element.removeClass(this.options.unsavedclass):this.$element.addClass(this.options.unsavedclass)}if(this.options.highlight){var d=this.$element,e=d.css("background-color");d.css("background-color",this.options.highlight),setTimeout(function(){"transparent"===e&&(e=""),d.css("background-color",e),d.addClass("editable-bg-transition"),setTimeout(function(){d.removeClass("editable-bg-transition")},1700)},10)}this.setValue(b.newValue,!1,b.response)},validate:function(){return"function"==typeof this.options.validate?this.options.validate.call(this,this.value):void 0},setValue:function(b,c,d){this.value=c?this.input.str2value(b):b,this.container&&this.container.option("value",this.value),a.when(this.render(d)).then(a.proxy(function(){this.handleEmpty()},this))},activate:function(){this.container&&this.container.activate()},destroy:function(){this.disable(),this.container&&this.container.destroy(),this.input.destroy(),"manual"!==this.options.toggle&&(this.$element.removeClass("editable-click"),this.$element.off(this.options.toggle+".editable")),this.$element.off("save.internal"),this.$element.removeClass("editable editable-open editable-disabled"),this.$element.removeData("editable")}},a.fn.editable=function(c){var d={},e=arguments,f="editable";switch(c){case"validate":return this.each(function(){var b,c=a(this),e=c.data(f);e&&(b=e.validate())&&(d[e.options.name]=b)}),d;case"getValue":return 2===arguments.length&&arguments[1]===!0?d=this.eq(0).data(f).value:this.each(function(){var b=a(this),c=b.data(f);c&&void 0!==c.value&&null!==c.value&&(d[c.options.name]=c.input.value2submit(c.value))}),d;case"submit":var g=arguments[1]||{},h=this,i=this.editable("validate");if(a.isEmptyObject(i)){var j={};if(1===h.length){var k=h.data("editable"),l={name:k.options.name||"",value:k.input.value2submit(k.value),pk:"function"==typeof k.options.pk?k.options.pk.call(k.options.scope):k.options.pk};"function"==typeof k.options.params?l=k.options.params.call(k.options.scope,l):(k.options.params=a.fn.editableutils.tryParseJson(k.options.params,!0),a.extend(l,k.options.params)),j={url:k.options.url,data:l,type:"POST"},g.success=g.success||k.options.success,g.error=g.error||k.options.error}else{var m=this.editable("getValue");j={url:g.url,data:m,type:"POST"}}j.success="function"==typeof g.success?function(a){g.success.call(h,a,g)}:a.noop,j.error="function"==typeof g.error?function(){g.error.apply(h,arguments)}:a.noop,g.ajaxOptions&&a.extend(j,g.ajaxOptions),g.data&&a.extend(j.data,g.data),a.ajax(j)}else"function"==typeof g.error&&g.error.call(h,i);return this}return this.each(function(){var d=a(this),g=d.data(f),h="object"==typeof c&&c;return h&&h.selector?(g=new b(this,h),void 0):(g||d.data(f,g=new b(this,h)),"string"==typeof c&&g[c].apply(g,Array.prototype.slice.call(e,1)),void 0)})},a.fn.editable.defaults={type:"text",disabled:!1,toggle:"click",emptytext:"Empty",autotext:"auto",value:null,display:null,emptyclass:"editable-empty",unsavedclass:"editable-unsaved",selector:null,highlight:"#FFFF80"}}(window.jQuery),function(a){"use strict";a.fn.editabletypes={};var b=function(){};b.prototype={init:function(b,c,d){this.type=b,this.options=a.extend({},d,c)},prerender:function(){this.$tpl=a(this.options.tpl),this.$input=this.$tpl,this.$clear=null,this.error=null},render:function(){},value2html:function(b,c){a(c)[this.options.escape?"text":"html"](a.trim(b))},html2value:function(b){return a("
    ").html(b).text()},value2str:function(a){return a},str2value:function(a){return a},value2submit:function(a){return a},value2input:function(a){this.$input.val(a)},input2value:function(){return this.$input.val()},activate:function(){this.$input.is(":visible")&&this.$input.focus()},clear:function(){this.$input.val(null)},escape:function(b){return a("
    ").text(b).html()},autosubmit:function(){},destroy:function(){},setClass:function(){this.options.inputclass&&this.$input.addClass(this.options.inputclass)},setAttr:function(a){void 0!==this.options[a]&&null!==this.options[a]&&this.$input.attr(a,this.options[a])},option:function(a,b){this.options[a]=b}},b.defaults={tpl:"",inputclass:null,escape:!0,scope:null,showbuttons:!0},a.extend(a.fn.editabletypes,{abstractinput:b})}(window.jQuery),function(a){"use strict";var b=function(){};a.fn.editableutils.inherit(b,a.fn.editabletypes.abstractinput),a.extend(b.prototype,{render:function(){var b=a.Deferred();return this.error=null,this.onSourceReady(function(){this.renderList(),b.resolve()},function(){this.error=this.options.sourceError,b.resolve()}),b.promise()},html2value:function(){return null},value2html:function(b,c,d,e){var f=a.Deferred(),g=function(){"function"==typeof d?d.call(c,b,this.sourceData,e):this.value2htmlFinal(b,c),f.resolve()};return null===b?g.call(this):this.onSourceReady(g,function(){f.resolve()}),f.promise()},onSourceReady:function(b,c){var d;if(a.isFunction(this.options.source)?(d=this.options.source.call(this.options.scope),this.sourceData=null):d=this.options.source,this.options.sourceCache&&a.isArray(this.sourceData))return b.call(this),void 0;try{d=a.fn.editableutils.tryParseJson(d,!1)}catch(e){return c.call(this),void 0}if("string"==typeof d){if(this.options.sourceCache){var f,g=d;if(a(document).data(g)||a(document).data(g,{}),f=a(document).data(g),f.loading===!1&&f.sourceData)return this.sourceData=f.sourceData,this.doPrepend(),b.call(this),void 0;if(f.loading===!0)return f.callbacks.push(a.proxy(function(){this.sourceData=f.sourceData,this.doPrepend(),b.call(this)},this)),f.err_callbacks.push(a.proxy(c,this)),void 0;f.loading=!0,f.callbacks=[],f.err_callbacks=[]}var h=a.extend({url:d,type:"get",cache:!1,dataType:"json",success:a.proxy(function(d){f&&(f.loading=!1),this.sourceData=this.makeArray(d),a.isArray(this.sourceData)?(f&&(f.sourceData=this.sourceData,a.each(f.callbacks,function(){this.call()})),this.doPrepend(),b.call(this)):(c.call(this),f&&a.each(f.err_callbacks,function(){this.call()}))},this),error:a.proxy(function(){c.call(this),f&&(f.loading=!1,a.each(f.err_callbacks,function(){this.call()}))},this)},this.options.sourceOptions);a.ajax(h)}else this.sourceData=this.makeArray(d),a.isArray(this.sourceData)?(this.doPrepend(),b.call(this)):c.call(this)},doPrepend:function(){null!==this.options.prepend&&void 0!==this.options.prepend&&(a.isArray(this.prependData)||(a.isFunction(this.options.prepend)&&(this.options.prepend=this.options.prepend.call(this.options.scope)),this.options.prepend=a.fn.editableutils.tryParseJson(this.options.prepend,!0),"string"==typeof this.options.prepend&&(this.options.prepend={"":this.options.prepend}),this.prependData=this.makeArray(this.options.prepend)),a.isArray(this.prependData)&&a.isArray(this.sourceData)&&(this.sourceData=this.prependData.concat(this.sourceData)))},renderList:function(){},value2htmlFinal:function(){},makeArray:function(b){var c,d,e,f,g=[];if(!b||"string"==typeof b)return null;if(a.isArray(b)){f=function(a,b){return d={value:a,text:b},c++>=2?!1:void 0};for(var h=0;h1&&(e.children&&(e.children=this.makeArray(e.children)),g.push(e))):g.push({value:e,text:e})}else a.each(b,function(a,b){g.push({value:a,text:b})});return g},option:function(a,b){this.options[a]=b,"source"===a&&(this.sourceData=null),"prepend"===a&&(this.prependData=null)}}),b.defaults=a.extend({},a.fn.editabletypes.abstractinput.defaults,{source:null,prepend:!1,sourceError:"Error when loading list",sourceCache:!0,sourceOptions:null}),a.fn.editabletypes.list=b}(window.jQuery),function(a){"use strict";var b=function(a){this.init("text",a,b.defaults)};a.fn.editableutils.inherit(b,a.fn.editabletypes.abstractinput),a.extend(b.prototype,{render:function(){this.renderClear(),this.setClass(),this.setAttr("placeholder")},activate:function(){this.$input.is(":visible")&&(this.$input.focus(),a.fn.editableutils.setCursorPosition(this.$input.get(0),this.$input.val().length),this.toggleClear&&this.toggleClear())},renderClear:function(){this.options.clear&&(this.$clear=a(''),this.$input.after(this.$clear).css("padding-right",24).keyup(a.proxy(function(b){if(!~a.inArray(b.keyCode,[40,38,9,13,27])){clearTimeout(this.t);var c=this;this.t=setTimeout(function(){c.toggleClear(b)},100)}},this)).parent().css("position","relative"),this.$clear.click(a.proxy(this.clear,this)))},postrender:function(){},toggleClear:function(){if(this.$clear){var a=this.$input.val().length,b=this.$clear.is(":visible");a&&!b&&this.$clear.show(),!a&&b&&this.$clear.hide()}},clear:function(){this.$clear.hide(),this.$input.val("").focus()}}),b.defaults=a.extend({},a.fn.editabletypes.abstractinput.defaults,{tpl:'',placeholder:null,clear:!0}),a.fn.editabletypes.text=b}(window.jQuery),function(a){"use strict";var b=function(a){this.init("textarea",a,b.defaults)};a.fn.editableutils.inherit(b,a.fn.editabletypes.abstractinput),a.extend(b.prototype,{render:function(){this.setClass(),this.setAttr("placeholder"),this.setAttr("rows"),this.$input.keydown(function(b){b.ctrlKey&&13===b.which&&a(this).closest("form").submit()})},activate:function(){a.fn.editabletypes.text.prototype.activate.call(this)}}),b.defaults=a.extend({},a.fn.editabletypes.abstractinput.defaults,{tpl:"",inputclass:"input-large",placeholder:null,rows:7}),a.fn.editabletypes.textarea=b}(window.jQuery),function(a){"use strict";var b=function(a){this.init("select",a,b.defaults)};a.fn.editableutils.inherit(b,a.fn.editabletypes.list),a.extend(b.prototype,{renderList:function(){this.$input.empty();var b=function(c,d){var e;if(a.isArray(d))for(var f=0;f",e),d[f].children))):(e.value=d[f].value,d[f].disabled&&(e.disabled=!0),c.append(a("