Browse Source

知行同德项目构建,利润报表导出功能开发

lfx 1 year ago
parent
commit
bb2e7a61f0

+ 5 - 5
mjava-tianhe/src/main/resources/application-prod.yml

@@ -27,7 +27,7 @@ dingtalk:
   agentId: 2673435445
   appKey: dingozv6fzkpqkiupd3d
   appSecret: bO4AA6ujXj8xgLBJI5pR7ns0vRsHCn8Ng9fTf9WF95HTOlCW0oybYpHsuxXuBPiO
-  corpId: dingcc1b1ffad0d5ca1d
+  corpId: dinga41ec6a58a4911d0f2c783f7214b6d69
   aesKey:
   token:
   operator: ""   # OA管理员账号 [0开头需要转一下字符串]
@@ -39,8 +39,8 @@ aliwork:
 
 # teambition
 teambition:
-  AppID: 659cf4922fefb4a7ec89137b
-  AppSecret: ploT7pyTcEVz91i5IIBZ8Pw7LbrOWPYD
-  TenantId: 655f1512ad7db5a6a70cf7b1                # 管理后台 - 企业xx - 企业ID
+  AppID: 65f92ac8046a09f810107919
+  AppSecret: fy9OcKys3ZMdPnj0jvATrni5LvEn8ksk
+  TenantId: 65b1dca21ab0fa13be993595                # 管理后台 - 企业xx - 企业ID
   OperatorId: 65682c174655a82b4fa04dfe              # 公共账号, 需要有操作权限 [x]
-  ApiHost: https://tb.awinic.com:443/gateway        # 私有部署
+  ApiHost: https://tb.trinasolar.com/gateway        # 私有部署

+ 29 - 0
mjava-tianhe/src/test/java/com.malk.tianhe/TbTest.java

@@ -0,0 +1,29 @@
+package com.malk.tianhe;
+
+import com.alibaba.fastjson.JSONObject;
+import com.malk.service.teambition.TBClient;
+import lombok.extern.slf4j.Slf4j;
+import org.checkerframework.checker.units.qual.A;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@SpringBootTest(classes = Boot.class)
+public class TbTest {
+
+    @Autowired
+    private TBClient tbClient;
+
+    @Test
+    public void test(){
+        List<Map> list = tbClient.idMapQuery("66051b6ad282db9e95feafaa",true);
+        System.out.println(JSONObject.toJSONString(list));
+        List<Map> users = tbClient.userSearch("127515");
+        System.out.println(JSONObject.toJSONString(users));
+    }
+
+}

+ 49 - 0
mjava-zhixingtongde/pom.xml

