Giter Club home page Giter Club logo

dingtalk-app-server's Issues

实体类的属性是一个List (OneToMany关系), 前端如何将数据一次性传给后端

如下,一个Application包含多个AcItem。前端如何一次性将这一对多的关系提交?

public class Application {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private int month;
    private int week;
    private int DC;
    private boolean isCheck;   // 是否已审核
    @Column(columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP", updatable = false, insertable = false)
    private LocalDateTime insertTime;   //插入时间

    @ManyToOne
    private User applicant;    // 申请人
    @ManyToOne
    private User auditor;      // 审核人


    @OneToMany(mappedBy = "application")
    private List<AcItem> acItems;  //本次绩效申请包含的 AC申请
}
public class AcItem {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private int AC;
    private String reason;

    @ManyToOne
    private Application application;  //ac申请属于的周绩效申请
}

更新ac_record的sql语句

select ac_record_id FROM paper_detail WHERE paper_id = 6

select * FROM ac_record ac RIGHT JOIN (select ac_record_id FROM paper_detail WHERE paper_id = 6) t on ac.id = t.ac_record_id

update ac_record a, (select ac_record_id FROM paper_detail WHERE paper_id = 6) t set a.create_time = '2021-01-15' WHERE a.id = t.ac_record_id

refactor(string append): can concatenate strings using string placeholders

private String voteResultInfo(String title, boolean result, int acceptCnt, int totalCnt) {
return new StringBuilder().append(" #### 投票结果 \n ##### 论文: ").append(title)
.append(" \n 最终结果: ").append(result ? "Accept" : "reject")
.append(" \n Accept: ").append(acceptCnt).append(" 票 \n ")
.append("Reject: ").append(totalCnt - acceptCnt).append(" 票 \n ")
.append("已参与人数: ").append(totalCnt).append("人 \n ").toString();
}

是否需要用 String.format 代替 append(), 性能和可读性的权衡?
https://cowtowncoder.medium.com/measuring-performance-of-java-string-format-or-lack-thereof-2e1c6a13362c

更新投票获得ac原因的SQL

SELECT
	ac_record_id,
	vote_id,
	result AS v_res 
FROM
	vote_detail 
WHERE
	ac_record_id IS NOT NULL


SELECT
	v.id,
	p.title,
	p.result AS p_res 
FROM
	paper p
	LEFT JOIN vote v ON p.vote_id = v.id


SELECT
	title,
	ac_record_id,
	user_id,
	case
		when B.p_res = 4 and A.v_res = 1 or B.p_res = 3 and A.v_res = 0 then
			1
		else 
			0
	END
	as res
FROM
	( SELECT ac_record_id, vote_id, user_id, result AS v_res FROM vote_detail WHERE ac_record_id IS NOT NULL ) A
	INNER JOIN (
	SELECT
		v.id,
		p.title,
		p.result AS p_res 
	FROM
		paper p
		LEFT JOIN vote v ON p.vote_id = v.id 
	) B ON A.vote_id = B.id


UPDATE ac_record a,
(
	SELECT
		title,
		ac_record_id,
	CASE
			
			WHEN B.p_res = 4 
			AND A.v_res = 1 
			OR B.p_res = 3 
			AND A.v_res = 0 THEN
				1 ELSE 0 
			END AS res 
		FROM
			( SELECT ac_record_id, vote_id, user_id, result AS v_res FROM vote_detail WHERE ac_record_id IS NOT NULL ) A
			INNER JOIN (
			SELECT
				v.id,
				p.title,
				p.result AS p_res 
			FROM
				paper p
				LEFT JOIN vote v ON p.vote_id = v.id 
			) B ON A.vote_id = B.id 
		) tmp 
		SET a.reason = if(res = 1, CONCAT('投票预测正确:' , tmp.title ), CONCAT('投票预测错误:' , tmp.title ))
WHERE
	a.id = tmp.ac_record_id

自定义JPA主键生成策略实现保存时允许自定义ID

而在一些场景下,会有自定义主键的需求,比如主键来源于其他第三方系统,这时候我们期望的还是使用第三方系统的主键作为主键以表示同一条数据,这就需要我们能够实现自定义主键生成策略,并且JPA也提供了这样的通道。
参考1

参考2

反序列化时一对多关系循环引用与直接将对象的属性(数组)序列化为List<?>冲突

为了避免序列化Application时出现循环引用,在application类的acItems属性上加上了@JsonIgnore
结果 ApplicationControlleraddApplication方法出现了空指针异常
发现是因为@JsonIgnore导致反序列化时acItems被忽略了,导致acItems为空

#6 的第一个解决方案有问题,还是需要将applicationacItems分开来传给后台,但是可以封装起来

更新预测原因ac 的sql

select ac_record_id, vote_id FROM vote_detail WHERE ac_record_id is not null


SELECT id from vote WHERE external = 0

SELECT v.id, p.title from paper p LEFT JOIN vote v on p.vote_id = v.id 


SELECT * FROM (select ac_record_id, vote_id FROM vote_detail WHERE ac_record_id is not null
) A INNER JOIN (SELECT v.id, p.title from paper p LEFT JOIN vote v on p.vote_id = v.id ) B on A.vote_id = B.id


UPDATE ac_record a, (SELECT * FROM (select ac_record_id, vote_id FROM vote_detail WHERE ac_record_id is not null
) A INNER JOIN (SELECT v.id, p.title from paper p LEFT JOIN vote v on p.vote_id = v.id ) B on A.vote_id = B.id) tmp set a.reason = CONCAT(tmp.title, a.reason) WHERE a.id = tmp.ac_record_id

SELECT v.id, p.title from external_paper p LEFT JOIN vote v on p.vote_id = v.id 


SELECT * FROM (select ac_record_id, vote_id FROM vote_detail WHERE ac_record_id is not null
) A INNER JOIN (SELECT v.id, p.title from external_paper p LEFT JOIN vote v on p.vote_id = v.id ) B on A.vote_id = B.id


UPDATE ac_record a, (SELECT * FROM (select ac_record_id, vote_id FROM vote_detail WHERE ac_record_id is not null
) A INNER JOIN (SELECT v.id, p.title from external_paper p LEFT JOIN vote v on p.vote_id = v.id ) B on A.vote_id = B.id) tmp set a.reason = CONCAT(tmp.title, a.reason) WHERE a.id = tmp.ac_record_id

refactor(VoteService)

注意到用户投一张票,调用一次poll函数,只会在vote_detail表中添加一条记录,不会产生ac_record,这段代码没有必要。

// 删除旧的 acRecord
List<AcRecord> oldAcRecords = Optional.ofNullable(voteDetails).orElse(new ArrayList<>()).stream()
.filter(x -> x.getAcRecord() != null)
.map(x -> x.getAcRecord())
.collect(Collectors.toList());
acRecordRepository.deleteAll(oldAcRecords);

配置内网穿

调用钉钉服务端API需要配置合法IP列表,因为开发环境没有公网IP, 需要进行内网穿透

提醒功能

对学生不利的情况将要出现(扣分……),提前提醒学生规避

