瀏覽代碼

Merge branch 'master' of http://47.100.37.243:10191/wutt/manHourHousekeeper

zhouyy 7 月之前
父節點
當前提交
ef7ae618ce
共有 31 個文件被更改,包括 4815 次插入33426 次删除
  1. 4 176
      fhKeeper/formulahousekeeper/ArticleOperation/log/article.log
  2. 1483 31022
      fhKeeper/formulahousekeeper/management-crm/crm.log
  3. 1 0
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/ClueServiceImpl.java
  4. 1 1
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/ProductServiceImpl.java
  5. 39 22
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/SalesOrderServiceImpl.java
  6. 5 3
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/TaskServiceImpl.java
  7. 58 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/CompanyDictController.java
  8. 51 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/CompanyDict.java
  9. 2 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/WorktimeItem.java
  10. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/CompanyDictMapper.java
  11. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/CompanyDictService.java
  12. 20 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/CompanyDictServiceImpl.java
  13. 45 16
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  14. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/JavaFileProcessor.java
  15. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/application.yml
  16. 18 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/CompanyDictMapper.xml
  17. 10 10
      fhKeeper/formulahousekeeper/timesheet/config/index.js
  18. 0 45
      fhKeeper/formulahousekeeper/timesheet/src/common/js/appidConfiguration.js
  19. 2 0
      fhKeeper/formulahousekeeper/timesheet/src/permissions.js
  20. 3 7
      fhKeeper/formulahousekeeper/timesheet/src/views/Login.vue
  21. 77 1986
      fhKeeper/formulahousekeeper/timesheet/src/views/project/finance.vue
  22. 153 0
      fhKeeper/formulahousekeeper/timesheet/src/views/project/financeComponents/common.js
  23. 378 0
      fhKeeper/formulahousekeeper/timesheet/src/views/project/financeComponents/incomeDetail.vue
  24. 2175 0
      fhKeeper/formulahousekeeper/timesheet/src/views/project/financeComponents/salaryDetails.vue
  25. 173 61
      fhKeeper/formulahousekeeper/timesheet/src/views/settings/timetype.vue
  26. 31 7
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue
  27. 0 45
      fhKeeper/formulahousekeeper/timesheet_h5/src/utils/appidConfiguration.js
  28. 34 4
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue
  29. 6 8
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/login/index.vue
  30. 2 1
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/view/index.vue
  31. 10 10
      fhKeeper/formulahousekeeper/timesheet_h5/vue.config.js

+ 4 - 176
fhKeeper/formulahousekeeper/ArticleOperation/log/article.log