@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>java-mcli</artifactId>
+        <groupId>com.malk</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>mjava-zhixingtongde</artifactId>
+    <description>知行同德</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.malk</groupId>
+            <artifactId>mjava</artifactId>
+            <version>${mjava.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.1.1.RELEASE</version>
+                <configuration>
+                    <includeSystemScope>true</includeSystemScope>
+                    <!-- 如果没有该配置,devtools不会生效: 打包时关闭 -->
+                    <fork>false</fork>
+                    <!-- 避免中文乱码 -->
+                    <jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
+                </configuration>
+                <!-- 允许生成可运行jar -->
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+        <finalName>${project.artifactId}</finalName>
+    </build>
+
+</project>

+ 36 - 0
mjava-zhixingtongde/src/main/java/com/malk/zhixingtongde/Boot.java

@@ -0,0 +1,36 @@
+package com.malk.zhixingtongde;
+
+import com.querydsl.jpa.impl.JPAQueryFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+
+import javax.persistence.EntityManager;
+
+/**
+ * corp项目: 扫描公共模块
+ * -
+ * 若是无需数据库模块, 配置无效地址也可启动, 引入mjava不支持直接 @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) 配置
+ * 需要配置 jpa.hibernate.ddl-auto 为 none. 标识对表没有任何操作. 若不设置为 none, flyway.enabled 配置会无效, 在没有数库连接情况下程序无法启动
+ */
+@EnableJpaAuditing
+@SpringBootApplication(scanBasePackages = {"com.malk"})
+public class Boot {
+
+    public static void main(String... args) {
+        try {
+            SpringApplication.run(Boot.class, args);
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 让Spring管理JPAQueryFactory [不使用Qualifier详见mjava-Boot]
+     */
+    @Bean
+    public JPAQueryFactory jpaQueryFactory(EntityManager entityManager) {
+        return new JPAQueryFactory(entityManager);
+    }
+}

+ 29 - 0
mjava-zhixingtongde/src/main/java/com/malk/zhixingtongde/controller/ZxtdReportConroller.java

@@ -0,0 +1,29 @@
+package com.malk.zhixingtongde.controller;
+
+import com.malk.server.common.McR;
+import com.malk.zhixingtongde.service.ZxtdReportService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+
+@RestController
+@CrossOrigin
+@RequestMapping("/report")
+public class ZxtdReportConroller {
+
+    @Autowired
+    private ZxtdReportService zxtdReportService;
+
+    @GetMapping("/test")
+    public McR test(){
+       return McR.success();
+    }
+
+    @GetMapping("/exportProfit")
+    public void exportProfit(HttpServletResponse response,String year){
+        zxtdReportService.exportProfit(response,year);
+    }
+
+
+}

+ 34 - 0
mjava-zhixingtongde/src/main/java/com/malk/zhixingtongde/entity/Profit.java

@@ -0,0 +1,34 @@
+package com.malk.zhixingtongde.entity;
+
+import cn.hutool.core.util.NumberUtil;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+public class Profit {
+    private String subject;
+    private String amt1;
+    private String amt2;
+    private String amt3;
+    private String amt4;
+    private String amt5;
+    private String amt6;
+    private String amt7;
+    private String amt8;
+    private String amt9;
+    private String amt10;
+    private String amt11;
+    private String amt12;
+    private String totalAmt;
+
+    public Profit(String subject){
+        this.subject=subject;
+    }
+
+
+    public Profit buildTotal(){
+        this.totalAmt= NumberUtil.add(amt1,amt2,amt3,amt4,amt5,amt6,amt7,amt8,amt9,amt10,amt11,amt12).toString();
+        return this;
+    }
+}

+ 9 - 0
mjava-zhixingtongde/src/main/java/com/malk/zhixingtongde/service/ZxtdReportService.java

@@ -0,0 +1,9 @@
+package com.malk.zhixingtongde.service;
+
+import javax.servlet.http.HttpServletResponse;
+
+public interface ZxtdReportService {
+
+    void exportProfit(HttpServletResponse response,String year);
+
+}

+ 115 - 0
mjava-zhixingtongde/src/main/java/com/malk/zhixingtongde/service/impl/ZxtdReportServiceImpl.java

@@ -0,0 +1,115 @@
+package com.malk.zhixingtongde.service.impl;
+
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.ReflectUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.malk.server.aliwork.YDConf;
+import com.malk.server.aliwork.YDParam;
+import com.malk.service.aliwork.YDClient;
+import com.malk.utils.UtilEnv;
+import com.malk.utils.UtilExcel;
+import com.malk.utils.UtilMap;
+import com.malk.zhixingtongde.entity.Profit;
+import com.malk.zhixingtongde.service.ZxtdReportService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@Service
+public class ZxtdReportServiceImpl implements ZxtdReportService {
+
+    @Autowired
+    private YDClient ydClient;
+
+    private static String[] PROFIT_CLASSIFYS={"收入","销售费用","管理费用","研发费用","财务费用"};
+    private static int[] PROFIT_NUMBERS={15,25,25,25,10};
+
+    String _matchFormUuid(String code) {
+        Map<String, String> formUuid = UtilMap.empty();
+        if (UtilEnv.getActiveProfile().equals(UtilEnv.ENV_PROD)) {
+            formUuid.put("PROFIT", "FORM-32937639BC314882AF45201131EAE4C0YD2L"); // 利润表
+            formUuid.put("DOMAIN", "https://nxcyz4.aliwork.com/"); // 宜搭域名
+        } else {
+            formUuid.put("DOMAIN", "https://nxcyz4.aliwork.com/");
+        }
+        return formUuid.get(code);
+    }
+
+    @Override
+    public void exportProfit(HttpServletResponse response,String year) {
+        // 1.获取宜搭数据
+        List<Profit> dataList=getData(year);
+        UtilExcel.exportListByTemplate(response,dataList, Profit.class, "利润", "Template_profit.xlsx");
+    }
+
+    // 按月获取利润表数据
+    private List<Profit> getData(String year){
+        // 查询宜搭底表数据
+        List<Map> list = (List<Map>) ydClient.queryData(YDParam.builder().formUuid(_matchFormUuid("PROFIT")).searchCondition(
+                JSONObject.toJSONString(UtilMap.map("textField_lqvp89br",year))
+        ).build(), YDConf.FORM_QUERY.retrieve_list).getData();
+        Map<String,Map<String,Profit>> dataMap=new HashMap<>();
+        // 数据预处理(金额数据累加,根据 类型,科目,年月)
+        for (Map map:list){
+            JSONObject formData=JSONObject.parseObject(String.valueOf(map.get("formData")));
+            String classify=formData.getString("textField_lqvp89bt");// 类型
+            String subject=formData.getString("textField_lqvp89bu");// 科目
+            String amt=formData.getString("numberField_lqqhf8yn");// 金额
+            String date=formData.getString("textField_lqvp89br");// 年月 2024-01
+            String month=date.split("-")[1].replaceFirst("^0+(?!$)", "");// 月份(去除前缀0)
+            // 数据累加
+            if(dataMap.containsKey(classify)){
+                Map<String,Profit> classifyMap=dataMap.get(classify);
+                if(classifyMap.containsKey(subject)){
+                    Profit profit=classifyMap.get(subject);
+                    // 获取已有数据
+                    String amtTemp=ReflectUtil.invoke(profit,"getAmt"+month);
+                    ReflectUtil.invoke(profit, "setAmt"+month, NumberUtil.add(amt,amtTemp).toString());
+                    dataMap.get(classify).put(subject, profit);
+                }else{
+                    Profit profit=new Profit(subject);
+                    ReflectUtil.invoke(profit, "setAmt"+month, amt);
+                    dataMap.get(classify).put(subject,profit);
+                }
+            }else{
+                Profit profit=new Profit(subject);
+                ReflectUtil.invoke(profit, "setAmt"+month, amt);
+                Map<String,Profit> classifyMap=new HashMap<>();
+                classifyMap.put(subject,profit);
+                dataMap.put(classify,classifyMap);
+            }
+        }
+        List<Profit> profitList=new ArrayList<>();
+        Profit nullProfit=new Profit();
+        // 根据 类型 处理数据
+        for (int i = 0; i < PROFIT_CLASSIFYS.length; i++) {
+            List<Profit> list1=new ArrayList<>();
+            Profit totalProfit=new Profit(PROFIT_CLASSIFYS[i]+(i==0?"合计":"小计"));
+            if(dataMap.containsKey(PROFIT_CLASSIFYS[i])){
+                for (String str:dataMap.get(PROFIT_CLASSIFYS[i]).keySet()){
+                    list1.add(dataMap.get(PROFIT_CLASSIFYS[i]).get(str).buildTotal());
+                    for (int j = 1; j < 13; j++) {
+                        String amtTemp=ReflectUtil.invoke(dataMap.get(PROFIT_CLASSIFYS[i]).get(str),"getAmt"+j);
+                        String amt=ReflectUtil.invoke(totalProfit,"getAmt"+j);
+                        ReflectUtil.invoke(totalProfit, "setAmt"+j, NumberUtil.add(amt,amtTemp).toString());
+                    }
+                }
+            }
+            // 补充空数据
+            for (int j = list1.size(); j < PROFIT_NUMBERS[i]; j++) {
+                list1.add(nullProfit);
+            }
+            // 添加小计
+            list1.add(totalProfit.buildTotal());
+            profitList.addAll(list1);
+        }
+        return profitList;
+    }
+}

+ 53 - 0
mjava-zhixingtongde/src/main/resources/application-dev.yml

@@ -0,0 +1,53 @@
+# 环境配置
+server:
+  port: 9001
+  servlet:
+    context-path: /api/zxtd
+
+# condition
+spel:
+  scheduling: false        # 定时任务是否执行
+  multiSource: false       # 是否多数据源配置
+
+spring:
+  # database
+  datasource:
+    hikari:
+      connection-init-sql: SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci           # SqlServer, Oracle 无需设置类型
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    username: root
+    password: mu123
+    url: jdbc:mysql://127.0.0.1:3306/mjava?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+  jpa:
+    hibernate:
+      ddl-auto: none      # JPA对表没有任何操作
+    show-sql: true
+    database: MYSQL
+    database-platform: org.hibernate.dialect.MySQL57Dialect
+
+# filepath
+file:
+  path:
+    file: /Users/malk/server/_Tool/var/mjava/tmp/file/
+    image: /Users/malk/server/_Tool/var/mjava/tmp/image/
+    tmp: /Users/malk/server/_Tool/var/mjava/tmp/
+  source:
+    fonts: /Users/malk/server/_Tool/fonts/simsun.ttc
+logging:
+  file:
+    path: /Users/malk/server/_Tool/var/mjava/log
+
+# dingtalk
+dingtalk:
+  agentId: 2673435445
+  appKey: dingozv6fzkpqkiupd3d
+  appSecret: bO4AA6ujXj8xgLBJI5pR7ns0vRsHCn8Ng9fTf9WF95HTOlCW0oybYpHsuxXuBPiO
+  corpId: dingcc1b1ffad0d5ca1d
+  aesKey:
+  token:
+  operator: ""   # OA管理员账号 [0开头需要转一下字符串]
+
+# aliwork
+aliwork:
+  appType: APP_ZL5NE83JE84UUACZDD03
+  systemToken: 3J966U61PPNCA6ROEIX8L8TY6DF33EYW60BKLY

+ 38 - 0
mjava-zhixingtongde/src/main/resources/application-prod.yml

@@ -0,0 +1,38 @@
+# 环境配置
+server:
+  port: 9013
+  servlet:
+    context-path: /api/zxtd
+
+# condition
+spel:
+  scheduling: true        # 定时任务是否执行
+  multiSource: false      # 是否多数据源配置
+
+spring:
+  # database
+  datasource:
+    hikari:
+      connection-init-sql: SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci           # SqlServer, Oracle 无需设置类型
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    username: root
+    password: mu123
+    url: jdbc:mysql://127.0.0.1:3306/mjava?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+  jpa:
+    database: MYSQL
+    database-platform: org.hibernate.dialect.MySQL57Dialect
+
+# dingtalk
+dingtalk:
+  agentId: 2673435445
+  appKey: dingozv6fzkpqkiupd3d
+  appSecret: bO4AA6ujXj8xgLBJI5pR7ns0vRsHCn8Ng9fTf9WF95HTOlCW0oybYpHsuxXuBPiO
+  corpId: ding9400625d56a28e4135c2f4657eb6378f
+  aesKey:
+  token:
+  operator: ""   # OA管理员账号 [0开头需要转一下字符串]
+
+# aliwork
+aliwork:
+  appType: APP_K8EYBJO1GLUWYIXT12DI
+  systemToken: 7C766871QS1GIKQ68SWX0BS71RSZ1LONSB2PLA

BIN
mjava-zhixingtongde/src/main/resources/templates/Template_profit.xlsx


+ 53 - 0
mjava-zhixingtongde/src/test/java/com/milk/zxtd/test.java

@@ -0,0 +1,53 @@
+package com.milk.zxtd;
+
+import cn.hutool.core.util.NumberUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.malk.server.aliwork.YDConf;
+import com.malk.server.aliwork.YDParam;
+import com.malk.server.dingtalk.DDR_New;
+import com.malk.service.aliwork.YDClient;
+import com.malk.utils.UtilEnv;
+import com.malk.utils.UtilMap;
+import com.malk.zhixingtongde.Boot;
+import com.malk.zhixingtongde.entity.Profit;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.MapUtils;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@SpringBootTest(classes = Boot.class)
+public class test {
+
+    @Autowired
+    private YDClient ydClient;
+
+    String _matchFormUuid(String code) {
+        Map<String, String> formUuid = UtilMap.empty();
+        if (UtilEnv.getActiveProfile().equals(UtilEnv.ENV_PROD)) {
+            formUuid.put("PROFIT", "FORM-32937639BC314882AF45201131EAE4C0YD2L"); // 利润表
+            formUuid.put("DOMAIN", "https://nxcyz4.aliwork.com/"); // 宜搭域名
+        } else {
+            formUuid.put("DOMAIN", "https://nxcyz4.aliwork.com/");
+        }
+        return formUuid.get(code);
+    }
+
+    @Test
+    public void test(){
+        List<Map> list = (List<Map>) ydClient.queryData(YDParam.builder().formUuid(_matchFormUuid("PROFIT")).searchCondition(
+                JSONObject.toJSONString(UtilMap.map("textField_lqvp89br","2024")) // 这里需要修改为模糊查询
+        ).build(), YDConf.FORM_QUERY.retrieve_list).getData();
+        for (Map map:list){
+            JSONObject formData=JSONObject.parseObject(String.valueOf(map.get("formData")));
+            System.out.println(JSONObject.toJSONString(formData));
+        }
+    }
+
+}

+ 1 - 0
pom.xml

@@ -13,6 +13,7 @@
         <module>mjava-tianhe</module>
         <module>mjava-kaiyue_yt</module>
         <module>mjava-kaiyue_cd</module>
+        <module>mjava-zhixingtongde</module>
     </modules>
     <packaging>pom</packaging>