  • 投票
  • 绩效填写
  • 周报
  • 通知审核人审核

java.lang.NoClassDefFoundError(第三方依赖jar包的问题)

maven项目通过在pom添加依赖导入本地jar包。项目部署打成 jar包后,运行时会出现java.lang.NoClassDefFoundError, 并且解压jar包发现BOOT-INF/lib下没有之前引入jar包

 <!--添加外部依赖-->
<dependency>
    <groupId>com.dingtalk.open</groupId>
    <artifactId>taobao-sdk-java-auto</artifactId>
    <version>2019.12.05</version>
    <scope>system</scope>
    <systemPath>${basedir}/src/main/resources/lib/taobao-sdk-java-auto.jar</systemPath>
</dependency>

解决方案
我们需要在pom中给springboot的打包插件设置includeSystemScope参数

<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <includeSystemScope>true</includeSystemScope>
                </configuration>
            </plugin>
        </plugins>
</build>

重点在于

<configuration>
    <includeSystemScope>true</includeSystemScope>
</configuration>

refactor(internal_paper, external_paper): Merge into one table

问题:外部论文和内部论文两张表没多大差别,代码冗余。
方案:合成一张表,加个is_external字段,前端增加相应的是否是外部论文的选项,如果不是,扩展必填字段,如果是,直接提交。

绩效报表完善