@@ -1,176 +1,4 @@
-2024-11-12 14:32:51.481 [main] ERROR o.s.b.SpringApplication - [reportFailure,818] - Application run failed
-org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException: Input length = 1
-	at org.yaml.snakeyaml.reader.StreamReader.update(StreamReader.java:218)
-	at org.yaml.snakeyaml.reader.StreamReader.ensureEnoughData(StreamReader.java:176)
-	at org.yaml.snakeyaml.reader.StreamReader.ensureEnoughData(StreamReader.java:171)
-	at org.yaml.snakeyaml.reader.StreamReader.peek(StreamReader.java:126)
-	at org.yaml.snakeyaml.scanner.ScannerImpl.scanToNextToken(ScannerImpl.java:1218)
-	at org.yaml.snakeyaml.scanner.ScannerImpl.fetchMoreTokens(ScannerImpl.java:329)
-	at org.yaml.snakeyaml.scanner.ScannerImpl.checkToken(ScannerImpl.java:251)
-	at org.yaml.snakeyaml.parser.ParserImpl$ParseImplicitDocumentStart.produce(ParserImpl.java:214)
-	at org.yaml.snakeyaml.parser.ParserImpl.peekEvent(ParserImpl.java:166)
-	at org.yaml.snakeyaml.parser.ParserImpl.checkEvent(ParserImpl.java:156)
-	at org.yaml.snakeyaml.composer.Composer.checkNode(Composer.java:93)
-	at org.yaml.snakeyaml.constructor.BaseConstructor.checkData(BaseConstructor.java:124)
-	at org.yaml.snakeyaml.Yaml$1.hasNext(Yaml.java:509)
-	at org.springframework.beans.factory.config.YamlProcessor.process(YamlProcessor.java:199)
-	at org.springframework.beans.factory.config.YamlProcessor.process(YamlProcessor.java:166)
-	at org.springframework.boot.env.OriginTrackedYamlLoader.load(OriginTrackedYamlLoader.java:88)
-	at org.springframework.boot.env.YamlPropertySourceLoader.load(YamlPropertySourceLoader.java:50)
-	at org.springframework.boot.context.config.StandardConfigDataLoader.load(StandardConfigDataLoader.java:54)
-	at org.springframework.boot.context.config.StandardConfigDataLoader.load(StandardConfigDataLoader.java:36)
-	at org.springframework.boot.context.config.ConfigDataLoaders.load(ConfigDataLoaders.java:108)
-	at org.springframework.boot.context.config.ConfigDataImporter.load(ConfigDataImporter.java:132)
-	at org.springframework.boot.context.config.ConfigDataImporter.resolveAndLoad(ConfigDataImporter.java:87)
-	at org.springframework.boot.context.config.ConfigDataEnvironmentContributors.withProcessedImports(ConfigDataEnvironmentContributors.java:116)
-	at org.springframework.boot.context.config.ConfigDataEnvironment.processInitial(ConfigDataEnvironment.java:240)
-	at org.springframework.boot.context.config.ConfigDataEnvironment.processAndApply(ConfigDataEnvironment.java:227)
-	at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:102)
-	at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:94)
-	at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEnvironmentPreparedEvent(EnvironmentPostProcessorApplicationListener.java:102)
-	at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEvent(EnvironmentPostProcessorApplicationListener.java:87)
-	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:178)
-	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:171)
-	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:145)
-	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:133)
-	at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:85)
-	at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:66)
-	at org.springframework.boot.SpringApplicationRunListeners$$Lambda$37/1452442375.accept(Unknown Source)
-	at java.util.ArrayList.forEach(ArrayList.java:1249)
-	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:120)
-	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:114)
-	at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:65)
-	at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:344)
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300)
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1289)
-	at com.my.bigevent.BigEventApplication.main(BigEventApplication.java:12)
-Caused by: java.nio.charset.MalformedInputException: Input length = 1
-	at java.nio.charset.CoderResult.throwException(CoderResult.java:281)
-	at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339)
-	at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
-	at java.io.InputStreamReader.read(InputStreamReader.java:184)
-	at org.yaml.snakeyaml.reader.UnicodeReader.read(UnicodeReader.java:125)
-	at org.yaml.snakeyaml.reader.StreamReader.update(StreamReader.java:183)
-	... 44 common frames omitted
-2024-11-12 14:34:08.746 [main] ERROR o.s.b.SpringApplication - [reportFailure,818] - Application run failed
-org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException: Input length = 1
-	at org.yaml.snakeyaml.reader.StreamReader.update(StreamReader.java:218)
-	at org.yaml.snakeyaml.reader.StreamReader.ensureEnoughData(StreamReader.java:176)
-	at org.yaml.snakeyaml.reader.StreamReader.ensureEnoughData(StreamReader.java:171)
-	at org.yaml.snakeyaml.reader.StreamReader.peek(StreamReader.java:126)
-	at org.yaml.snakeyaml.scanner.ScannerImpl.scanToNextToken(ScannerImpl.java:1218)
-	at org.yaml.snakeyaml.scanner.ScannerImpl.fetchMoreTokens(ScannerImpl.java:329)
-	at org.yaml.snakeyaml.scanner.ScannerImpl.checkToken(ScannerImpl.java:251)
-	at org.yaml.snakeyaml.parser.ParserImpl$ParseImplicitDocumentStart.produce(ParserImpl.java:214)
-	at org.yaml.snakeyaml.parser.ParserImpl.peekEvent(ParserImpl.java:166)
-	at org.yaml.snakeyaml.parser.ParserImpl.checkEvent(ParserImpl.java:156)
-	at org.yaml.snakeyaml.composer.Composer.checkNode(Composer.java:93)
-	at org.yaml.snakeyaml.constructor.BaseConstructor.checkData(BaseConstructor.java:124)
-	at org.yaml.snakeyaml.Yaml$1.hasNext(Yaml.java:509)
-	at org.springframework.beans.factory.config.YamlProcessor.process(YamlProcessor.java:199)
-	at org.springframework.beans.factory.config.YamlProcessor.process(YamlProcessor.java:166)
-	at org.springframework.boot.env.OriginTrackedYamlLoader.load(OriginTrackedYamlLoader.java:88)
-	at org.springframework.boot.env.YamlPropertySourceLoader.load(YamlPropertySourceLoader.java:50)
-	at org.springframework.boot.context.config.StandardConfigDataLoader.load(StandardConfigDataLoader.java:54)
-	at org.springframework.boot.context.config.StandardConfigDataLoader.load(StandardConfigDataLoader.java:36)
-	at org.springframework.boot.context.config.ConfigDataLoaders.load(ConfigDataLoaders.java:108)
-	at org.springframework.boot.context.config.ConfigDataImporter.load(ConfigDataImporter.java:132)
-	at org.springframework.boot.context.config.ConfigDataImporter.resolveAndLoad(ConfigDataImporter.java:87)
-	at org.springframework.boot.context.config.ConfigDataEnvironmentContributors.withProcessedImports(ConfigDataEnvironmentContributors.java:116)
-	at org.springframework.boot.context.config.ConfigDataEnvironment.processInitial(ConfigDataEnvironment.java:240)
-	at org.springframework.boot.context.config.ConfigDataEnvironment.processAndApply(ConfigDataEnvironment.java:227)
-	at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:102)
-	at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:94)
-	at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEnvironmentPreparedEvent(EnvironmentPostProcessorApplicationListener.java:102)
-	at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEvent(EnvironmentPostProcessorApplicationListener.java:87)
-	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:178)
-	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:171)
-	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:145)
-	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:133)
-	at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:85)
-	at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:66)
-	at org.springframework.boot.SpringApplicationRunListeners$$Lambda$37/1452442375.accept(Unknown Source)
-	at java.util.ArrayList.forEach(ArrayList.java:1249)
-	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:120)
-	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:114)
-	at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:65)
-	at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:344)
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300)
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1289)
-	at com.my.bigevent.BigEventApplication.main(BigEventApplication.java:12)
-Caused by: java.nio.charset.MalformedInputException: Input length = 1
-	at java.nio.charset.CoderResult.throwException(CoderResult.java:281)
-	at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339)
-	at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
-	at java.io.InputStreamReader.read(InputStreamReader.java:184)
-	at org.yaml.snakeyaml.reader.UnicodeReader.read(UnicodeReader.java:125)
-	at org.yaml.snakeyaml.reader.StreamReader.update(StreamReader.java:183)
-	... 44 common frames omitted
-2024-11-12 14:34:32.513 [main] ERROR o.s.b.SpringApplication - [reportFailure,818] - Application run failed
-org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException: Input length = 1
-	at org.yaml.snakeyaml.reader.StreamReader.update(StreamReader.java:218)
-	at org.yaml.snakeyaml.reader.StreamReader.ensureEnoughData(StreamReader.java:176)
-	at org.yaml.snakeyaml.reader.StreamReader.ensureEnoughData(StreamReader.java:171)
-	at org.yaml.snakeyaml.reader.StreamReader.peek(StreamReader.java:126)
-	at org.yaml.snakeyaml.scanner.ScannerImpl.scanToNextToken(ScannerImpl.java:1218)
-	at org.yaml.snakeyaml.scanner.ScannerImpl.fetchMoreTokens(ScannerImpl.java:329)
-	at org.yaml.snakeyaml.scanner.ScannerImpl.checkToken(ScannerImpl.java:251)
-	at org.yaml.snakeyaml.parser.ParserImpl$ParseImplicitDocumentStart.produce(ParserImpl.java:214)
-	at org.yaml.snakeyaml.parser.ParserImpl.peekEvent(ParserImpl.java:166)
-	at org.yaml.snakeyaml.parser.ParserImpl.checkEvent(ParserImpl.java:156)
-	at org.yaml.snakeyaml.composer.Composer.checkNode(Composer.java:93)
-	at org.yaml.snakeyaml.constructor.BaseConstructor.checkData(BaseConstructor.java:124)
-	at org.yaml.snakeyaml.Yaml$1.hasNext(Yaml.java:509)
-	at org.springframework.beans.factory.config.YamlProcessor.process(YamlProcessor.java:199)
-	at org.springframework.beans.factory.config.YamlProcessor.process(YamlProcessor.java:166)
-	at org.springframework.boot.env.OriginTrackedYamlLoader.load(OriginTrackedYamlLoader.java:88)
-	at org.springframework.boot.env.YamlPropertySourceLoader.load(YamlPropertySourceLoader.java:50)
-	at org.springframework.boot.context.config.StandardConfigDataLoader.load(StandardConfigDataLoader.java:54)
-	at org.springframework.boot.context.config.StandardConfigDataLoader.load(StandardConfigDataLoader.java:36)
-	at org.springframework.boot.context.config.ConfigDataLoaders.load(ConfigDataLoaders.java:108)
-	at org.springframework.boot.context.config.ConfigDataImporter.load(ConfigDataImporter.java:132)
-	at org.springframework.boot.context.config.ConfigDataImporter.resolveAndLoad(ConfigDataImporter.java:87)
-	at org.springframework.boot.context.config.ConfigDataEnvironmentContributors.withProcessedImports(ConfigDataEnvironmentContributors.java:116)
-	at org.springframework.boot.context.config.ConfigDataEnvironment.processInitial(ConfigDataEnvironment.java:240)
-	at org.springframework.boot.context.config.ConfigDataEnvironment.processAndApply(ConfigDataEnvironment.java:227)
-	at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:102)
-	at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:94)
-	at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEnvironmentPreparedEvent(EnvironmentPostProcessorApplicationListener.java:102)
-	at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEvent(EnvironmentPostProcessorApplicationListener.java:87)
-	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:178)
-	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:171)
-	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:145)
-	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:133)
-	at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:85)
-	at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:66)
-	at org.springframework.boot.SpringApplicationRunListeners$$Lambda$37/1667148529.accept(Unknown Source)
-	at java.util.ArrayList.forEach(ArrayList.java:1249)
-	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:120)
-	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:114)
-	at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:65)
-	at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:344)
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300)
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1289)
-	at com.my.bigevent.BigEventApplication.main(BigEventApplication.java:12)
-Caused by: java.nio.charset.MalformedInputException: Input length = 1
-	at java.nio.charset.CoderResult.throwException(CoderResult.java:281)
-	at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339)
-	at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
-	at java.io.InputStreamReader.read(InputStreamReader.java:184)
-	at org.yaml.snakeyaml.reader.UnicodeReader.read(UnicodeReader.java:125)
-	at org.yaml.snakeyaml.reader.StreamReader.update(StreamReader.java:183)
-	... 44 common frames omitted
-2024-11-12 14:34:52.557 [background-preinit] INFO  o.h.v.i.util.Version - [<clinit>,21] - HV000001: Hibernate Validator 6.2.5.Final
-2024-11-12 14:34:52.560 [main] INFO  c.m.b.BigEventApplication - [logStarting,55] - Starting BigEventApplication using Java 1.8.0_45 on Yurk with PID 29304 (D:\WorkSpeace\manHourHousekeeper\fhKeeper\formulahousekeeper\ArticleOperation\target\classes started by 123 in D:\WorkSpeace\manHourHousekeeper\fhKeeper\formulahousekeeper\ArticleOperation)
-2024-11-12 14:34:52.561 [main] INFO  c.m.b.BigEventApplication - [logStartupProfileInfo,632] - No active profile set, falling back to 1 default profile: "default"
-2024-11-12 14:34:53.152 [main] ERROR o.a.c.c.AprLifecycleListener - [log,173] - An incompatible version [1.1.32] of the Apache Tomcat Native library is installed, while Tomcat requires version [1.2.14]
-2024-11-12 14:34:53.285 [main] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Initializing ProtocolHandler ["http-nio-8091"]
-2024-11-12 14:34:53.286 [main] INFO  o.a.c.c.StandardService - [log,173] - Starting service [Tomcat]
-2024-11-12 14:34:53.286 [main] INFO  o.a.c.c.StandardEngine - [log,173] - Starting Servlet engine: [Apache Tomcat/9.0.83]
-2024-11-12 14:34:53.404 [main] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring embedded WebApplicationContext
-2024-11-12 14:34:53.849 [main] INFO  o.a.c.h.Http11NioProtocol - [log,173] - Starting ProtocolHandler ["http-nio-8091"]
-2024-11-12 14:34:53.866 [main] INFO  c.m.b.BigEventApplication - [logStarted,61] - Started BigEventApplication in 1.554 seconds (JVM running for 2.339)
-2024-11-12 14:35:03.671 [http-nio-8091-exec-1] INFO  o.a.c.c.C.[.[.[/] - [log,173] - Initializing Spring DispatcherServlet 'dispatcherServlet'
+2024-11-14 19:33:31.163 [main] INFO  c.m.b.BigEventApplicationTests - [logStarting,55] - Starting BigEventApplicationTests using Java 1.8.0_181 on DESKTOP-0TSN311 with PID 48660 (started by seya in C:\gitproject\manHourHousekeeper\fhKeeper\formulahousekeeper\ArticleOperation)
+2024-11-14 19:33:31.173 [main] INFO  c.m.b.BigEventApplicationTests - [logStartupProfileInfo,632] - No active profile set, falling back to 1 default profile: "default"
+2024-11-14 19:33:31.184 [background-preinit] INFO  o.h.v.i.util.Version - [<clinit>,21] - HV000001: Hibernate Validator 6.2.5.Final
+2024-11-14 19:33:33.948 [main] INFO  c.m.b.BigEventApplicationTests - [logStarted,61] - Started BigEventApplicationTests in 3.171 seconds (JVM running for 4.433)

文件差異過大導致無法顯示
+ 1483 - 31022
fhKeeper/formulahousekeeper/management-crm/crm.log


+ 1 - 0
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/ClueServiceImpl.java

@@ -597,6 +597,7 @@ public class ClueServiceImpl extends ServiceImpl<ClueMapper, Clue> implements Cl
                     }
 
                 }
