Compare commits

...

6 Commits

Author SHA1 Message Date
caixiang
d26600892f mark 2022-07-25 16:58:55 +08:00
caixiang
1477d05a69 Merge branch 'master' of http://git.picaiba.com/CaiXiang/SPC
 Conflicts:
	ym-baisc/src/main/java/com/cnbm/basic/controller/FactoryController.java
	ym-influx/src/main/java/com/cnbm/influx/Main.java
2022-07-21 09:50:48 +08:00
caixiang
f498afd856 mark for pull 2022-07-21 09:50:01 +08:00
caixiang
23b5ce90c9 Merge branch 'yanyang' of http://git.picaiba.com/CaiXiang/SPC 2022-07-20 15:33:46 +08:00
caixiang
2b34011129 mark for pull 2022-07-20 15:33:30 +08:00
caixiang
13020d05c9 新增判读方案 2022-07-15 17:15:42 +08:00
34 changed files with 1876 additions and 121 deletions

View File

@ -16,6 +16,7 @@
<module>ym-schedule-task</module>
<module>ym-influx</module>
<module>ym-quality-planning</module>
<module>ym-process-inspection</module>
</modules>
<packaging>pom</packaging>

View File

@ -73,6 +73,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
"/webjars/**",
"/websocket/**",
"/influx/**",
"/processInspection/**",
"/captcha").anonymous()
// .antMatchers("/testCors").hasAuthority("system:dept:list222")
// 除上面外的所有请求全部需要鉴权认证

View File

