Undefined attribute name (th:text).

本文介绍了解决在Eclipse中使用Thymeleaf时出现的“Undefinedattributename(th:text).”错误的方法。主要通过在HTML标签中正确声明Thymeleaf命名空间并使用block标签来实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在eclipse中用到thymeleaf时会提示“Undefined attribute name (th:text).”

解决办法
1、在html标签中写

<html xmlnsth="http://www.thymeleaf.org">

2、把要取值的标签写在block标签里

<th:block xmlns:th="http://www.thymeleaf.org">
    <div th:text="${'Here we go Thymeleaf!'}"></div>
</th:block>
Description Resource Path Location Type Compiling for Java version '1.6' is no longer supported. Minimal supported version is '1.8' DepartmentController.java /EmployeesManager/src/main/java/com/esms/controller line 0 Java Problem cvc-elt.1.a: Cannot find the declaration of element 'beans'. [cvc-elt.1.a] applicationContext.xml /EmployeesManager/src/main/resources line 2 Language Servers Downloading external resources is disabled. [DownloadResourceDisabled] applicationContext.xml /EmployeesManager/src/main/resources line 6 Language Servers Downloading external resources is disabled. [DownloadResourceDisabled] applicationContext.xml /EmployeesManager/src/main/resources line 8 Language Servers Downloading external resources is disabled. [DownloadResourceDisabled] applicationContext.xml /EmployeesManager/src/main/resources line 10 Language Servers Downloading external resources is disabled. [DownloadResourceDisabled] applicationContext.xml /EmployeesManager/src/main/resources line 12 Language Servers Java compiler level does not match the version of the installed Java project facet. EmployeesManager Unknown Faceted Project Problem (Java Version Mismatch) Referenced file contains errors (file:/F:/eclipse/workspace/EmployeesManager/src/main/resources/xsd/spring-aop-4.3.xsd). For more information, right click on the message in the Problems View and select "Show Details..." applicationContext.xml /EmployeesManager/src/main/resources line 1 XML Problem Referenced file contains errors (file:/F:/eclipse/workspace/EmployeesManager/src/main/resources/xsd/spring-context-4.3.xsd). For more information, right click on the message in the Problems View and select "Show Details..." applicationContext.xml /EmployeesManager/src/main/resources line 1 XML Problem Referenced file contains errors (file:/F:/eclipse/workspace/EmployeesManager/src/main/resources/xsd/spring-context-4.3.xsd). For more information, right click on the message in the Problems View and select "Show Details..." springmvc.xml /EmployeesManager/src/main/resources line 1 XML Problem Referenced file contains errors (file:/F:/eclipse/workspace/EmployeesManager/src/main/resources/xsd/spring-tx-4.3.xsd). For more information, right click on the message in the Problems View and select "Show Details..." applicationContext.xml /EmployeesManager/src/main/resources line 1 XML Problem Referenced file contains errors (http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd). For more information, right click on the message in the Problems View and select "Show Details..." springmvc.xml /EmployeesManager/src/main/resources line 1 XML Problem Attribute (frameborder) is obsolete. Its use is discouraged in HTML5 documents. index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 224 HTML Problem Attribute (frameborder) is obsolete. Its use is discouraged in HTML5 documents. index.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 101 HTML Problem Attribute (scrolling) is obsolete. Its use is discouraged in HTML5 documents. index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 224 HTML Problem Attribute (scrolling) is obsolete. Its use is discouraged in HTML5 documents. index.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 101 HTML Problem Build path specifies execution environment JavaSE-1.6. There are no JREs installed in the workspace that are strictly compatible with this environment. EmployeesManager Build path JRE System Library Problem Classpath entry org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER will not be exported or published. Runtime ClassNotFoundExceptions may result. EmployeesManager P/EmployeesManager Classpath Dependency Validator Message End tag (</br>) not needed. monthlyattendance-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 29 HTML Problem Implementation of project facet maven could not be found. Functionality will be limited. EmployeesManager Unknown Faceted Project Problem Invalid character used in text string (&nbsp&nbsp&nbsp ). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 48 HTML Problem Invalid character used in text string ( &nbsp&nbsp&nbsp ). employee-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 57 HTML Problem Invalid character used in text string (&nbsp&nbsp&nbsp 部门: ). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 36 HTML Problem Invalid character used in text string ( &nbsp&nbsp&nbsp 部门: ). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 40 HTML Problem Invalid character used in text string ( &nbsp&nbsp&nbsp 部门: ). employee-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 49 HTML Problem Invalid character used in text string (&nbsp&nbsp&nbsp部门管理). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 62 HTML Problem Invalid character used in text string (&nbsp&nbsp&nbsp岗位管理). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 76 HTML Problem Invalid character used in text string (&nbsp&nbsp&nbsp工龄奖金管理). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 106 HTML Problem Invalid character used in text string (&nbsp&nbsp&nbsp工资管理). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 153 HTML Problem Invalid character used in text string (&nbsp&nbsp&nbsp工资项管理). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 121 HTML Problem Invalid character used in text string ( &nbsp&nbsp&nbsp 考勤月份: ). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 51 HTML Problem Invalid character used in text string (&nbsp&nbsp&nbsp图表显示). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 181 HTML Problem Invalid character used in text string (&nbsp&nbsp&nbsp员工管理). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 47 HTML Problem Invalid character used in text string ( &nbsp&nbsp&nbsp 员工姓名: ). employee-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 44 HTML Problem Invalid character used in text string (&nbsp&nbsp&nbsp月考勤管理). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 137 HTML Problem Invalid character used in text string (&nbsp&nbsp&nbsp职称奖金管理). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 90 HTML Problem Invalid location of tag (script). adminLogin.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 86 HTML Problem Invalid location of tag (script). login.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 92 HTML Problem Invalid location of text (,) in tag (<th>). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 84 HTML Problem Invalid location of text (,) in tag (<th>). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 70 HTML Problem Invalid location of text ([endif]--) in tag (<!>). department-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/department line 20 HTML Problem Invalid location of text ([endif]--) in tag (<!>). department-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/department line 20 HTML Problem Invalid location of text ([endif]--) in tag (<!>). position-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/position line 20 HTML Problem Invalid location of text ([endif]--) in tag (<!>). position-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/position line 20 HTML Problem Invalid location of text ([endif]--) in tag (<!>). rankBonusEdit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rankBonus line 20 HTML Problem Invalid location of text ([endif]--) in tag (<!>). rankBonusadd.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rankBonus line 20 HTML Problem Invalid location of text ([endif]--) in tag (<!>). workingYearsBonusAdd.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/workBonus line 20 HTML Problem No start tag (<div>). attendanceList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 42 HTML Problem No start tag (<div>). attendanceList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 91 HTML Problem No start tag (<div>). employee-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 120 HTML Problem No start tag (<div>). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 72 HTML Problem No start tag (<div>). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 139 HTML Problem No start tag (<div>). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 111 HTML Problem No start tag (<div>). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 58 HTML Problem No start tag (<div>). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 125 HTML Problem Project 'EmployeesManager' has no explicit encoding set EmployeesManager /EmployeesManager No explicit project encoding The compiler compliance specified is 1.6 but a JRE 21 is used EmployeesManager Compiler Compliance JRE Compiler Compliance Problem Undefined attribute name (_href). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 52 HTML Problem Undefined attribute name (_href). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 67 HTML Problem Undefined attribute name (_href). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 81 HTML Problem Undefined attribute name (_href). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 96 HTML Problem Undefined attribute name (_href). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 112 HTML Problem Undefined attribute name (_href). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 127 HTML Problem Undefined attribute name (_href). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 142 HTML Problem Undefined attribute name (_href). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 159 HTML Problem Undefined attribute name (_href). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 165 HTML Problem Undefined attribute name (_href). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 171 HTML Problem Undefined attribute name (_href). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 186 HTML Problem Undefined attribute name (_href). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 192 HTML Problem Undefined attribute name (_href). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 198 HTML Problem Undefined attribute name (_href). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 204 HTML Problem Undefined attribute name (_href). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 52 HTML Problem Undefined attribute name (_href). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 66 HTML Problem Undefined attribute name (_href). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 81 HTML Problem Undefined attribute name (lay-allowclose). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 218 HTML Problem Undefined attribute name (lay-allowclose). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 95 HTML Problem Undefined attribute name (lay-data). attendanceList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 46 HTML Problem Undefined attribute name (lay-data). attendanceList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 50 HTML Problem Undefined attribute name (lay-data). attendanceList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 53 HTML Problem Undefined attribute name (lay-data). attendanceList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 54 HTML Problem Undefined attribute name (lay-data). attendanceList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 55 HTML Problem Undefined attribute name (lay-data). attendanceList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 58 HTML Problem Undefined attribute name (lay-data). attendanceList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 61 HTML Problem Undefined attribute name (lay-data). attendanceList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 65 HTML Problem Undefined attribute name (lay-data). attendanceList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 68 HTML Problem Undefined attribute name (lay-data). attendanceList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 71 HTML Problem Undefined attribute name (lay-data). attendanceList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 75 HTML Problem Undefined attribute name (lay-data). attendanceList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 78 HTML Problem Undefined attribute name (lay-data). attendanceList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 81 HTML Problem Undefined attribute name (lay-data). attendanceList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 84 HTML Problem Undefined attribute name (lay-data). department-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/department line 48 HTML Problem Undefined attribute name (lay-data). department-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/department line 51 HTML Problem Undefined attribute name (lay-data). department-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/department line 52 HTML Problem Undefined attribute name (lay-data). department-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/department line 53 HTML Problem Undefined attribute name (lay-data). employee-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 78 HTML Problem Undefined attribute name (lay-data). employee-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 82 HTML Problem Undefined attribute name (lay-data). employee-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 84 HTML Problem Undefined attribute name (lay-data). employee-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 87 HTML Problem Undefined attribute name (lay-data). employee-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 90 HTML Problem Undefined attribute name (lay-data). employee-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 93 HTML Problem Undefined attribute name (lay-data). employee-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 96 HTML Problem Undefined attribute name (lay-data). employee-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 99 HTML Problem Undefined attribute name (lay-data). employee-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 102 HTML Problem Undefined attribute name (lay-data). employee-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 105 HTML Problem Undefined attribute name (lay-data). employee-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 108 HTML Problem Undefined attribute name (lay-data). employee-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 111 HTML Problem Undefined attribute name (lay-data). employee-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 114 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 42 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 45 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 46 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 47 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 48 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 49 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 50 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 51 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 52 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 54 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 55 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 58 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 59 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 60 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 61 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 63 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 64 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 65 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 66 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 68 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 69 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 70 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 71 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 72 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 73 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 75 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 76 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 77 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 78 HTML Problem Undefined attribute name (lay-data). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 79 HTML Problem Undefined attribute name (lay-data). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 80 HTML Problem Undefined attribute name (lay-data). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 84 HTML Problem Undefined attribute name (lay-data). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 85 HTML Problem Undefined attribute name (lay-data). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 88 HTML Problem Undefined attribute name (lay-data). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 91 HTML Problem Undefined attribute name (lay-data). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 92 HTML Problem Undefined attribute name (lay-data). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 93 HTML Problem Undefined attribute name (lay-data). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 94 HTML Problem Undefined attribute name (lay-data). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 95 HTML Problem Undefined attribute name (lay-data). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 98 HTML Problem Undefined attribute name (lay-data). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 101 HTML Problem Undefined attribute name (lay-data). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 105 HTML Problem Undefined attribute name (lay-data). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 108 HTML Problem Undefined attribute name (lay-data). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 112 HTML Problem Undefined attribute name (lay-data). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 115 HTML Problem Undefined attribute name (lay-data). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 118 HTML Problem Undefined attribute name (lay-data). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 122 HTML Problem Undefined attribute name (lay-data). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 125 HTML Problem Undefined attribute name (lay-data). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 128 HTML Problem Undefined attribute name (lay-data). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 131 HTML Problem Undefined attribute name (lay-data). position-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/position line 52 HTML Problem Undefined attribute name (lay-data). position-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/position line 56 HTML Problem Undefined attribute name (lay-data). position-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/position line 57 HTML Problem Undefined attribute name (lay-data). position-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/position line 58 HTML Problem Undefined attribute name (lay-data). position-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/position line 59 HTML Problem Undefined attribute name (lay-data). rankBonusList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rankBonus line 45 HTML Problem Undefined attribute name (lay-data). rankBonusList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rankBonus line 48 HTML Problem Undefined attribute name (lay-data). rankBonusList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rankBonus line 49 HTML Problem Undefined attribute name (lay-data). rankBonusList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rankBonus line 50 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 58 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 61 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 62 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 65 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 66 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 67 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 68 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 69 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 70 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 71 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 72 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 74 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 75 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 79 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 82 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 85 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 86 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 87 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 88 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 90 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 91 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 92 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 93 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 95 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 96 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 97 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 98 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 99 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 100 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 101 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 102 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 103 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 104 HTML Problem Undefined attribute name (lay-data). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 105 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 66 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 70 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 71 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 72 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 75 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 76 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 77 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 78 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 79 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 80 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 81 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 82 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 84 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 87 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 92 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 95 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 98 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 99 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 100 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 101 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 103 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 104 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 105 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 106 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 108 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 109 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 110 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 111 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 112 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 113 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 115 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 116 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 117 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 118 HTML Problem Undefined attribute name (lay-data). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 119 HTML Problem Undefined attribute name (lay-data). workingYearsBonusList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/workBonus line 52 HTML Problem Undefined attribute name (lay-data). workingYearsBonusList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/workBonus line 55 HTML Problem Undefined attribute name (lay-data). workingYearsBonusList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/workBonus line 56 HTML Problem Undefined attribute name (lay-data). workingYearsBonusList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/workBonus line 57 HTML Problem Undefined attribute name (lay-filter). attendanceList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 47 HTML Problem Undefined attribute name (lay-filter). changePassword.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/infor line 57 HTML Problem Undefined attribute name (lay-filter). changePassword.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 57 HTML Problem Undefined attribute name (lay-filter). department-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/department line 51 HTML Problem Undefined attribute name (lay-filter). department-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/department line 53 HTML Problem Undefined attribute name (lay-filter). department-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/department line 48 HTML Problem Undefined attribute name (lay-filter). employee-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 115 HTML Problem Undefined attribute name (lay-filter). employee-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 128 HTML Problem Undefined attribute name (lay-filter). employee-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 139 HTML Problem Undefined attribute name (lay-filter). employee-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 227 HTML Problem Undefined attribute name (lay-filter). employee-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 119 HTML Problem Undefined attribute name (lay-filter). employee-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 132 HTML Problem Undefined attribute name (lay-filter). employee-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 143 HTML Problem Undefined attribute name (lay-filter). employee-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 231 HTML Problem Undefined attribute name (lay-filter). employee-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 52 HTML Problem Undefined attribute name (lay-filter). employee-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 79 HTML Problem Undefined attribute name (lay-filter). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 42 HTML Problem Undefined attribute name (lay-filter). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 27 HTML Problem Undefined attribute name (lay-filter). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 218 HTML Problem Undefined attribute name (lay-filter). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 28 HTML Problem Undefined attribute name (lay-filter). index.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 95 HTML Problem Undefined attribute name (lay-filter). inforEmployee.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 186 HTML Problem Undefined attribute name (lay-filter). monthlyattendance-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 125 HTML Problem Undefined attribute name (lay-filter). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 45 HTML Problem Undefined attribute name (lay-filter). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 81 HTML Problem Undefined attribute name (lay-filter). position-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/position line 57 HTML Problem Undefined attribute name (lay-filter). position-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/position line 59 HTML Problem Undefined attribute name (lay-filter). position-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/position line 53 HTML Problem Undefined attribute name (lay-filter). rank-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rank line 52 HTML Problem Undefined attribute name (lay-filter). rank-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rank line 64 HTML Problem Undefined attribute name (lay-filter). rank-list.jsp /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rank line 42 JSP Problem Undefined attribute name (lay-filter). rankBonusEdit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rankBonus line 55 HTML Problem Undefined attribute name (lay-filter). rankBonusList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rankBonus line 45 HTML Problem Undefined attribute name (lay-filter). rankBonusadd.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rankBonus line 53 HTML Problem Undefined attribute name (lay-filter). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 58 HTML Problem Undefined attribute name (lay-filter). salaryIssueList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 67 HTML Problem Undefined attribute name (lay-filter). salarySettlement.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 42 HTML Problem Undefined attribute name (lay-filter). salarySettlement.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 65 HTML Problem Undefined attribute name (lay-filter). wageManagement.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/wage line 91 HTML Problem Undefined attribute name (lay-filter). workingYearsBonusAdd.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/workBonus line 53 HTML Problem Undefined attribute name (lay-filter). workingYearsBonusEdit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/workBonus line 55 HTML Problem Undefined attribute name (lay-filter). workingYearsBonusList.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/workBonus line 52 HTML Problem Undefined attribute name (lay-search). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 40 HTML Problem Undefined attribute name (lay-skin). rank-list.jsp /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rank line 54 JSP Problem Undefined attribute name (lay-skin). rank-list.jsp /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rank line 67 JSP Problem Undefined attribute name (lay-submit). changePassword.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/infor line 57 HTML Problem Undefined attribute name (lay-submit). changePassword.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 57 HTML Problem Undefined attribute name (lay-submit). department-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/department line 51 HTML Problem Undefined attribute name (lay-submit). department-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/department line 53 HTML Problem Undefined attribute name (lay-submit). employee-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 227 HTML Problem Undefined attribute name (lay-submit). employee-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 231 HTML Problem Undefined attribute name (lay-submit). inforEmployee.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 186 HTML Problem Undefined attribute name (lay-submit). monthlyattendance-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 125 HTML Problem Undefined attribute name (lay-submit). position-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/position line 57 HTML Problem Undefined attribute name (lay-submit). position-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/position line 59 HTML Problem Undefined attribute name (lay-submit). rank-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rank line 52 HTML Problem Undefined attribute name (lay-submit). rank-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rank line 64 HTML Problem Undefined attribute name (lay-submit). rank-list.jsp /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rank line 42 JSP Problem Undefined attribute name (lay-submit). rankBonusEdit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rankBonus line 55 HTML Problem Undefined attribute name (lay-submit). rankBonusadd.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rankBonus line 53 HTML Problem Undefined attribute name (lay-submit). salarySettlement.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 42 HTML Problem Undefined attribute name (lay-submit). salarySettlement.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 65 HTML Problem Undefined attribute name (lay-submit). wageManagement.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/wage line 91 HTML Problem Undefined attribute name (lay-submit). workingYearsBonusAdd.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/workBonus line 53 HTML Problem Undefined attribute name (lay-submit). workingYearsBonusEdit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/workBonus line 55 HTML Problem Undefined attribute name (lay-verify). adminLogin.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 46 HTML Problem Undefined attribute name (lay-verify). adminLogin.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 52 HTML Problem Undefined attribute name (lay-verify). adminLogin.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin line 64 HTML Problem Undefined attribute name (lay-verify). attendanceList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 37 HTML Problem Undefined attribute name (lay-verify). changePassword.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/infor line 28 HTML Problem Undefined attribute name (lay-verify). changePassword.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/infor line 39 HTML Problem Undefined attribute name (lay-verify). changePassword.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/infor line 49 HTML Problem Undefined attribute name (lay-verify). changePassword.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 28 HTML Problem Undefined attribute name (lay-verify). changePassword.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 39 HTML Problem Undefined attribute name (lay-verify). changePassword.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 49 HTML Problem Undefined attribute name (lay-verify). department-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/department line 40 HTML Problem Undefined attribute name (lay-verify). department-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/department line 46 HTML Problem Undefined attribute name (lay-verify). department-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/department line 42 HTML Problem Undefined attribute name (lay-verify). department-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/department line 48 HTML Problem Undefined attribute name (lay-verify). department-salary.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/echarts line 29 HTML Problem Undefined attribute name (lay-verify). employee-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 39 HTML Problem Undefined attribute name (lay-verify). employee-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 47 HTML Problem Undefined attribute name (lay-verify). employee-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 56 HTML Problem Undefined attribute name (lay-verify). employee-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 87 HTML Problem Undefined attribute name (lay-verify). employee-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 97 HTML Problem Undefined attribute name (lay-verify). employee-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 154 HTML Problem Undefined attribute name (lay-verify). employee-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 164 HTML Problem Undefined attribute name (lay-verify). employee-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 173 HTML Problem Undefined attribute name (lay-verify). employee-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 203 HTML Problem Undefined attribute name (lay-verify). employee-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 209 HTML Problem Undefined attribute name (lay-verify). employee-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 218 HTML Problem Undefined attribute name (lay-verify). employee-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 223 HTML Problem Undefined attribute name (lay-verify). employee-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 237 HTML Problem Undefined attribute name (lay-verify). employee-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 43 HTML Problem Undefined attribute name (lay-verify). employee-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 51 HTML Problem Undefined attribute name (lay-verify). employee-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 60 HTML Problem Undefined attribute name (lay-verify). employee-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 91 HTML Problem Undefined attribute name (lay-verify). employee-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 101 HTML Problem Undefined attribute name (lay-verify). employee-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 158 HTML Problem Undefined attribute name (lay-verify). employee-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 168 HTML Problem Undefined attribute name (lay-verify). employee-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 177 HTML Problem Undefined attribute name (lay-verify). employee-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 207 HTML Problem Undefined attribute name (lay-verify). employee-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 213 HTML Problem Undefined attribute name (lay-verify). employee-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 222 HTML Problem Undefined attribute name (lay-verify). employee-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 227 HTML Problem Undefined attribute name (lay-verify). employee-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 241 HTML Problem Undefined attribute name (lay-verify). employeeSalaryList.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 36 HTML Problem Undefined attribute name (lay-verify). inforEmployee.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 162 HTML Problem Undefined attribute name (lay-verify). inforEmployee.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 168 HTML Problem Undefined attribute name (lay-verify). inforEmployee.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 177 HTML Problem Undefined attribute name (lay-verify). inforEmployee.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 182 HTML Problem Undefined attribute name (lay-verify). inforEmployee.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 194 HTML Problem Undefined attribute name (lay-verify). monthlyattendance-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 66 HTML Problem Undefined attribute name (lay-verify). monthlyattendance-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 71 HTML Problem Undefined attribute name (lay-verify). monthlyattendance-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 82 HTML Problem Undefined attribute name (lay-verify). monthlyattendance-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 87 HTML Problem Undefined attribute name (lay-verify). monthlyattendance-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 92 HTML Problem Undefined attribute name (lay-verify). monthlyattendance-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 103 HTML Problem Undefined attribute name (lay-verify). monthlyattendance-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 108 HTML Problem Undefined attribute name (lay-verify). monthlyattendance-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 113 HTML Problem Undefined attribute name (lay-verify). monthlyattendance-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 118 HTML Problem Undefined attribute name (lay-verify). monthlyattendance-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/attendance line 54 HTML Problem Undefined attribute name (lay-verify). position-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/position line 40 HTML Problem Undefined attribute name (lay-verify). position-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/position line 46 HTML Problem Undefined attribute name (lay-verify). position-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/position line 52 HTML Problem Undefined attribute name (lay-verify). position-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/position line 42 HTML Problem Undefined attribute name (lay-verify). position-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/position line 48 HTML Problem Undefined attribute name (lay-verify). position-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/position line 54 HTML Problem Undefined attribute name (lay-verify). rankBonusEdit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rankBonus line 43 HTML Problem Undefined attribute name (lay-verify). rankBonusEdit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rankBonus line 50 HTML Problem Undefined attribute name (lay-verify). rankBonusadd.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rankBonus line 41 HTML Problem Undefined attribute name (lay-verify). rankBonusadd.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rankBonus line 48 HTML Problem Undefined attribute name (lay-verify). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 40 HTML Problem Undefined attribute name (lay-verify). salary-list.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 47 HTML Problem Undefined attribute name (lay-verify). salary-percent.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/echarts line 28 HTML Problem Undefined attribute name (lay-verify). salary-percent.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/echarts line 35 HTML Problem Undefined attribute name (lay-verify). salarySettlement.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 38 HTML Problem Undefined attribute name (lay-verify). salarySettlement.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 55 HTML Problem Undefined attribute name (lay-verify). salarySettlement.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/salary line 60 HTML Problem Undefined attribute name (lay-verify). wageManagement.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/wage line 44 HTML Problem Undefined attribute name (lay-verify). wageManagement.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/wage line 52 HTML Problem Undefined attribute name (lay-verify). wageManagement.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/wage line 60 HTML Problem Undefined attribute name (lay-verify). wageManagement.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/wage line 68 HTML Problem Undefined attribute name (lay-verify). wageManagement.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/wage line 76 HTML Problem Undefined attribute name (lay-verify). wageManagement.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/wage line 84 HTML Problem Undefined attribute name (lay-verify). workingYearsBonusAdd.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/workBonus line 41 HTML Problem Undefined attribute name (lay-verify). workingYearsBonusAdd.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/workBonus line 48 HTML Problem Undefined attribute name (lay-verify). workingYearsBonusEdit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/workBonus line 41 HTML Problem Undefined attribute name (lay-verify). workingYearsBonusEdit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/workBonus line 49 HTML Problem Undefined attribute name (pane). employee-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 75 HTML Problem Undefined attribute name (pane). employee-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/employee line 79 HTML Problem Undefined attribute value (). changePassword.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/infor line 28 HTML Problem Undefined attribute value (). changePassword.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/infor line 39 HTML Problem Undefined attribute value (). changePassword.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/infor line 49 HTML Problem Undefined attribute value (). changePassword.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 28 HTML Problem Undefined attribute value (). changePassword.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 39 HTML Problem Undefined attribute value (). changePassword.html /EmployeesManager/src/main/webapp/WEB-INF/page/employee line 49 HTML Problem Undefined attribute value (). rank-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rank line 36 HTML Problem Undefined attribute value (). rank-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rank line 45 HTML Problem Undefined attribute value (). rank-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rank line 39 HTML Problem Undefined attribute value (). rank-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rank line 48 HTML Problem Undefined attribute value (). rank-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rank line 57 HTML Problem Unknown referenced nature: org.springframework.ide.eclipse.core.springnature. .project /EmployeesManager Unknown Unknown nature Unknown tag (!). department-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/department line 20 HTML Problem Unknown tag (!). department-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/department line 20 HTML Problem Unknown tag (!). position-add.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/position line 20 HTML Problem Unknown tag (!). position-edit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/position line 20 HTML Problem Unknown tag (!). rankBonusEdit.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rankBonus line 20 HTML Problem Unknown tag (!). rankBonusadd.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rankBonus line 20 HTML Problem Unknown tag (!). workingYearsBonusAdd.html /EmployeesManager/src/main/webapp/WEB-INF/page/admin/workBonus line 20 HTML Problem Unknown tag (xblock). rank-list.jsp /EmployeesManager/src/main/webapp/WEB-INF/page/admin/rank line 45 JSP Problem
07-19
/* 文件路径: index.js */ /* 文件路径: pages/index/index.js */ // 首页逻辑文件 const app = getApp(); Page({ data: { // 统计数据 totalOrders: 0, totalProducts: 0, totalMaterials: 0, totalStock: 0, // 搜索条件 orderSearch: '', productSearch: '', materialSearch: '', woodSearch: '', thicknessSearch: '', minStock: '', maxStock: '', // 结果数据 loading: true, results: [], filteredResults: [], resultCount: 0, lastUpdate: '--:--:--', // 排序 sortField: null, sortDirection: 'asc', // 分页 currentPage: 1, pageSize: 10, totalPages: 1, // 当前页数据 currentPageData: [], // 板材详情 showMaterialDetail: false, materialDetail: null }, onLoad: function() { console.log('index页面加载'); // 获取全局数据管理器 if (app.globalData && app.globalData.dataManager) { this.dataManager = app.globalData.dataManager; console.log('获取到dataManager实例'); // 注册数据更新回调 this.dataManager.registerCallback('all', () => { console.log('收到数据更新回调'); this.updatePageData(); }); // 初始化页面数据 this.updatePageData(); // 主动加载数据 this.dataManager.fetchAll().then(() => { console.log('数据加载成功'); }).catch(err => { console.error('数据加载失败:', err); wx.showToast({ title: '数据加载失败', icon: 'none' }); }); } else { console.error('DataManager not available'); wx.showToast({ title: '数据管理器未初始化', icon: 'none' }); // 尝试重新初始化 if (app.initDataManager) { app.initDataManager(); } } }, onShow: function() { console.log('首页显示'); // 检查是否需要登录 if (app.globalData && app.globalData.needLogin) { console.log('检测到需要登录'); // 延迟500ms确保页面渲染完成 setTimeout(() => { app.checkWechatLogin(); }, 500); } }, // 更新页面数据 updatePageData: function() { if (!this.dataManager || !this.dataManager.data) return; this.setData({ loading: true }); // 更新统计数据 this.updateStats(); // 更新表格数据 this.updateTable(); // 更新最后更新时间 const now = new Date(); const lastUpdate = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`; this.setData({ lastUpdate }); }, // 更新统计数据 updateStats: function() { const data = this.dataManager.data; const totalOrders = data.dingdans?.length || 0; const totalProducts = data.chanpins?.length || 0; const totalMaterials = data.bancais?.length || 0; const totalStock = data.kucuns?.reduce((sum, kucun) => sum + kucun.shuliang, 0) || 0; this.setData({ totalOrders, totalProducts, totalMaterials, totalStock }); }, // 更新表格数据 updateTable: function() { console.log('开始更新表格数据'); const data = this.dataManager.data; console.log('原始数据:', JSON.stringify(data, null, 2)); let results = []; // 直接遍历dingdan_bancai表获取数据 if (data.dingdan_bancais) { data.dingdan_bancais.forEach(db => { // 获取关联信息 const dingdan = db.dingdan || {}; const chanpin = db.chanpin || {}; const zujian = db.zujian || {}; const bancai = db.bancai || {}; // 获取库存数量 const kucun = data.kucuns?.find(k => k.bancai && k.bancai.id === bancai.id); const stockQuantity = kucun ? kucun.shuliang : 0; // 构建板材信息 const materialInfo = this.getMaterialInfo(bancai); // 构建结果项 results.push({ id: `${db.id}`, orderNumber: dingdan.number || '无', productInfo: chanpin.bianhao || '独立订购', productQuantity: db.shuliang, component: zujian.name || '独立板材', material: materialInfo, materialPerComponent: 1, // 直接订购时,每件用量为1 materialOrderQuantity: db.shuliang, stockQuantity: stockQuantity, raw: { orderNumber: dingdan.number, productQuantity: db.shuliang, materialPerComponent: 1, materialOrderQuantity: db.shuliang, stockQuantity: stockQuantity, thickness: bancai.houdu || 0 }, bancaiId: bancai.id }); }); } // 应用排序 if (this.data.sortField !== null) { results = this.sortResults(results, this.data.sortField, this.data.sortDirection); } // 更新页面数据 this.setData({ results: results, filteredResults: results, resultCount: results.length, totalPages: Math.ceil(results.length / this.data.pageSize), currentPage: 1, loading: false }, () => { // 更新当前页数据 this.updateCurrentPageData(); }); // 应用筛选 this.applyFilters(); }, // 获取板材详细信息函数 getMaterialInfo: function(bancai) { if (!bancai) return '未知板材'; // 获取材质名称 const caizhiName = bancai.caizhi?.name || '未知材质'; // 获取木皮信息 const formatMupi = (mupi) => { if (!mupi) return null; return `${mupi.name}${mupi.you ? '()' : ''}`; }; const mupi1Str = formatMupi(bancai.mupi1) || '无'; const mupi2Str = formatMupi(bancai.mupi2) || '无'; const mupiInfo = mupi1Str + (mupi2Str !== '无' ? `/${mupi2Str}` : ''); // 厚度转换为字符串 const thickness = bancai.houdu ? `${bancai.houdu}mm` : '未知厚度'; return `${caizhiName}-${mupiInfo} (${thickness})`; }, // 搜索输入处理函数 onOrderSearchInput: function(e) { this.setData({ orderSearch: e.detail.value }); this.applyFilters(); }, onProductSearchInput: function(e) { this.setData({ productSearch: e.detail.value }); this.applyFilters(); }, onMaterialSearchInput: function(e) { this.setData({ materialSearch: e.detail.value }); this.applyFilters(); }, onWoodSearchInput: function(e) { this.setData({ woodSearch: e.detail.value }); // 支持中文和数字搜索 const searchTerm = e.detail.value.toLowerCase(); const searchKeywords = { '有油': '有油', '无油': '无油', 'you': '有油', 'wu': '无油', '1': '有油', '0': '无油', '()': '()' }; this.setData({ woodSearch: searchKeywords[searchTerm] || searchTerm }); this.applyFilters(); }, onThicknessSearchInput: function(e) { this.setData({ thicknessSearch: e.detail.value }); this.applyFilters(); }, onMinStockInput: function(e) { this.setData({ minStock: e.detail.value }); }, onMaxStockInput: function(e) { this.setData({ maxStock: e.detail.value }); }, // 库存范围搜索 onStockSearch: function() { this.applyFilters(); }, // 重置筛选 resetFilters: function() { this.setData({ orderSearch: '', productSearch: '', materialSearch: '', woodSearch: '', thicknessSearch: '', minStock: '', maxStock: '', sortField: null, sortDirection: 'asc', currentPage: 1 }); this.updateTable(); }, // 应用筛选条件 applyFilters: function() { let filtered = [...this.data.results]; // 应用订单号筛选 if (this.data.orderSearch) { const search = this.data.orderSearch.toLowerCase(); filtered = filtered.filter(item => item.orderNumber && item.orderNumber.toLowerCase().includes(search) ); } // 应用产品筛选 if (this.data.productSearch) { const search = this.data.productSearch.toLowerCase(); filtered = filtered.filter(item => item.productInfo && item.productInfo.toLowerCase().includes(search) ); } // 应用板材筛选 if (this.data.materialSearch) { const search = this.data.materialSearch.toLowerCase(); filtered = filtered.filter(item => item.material && item.material.toLowerCase().includes(search) ); } // 应用木皮筛选 if (this.data.woodSearch) { const search = this.data.woodSearch.toLowerCase(); filtered = filtered.filter(item => item.material && item.material.toLowerCase().includes(search) ); } // 应用厚度筛选 if (this.data.thicknessSearch) { const thickness = parseFloat(this.data.thicknessSearch); if (!isNaN(thickness)) { filtered = filtered.filter(item => { // 提取厚度数字部分进行匹配 const thicknessMatch = item.material.match(/(\d+\.?\d*)/); if (thicknessMatch) { const thicknessValue = parseFloat(thicknessMatch[1]); // 允许小数点误差 return Math.abs(thicknessValue - thickness) < 0.5; } return false; }); } } // 应用库存范围筛选 if (this.data.minStock !== '' || this.data.maxStock !== '') { const min = this.data.minStock !== '' ? parseInt(this.data.minStock) : Number.MIN_SAFE_INTEGER; const max = this.data.maxStock !== '' ? parseInt(this.data.maxStock) : Number.MAX_SAFE_INTEGER; filtered = filtered.filter(item => item.stockQuantity >= min && item.stockQuantity <= max ); } // 更新筛选结果 this.setData({ filteredResults: filtered, resultCount: filtered.length, totalPages: Math.ceil(filtered.length / this.data.pageSize), currentPage: 1 }, () => { this.updateCurrentPageData(); }); }, // 排序处理 sortBy: function(e) { const field = e.currentTarget.dataset.field; // 如果点击的是当前排序字段,则切换排序方向 if (field === this.data.sortField) { this.setData({ sortDirection: this.data.sortDirection === 'asc' ? 'desc' : 'asc' }); } else { // 否则,设置新的排序字段,默认升序 this.setData({ sortField: field, sortDirection: 'asc' }); } // 应用排序 const sorted = this.sortResults(this.data.filteredResults, this.data.sortField, this.data.sortDirection); this.setData({ filteredResults: sorted }, () => { // 更新当前页数据 this.updateCurrentPageData(); }); }, // 排序结果 sortResults: function(results, field, direction) { if (!field) return results; return [...results].sort((a, b) => { let valueA, valueB; // 根据排序字段获取值 switch (field) { case 'dingdan.number': valueA = a.orderNumber; valueB = b.orderNumber; break; case 'chanpin.bianhao': valueA = a.productInfo; valueB = b.productInfo; break; case 'dingdan_chanpin.shuliang': valueA = a.productQuantity; valueB = b.productQuantity; break; case 'zujian.name': valueA = a.component; valueB = b.component; break; case 'bancai.id': // 特殊处理:按厚度排序 return this.sortByThickness(a, b, direction); case 'chanpin_zujian.one_howmany': valueA = a.materialPerComponent; valueB = b.materialPerComponent; break; case 'orderUsage': valueA = a.materialOrderQuantity; valueB = b.materialOrderQuantity; break; case 'kucun.shuliang': valueA = a.stockQuantity; valueB = b.stockQuantity; break; default: valueA = a.orderNumber; valueB = b.orderNumber; } // 数值比较 if (['productQuantity', 'materialPerComponent', 'materialOrderQuantity', 'stockQuantity'].includes(field)) { return this.sortNumeric(valueA, valueB, direction); } // 字符串比较 return this.sortString(valueA, valueB, direction); }); }, // 按厚度排序(特殊处理) sortByThickness: function(a, b, direction) { return this.sortNumeric(a.raw.thickness, b.raw.thickness, direction); }, // 数值排序辅助函数 sortNumeric: function(aVal, bVal, direction) { const aNum = parseFloat(aVal) || 0; const bNum = parseFloat(bVal) || 0; return direction === 'asc' ? aNum - bNum : bNum - aNum; }, // 字符串排序辅助函数 sortString: function(aVal, bVal, direction) { const aStr = String(aVal).toLowerCase(); const bStr = String(bVal).toLowerCase(); if (aStr < bStr) return direction === 'asc' ? -1 : 1; if (aStr > bStr) return direction === 'asc' ? 1 : -1; return 0; }, // 分页处理 prevPage: function() { if (this.data.currentPage > 1) { this.setData({ currentPage: this.data.currentPage - 1 }, () => { this.updateCurrentPageData(); }); } }, nextPage: function() { if (this.data.currentPage < this.data.totalPages) { this.setData({ currentPage: this.data.currentPage + 1 }, () => { this.updateCurrentPageData(); }); } }, // 更新当前页数据 updateCurrentPageData: function() { const startIndex = (this.data.currentPage - 1) * this.data.pageSize; const endIndex = startIndex + this.data.pageSize; const currentPageData = this.data.filteredResults.slice(startIndex, endIndex).map((item, index) => { // 为每个项目添加一个唯一的ID,使用索引确保唯一性 return { ...item, uniqueId: `item-${startIndex + index}` }; }); this.setData({ currentPageData }); }, // 显示板材详情 showMaterialDetail: function(e) { const materialId = e.currentTarget.dataset.id; // 查找板材详情 const bancai = this.dataManager.data.bancais.find(b => b.id === materialId); if (!bancai) { wx.showToast({ title: '未找到板材信息', icon: 'none' }); return; } // 获取库存信息 const kucun = this.dataManager.data.kucuns ? this.dataManager.data.kucuns.find(k => k.bancai && k.bancai.id === materialId) : null; // 格式化木皮信息 const formatMupiDetail = (mupi) => { if (!mupi) return '无'; return `${mupi.name}${mupi.you ? '()' : ''}`; }; // 获取相关订单 const relatedOrders = this.getRelatedOrders(bancai); // 设置详情数据 this.setData({ materialDetail: { id: bancai.id, material: bancai.caizhi?.name || '未知', thickness: bancai.houdu ? bancai.houdu.toFixed(1) + 'mm' : '未知', stock: kucun ? kucun.shuliang : 0, mupi1: formatMupiDetail(bancai.mupi1), mupi2: formatMupiDetail(bancai.mupi2), relatedOrders: relatedOrders.map(order => ({ number: order.number, xiadan: order.xiadan ? this.formatDate(order.xiadan) : '-', jiaohuo: order.jiaohuo ? this.formatDate(order.jiaohuo) : '-' })) }, showMaterialDetail: true }); }, // 关闭板材详情 closeMaterialDetail: function() { this.setData({ showMaterialDetail: false }); }, // 获取板材相关订单 getRelatedOrders: function(bancai) { const data = this.dataManager.data; const orderMap = new Map(); // 使用Map进行订单去重 // 查找直接订单组件关联 const dingdan_bancais = data.dingdan_bancais || []; dingdan_bancais.forEach(db => { if (db.bancai && db.bancai.id === bancai.id && db.dingdan) { orderMap.set(db.dingdan.id, db.dingdan); } }); // 转换为数组并排序(按下单日期降序) return Array.from(orderMap.values()).sort((a, b) => { const dateA = a.xiadan ? new Date(a.xiadan) : new Date(0); const dateB = b.xiadan ? new Date(b.xiadan) : new Date(0); return dateB - dateA; // 最近的订单在前 }); }, // 格式化日期 formatDate: function(dateString) { if (!dateString) return ''; const date = new Date(dateString); return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`; } }); ================================================================================ /* 文件路径: index.wxml */ <!-- 首页页面结构 --> <view class="container"> <!-- 标题部分 --> <view class="header-section"> <view class="title">板材库存管理系统</view> <view class="subtitle">查询订单、产品、板材及库存信息</view> </view> <!-- 统计卡片区域 --> <view class="stats-container"> <view class="stat-card"> <view class="stat-title">总订单数</view> <view class="stat-value">{{totalOrders}}</view> <view class="stat-icon"><icon type="success" size="20"/></view> </view> <view class="stat-card"> <view class="stat-title">产品总数</view> <view class="stat-value">{{totalProducts}}</view> <view class="stat-icon"><icon type="info" size="20"/></view> </view> <view class="stat-card"> <view class="stat-title">板材总数</view> <view class="stat-value">{{totalMaterials}}</view> <view class="stat-icon"><icon type="waiting" size="20"/></view> </view> </view> <!-- 搜索区域 --> <view class="search-section"> <view class="search-header"> <icon type="search" size="18"/> <text>高级搜索</text> </view> <view class="search-body"> <view class="search-row"> <!-- 订单搜索 --> <view class="search-item"> <view class="search-control"> <icon type="search" size="16"/> <input type="text" placeholder="搜索订单号..." bindinput="onOrderSearchInput"/> </view> </view> <!-- 产品搜索 --> <view class="search-item"> <view class="search-control"> <icon type="search" size="16"/> <input type="text" placeholder="搜索产品编号..." bindinput="onProductSearchInput"/> </view> </view> </view> <view class="search-row"> <!-- 板材搜索 --> <view class="search-item"> <view class="search-control"> <icon type="search" size="16"/> <input type="text" placeholder="搜索板材ID或材质..." bindinput="onMaterialSearchInput"/> </view> </view> <!-- 木皮搜索 --> <view class="search-item"> <view class="search-control"> <icon type="search" size="16"/> <input type="text" placeholder="搜索木皮名称..." bindinput="onWoodSearchInput"/> </view> </view> </view> <view class="search-row"> <!-- 厚度搜索 --> <view class="search-item"> <view class="search-control"> <icon type="search" size="16"/> <input type="digit" placeholder="厚度(mm)" bindinput="onThicknessSearchInput"/> </view> </view> <!-- 库存范围搜索 --> <view class="search-item"> <view class="stock-range"> <input type="number" placeholder="最小库存" bindinput="onMinStockInput"/> <input type="number" placeholder="最大库存" bindinput="onMaxStockInput"/> <button class="search-btn" bindtap="onStockSearch"><icon type="search" size="16"/></button> </view> </view> </view> <!-- 重置按钮 --> <view class="search-actions"> <button class="reset-btn" bindtap="resetFilters"> <icon type="cancel" size="16"/> 重置筛选 </button> </view> </view> </view> <!-- 结果区域 --> <view class="results-section"> <view class="results-header"> <view class="results-title"> <icon type="success" size="18"/> <text>查询结果</text> </view> <view class="results-info"> <text>{{resultCount}} 条记录</text> <text class="update-time">数据更新时间: {{lastUpdate}}</text> </view> </view> <view class="results-body"> <!-- 表格头部 --> <view class="table-header"> <view class="th" bindtap="sortBy" data-field="dingdan.number">订单号</view> <view class="th" bindtap="sortBy" data-field="chanpin.bianhao">产品信息</view> <view class="th" bindtap="sortBy" data-field="dingdan_chanpin.shuliang">产品数量</view> <view class="th" bindtap="sortBy" data-field="zujian.name">组件</view> <view class="th" bindtap="sortBy" data-field="bancai.id">板材</view> <view class="th" bindtap="sortBy" data-field="chanpin_zujian.one_howmany">单件用量</view> <view class="th" bindtap="sortBy" data-field="orderUsage">订单用量</view> <view class="th" bindtap="sortBy" data-field="kucun.shuliang">库存数量</view> <view class="th">操作</view> </view> <!-- 表格内容 --> <view class="table-body"> <block wx:if="{{loading}}"> <view class="loading-row"> <view class="loading-spinner"></view> <text>正在加载数据,请稍候...</text> </view> </block> <block wx:elif="{{results.length === 0}}"> <view class="no-results"> <icon type="info" size="40"/> <view class="no-results-text">没有找到匹配的记录</view> <view class="no-results-hint">请尝试调整您的搜索条件</view> </view> </block> <block wx:else> <!-- 调试信息 --> <view class="debug-info"> <text>currentPageData长度: {{currentPageData.length}}</text> <text>results长度: {{results.length}}</text> </view> <view class="table-row" wx:for="{{currentPageData}}" wx:key="uniqueId"> <view class="td">{{item.orderNumber}}</view> <view class="td">{{item.productInfo}}</view> <view class="td">{{item.productQuantity}}</view> <view class="td">{{item.component}}</view> <view class="td">{{item.material}}</view> <view class="td">{{item.materialPerComponent}}</view> <view class="td">{{item.materialOrderQuantity}}</view> <view class="td">{{item.stockQuantity}}</view> <view class="td"> <button class="detail-btn" bindtap="showMaterialDetail" data-id="{{item.bancaiId}}">详情</button> </view> </view> </block> </view> <!-- 分页控件 --> <view class="pagination" wx:if="{{!loading && results.length > 0}}"> <button class="page-btn" disabled="{{currentPage === 1}}" bindtap="prevPage">上一页</button> <view class="page-info">{{currentPage}}/{{totalPages}}</view> <button class="page-btn" disabled="{{currentPage === totalPages}}" bindtap="nextPage">下一页</button> </view> </view> </view> </view> <!-- 板材详情弹窗 --> <view class="material-modal {{showMaterialDetail ? 'show' : ''}}"> <view class="modal-content"> <view class="modal-header"> <text>板材详情</text> <icon type="cancel" size="20" bindtap="closeMaterialDetail"/> </view> <view class="modal-body"> <!-- 详情内容 --> <block wx:if="{{materialDetail}}"> <view class="detail-item"> <text class="detail-label">板材ID:</text> <text class="detail-value">{{materialDetail.id}}</text> </view> <view class="detail-item"> <text class="detail-label">材质:</text> <text class="detail-value">{{materialDetail.material}}</text> </view> <view class="detail-item"> <text class="detail-label">木皮:</text> <text class="detail-value">{{materialDetail.wood}}</text> </view> <view class="detail-item"> <text class="detail-label">厚度:</text> <text class="detail-value">{{materialDetail.thickness}}mm</text> </view> <view class="detail-item"> <text class="detail-label">库存:</text> <text class="detail-value">{{materialDetail.stock}}</text> </view> </block> </view> <view class="modal-footer"> <button bindtap="closeMaterialDetail">关闭</button> </view> </view> </view> ================================================================================ /* 文件路径: MiniProgramDataManager.js */ /** * 微信小程序数据管理器 * 基于DataManager.js的逻辑,但适配微信小程序环境 */ // 解析数据引用关系的辅助函数 /** * 解析数据中的引用关系 * * 该函数用于处理嵌套的数据结构,将数据中的引用关系解析为实际的对象引用。 * 它会遍历数据中的所有实体,查找属性名中包含的数字(如"item1"), * 并尝试将这些属性值替换为对应类型数据中的实际对象引用。 * * @param {Object} data - 包含嵌套引用的原始数据对象 * @returns {Object} 处理后的数据对象,其中引用已被解析为实际对象 */ function resolveDataReferences(data) { const keys = Object.keys(data); for (const key of keys) { const entities = data[key]; for (const entity of entities) { for (const attribute in entity) { if (entity.hasOwnProperty(attribute)) { // 修复:统一使用复数形式查找引用类型 let refType = attribute.replace(/\d/g, ''); // 尝试直接查找复数形式 if (!data[refType] && data[`${refType}s`]) { refType = `${refType}s`; } if (Array.isArray(entity[attribute])) { entity[attribute] = entity[attribute].map(item => data[refType]?.find(updateItem => updateItem.id === item.id) || item ); } else if (typeof entity[attribute] === "object" && entity[attribute] !== null) { entity[attribute] = data[refType]?.find(updateItem => updateItem.id === entity[attribute].id) || entity[attribute]; } } } } } return data; } // 解析单个实体的数据引用 /** * 解析数据引用关系 * * 该函数用于处理实体对象与数据源之间的引用关系,自动匹配并更新实体中的引用字段。 * * @param {Object} entity - 需要处理的实体对象 * @param {Object} data - 包含引用数据的数据源对象 * @returns {Object} 处理后的实体对象 * * 功能说明: * 1. 遍历实体对象的每个属性 * 2. 如果属性值是数组,则尝试在数据源中查找匹配项更新数组元素 * 3. 如果属性值是对象,则尝试在数据源中查找匹配项更新该对象 * 4. 自动处理单复数形式的数据源键名 */ function resolveDataReference(entity, data) { for (const attribute in entity) { if (entity.hasOwnProperty(attribute)) { // 修复:统一使用复数形式查找引用类型 let refType = attribute.replace(/\d/g, ''); // 尝试直接查找复数形式 if (!data[refType] && data[`${refType}s`]) { refType = `${refType}s`; } if (Array.isArray(entity[attribute])) { entity[attribute] = entity[attribute].map(item => data[refType]?.find(updateItem => updateItem.id === item.id) || item ); } else if (typeof entity[attribute] === "object" && entity[attribute] !== null) { entity[attribute] = data[refType]?.find(updateItem => updateItem.id === entity[attribute].id) || entity[attribute]; } } } return entity; } class LazyLoader { constructor(dataManager) { this.dataManager = dataManager; this.resolvedCache = new Map(); // 缓存已解析的实体 } /** * 创建实体代理 * @param {Object} entity 实体对象 * @param {string} entityType 实体类型 * @returns {Proxy} 返回代理后的实体 */ createProxy(entity, entityType) { const handler = { get: (target, prop) => { // 1. 处理特殊属性直接返回 if (prop.startsWith('_') || typeof target[prop] === 'function') { return target[prop]; } const value = target[prop]; // 2. 处理数组属性 if (Array.isArray(value)) { return value.map(item => this.resolveReference(item, prop) ); } // 3. 处理对象属性 if (typeof value === 'object' && value !== null) { return this.resolveReference(value, prop); } // 4. 返回普通属性值 return value; } }; return new Proxy(entity, handler); } /** * 解析引用关系(核心逻辑) * 根据resolveDataReference函数逻辑实现 */ resolveReference(ref, propName) { // 1. 检查缓存 const cacheKey = `${propName}_${ref.id}`; if (this.resolvedCache.has(cacheKey)) { return this.resolvedCache.get(cacheKey); } // 2. 确定引用类型(与resolveDataReference相同逻辑) let refType = propName.replace(/\d/g, ''); const rawData = this.dataManager._rawData; // 处理复数形式(与resolveDataReference相同) if (!rawData[refType] && rawData[`${refType}s`]) { refType = `${refType}s`; } // 3. 查找引用实体(与resolveDataReference相同) const refEntities = rawData[refType]; if (!refEntities) return ref; const resolved = refEntities.find(e => e.id === ref.id); if (!resolved) return ref; // 4. 创建代理并缓存 const proxy = this.createProxy(resolved, refType); this.resolvedCache.set(cacheKey, proxy); return proxy; } /** * 清除缓存(数据更新时调用) */ clearCache() { this.resolvedCache.clear(); } } class MiniProgramDataManager { // 修复:合并重复的构造函数 constructor(baseUrl) { this.baseUrl = baseUrl; this.debug = true; // 调试模式开关 this.requestCount = 0; // 请求计数器 // 数据结构定义 this._rawData = { bancais: [], dingdans: [], mupis: [], chanpins: [], kucuns: [], dingdan_bancais: [], chanpin_zujians: [], zujians: [], caizhis: [], dingdan_chanpins: [], users: [], jinhuos: [], _lastModified: null, _lastSync: null }; // 初始化网络状态 this.networkAvailable = false; this.checkNetwork().then(type => { this.networkAvailable = type !== 'none'; }); this.lazyLoader = new LazyLoader(this); // 仅从本地存储加载数据,不自动同步 this.loadDataFromStorage(); this.isSyncing = false; this.lastSync = null; this.callbacks = { all: [], bancais: [], dingdan: [], mupi: [], chanpin: [], kucun: [], chanpin_zujian: [], dingdan_bancai: [], zujian: [], caizhi: [], dingdan_chanpin: [], user: [], jinhuo: [] }; this.syncQueue = Promise.resolve(); this.entiyeText = { bancai: '板材已存在', dingdan: '订单已存在', mupi: '木皮已存在', chanpin: '产品已存在', kucun: '已有库存记录', chanpin_zujian: '产品已有该组件', dingdan_bancai: '', zujian: '组件已定义过了', caizhi: '材质已定义过了', dingdan_chanpin: '订单下已有该产品', user: '' }; this.syncInterval = 5 * 60 * 1000; // 5分钟 this.storageKey = 'miniProgramData'; // 本地存储的键名 } // 修改数据获取方法 get data() { const handler = { get: (target, prop) => { // 处理特殊属性 if (prop.startsWith('_')) { return target[prop]; } // 处理数组类型的实体集合 if (Array.isArray(target[prop])) { return target[prop].map(item => this.lazyLoader.createProxy(item, prop.replace(/s$/, '')) ); } return target[prop]; }, set: (target, prop, value) => { target[prop] = value; return true; } }; return new Proxy(this._rawData, handler); } // 添加显式初始化方法 async initialize() { // 启动自动同步 this.startAutoSync(); // 执行首次数据同步 await this.syncData(); } /** * 启动自动同步定时器 * 每隔syncInterval毫秒检查并执行数据同步 * 如果已有同步任务进行中则跳过 */ startAutoSync() { if (this.autoSyncTimer) clearInterval(this.autoSyncTimer); this.autoSyncTimer = setInterval(() => { if (!this.isSyncing) this.syncData(); }, this.syncInterval); } /** * 停止自动同步 */ stopAutoSync() { clearInterval(this.autoSyncTimer); } /** * 检查网络状态 */ checkNetwork() { return new Promise((resolve) => { wx.getNetworkType({ success: (res) => { resolve(res.networkType); }, fail: () => { resolve('unknown'); } }); }); } /** * 获取所有数据(全量或增量) * @async * @param {string} [since] - 增量获取的时间戳,不传则全量获取 * @returns {Promise<boolean>} 是否获取成功 * @description * - 根据since参数决定全量或增量获取数据 * - 增量获取时会合并新数据到现有数据 * - 全量获取会直接替换现有数据 * - 成功后会更新同步时间并保存到本地存储 * - 失败时会触发错误回调,若无历史数据则抛出错误 */ async fetchAll(since) { try { console.log(since ? `增量获取数据(自${since})...` : '全量获取数据...'); const params = since ? { since } : {}; const result = await this.request('/app/all', 'GET', params); const resolvedData =result ; // 更新networkData Object.keys(this._rawData).forEach(key => { if (key.startsWith('_')) return; if (resolvedData[key]) { if (since) { // 增量更新: 合并新数据到现有数据 resolvedData[key].forEach(newItem => { const index = this._rawData[key].findIndex(item => item.id === newItem.id); if (index >= 0) { this._rawData[key][index] = newItem; } else { this._rawData[key].push(newItem); } }); } else { // 全量更新: 直接替换 this._rawData[key] = resolvedData[key]; } } }); // 更新同步时间 this.lastSync = new Date(); this._rawData._lastSync = this.lastSync.toISOString(); // 保存到本地存储 this.saveDataToStorage(); this.triggerCallbacks('refresh', 'all', this.data); return true; } catch (error) { console.error('Fetch error:', error); this.triggerCallbacks('fetch_error', 'all', { error }); // 失败时尝试使用本地数据 if (!this.lastSync) { throw new Error('初始化数据获取失败'); } return false; } } /** * 微信小程序API请求封装 */ request(url, method = 'GET', data = null, retryCount = 3) { return new Promise((resolve, reject) => { const makeRequest = (attempt) => { const fullUrl = `${this.baseUrl}${url}`; if (this.debug) { console.log(`[请求] ${method} ${fullUrl}`, { attempt, data, timestamp: new Date().toISOString() }); } wx.request({ url: fullUrl, method, data, header: { 'Content-Type': 'application/json' }, success: (res) => { if (this.debug) { console.log(`[响应] ${fullUrl}`, { status: res.statusCode, data: res.data, headers: res.header }); } // 修复:更灵活的响应格式处理 if (!res.data) { const err = new Error('空响应数据'); if (attempt < retryCount) { this.retryRequest(makeRequest, attempt, retryCount, err); } else { reject(err); } return; } // 修复:支持多种成功状态码和响应格式 const isSuccess = res.statusCode >= 200 && res.statusCode < 300; const hasData = res.data && (res.data.data !== undefined || typeof res.data === 'object'); if (isSuccess && hasData) { resolve(res.data.data || res.data); } else { const errMsg = res.data.message || res.data.text || 'API错误'; const err = new Error(errMsg); if (attempt < retryCount) { this.retryRequest(makeRequest, attempt, retryCount, err); } else { reject(err); } } }, fail: (err) => { if (this.debug) { console.error(`[失败] ${fullUrl}`, err); } const error = new Error(`网络请求失败: ${err.errMsg || '未知错误'}`); if (attempt < retryCount) { this.retryRequest(makeRequest, attempt, retryCount, error); } else { reject(error); } } }); }; makeRequest(1); }); } retryRequest(makeRequest, attempt, retryCount, error) { const delay = 1000 * attempt; console.warn(`请求失败 (${attempt}/${retryCount}), ${delay}ms后重试:`, error.message); setTimeout(() => makeRequest(attempt + 1), delay); } /** * 注册回调函数 */ registerCallback(entity, callback) { if (!this.callbacks[entity]) { this.callbacks[entity] = []; } this.callbacks[entity].push(callback); } /** * 注销回调函数 */ unregisterCallback(entity, callback) { if (!this.callbacks[entity]) return; const index = this.callbacks[entity].indexOf(callback); if (index !== -1) { this.callbacks[entity].splice(index, 1); } } /** * 触发回调函数 */ triggerCallbacks(operation, entity, data) { this.callbacks.all.forEach(cb => cb(operation, entity, data)); if (this.callbacks[entity]) { this.callbacks[entity].forEach(cb => cb(operation, data)); } } /** * 检查重复实体 */ checkDuplicate(entity, data) { // 修复:确保引用已解析 const resolvedData = resolveDataReference(data, this.data); switch (entity) { case 'bancai': return this.data.bancais.some(b => b.houdu === resolvedData.houdu && b.caizhi?.id === resolvedData.caizhi?.id && b.mupi1?.id === resolvedData.mupi1?.id && b.mupi2?.id === resolvedData.mupi2?.id ); case 'caizhi': return this.data.caizhis.some(c => c.name === resolvedData.name); case 'mupi': return this.data.mupis.some(m => m.name === resolvedData.name && m.you === resolvedData.you); case 'chanpin': return this.data.chanpins.some(c => c.bianhao === resolvedData.bianhao); case 'zujian': return this.data.zujians.some(z => z.name === resolvedData.name); case 'dingdan': return this.data.dingdans.some(d => d.number === resolvedData.number); case 'chanpin_zujian': return this.data.chanpin_zujians.some(cz => cz.chanpin?.id === resolvedData.chanpin?.id && cz.zujian?.id === resolvedData.zujian?.id ); case 'dingdan_chanpin': return this.data.dingdan_chanpins.some(dc => dc.dingdan?.id === resolvedData.dingdan?.id && dc.chanpin?.id === resolvedData.chanpin?.id ); case 'dingdan_bancai': return this.data.dingdan_bancais.some(db => db.dingdan?.id === resolvedData.dingdan?.id && db.chanpin?.id === resolvedData.chanpin?.id && db.zujian?.id === resolvedData.zujian?.id && db.bancai?.id === resolvedData.bancai?.id ); case 'user': return this.data.users.some(u => u.name === resolvedData.name); default: return false; } } /** * CRUD操作通用方法 */ async crudOperation(operation, entity, data) { try { // 使用微信请求API替代fetch const result = await this.request(`/app/${operation}/${entity}`, 'POST', data); this.updateLocalData(operation, entity, result || data); this.triggerCallbacks(operation, entity, result || data); return result; } catch (error) { console.error('CRUD error:', error); this.triggerCallbacks(`${operation}_error`, entity, { data, error: error.message }); throw error; } } /** * 更新本地数据 */ /** * 更新本地数据 * @param {string} operation - 操作类型: 'add' | 'update' | 'delete' * @param {string} entity - 实体名称 * @param {Object} newData - 新数据对象(包含id字段) * @description 根据操作类型对本地数据进行增删改操作 */ updateLocalData(operation, entity, newData) { const key = `${entity}s`; const entities = this._rawData[key]; // 确保新数据的引用已解析 const resolvedData = resolveDataReference(newData, this._rawData); switch (operation) { case 'add': entities.push(resolvedData); break; case 'update': const index = entities.findIndex(item => item.id === resolvedData.id); if (index !== -1) { // 修复:使用对象展开操作符确保属性完整覆盖 entities[index] = { ...entities[index], ...resolvedData }; } else { entities.push(resolvedData); } break; case 'delete': const deleteIndex = entities.findIndex(item => item.id === resolvedData.id); if (deleteIndex !== -1) { entities.splice(deleteIndex, 1); } break; } // 更新最后修改时间 this._rawData._lastModified = new Date().toISOString(); this.lazyLoader.clearCache(); // 保存修改后的数据到本地存储 this.saveDataToStorage(); } /** * 同步数据 */ /** * 同步数据方法 * 该方法用于异步获取所有数据,并处理同步过程中的并发请求 * 如果同步正在进行中,会将请求标记为待处理(pendingSync) * 同步完成后会自动处理待处理的请求 * @async * @throws {Error} 当获取数据失败时会抛出错误并记录日志 */ async syncData() { if (this.isSyncing) { this.pendingSync = true; return; } this.isSyncing = true; try { // 1. 先加载本地数据 this.loadDataFromStorage(); // 2. 获取最后同步时间,用于增量更新 const since = this._rawData._lastSync || null; // 3. 获取增量数据 await this.fetchAll(since); // 4. 保存更新后的数据到本地存储 this.saveDataToStorage(); // 5. 触发数据更新回调 this.triggerCallbacks('refresh', 'all', this.data); } catch (error) { console.error('Sync failed:', error); this.triggerCallbacks('sync_error', 'all', { error }); // 失败时尝试使用本地数据 if (!this._rawData._lastSync) { throw new Error('初始化数据同步失败'); } } finally { this.isSyncing = false; if (this.pendingSync) { this.pendingSync = false; this.syncData(); } } } /** * 从本地存储加载数据 * 使用微信小程序的同步存储API获取之前保存的数据 */ loadDataFromStorage() { try { const storedData = wx.getStorageSync(this.storageKey); if (storedData) { // 修复:加载到_rawData而非data代理对象 this._rawData = storedData; } } catch (error) { console.error('加载本地存储数据失败:', error); // 提供默认空数据 this._rawData = { bancais: [], dingdans: [], mupis: [], chanpins: [], kucuns: [], dingdan_bancais: [], chanpin_zujians: [], zujians: [], caizhis: [], dingdan_chanpins: [], users: [], jinhuos: [], _lastModified: null, _lastSync: null }; } } /** * 保存数据到本地存储 * 使用微信小程序的同步存储API持久化当前数据 */ saveDataToStorage() { try { // 修复:保存_rawData而非localData wx.setStorageSync(this.storageKey, this._rawData); } catch (error) { console.error('保存数据到本地存储失败:', error); // 提示用户或执行降级策略 wx.showToast({ title: '数据保存失败,请稍后重试', icon: 'none' }); } } /** * 添加实体 */ /** * 添加实体数据 * @async * @param {string} entity - 实体类型 * @param {Object} data - 要添加的实体数据 * @returns {Promise} 返回CRUD操作结果 * @throws {Error} 如果数据已存在则抛出错误 */ async addEntity(entity, data) { if (this.checkDuplicate(entity, data)) { const errorMsg = `${this.entiyeText[entity]}`; this.triggerCallbacks('duplicate_error', entity, { data, error: errorMsg }); throw new Error(errorMsg); } return this.crudOperation('add', entity, data); } /** * 更新实体 */ async updateEntity(entity, data) { return this.crudOperation('update', entity, data); } /** * 删除实体 */ async deleteEntity(entity, id) { return this.crudOperation('delete', entity, { id }); } getBancaisForZujian(zujianId) { const dingdan_bancais = this.data.dingdan_bancais.filter(db => db.zujian?.id == zujianId); return dingdan_bancais.map(db => db.bancai).filter(Boolean); } /** * 获取板材的库存信息 */ getKucunForBancai(bancaiId) { return this.data.kucuns.find(k => k.bancai?.id == bancaiId); } } // 导出模块 module.exports = MiniProgramDataManager; [响应] http://192.168.1.4:8080/app/all {status: 200, data: {…}, headers: Proxy} index.js? [sm]:56 收到数据更新回调 index.js? [sm]:136 开始更新表格数据 MiniProgramDataManager.js? [sm]:359 Fetch error: TypeError: Converting circular structure to JSON --> starting at object with constructor 'Object' | property 'bancai' -> object with constructor 'Array' | index 0 -> object with constructor 'Object' --- property 'caizhi' closes the circle at JSON.stringify (<anonymous>) at li.updateTable (index.js? [sm]:138) at li.updatePageData (index.js? [sm]:109) at index.js? [sm]:57 at MiniProgramDataManager.js? [sm]:479 at Array.forEach (<anonymous>) at MiniProgramDataManager.triggerCallbacks (MiniProgramDataManager.js? [sm]:479) at MiniProgramDataManager._callee2$ (MiniProgramDataManager.js? [sm]:356) at s (regeneratorRuntime.js?forceSync=true:1) at Generator.<anonymous> (regeneratorRuntime.js?forceSync=true:1)(env: Windows,mp,1.06.2412050; lib: 3.8.10) _callee2$ @ MiniProgramDataManager.js? [sm]:359 s @ regeneratorRuntime.js?forceSync=true:1 (anonymous) @ regeneratorRuntime.js?forceSync=true:1 (anonymous) @ regeneratorRuntime.js?forceSync=true:1 asyncGeneratorStep @ asyncToGenerator.js?forceSync=true:1 c @ asyncToGenerator.js?forceSync=true:1 Promise.then (async) asyncGeneratorStep @ asyncToGenerator.js?forceSync=true:1 c @ asyncToGenerator.js?forceSync=true:1 (anonymous) @ asyncToGenerator.js?forceSync=true:1 (anonymous) @ asyncToGenerator.js?forceSync=true:1 fetchAll @ MiniProgramDataManager.js? [sm]:319 onLoad @ index.js? [sm]:64 index.js? [sm]:56 收到数据更新回调 index.js? [sm]:136 开始更新表格数据 index.js? [sm]:67 数据加载失败: TypeError: Converting circular structure to JSON --> starting at object with constructor 'Object' | property 'bancai' -> object with constructor 'Array' | index 0 -> object with constructor 'Object' --- property 'caizhi' closes the circle at JSON.stringify (<anonymous>) at li.updateTable (index.js? [sm]:138) at li.updatePageData (index.js? [sm]:109) at index.js? [sm]:57 at MiniProgramDataManager.js? [sm]:479 at Array.forEach (<anonymous>) at MiniProgramDataManager.triggerCallbacks (MiniProgramDataManager.js? [sm]:479) at MiniProgramDataManager._callee2$ (MiniProgramDataManager.js? [sm]:360) at s (regeneratorRuntime.js?forceSync=true:1) at Generator.<anonymous> (regeneratorRuntime.js?forceSync=true:1)(env: Windows,mp,1.06.2412050; lib: 3.8.10)
07-15
------------------------ DataManager.js ------------------------ //{ 实体类的关联和属性列表 // “entities”: { // “Dingdan”: { // “properties”: { // “id”: “Integer”, // “number”: “String”, // “xiadan”: “Date”, // “jiaohuo”: “Date”, // “dingdan_chanpin”: “List<Dingdan_chanpin> (OneToMany)”, // “dingdan_chanpins_zujian”: “List<Dingdan_chanpin_zujian> (OneToMany)” // }, // “relations”: [ // “关联订单产品(Dingdan_chanpin)”, // “关联订单组件(Dingdan_chanpin_zujian)” // ] // }, // “Dingdan_chanpin”: { // “properties”: { // “id”: “Integer”, // “shuliang”: “Integer” // }, // “relations”: [ // “多对一关联订单(Dingdan)”, // “多对一关联产品(Chanpin)” // ] // }, // “Dingdan_chanpin_zujian”: { // “properties”: { // “id”: “Integer”, // “shuliang”: “Integer” // }, // “relations”: [ // “多对一关联订单(Dingdan)”, // “多对一关联组件(Chanpin_zujian)”, // “多对一关联板材(Bancai)” // ] // }, // “Jinhuo”: { // “properties”: { // “id”: “Integer”, // “shuliang”: “Integer”, // “date”: “Date” // }, // “relations”: [ // “多对一关联订单(Dingdan)”, // “多对一关联产品(Chanpin)”, // “多对一关联组件(Zujian)”, // “多对一关联板材(Bancai)”, // “多对一关联用户(User)” // ] // }, // “Kucun”: { // “properties”: { // “id”: “Integer”, // “shuliang”: “Long” // }, // “relations”: [ // “一对一关联板材(Bancai)” // ] // }, // “Mupi”: { // “properties”: { // “id”: “Integer”, // “name: “String”, // “you”: “Boolean” // }, // “relations”: [ // “被板材关联(Bancai - mupi1/mupi2)” // ] // }, // “User”: { // “properties”: { // “id”: “Integer”, // “name: “String”, // “andy”: “String”, // “pass”: “String”, // “role”: “int” // } // }, // “Zujian”: { // “properties”: { // “id”: “Integer”, // “name: “String” // }, // “relations”: [ // “一对多关联产品组件(Chanpin_zujian)” // ] // }, // “Bancai”: { // “properties”: { // “id”: “Integer”, // “houdu”: “Double” // }, // “relations”: [ // “多对一关联材质(Caizhi)”, // “多对一关联木皮(Mupi - mupi1/mupi2)”, // “一对一关联库存(Kucun)” // ] // }, // “Caizhi”: { // “properties”: { // “id”: “Integer”, // “name: “String” // }, // “relations”: [ // “一对多关联板材(Bancai)” // ] // }, // “Chanpin”: { // “properties”: { // “id”: “Integer”, // “bianhao”: “String” // }, // “relations”: [ // “一对多关联订单产品(Dingdan_chanpin)”, // “一对多关联产品组件(Chanpin_zujian)” // ] // }, // “Chanpin_zujian”: { // “properties”: { // “id”: “Integer”, // “one_howmany”: “Double” // }, // “relations”: [ // “多对一关联产品(Chanpin)”, // “多对一关联组件(Zujian)”, // “多对一关联板材(Bancai)” // ] // } // }, // “relationsSummary”: [ // “订单(Dingdan) 1:N 订单产品(Dingdan_chanpin)”, // “订单(Dingdan) 1:N 订单组件(Dingdan_chanpin_zujian)”, // “产品(Chanpin) 1:N 产品组件(Chanpin_zujian)”, // “组件(Zujian) 1:N 产品组件(Chanpin_zujian)”, // “板材(Bancai) 1:1 库存(Kucun)”, // “材质(Caizhi) 1:N 板材(Bancai)” // ] //} /** 优化后的关联解析函数(解决空值问题) @param {Object} data - 后端原始数据 @returns {Object} 处理后的完整关联数据 */ function __resolveDataReferences(data) { // 创建ID映射表(带空值保护) const idMaps = {}; Object.keys(data).forEach(key => { if (Array.isArray(data[key])) { idMaps[key] = new Map(); data[key].forEach(item => item.id && idMaps[key].set(item.id, item)); } }); // 通用关联解析方法(带安全检测) const resolveRef = (sourceArray, sourceKey, targetKey, refProperty) => { if (!Array.isArray(sourceArray)) return; sourceArray.forEach(item => { const refObj = item[refProperty]; if (refObj && refObj.id && idMaps[targetKey]) { const target = idMaps[targetKey].get(refObj.id); if (target) { // 建立正向引用 item[refProperty] = target; // 建立反向引用(自动创建关联数组) const reverseProp = sourceKey.endsWith('s') ? sourceKey.slice(0, -1) + '_list' : sourceKey + '_list'; if (!target[reverseProp]) target[reverseProp] = []; if (!target[reverseProp].includes(item)) { target[reverseProp].push(item); } } } }); }; // 处理特定关联(使用新安全方法) // 订单 ↔ 订单产品 if (data.dingdans && data.dingdan_chanpins) { resolveRef(data.dingdan_chanpins, ‘dingdans’, ‘dingdans’, ‘dingdan’); } // 订单 ↔ 订单组件 if (data.dingdans && data.dingdan_chanpin_zujians) { resolveRef(data.dingdan_chanpin_zujians, ‘dingdans’, ‘dingdans’, ‘dingdan’); } // 产品 ↔ 产品组件 if (data.chanpins && data.chanpin_zujians) { resolveRef(data.chanpin_zujians, ‘chanpins’, ‘chanpins’, ‘chanpin’); } // 组件 ↔ 产品组件 if (data.zujians && data.chanpin_zujians) { resolveRef(data.chanpin_zujians, ‘zujians’, ‘zujians’, ‘zujian’); } // 材质 ↔ 板材 if (data.caizhis && data.bancais) { resolveRef(data.bancais, ‘caizhis’, ‘caizhis’, ‘caizhi’); } // 板材 ↔ 库存(一对一) if (data.bancais && data.kucuns) { resolveRef(data.bancais, ‘kucuns’, ‘kucuns’, ‘kucun’); resolveRef(data.kucuns, ‘bancais’, ‘bancais’, ‘bancai’); // 反向引用 } // 板材 ↔ 木皮(mupi1/mupi2) if (data.bancais && data.mupis) { resolveRef(data.bancais, ‘mupis’, ‘mupis’, ‘mupi1’); resolveRef(data.bancais, ‘mupis’, ‘mupis’, ‘mupi2’); } // 订单产品 ↔ 产品 if (data.dingdan_chanpins && data.chanpins) { resolveRef(data.dingdan_chanpins, ‘chanpins’, ‘chanpins’, ‘chanpin’); } // 订单组件 ↔ 产品组件 if (data.dingdan_chanpin_zujians && data.chanpin_zujians) { resolveRef(data.dingdan_chanpin_zujians, ‘chanpin_zujians’, ‘chanpin_zujians’, ‘chanpin_zujian’); } // 订单组件 ↔ 板材 if (data.dingdan_chanpin_zujians && data.bancais) { resolveRef(data.dingdan_chanpin_zujians, ‘bancais’, ‘bancais’, ‘bancai’); } // 进货 ↔ 相关实体 if (data.jinhuos) { [‘dingdan’, ‘chanpin’, ‘zujian’, ‘bancai’, ‘user’].forEach(entity => { const plural = entity + ‘s’; if (data[plural]) { resolveRef(data.jinhuos, plural, plural, entity); } }); } return data; } function resolveDataReferences(data) { // 获取 data 对象的所有顶层键 const keys = Object.keys(data); // 遍历每个顶层键(如 users, posts 等) for (const key of keys) { const entities = data[key]; // 遍历该顶层键下的每个实体(如每个 user 或 post) for (const entity of entities) { // 遍历实体的每个属性 for (const attribute in entity) { if (entity.hasOwnProperty(attribute)) { var trpe=attribute.replace(/\d/g, ''); // 确保属性属于当前实体 if (Array.isArray(entity[attribute])) { if(data[trpe]==null){ trpe+="s" } // 如果属性是一个数组,则将数组中的每个 ID 替换为对应的实际对象 entity[attribute] = entity[attribute].map(item => data[trpe ]?.find(updateItem => updateItem.id === item.id) || item ); } else if (typeof entity[attribute] === "object" && entity[attribute] !== null) { // 如果属性是一个对象,则将其替换为对应的实际对象 entity[attribute] = data[trpe + "s"]?.find(updateItem => updateItem.id === entity[attribute].id); } } } } } console.log(data) return data; } /** 数据管理器类,负责与后端API通信并管理数据 */ class DataManager { constructor(baseUrl) { this.baseUrl = baseUrl; this.data = { bancais: [], dingdans: [], mupis: [], chanpins: [], kucuns: [], dingdan_chanpin_zujians: [], chanpin_zujians: [], zujians: [], caizhis: [], dingdan_chanpins: [], users: [] }; this.isSyncing = false; this.lastSync = null; // 回调注册表 this.callbacks = { // 全局回调 all: [], // 按实体类型分类的回调 bancais: [], dingdan: [], mupi: [], chanpin: [], kucun: [], dingdan_chanpin_zujian: [], chanpin_zujian: [], zujian: [], caizhi: [], dingdan_chanpin: [], user: [], // …其他实体 }; this.syncQueue = Promise.resolve(); } /** 获取所有数据 @returns {Promise} 是否成功 */ async fetchAll() { console.log(this) try { const response = await fetch(${this.baseUrl}/app/all); if (!response.ok) throw new Error(‘Network response was not ok’); const result = await response.json(); if (result.status !== 200) throw new Error(result.text || ‘API error’); const resolvedData = resolveDataReferences(result.data); // 更新本地数据 Object.keys(this.data).forEach(key => { if (resolvedData[key]) { this.data[key] = resolvedData[key]; } }); this.lastSync = new Date(); // 关键改进:数据更新后触发刷新回调 this.triggerCallbacks(‘refresh’, ‘all’, this.data); return true; } catch (error) { console.error(‘Fetch error:’, error); // 触发错误回调 this.triggerCallbacks(‘fetch_error’, ‘all’, { error }); return false; } } /** 注册回调函数 @param {string} entity - 实体类型(如’bancai’)或’all’表示全局回调 @param {Function} callback - 回调函数,参数为(operation, data) */ registerCallback(entity, callback) { if (!this.callbacks[entity]) { this.callbacks[entity] = []; } this.callbacks[entity].push(callback); } /** 移除回调函数 @param {string} entity - 实体类型单数性质 @param {Function} callback - 要移除的回调函数 */ unregisterCallback(entity, callback) { if (!this.callbacks[entity]) return; const index = this.callbacks[entity].indexOf(callback); if (index !== -1) { this.callbacks[entity].splice(index, 1); } } /** 触发回调 @param {string} operation - 操作类型(‘add’, ‘update’, ‘delete’) @param {string} entity - 实体类型单数性质 @param {Object} data - 相关数据 */ triggerCallbacks(operation, entity, data) { // 触发全局回调 this.callbacks.all.forEach(cb => cb(operation, entity, data)); // 触发特定实体回调 if (this.callbacks[entity]) { this.callbacks[entity].forEach(cb => cb(operation, data)); } } /** 执行CRUD操作并触发回调 */ async crudOperation(operation, entity, data) { try { const response = await fetch(${this.baseUrl}/app/${operation}/${entity}, { method: ‘POST’, headers: {‘Content-Type’: ‘application/json’}, body: JSON.stringify(data) }); if (!response.ok) throw new Error(‘Network response was not ok’); const result = await response.json(); if (result.status !== 200) throw new Error(result.text || ‘API error’); // 自动同步数据 this.syncData(); // 触发操作成功的回调 this.triggerCallbacks(operation, entity, data); return result; } catch (error) { console.error(‘CRUD error:’, error); // 触发操作失败的回调 this.triggerCallbacks(${operation}_error, entity, { data, error: error.message }); throw error; } } /** 执行CRUD操作 @param {string} operation - ‘add’, ‘delete’, ‘update’ @param {string} entity - 实体名称单数性质(小写) @param {Object} data - 要发送的数据 后端要求数据格式为{属性: “值”, 关联对象: {id:0}, 关联对象集: [{id:0}]} @returns {Promise} 响应结果 */ async crudOperation(operation, entity, data) { try { const response = await fetch(${this.baseUrl}/app/${operation}/${entity}, { method: ‘POST’, headers: {‘Content-Type’: ‘application/json’}, body: JSON.stringify(data) }); if (!response.ok) throw new Error('Network response was not ok'); const result = await response.json(); if (result.status !== 200) throw new Error(result.text || 'API error'); // 自动同步数据 this.syncQueue = this.syncQueue.then(async () => { await this.syncData(); // 同步完成后触发操作回调 this.triggerCallbacks(operation, entity, data); }); return result; } catch (error) { console.error(‘CRUD error:’, error); // 触发操作失败的回调 this.triggerCallbacks(${operation}_error, entity, { data, error: error.message }); throw error; } } /** 自动同步数据(防止频繁请求) */ async syncData() { if (this.isSyncing) { this.pendingSync = true; return; } this.isSyncing = true; try { await this.fetchAll(); } catch (error) { console.error(‘Sync failed:’, error); } finally { this.isSyncing = false; // 处理等待中的同步请求 if (this.pendingSync) { this.pendingSync = false; setTimeout(() => this.syncData(), 1000); } } } /** 添加实体 @param {string} entity - 实体名称单数性质 @param {Object} data - 实体数据 */ async addEntity(entity, data) { return this.crudOperation(‘add’, entity, data); } /** 更新实体 @param {string} entity - 实体名称单数性质 @param {Object} data - 实体数据(必须包含id) */ async updateEntity(entity, data) { return this.crudOperation(‘update’, entity, data); } /** 删除实体 @param {string} entity - 实体名称单数性质 @param {number} id - 实体ID */ async deleteEntity(entity, id) { return this.crudOperation(‘delete’, entity, {id}); } /** 新增方法:手动触发数据刷新 */ async refreshData() { return this.syncQueue = this.syncQueue.then(() => this.syncData()); } } export { DataManager }; // 创建单例实例 //const dataManager = new DataManager(‘http://127.0.0.1:8080/KuCun2’); //// 初始化时获取所有数据 //dataManager.fetchAll().then(() => { // console.log(‘Initial data loaded’); //}); // 导出数据对象,外部可以直接访问 data.bancais, data.dingdans 等 //export const data = dataManager.data; //// 导出操作方法 //export const addEntity = dataManager.addEntity.bind(dataManager); //export const updateEntity = dataManager.updateEntity.bind(dataManager); //export const deleteEntity = dataManager.deleteEntity.bind(dataManager); //export const fetchAll = dataManager.fetchAll.bind(dataManager); ------------------------ dingdan.html ------------------------ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>订单-产品-组件-板材查询系统</title> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <style> body { font-family: Arial, sans-serif; max-width: 1000px; margin: 0 auto; padding: 20px; background-color: #f5f5f5; } .container { background: white; border-radius: 8px; padding: 20px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); } h1 { color: #2c3e50; text-align: center; margin-bottom: 30px; } .query-section { background: #f8f9fa; border-radius: 6px; padding: 15px; margin-bottom: 25px; border-left: 4px solid #3498db; } .query-section h2 { color: #2c3e50; margin-top: 0; } label { display: block; margin-bottom: 8px; font-weight: bold; color: #34495e; } input, select, button { padding: 10px; border: 1px solid #ddd; border-radius: 4px; font-size: 16px; margin-bottom: 15px; width: 100%; box-sizing: border-box; } button { background: #3498db; color: white; border: none; cursor: pointer; transition: background 0.3s; font-weight: bold; } button:hover { background: #2980b9; } .query-row { display: flex; gap: 15px; align-items: flex-end; } .query-row .form-group { flex: 1; } .results { background: white; border: 1px solid #eee; border-radius: 6px; padding: 15px; margin-top: 20px; max-height: 300px; overflow-y: auto; } .results h3 { margin-top: 0; color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 8px; } table { width: 100%; border-collapse: collapse; margin-top: 10px; } th, td { padding: 10px; text-align: left; border-bottom: 1px solid #eee; } th { background: #f8f9fa; font-weight: bold; color: #2c3e50; } tr:hover td { background-color: #f1f8ff; } .loading { display: none; text-align: center; padding: 10px; color: #3498db; } .loading::after { content: "加载中..."; } </style> </head> <body> <div class="container"> <h1>订单-产品-组件-板材查询系统</h1> <!-- 查询面板 --> <div class="query-section"> <h2>查询条件</h2> <div class="query-row"> <div class="form-group"> <label for="orderId">订单ID:</label> <input type="text" id="orderId" placeholder="输入订单ID"> </div> <div class="form-group"> <button id="searchButton">查询订单</button> </div> </div> <div class="loading" id="orderLoading"></div> <div class="results" id="orderResults"></div> </div> <div class="query-section"> <h2>产品查询</h2> <div class="query-row"> <div class="form-group"> <label for="productId">产品ID (从上方选择):</label> <select id="productId"></select> </div> <div class="form-group"> <button id="searchProductButton">查询产品</button> </div> </div> <div class="loading" id="productLoading"></div> <div class="results" id="productResults"></div> </div> <div class="query-section"> <h2>组件查询</h2> <div class="query-row"> <div class="form-group"> <label for="componentId">组件ID (从上方选择):</label> <select id="componentId"></select> </div> <div class="form-group"> <button id="searchComponentButton">查询组件</button> </div> </div> <div class="loading" id="componentLoading"></div> <div class="results" id="componentResults"></div> </div> <div class="query-section"> <h2>板材查询</h2> <div class="loading" id="boardLoading"></div> <div class="results" id="boardResults"></div> </div> </div> <script> // 全局数据存储 let globalData = { orders: [], products: [], components: [], boards: [] }; // 模拟后端数据存储 const mockData = { orders: [ {id: 1, number: "ORD-2023-001"}, {id: 2, number: "ORD-2023-002"} ], products: [ {id: 101, bianhao: "P-001", orderId: 1}, {id: 102, bianhao: "P-002", orderId: 1}, {id: 103, bianhao: "P-003", orderId: 2} ], components: [ {id: 201, name: "门板", productId: 101}, {id: 202, name: "抽屉面板", productId: 101}, {id: 203, name: "框架", productId: 102} ], boards: [ { id: 301, caizhi: {id: 401, name: "橡木"}, mupi1: {id: 501, name: "直纹橡木"}, houdu: 18.0, kucun: {id: 601, shuliang: 150} }, { id: 302, caizhi: {id: 402, name: "胡桃木"}, mupi1: {id: 502, name: "直纹胡桃木"}, houdu: 25.0, kucun: {id: 602, shuliang: 80} } ] }; // 通信函数实现 async function https(url, data, callback) { const defaultConfig = { contentType: 'application/json', dataType: 'json', timeout: 10000 }; // 显示对应区域的加载动画 const domain = url.split("/")[1]; const loadingElement = $("#" + domain + "Loading"); loadingElement.show(); try { // 在实际项目中是AJAX请求 // 这里用模拟数据代替 let response; // 模拟不同端点的响应 switch(url) { case "/order/search": // 模拟搜索延迟 await new Promise(resolve => setTimeout(resolve, 800)); response = new Information(200, "success", mockData.orders.filter( o => o.id == data.id )); break; case "/product/searchByOrder": await new Promise(resolve => setTimeout(resolve, 600)); response = new Information(200, "success", mockData.products.filter( p => p.orderId == data.orderId )); break; case "/component/searchByProduct": await new Promise(resolve => setTimeout(resolve, 500)); response = new Information(200, "success", mockData.components.filter( c => c.productId == data.productId )); break; case "/board/searchByComponent": await new Promise(resolve => setTimeout(resolve, 400)); // 在实际应用中,组件到板材可能有复杂的映射关系 response = new Information(200, "success", mockData.boards); break; default: response = new Information(404, "Endpoint not found", null); } console.log(response) console.log(mockData) // 在实际项目中: // const response = await $.ajax({ // ...defaultConfig, // url: BASE_URL + url, // method: 'POST', // data: JSON.stringify(data) // }); if (response.Status === 200) { callback?.(response.data); } else { handleBusinessError(response); } return response.data; } catch (error) { handleNetworkError(error, url); return null; } finally { loadingElement.hide(); } } function handleBusinessError(response) { console.error('业务错误:', response.text); alert(`业务错误: ${response.text}`); } function handleNetworkError(error, url) { console.error(`网络请求错误: ${url}`, error); alert(`网络请求错误: ${url}, 请检查控制台`); } // 通信信息类 class Information { constructor(status, text, data) { this.Status = status; this.text = text; this.data = data; } static NewSuccess(data) { return new Information(200, "success", data); } static Newfail(status, text, data) { return new Information(status, text, data); } } // 订单查询 $("#searchButton").click(() => { const orderId = $("#orderId").val(); if (!orderId) { alert("请输入订单ID"); return; } https("/order/search", { id: parseInt(orderId) }, function(orders) { globalData.orders = orders; renderOrderResults(); $("#productId").empty(); // 清除产品选择框 }); }); // 产品查询 $("#searchProductButton").click(() => { const productId = $("#productId").val(); if (!productId) { alert("请先查询订单并选择产品"); return; } // 查找当前订单ID const selectedOrderId = globalData.orders[0].id; https("/product/searchByOrder", { orderId: selectedOrderId }, function(products) { globalData.products = products; renderProductResults(); $("#componentId").empty(); // 清除组件选择框 }); }); // 组件查询 $("#searchComponentButton").click(() => { const componentId = $("#componentId").val(); if (!componentId) { alert("请先查询产品并选择组件"); return; } // 查找当前产品ID const selectedProductId = $("#productId").val(); https("/component/searchByProduct", { productId: parseInt(selectedProductId) }, function(components) { globalData.components = components; renderComponentResults(); // 自动发起板材查询 $("#boardLoading").show(); https("/board/searchByComponent", { componentId: parseInt(componentId) }, function(boards) { globalData.boards = boards; renderBoardResults(); }); }); }); // 渲染函数 function renderOrderResults() { const container = $("#orderResults"); container.empty(); if (!globalData.orders || globalData.orders.length === 0) { container.html("<p>未找到相关订单</p>"); return; } let html = `<h3>订单查询结果 (${globalData.orders.length})</h3>`; html += `<table> <tr> <th>ID</th> <th>订单号</th> </tr>`; globalData.orders.forEach(order => { html += `<tr> <td>${order.id}</td> <td>${order.number}</td> </tr>`; }); html += `</table>`; container.html(html); // 填充产品选择框 $("#productId").empty(); $("#productId").append('<option value="">-- 选择产品 --</option>'); globalData.products.forEach(product => { $("#productId").append(`<option value="${product.id}">${product.bianhao}</option>`); console.log(product) }); } function renderProductResults() { const container = $("#productResults"); container.empty(); if (!globalData.products || globalData.products.length === 0) { container.html("<p>该订单下无产品</p>"); return; } let html = `<h3>产品查询结果 (${globalData.products.length})</h3>`; html += `<table> <tr> <th>ID</th> <th>产品编号</th> <th>所属订单</th> </tr>`; globalData.products.forEach(product => { html += `<tr> <td>${product.id}</td> <td>${product.bianhao}</td> <td>${product.orderId}</td> </tr>`; }); html += `</table>`; container.html(html); // 填充组件选择框 $("#componentId").empty(); $("#componentId").append('<option value="">-- 选择组件 --</option>'); globalData.components.forEach(component => { $("#componentId").append(`<option value="${component.id}">${component.name}</option>`); }); } function renderComponentResults() { const container = $("#componentResults"); container.empty(); if (!globalData.components || globalData.components.length === 0) { container.html("<p>该产品下无组件</p>"); return; } let html = `<h3>组件查询结果 (${globalData.components.length})</h3>`; html += `<table> <tr> <th>ID</th> <th>组件名称</th> <th>所属产品</th> </tr>`; globalData.components.forEach(component => { html += `<tr> <td>${component.id}</td> <td>${component.name}</td> <td>${component.productId}</td> </tr>`; }); container.html(html); } function renderBoardResults() { const container = $("#boardResults"); container.empty(); if (!globalData.boards || globalData.boards.length === 0) { container.html("<p>该组件无相关板材信息</p>"); return; } let html = `<h3>板材查询结果 (${globalData.boards.length})</h3>`; html += `<table> <tr> <th>板材ID</th> <th>材质</th> <th>木皮1</th> <th>厚度(mm)</th> <th>库存量</th> </tr>`; globalData.boards.forEach(board => { html += `<tr> <td>${board.id}</td> <td>${board.caizhi.name}</td> <td>${board.mupi1.name}</td> <td>${board.houdu}</td> <td>${board.kucun ? board.kucun.shuliang : 0}</td> </tr>`; }); container.html(html); } // 为选择框添加变更事件 $("#productId").change(function() { $("#searchProductButton").click(); }); $("#componentId").change(function() { $("#searchComponentButton").click(); }); </script> </body> </html> ------------------------ index.html ------------------------ <!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <title>峤丞板材库存管理</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" href="fonts/font-awesome-4.7.0/css/font-awesome.min.css"> <link rel="stylesheet" type="text/css" href="main/bootstrap-3.3.7-dist/css/bootstrap.css.map"> <link rel="stylesheet" type="text/css" href="css/util.css"> <link rel="stylesheet" type="text/css" href="css/main.css"> <link rel="stylesheet" type="text/css" href="css/index2.css"> <script type="text/javascript" src="js/jquery-3.2.1.min.js"></script> <script type="text/javascript" src="js/jsyilai.js"></script> <script type="module"> // 共享的DataManager类 import { DataManager } from './data/DataManager.js?'; document.addEventListener('DOMContentLoaded', async () => { try { // 创建实例并挂载到window window.dataManager = new DataManager('/KuCun2'); // 初始化数据 await window.dataManager.fetchAll(); console.log('Data Manager initialized successfully'); // 设置iframe通信 const iframe = document.getElementById('iframeid'); iframe.onload = () => { // 通知iframe数据已准备好 iframe.contentWindow.postMessage('DataManagerReady', '*'); }; // 如果iframe已经加载,立即发送消息 if (iframe.contentDocument.readyState === 'complete') { iframe.contentWindow.postMessage('DataManagerReady', '*'); } } catch (error) { console.error('Failed to initialize DataManager:', error); } }); </script> <style type="text/css"> *{ margin:0; padding:0; } .frame-header { height: 60px; background-color: #23262E; justify-content: space-between; } .frame-header-li{ font-family: Arial, Helvetica, sans-serif; font-size:40px; } .frame-ul{ } .frame-ul li{ border-style: solid; border-width:1px 0px 1px 0px; margin-top: 1px; height: 35px; text-align: center } #username{ position: absolute; right: 0; /* 靠右 */ } .frame-body { position: fixed; top: 60px; right: 0; bottom: 0; left: 0; display: flex; flex-direction: row; } .frame-side { scrollbar-width: none; /* firefox隐藏滚动条 */ -ms-overflow-style: none; /* IE 10+隐藏滚动条 */ overflow-x: hidden; overflow-y: auto; width: 200px; background-color:#9e5; } .frame-side::-webkit-scrollbar { display: none; /* Chrome Safari 隐藏滚动条*/ } .frame-main { flex-grow: 1; background-color:#fff; } .jiaoluo{ margin: auto; margin-right: 0px; } .menu { display: none; position: absolute; background-color: #f9f9f9; border: 1px solid #ccc; padding: 10px; list-style-type: none; margin: 0; z-index: 10; } </style> </head> <body> <div class="frame-header"> <a class='frame-header-li' style="color:#fff">峤丞木材仓库管理</a> <a id="username" class='frame-header-li' style="color:#520">峤丞木材仓库管理</a> <!-- 菜单 --> <ul class="menu"> <li id="profile">个人资料</li> <li id="change-password">修改密码</li> <li id="logout-btn">注销</li> </ul> </div> <div class="frame-body"> <div class="frame-side"> <ul id="main_u" class='frame-ul' style="text-align:center;"> <li ><a href="main/test.html" target="main">首页</a></li> <li><a href="main/bancai.html" target="main">板材查询</a></li> <li><a href="main/tianjia.html" target="main">订单板材录入</a></li> <li><a href="main/Guanli.html" target="main">人员管理</a></li> </ul> </div> <div class="frame-main"> <!-- 内容主体区域 --> <iframe id="iframeid" name="main" src="main/bancai.html" width="100%" height="100%" frameborder="0"> </iframe> </div> </div> </body> </html> ------------------------ dingdan.js ------------------------ // 监听来自父窗口的消息 window.addEventListener('message', function(event) { // 确保消息来自父窗口且是 DataManagerReady 事件 if (event.source === window.parent && event.data === 'DataManagerReady') { initializeDataManager(); } }); // 初始化数据管理器 function initializeDataManager() { // 从父窗口获取 DataManager 实例 const dataManager = window.parent.dataManager; if (dataManager) { // 注册数据刷新回调 dataManager.registerCallback('all', function(operation, entity, data) { console.log("dhdhdh") // 当数据更新时刷新页面 updatePageData(dataManager); }); // 初始页面数据更新 updatePageData(dataManager); // 设置搜索功能 setupSearch(dataManager); } else { console.error('DataManager not available'); } } // 更新页面数据 function updatePageData(dataManager) { // 更新统计卡片 updateStats(dataManager); // 更新结果表格 updateTable(dataManager); // 更新最后更新时间 document.getElementById('lastUpdate').textContent = new Date().toLocaleTimeString(); } // 更新统计卡片数据 function updateStats(dataManager) { const data = dataManager.data; // 订单总数 document.getElementById('orderCount').textContent = data.dingdans?.length || 0; // 产品种类 document.getElementById('productCount').textContent = data.chanpins?.length || 0; // 板材库存种类 document.getElementById('materialCount').textContent = data.bancais?.length || 0; // 库存总量(所有库存数量之和) const totalStock = data.kucuns?.reduce((sum, kucun) => sum + kucun.shuliang, 0) || 0; document.getElementById('totalStock').textContent = totalStock; } // 更新结果表格 function updateTable(dataManager) { const tableBody = document.getElementById(‘resultBody’); tableBody.innerHTML = ‘’; // 清空现有内容 const data = dataManager.data; const results = []; let resultCount = 0; // 处理订单产品数据 if (data.dingdan_chanpins) { data.dingdan_chanpins.forEach(dc => { if (!dc.dingdan || !dc.chanpin) return; // 处理产品组件 if (dc.chanpin.chanpin_zujians) { dc.chanpin.chanpin_zujians.forEach(cz => { if (!cz.zujian || !cz.bancai) return; results.push({ orderNumber: dc.dingdan.number, productInfo: dc.chanpin.bianhao, productQuantity: dc.shuliang, component: cz.zujian.name, material: `${cz.bancai.id} (${cz.bancai.caizhi?.name || '未知材质'})`, materialPerComponent: cz.one_howmany, materialOrderQuantity: dc.shuliang * cz.one_howmany, operation: '<button class="btn btn-sm btn-outline-primary">详情</button>' }); resultCount++; }); } }); } // 处理直接订单组件数据 if (data.dingdan_chanpin_zujians) { data.dingdan_chanpin_zujians.forEach(dcz => { if (!dcz.dingdan || !dcz.chanpin_zujian || !dcz.chanpin_zujian.zujian || !dcz.bancai) return; results.push({ orderNumber: dcz.dingdan.number, productInfo: dcz.chanpin_zujian.chanpin?.bianhao || '独立组件', productQuantity: dcz.shuliang, component: dcz.chanpin_zujian.zujian.name, material: `${dcz.bancai.id} (${dcz.bancai.caizhi?.name || '未知材质'})`, materialPerComponent: dcz.chanpin_zujian.one_howmany, materialOrderQuantity: dcz.shuliang * dcz.chanpin_zujian.one_howmany, operation: '<button class="btn btn-sm btn-outline-primary">详情</button>' }); resultCount++; }); } // 填充表格 if (resultCount > 0) { document.getElementById('noResults').style.display = 'none'; results.forEach(row => { const tr = document.createElement('tr'); tr.innerHTML = ` <td>${row.orderNumber}</td> <td>${row.productInfo}</td> <td>${row.productQuantity}</td> <td>${row.component}</td> <td>${row.material}</td> <td>${row.materialPerComponent}</td> <td>${row.materialOrderQuantity}</td> <td>${row.operation}</td> `; tableBody.appendChild(tr); }); } else { document.getElementById('noResults').style.display = 'flex'; } // 更新结果计数 document.getElementById('resultCount').textContent = resultCount; } // 设置搜索功能 function setupSearch(dataManager) { // 订单搜索 ParseError: KaTeX parse error: Expected 'EOF', got '#' at position 3: ('#̲orderSearch').o…(this).val().toLowerCase(), 0); }); // 产品搜索 $('#productSearch').on('input', function() { filterTable($(this).val().toLowerCase(), 1); }); // 板材搜索 $('#materialSearch').on('input', function() { filterTable($(this).val().toLowerCase(), 4); }); // 木皮搜索 $('#woodSearch').on('input', function() { filterTable($(this).val().toLowerCase(), 4); // 假设材质信息在第4列 }); // 厚度搜索 $('#thicknessBtn').click(function() { const thickness = parseFloat($('#minThickness').val()); if (!isNaN(thickness)) { filterByThickness(thickness); } }); } // 表格过滤函数 function filterTable(searchTerm, columnIndex) { const rows = $(‘#resultBody tr’); let visibleCount = 0; rows.each(function() { const cellText = $(this).find(`td:eq(${columnIndex})`).text().toLowerCase(); const isMatch = cellText.includes(searchTerm); $(this).toggle(isMatch); // 高亮匹配文本 if (isMatch && searchTerm) { $(this).addClass('highlight'); } else { $(this).removeClass('highlight'); } if (isMatch) visibleCount++; }); // 更新结果计数 document.getElementById('resultCount').textContent = visibleCount; document.getElementById('noResults').style.display = visibleCount > 0 ? 'none' : 'flex'; } // 按厚度过滤 function filterByThickness(thickness) { const rows = $(‘#resultBody tr’); let visibleCount = 0; rows.each(function() { const materialText = $(this).find('td:eq(4)').text(); // 从文本中提取厚度值(假设格式为"ID (材质) 厚度mm") const match = materialText.match(/(\d+(\.\d+)?)\s*mm/); if (match) { const materialThickness = parseFloat(match[1]); const isMatch = !isNaN(materialThickness) && materialThickness >= thickness; $(this).toggle(isMatch); if (isMatch) visibleCount++; } else { $(this).hide(); } }); // 更新结果计数 document.getElementById('resultCount').textContent = visibleCount; document.getElementById('noResults').style.display = visibleCount > 0 ? 'none' : 'flex'; } // 如果直接加载test.html,尝试请求DataManager if (window.parent) { window.parent.postMessage(‘RequestDataManager’, ‘*’); } 修改dingdan.js,使之更契合数据原,板材显示要全面材质和木皮都要显示
06-20
attach: function (jid, sid, rid, callback) { this.jid = jid; this.sid = sid; this.rid = rid; this.connect_callback = callback; this.domain = Strophe.getDomainFromJid(this.jid); this.authenticated = true; this.connected = true; }, /** Function: rawInput * User overrideable function that receives raw data coming into the * connection. * * The default function does nothing. User code can override this with * > Strophe.Connection.rawInput = function (data) { * > (user code) * > }; * * Parameters: * (String) data - The data received by the connection. */ rawInput: function (data) { return; }, /** Function: rawOutput * User overrideable function that receives raw data sent to the * connection. * * The default function does nothing. User code can override this with * > Strophe.Connection.rawOutput = function (data) { * > (user code) * > }; * * Parameters: * (String) data - The data sent by the connection. */ rawOutput: function (data) { return; }, /** Function: send * Send a stanza. * * This function is called to push data onto the send queue to * go out over the wire. Whenever a request is sent to the BOSH * server, all pending data is sent and the queue is flushed. * * Parameters: * (XMLElement) elem - The stanza to send. */ send: function (elem) { if (elem !== null && typeof(elem["sort"]) == "function") { for (var i = 0; i < elem.length; i++) { this._data.push(elem[i]); } } else { this._data.push(elem); } this._throttledRequestHandler(); clearTimeout(this._idleTimeout); this._idleTimeout = setTimeout(this._onIdle.bind(this), 100); }, /** PrivateFunction: _sendRestart * Send an xmpp:restart stanza. */ _sendRestart: function () { this._data.push("restart"); this._throttledRequestHandler(); clearTimeout(this._idleTimeout); this._idleTimeout = setTimeout(this._onIdle.bind(this), 100); }, /** Function: addTimedHandler * Add a timed handler to the connection. * * This function adds a timed handler. The provided handler will * be called every period milliseconds until it returns false, * the connection is terminated, or the handler is removed. Handlers * that wish to continue being invoked should return true. * * Because of method binding it is necessary to save the result of * this function if you wish to remove a handler with * deleteTimedHandler(). * * Note that user handlers are not active until authentication is * successful. * * Parameters: * (Integer) period - The period of the handler. * (Function) handler - The callback function. * * Returns: * A reference to the handler that can be used to remove it. */ addTimedHandler: function (period, handler) { var thand = new Strophe.TimedHandler(period, handler); this.addTimeds.push(thand); return thand; }, /** Function: deleteTimedHandler * Delete a timed handler for a connection. * * This function removes a timed handler from the connection. The * handRef parameter is *not* the function passed to addTimedHandler(), * but is the reference returned from addTimedHandler(). * * Parameters: * (Strophe.TimedHandler) handRef - The handler reference. */ deleteTimedHandler: function (handRef) { // this must be done in the Idle loop so that we don't change // the handlers during iteration this.removeTimeds.push(handRef); }, /** Function: addHandler * Add a stanza handler for the connection. * * This function adds a stanza handler to the connection. The * handler callback will be called for any stanza that matches * the parameters. Note that if multiple parameters are supplied, * they must all match for the handler to be invoked. * * The handler will receive the stanza that triggered it as its argument. * The handler should return true if it is to be invoked again; * returning false will remove the handler after it returns. * * As a convenience, the ns parameters applies to the top level element * and also any of its immediate children. This is primarily to make * matching /iq/query elements easy. * * The return value should be saved if you wish to remove the handler * with deleteHandler(). * * Parameters: * (Function) handler - The user callback. * (String) ns - The namespace to match. * (String) name - The stanza name to match. * (String) type - The stanza type attribute to match. * (String) id - The stanza id attribute to match. * (String) from - The stanza from attribute to match. * * Returns: * A reference to the handler that can be used to remove it. */ addHandler: function (handler, ns, name, type, id, from) { var hand = new Strophe.Handler(handler, ns, name, type, id, from); this.addHandlers.push(hand); return hand; }, /** Function: deleteHandler * Delete a stanza handler for a connection. * * This function removes a stanza handler from the connection. The * handRef parameter is *not* the function passed to addHandler(), * but is the reference returned from addHandler(). * * Parameters: * (Strophe.Handler) handRef - The handler reference. */ deleteHandler: function (handRef) { // this must be done in the Idle loop so that we don't change // the handlers during iteration this.removeHandlers.push(handRef); }, /** Function: disconnect * Start the graceful disconnection process. * * This function starts the disconnection process. This process starts * by sending unavailable presence and sending BOSH body of type * terminate. A timeout handler makes sure that disconnection happens * even if the BOSH server does not respond. * * The user supplied connection callback will be notified of the * progress as this process happens. */ disconnect: function () { Strophe.info("disconnect was called"); if (this.connected) { // setup timeout handler this._disconnectTimeout = this._addSysTimedHandler( 3000, this._onDisconnectTimeout.bind(this)); this._sendTerminate(); } }, /** PrivateFunction: _buildBody * _Private_ helper function to generate the <body/> wrapper for BOSH. * * Returns: * A Strophe.Builder with a <body/> element. */ _buildBody: function () { var bodyWrap = $build('body', { rid: this.rid++, xmlns: Strophe.NS.HTTPBIND }); if (this.sid !== null) { bodyWrap.attrs({sid: this.sid}); } return bodyWrap; }, /** PrivateFunction: _removeRequest * _Private_ function to remove a request from the queue. * * Parameters: * (Strophe.Request) req - The request to remove. */ _removeRequest: function (req) { Strophe.debug("removing request"); var i; for (i = this._requests.length - 1; i >= 0; i--) { if (req == this._requests[i]) { this._requests.splice(i, 1); } } // set the onreadystatechange handler to a null function so // that we don't get any misfires req.xhr.onreadystatechange = function () {}; this._throttledRequestHandler(); }, /** PrivateFunction: _restartRequest * _Private_ function to restart a request that is presumed dead. * * Parameters: * (Integer) i - The index of the request in the queue. */ _restartRequest: function (i) { var req = this._requests[i]; if (req.dead === null) { req.dead = new Date(); } this._processRequest(i); }, /** PrivateFunction: _processRequest * _Private_ function to process a request in the queue. * * This function takes requests off the queue and sends them and * restarts dead requests. * * Parameters: * (Integer) i - The index of the request in the queue. */ _processRequest: function (i) { var req = this._requests[i]; var reqStatus = -1; try { if (req.xhr.readyState == 4) { reqStatus = req.xhr.status; } } catch (e) { Strophe.error("caught an error in _requests[" + i + "], reqStatus: " + reqStatus); } if (typeof(reqStatus) == "undefined") { reqStatus = -1; } var now = new Date(); var time_elapsed = req.age(); var primaryTimeout = (!isNaN(time_elapsed) && time_elapsed > Strophe.TIMEOUT); var secondaryTimeout = (req.dead !== null && req.timeDead() > Strophe.SECONDARY_TIMEOUT); var requestCompletedWithServerError = (req.xhr.readyState == 4 && (reqStatus < 1 || reqStatus >= 500)); var oldreq; if (primaryTimeout || secondaryTimeout || requestCompletedWithServerError) { if (secondaryTimeout) { Strophe.error("Request " + this._requests[i].id + " timed out (secondary), restarting"); } req.abort = true; req.xhr.abort(); oldreq = req; this._requests[i] = new Strophe.Request(req.data, req.origFunc, req.rid, req.sends); req = this._requests[i]; } if (req.xhr.readyState === 0) { Strophe.debug("request id " + req.id + "." + req.sends + " posting"); req.date = new Date(); try { req.xhr.open("POST", this.service, true); } catch (e) { Strophe.error("XHR open failed."); if (!this.connected) this.connect_callback(Strophe.Status.CONNFAIL, "bad-service"); this.disconnect(); return; } // Fires the XHR request -- may be invoked immediately // or on a gradually expanding retry window for reconnects var sendFunc = function () { req.xhr.send(req.data); }; // Implement progressive backoff for reconnects -- // First retry (send == 1) should also be instantaneous if (req.sends > 1) { // Using a cube of the retry number creats a nicely // expanding retry window var backoff = Math.pow(req.sends, 3) * 1000; setTimeout(sendFunc, backoff); } else { sendFunc(); } req.sends++; this.rawOutput(req.data); } else { Strophe.debug("_throttledRequestHandler: " + (i === 0 ? "first" : "second") + " request has readyState of " + req.xhr.readyState); } }, /** PrivateFunction: _throttledRequestHandler * _Private_ function to throttle requests to the connection window. * * This function makes sure we don't send requests so fast that the * request ids overflow the connection window in the case that one * request died. */ _throttledRequestHandler: function () { if (!this._requests) { Strophe.debug("_throttledRequestHandler called with " + "undefined requests"); } else { Strophe.debug("_throttledRequestHandler called with " + this._requests.length + " requests"); } if (!this._requests || this._requests.length === 0) { return; } if (this._requests.length > 0) { this._processRequest(0); } if (this._requests.length > 1 && Math.abs(this._requests[0].rid - this._requests[1].rid) < this.window - 1) { this._processRequest(1); } }, /** PrivateFunction: _onRequestStateChange * _Private_ handler for Strophe.Request state changes. * * This function is called when the XMLHttpRequest readyState changes. * It contains a lot of error handling logic for the many ways that * requests can fail, and calls the request callback when requests * succeed. * * Parameters: * (Function) func - The handler for the request. * (Strophe.Request) req - The request that is changing readyState. */ _onRequestStateChange: function (func, req) { Strophe.debug("request id " + req.id + "." + req.sends + " state changed to " + req.xhr.readyState); if (req.abort) { req.abort = false; return; } // request complete var reqStatus; if (req.xhr.readyState == 4) { reqStatus = 0; try { reqStatus = req.xhr.status; } catch (e) { // ignore errors from undefined status attribute. works // around a browser bug } if (typeof(reqStatus) == "undefined") { reqStatus = 0; } if (this.disconnecting) { if (reqStatus >= 400) { this._hitError(reqStatus); return; } } var reqIs0 = (this._requests[0] == req); var reqIs1 = (this._requests[1] == req); if ((reqStatus > 0 && reqStatus < 500) || req.sends > 5) { // remove from internal queue this._removeRequest(req); Strophe.debug("request id " + req.id + " should now be removed"); } // request succeeded if (reqStatus == 200) { // if request 1 finished, or request 0 finished and request // 1 is over Strophe.SECONDARY_TIMEOUT seconds old, we need to // restart the other - both will be in the first spot, as the // completed request has been removed from the queue already if (reqIs1 || (reqIs0 && this._requests.length > 0 && this._requests[0].age() > Strophe.SECONDARY_TIMEOUT)) { this._restartRequest(0); } // call handler Strophe.debug("request id " + req.id + "." + req.sends + " got 200"); func(req); this.errors = 0; } else { Strophe.error("request id " + req.id + "." + req.sends + " error " + reqStatus + " happened"); if (reqStatus === 0 || (reqStatus >= 400 && reqStatus < 600) || reqStatus >= 12000) { this._hitError(reqStatus); if (reqStatus >= 400 && reqStatus < 500) { this.connect_callback(Strophe.Status.DISCONNECTING, null); this._doDisconnect(); } } } if (!((reqStatus > 0 && reqStatus < 10000) || req.sends > 5)) { this._throttledRequestHandler(); } } }, /** PrivateFunction: _hitError * _Private_ function to handle the error count. * * Requests are resent automatically until their error count reaches * 5. Each time an error is encountered, this function is called to * increment the count and disconnect if the count is too high. * * Parameters: * (Integer) reqStatus - The request status. */ _hitError: function (reqStatus) { this.errors++; Strophe.warn("request errored, status: " + reqStatus + ", number of errors: " + this.errors); if (this.errors > 4) { this._onDisconnectTimeout(); } }, /** PrivateFunction: _doDisconnect * _Private_ function to disconnect. * * This is the last piece of the disconnection logic. This resets the * connection and alerts the user's connection callback. */ _doDisconnect: function () { Strophe.info("_doDisconnect was called"); this.authenticated = false; this.disconnecting = false; this.sid = null; this.streamId = null; this.rid = Math.floor(Math.random() * 4294967295); // tell the parent we disconnected if (this.connected) { this.connect_callback(Strophe.Status.DISCONNECTED, null); this.connected = false; } // delete handlers this.handlers = []; this.timedHandlers = []; this.removeTimeds = []; this.removeHandlers = []; this.addTimeds = []; this.addHandlers = []; }, /** PrivateFunction: _dataRecv * _Private_ handler
最新发布
08-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值