+                product.setIsDelete(0);
                 importProductList.add(product);
             }
             if(importProductList.size()>0){

+ 1 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/ProductServiceImpl.java

@@ -381,7 +381,7 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> impl
                             }
                         }
                     } else if(modelName.equals("unit")){
-                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
+                        if(cell!=null&&!StringUtils.isEmpty(cell.getStringCellValue())){
                             Optional<SysDict> first = sysDictOfProductUnit.stream().filter(s -> s.getName().equals(cell.getStringCellValue())).findFirst();
                             if(first.isPresent()){
                                 product.setUnit(first.get().getId());

+ 39 - 22
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/SalesOrderServiceImpl.java

@@ -17,6 +17,10 @@ import org.apache.poi.hssf.usermodel.HSSFRow;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.ss.usermodel.CellType;
+import org.apache.poi.xssf.usermodel.XSSFCell;
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -318,13 +322,13 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
             inputStream.close();
             outputStream.close();
             //解析表格
-            HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(file));
+            XSSFWorkbook workbook = new XSSFWorkbook(file);
             //我们只需要第一个sheet
-            HSSFSheet sheet = workbook.getSheetAt(0);
+            XSSFSheet sheet = workbook.getSheetAt(0);
             //由于第一行需要指明列对应的标题
             int rowNum = sheet.getLastRowNum();
             //获取当前表单模板 校验规则
-            SysForm sysForm = sysFormMapper.selectOne(new LambdaQueryWrapper<SysForm>().eq(SysForm::getCode, "Product").eq(SysForm::getCompanyId, companyId).eq(SysForm::getIsCurrent, 1));
+            SysForm sysForm = sysFormMapper.selectOne(new LambdaQueryWrapper<SysForm>().eq(SysForm::getCode, "Order").eq(SysForm::getCompanyId, companyId).eq(SysForm::getIsCurrent, 1));
             if(sysForm==null){
                 msg.setError("当前模块未配置自定义模板,需先完成配置");
                 return msg;
@@ -354,7 +358,7 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
             List<String> userNameList=new ArrayList<>();
             HttpRespMsg respMsg=new HttpRespMsg();
             for (int rowIndex = 1; rowIndex <= rowNum; rowIndex++) {
-                HSSFRow row = sheet.getRow(rowIndex);
+                XSSFRow row = sheet.getRow(rowIndex);
                 if (row == null) {
                     continue;
                 }
@@ -366,19 +370,19 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
                 int cellNum = row.getLastCellNum();
                 for (int i = 0; i < cellNum; i++) {
                     String modelName = modelNameList.get(i);
-                    HSSFCell cell = row.getCell(i);
+                    XSSFCell cell = row.getCell(i);
                     if(modelName.equals("inchargerId")){
                         if(!StringUtils.isEmpty(cell.getStringCellValue())){
                             userNameList.add(cell.getStringCellValue());
                         }
                     }
                     if(modelName.equals("customSigner")){
-                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
+                        if(cell!=null&&!StringUtils.isEmpty(cell.getStringCellValue())){
                             userNameList.add(cell.getStringCellValue());
                         }
                     }
                     if(modelName.equals("companySigner")){
-                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
+                        if(cell!=null&&!StringUtils.isEmpty(cell.getStringCellValue())){
                             userNameList.add(cell.getStringCellValue());
                         }
                     }
@@ -395,7 +399,7 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
             }
             List<User> targetUserList= (List<User>) respMsg.data;
             for (int rowIndex = 1; rowIndex <= rowNum; rowIndex++) {
-                HSSFRow row = sheet.getRow(rowIndex);
+                XSSFRow row = sheet.getRow(rowIndex);
                 if (row == null) {
                     continue;
                 }
@@ -427,7 +431,7 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
                     String className = modelName.substring(0, 1).toUpperCase() + modelName.substring(1);
                     String getter="get"+className;
                     String setter="set"+className;
-                    HSSFCell cell = row.getCell(i);
+                    XSSFCell cell = row.getCell(i);
                     if(cell!=null){
                         switch (item.getString("type")){
 //                            case "time":cell.setCellType(CellType.NUMERIC);
@@ -446,7 +450,7 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
                         }
                     }
                     if(modelName.equals("orderCode")){
-                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
+                        if(cell!=null&&!StringUtils.isEmpty(cell.getStringCellValue())){
                             //系统中同公司已存在的订单编码 更新
                             Optional<SalesOrder> first = orderList.stream().filter(p ->p.getOrderCode()!=null&& p.getOrderCode().equals(cell.getStringCellValue())).findFirst();
                             if(first.isPresent()){
@@ -466,7 +470,7 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
                             }
                         }
                     } else if(modelName.equals("businessOpportunityId")){
-                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
+                        if(cell!=null&&!StringUtils.isEmpty(cell.getStringCellValue())){
                             //系统中同公司已存在的订单编码 更新
                             BusinessOpportunity one = businessOpportunityService.getOne(new LambdaQueryWrapper<BusinessOpportunity>().eq(BusinessOpportunity::getCompanyId, companyId).eq(BusinessOpportunity::getName, cell.getStringCellValue()));
                             if(one!=null){
@@ -477,19 +481,19 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
                             }
                         }
                     } else if(modelName.equals("price")){
-                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
+                        if(cell!=null&&!StringUtils.isEmpty(cell.getStringCellValue())){
                             order.setPrice(new BigDecimal(cell.getStringCellValue()));
                         }
                     } else if(modelName.equals("receivedPayment")){
-                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
+                        if(cell!=null&&!StringUtils.isEmpty(cell.getStringCellValue())){
                             order.setReceivedPayment(new BigDecimal(cell.getStringCellValue()));
                         }
                     } else if(modelName.equals("unReceivedPayment")){
-                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
+                        if(cell!=null&&!StringUtils.isEmpty(cell.getStringCellValue())){
                             order.setUnReceivedPayment(new BigDecimal(cell.getStringCellValue()));
                         }
                     }else if(modelName.equals("type")){
-                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
+                        if(cell!=null&&!StringUtils.isEmpty(cell.getStringCellValue())){
                             Optional<SysDict> first = sysDictOfOrderType.stream().filter(s -> s.getName().equals(cell.getStringCellValue())).findFirst();
                             if(first.isPresent()){
                                 order.setType(first.get().getId());
@@ -499,19 +503,32 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
                             }
                         }
                     }else if(modelName.equals("placeTime")){
-                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
-                            order.setPlaceTime(LocalDate.parse(cell.getStringCellValue(),df));
+                        if(cell!=null&&!StringUtils.isEmpty(cell.getStringCellValue())){
+                            try {
+                                int count = Integer.parseInt(cell.getStringCellValue());
+                                // Excel中的日期序列号的基准日期是1900年1月1日
+                                LocalDate baseDate = LocalDate.of(1900, 1, 1);
+                                LocalDate date = baseDate.plusDays(count - 2);
+
+                                // 将 ZonedDateTime 转换为 Date
+                                order.setPlaceTime(date);
+
+                            } catch (Exception e) {
+                                System.out.println("日期时间格式不正确,应该是yyyy/MM/dd" );
+                                msg.setError("日期时间格式不正确,应该是yyyy/MM/dd");
+                                return msg;
+                            }
                         }
                     }else if(modelName.equals("orderStartDate")){
-                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
+                        if(cell!=null&&!StringUtils.isEmpty(cell.getStringCellValue())){
                             order.setOrderStartDate(LocalDate.parse(cell.getStringCellValue(),df));
                         }
                     }else if(modelName.equals("orderEndDate")){
-                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
+                        if(cell!=null&&!StringUtils.isEmpty(cell.getStringCellValue())){
                             order.setOrderEndDate(LocalDate.parse(cell.getStringCellValue(),df));
                         }
                     }else if(modelName.equals("inchargerId")){
-                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
+                        if(cell!=null&&!StringUtils.isEmpty(cell.getStringCellValue())){
                             String userName = cell.getStringCellValue();
                             Optional<User> first;
                             if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
@@ -528,7 +545,7 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
                             }
                         }
                     }else if(modelName.equals("customSigner")){
-                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
+                        if(cell!=null&&!StringUtils.isEmpty(cell.getStringCellValue())){
                             String userName = cell.getStringCellValue();
                             Optional<User> first;
                             if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
@@ -545,7 +562,7 @@ public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOr
                             }
                         }
                     }else if(modelName.equals("companySigner")){
-                        if(!StringUtils.isEmpty(cell.getStringCellValue())){
+                        if(cell!=null&&!StringUtils.isEmpty(cell.getStringCellValue())){
                             String userName = cell.getStringCellValue();
                             Optional<User> first;
                             if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){

+ 5 - 3
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/TaskServiceImpl.java

@@ -853,7 +853,7 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
                     ArrayList<Information> informationArrayList = new ArrayList<>();
                     for (Task task : importTaskList) {
                         String executorId = task.getExecutorId();
-                        Information information = new Information();
+
 
                         if (StringUtils.isNotEmpty(executorId)){
                             String[] split = executorId.split(",");
@@ -865,7 +865,10 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
                                 taskExecutor.setCompanyId(user.getCompanyId());
                                 taskExecutors.add(taskExecutor);
 
+                                Information information = new Information();
                                 information.setUserId(userList.stream().filter(u -> u.getId().equals(userId)).collect(Collectors.toList()).get(0).getId());
+                                information.setMsg("你有新的任务").setTime(new Date()).setChecked(0);
+                                informationArrayList.add(information);
                             }
                         }
                         TaskLog taskLog = new TaskLog();
@@ -877,8 +880,7 @@ public class TaskServiceImpl extends ServiceImpl<TaskMapper, Task> implements Ta
                         taskLogs.add(taskLog);
 
 
-                        information.setMsg("你有新的任务").setTime(new Date()).setChecked(0);
-                        informationArrayList.add(information);
+
                     }
 
                     boolean b1 = true;

+ 58 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/CompanyDictController.java

@@ -0,0 +1,58 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.CompanyDict;
+import com.management.platform.mapper.CompanyDictMapper;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-12-05
+ */
+@RestController
+@RequestMapping("/company-dict")
+public class CompanyDictController {
+
+    @Resource
+    private CompanyDictMapper companyDictMapper;
+
+    //新增保存公司字典
+    @RequestMapping("/save")
+    public HttpRespMsg save(CompanyDict companyDict) {
+        HttpRespMsg msg = new HttpRespMsg();
+        if (companyDict.getId() != null) {
+            companyDictMapper.updateById(companyDict);
+        } else {
+            companyDictMapper.insert(companyDict);
+        }
+        return msg;
+    }
+
+    //删除公司字典
+    @RequestMapping("/delete")
+    public HttpRespMsg delete(Integer id) {
+        HttpRespMsg msg = new HttpRespMsg();
+        companyDictMapper.deleteById(id);
+        return msg;
+    }
+
+    //获取字典
+    @RequestMapping("/getAll")
+    public HttpRespMsg getAll(String code, Integer companyId) {
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.setData(companyDictMapper.selectList(new QueryWrapper<>(new CompanyDict().setCode(code).setCompanyId(companyId))));
+        return msg;
+    }
+
+}
+

+ 51 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/CompanyDict.java

@@ -0,0 +1,51 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-12-05
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class CompanyDict extends Model<CompanyDict> {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @TableField("company_id")
+    private Integer companyId;
+
+    /**
+     * 字典key,可以重复
+     */
+    @TableField("code")
+    private String code;
+
+    /**
+     * 字典值
+     */
+    @TableField("value")
+    private String value;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 2 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/WorktimeItem.java

@@ -8,4 +8,6 @@ public class WorktimeItem {
     String endTime;
     String content;
     double time;
+
+    String detail;//工作细项,美莱德新增
 }

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/CompanyDictMapper.java

@@ -0,0 +1,16 @@
+package com.management.platform.mapper;
+
+import com.management.platform.entity.CompanyDict;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-12-05
+ */
+public interface CompanyDictMapper extends BaseMapper<CompanyDict> {
+
+}

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/CompanyDictService.java

@@ -0,0 +1,16 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.CompanyDict;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-12-05
+ */
+public interface CompanyDictService extends IService<CompanyDict> {
+
+}

+ 20 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/CompanyDictServiceImpl.java

@@ -0,0 +1,20 @@
+package com.management.platform.service.impl;
+
+import com.management.platform.entity.CompanyDict;
+import com.management.platform.mapper.CompanyDictMapper;
+import com.management.platform.service.CompanyDictService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-12-05
+ */
+@Service
+public class CompanyDictServiceImpl extends ServiceImpl<CompanyDictMapper, CompanyDict> implements CompanyDictService {
+
+}

+ 45 - 16
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -1630,7 +1630,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 delLog.setDeleteUserId(delUserId);
                 delList.add(delLog);
             }
-            reportDeleteService.saveBatch(delList);
+            reportDeleteService.saveOrUpdateBatch(delList);
         }
         return httpRespMsg;
     }
@@ -5257,12 +5257,17 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                                 //赛元微电子,导入的按照项目审核的模式进行
                                 if (company.getId() == 469) {
                                     report.setState(0);//待审核员审核
-                                    //赛元都是非项目,直接取员工所属部门的主要负责人来审核
-                                    Department department = departmentMapper.selectById(reportCreator.getDepartmentId());
-                                    if (department != null) {
-                                        report.setProjectAuditorId(department.getManagerId());
-                                    }
+                                    //赛元都是非项目,直接取员工所属部门的主要负责人来审核,如果设置了非项目审核人,优先用非项目审核人
+                                    int mode = 0;
+                                    String superiorId = user.getSuperiorId();
+                                    if (superiorId == null) {
+                                        Department department = departmentMapper.selectById(reportCreator.getDepartmentId());
+                                        if (department != null) {
+                                            superiorId = department.getManagerId();
 
+                                        }
+                                    }
+                                    report.setProjectAuditorId(superiorId);
                                     List<AuditWorkflowTimeSetting> auditWorkflowList
                                             = auditWorkflowTimeSettingMapper.selectList(
                                             new QueryWrapper<AuditWorkflowTimeSetting>().eq("dept_id", reportCreator.getDepartmentId()).orderByAsc("seq"));
@@ -5656,12 +5661,32 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                                 report.setState(0);//待审核
                                 //目前仅支持项目审核人审核的模式,叠加审批流
                                 if (timeType.getReportAuditType() == 0) {
-                                    //设置日报审核人
-                                    List<ProjectAuditor> projectAuditors = projectAuditorMapper.selectList(new QueryWrapper<ProjectAuditor>().eq("project_id", project.getId()));
-                                    if (projectAuditors.size() > 0) {
-                                        report.setProjectAuditorId(projectAuditors.get(0).getAuditorId());
+                                    int mode = 0;
+                                    if (company.getNonProjectSimple() == 1) {
+                                        //启用了简易模式
+                                        List<ProjectAuditor> pAuditorList = new ArrayList<>();
+                                        if (project.getIsPublic() == 1) {
+                                            //非项目,该员工的部门主要负责人审核
+                                            mode = 1;
+                                            //优先取员工的上级领导
+                                            String superiorId = user.getSuperiorId();
+                                            if (superiorId == null) {
+                                                Integer departmentId = user.getDepartmentId();
+                                                Department department = departmentMapper.selectById(departmentId);
+                                                if (department != null) {
+                                                    superiorId = department.getManagerId();
+                                                }
+                                            }
+                                            report.setProjectAuditorId(superiorId);
+                                        }
+                                    }
+                                    if (mode == 0) {
+                                        //没有设置部门的审核人,按项目日报审核人设置
+                                        List<ProjectAuditor> projectAuditors = projectAuditorMapper.selectList(new QueryWrapper<ProjectAuditor>().eq("project_id", project.getId()));
+                                        if (projectAuditors.size() > 0) {
+                                            report.setProjectAuditorId(projectAuditors.get(0).getAuditorId());
+                                        }
                                     }
-
                                     List<AuditWorkflowTimeSetting> auditWorkflowList
                                             = auditWorkflowTimeSettingMapper.selectList(
                                             new QueryWrapper<AuditWorkflowTimeSetting>().eq("dept_id", reportCreator.getDepartmentId()).orderByAsc("seq"));
@@ -8264,12 +8289,16 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                             if (project.getIsPublic() == 1) {
                                 //非项目,该员工的部门主要负责人审核
                                 mode = 1;
-                                String superiorId = null;
-                                Integer departmentId = user.getDepartmentId();
-                                Department department = departmentMapper.selectById(departmentId);
-                                if (department != null) {
-                                    superiorId = department.getManagerId();
+                                //优先取员工的上级领导
+                                String superiorId = user.getSuperiorId();
+                                if (superiorId == null) {
+                                    Integer departmentId = user.getDepartmentId();
+                                    Department department = departmentMapper.selectById(departmentId);
+                                    if (department != null) {
+                                        superiorId = department.getManagerId();
+                                    }
                                 }
+
                                 if (superiorId != null) {
                                     User superior = userMapper.selectById(superiorId);
                                     if (superior != null) {

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/JavaFileProcessor.java

@@ -50,7 +50,7 @@ public class JavaFileProcessor {
     private static List<String> getJavaFiles(String directoryPath) throws IOException {
         List<String> javaFiles = new ArrayList<>();
         Files.walk(Paths.get(directoryPath))
-                .filter(p -> p.toString().endsWith(".java"))
+                .filter(p -> p.toString().endsWith(".java") || p.toString().endsWith(".vue"))
                 .forEach(p -> javaFiles.add(p.toString()));
         return javaFiles;
     }

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/resources/application.yml

@@ -15,7 +15,7 @@ spring:
       location: C:/upload/
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://47.101.180.183:17089/man_hour_manager?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&useSSL=false
+    url: jdbc:mysql://47.101.180.183:17089/man_dev?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&useSSL=false
     username: root
     password: P011430@Huoshi*
 

+ 18 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/CompanyDictMapper.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.management.platform.mapper.CompanyDictMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.CompanyDict">
+        <id column="id" property="id" />
+        <result column="company_id" property="companyId" />
+        <result column="code" property="code" />
+        <result column="value" property="value" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, company_id, code, value
+    </sql>
+
+</mapper>

+ 10 - 10
fhKeeper/formulahousekeeper/timesheet/config/index.js

@@ -4,17 +4,17 @@ var path = require('path')
 // var ip = '47.101.180.183'
 // var ip = '47.100.37.243'
 // var ip = '192.168.10.2'
-var ip = '192.168.2.3' 
+// var ip = '192.168.2.3' 
 
-// var os = require('os'), ip = '', ifaces = os.networkInterfaces() // 获取本机ip
-// for (var i in ifaces) {
-//     for (var j in ifaces[i]) {
-//         var val = ifaces[i][j]
-//         if (val.family === 'IPv4' && val.address !== '127.0.0.1') {
-//             ip = val.address
-//         }
-//     }
-// }
+var os = require('os'), ip = '', ifaces = os.networkInterfaces() // 获取本机ip
+for (var i in ifaces) {
+    for (var j in ifaces[i]) {
+        var val = ifaces[i][j]
+        if (val.family === 'IPv4' && val.address !== '127.0.0.1') {
+            ip = val.address
+        }
+    }
+}
 // 1196735749
 module.exports = {
   build: {

+ 0 - 45
fhKeeper/formulahousekeeper/timesheet/src/common/js/appidConfiguration.js

@@ -1,45 +0,0 @@
-/**
- * 各个公司企业微信的配置, 根据域名来解析
- * @path 完整域名
- * @appId 企业微信的appId,针对私有化部署的情况appId就是corpId
- */
-const config = {
-  "worktime.ttkuaiban.com": {
-    // 工时管家
-    path: "https://worktime.ttkuaiban.com",
-    appId: "ww4e237fd6abb635af",
-    agentId: "",
-  },
-  "blue.blovelight.net": {
-    // 蓝光研发
-    path: "http://blue.blovelight.net:2021",
-    appId: "wwb12ec40df8c35139",
-    agentId: "1000075",
-  },
-  "privatewx.ttkuaiban.com": {
-    // 火石闪信-企业微信私有化
-    path: "http://privatewx.ttkuaiban.com",
-    appId: "wwf11426cf618e1703",
-    agentId: "1000069",
-  },
-};
-
-const fixedPath = `/api/corpWXAuth`; // 授权回调页面 (需要拼接)
-const fixedPathAgentId = `/api/corpInsideWXAuth`
-
-export function obtainCorrespondingConfigurationInformation() {
-  const hostname = window.location.hostname; // 获取域名和端口,(不包括http 和 https)
-  const row = config[hostname];
-  const agentId = row.agentId;
-  const appId = row.appId;
-  const tokenUrl = `${row.path}${fixedPath}`;
-  const tokenUrlAgentId = `${row.path}${fixedPathAgentId}`;
-  const authorizationCallback = agentId
-    ? `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${encodeURI(tokenUrlAgentId)}&response_type=code&scope=snsapi_base&state=0&agentid=${agentId}#wechat_redirect`
-    : `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${encodeURI(tokenUrl)}&response_type=code&scope=snsapi_base&state=1#wechat_redirect`;
-  return {
-    appId,
-    tokenUrl,
-    authorizationCallback,
-  };
-}

+ 2 - 0
fhKeeper/formulahousekeeper/timesheet/src/permissions.js

@@ -63,6 +63,7 @@ const StringUtil = {
         financialExport: false, // 薪资数据导出 // 
         financialShare: false, // 导出分摊数据 //
         setFinanceAuditor: false, //设置财务审核人
+        financialBonusDetails: false, // 奖金明细 // 
 
         // 项目报表服务 // 
         reportAllProject: false, // 全部项目报表 //
@@ -289,6 +290,7 @@ const StringUtil = {
         
         arr[i] == '设备信息管理' ? obj.equipmentInformationManagement = true : ''
         arr[i] == '设备成本管理' ? obj.equipmentCostManagement = true : ''
+        arr[i] == '奖金明细' ? obj.financialBonusDetails = true : ''
     }
     return obj
   }

+ 3 - 7
fhKeeper/formulahousekeeper/timesheet/src/views/Login.vue

@@ -68,7 +68,6 @@
     import * as dd from 'dingtalk-jsapi';
     import "../permissions.js"
     import WxLogin from "../assets/js/wwLogin.js"
-    import { obtainCorrespondingConfigurationInformation } from '../common/js/appidConfiguration.js'
     export default {
         inject:['reloads'],
         data() {
@@ -361,12 +360,9 @@
             },
             tryAutoLogin() {
                 let href = window.location.href;
-                // var appId = "ww4e237fd6abb635af";//企业微信第三方的SUIT ID
-                // var url = "https://worktime.ttkuaiban.com/api/corpWXAuth";//授权回调页面
-                // var weixinUrl="https://open.weixin.qq.com/connect/oauth2/authorize?appid="+appId+"&redirect_uri="+encodeURI(url)+"&response_type=code&scope=snsapi_base&state=1#wechat_redirect";
-
-                const config = obtainCorrespondingConfigurationInformation()
-                var weixinUrl = config.authorizationCallback;
+                var appId = "ww4e237fd6abb635af";//企业微信第三方的SUIT ID
+                var url = "https://worktime.ttkuaiban.com/api/corpWXAuth";//授权回调页面
+                var weixinUrl="https://open.weixin.qq.com/connect/oauth2/authorize?appid="+appId+"&redirect_uri="+encodeURI(url)+"&response_type=code&scope=snsapi_base&state=1#wechat_redirect";
                 window.location.href = weixinUrl;
             },
             tryDingDingUrlRedirect() {

文件差異過大導致無法顯示
+ 77 - 1986
fhKeeper/formulahousekeeper/timesheet/src/views/project/finance.vue


+ 153 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/project/financeComponents/common.js

@@ -0,0 +1,153 @@
+export const FINANCIAL_DETAILS = "资金明细"; // 资金明细
+export const INCOME_DETAIL = "奖金明细"; // 奖金明细
+
+export const fundCascadingPanel = [
+  {
+    value: "季度奖",
+    label: "季度奖",
+    children: [
+      {
+        value: "第一季度奖",
+        label: "第一季度奖",
+      },
+      {
+        value: "第二季度奖",
+        label: "第二季度奖",
+      },
+      {
+        value: "第三季度奖",
+        label: "第三季度奖",
+      },
+      {
+        value: "第四季度奖",
+        label: "第四季度奖",
+      },
+    ],
+  },
+  {
+    value: "半年奖",
+    label: "半年奖",
+    children: [
+      {
+        value: "上半年奖",
+        label: "上半年奖",
+      },
+      {
+        value: "下半年奖",
+        label: "下半年奖",
+      },
+    ],
+  },
+  {
+    value: "全年奖",
+    label: "全年奖",
+  },
+];
+
+
+export function processingChartOptions(list = []) {
+  const xAxisData = list.map(item => item.projectName)
+  const item = { type: 'bar', barWidth: 30, emphasis: { focus: 'series' } }
+  const QUARTER = 'quarter'
+  const YEAR = 'year'
+  const series = [
+    {
+      name: '第一季度奖',
+      filed: 'firstSeasonBonus',
+      stack: QUARTER,
+      itemStyle: { color: '#c1adad' },
+      data: [],
+      ...item,
+    },
+    {
+      name: '第二季度奖',
+      filed: 'secondSeasonBonus',
+      stack: QUARTER,
+      itemStyle: { color: '#d7ad9b' },
+      data: [],
+      ...item,
+    },
+    {
+      name: '第三季度奖',
+      filed: 'thirdSeasonBonus',
+      stack: QUARTER,
+      itemStyle: { color: '#e5dcd1' },
+      data: [],
+      ...item,
+    },
+    {
+      name: '第四季度奖',
+      filed: 'forthSeasonBonus',
+      stack: QUARTER,
+      itemStyle: { color: '#e6d7d7' },
+      data: [],
+      ...item,
+    },
+    {
+      name: '上半年奖',
+      filed: 'soonerHalfYearBonus',
+      stack: YEAR,
+      itemStyle: { color: '#c4cdd0' },
+      data: [],
+      ...item,
+    },
+    {
+      name: '下半年奖',
+      filed: 'latterHalfYearBonus',
+      stack: YEAR,
+      itemStyle: { color: '#dac890' },
+      data: [],
+      ...item,
+    },
+    {
+      name: '全年奖',
+      filed: 'yearBonus',
+      itemStyle: { color: '#afbfad' },
+      data: [],
+      ...item,
+    }
+  ]
+
+  series.forEach((seriesItem) => {
+    const field = seriesItem.filed;
+    seriesItem.data = list.map((listItem) => parseFloat(listItem[field])); 
+  });
+  
+  const options = {
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'shadow'
+      }
+    },
+    legend: { 
+      data: series.map(item => item.name)
+    },
+    grid: {
+      top: '40px',
+      left: '80px',
+      right: '80px',
+      bottom: '50px'
+    },
+    xAxis: [
+      {
+        type: 'category',
+        data: xAxisData,
+        axisLabel: {
+          formatter: function (value) {
+            return value.replace(/(.{7})/g, '\$1\n');
+          },
+          rotate: 20
+        }
+      }
+    ],
+    yAxis: [
+      {
+        type: 'value'
+      }
+    ],
+    series
+  }
+
+  return options
+}

+ 378 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/project/financeComponents/incomeDetail.vue

@@ -0,0 +1,378 @@
+<template>
+  <div class="incomeDetail w-full h-full">
+    <!-- 头部 -->
+    <div class="incomeDetail-header flex-center">
+      <div class="item-center">
+        <i class="fa fa-align-justify" @click.prevent="switchMenu" style="cursor: pointer" />
+        <div class="m-lr">选择月份</div>
+        <el-date-picker size="small" v-model="selectMonth" :editable="false" format="yyyy-MM" value-format="yyyy-MM"
+          @change="retrieveDataAgain" :clearable="false" type="month" placeholder="选择月份" />
+      </div>
+      <div class="item-center">
+        <el-link type="primary" :underline="false" class="ml" @click="bonusDataExport">数据导出</el-link>
+        <el-link type="primary" :underline="false" class="ml" @click="clickOnFundingData">数据上传</el-link>
+        <el-link type="primary" :underline="false" class="ml" href="./upload/员工奖金模板.xlsx"
+          :download="'员工奖金模板' + '.xlsx'">模板下载</el-link>
+      </div>
+    </div>
+    <!-- 表格 -->
+    <div class="incomeDetail-table">
+      <el-table :data="tableList" highlight-current-row v-loading="tableListLoading" ref="tableListRef"
+        @selection-change="deleteSel" :height="300" style="width: 100%;">
+        <el-table-column type="selection" width="80" fixed="left"></el-table-column>
+        <el-table-column prop="jobNumber" label="工号"></el-table-column>
+        <el-table-column prop="userName" label="姓名"></el-table-column>
+        <el-table-column prop="bonusType" label="奖金类型"></el-table-column>
+        <el-table-column prop="totalBonusValue" label="奖金金额(元)"></el-table-column>
+        <el-table-column prop="name" label="分摊月份">
+          <template slot-scope="scope">
+            {{ scope.row.startYM }} - {{ scope.row.endYM }}
+          </template>
+        </el-table-column>
+      </el-table>
+      <div style="padding: 10px 14px;">
+        <el-button size="mini" type="primary" :disabled="deleteSelList.length == 0"
+          @click="batchDeletion">批量删除</el-button>
+      </div>
+    </div>
+    <!-- 图表 -->
+    <div class="incomeDetail-echart flex-1">
+      <!-- echarts 图 -->
+      <div class="incomeDetail-echart-echart flex-1" v-loading="echartsLoading">
+        <div id="clearfix" class="echarts-com w-full h-full">
+          <div id="containerEcharts" class="w-full h-full"></div>
+        </div>
+      </div>
+    </div>
+
+    <!-- 资金数据导入 -->
+    <el-dialog title="资金数据导入" v-if="fundsImportIntoVisable" :visible.sync="fundsImportIntoVisable"
+      customClass="customWidth" width="500px">
+      <div class="importOfFundDataClass">
+        <el-form ref="form" label-width="100px">
+          <el-form-item label="分摊月份">
+            <el-date-picker v-model="sharingMonths" type="monthrange" value-format="yyyy-MM" range-separator="至"
+              start-placeholder="开始月份" end-placeholder="结束月份" :size="'small'" :picker-options="pickerOptions"
+              @change="sharingMonthsChange">
+            </el-date-picker>
+          </el-form-item>
+          <el-form-item label="奖金类型">
+            <el-cascader v-model="typeOfFundsValue" :options="typeOfFundsArray" :props="{ expandTrigger: 'hover' }"
+              :size="'small'" :show-all-levels="false"></el-cascader>
+          </el-form-item>
+          <el-form-item label="导入模板">
+            <el-upload class="upload-demo" :limit="1" :http-request="fundUpload" :size="'small'">
+              <el-button size="small" type="primary" :size="'small'">点击上传</el-button>
+            </el-upload>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitFunds()" :loading="dataImportLoading">{{ $t('btn.determine')
+          }}</el-button>
+      </span>
+    </el-dialog>
+
+    <!-- 数据导出 -->
+    <el-dialog title="数据导出" v-if="dataExportVisable" :visible.sync="dataExportVisable" customClass="customWidth"
+      width="500px">
+      <div class="importOfFundDataClass">
+        <el-form ref="form" label-width="100px">
+          <el-form-item label="导出年份">
+            <el-date-picker v-model="selectYear" type="year" value-format="yyyy" :size="'small'">
+            </el-date-picker>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitExport()" :loading="dataExportLoading">导出</el-button>
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import dayjs from 'dayjs';
+import { fundCascadingPanel, processingChartOptions } from './common'
+export default {
+  components: {},
+  data() {
+    return {
+      user: JSON.parse(sessionStorage.getItem("user")),
+      permissions: JSON.parse(sessionStorage.getItem("permissions")),
+      selectMonth: dayjs().format('YYYY-MM'),
+      selectYear: dayjs().format('YYYY'),
+      typeOfFundsValue: '',
+      deleteSelList: [],
+      missingFinanceUserList: [],
+      sharingMonths: [],
+      sharingMonthsTwo: [],
+      tableList: [],
+      tableListLoading: false,
+      echartsLoading: false,
+      dataExportLoading: false,
+      dataImportLoading: false,
+      showMissingDialog: false,
+      fundsImportIntoVisable: false,
+      dataExportVisable: false,
+      typeOfFundsArray: fundCascadingPanel,
+      pickerOptions: {
+        disabledDate(time) {
+          return time.getFullYear() > dayjs().format('YYYY');
+        }
+      },
+      importTemplateData: null,
+      echartsData: [],
+      myChart: null,
+    };
+  },
+  mounted() {
+    this.retrieveDataAgain()
+    this.scrollFunction()
+  },
+  methods: {
+    retrieveDataAgain() {
+      this.getEchartsData()
+      this.getTableList()
+    },
+    submitExport() {
+      this.http.downloadFile('/contractBonusDetail/exportContractBonus', {
+        year: this.selectYear
+      }, '奖金项目分摊.xlsx', err => {
+        this.$message({
+          message: err,
+          type: 'error'
+        })
+      })
+    },
+    bonusDataExport() {
+      this.selectYear = dayjs().format('YYYY')
+      this.dataExportVisable = true
+    },
+    batchDeletion() {
+      this.$confirm(this.$t(this.$t('doyouwanttodeleteit')), this.$t('other.prompts'), {
+        confirmButtonText: this.$t('btn.determine'),
+        cancelButtonText: this.$t('btn.cancel'),
+        type: 'warning'
+      }).then(() => {
+        const ids = this.deleteSelList.map(item => item.id).join(',')
+        this.postData(`/contractBonusSummary/deleteBonusSummary`, { ids }).then((res) => {
+          this.$message.success('操作成功')
+          this.retrieveDataAgain()
+        })
+      })
+    },
+    sharingMonthsChange(val) {
+      const startData = val[0]
+      const endData = val[1]
+      const dateDetermination = dayjs(startData).isSame(dayjs(endData), 'year');
+      if (!dateDetermination) {
+        this.sharingMonths = JSON.parse(JSON.stringify(this.sharingMonthsTwo))
+        this.$message.warning('请选择同一年的月份')
+        return
+      }
+      this.sharingMonthsTwo = JSON.parse(JSON.stringify(val))
+    },
+    submitFunds() {
+      if (!this.typeOfFundsValue || this.typeOfFundsValue.length == 0) {
+        this.$message.warning('请选择奖金类型')
+        return
+      }
+      if (!this.importTemplateData) {
+        this.$message.warning('请选择导入模板')
+        return
+      }
+      let formData = new FormData();
+      formData.append("startYM", this.sharingMonths[0]);
+      formData.append("endYM", this.sharingMonths[1]);
+      formData.append("bonusType", this.typeOfFundsValue[this.typeOfFundsValue.length - 1]);
+      formData.append("file", this.importTemplateData);
+      this.dataImportLoading = true
+      this.http.uploadFile('/contractBonusDetail/transTemplateData', formData,
+        res => {
+          this.dataImportLoading = false
+          if (res.code == 'ok') {
+            this.fundsImportIntoVisable = false
+            this.$message({
+              message: '操作成功',
+              type: 'success'
+            })
+            this.retrieveDataAgain()
+          } else {
+            this.$message({
+              message: res.msg,
+              type: 'error'
+            })
+          }
+        }, error => {
+          this.dataImportLoading = false
+          this.$message({
+            message: error,
+            type: 'error'
+          })
+        })
+    },
+    fundUpload(file) {
+      this.importTemplateData = file.file
+    },
+    clickOnFundingData() {
+      this.typeOfFundsValue = ''
+      this.sharingMonths = [dayjs().format('YYYY-MM'), dayjs().format('YYYY-MM')]
+      this.importTemplateData = null
+      this.fundsImportIntoVisable = true
+    },
+    getTableList() {
+      this.tableListLoading = true
+      this.postData(`/contractBonusSummary/getBonusSummary`, { ym: this.selectMonth }).then((res) => {
+        this.tableList = res.data || []
+      }).finally(() => {
+        this.tableListLoading = false
+      })
+    },
+    getEchartsData() {
+      this.echartsLoading = true
+      this.postData(`/contractBonusDetail/getContractBonus`, { year: dayjs(this.selectMonth).format('YYYY') }).then(res => {
+        // this.echartsData = res.data || []
+        this.instantiateChart(res.data || [])
+      }).finally(() => {
+        this.echartsLoading = false
+      })
+    },
+    instantiateChart(list = []) {
+      const listNew = [...list]
+      if (this.myChart) {
+        this.myChart.dispose();
+        this.myChart = null
+      }
+      this.myChart = echarts.init(document.getElementById("containerEcharts"));
+      const option = processingChartOptions(listNew)
+      // 设置图表
+      this.myChart.resize({
+        // width: this.widthHtval
+      })
+
+      this.myChart.setOption(option, { notMerge: true });
+    },
+    deleteSel(sel) {
+      this.deleteSelList = sel
+    },
+    // 左右滚动
+    scrollFunction() {
+      this.domObj = document.getElementById('clearfix') // 通过id获取要设置的div
+      if (this.domObj.attachEvent) { // IE
+        this.domObj.attachEvent('onmousewheel', this.mouseScroll)
+      } else if (this.domObj.addEventListener) {
+        this.domObj.addEventListener('DOMMouseScroll', this.mouseScroll, false)
+      }
+      this.domObj.onmousewheel = this.domObj.onmousewheel = this.mouseScroll
+    },
+    mouseScroll(event) { // google 浏览器下
+      let detail = event.wheelDelta || event.detail
+      let moveForwardStep = -1
+      let moveBackStep = 1
+      let step = 0
+      step = detail > 0 ? moveForwardStep * 100 : moveBackStep * 100
+      event.preventDefault() // 阻止浏览器默认事件
+      this.domObj.scrollLeft = this.domObj.scrollLeft + step
+    },
+    switchMenu() {
+      this.$emit("switchMenu");
+    },
+    destroyChart() {
+      if (this.myChart) {
+        this.myChart.dispose();
+        this.myChart = null;
+      }
+    },
+    async postData(urls, param) {
+      return new Promise((resolve, reject) => {
+        this.http.post(urls, { ...param },
+          res => {
+            if (res.code == 'ok') {
+              resolve(res)
+            } else {
+              this.$message({
+                message: res.msg,
+                type: 'error'
+              })
+              reject(res)
+            }
+            resolve(res)
+          },
+          error => {
+            this.$message({
+              message: error,
+              type: "error"
+            });
+            reject(error)
+          }
+        )
+      });
+    },
+  },
+  beforeDestroy() {
+    this.destroyChart();
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.incomeDetail {
+  color: #606266;
+  position: relative;
+  display: flex;
+  flex-direction: column;
+
+  .incomeDetail-header {
+    height: 40px;
+    background: #f2f2f2;
+    padding: 10px;
+
+    .incomeDetail-header-const {
+      width: 440px;
+    }
+  }
+
+  .incomeDetail-echart {
+    display: flex;
+    flex-direction: column;
+    padding: 8px;
+
+    .echarts-com {
+      overflow-x: auto;
+      position: relative;
+    }
+  }
+}
+
+.flex-1 {
+  flex: 1;
+}
+
+.ml {
+  margin-left: 14px;
+}
+
+.m-lr {
+  margin: 0 12px;
+}
+
+.item-center {
+  display: flex;
+  align-items: center;
+}
+
+.flex-center {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.w-full {
+  width: 100%;
+}
+
+.h-full {
+  height: 100%;
+}
+</style>

文件差異過大導致無法顯示
+ 2175 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/project/financeComponents/salaryDetails.vue


文件差異過大導致無法顯示
+ 173 - 61
fhKeeper/formulahousekeeper/timesheet/src/views/settings/timetype.vue


+ 31 - 7
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

@@ -325,6 +325,9 @@
                                                             <p style="display: inline-block;">{{$t('time.duration')}}:
                                                                 <span v-if="item2.reportTimeType == 2" style="margin-right:10px;">{{timeItem.startTime+'-'+timeItem.endTime}}</span>
                                                             {{timeItem.time.toFixed(1)}}h  
+                                                            <span v-if="timeItem.detail" style="margin-left:10px;">细项:
+                                                                {{timeItem.detail}}
+                                                            </span>
                                                             </p>
                                                             <p>{{$t('other.matters')}}:<span v-html="timeItem.content"></span></p>
                                                         </div>
@@ -764,11 +767,6 @@
                                 <el-select v-model="domain.projectId" :placeholder="$t('defaultText.pleaseSelectSnItem')" style="width:200px;" clearable="true"  filterable="true" value-key="id"
                                 @change="selectProject(domain, index)"
                                 :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)" popper-class="projectSelectPopperClass">
-                                    <!-- <el-option v-for="item in fillProjectList" :disabled="item.status!=1 && item.status!=4" :key="item.id" :label="item.projectName + '\u3000' + item.projectCode" :value="item.id">
-                                        <span style="float: left; color: #8492a6; font-size: 13px;">{{ item.projectCode }}</span>
-                                        <span style="float: right;">{{ item.projectName }}</span>
-                                    </el-option> -->
-
                                     <el-option-group v-for="group in integrationProjectList" :key="group.label" :label="group.label">
                                         <el-option v-for="item in group.peojectList" :key="item.id" :label="item.projectName + '\u3000' + item.projectCode" :value="item.id" :disabled="item.status!=1 && item.status!=4">
                                             <span style="float: left; color: #8492a6; font-size: 13px;">{{ item.projectCode }}</span>
@@ -913,6 +911,11 @@
                                     @change="iptChangs()">
                                 </el-time-picker>
                                 </span>
+                                <!--工作细项-->
+                                <el-select v-model="timeItem.detail" :placeholder="$t('defaultText.pleaseChoose')" style="width:200px;margin-left:10px;" filterable="true" v-if="multiOptionData.length>0"
+                                    :disabled="workForm.domains.length==0?true:(workForm.domains[index].state>=2?false:true)">
+                                    <el-option v-for="item in multiOptionData" :key="item.value" :label="item.value" :value="item.value"></el-option>
+                                </el-select>
                             </el-form-item>
                             <el-form-item :label="$t('other.workMatters')" :prop="'domains.' + index + '.worktimeList.'+tIndex+'.content'" 
                             :rules="user.timeType.workContentState == 1 ? { required: true, message: $t('other.tianworkMatters'), trigger: 'blur' } : null">
@@ -2617,8 +2620,8 @@
                 isReminder:true,
                 reportLogCheckDialog:false,
                 deptIdForHasReport:[],
-
-                transferWorkingHoursVisable: false
+                transferWorkingHoursVisable: false,
+                multiOptionData:[],
             };
         },
         watch: {
@@ -2671,6 +2674,7 @@
             this.scrollFunction()
             this.userssHu();
             this.getFirstAndLastDay()
+            this.getMultiOptionData();
             if(this.user.timeType.reportAuditType == 3){
                 this.getAllUsersList()
             }
@@ -2730,6 +2734,26 @@
                     
                 }
             },
+            getMultiOptionData() {
+                this.http.post('/company-dict/getAll ',{companyId: this.user.companyId, code: 'multiOption'},
+                res => {
+                    if (res.code == "ok") {
+                        this.multiOptionData = res.data;
+                    } else {
+                        this.$message({
+                            message: res.msg,
+                            type: "error"
+                        });
+                    }
+                },
+                error => {
+                    this.$message({
+                        message: error,
+                        type: "error"
+                    });
+                    }
+                );
+            },
             showReportTimeLessThanCardTimeList() {
                 this.monthTotalPage = 0,
                 this.tbload = true,

+ 0 - 45
fhKeeper/formulahousekeeper/timesheet_h5/src/utils/appidConfiguration.js

@@ -1,45 +0,0 @@
-/**
- * 各个公司企业微信的配置, 根据域名来解析
- * @path 完整域名
- * @appId 企业微信的appId,针对私有化部署的情况appId就是corpId
- */
-const config = {
-  "mobworktime.ttkuaiban.com": {
-    // 工时管家 
-    path: "http://mobworktime.ttkuaiban.com",
-    appId: "ww4e237fd6abb635af",
-    agentId: "",
-  },
-  "moblue.blovelight.net": {
-    // 蓝光研发 
-    path: "http://moblue.blovelight.net:2021",
-    appId: "wwb12ec40df8c35139",
-    agentId: "1000075",
-  },
-  "mobprivatewx.ttkuaiban.com": {
-    // 火石闪信-企业微信私有化 
-    path: "http://mobprivatewx.ttkuaiban.com",
-    appId: "wwf11426cf618e1703",
-    agentId: "1000069",
-  },
-};
-
-const fixedPath = `/api/corpWXAuth`; // 授权回调页面 (需要拼接)
-const fixedPathAgentId = `/api/corpInsideWXAuth`
-
-export function obtainCorrespondingConfigurationInformation() {
-  const hostname = window.location.hostname; // 获取域名和端口,(不包括http 和 https)
-  const row = config[hostname];
-  const agentId = row.agentId;
-  const appId = row.appId;
-  const tokenUrl = `${row.path}${fixedPath}`;
-  const tokenUrlAgentId = `${row.path}${fixedPathAgentId}`;
-  const authorizationCallback = agentId
-    ? `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${encodeURI(tokenUrlAgentId)}&response_type=code&scope=snsapi_base&state=0&agentid=${agentId}#wechat_redirect`
-    : `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${encodeURI(tokenUrl)}&response_type=code&scope=snsapi_base&state=1#wechat_redirect`;
-  return {
-    appId,
-    tokenUrl,
-    authorizationCallback,
-  };
-}

+ 34 - 4
fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue

@@ -396,7 +396,15 @@
                                 :value="timeItem.endTime" label="结束时间" placeholder="点击选择时间"
                                 :rules="[{ required: true, message: '必填项' }]"
                                 @click="item.canEdit ? showEndDialog(timeItem) : ''" />
-
+                            <van-field v-if="multiOptionData.length>0" readonly :clickable="canEdit" name="multiTimePicker"
+                                :value="timeItem.detail" label="细项" placeholder="点击选择"
+                                :rules="[{ required: true, message: '必填项' }]"
+                                @click="item.canEdit ? showChooseDetail(timeItem) : ''" />
+                            <!-- 工作细项, 美莱德 -->
+                            <van-popup v-model="showMultiOpPicker" position="bottom">
+                                                        <van-picker show-toolbar :columns="multiOptionData" :default-index="1" @confirm="choseMultiOptionPick"
+                                                            @cancel="showMultiOpPicker = false" />
+                                                    </van-popup>
                             <van-field class="form_input" :disabled="!item.canEdit"
                                 style="color:#333;-webkit-text-fill-color:#646566;" v-model="timeItem.content"
                                 name="content" type="textarea" label="工作事项" placeholder="请输入工作事项"
@@ -646,7 +654,7 @@ export default {
             },
             project: [],
             report: {},
-
+            showMultiOpPicker: false,
             loading: false,
             finished: false,
             // isOvertime: false
@@ -659,7 +667,7 @@ export default {
             flgLg: true,
             reportBasecostList: [],
             isWeekend: false,
-
+            multiOptionData:[],
             auditorShow: false,
             auditor: {
                 index: 0,
@@ -1097,6 +1105,14 @@ export default {
                     this.$forceUpdate();
                 }).catch(err => { this.$toast.clear(); });
         },
+        showChooseDetail(timeItem) {
+            this.curWorktime = timeItem;
+            this.showMultiOpPicker=true;
+        },
+        choseMultiOptionPick(value) {
+            this.curWorktime.detail = value;
+            this.showMultiOpPicker = false;
+        },
         showEndDialog(timeItem) {
             this.curWorktime = timeItem;
             this.showWorkEndTime = true;
@@ -1280,6 +1296,7 @@ export default {
             }
             this.setTotalReportHours()
         },
+        
 
         confirmTime(item, field, index) {
             if (field == 0) {
@@ -1447,6 +1464,18 @@ export default {
                 }).catch(err => { this.$toast.clear(); });
             }
         },
+        getMultiOptionData() {
+            this.$axios.post('/company-dict/getAll', { companyId: this.user.companyId,code: 'multiOption' })
+                .then(res => {
+                    if (res.code == "ok") {
+                        var list = res.data;
+                        this.multiOptionData = [];
+                        for (var i in list) {
+                            this.multiOptionData.push(list[i].value);
+                        }
+                    } 
+                }).catch(err => { this.$toast.clear(); });
+        },
         getTimeType() {
             this.$axios.post('/time-type/getCompanyTimeSetting', { companyId: this.user.companyId })
                 .then(res => {
@@ -2866,7 +2895,7 @@ export default {
         
         this.getAllUsersList()
         this.getTimeType();
-
+        this.getMultiOptionData();
         //初始化微信js-sdk参数
         if (this.isCorpWX) {
             this.initWxConfig();
@@ -2881,6 +2910,7 @@ export default {
         if(this.user.timeType.userWithMultiDept) {
             this.getReportDeptList()
         }
+
     },
     beforeDestroy() {
         localStorage.removeItem('formVal')

+ 6 - 8
fhKeeper/formulahousekeeper/timesheet_h5/src/views/login/index.vue

@@ -17,8 +17,7 @@
 
 <script>
     import { constants } from "crypto";
-    import * as dd from 'dingtalk-jsapi'; 
-    import { obtainCorrespondingConfigurationInformation } from '../../utils/appidConfiguration';
+    import * as dd from 'dingtalk-jsapi';
     export default {
         data() {
             return {
@@ -166,18 +165,17 @@
                 }
             },
             tryAutoLogin() {
-                const rowConfig = obtainCorrespondingConfigurationInformation()
                 var appId = "wx749c84daac654e1e";//工时管家公众号
                 var url = "http://mobworktime.ttkuaiban.com/api/wechat/loginByWXCode";//工时管家公众号授权回调页面
-                // if (this.isCorpWX) {
-                    // appId = "ww4e237fd6abb635af"; //企业微信第三方的SUIT ID
-                    // url = "http://worktime.ttkuaiban.com/api/corpWXAuth";//授权回调页面
-                // } 
+                if (this.isCorpWX) {
+                    appId = "ww4e237fd6abb635af"; //企业微信第三方的SUIT ID
+                    url = "http://worktime.ttkuaiban.com/api/corpWXAuth";//授权回调页面
+                } 
 
                 // var appId = "ww4e237fd6abb635af";//企业微信第三方的SUIT ID
                 // var url = "http://worktime.ttkuaiban.com/api/corpWXAuth";//授权回调页面
                 
-                var weixinUrl = this.isCorpWX ? rowConfig.authorizationCallback : "https://open.weixin.qq.com/connect/oauth2/authorize?appid="+appId+"&redirect_uri="+encodeURI(url)+"&response_type=code&scope=snsapi_base&state=0#wechat_redirect";
+                var weixinUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="+appId+"&redirect_uri="+encodeURI(url)+"&response_type=code&scope=snsapi_base&state=0#wechat_redirect";
                 window.location.href = weixinUrl;
             },
             tryDingDingUrlRedirect() {

+ 2 - 1
fhKeeper/formulahousekeeper/timesheet_h5/src/views/view/index.vue

@@ -176,7 +176,8 @@
                                         <div class="project_time">时长:
                                             <!-- <span v-if="timeItem.reportTimeType == 0" style="margin-right:10px;">{{fullDayTxt[item1.timeType]}}</span> -->
                                             <span style="margin-right:10px;">{{ timeItem.startTime + '-' + timeItem.endTime
-                                            }}</span>{{ timeItem.time.toFixed(1) }}h
+                                            }}</span>{{ timeItem.time.toFixed(1) }}h 
+                                            <span style="margin-left:5px;" v-if="timeItem.detail">{{ timeItem.detail }}</span>
                                         </div>
                                         <div class="project_content">事项:<span v-html="timeItem.content"></span></div>
                                     </div>

+ 10 - 10
fhKeeper/formulahousekeeper/timesheet_h5/vue.config.js

@@ -5,19 +5,19 @@ const themePath = path.resolve(__dirname,'src/assets/style/theme.less');
 const Timestamp = new Date().getTime();
 
 // var ip = '47.101.180.183'
-var ip = '47.100.37.243'
+// var ip = '47.100.37.243'
 // var ip = '192.168.2.8'
 // var ip = '127.0.0.1'
 
-// var os = require('os'), ip = '', ifaces = os.networkInterfaces() // 获取本机ip
-// for (var i in ifaces) {
-//     for (var j in ifaces[i]) {
-//         var val = ifaces[i][j]
-//         if (val.family === 'IPv4' && val.address !== '127.0.0.1') {
-//             ip = val.address
-//         }
-//     }
-// }
+var os = require('os'), ip = '', ifaces = os.networkInterfaces() // 获取本机ip
+for (var i in ifaces) {
+    for (var j in ifaces[i]) {
+        var val = ifaces[i][j]
+        if (val.family === 'IPv4' && val.address !== '127.0.0.1') {
+            ip = val.address
+        }
+    }
+}
 
 module.exports = {
     runtimeCompiler: true,