@ -2,6 +2,7 @@ package com.cnbm.common.spc.math;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.List;
public class Math {
@ -17,7 +18,7 @@ public class Math {
// }
//8.1 10.6 9.8 9.0 9.4 9.3 10.2 11.7
double[] d = new double[8];
Double[] d = new Double[8];
d[0] = new Double(8.1) ;
d[1] = new Double(10.6);
d[2] = new Double(9.8);
@ -32,12 +33,12 @@ public class Math {
}
//平均值
public static double getMean(double...numbers) {
public static double getMean(Double...numbers) {
return format(getSum(numbers) / numbers.length);
}
//极差
public static double range(double[] in) {
public static double range(Double[] in) {
if (in == null) {
throw new NumberFormatException();
}
@ -51,14 +52,14 @@ public class Math {
//return Mutil.subtract(max, min);
}
public static double format(double value) {
public static double format(Double value) {
DecimalFormat df = new DecimalFormat("0.00");//创建一个df对象传入0.00表示构造一个保留小数点后两位的df对象
df.setRoundingMode(RoundingMode.HALF_UP);//设置规则这里采用的也是四舍五入规则
return Double.parseDouble(df.format(value));//返回value在返回之前使用df对象的格式化方法将数据格式化
}
//方差s^2=[(x1-x)^2 +...(xn-x)^2]/n 或者s^2=[(x1-x)^2 +...(xn-x)^2]/(n-1)
public static double Variance(double[] x) {
public static double Variance(Double[] x) {
int m=x.length;
double sum=0;
for(int i=0;i<m;i++){//求和
@ -72,8 +73,10 @@ public class Math {
return format(dVar/m);
}
//标准差σ=sqrt(s^2)
public static double StandardDiviation(double[] x) {
public static StandardDiviation StandardDiviation(Double[] x) {
int m=x.length;
double sum=0;
for(int i=0;i<m;i++){//求和
@ -84,13 +87,12 @@ public class Math {
for(int i=0;i<m;i++){//求方差
dVar+=(x[i]-dAve)*(x[i]-dAve);
}
return format(java.lang.Math.sqrt(dVar/(m-1)));
return new StandardDiviation(format(java.lang.Math.sqrt(dVar/(m-1))),format(java.lang.Math.sqrt(dVar/(m))));
//return Math.sqrt(dVar/m);
}
//前n项和
public static double getSum(double...numbers) {
public static double getSum(Double...numbers) {
double sum = 0.0;
for (double i : numbers) {

View File

@ -0,0 +1,21 @@
package com.cnbm.common.spc.math;
import lombok.Data;
/**
* @Desc: ""
* @Author: caixiang
* @DATE: 2022/7/25 15:23
*/
@Data
public class StandardDiviation {
//标准差
private Double normal;
//总体标准差
private Double totality;
public StandardDiviation(Double normal, Double totality) {
this.normal = normal;
this.totality = totality;
}
}

View File

@ -0,0 +1,105 @@
/*
* Copyright (c) 2018.
* http://www.ulabcare.com
*/
package com.cnbm.common.vo;
/**
* REST API 错误码
*
* @author jiff
* @date 2018/11/1
* @since 1.0
*/
public enum ApiErrorCode implements IErrorCode {
/**
* 成功
*/
SUCCESSFUL(CODE_SUCCESSFUL, "成功"),
/**
* 失败
*/
FAILED(CODE_FAILED, "失败"),
/**
* 无效的请求参数
*/
//INVALID_PARAMETER(CODE_INVALID_PARAMETER, "无效的请求参数"),
INVALID_PARAMETER(CODE_INVALID_PARAMETER, "Invalid request parameter"),
/**
* 数据未授权
*/
FORBIDDEN_DATA(CODE_FORBIDDEN_DATA, "数据未授权"),
/**
* 用户已存在
*/
USER_EXISTENT(CODE_USER_EXISTENT, "用户已存在"),
/**
* 用户不存在
*/
//USER_NON_EXISTENT(CODE_USER_NON_EXISTENT, "用户不存在"),
USER_NON_EXISTENT(CODE_USER_NON_EXISTENT, "User does not exist"),
/**
* 用户已停用
*/
USER_DISABLED(CODE_FAILED, "用户已停用"),
/**
* 用户不存在或密码错误
*/
USER_NON_EXISTENT_OR_INVALID_PASSWORD(CODE_FAILED, "The user does not exist or the password is wrong"),
//USER_NON_EXISTENT_OR_INVALID_PASSWORD(CODE_FAILED, "用户不存在或密码错误"),
/**
* 密码错误
*/
//INVALID_PASSWORD(CODE_FAILED, "密码错误"),
INVALID_PASSWORD(CODE_FAILED, "Wrong password"),
/**
* 电话号码不能为空
*/
MOBILE_IS_EMPTY(CODE_FAILED, "手机号码不能为空"),
/**
* 用户未登录
*/
UNAUTHORIZED(CODE_UNAUTHORIZED, "用户未登录"),
/**
* 用户未授权
*/
FORBIDDEN(CODE_FORBIDDEN, "用户未授权");
private final int code;
private final String msg;
ApiErrorCode(final int code, final String msg) {
this.code = code;
this.msg = msg;
}
public static ApiErrorCode fromCode(int code) {
ApiErrorCode[] apiErrorCodes = ApiErrorCode.values();
for (ApiErrorCode apiErrorCode : apiErrorCodes) {
if (apiErrorCode.getCode() == code) {
return apiErrorCode;
}
}
return SUCCESSFUL;
}
@Override
public int getCode() {
return code;
}
@Override
public String getMsg() {
return msg;
}
@Override
public String toString() {
return String.format(" ErrorCode:{code=%s, msg=%s} ", code, msg);
}
}

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2018.
* http://www.ulabcare.com
*/
package com.cnbm.common.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
/**
* 公共视图对象
*
* @author jiff
* @date 2018/11/9
* @since 1.0
*/
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Data
@ApiModel("公共视图对象")
public class CommonVo {
/**
* 启用状态:0 停用1启用
*/
@ApiModelProperty(value = "启用状态:0 、停用1、启用", example = "1", position = Integer.MAX_VALUE - 1)
private Integer enabled;
/**
* 备注
*/
@ApiModelProperty(value = "备注", position = Integer.MAX_VALUE - 1)
private String remark;
/**
* 创建人
*/
@ApiModelProperty(value = "创建人", example = "1", position = Integer.MAX_VALUE)
private Long creatorId;
/**
* 创建人姓名
*/
@ApiModelProperty(value = "创建人姓名", example = "ulabcare", position = Integer.MAX_VALUE)
private String creatorName;
/**
* 创建时间
*/
@ApiModelProperty(value = "创建时间", position = Integer.MAX_VALUE)
private LocalDateTime createTime;
/**
* 更新人
*/
@ApiModelProperty(value = "更新人", example = "1", position = Integer.MAX_VALUE)
private Long updaterId;
/**
* 更新人姓名
*/
@ApiModelProperty(value = "更新人姓名", example = "ulabcare", position = Integer.MAX_VALUE)
private String updaterName;
/**
* 更新时间
*/
@ApiModelProperty(value = "更新时间", position = Integer.MAX_VALUE)
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,24 @@
package com.cnbm.common.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* <p>
*
* </P>
*
* @author FanYi
* @date 2020/7/6
* @since 1.0
*/
@ApiModel("字典值对象")
@Data
public class DictDataVo {
@ApiModelProperty("字典编码")
private String code;
@ApiModelProperty("字典名称")
private String name;
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2018.
* http://www.ulabcare.com
*/
package com.cnbm.common.vo;
/**
* api错误码定义
*
* @author jiff
* @date 2018/11/1
* @since 1.0
*/
public interface IErrorCode {
/**
* 成功
*/
int CODE_SUCCESSFUL = 0;
/**
* 失败
*/
int CODE_FAILED = 1;
/**
* 无效的请求参数
*/
int CODE_INVALID_PARAMETER = 2;
/**
* 数据未授权
*/
int CODE_FORBIDDEN_DATA = 9;
/**
* 用户已存在
*/
int CODE_USER_EXISTENT = 10;
/**
* 用户不存在
*/
int CODE_USER_NON_EXISTENT = 11;
/**
* 用户未登录
*/
int CODE_UNAUTHORIZED = 401;
/**
* 用户未授权
*/
int CODE_FORBIDDEN = 403;
/**
* 错误编码0成功 否则失败
*
* @return 错误码0成功 否则失败
*/
int getCode();
/**
* 错误描述
*
* @return 错误描述
*/
String getMsg();
}

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2018.
* http://www.ulabcare.com
*/
package com.cnbm.common.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.List;
/**
* 主键列表对象
*
* @author jiff
* @date 2018/11/14
* @since 1.0
*/
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Data
@Builder
@ApiModel("主键列表视图对象")
public class IdListVo {
@ApiModelProperty(value = "主键列表", required = true, example = "[1]", notes = "根据实际接口返回不同对象的主键列表")
private List<Long> ids;
}

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2018.
* http://www.ulabcare.com
*/
package com.cnbm.common.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 主键对象
*
* @author jiff
* @date 2018/11/7
* @since 1.0
*/
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Data
@Builder
@ApiModel("主键视图对象")
public class IdVo {
@ApiModelProperty(value = "主键", required = true, example = "1", notes = "根据实际接口返回不同对象的主键")
private Long id;
}

View File

@ -0,0 +1,102 @@
/*
* Copyright (c) 2018.
* http://www.ulabcare.com
*/
package com.cnbm.common.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* 处理结果类
*
* @param <T> 返回的数据类型
* @author jiff
* @date 2018/11/7
* @since 1.0
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@ApiModel("处理结果类")
@Accessors
public class R<T> implements Serializable {
@NonNull
@ApiModelProperty(value = "结果码", example = "0")
private int code = IErrorCode.CODE_SUCCESSFUL;
@ApiModelProperty(value = "结果说明", example = "成功")
private String msg;
@ApiModelProperty(value = "业务数据")
private T data;
public R<T> code(int code) {
this.code = code;
return this;
}
public R<T> msg(String msg) {
this.msg = msg;
return this;
}
public R<T> data(T data) {
this.data = data;
return this;
}
public boolean ok() {
return code == IErrorCode.CODE_SUCCESSFUL;
}
public static <T> R<T> failed() {
return failed("系统错误!");
}
public static <T> R<T> failed(String msg) {
return failed(ApiErrorCode.FAILED.getCode(), msg);
}
public static <T> R<T> failed(int code, String msg) {
return failed(code, msg, null);
}
public static <T> R<T> failed(int code, String msg, T data) {
return r(code == ApiErrorCode.SUCCESSFUL.getCode() ? ApiErrorCode.FAILED.getCode() : code, msg, data);
}
public static <T> R<T> failed(IErrorCode errorCode) {
return r(errorCode, null);
}
public static <T> R<T> r(IErrorCode errorCode, T data) {
return r(errorCode.getCode(), errorCode.getMsg(), data);
}
public static <T> R<T> r(int code, String msg, T data) {
return new R<T>().code(code).msg(msg).data(data);
}
public static <T> R<T> unauthorized() {
return failed(ApiErrorCode.UNAUTHORIZED);
}
public static <T> R<T> forbidden() {
return failed(ApiErrorCode.FORBIDDEN);
}
public static <T> R<T> ok(T data) {
return new R<T>().data(data);
}
public static <T> R<T> ok(String msg, T data) {
return new R<T>().msg(msg).data(data);
}
}

View File

@ -0,0 +1,26 @@
package com.cnbm.common.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
*
* </P>
*
* @author FanYi
* @date 2020/7/6
* @since 1.0
*/
@ApiModel("下拉选择列表对象")
@Data
public class SelectVo {
@ApiModelProperty("key值用于传给后端")
private Object k;
@ApiModelProperty("value值用于前端显示")
private Object v;
}

View File

@ -0,0 +1,26 @@
package com.cnbm.common.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
*
* </P>
*
* @author FanYi
* @date 2020/4/28
* @since 1.0
*/
@Data
public class SmsSignCodeVo {
private Long sceneId;
private String signName;
private String templateCode;
private Integer templateType;
private String templateContent;
}

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2018.
* http://www.ulabcare.com
*/
package com.cnbm.common.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 是否对象
*
* @author jiff
* @date 2018/11/11
* @since 1.0
*/
@Data
@Accessors(chain = true)
@Builder
@ApiModel("是否对象")
public class WhetherVo {
@ApiModelProperty(value = "是否true、是false、否", required = true, example = "true")
private Boolean whether;
}

View File

@ -42,7 +42,13 @@
<artifactId>ym-quality-planning</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- <dependency>-->
<dependency>
<groupId>com.cnbm</groupId>
<artifactId>ym-process-inspection</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-actuator-autoconfigure</artifactId>-->
<!-- <version>2.7.0</version>-->

View File

@ -128,6 +128,22 @@ public class SwaggerConfig {
.securitySchemes(Arrays.asList(new ApiKey("token", "token", "header")));
}
@Bean
public Docket processInspectionApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("ym-process-inspection")
.apiInfo(apiInfos("过程检验", "过程检验模块"))
.useDefaultResponseMessages(true)
.forCodeGeneration(false)
.select()
.apis(RequestHandlerSelectors.basePackage("com.cnbm.processInspection"))
.paths(PathSelectors.any())
.build()
.securityContexts(Arrays.asList(securityContext()))
// ApiKey的name需与SecurityReference的reference保持一致
.securitySchemes(Arrays.asList(new ApiKey("token", "token", "header")));
}
/**
* 创建该API的基本信息这些基本信息会展现在文档页面中
* 访问地址http://ip:port/swagger-ui.html

View File

@ -27,7 +27,7 @@ public class CodeGenerator {
@Test
public void test(){
mybatisPlusGenerator(new String[]{"product_type"});
mybatisPlusGenerator(new String[]{"product_features"});
}
public static void mybatisPlusGenerator(String[] include){

View File

@ -2,6 +2,7 @@ package com.cnbm.influx;
import com.cnbm.influx.config.InfluxClient;
import com.cnbm.influx.param.QueryDataParam;
import com.cnbm.influx.param.PageInfo;
import com.cnbm.influx.param.Range;
import com.cnbm.influx.param.Tag;
@ -48,23 +49,23 @@ public class Main {
// InfluxClient.Client.insert(event,"ASProcessCompleteEvent");
Point point = Point.measurement("ASProcessCompleteEvent")
.addTag("transationId", "112311")
.addTag("argName", "argName11")
.addField("argValue", 3D)
.time(Instant.now().toEpochMilli(), WritePrecision.MS);
Point point2 = Point.measurement("ASProcessCompleteEvent")
.addTag("transationId", "222312")
.addTag("argName", "argName11")
.addField("argValue", 4D)
.time(Instant.now().toEpochMilli(), WritePrecision.MS);
List<Point> list = new ArrayList<>();
list.add(point);
list.add(point2);
writeApi.writePoints(list);
// Point point = Point.measurement("ASProcessCompleteEvent")
// .addTag("transationId", "112311")
// .addTag("argName", "argName11")
// .addField("argValue", 3D)
// .time(Instant.now().toEpochMilli(), WritePrecision.MS);
//
//
// Point point2 = Point.measurement("ASProcessCompleteEvent")
// .addTag("transationId", "222312")
// .addTag("argName", "argName11")
// .addField("argValue", 4D)
// .time(Instant.now().toEpochMilli(), WritePrecision.MS);
// List<Point> list = new ArrayList<>();
// list.add(point);
// list.add(point2);
//
// writeApi.writePoints(list);
//todo api.writeMeasurements(WritePrecision.NS, Arrays.asList(new H2OFeetMeasurement("coyote_creek", 15.0D, null, Instant.ofEpochSecond(0, 15)), new H2OFeetMeasurement("coyote_creek", 16.0D, null, Instant.ofEpochSecond(0, 16))));
// List<Event> events = new ArrayList<>();
@ -104,23 +105,24 @@ public class Main {
// }
// String flux = "from(bucket:\"mytest\") |> range(start: -60m)";
// flux += "|> filter(fn: (r) =>\n" +
// " r._measurement == \"ASProcessCompleteEvent\" and \n" +
//// " r._field == \"type\" and \n" + //对应 Field key
// " r.argName == \"arg3\"\n" + //对应 Tags key (Tag 信息无法在FluxRecord 里面获取)
// " )";
// QueryApi queryApi = influxDBClient.getQueryApi();
//
// List<FluxTable> tables = queryApi.query(flux);
// for (FluxTable fluxTable : tables) {
// List<FluxRecord> records = fluxTable.getRecords();
// for (FluxRecord fluxRecord : records) {
// System.out.println("time: "+fluxRecord.getTime() +" key:"+fluxRecord.getField()+" value: " + fluxRecord.getValueByKey("_value")+" measurement: " + fluxRecord.getMeasurement());
//// System.out.println("time: "+fluxRecord.getTime() +" key:"++" value: " + fluxRecord.getValueByKey("_value")+" measurement: " + fluxRecord.getMeasurement());
//
// }
// }
String flux = "from(bucket:\"mytest\") |> range(start: -6000000000000000m)";
flux += "|> filter(fn: (r) =>\n" +
" r._measurement == \"ASProcessCompleteEvent\" and \n" +
// " r._field == \"type\" and \n" + //对应 Field key
" r.argName == \"arg3\"\n" + //对应 Tags key (Tag 信息无法在FluxRecord 里面获取)
" )";
QueryApi queryApi = influxDBClient.getQueryApi();
List<FluxTable> tables = queryApi.query(flux);
for (FluxTable fluxTable : tables) {
List<FluxRecord> records = fluxTable.getRecords();
for (FluxRecord fluxRecord : records) {
Double o = (Double)fluxRecord.getValueByKey("_value");
System.out.println("time: "+fluxRecord.getTime() +" key:"+fluxRecord.getField()+" value: " + fluxRecord.getValueByKey("_value")+" measurement: " + fluxRecord.getMeasurement());
// System.out.println("time: "+fluxRecord.getTime() +" key:"++" value: " + fluxRecord.getValueByKey("_value")+" measurement: " + fluxRecord.getMeasurement());
}
}
// from(bucket: "mytest")

View File

@ -7,20 +7,19 @@ import com.cnbm.influx.param.QueryDataParam;
import com.cnbm.influx.param.Range;
import com.cnbm.influx.param.Tag;
import com.cnbm.influx.template.Event;
import com.influxdb.client.InfluxDBClient;
import com.influxdb.client.domain.WritePrecision;
import com.influxdb.client.write.Point;
import com.influxdb.query.FluxRecord;
import com.influxdb.query.FluxTable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
@RestController
@RequestMapping("/influx")
@ -31,17 +30,20 @@ public class S7DemoController {
@PostMapping("/insertBatch")
public void insertBatch() throws InterruptedException {
List<Event> list = new ArrayList<>();
Random r = new Random();
for(int i=0;i<99;i++){
Thread.sleep(100);
for(int i=0;i<999;i++){
Thread.sleep(10);
Event event = new Event();
event.setTime(Instant.now());
event.setTransationId("asas"+i);
event.setArgName("arg7");
event.setArgValue(new Double(i));
event.setArgName("LTWeight");
Double d = r.nextDouble() * 2.5 + 66;
event.setArgValue(d);
list.add(event);
}
InfluxClient.Client.batchInsert(list,"ASProcessCompleteEventAS");
InfluxClient.Client.batchInsert(list,"Weight");
}
/**

View File

@ -0,0 +1,42 @@
<?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>ym-pass</artifactId>
<groupId>com.cnbm</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ym-process-inspection</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.cnbm</groupId>
<artifactId>ym-influx</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.cnbm</groupId>
<artifactId>ym-baisc</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.cnbm</groupId>
<artifactId>ym-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.cnbm</groupId>
<artifactId>ym-quality-planning</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@ -1,4 +1,4 @@
package com.cnbm.qualityPlanning.constant;
package com.cnbm.processInspection.controlCoefficientConstant;
/**
* @Desc: " "x bar - R" 控制系数 "

View File

@ -1,6 +1,7 @@
package com.cnbm.qualityPlanning.constant;
package com.cnbm.processInspection.controlCoefficientConstant;
/**
* 均值-标准差 控制图 常数系数
* @Desc: " "x bar - s" 控制系数 "
* @Author: caixiang
* @DATE: 2022/6/30 10:44

View File

@ -0,0 +1,70 @@
package com.cnbm.processInspection.controller;
import com.cnbm.basic.dto.UnitDTO;
import com.cnbm.basic.entity.ProductFeatures;
import com.cnbm.common.spc.math.StandardDiviation;
import com.cnbm.common.spc.util.DataUtils;
import com.cnbm.common.utils.Result;
import com.cnbm.common.vo.R;
import com.cnbm.influx.config.InfluxClient;
import com.cnbm.influx.constant.Constant;
import com.cnbm.influx.param.PageInfo;
import com.cnbm.influx.param.QueryDataParam;
import com.cnbm.influx.param.Range;
import com.cnbm.influx.param.Tag;
import com.cnbm.influx.template.Event;
import com.cnbm.processInspection.dto.XbarSGraphData;
import com.cnbm.processInspection.graphAnalyzed.MeanStandardDeviationGraph;
import com.cnbm.qualityPlanning.entity.SpecificationLimit;
import com.influxdb.client.domain.WritePrecision;
import com.influxdb.client.write.Point;
import com.influxdb.query.FluxRecord;
import com.influxdb.query.FluxTable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
@RestController
@RequestMapping("/processInspection")
public class ProcessInspectionController {
private static final Logger logger = LoggerFactory.getLogger(ProcessInspectionController.class);
@PostMapping("/XbarSGraph")
public R<XbarSGraphData> xbarSGraph() throws Exception {
ProductFeatures productFeatures = new ProductFeatures();
productFeatures.setSl(new Float(5));
productFeatures.setUsl(new Float(10));
productFeatures.setLsl(new Float(1));
productFeatures.setName("LTWeight");
productFeatures.setSampleSize(BigDecimal.TEN);
MeanStandardDeviationGraph meanStandardDeviationGraph = new MeanStandardDeviationGraph(productFeatures);
QueryDataParam queryDataParam = new QueryDataParam();
queryDataParam.setMeasurement("Weight");
queryDataParam.setRange(new Range(DataUtils.getBeforeDate(10).toInstant(), Instant.now()));
meanStandardDeviationGraph.initialDate(queryDataParam);
XbarSGraphData xbarSGraphData = new XbarSGraphData(
meanStandardDeviationGraph.getMsdGraphEntity(),
meanStandardDeviationGraph.getXbarCL(),
meanStandardDeviationGraph.getSCL(),
meanStandardDeviationGraph.getSpecificationLimit(),
meanStandardDeviationGraph.getProcessCapacity(),
new StandardDiviation(meanStandardDeviationGraph.getXigma(),meanStandardDeviationGraph.getTotalXigma())
);
return R.ok("成功",xbarSGraphData);
}
}

View File

@ -0,0 +1,45 @@
package com.cnbm.processInspection.dto;
import com.cnbm.common.spc.math.StandardDiviation;
import com.cnbm.processInspection.graphAnalyzed.MSDGraphEntity;
import com.cnbm.qualityPlanning.entity.ControlLimit;
import com.cnbm.qualityPlanning.entity.ProcessCapability;
import com.cnbm.qualityPlanning.entity.SpecificationLimit;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @Desc: ""
* @Author: caixiang
* @DATE: 2022/7/22 14:18
*/
@Data
@ApiModel(value = "均值标准差控制图 结果类")
public class XbarSGraphData {
@ApiModelProperty(value = "控制图list数据")
private MSDGraphEntity msdGraphEntity;
@ApiModelProperty(value = "xbar控制图 控制限")
private ControlLimit XBarCL;
@ApiModelProperty(value = "s控制图 控制限")
private ControlLimit SCL;
@ApiModelProperty(value = "工艺规格限")
private SpecificationLimit SL;
@ApiModelProperty(value = "工序能力")
private ProcessCapability processCapability;
@ApiModelProperty(value = "标准差/总体标准差")
private StandardDiviation standardDiviation;
public XbarSGraphData(MSDGraphEntity msdGraphEntity,ControlLimit xBarCL,ControlLimit sCL,SpecificationLimit sl,ProcessCapability processCapability,StandardDiviation standardDiviation){
this.msdGraphEntity = msdGraphEntity;
this.XBarCL = xBarCL;
this.SCL = sCL;
this.SL = sl;
this.processCapability = processCapability;
this.standardDiviation = standardDiviation;
}
}

View File

@ -0,0 +1,59 @@
package com.cnbm.processInspection.graphAnalyzed;
import com.cnbm.qualityPlanning.entity.XbarSPoint;
import java.util.Date;
import java.util.List;
/**
* @Desc: ""
* @Author: caixiang
* @DATE: 2022/7/21 16:26
*/
public class MSDGraphEntity {
private List<XbarSPoint> list;
private Double xbarbar;
private Double sbar;
private Double Rbar;
public MSDGraphEntity(List<XbarSPoint> list,Double xbarbar,Double sbar,Double Rbar){
this.list = list;
this.Rbar = Rbar;
this.sbar = sbar;
this.xbarbar = xbarbar;
}
public List<XbarSPoint> getList() {
return list;
}
public void setList(List<XbarSPoint> list) {
this.list = list;
}
public Double getXbarbar() {
return xbarbar;
}
public void setXbarbar(Double xbarbar) {
this.xbarbar = xbarbar;
}
public Double getSbar() {
return sbar;
}
public void setSbar(Double sbar) {
this.sbar = sbar;
}
public Double getRbar() {
return Rbar;
}
public void setRbar(Double rbar) {
Rbar = rbar;
}
}

View File

@ -0,0 +1,223 @@
package com.cnbm.processInspection.graphAnalyzed;
import com.cnbm.basic.entity.ProductFeatures;
import com.cnbm.common.spc.math.Math;
import com.cnbm.common.spc.math.StandardDiviation;
import com.cnbm.common.spc.util.DataUtils;
import com.cnbm.common.utils.DateUtils;
import com.cnbm.influx.config.InfluxClient;
import com.cnbm.influx.constant.Constant;
import com.cnbm.influx.param.PageInfo;
import com.cnbm.influx.param.QueryDataParam;
import com.cnbm.influx.param.Range;
import com.cnbm.influx.param.Tag;
import com.cnbm.processInspection.controlCoefficientConstant.XBarSCoefficients;
import com.cnbm.qualityPlanning.entity.ControlLimit;
import com.cnbm.qualityPlanning.entity.ProcessCapability;
import com.cnbm.qualityPlanning.entity.SpecificationLimit;
import com.cnbm.qualityPlanning.entity.XbarSPoint;
import com.influxdb.query.FluxRecord;
import com.influxdb.query.FluxTable;
import lombok.Data;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @Desc: "均值标准差 控制图 , 计算类"
* @Author: caixiang
* @DATE: 2022/7/20 14:26
* 使用方式 先new MeanStandardDeviationGraph 对象 再initialData 初始化数据 再get 控制限
*
* 步骤
* 先读mysql表查询 product_features 先读到 sample_size样本量
* 再依据 influx.argName == mysql.product_feature.name && 时间段 查询所有的 参数数据
* 拿到参数数据后分组 整合成List<Point>,
* 计算控制限
* 计算 母体 \sigma bar{x}
* 计算CPK CPU CPL这些
* 如果配置了判读方案还要 调用 StatisticalControlledTest Function 检验
*
*/
@Data
public class MeanStandardDeviationGraph {
//母体的 μ = xbarbar
private Double miu;
//母体的 xigma 全局计算的;
private Double xigma;
//母体的 xigma 全局计算的;
private Double totalXigma;
private Double sbar;
private Double xbarbar;
private Double as;
private Double bu;
private Double bl;
private Integer sampleSize;
private String argName;
private SpecificationLimit specificationLimit;
private MSDGraphEntity msdGraphEntity;
public MeanStandardDeviationGraph(ProductFeatures productFeatures) throws Exception {
if(productFeatures.getSampleSize()==null || productFeatures.getName()==null){
throw new Exception("ProductFeatures 参数异常");
}
this.argName = productFeatures.getName();
this.sampleSize = productFeatures.getSampleSize().intValue();
this.as = XBarSCoefficients.getAS(sampleSize);
this.bu = XBarSCoefficients.getBU(sampleSize);
this.bl = XBarSCoefficients.getBU(sampleSize);
this.specificationLimit = new SpecificationLimit(
productFeatures.getUsl()==null?null:productFeatures.getUsl(),
productFeatures.getSl()==null?null:productFeatures.getSl(),
productFeatures.getUsl()==null?null:productFeatures.getUsl()
);
}
private Double[] toDoubleArray(Object[] o){
Double[] res= new Double[o.length];
for(int i=0;i<o.length;i++){
res[i] = (Double) o[i];
}
return res;
}
/**
* name : 初始化数据函数
* desc : 从influxdb 里面读取数据然后 加工处理成 我需要的
* 步骤
*
* */
public void initialDate(QueryDataParam queryDataParam){
queryDataParam.setBucket(Constant.bucket);
queryDataParam.setDropedTagName("transationId");
queryDataParam.setTag(new Tag("argName",argName));
queryDataParam.setRange(new Range(DataUtils.getBeforeDate(10).toInstant(), Instant.now()));
List<FluxTable> query = InfluxClient.Client.query(queryDataParam);
//1. 先从fluxdb 里面提取原始数据
List<Double> originData = new ArrayList<>();
for (FluxTable fluxTable : query) {
List<FluxRecord> records = fluxTable.getRecords();
for (FluxRecord fluxRecord : records) {
//因为 传进去的就是Double 类型所以取出来自然而然就是Double
originData.add(Double.parseDouble(fluxRecord.getValueByKey("_value").toString()));
}
}
//2. convert to XbarSPoint
List<List<Double>> doubleListList = DataUtils.fixedGroup(originData, sampleSize);
List<XbarSPoint> list = new ArrayList<>();
List<Double> xbarArray = new ArrayList<>();
List<Double> sArray = new ArrayList<>();
List<Double> rArray = new ArrayList<>();
for(int i=0;i<doubleListList.size();i++){
Double[] doubleList = toDoubleArray(doubleListList.get(i).toArray());
Double xbar = Math.getMean(doubleList);
Double s = Math.StandardDiviation(doubleList).getNormal();
Double r = Math.range(doubleList);
xbarArray.add(xbar);
sArray.add(s);
rArray.add(r);
list.add(new XbarSPoint(
i,
new Double(0),
xbar,
s,
r
)
);
}
//3. 以及一些 控制图的全局参数
Double xbarbar = Math.getMean(toDoubleArray(xbarArray.toArray()));
this.miu = xbarbar;
StandardDiviation standardDiviation =Math.StandardDiviation(toDoubleArray(originData.toArray()));
this.xigma = standardDiviation.getNormal();
this.totalXigma = standardDiviation.getTotality();
Double sbar = Math.getMean(toDoubleArray(sArray.toArray()));
Double rbar = Math.getMean(toDoubleArray(rArray.toArray()));
this.msdGraphEntity = new MSDGraphEntity(list,xbarbar,sbar,rbar);
}
/**
* desc: get Xbar控制图 的控制限
* 注意此函数 要在 initialDate()函数执行之后
* */
public ControlLimit getXbarCL(){
return new ControlLimit(
(as*this.msdGraphEntity.getSbar() + this.msdGraphEntity.getXbarbar()),
this.msdGraphEntity.getXbarbar(),
(this.msdGraphEntity.getXbarbar() - as*this.msdGraphEntity.getSbar())
);
}
/**
* desc: get S控制图 的控制限
* 注意此函数 要在 initialDate()函数执行之后
* */
public ControlLimit getSCL(){
return new ControlLimit(
( bu * this.msdGraphEntity.getSbar() ) ,
this.msdGraphEntity.getSbar() ,
(bl * this.msdGraphEntity.getSbar())
);
}
/**
* desc: get 工序能力
* 注意此函数 要在 initialDate()函数执行之后
* */
public ProcessCapability getProcessCapacity(){
SpecificationLimit sp = this.specificationLimit;
List<String> warming = new ArrayList<>();
Float usl = sp.getUSL();
Float lsl = sp.getLSL();
if(usl==null || lsl==null){
if(usl==null && lsl!=null){
if(this.miu<lsl){
warming.add("平均值已不能满足规范要求, 有相当多数据均为不合格, 则表示完全没有工序能力");
return new ProcessCapability(null,null,null,(double)0,warming);
}
Double cpl = ( (this.miu-lsl) / (3 * this.xigma) );
return new ProcessCapability(null,null,null,cpl,warming);
} else if (lsl == null && usl!=null) {
if(this.miu>usl){
warming.add("平均值已不能满足规范要求, 有相当多数据均为不合格, 则表示完全没有工序能力");
return new ProcessCapability(null,null,(double)0,null,warming);
}
Double cpu = ( (usl-this.miu) / (3 * this.xigma) );
return new ProcessCapability(null,null,cpu,null,warming);
}else {
return new ProcessCapability(null,null,null,null,warming);
}
}
//下面就是 usl lsl 都部位null的情况
Float k1 = usl-lsl;
Float k2 = usl+lsl;
Double cp = ( k1 / (6*this.xigma) );
Double k = ( java.lang.Math.abs( (this.miu-k2/2) ) / (k1/2) );
if(k>1){
warming.add("此工艺参数K 大于1, 说明均值μ已经偏离到规范范围意外,即相当多的工艺参数均不满足规范要求,这说明工艺加工结果很差,该设备根本不适用于批量生产");
}
Double cpk = cp * ( 1- k);
if(cpk<0){
warming.add("Cpk=0该工序完全没有能力 批量生产");
cpk = (double) 0;
}
Double cpu = ( (usl-this.miu) / (3 * this.xigma) );
Double cpl = ( (this.miu-lsl) / (3 * this.xigma) );
return new ProcessCapability(cp,cpk,cpu,cpl,warming);
}
}

View File

@ -1,17 +1,18 @@
package com.cnbm.qualityPlanning.common;
import com.cnbm.qualityPlanning.entity.ControlLimit;
import com.cnbm.qualityPlanning.entity.Point;
import io.swagger.models.auth.In;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import com.cnbm.qualityPlanning.entity.ControlLimit;
import com.cnbm.qualityPlanning.entity.ControlLimitDetail;
import com.cnbm.qualityPlanning.entity.Point;
import com.cnbm.qualityPlanning.entity.XbarSPoint;
import java.util.*;
/**
* @Desc: "检测参数统计受控 检验类"
* @Author: caixiang
* todo 开头第一组和最后一组 是否漏掉 问题 中间情况 时候把最后一个元素漏掉
* @DATE: 2022/7/11 15:27
*/
public class StatisticalControlledTest {
@ -27,18 +28,27 @@ public class StatisticalControlledTest {
private static final Integer rule10Number = 10;
public static List<Point> createData(){
Point point = new Point(1,new Double(1));
Point point2 = new Point(2,new Double(2));
Point point3 = new Point(3,new Double(3));
Point point4 = new Point(4,new Double(4));
Point point5 = new Point(5,new Double(5));
Point point6 = new Point(6,new Double(6));
Point point7 = new Point(7,new Double(7));
Point point8 = new Point(8,new Double(8));
Point point9 = new Point(9,new Double(9));
Point point10 = new Point(10,new Double(10));
Point point11 = new Point(11,new Double(11));
Point point12 = new Point(12,new Double(12));
Point point = new Point(1,new Double(0.7));
Point point2 = new Point(2,new Double(0.7));
Point point3 = new Point(3,new Double(3.7));
Point point4 = new Point(4,new Double(0.7));
Point point5 = new Point(5,new Double(0.7));
Point point6 = new Point(6,new Double(3.7)); //3
Point point7 = new Point(7,new Double(3.7)); //3
Point point8 = new Point(8,new Double(3.7)); //3 //3
Point point9 = new Point(9,new Double(3.7));
Point point10 = new Point(10,new Double(3.7));
Point point11 = new Point(11,new Double(3.7));
Point point12 = new Point(12,new Double(3.7));
Point point13 = new Point(13,new Double(3.7));
Point point14 = new Point(14,new Double(3.7));
Point point15 = new Point(15,new Double(3.7));
Point point16 = new Point(16,new Double(3.7));
Point point17 = new Point(17,new Double(3.7));
Point point18 = new Point(18,new Double(3.7));
Point point19 = new Point(19,new Double(3.7));
Point point20 = new Point(20,new Double(3.7));
List<Point> list = new ArrayList<>();
list.add(point);
list.add(point2);
@ -54,37 +64,123 @@ public class StatisticalControlledTest {
list.add(point12);
return list;
}
public static List<Point> createData2(){
XbarSPoint point = new XbarSPoint(1, new Double(2.5));
XbarSPoint point2 = new XbarSPoint(2, new Double(2.5));
XbarSPoint point3 = new XbarSPoint(3, new Double(2.5));
XbarSPoint point4 = new XbarSPoint(4, new Double(2.5));
XbarSPoint point5 = new XbarSPoint(5, new Double(2.5));
XbarSPoint point6 = new XbarSPoint(6, new Double(2.5));
XbarSPoint point7 = new XbarSPoint(7, new Double(2.5));
XbarSPoint point8 = new XbarSPoint(8, new Double(2));
XbarSPoint point9 = new XbarSPoint(9, new Double(2.5));
XbarSPoint point10 = new XbarSPoint(10, new Double(2.5));
XbarSPoint point11 = new XbarSPoint(11, new Double(2.5));
XbarSPoint point12 = new XbarSPoint(12, new Double(2.5));
XbarSPoint point13 = new XbarSPoint(13,new Double(2.5));
XbarSPoint point14 = new XbarSPoint(14,new Double(2.5));
XbarSPoint point15 = new XbarSPoint(15,new Double(2.5));
XbarSPoint point16 = new XbarSPoint(16,new Double(2));
XbarSPoint point17 = new XbarSPoint(17,new Double(2.5));
XbarSPoint point18 = new XbarSPoint(18,new Double(2.5));
XbarSPoint point19 = new XbarSPoint(19,new Double(2.5));
XbarSPoint point20 = new XbarSPoint(20,new Double(2.5));
XbarSPoint point21 = new XbarSPoint(21,new Double(2.5));
XbarSPoint point22 = new XbarSPoint(22,new Double(2.5));
XbarSPoint point23 = new XbarSPoint(23,new Double(2.5));
List<Point> list = new ArrayList<>();
list.add(point);
list.add(point2);
list.add(point3);
list.add(point4);
list.add(point5);
list.add(point6);
list.add(point7);
list.add(point8);
list.add(point9);
list.add(point10);
list.add(point11);
list.add(point12);
list.add(point13);
list.add(point14);
list.add(point15);
list.add(point16);
list.add(point17);
list.add(point18);
list.add(point19);
list.add(point20);
list.add(point21);
list.add(point22);
list.add(point23);
return list;
}
public static void main(String[] args) {
List<Point> list = createData();
ControlLimit controlLimit = new ControlLimit(new Double(12),new Double(2),new Double(1));
//TEST FOR RULE1
Boolean aBoolean1 = rule1(list, controlLimit);
// List<Point> list = createData();
List<Point> list = createData2();
ControlLimit controlLimit = new ControlLimit(new Double(12),new Double(3),new Double(1));
System.out.println("controlLimit : "+controlLimit.toString());
//
// //TEST FOR RULE1
// Boolean aBoolean1 = rule1(list, controlLimit);
//
//TEST FOR RULE2
Boolean aBoolean2 = rule2(list, controlLimit, 9);
// Boolean aBoolean2 = rule2(list, controlLimit, 5);
// System.out.println();
//
//
// //TEST FOR RULE3
// Boolean aBoolean3 = rule3(list, 3);
// System.out.println();
//
//
// //TEST FOR RULE4
// Boolean aBoolean4 = rule4(list, 6);
// System.out.println();
// //TEST FOR RULE5
// Boolean aBoolean5 = rule5(list, controlLimit, 3,2);
// System.out.println();
// //TEST FOR RULE6
// >6 或者 <2.3
// Boolean aBoolean6 = rule6(list, controlLimit, 5,4);
// System.out.println();
//TEST FOR RULE7
//LC0 = 1.6666 ;; UC1 = 5
// //>2.33 <3
// Boolean aBoolean7 = rule7(list, controlLimit,7);
// System.out.println();
//TEST FOR RULE8
Boolean aBoolean8 = rule8(list, controlLimit,8);
System.out.println();
//TEST FOR RULE3
Boolean aBoolean3 = rule3(list, 3);
System.out.println();
// int[] array={1,2,3,4,5,6};
// int[] ret=new int[3];
// System.arraycopy(array,0,ret,0,3);
// System.out.println(Arrays.toString(ret));
}
/**
* status : ok
* name : 规则1
* desc : 控制图上有 1 个点位于三倍标准差以外(对中心线来说)母体的 $\sigma$
*
* return : 返回的 就是不满足 规则1 的点
* 注意 如果存在满足rule1的点会在原数组 Point.unsatisfiedRules 里标注出来
* return :
* 存在满足rule1的点 => true
* 不存在满足rule1的点 => false
* */
private static Boolean rule1(List<Point> data, ControlLimit controlLimit){
Boolean flag = false;
for(Point i:data){
if(i.getValue() > controlLimit.getUCL() || i.getValue() < controlLimit.getLCL()){
i.getUnsatisfiedRules().add(1);
if(i.getValueForInterpretation() > controlLimit.getUCL() || i.getValueForInterpretation() < controlLimit.getLCL()){
i.getUnsatisfiedRules().add(rule1Number);
flag = true;
}
}
return true;
return flag;
}
private static void markUnsatisfiedRulesByKeys(List<Point> data,List<Integer> keys,Integer ruleNumber){
@ -94,18 +190,23 @@ public class StatisticalControlledTest {
}
/**
* status : ok
* name : 规则2
* desc : 连续 n 点落在中心线的用一侧 (默认9)
*
* return : 返回的 就是不满足 规则2 的点
* desc : 连续 n 点落在中心线的同一侧 (默认9)
* 注意 如果存在满足rule2的点会在原数组 Point.unsatisfiedRules 里标注出来
* return :
* 存在满足rule2的点 => true
* 不存在满足rule2的点 => false
* */
private static Boolean rule2(List<Point> data, ControlLimit controlLimit,Integer n){
Boolean result = false;
List<Point> upList = new ArrayList<>();
List<Point> downList = new ArrayList<>();
for(Point i:data){
if(i.getValue() > controlLimit.getCL()){
if(i.getValueForInterpretation() > controlLimit.getCL()){
upList.add(i);
}else if(i.getValue() < controlLimit.getCL()){
}else if(i.getValueForInterpretation() < controlLimit.getCL()){
downList.add(i);
}
}
@ -113,31 +214,38 @@ public class StatisticalControlledTest {
//上侧的情况
Integer upi = 0;
Integer uptime = 0;
Integer upTotalSize = upList.size();
//标注不合格的 参数
List<Point> forMarkPoints = new ArrayList<>();
while((upi+1) < upList.size()){
//if((upList.get(upi).getPosition()+1)==upList.get(upi+1).getPosition()){
if(isBetween(upList.get(upi),upList.get(upi+1))){
//|| upi==(n-1)
if( isBetween(upList.get(upi),upList.get(upi+1)) || upi==(n-1) ){
uptime +=1;
forMarkPoints.add(upList.get(upi));
if((upi+1)==(upTotalSize-1)){
uptime +=1;
forMarkPoints.add(upList.get(upi+1));
}
//只要到达n 就return防止中间段到达 后面又被重置了
if(uptime>=n){
result = true;
//1.
for (Point key:forMarkPoints){
for(Point j:data){
if(key.getPosition()== j.getPosition()){
if(key.getPosition().equals(j.getPosition())){
j.getUnsatisfiedRules().add(rule2Number);
continue;
}
}
}
//2.
// markUnsatisfiedRulesByKeys(data,forMarkKey,rule2Number);
return true;
//2.不考虑 return ,先把所有点都找出来( 重置所有标志位 )
uptime = 0;
}
}else {
forMarkPoints = new ArrayList<>();
// upTotalSize--;
uptime = 0;
}
upi++;
@ -147,40 +255,50 @@ public class StatisticalControlledTest {
//下侧的情况
Integer downi = 0;
Integer downtime = 0;
Integer totalSize = downList.size();
forMarkPoints = new ArrayList<>();
while((downi+1) < downList.size()){
if(isBetween(downList.get(upi),downList.get(upi+1))){
//这里之所以 要加上downi==(n-1) 是因为在比较顺序的时候要把最后一种可能加上
//|| downi==(n-1)
if(isBetween(downList.get(downi),downList.get(downi+1)) || downi==(n-1) ){
downtime +=1;
forMarkPoints.add(downList.get(downi));
if((downi+1)==(totalSize-1)){
downtime++;
forMarkPoints.add(downList.get(downi+1));
}
if(downtime>=n){
result = true;
for (Point key:forMarkPoints){
for(Point j:data){
if(key.getPosition()== j.getPosition()){
if(key.getPosition().equals(j.getPosition())){
j.getUnsatisfiedRules().add(rule2Number);
continue;
}
}
}
return true;
//2.不考虑 return ,先把所有点都找出来( 重置所有标志位 )
downtime = 0;
}
}else {
forMarkPoints = new ArrayList<>();
// totalSize--;
downtime = 0;
}
downi++;
}
return false;
return result;
}
/**
* status : ok
* name : 规则3
* desc : 连续 n 点递增或者递减 (默认6)
*
* return : 返回的 就是不满足 规则2 的点
* 注意 如果存在满足rule3的点会在原数组 Point.unsatisfiedRules 里标注出来
* return :
* 存在满足rule3的点 => true
* 不存在满足rule3的点 => false
* */
private static Boolean rule3(List<Point> data, Integer n){
@ -197,7 +315,9 @@ public class StatisticalControlledTest {
data.get(key).getUnsatisfiedRules().add(rule3Number);
}
return true;
//不return了, 把所有不满足的点都找出来
// return true;
uptime = 0;
}
}else {
uptime = 0;
@ -220,7 +340,8 @@ public class StatisticalControlledTest {
data.get(key).getUnsatisfiedRules().add(rule3Number);
}
return true;
// return true;
downtime = 0;
}
}else {
downtime = 0;
@ -232,8 +353,423 @@ public class StatisticalControlledTest {
return false;
}
/**
* status : ok
* name : 规则4
* desc : 连续 n 点中 相邻点 交替上下 ( 默认14 ) (n>2)
* 注意 如果存在满足rule4的点会在原数组 Point.unsatisfiedRules 里标注出来
* return :
* 存在满足rule4的点 => true
* 不存在满足rule4的点 => false
* */
private static Boolean rule4(List<Point> data, Integer n){
if(n<=2){
return false;
}
Boolean result = false;
Integer upi = 0;
Boolean current;
Boolean nextNeeded;
Integer times = 0;
Integer isAgain = 1;
List<Integer> forMarkKey = new ArrayList<>();
if(isSmall(data.get(0),data.get(1))){
current = true;
nextNeeded = true;
}else {
current = false;
nextNeeded = false;
}
while((upi+1) < data.size()){
if(isBetween( data.get(upi),data.get(upi+1) )){
//最后一个节点情况
if((upi+1)==(data.size()-1)){
Double u1 = data.get(upi-1).getValueForInterpretation();
Double u2 = data.get(upi).getValueForInterpretation();
Double u3 = data.get(upi+1).getValueForInterpretation();
if(isUpAndDown(u1,u2,u3)){
forMarkKey.add(upi);
forMarkKey.add(upi+1);
times+=2;
}
if(times >= n){
for(Integer key:forMarkKey){
data.get(key).getUnsatisfiedRules().add(rule4Number);
}
//set完了就重置
result = true;
return result;
}
}
//formark 最后一个点的时候
if(forMarkKey.size()==(n-1)){
Double u1 = data.get(upi-2).getValueForInterpretation();
Double u2 = data.get(upi-1).getValueForInterpretation();
Double u3 = data.get(upi).getValueForInterpretation();
if(isUpAndDown(u1,u2,u3)){
forMarkKey.add(upi);
times++;
}
if(times >= n){
for(Integer key:forMarkKey){
data.get(key).getUnsatisfiedRules().add(rule4Number);
}
//set完了就重置
result = true;
times=0;
forMarkKey = new ArrayList<>();
//
isAgain =2;
//
continue;
}
}
//A-B<0 True
//A-B>0 False
if(isSmall(data.get(upi),data.get(upi+1))){
current = true;
}else {
current = false;
}
if(isAgain == 2){
nextNeeded = current;
isAgain = 1;
}
if (current.equals(nextNeeded)){
times++;
forMarkKey.add(upi);
//加入最后一个元素的判断
if((upi+1)==(data.size()-1)){
Double u0 = data.get(upi - 1).getValueForInterpretation();
Double u1 = data.get(upi).getValueForInterpretation();
Double u2 = data.get(upi + 1).getValueForInterpretation();
if(isUpAndDown(u0,u1,u2)){
forMarkKey.add(upi+1);
times++;
}
}
if(times >= n){
for(Integer key:forMarkKey){
data.get(key).getUnsatisfiedRules().add(rule4Number);
}
// return true;
result = true;
times=0;
forMarkKey = new ArrayList<>();
//
isAgain =2;
//
continue;
}
}else {
times=0;
forMarkKey = new ArrayList<>();
}
nextNeeded = !current;
}else {
times = 0;
forMarkKey = new ArrayList<>();
}
upi++;
}
return result;
}
/**
* name : 规则5
* desc : 连续 m 点中 n 落在中心线同一侧B区以外( 默认 m:3 , n:2 )
* 注意 如果存在满足rule5的点会在原数组 Point.unsatisfiedRules 里标注出来
* return :
* 存在满足rule5的点 => true
* 不存在满足rule5的点 => false
* */
private static Boolean rule5(List<Point> data,ControlLimit controlLimit, Integer m, Integer n){
Boolean result = false;
Integer upi = 0;
List<Point> upforMarkKey = new ArrayList<>();
List<Point> downforMarkKey = new ArrayList<>();
// Double[] dataArray = (Double[])data.toArray();
Object[] dataArray = data.toArray();
ControlLimitDetail controlLimitDetail = new ControlLimitDetail(controlLimit.getUCL(), controlLimit.getCL(), controlLimit.getLCL());
System.out.println("controlLimitDetail : "+controlLimitDetail.toString());
Boolean lastFlag = false;
while(upi < data.size()){
Point[] keyList = new Point[m];
if(m>=(data.size()-upi)){
if(lastFlag){
break;
}
//System.arraycopy(dataArray , 10 , keyList , 0 , 2 );
System.arraycopy(dataArray,upi,keyList,0,(data.size()-upi));
lastFlag = true;
}else {
System.arraycopy(dataArray,upi,keyList,0,m);
}
Integer upTimes = 0;
Integer downTimes = 0;
for(Point i:keyList){
if(i.getValueForInterpretation()>controlLimitDetail.getUB()[1]){
upTimes++;
upforMarkKey.add(i);
System.out.println();
}
if(i.getValueForInterpretation()<controlLimitDetail.getLB()[0]){
downTimes++;
downforMarkKey.add(i);
}
}
if(upTimes>=n || downTimes>=n){
result = true;
if(upTimes>=n){
for(Point i:upforMarkKey){
i.getUnsatisfiedRules().add(rule5Number);
}
upforMarkKey = new ArrayList<>();
// return true;
}
if(downTimes>=n){
for(Point i:downforMarkKey){
i.getUnsatisfiedRules().add(rule5Number);
}
downforMarkKey = new ArrayList<>();
// return true;
}
// return true;
}else {
upforMarkKey = new ArrayList<>();
downforMarkKey = new ArrayList<>();
}
upi++;
}
return result;
}
/**
* name : 规则6
* desc : 连续 m 点中 n 落在中心线同一侧C区以外( 默认 m:5 , n:4 )
* 注意 如果存在满足rule6的点会在原数组 Point.unsatisfiedRules 里标注出来
* return :
* 存在满足rule6的点 => true
* 不存在满足rule6的点 => false
* */
private static Boolean rule6(List<Point> data,ControlLimit controlLimit, Integer m, Integer n){
Boolean result = false;
Integer upi = 0;
List<Point> upforMarkKey = new ArrayList<>();
List<Point> downforMarkKey = new ArrayList<>();
// Double[] dataArray = (Double[])data.toArray();
Object[] dataArray = data.toArray();
ControlLimitDetail controlLimitDetail = new ControlLimitDetail(controlLimit.getUCL(), controlLimit.getCL(), controlLimit.getLCL());
System.out.println("controlLimitDetail : "+controlLimitDetail.toString());
Boolean lastFlag = false;
while(upi < data.size()){
Point[] keyList = new Point[m];
if(m>=(data.size()-upi)){
if(lastFlag){
break;
}
//System.arraycopy(dataArray , 10 , keyList , 0 , 2 );
System.arraycopy(dataArray,upi,keyList,0,(data.size()-upi));
lastFlag = true;
}else {
System.arraycopy(dataArray,upi,keyList,0,m);
}
Integer upTimes = 0;
Integer downTimes = 0;
for(Point i:keyList){
if(i.getValueForInterpretation()>controlLimitDetail.getUC()[1]){
upTimes++;
upforMarkKey.add(i);
}
if(i.getValueForInterpretation()<controlLimitDetail.getLC()[0]){
downTimes++;
downforMarkKey.add(i);
}
}
if(upTimes>=n || downTimes>=n){
result = true;
if(upTimes>=n){
for(Point i:upforMarkKey){
i.getUnsatisfiedRules().add(rule6Number);
}
upforMarkKey = new ArrayList<>();
// return true;
}
if(downTimes>=n){
for(Point i:downforMarkKey){
if(i.getPosition() == 13){
System.out.println(1);
}
i.getUnsatisfiedRules().add(rule6Number);
}
// return true;
downforMarkKey = new ArrayList<>();
}
// return true;
}else {
upforMarkKey = new ArrayList<>();
downforMarkKey = new ArrayList<>();
}
upi++;
}
return result;
}
/**
* name : 规则7
* desc : 连续 n 落在中心线两侧的C区内( 默认 n:15 )
* 注意 如果存在满足rule7的点会在原数组 Point.unsatisfiedRules 里标注出来
* return :
* 存在满足rule7的点 => true
* 不存在满足rule7的点 => false
* */
private static Boolean rule7(List<Point> data,ControlLimit controlLimit, Integer n){
Boolean result = false;
//Integer upi = 0;
ControlLimitDetail controlLimitDetail = new ControlLimitDetail(controlLimit.getUCL(), controlLimit.getCL(), controlLimit.getLCL());
System.out.println(controlLimitDetail.toString());
Integer times = 0;
List<Point> markKey = new ArrayList<>();
for(int i=0;i<data.size();i++){
//判断最后一次
if((i+1) == data.size()){
Point point = data.get(i);
if(point.getValueForInterpretation()>controlLimitDetail.getLC()[0] && point.getValueForInterpretation()<controlLimitDetail.getUC()[1]){
times++;
markKey.add(point);
if(times.equals(n)){
for(Point j:markKey){
j.getUnsatisfiedRules().add(rule7Number);
}
return true;
}
}else {
times = 0;
markKey = new ArrayList<>();
}
break;
}
//通常情况
Point point = data.get(i);
if( isBetween( data.get(i),data.get(i+1) ) ){
if(point.getValueForInterpretation()>controlLimitDetail.getLC()[0] && point.getValueForInterpretation()<controlLimitDetail.getUC()[1]){
times++;
markKey.add(point);
if(times.equals(n)){
for(Point j:markKey){
j.getUnsatisfiedRules().add(rule7Number);
}
// return true;
result = true;
times = 0;
markKey = new ArrayList<>();
}
}else {
times = 0;
markKey = new ArrayList<>();
}
}else {
times = 0;
markKey = new ArrayList<>();
}
}
return result;
}
/**
* name : 规则8
* desc : 连续 n 落在中心线两侧且无一点在C区内( 默认 n:8 )
* 注意 如果存在满足rule8的点会在原数组 Point.unsatisfiedRules 里标注出来
* return :
* 存在满足rule8的点 => true
* 不存在满足rule8的点 => false
* */
private static Boolean rule8(List<Point> data,ControlLimit controlLimit, Integer n){
Boolean result = true;
//Integer upi = 0;
ControlLimitDetail controlLimitDetail = new ControlLimitDetail(controlLimit.getUCL(), controlLimit.getCL(), controlLimit.getLCL());
System.out.println(controlLimitDetail.toString());
Integer times = 0;
List<Point> markKey = new ArrayList<>();
for(int i=0;i<data.size();i++){
//判断最后一次
if((i+1) == data.size()){
Point point = data.get(i);
if( point.getValueForInterpretation()>controlLimitDetail.getUC()[1] || point.getValueForInterpretation()<controlLimitDetail.getLC()[0] ){
times++;
markKey.add(point);
if(times.equals(n)){
for(Point j:markKey){
j.getUnsatisfiedRules().add(rule8Number);
}
return true;
}
}else {
times = 0;
markKey = new ArrayList<>();
}
break;
}
//通常情况
Point point = data.get(i);
if( isBetween( data.get(i),data.get(i+1) ) ){
if( point.getValueForInterpretation()>controlLimitDetail.getUC()[1] || point.getValueForInterpretation()<controlLimitDetail.getLC()[0] ){
times++;
markKey.add(point);
if(times.equals(n)){
for(Point j:markKey){
j.getUnsatisfiedRules().add(rule8Number);
}
result = true;
times = 0;
markKey = new ArrayList<>();
}
}else {
times = 0;
markKey = new ArrayList<>();
}
}else {
times = 0;
markKey = new ArrayList<>();
}
}
return result;
}
/**
* 如果 这两个点是相邻的 == true
@ -245,13 +781,28 @@ public class StatisticalControlledTest {
* 如果 head 小于 after == true
* */
private static boolean isSmall(Point head,Point after){
return (head.getValue()- after.getValue()) < 0;
return (head.getValueForInterpretation()- after.getValueForInterpretation()) < 0;
}
/**
* 如果 head 大于 after == true
* */
private static boolean isBig(Point head,Point after){
return (head.getValue()- after.getValue()) > 0;
return (head.getValueForInterpretation()- after.getValueForInterpretation()) > 0;
}
/**
* 如果这三个参数 是起伏的 ====> true
*
* */
private static boolean isUpAndDown(Double u1,Double u2,Double u3){
Boolean r1 = ((u1-u2)>0);
Boolean r2 = ((u2-u3)>0);
if(!r1.equals(r2)){
return true;
}else {
return false;
}
}
}

View File

@ -1,5 +1,7 @@
package com.cnbm.qualityPlanning.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
@ -8,12 +10,16 @@ import lombok.Data;
* @DATE: 2022/7/12 15:17
*/
@Data
@ApiModel(value = "控制限")
public class ControlLimit {
//控制上限
@ApiModelProperty(value = "控制上限")
private Double UCL;
//控制中心线
@ApiModelProperty(value = "控制中心线")
private Double CL;
//控制下限
@ApiModelProperty(value = "控制下限")
private Double LCL;
public ControlLimit(Double UCL,Double CL,Double LCL){

View File

@ -0,0 +1,45 @@
package com.cnbm.qualityPlanning.entity;
import lombok.Data;
/**
* @Desc: ""
* @Author: caixiang
* @DATE: 2022/7/12 15:17
*/
@Data
public class ControlLimitDetail {
//控制上限
private Double UCL;
private Double[] UA = new Double[2];
private Double[] UB = new Double[2];
private Double[] UC = new Double[2];
//控制中心线
private Double CL;
//控制下限
private Double LCL;
private Double[] LA = new Double[2];
private Double[] LB = new Double[2];
private Double[] LC = new Double[2];
public ControlLimitDetail(Double UCL, Double CL, Double LCL){
this.UCL = UCL;
this.CL = CL;
this.LCL = LCL;
Double agv1 = (this.UCL-this.CL)/3;
this.UC[0] = this.CL;
this.UC[1] = this.CL+agv1;
this.UB[0] = this.UC[0];
this.UB[1] = this.UC[0]+agv1;
this.UA[0] = this.UB[0];
this.UA[1] = this.UB[0]+agv1;
Double agv2 = (this.CL-this.LCL)/3;
this.LC[0] = this.CL-agv2;
this.LC[1] = this.CL;
this.LB[0] = this.LC[0]-agv2;
this.LB[1] = this.LC[0];
this.LA[0] = this.LB[0]-agv2;
this.LA[1] = this.LB[0];
}
}

View File

@ -0,0 +1,9 @@
package com.cnbm.qualityPlanning.entity;
/**
* @Desc: ""
* @Author: caixiang
* @DATE: 2022/7/25 16:31
*/
public class PCWarming {
}

View File

@ -1,10 +1,8 @@
package com.cnbm.qualityPlanning.entity;
import io.swagger.models.auth.In;
import lombok.Data;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
@ -15,14 +13,14 @@ import java.util.Set;
@Data
public class Point {
private Integer position;
private Double value;
private Double valueForInterpretation;
//不满足的 规则 例子 : [1,2] => 代表 不满足 规则1 规则2
private Set<Integer> unsatisfiedRules;
public Point(Integer position , Double value){
public Point(Integer position , Double valueForInterpretation){
this.position = position;
this.value = value;
this.valueForInterpretation = valueForInterpretation;
this.unsatisfiedRules = new HashSet();
}

View File

@ -0,0 +1,40 @@
package com.cnbm.qualityPlanning.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* @Desc: ""
* @Author: caixiang
* @DATE: 2022/7/12 15:17
*/
@Data
@ApiModel(value = "工序能力")
public class ProcessCapability {
//工序能力指数CP
@ApiModelProperty(value = "工序能力指数CP")
private Double CP;
//实际工序能力指数CPK
@ApiModelProperty(value = "实际工序能力指数CPK")
private Double CPK;
//上侧规范 工序能力指数CPU
@ApiModelProperty(value = "上侧规范 工序能力指数CPU")
private Double CPU;
//下侧规范 工序能力指数CPL
@ApiModelProperty(value = "下侧规范 工序能力指数CPL")
private Double CPL;
@ApiModelProperty(value = "工序能力报警")
private List<String> warming;
public ProcessCapability(Double CP, Double CPK, Double CPU, Double CPL,List<String> warming) {
this.CP = CP;
this.CPK = CPK;
this.CPU = CPU;
this.CPL = CPL;
this.warming = warming;
}
}

View File

@ -1,5 +1,7 @@
package com.cnbm.qualityPlanning.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
@ -8,11 +10,21 @@ import lombok.Data;
* @DATE: 2022/7/12 15:19
*/
@Data
@ApiModel(value = "规格限")
public class SpecificationLimit {
//规格上限
private Double USL;
@ApiModelProperty(value = "规格上限")
private Float USL;
//规格中心线
private Double SL;
@ApiModelProperty(value = "规格中心限")
private Float SL;
//规格下限
private Double LSL;
@ApiModelProperty(value = "规格下限")
private Float LSL;
public SpecificationLimit(Float USL, Float SL, Float LSL) {
this.USL = USL;
this.SL = SL;
this.LSL = LSL;
}
}

View File

@ -0,0 +1,84 @@
package com.cnbm.qualityPlanning.entity;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* @Desc: "整合,处理好 后的一行数据 (sampleSize 后的数据) "
* @Author: caixiang
* @DATE: 2022/7/21 9:43
*/
public class XbarSPoint extends Point {
List<Double> data = new ArrayList<>();
private Double xbar;
private Double s;
private Double r;
//position 是这个数据在数组中的位置 value 是待被判读方案 分析的value xbarsr 中选一
public XbarSPoint(Integer position, Double value) {
super(position, value);
}
//
public Double getXbar() {
return xbar;
}
public void setXbar(Double xbar) {
this.xbar = xbar;
}
public Double getS() {
return s;
}
public void setS(Double s) {
this.s = s;
}
public Double getR() {
return r;
}
public void setR(Double r) {
this.r = r;
}
public XbarSPoint(Integer position, Double value, Double xbar, Double s, Double r) {
super(position,value);
this.xbar = xbar;
this.s = s;
this.r = r;
}
@Override
public Integer getPosition() {
return super.getPosition();
}
@Override
public Double getValueForInterpretation() {
return super.getValueForInterpretation();
}
@Override
public Set<Integer> getUnsatisfiedRules() {
return super.getUnsatisfiedRules();
}
@Override
public void setPosition(Integer position) {
super.setPosition(position);
}
@Override
public void setValueForInterpretation(Double valueForInterpretation) {
super.setValueForInterpretation(valueForInterpretation);
}
@Override
public void setUnsatisfiedRules(Set<Integer> unsatisfiedRules) {
super.setUnsatisfiedRules(unsatisfiedRules);
}
}