  • 将每月的AC变动集成到每月的绩效表中
  • 增加专硕科研津贴项:满足某个条件(当月DC > ?)获得 x 元津贴

算法层抽取

将service层中的根据实验室规则算分的逻辑抽取整合成一层,前端做一个单独的管理后台页面,用来动态配置这一层参数(所有硬编码参数改掉,动态配置)。

bug(dc_record): dc summary problem

问题:计算某周dc时没有排除未审核的dc,即没有加上where status <> 0。没出问题是因为未审核的dc记录c值为0

/**
* 获取 dc_record 的指定用户所在日期,周,所有dc值之和(即包括其他审核人审核的dc值)
* @param uid, yearmonth, week
* @return java.lang.Double
* @Date 8:34 PM 1/2/2020
*
**/
@Query(value = "SELECT IFNULL((select sum(dc) from dc_record where applicant_id = :uid and yearmonth = :yearmonth and week = :week), 0)",
nativeQuery = true)
Double getUserWeekTotalDc(@Param("uid") int uid, @Param("yearmonth") int yearmonth, @Param("week") int week);

关于该项目中方法命名的建议

尊敬的开发者:
您好!非常感谢您能抽出宝贵的时间来阅读此Issue,我们是来自西北工业大学软件学院硕士课题组的科研团队,正在进行一项关于Java开源项目中方法(函数)名称一致性检查和建议的科研研究,方法(函数)名称的可读性对开发人员理解代码至关重要,我们在本开源项目中随机选择了一些文件作为我们研发工具DMName的实验验证对象,共发现了以下存在的15个方法(函数)命名问题,原始的建议修改的方法名称是第3列original_name,建议的方法名称为第4列suggest_name::

<style> </style>
path line original_name suggest_name
dingtalk-app-server/src/test/java/com/softeng/dingtalk/service/ApplicationServiceTests.java 93 testSetByAuditor testSetApplicationByAuditor
dingtalk-app-server/src/test/java/com/softeng/dingtalk/service/PaperServiceTest.java 59 testUpdateExternalPaperShouldOk testUpdateExternalPaper
dingtalk-app-server/src/test/java/com/softeng/dingtalk/service/PerformanceServiceTest.java 38 test1 testListDcSummaryData
dingtalk-app-server/src/test/java/com/softeng/dingtalk/DingtalkApplicationTests.java 34 test testEncryptor
dingtalk-app-server/src/test/java/com/softeng/dingtalk/DingtalkApplicationTests.java 39 test2 testAddInternalPaper
dingtalk-app-server/src/main/java/com/softeng/dingtalk/api/BaseApi.java 53 setCORPID setCorpId
dingtalk-app-server/src/main/java/com/softeng/dingtalk/api/BaseApi.java 73 setAGENTID setAgentId
dingtalk-app-server/src/main/java/com/softeng/dingtalk/api/BaseApi.java 78 setDOMAIN setDomain
dingtalk-app-server/src/main/java/com/softeng/dingtalk/api/BaseApi.java 194 sign getSignature
dingtalk-app-server/src/main/java/com/softeng/dingtalk/api/BaseApi.java 214 authentication authSignature
dingtalk-app-server/src/main/java/com/softeng/dingtalk/config/FabricConfig.java 36 FabricConfig configFabric
dingtalk-app-server/src/main/java/com/softeng/dingtalk/entity/AbsentOA.java 45 AbsentOA setAbsentOA
dingtalk-app-server/src/main/java/com/softeng/dingtalk/entity/AcItem.java 45 AcItem setAcItem
dingtalk-app-server/src/main/java/com/softeng/dingtalk/entity/Bug.java 55 Bug setBugId
dingtalk-app-server/src/main/java/com/softeng/dingtalk/entity/BugDetail.java 37 BugDetail setBugDetail

如果您认可或反对上述所涉及的问题和命名建议,可以发邮件([email protected])联系我们或直接在本Issue下回复,我们由衷地希望能够得到您宝贵的意见反馈,期待您的回复!

SQL 提取AC数据

SELECT
	u.NAME AS NAME,
	a.ac,
	a.reason, 
	create_time
FROM
	( SELECT * FROM `user` WHERE is_deleted = 0 ) u
	INNER JOIN ( SELECT * FROM ac_record WHERE create_time > "2020-12-31" and create_time < "2021-02-01") a ON a.user_id = u.id 
ORDER BY
	user_id DESC

refactor(DcRecord): Delete the fields of the table and reconstruct the corresponding code

DcRecord的表字段:id、dvalue、cvalue、dc、ac、status、insert_time、yearmonth、week、weekdate、version、datecode、applicant_id、auditor_id、(ac_items)
重构为:id、dvalue、cvalue、status、insert_time、year_month_week、version、applicant_id、auditor_id
说明:

  1. 删除dc:dc可以在dao层用select dvalue * cvalue as dc ……算出来
  2. 删除ac和ac_items:这功能单独提出来
  3. yearmonth、week、weekdate、datecode由year_month_week替代:yyyyMMww这样的整数应该可以替代这些字段的功能

bug: whether the exception information of repeated voting can be encapsulated into user-friendly info

nju-softeng/dingtalk-app-web#29

缺陷描述:

进入投票页面后,第一次投票,页面没有变化;第二次投票出现异常,但前端异常信息为null, (这里其实是后端 Duplicate entry 'v_id-u_id' for key, 重复投票的异常)

问题分析:

投票后确实发送到后端了,但是前端没有正确切换到投票状态页面,后端异常信息也没提示 ”用户已投票“

  • 前端异常log:
POST http://47.104.103.33:8089/api/vote/52 500 ()
{timestamp: "2021-12-03", status: 500, error: "Internal Server Error", message: "", path: "/api/vote/52"}
  • 后端异常log:
Duplicate entry '52-27' for key 'vote_detail.UK61vpx1woxr2v6exm8a2hxwtgb'
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [vote_detail.UK61vpx1woxr2v6exm8a2hxwtgb]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '52-27' for key 'vote_detail.UK61vpx1woxr2v6exm8a2hxwtgb'
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:117)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
	at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)
	at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1092)
........

Team meeting sign-in solution

  • 组会签到可以通过定位 + 扫二维码的形式实现?
  • 钉钉现有的签到接口是否可以使用?定位精度问题?
  • 这个需求是否太严格,是否增加同学负担,如何销假》

MySQL生成大量测试数据方法

使用存储过程link

实践:
1.创建测试数据库

 create database test charset=utf8;
 use test;

2.创建数据表

CREATE TABLE `dc_record` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `dc` double DEFAULT NULL,
  `insert_time` datetime NOT NULL,
  `week` int(11) DEFAULT NULL,
  `application_id` int(11) DEFAULT NULL,
  `user_id` int(11) DEFAULT NULL,
  `auditor_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=166104 DEFAULT CHARSET=utf8;

3.创建存储过程

CREATE DEFINER=`root`@`localhost` PROCEDURE `insertdata`(IN n int)
BEGIN  
  DECLARE i INT DEFAULT 1;
	DECLARE j INT;
  WHILE (i <= n ) DO
		WHILE (j <= 100) DO
			INSERT into dc_record (application_id, auditor_id, user_id,insert_time, week, dc) VALUES (i, i, j ,now(), 1, FLOOR(RAND() * 100) );
			SET j=j+1;
		END WHILE;
		SET i=i+1;
		SET j = 1;
  END WHILE;
END

后端定义DTO对象

  • 说明:现阶段后端controller层返回值全是Map,而且前端依赖undefined值,即后端返回的Map中没有定义字段,前端依赖了后端这个行为。
  • 要求:后端定义DTO对象,前端修改逻辑

Bug(service.VoteService并发问题)

可能出现并发问题

public Vote createVote(VoteVO voteVO) {
// 判断投票是否已经创建过
if (voteRepository.isExisted(voteVO.getPaperid(), false) != 0) {
throw new ResponseStatusException(HttpStatus.CONFLICT, "慢了一步,投票已经被别人发起了");
}
Vote vote = new Vote(LocalDateTime.now() ,LocalDateTime.of(LocalDate.now(), voteVO.getEndTime()), voteVO.getPaperid());
voteRepository.save(vote);

回收AC 的sql

select * FROM paper_detail WHERE paper_id = 4

select * FROM ac_record ac RIGHT JOIN (select ac_record_id FROM paper_detail WHERE paper_id = 4) t on ac.id = t.ac_record_id

update ac_record a, (select ac_record_id FROM paper_detail WHERE paper_id = 4) t set a.reason = CONCAT('(AC待分配)', a.reason), a.ac = 0  WHERE a.id = t.ac_record_id

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.