Compare commits
149 Commits
440e70ee82
...
0.8.X
| Author | SHA1 | Date | |
|---|---|---|---|
| 89867e8d70 | |||
| 634adccce8 | |||
| 788f5d2b7c | |||
| 6c1a15b952 | |||
| 7d4d2282fe | |||
| bbe451cb23 | |||
| 73c461f0e4 | |||
|
|
5a56094e4f | ||
| dde947516d | |||
| 0f0e0f3ae2 | |||
| b12d7679d8 | |||
| 419fcb6c62 | |||
| 674859504f | |||
| b7161e9541 | |||
| 5b38ef734a | |||
| b85971d532 | |||
| dc170c77d9 | |||
| 702de37397 | |||
| 81252ccb2d | |||
| 0c3382d6db | |||
| 3746175b24 | |||
| b3d33f4368 | |||
| 3c5c71408b | |||
| bfb253ee1b | |||
| 74d0cfedf4 | |||
| 9e03dbe9de | |||
| 43ace2f91e | |||
| fe048ff91f | |||
| 3e0859d4ce | |||
| db18d4dc34 | |||
| dd4ca3d380 | |||
| 8c0126d7f8 | |||
| 73b65962f2 | |||
| ffc73689a1 | |||
| 7fa0a7d38f | |||
| a1be1bf5ad | |||
| bf44909686 | |||
| 0cfffc3adb | |||
| 5729f2ee1a | |||
| 511d5b7385 | |||
| 01a06566ee | |||
| 865c00b5b4 | |||
| 133817883d | |||
| 668af2140a | |||
| c5fa84df98 | |||
| 594a921880 | |||
| e4028effc7 | |||
| 2aaa991516 | |||
| c7cf377358 | |||
| f6c365d60e | |||
| a17969e5e2 | |||
| 7803c38c27 | |||
| a1b2a3b6bb | |||
| 9e32a34f62 | |||
| c84000059f | |||
| b7dade8ce1 | |||
| 323d90db92 | |||
| b4bd96147f | |||
| 595d4839f3 | |||
| cae3f0e14a | |||
| 2d1f4eb281 | |||
| 84c26a2990 | |||
| b840574286 | |||
| a553b8ddc4 | |||
| 98eee1785f | |||
| 8897a2ad9f | |||
| ce71fc937b | |||
| 18f5931b62 | |||
| 1d4fbc6d3f | |||
| 1259a33664 | |||
| 19dad696a7 | |||
| fc203acd68 | |||
| c60ed8eb86 | |||
| 7229b23fcd | |||
| 54bdf600df | |||
| a8e667a69b | |||
| ba613bb88d | |||
| e44235abd8 | |||
| fecfb977e8 | |||
| bd9beb32eb | |||
| c571b12463 | |||
| a2067815a9 | |||
| b160b86838 | |||
| 626aca5b85 | |||
| e22648bff0 | |||
| 5adc316854 | |||
|
|
d61a2c795b | ||
|
|
f501994da6 | ||
|
|
62b594026b | ||
| ee199388d5 | |||
| d69e445e82 | |||
| 3d7fd09c60 | |||
| 5634964002 | |||
| 9f7870c63b | |||
| 29d0303247 | |||
| c3bef9615e | |||
| d398c2e4fc | |||
| 2dbf4a042e | |||
| be59e4cc79 | |||
| 14e28a0169 | |||
| a26089ce15 | |||
| 2d3caa65bc | |||
| bd4d591934 | |||
| f7a8b3df22 | |||
| 4fefc68bbc | |||
| cdcf5e2428 | |||
| deb684ce27 | |||
| 3f300e05e9 | |||
| af002b84d3 | |||
| 143764f7f8 | |||
| 0822ca7cc8 | |||
| 5b452bad31 | |||
| 4f259c5aba | |||
| 34dd8004c4 | |||
| 254dada485 | |||
| ee2bb280b6 | |||
| 96082b9124 | |||
| ddb1beb629 | |||
| 67cf5aa7cb | |||
| e1cc0fda34 | |||
| 4e5e1bbca1 | |||
| 2e363f9ad8 | |||
| f158830abf | |||
| 843512ab7e | |||
| dd27069b4c | |||
| b95bd5b93d | |||
| 4d588985e8 | |||
| 3ad3fd2fee | |||
| 79ee9d572d | |||
| c9742b08cf | |||
| 6bd5d2ded3 | |||
| da1813e65a | |||
| 8dbb7d1113 | |||
| ae77c529ae | |||
| edcbf7a5f1 | |||
| 28622a2b16 | |||
| 44303cb1c7 | |||
| c0f7c699a8 | |||
| e69dc5e76e | |||
| ec0660acba | |||
| 110597657e | |||
| 50670b64d8 | |||
|
|
823afd7a00 | ||
|
|
344488f08e | ||
| c2da7640c3 | |||
| e99d7709d2 | |||
| 623e78629d | |||
| c1938e29a4 | |||
| 54d426984b |
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"java.configuration.updateBuildConfiguration": "interactive"
|
||||
}
|
||||
@@ -0,0 +1,428 @@
|
||||
package com.klp.framework.client;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.klp.framework.config.SqlServerApiProperties;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* sql-server-api 统一调用客户端。
|
||||
* <p>
|
||||
* 对齐 {@code sql-server-api/app.py} 的接口规范:
|
||||
* <ul>
|
||||
* <li>GET /health</li>
|
||||
* <li>GET /heartbeat</li>
|
||||
* <li>POST /table-schema</li>
|
||||
* <li>POST /execute-sql</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Component
|
||||
public class SqlServerApiClient {
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
private final SqlServerApiProperties properties;
|
||||
|
||||
public SqlServerApiClient(RestTemplate sqlServerApiRestTemplate, SqlServerApiProperties properties) {
|
||||
this.restTemplate = sqlServerApiRestTemplate;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public String getBaseUrl() {
|
||||
return normalizeBaseUrl();
|
||||
}
|
||||
|
||||
public Map<String, Object> health() {
|
||||
return getForMap("/health");
|
||||
}
|
||||
|
||||
public Map<String, Object> heartbeat() {
|
||||
return getForMap("/heartbeat");
|
||||
}
|
||||
|
||||
public TableSchemaResponse tableSchema(String tableType, String tableName) {
|
||||
return postForObject("/table-schema", new TableSchemaRequest(tableType, tableName), TableSchemaResponse.class);
|
||||
}
|
||||
|
||||
public ExecuteSqlResponse executeSql(String tableType, String sql, Map<String, Object> params) {
|
||||
return postForObject("/execute-sql", new ExecuteSqlRequest(tableType, sql, params), ExecuteSqlResponse.class);
|
||||
}
|
||||
|
||||
public <T> T get(String path, Class<T> responseType) {
|
||||
return restTemplate.getForObject(buildUri(path), responseType);
|
||||
}
|
||||
|
||||
public <T> T get(String path, Map<String, ?> queryParams, Class<T> responseType) {
|
||||
URI uri = UriComponentsBuilder.fromHttpUrl(normalizeBaseUrl())
|
||||
.path(normalizePath(path))
|
||||
.queryParams(convertToQueryParams(queryParams))
|
||||
.build(true)
|
||||
.toUri();
|
||||
return restTemplate.getForObject(uri, responseType);
|
||||
}
|
||||
|
||||
public <T, R> T post(String path, R requestBody, Class<T> responseType) {
|
||||
return restTemplate.postForObject(buildUri(path), requestBody, responseType);
|
||||
}
|
||||
|
||||
public static class TableSchemaRequest {
|
||||
@JsonProperty("table_type")
|
||||
private String tableType;
|
||||
@JsonProperty("table_name")
|
||||
private String tableName;
|
||||
|
||||
public TableSchemaRequest() {
|
||||
}
|
||||
|
||||
public TableSchemaRequest(String tableType, String tableName) {
|
||||
this.tableType = tableType;
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
public String getTableType() {
|
||||
return tableType;
|
||||
}
|
||||
|
||||
public void setTableType(String tableType) {
|
||||
this.tableType = tableType;
|
||||
}
|
||||
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public void setTableName(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExecuteSqlRequest {
|
||||
@JsonProperty("table_type")
|
||||
private String tableType;
|
||||
private String sql;
|
||||
private Map<String, Object> params;
|
||||
|
||||
public ExecuteSqlRequest() {
|
||||
}
|
||||
|
||||
public ExecuteSqlRequest(String tableType, String sql, Map<String, Object> params) {
|
||||
this.tableType = tableType;
|
||||
this.sql = sql;
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public String getTableType() {
|
||||
return tableType;
|
||||
}
|
||||
|
||||
public void setTableType(String tableType) {
|
||||
this.tableType = tableType;
|
||||
}
|
||||
|
||||
public String getSql() {
|
||||
return sql;
|
||||
}
|
||||
|
||||
public void setSql(String sql) {
|
||||
this.sql = sql;
|
||||
}
|
||||
|
||||
public Map<String, Object> getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public void setParams(Map<String, Object> params) {
|
||||
this.params = params;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TableSchemaResponse {
|
||||
private String tableType;
|
||||
private String tableName;
|
||||
private Schema schema;
|
||||
|
||||
public String getTableType() {
|
||||
return tableType;
|
||||
}
|
||||
|
||||
public void setTableType(String tableType) {
|
||||
this.tableType = tableType;
|
||||
}
|
||||
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public void setTableName(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
public Schema getSchema() {
|
||||
return schema;
|
||||
}
|
||||
|
||||
public void setSchema(Schema schema) {
|
||||
this.schema = schema;
|
||||
}
|
||||
|
||||
public static class Schema {
|
||||
private List<Column> columns = Collections.emptyList();
|
||||
|
||||
public List<Column> getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
public void setColumns(List<Column> columns) {
|
||||
this.columns = columns;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Column {
|
||||
private String name;
|
||||
private String type;
|
||||
private boolean nullable;
|
||||
private Object defaultValue;
|
||||
private boolean primaryKey;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public boolean isNullable() {
|
||||
return nullable;
|
||||
}
|
||||
|
||||
public void setNullable(boolean nullable) {
|
||||
this.nullable = nullable;
|
||||
}
|
||||
|
||||
public Object getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public void setDefaultValue(Object defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public boolean isPrimaryKey() {
|
||||
return primaryKey;
|
||||
}
|
||||
|
||||
public void setPrimaryKey(boolean primaryKey) {
|
||||
this.primaryKey = primaryKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExecuteSqlResponse {
|
||||
private String tableType;
|
||||
private String resultType;
|
||||
private Integer rowCount;
|
||||
private Object result;
|
||||
|
||||
public String getTableType() {
|
||||
return tableType;
|
||||
}
|
||||
|
||||
public void setTableType(String tableType) {
|
||||
this.tableType = tableType;
|
||||
}
|
||||
|
||||
public String getResultType() {
|
||||
return resultType;
|
||||
}
|
||||
|
||||
public void setResultType(String resultType) {
|
||||
this.resultType = resultType;
|
||||
}
|
||||
|
||||
public Integer getRowCount() {
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
public void setRowCount(Integer rowCount) {
|
||||
this.rowCount = rowCount;
|
||||
}
|
||||
|
||||
public Object getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(Object result) {
|
||||
this.result = result;
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Object> getForMap(String path) {
|
||||
ResponseEntity<Map> responseEntity = restTemplate.exchange(buildUri(path), HttpMethod.GET, HttpEntity.EMPTY, Map.class);
|
||||
Map<String, Object> body = responseEntity.getBody();
|
||||
return body == null ? Collections.emptyMap() : body;
|
||||
}
|
||||
|
||||
private <T> T postForObject(String path, Object requestBody, Class<T> responseType) {
|
||||
return restTemplate.postForObject(buildUri(path), requestBody, responseType);
|
||||
}
|
||||
|
||||
private URI buildUri(String path) {
|
||||
return UriComponentsBuilder.fromHttpUrl(normalizeBaseUrl())
|
||||
.path(normalizePath(path))
|
||||
.build(true)
|
||||
.toUri();
|
||||
}
|
||||
|
||||
private String normalizeBaseUrl() {
|
||||
if (properties.getBaseUrl() != null && properties.getBaseUrl().trim().length() > 0) {
|
||||
return properties.getBaseUrl();
|
||||
}
|
||||
if (properties.getHost() == null || properties.getHost().trim().length() == 0 || properties.getPort() == null) {
|
||||
throw new IllegalStateException("sql-server-api 配置缺失,请检查 host/port/base-url");
|
||||
}
|
||||
return "http://" + properties.getHost() + ":" + properties.getPort();
|
||||
}
|
||||
|
||||
private String normalizePath(String path) {
|
||||
if (path == null || path.trim().length() == 0) {
|
||||
return "";
|
||||
}
|
||||
return path.startsWith("/") ? path : "/" + path;
|
||||
}
|
||||
|
||||
public ExecuteSqlResponse queryPlanByCoilId(String coilId) {
|
||||
return executeSql(
|
||||
"oracle",
|
||||
"select * from JXPLTCM.PLTCM_PDI_PLAN where COILID = :coilId",
|
||||
singletonParam("coilId", coilId)
|
||||
);
|
||||
}
|
||||
|
||||
public ExecuteSqlResponse queryPlanList(int page, int pageSize) {
|
||||
int endRow = page * pageSize;
|
||||
int startRow = endRow - pageSize;
|
||||
Map<String, Object> params = new java.util.HashMap<>();
|
||||
params.put("startRow", startRow);
|
||||
params.put("endRow", endRow);
|
||||
return executeSql(
|
||||
"oracle",
|
||||
"select * from (select t.*, ROWNUM rn from (select * from JXPLTCM.PLTCM_PDI_PLAN order by INSDATE desc) t where ROWNUM <= :endRow) where rn > :startRow",
|
||||
params
|
||||
);
|
||||
}
|
||||
|
||||
public ExecuteSqlResponse queryPlanCount() {
|
||||
return executeSql(
|
||||
"oracle",
|
||||
"select count(*) as total from JXPLTCM.PLTCM_PDI_PLAN",
|
||||
emptyParams()
|
||||
);
|
||||
}
|
||||
|
||||
public ExecuteSqlResponse queryPlanListByProcessCode(String processCode) {
|
||||
return executeSql(
|
||||
"oracle",
|
||||
"select * from JXPLTCM.PLTCM_PDI_PLAN where PROCESS_CODE = :processCode order by INSDATE desc",
|
||||
singletonParam("processCode", processCode)
|
||||
);
|
||||
}
|
||||
|
||||
public ExecuteSqlResponse queryPlanListByStatus(String status) {
|
||||
return executeSql(
|
||||
"oracle",
|
||||
"select * from JXPLTCM.PLTCM_PDI_PLAN where STATUS = :status order by INSDATE desc",
|
||||
singletonParam("status", status)
|
||||
);
|
||||
}
|
||||
|
||||
public ExecuteSqlResponse queryPlanByHotCoilId(String hotCoilId) {
|
||||
return executeSql(
|
||||
"oracle",
|
||||
"select * from JXPLTCM.PLTCM_PDI_PLAN where HOT_COILID = :hotCoilId",
|
||||
singletonParam("hotCoilId", hotCoilId)
|
||||
);
|
||||
}
|
||||
|
||||
public ExecuteSqlResponse queryProSegByEncoilId(String encoilId) {
|
||||
return executeSql(
|
||||
"oracle",
|
||||
"select * from JXPLTCM.PLTCM_PRO_SEG where ENCOILID = :encoilId order by SEGNO",
|
||||
singletonParam("encoilId", encoilId)
|
||||
);
|
||||
}
|
||||
|
||||
public ExecuteSqlResponse queryProSegByExcoilId(String excoilId) {
|
||||
return executeSql(
|
||||
"oracle",
|
||||
"select * from JXPLTCM.PLTCM_PRO_SEG where EXCOILID = :excoilId order by SEGNO",
|
||||
singletonParam("excoilId", excoilId)
|
||||
);
|
||||
}
|
||||
|
||||
public ExecuteSqlResponse queryQualityByExcoilId(String excoilId) {
|
||||
return executeSql(
|
||||
"oracle",
|
||||
"select * from JXPLTCM.V_PLTCM_PDO_QUALITY where EXCOILID = :excoilId order by END_DATE desc",
|
||||
singletonParam("excoilId", excoilId)
|
||||
);
|
||||
}
|
||||
|
||||
public ExecuteSqlResponse queryGaugeByMatId(String matId) {
|
||||
return executeSql(
|
||||
"oracle",
|
||||
"select * from JXPLTCM.V_VBDA_GAUGE where MATID = :matId order by XTIME asc",
|
||||
singletonParam("matId", matId)
|
||||
);
|
||||
}
|
||||
|
||||
public ExecuteSqlResponse queryShapeByMatId(String matId) {
|
||||
return executeSql(
|
||||
"oracle",
|
||||
"select * from JXPLTCM.V_VBDA_SHAPE where MATID = :matId order by XTIME asc",
|
||||
singletonParam("matId", matId)
|
||||
);
|
||||
}
|
||||
|
||||
private org.springframework.util.MultiValueMap<String, String> convertToQueryParams(Map<String, ?> queryParams) {
|
||||
org.springframework.util.LinkedMultiValueMap<String, String> multiValueMap = new org.springframework.util.LinkedMultiValueMap<>();
|
||||
if (queryParams == null || queryParams.isEmpty()) {
|
||||
return multiValueMap;
|
||||
}
|
||||
for (Map.Entry<String, ?> entry : queryParams.entrySet()) {
|
||||
Object value = entry.getValue();
|
||||
if (value != null) {
|
||||
multiValueMap.add(entry.getKey(), String.valueOf(value));
|
||||
}
|
||||
}
|
||||
return multiValueMap;
|
||||
}
|
||||
|
||||
private Map<String, Object> singletonParam(String key, Object value) {
|
||||
java.util.HashMap<String, Object> params = new java.util.HashMap<String, Object>();
|
||||
if (value != null) {
|
||||
params.put(key, value);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
private Map<String, Object> emptyParams() {
|
||||
return new java.util.HashMap<String, Object>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.klp.framework.config;
|
||||
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* sql-server-api HTTP 客户端配置
|
||||
*/
|
||||
@Configuration
|
||||
public class SqlServerApiClientConfig {
|
||||
|
||||
@Bean
|
||||
public RestTemplate sqlServerApiRestTemplate(RestTemplateBuilder builder) {
|
||||
return builder
|
||||
.setConnectTimeout(Duration.ofSeconds(5))
|
||||
.setReadTimeout(Duration.ofSeconds(60))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.klp.framework.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* sql-server-api 中间件配置
|
||||
*/
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "sql-server-api")
|
||||
public class SqlServerApiProperties {
|
||||
|
||||
/**
|
||||
* 请求地址
|
||||
*/
|
||||
private String host;
|
||||
|
||||
/**
|
||||
* 请求端口
|
||||
*/
|
||||
private Integer port;
|
||||
|
||||
/**
|
||||
* 基础访问地址
|
||||
*/
|
||||
private String baseUrl;
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public Integer getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(Integer port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public String getBaseUrl() {
|
||||
return baseUrl;
|
||||
}
|
||||
|
||||
public void setBaseUrl(String baseUrl) {
|
||||
this.baseUrl = baseUrl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,318 @@
|
||||
package com.klp.framework.service;
|
||||
|
||||
import com.klp.framework.client.SqlServerApiClient;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 面向业务场景的 sql-server-api 查询服务。
|
||||
* <p>
|
||||
* 当前抽象为三个功能:
|
||||
* <ol>
|
||||
* <li>计划查询</li>
|
||||
* <li>钢卷实际 / SEG 查询</li>
|
||||
* <li>实时数据(Gauge / Shape)查询</li>
|
||||
* </ol>
|
||||
*/
|
||||
@Service
|
||||
public class SqlServerApiBusinessService {
|
||||
|
||||
private final SqlServerApiClient client;
|
||||
|
||||
public SqlServerApiBusinessService(SqlServerApiClient client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计划列表(分页):按时间倒序,page 从 1 开始。
|
||||
*/
|
||||
public PlanListView getPlanList(int page, int pageSize) {
|
||||
return PlanListView.fromExecuteSqlResponse(client.queryPlanList(page, pageSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* 计划总数。
|
||||
*/
|
||||
public long getPlanCount() {
|
||||
SqlServerApiClient.ExecuteSqlResponse resp = client.queryPlanCount();
|
||||
List<Map<String, Object>> rows = asRowList(resp);
|
||||
if (rows.isEmpty()) {
|
||||
return 0L;
|
||||
}
|
||||
Object total = rows.get(0).get("total");
|
||||
Number n = asNumber(total);
|
||||
return n == null ? 0L : n.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* 计划列表:按工艺流程编码筛选。
|
||||
*/
|
||||
public PlanListView getPlanListByProcessCode(String processCode) {
|
||||
return PlanListView.fromExecuteSqlResponse(client.queryPlanListByProcessCode(processCode));
|
||||
}
|
||||
|
||||
/**
|
||||
* 计划列表:按状态筛选。
|
||||
*/
|
||||
public PlanListView getPlanListByStatus(String status) {
|
||||
return PlanListView.fromExecuteSqlResponse(client.queryPlanListByStatus(status));
|
||||
}
|
||||
|
||||
/**
|
||||
* 计划详情:按成品卷号查询单条计划。
|
||||
*/
|
||||
public PlanDetailView getPlanByCoilId(String coilId) {
|
||||
return PlanDetailView.fromExecuteSqlResponse(coilId, client.queryPlanByCoilId(coilId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 计划详情:按热卷号查询。
|
||||
*/
|
||||
public PlanDetailView getPlanByHotCoilId(String hotCoilId) {
|
||||
return PlanDetailView.fromExecuteSqlResponse(hotCoilId, client.queryPlanByHotCoilId(hotCoilId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 钢卷实际 SEG 查询:按入口卷号查询。
|
||||
* <p>
|
||||
* 返回的是按 SEGNO 排序后的原始行数据。
|
||||
*/
|
||||
public SegSeriesView getSegByEncoilId(String encoilId) {
|
||||
return SegSeriesView.fromExecuteSqlResponse(encoilId, client.queryProSegByEncoilId(encoilId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 钢卷实际 SEG 查询:按出口卷号查询。
|
||||
*/
|
||||
public SegSeriesView getSegByExcoilId(String excoilId) {
|
||||
return SegSeriesView.fromExecuteSqlResponse(excoilId, client.queryProSegByExcoilId(excoilId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 钢卷 SEG 视图数据:把同一钢卷下按 SEGNO 排序的多行数据,整理成“一个钢卷 id + 一个属性对应一个列表”的结构。
|
||||
* <p>
|
||||
* 例如:厚度、张力、速度都会被整理成数组,方便前端直接画表或曲线。
|
||||
*/
|
||||
public SegSeriesView getSegSeriesViewByEncoilId(String encoilId) {
|
||||
return getSegByEncoilId(encoilId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 实时数据:厚度/仪表数据。
|
||||
*/
|
||||
public SqlServerApiClient.ExecuteSqlResponse getRealtimeGaugeByMatId(String matId) {
|
||||
return client.queryGaugeByMatId(matId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 实时数据:板形/形状数据。
|
||||
*/
|
||||
public SqlServerApiClient.ExecuteSqlResponse getRealtimeShapeByMatId(String matId) {
|
||||
return client.queryShapeByMatId(matId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 实时数据总入口:一次性返回厚度与板形两类数据。
|
||||
*/
|
||||
public RealtimeDataBundle getRealtimeData(String matId) {
|
||||
return new RealtimeDataBundle(
|
||||
getRealtimeGaugeByMatId(matId),
|
||||
getRealtimeShapeByMatId(matId)
|
||||
);
|
||||
}
|
||||
|
||||
private static PlanListView toPlanListView(SqlServerApiClient.ExecuteSqlResponse response) {
|
||||
return PlanListView.fromExecuteSqlResponse(response);
|
||||
}
|
||||
|
||||
private static List<Map<String, Object>> asRowList(SqlServerApiClient.ExecuteSqlResponse response) {
|
||||
if (response == null || response.getResult() == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Object result = response.getResult();
|
||||
if (result instanceof List) {
|
||||
List<?> list = (List<?>) result;
|
||||
List<Map<String, Object>> rows = new ArrayList<Map<String, Object>>();
|
||||
for (Object item : list) {
|
||||
if (item instanceof Map) {
|
||||
rows.add((Map<String, Object>) item);
|
||||
}
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private static Number asNumber(Object value) {
|
||||
if (value instanceof Number) {
|
||||
return (Number) value;
|
||||
}
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return new BigDecimal(String.valueOf(value));
|
||||
} catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static String asString(Object value) {
|
||||
return value == null ? null : String.valueOf(value);
|
||||
}
|
||||
|
||||
public static class PlanListView {
|
||||
private final List<String> coilIds;
|
||||
private final List<Map<String, Object>> rows;
|
||||
|
||||
public PlanListView(List<String> coilIds, List<Map<String, Object>> rows) {
|
||||
this.coilIds = coilIds;
|
||||
this.rows = rows;
|
||||
}
|
||||
|
||||
public List<String> getCoilIds() {
|
||||
return coilIds;
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> getRows() {
|
||||
return rows;
|
||||
}
|
||||
|
||||
public static PlanListView fromExecuteSqlResponse(SqlServerApiClient.ExecuteSqlResponse response) {
|
||||
List<Map<String, Object>> rows = asRowList(response);
|
||||
List<String> coilIds = rows.stream()
|
||||
.map(row -> asString(row.get("COILID")))
|
||||
.filter(value -> value != null && value.trim().length() > 0)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
return new PlanListView(coilIds, rows);
|
||||
}
|
||||
}
|
||||
|
||||
public static class PlanDetailView {
|
||||
private final String coilId;
|
||||
private final List<Map<String, Object>> rows;
|
||||
private final Map<String, Object> firstRow;
|
||||
|
||||
public PlanDetailView(String coilId, List<Map<String, Object>> rows, Map<String, Object> firstRow) {
|
||||
this.coilId = coilId;
|
||||
this.rows = rows;
|
||||
this.firstRow = firstRow;
|
||||
}
|
||||
|
||||
public String getCoilId() {
|
||||
return coilId;
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> getRows() {
|
||||
return rows;
|
||||
}
|
||||
|
||||
public Map<String, Object> getFirstRow() {
|
||||
return firstRow;
|
||||
}
|
||||
|
||||
public static PlanDetailView fromExecuteSqlResponse(String coilId, SqlServerApiClient.ExecuteSqlResponse response) {
|
||||
List<Map<String, Object>> rows = asRowList(response);
|
||||
Map<String, Object> firstRow = rows.isEmpty() ? Collections.<String, Object>emptyMap() : rows.get(0);
|
||||
return new PlanDetailView(coilId, rows, firstRow);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SegSeriesView {
|
||||
private final String coilId;
|
||||
private final List<Integer> segNo;
|
||||
private final Map<String, List<Object>> series;
|
||||
private final List<Map<String, Object>> rows;
|
||||
|
||||
public SegSeriesView(String coilId, List<Integer> segNo, Map<String, List<Object>> series, List<Map<String, Object>> rows) {
|
||||
this.coilId = coilId;
|
||||
this.segNo = segNo;
|
||||
this.series = series;
|
||||
this.rows = rows;
|
||||
}
|
||||
|
||||
public String getCoilId() {
|
||||
return coilId;
|
||||
}
|
||||
|
||||
public List<Integer> getSegNo() {
|
||||
return segNo;
|
||||
}
|
||||
|
||||
public Map<String, List<Object>> getSeries() {
|
||||
return series;
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> getRows() {
|
||||
return rows;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static SegSeriesView fromExecuteSqlResponse(String coilId, SqlServerApiClient.ExecuteSqlResponse response) {
|
||||
List<Map<String, Object>> rows = asRowList(response);
|
||||
Collections.sort(rows, new Comparator<Map<String, Object>>() {
|
||||
@Override
|
||||
public int compare(Map<String, Object> left, Map<String, Object> right) {
|
||||
Number leftSeg = asNumber(left.get("SEGNO"));
|
||||
Number rightSeg = asNumber(right.get("SEGNO"));
|
||||
int leftValue = leftSeg == null ? Integer.MAX_VALUE : leftSeg.intValue();
|
||||
int rightValue = rightSeg == null ? Integer.MAX_VALUE : rightSeg.intValue();
|
||||
if (leftValue > rightValue) {
|
||||
return 1;
|
||||
}
|
||||
if (leftValue < rightValue) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
List<Integer> segNo = new ArrayList<Integer>();
|
||||
for (Map<String, Object> row : rows) {
|
||||
Number seg = asNumber(row.get("SEGNO"));
|
||||
segNo.add(seg == null ? null : seg.intValue());
|
||||
}
|
||||
|
||||
Map<String, List<Object>> series = new LinkedHashMap<String, List<Object>>();
|
||||
for (Map<String, Object> row : rows) {
|
||||
for (Map.Entry<String, Object> entry : row.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if ("SEGNO".equalsIgnoreCase(key)) {
|
||||
continue;
|
||||
}
|
||||
series.computeIfAbsent(key, ignored -> new ArrayList<>()).add(entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return new SegSeriesView(coilId, segNo, series, rows);
|
||||
}
|
||||
}
|
||||
|
||||
public static class RealtimeDataBundle {
|
||||
private final SqlServerApiClient.ExecuteSqlResponse gauge;
|
||||
private final SqlServerApiClient.ExecuteSqlResponse shape;
|
||||
|
||||
public RealtimeDataBundle(SqlServerApiClient.ExecuteSqlResponse gauge,
|
||||
SqlServerApiClient.ExecuteSqlResponse shape) {
|
||||
this.gauge = gauge;
|
||||
this.shape = shape;
|
||||
}
|
||||
|
||||
public SqlServerApiClient.ExecuteSqlResponse getGauge() {
|
||||
return gauge;
|
||||
}
|
||||
|
||||
public SqlServerApiClient.ExecuteSqlResponse getShape() {
|
||||
return shape;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.klp.framework.sqlserver;
|
||||
|
||||
import com.klp.common.core.domain.R;
|
||||
import com.klp.framework.service.SqlServerApiBusinessService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* sql-server-api 业务查询接口。
|
||||
* <p>
|
||||
* 提供计划、SEG、实时数据三个入口,方便前端联动展示。
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/sql-server-api")
|
||||
public class SqlServerApiController {
|
||||
|
||||
private final SqlServerApiBusinessService businessService;
|
||||
|
||||
/**
|
||||
* 计划列表(分页)。
|
||||
* page 从 1 开始,默认第 1 页,每页 20 条。
|
||||
*/
|
||||
@GetMapping("/plans")
|
||||
public R<SqlServerApiBusinessService.PlanListView> planList(
|
||||
@RequestParam(defaultValue = "1") int page,
|
||||
@RequestParam(defaultValue = "20") int pageSize) {
|
||||
return R.ok(businessService.getPlanList(page, pageSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* 计划总数,用于前端分页器。
|
||||
*/
|
||||
@GetMapping("/plans/count")
|
||||
public R<Map<String, Long>> planCount() {
|
||||
Map<String, Long> result = new HashMap<>();
|
||||
result.put("total", businessService.getPlanCount());
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计划详情。
|
||||
*/
|
||||
@GetMapping("/plans/{coilId}")
|
||||
public R<SqlServerApiBusinessService.PlanDetailView> planDetail(@PathVariable String coilId) {
|
||||
return R.ok(businessService.getPlanByCoilId(coilId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 钢卷实际 SEG,按入口卷号查询。
|
||||
*/
|
||||
@GetMapping("/seg/{encoilId}")
|
||||
public R<SqlServerApiBusinessService.SegSeriesView> segByEncoilId(@PathVariable String encoilId) {
|
||||
return R.ok(businessService.getSegSeriesViewByEncoilId(encoilId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 钢卷实际 SEG,按出口卷号查询。
|
||||
*/
|
||||
@GetMapping("/seg-by-excoil/{excoilId}")
|
||||
public R<SqlServerApiBusinessService.SegSeriesView> segByExcoilId(@PathVariable String excoilId) {
|
||||
return R.ok(businessService.getSegByExcoilId(excoilId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 实时数据:厚度、板形。
|
||||
*/
|
||||
@GetMapping("/realtime/{matId}")
|
||||
public R<SqlServerApiBusinessService.RealtimeDataBundle> realtime(@PathVariable String matId) {
|
||||
return R.ok(businessService.getRealtimeData(matId));
|
||||
}
|
||||
}
|
||||
@@ -102,7 +102,6 @@ public class SysConfigController extends BaseController {
|
||||
/**
|
||||
* 根据参数键名修改参数配置
|
||||
*/
|
||||
@SaCheckPermission("system:config:edit")
|
||||
@Log(title = "参数管理", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/updateByKey")
|
||||
public R<Void> updateByKey(@RequestBody SysConfig config) {
|
||||
|
||||
@@ -11,7 +11,6 @@ import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.common.enums.BusinessType;
|
||||
import com.klp.common.utils.poi.ExcelUtil;
|
||||
import com.klp.system.service.ISysDictDataService;
|
||||
import com.klp.system.service.ISysDictTypeService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -32,7 +31,6 @@ import java.util.List;
|
||||
public class SysDictDataController extends BaseController {
|
||||
|
||||
private final ISysDictDataService dictDataService;
|
||||
private final ISysDictTypeService dictTypeService;
|
||||
|
||||
/**
|
||||
* 查询字典数据列表
|
||||
@@ -72,7 +70,7 @@ public class SysDictDataController extends BaseController {
|
||||
*/
|
||||
@GetMapping(value = "/type/{dictType}")
|
||||
public R<List<SysDictData>> dictType(@PathVariable("dictType") String dictType) {
|
||||
List<SysDictData> data = dictTypeService.selectDictDataByType(dictType);
|
||||
List<SysDictData> data = dictDataService.selectDictDataByTypeRealtime(dictType);
|
||||
if (ObjectUtil.isNull(data)) {
|
||||
data = new ArrayList<>();
|
||||
}
|
||||
|
||||
@@ -50,6 +50,14 @@ public class SysDictTypeController extends BaseController {
|
||||
ExcelUtil.exportExcel(list, "字典类型", SysDictType.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按字典类型编码精确查询(避免 /list 条件对 dict_type 使用 LIKE 时下划线通配问题;供页内齿轮等使用)
|
||||
*/
|
||||
@GetMapping("/byType/{dictType}")
|
||||
public R<SysDictType> getByDictType(@PathVariable String dictType) {
|
||||
return R.ok(dictTypeService.selectDictTypeByType(dictType));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询字典类型详细
|
||||
*
|
||||
|
||||
@@ -7,6 +7,12 @@ klp:
|
||||
# 开发环境文件存储目录
|
||||
directory-path: testDirectory
|
||||
|
||||
--- # sql-server-api 中间件配置(开发/测试环境)
|
||||
sql-server-api:
|
||||
host: 140.143.206.120
|
||||
port: 15000
|
||||
base-url: http://${sql-server-api.host}:${sql-server-api.port}
|
||||
|
||||
--- # OEE 聚合(klp-da)多服务地址配置
|
||||
da:
|
||||
oee:
|
||||
@@ -92,14 +98,17 @@ spring:
|
||||
url: jdbc:mysql://140.143.206.120:3306/cgldb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
||||
username: klp
|
||||
password: KeLunPu123@
|
||||
# oracle:
|
||||
# type: ${spring.datasource.type}
|
||||
# driverClassName: oracle.jdbc.OracleDriver
|
||||
# url: jdbc:oracle:thin:@//localhost:1521/XE
|
||||
# username: ROOT
|
||||
# password: root
|
||||
# hikari:
|
||||
# connectionTestQuery: SELECT 1 FROM DUAL
|
||||
# Oracle 数据源
|
||||
acid-l2:
|
||||
lazy: true
|
||||
type: ${spring.datasource.type}
|
||||
driverClassName: oracle.jdbc.OracleDriver
|
||||
# 示例:jdbc:oracle:thin:@//localhost:1521/XE
|
||||
url: jdbc:oracle:thin:@//localhost:1521/XE
|
||||
username: ROOT
|
||||
password: root
|
||||
hikari:
|
||||
connectionTestQuery: SELECT 1 FROM DUAL
|
||||
# postgres:
|
||||
# type: ${spring.datasource.type}
|
||||
# driverClassName: org.postgresql.Driver
|
||||
|
||||
@@ -7,6 +7,12 @@ klp:
|
||||
# 生产环境文件存储目录
|
||||
directory-path: /home/ubuntu/oa/folder
|
||||
|
||||
--- # sql-server-api 中间件配置(生产环境)
|
||||
sql-server-api:
|
||||
host: 140.143.206.120
|
||||
port: 15000
|
||||
base-url: http://${sql-server-api.host}:${sql-server-api.port}
|
||||
|
||||
--- # OEE 聚合(klp-da)多服务地址配置
|
||||
da:
|
||||
oee:
|
||||
@@ -86,14 +92,17 @@ spring:
|
||||
url: jdbc:mysql://140.143.206.120:3306/cgldb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
|
||||
username: klp
|
||||
password: KeLunPu123@
|
||||
# oracle:
|
||||
# type: ${spring.datasource.type}
|
||||
# driverClassName: oracle.jdbc.OracleDriver
|
||||
# url: jdbc:oracle:thin:@//localhost:1521/XE
|
||||
# username: ROOT
|
||||
# password: root
|
||||
# hikari:
|
||||
# connectionTestQuery: SELECT 1 FROM DUAL
|
||||
# Oracle 数据源
|
||||
acid-l2:
|
||||
lazy: true
|
||||
type: ${spring.datasource.type}
|
||||
driverClassName: oracle.jdbc.OracleDriver
|
||||
# 示例:jdbc:oracle:thin:@//localhost:1521/XE
|
||||
url: jdbc:oracle:thin:@//localhost:1521/XE
|
||||
username: ROOT
|
||||
password: root
|
||||
hikari:
|
||||
connectionTestQuery: SELECT 1 FROM DUAL
|
||||
# postgres:
|
||||
# type: ${spring.datasource.type}
|
||||
# driverClassName: org.postgresql.Driver
|
||||
|
||||
@@ -53,7 +53,7 @@ server:
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
com.klp: @logging.level@
|
||||
com.klp: warn
|
||||
org.springframework: warn
|
||||
config: classpath:logback-plus.xml
|
||||
|
||||
@@ -65,6 +65,7 @@ user:
|
||||
# 密码锁定时间(默认10分钟)
|
||||
lockTime: 10
|
||||
|
||||
# sql-server-api 中间件配置
|
||||
# Spring配置
|
||||
spring:
|
||||
application:
|
||||
@@ -154,7 +155,7 @@ security:
|
||||
- /test/**
|
||||
- /klp/generateRecord
|
||||
- /klp/generateRecord/**
|
||||
|
||||
- /wms/coilPendingAction/**
|
||||
# 测接口
|
||||
# - /ems/energyConsumption
|
||||
# - /ems/energyConsumption/**
|
||||
@@ -260,8 +261,8 @@ springdoc:
|
||||
xss:
|
||||
# 过滤开关
|
||||
enabled: true
|
||||
# 排除链接(多个用逗号分隔)
|
||||
excludes: /system/notice
|
||||
# 排除链接(多个用逗号分隔)
|
||||
excludes: /system/notice,/system/dict/data
|
||||
# 匹配链接
|
||||
urlPatterns: /system/*,/monitor/*,/tool/*
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
-- 冷轧涂镀数智运营 - 规程主表
|
||||
CREATE TABLE wms_process_spec (
|
||||
spec_id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
spec_code VARCHAR(64) NOT NULL COMMENT '规程编号',
|
||||
spec_name VARCHAR(200) NOT NULL COMMENT '规程名称',
|
||||
spec_type VARCHAR(32) NOT NULL DEFAULT 'PROCESS' COMMENT '类型(PROCESS=工艺规程,STANDARD=标准)',
|
||||
line_id BIGINT NOT NULL COMMENT '产线ID',
|
||||
product_type VARCHAR(100) NULL COMMENT '产品类型',
|
||||
is_enabled TINYINT NOT NULL DEFAULT 1 COMMENT '是否启用(0否1是)',
|
||||
create_by VARCHAR(64) NULL COMMENT '创建人',
|
||||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
update_by VARCHAR(64) NULL COMMENT '更新人',
|
||||
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
del_flag TINYINT NOT NULL DEFAULT 0 COMMENT '删除标志(0正常2删除,与全局逻辑删除配置一致)',
|
||||
remark VARCHAR(500) NULL COMMENT '备注',
|
||||
PRIMARY KEY (spec_id),
|
||||
UNIQUE KEY uk_wms_process_spec_code (spec_code),
|
||||
KEY idx_wms_process_spec_line (line_id),
|
||||
KEY idx_wms_process_spec_type (spec_type)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='规程主表';
|
||||
@@ -0,0 +1,39 @@
|
||||
-- 规程版本表
|
||||
CREATE TABLE wms_process_spec_version (
|
||||
version_id BIGINT NOT NULL COMMENT '主键',
|
||||
spec_id BIGINT NOT NULL COMMENT '规程主表ID',
|
||||
version_code VARCHAR(64) NOT NULL COMMENT '版本号',
|
||||
is_active TINYINT NOT NULL DEFAULT 0 COMMENT '是否当前生效(0否1是)',
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'DRAFT' COMMENT '状态(DRAFT草稿/PUBLISHED已发布/OBSOLETE作废等)',
|
||||
create_by VARCHAR(64) NULL COMMENT '创建人',
|
||||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
update_by VARCHAR(64) NULL COMMENT '更新人',
|
||||
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
del_flag TINYINT NOT NULL DEFAULT 0 COMMENT '删除标志(0正常2删除)',
|
||||
remark VARCHAR(500) NULL COMMENT '备注',
|
||||
PRIMARY KEY (version_id),
|
||||
UNIQUE KEY uk_spec_version_code (spec_id, version_code),
|
||||
KEY idx_spec_version_spec (spec_id),
|
||||
KEY idx_spec_version_active (spec_id, is_active)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='规程版本表';
|
||||
|
||||
-- 方案点位表
|
||||
CREATE TABLE wms_process_plan (
|
||||
plan_id BIGINT NOT NULL COMMENT '主键',
|
||||
version_id BIGINT NOT NULL COMMENT '规程版本ID',
|
||||
segment_type VARCHAR(32) NOT NULL COMMENT '段类型(INLET/PROCESS/OUTLET)',
|
||||
segment_name VARCHAR(100) NULL COMMENT '段名称',
|
||||
point_name VARCHAR(200) NOT NULL COMMENT '点位名称',
|
||||
point_code VARCHAR(64) NOT NULL COMMENT '点位编码',
|
||||
sort_order INT NOT NULL DEFAULT 0 COMMENT '排序',
|
||||
create_by VARCHAR(64) NULL COMMENT '创建人',
|
||||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
update_by VARCHAR(64) NULL COMMENT '更新人',
|
||||
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
del_flag TINYINT NOT NULL DEFAULT 0 COMMENT '删除标志(0正常2删除)',
|
||||
remark VARCHAR(500) NULL COMMENT '备注',
|
||||
PRIMARY KEY (plan_id),
|
||||
UNIQUE KEY uk_plan_version_point_code (version_id, point_code),
|
||||
KEY idx_plan_version (version_id),
|
||||
KEY idx_plan_sort (version_id, sort_order)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='方案点位表';
|
||||
@@ -0,0 +1,20 @@
|
||||
-- 方案参数表
|
||||
CREATE TABLE wms_process_plan_param (
|
||||
param_id BIGINT NOT NULL COMMENT '主键',
|
||||
plan_id BIGINT NOT NULL COMMENT '方案点位ID',
|
||||
param_code VARCHAR(64) NOT NULL COMMENT '参数编码',
|
||||
param_name VARCHAR(200) NOT NULL COMMENT '参数名称',
|
||||
target_value DECIMAL(24, 6) NULL COMMENT '设定值',
|
||||
lower_limit DECIMAL(24, 6) NULL COMMENT '下限',
|
||||
upper_limit DECIMAL(24, 6) NULL COMMENT '上限',
|
||||
unit VARCHAR(32) NULL COMMENT '单位',
|
||||
create_by VARCHAR(64) NULL COMMENT '创建人',
|
||||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
update_by VARCHAR(64) NULL COMMENT '更新人',
|
||||
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
del_flag TINYINT NOT NULL DEFAULT 0 COMMENT '删除标志(0正常2删除)',
|
||||
remark VARCHAR(500) NULL COMMENT '备注',
|
||||
PRIMARY KEY (param_id),
|
||||
UNIQUE KEY uk_plan_param_code (plan_id, param_code),
|
||||
KEY idx_plan_param_plan (plan_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='方案参数表';
|
||||
@@ -21,6 +21,7 @@ import com.klp.aps.domain.vo.ApsPlanDetailVo;
|
||||
import com.klp.aps.domain.bo.ApsPlanDetailBo;
|
||||
import com.klp.aps.service.IApsPlanDetailService;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.domain.vo.WmsMaterialCoilVo;
|
||||
|
||||
/**
|
||||
* 排产单明细
|
||||
@@ -96,4 +97,11 @@ public class ApsPlanDetailController extends BaseController {
|
||||
@PathVariable Long[] planDetailIds) {
|
||||
return toAjax(iApsPlanDetailService.deleteWithValidByIds(Arrays.asList(planDetailIds), true));
|
||||
}
|
||||
|
||||
// 根据排产单ID查询排产日期以及明细绑定的orderId,再根据这个orderId和排查时间查询返回钢卷
|
||||
@GetMapping("/coils/{planSheetId}")
|
||||
public R<List<WmsMaterialCoilVo>> getCoilsByPlanSheetId(@NotNull(message = "排产单ID不能为空")
|
||||
@PathVariable Long planSheetId) {
|
||||
return R.ok(iApsPlanDetailService.queryCoilsByPlanSheetId(planSheetId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import javax.validation.constraints.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
@@ -31,6 +32,11 @@ public class ApsPlanDetailBo extends BaseEntity {
|
||||
*/
|
||||
private Long planSheetId;
|
||||
|
||||
/**
|
||||
* 关联排产单ID列表(用于批量查询)
|
||||
*/
|
||||
private List<Long> planSheetIds;
|
||||
|
||||
/**
|
||||
* 内容序号
|
||||
*/
|
||||
|
||||
@@ -18,5 +18,5 @@ import java.util.List;
|
||||
*/
|
||||
public interface ApsPlanSheetMapper extends BaseMapperPlus<ApsPlanSheetMapper, ApsPlanSheet, ApsPlanSheetVo> {
|
||||
|
||||
List<ApsPlanSheetRowVo> selectList(ApsPlanSheetQueryReq req);
|
||||
List<ApsPlanSheetRowVo> selectListByReq(ApsPlanSheetQueryReq req);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import com.klp.common.core.domain.PageQuery;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.klp.domain.vo.WmsMaterialCoilVo;
|
||||
|
||||
/**
|
||||
* 排产单明细Service接口
|
||||
*
|
||||
@@ -31,6 +33,11 @@ public interface IApsPlanDetailService {
|
||||
*/
|
||||
List<ApsPlanDetailVo> queryList(ApsPlanDetailBo bo);
|
||||
|
||||
/**
|
||||
* 根据排产单ID列表查询明细
|
||||
*/
|
||||
List<ApsPlanDetailVo> queryListByPlanSheetIds(List<Long> planSheetIds);
|
||||
|
||||
/**
|
||||
* 新增排产单明细
|
||||
*/
|
||||
@@ -50,4 +57,12 @@ public interface IApsPlanDetailService {
|
||||
* 根据排产单ID删除明细
|
||||
*/
|
||||
int deleteByPlanSheetIds(Collection<Long> planSheetIds);
|
||||
|
||||
/**
|
||||
* 根据排产单ID查询关联的钢卷列表(根据计划日期筛选钢卷创建时间)
|
||||
*
|
||||
* @param planSheetId 排产单ID
|
||||
* @return 钢卷列表
|
||||
*/
|
||||
List<WmsMaterialCoilVo> queryCoilsByPlanSheetId(Long planSheetId);
|
||||
}
|
||||
|
||||
@@ -8,17 +8,24 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.klp.common.utils.StringUtils;
|
||||
import com.klp.domain.WmsCoilContractRel;
|
||||
import com.klp.domain.vo.WmsMaterialCoilVo;
|
||||
import com.klp.domain.vo.WmsCoilContractRelVo;
|
||||
import com.klp.domain.bo.WmsMaterialCoilBo;
|
||||
import com.klp.mapper.WmsCoilContractRelMapper;
|
||||
import com.klp.service.IWmsMaterialCoilService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.klp.aps.domain.bo.ApsPlanDetailBo;
|
||||
import com.klp.aps.domain.vo.ApsPlanDetailVo;
|
||||
import com.klp.aps.domain.vo.ApsPlanSheetVo;
|
||||
import com.klp.aps.domain.entity.ApsPlanDetail;
|
||||
import com.klp.aps.mapper.ApsPlanDetailMapper;
|
||||
import com.klp.aps.mapper.ApsPlanSheetMapper;
|
||||
import com.klp.aps.service.IApsPlanDetailService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 排产单明细Service业务层处理
|
||||
@@ -31,6 +38,9 @@ import java.util.Collection;
|
||||
public class ApsPlanDetailServiceImpl implements IApsPlanDetailService {
|
||||
|
||||
private final ApsPlanDetailMapper baseMapper;
|
||||
private final ApsPlanSheetMapper planSheetMapper;
|
||||
private final WmsCoilContractRelMapper coilContractRelMapper;
|
||||
private final IWmsMaterialCoilService materialCoilService;
|
||||
|
||||
/**
|
||||
* 查询排产单明细
|
||||
@@ -105,6 +115,19 @@ public class ApsPlanDetailServiceImpl implements IApsPlanDetailService {
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据排产单ID列表查询明细
|
||||
*/
|
||||
@Override
|
||||
public List<ApsPlanDetailVo> queryListByPlanSheetIds(List<Long> planSheetIds) {
|
||||
if (planSheetIds == null || planSheetIds.isEmpty()) {
|
||||
return new java.util.ArrayList<>();
|
||||
}
|
||||
LambdaQueryWrapper<ApsPlanDetail> lqw = Wrappers.lambdaQuery();
|
||||
lqw.in(ApsPlanDetail::getPlanSheetId, planSheetIds);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<ApsPlanDetail> buildQueryWrapper(ApsPlanDetailBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<ApsPlanDetail> lqw = Wrappers.lambdaQuery();
|
||||
@@ -194,4 +217,84 @@ public class ApsPlanDetailServiceImpl implements IApsPlanDetailService {
|
||||
public int deleteByPlanSheetIds(Collection<Long> planSheetIds) {
|
||||
return baseMapper.deleteByPlanSheetIds(planSheetIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WmsMaterialCoilVo> queryCoilsByPlanSheetId(Long planSheetId) {
|
||||
if (planSheetId == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
ApsPlanSheetVo planSheet = planSheetMapper.selectVoById(planSheetId);
|
||||
if (planSheet == null || planSheet.getPlanDate() == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Date planDate = planSheet.getPlanDate();
|
||||
|
||||
LambdaQueryWrapper<ApsPlanDetail> detailQw = Wrappers.lambdaQuery();
|
||||
detailQw.eq(ApsPlanDetail::getPlanSheetId, planSheetId);
|
||||
detailQw.eq(ApsPlanDetail::getDelFlag, 0);
|
||||
List<ApsPlanDetailVo> details = baseMapper.selectVoList(detailQw);
|
||||
|
||||
List<Long> orderIds = details.stream()
|
||||
.map(ApsPlanDetailVo::getOrderId)
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (orderIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
LambdaQueryWrapper<WmsCoilContractRel> relQw = Wrappers.lambdaQuery();
|
||||
relQw.in(WmsCoilContractRel::getContractId, orderIds);
|
||||
relQw.eq(WmsCoilContractRel::getDelFlag, 0);
|
||||
List<WmsCoilContractRelVo> coilRels = coilContractRelMapper.selectVoList(relQw);
|
||||
|
||||
Map<Long, List<Long>> coilIdMap = coilRels.stream()
|
||||
.filter(rel -> rel.getContractId() != null && rel.getCoilId() != null)
|
||||
.collect(Collectors.groupingBy(
|
||||
WmsCoilContractRelVo::getContractId,
|
||||
Collectors.mapping(WmsCoilContractRelVo::getCoilId, Collectors.toList())
|
||||
));
|
||||
|
||||
Set<Long> allCoilIds = coilIdMap.values().stream()
|
||||
.flatMap(List::stream)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (allCoilIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
WmsMaterialCoilBo coilBo = new WmsMaterialCoilBo();
|
||||
coilBo.setCoilIds(allCoilIds.stream().map(String::valueOf).collect(Collectors.joining(",")));
|
||||
coilBo.setByCreateTimeStart(getStartOfDay(planDate));
|
||||
coilBo.setByCreateTimeEnd(getEndOfDay(planDate));
|
||||
|
||||
return materialCoilService.queryList(coilBo);
|
||||
}
|
||||
|
||||
private Date getStartOfDay(Date date) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
cal.set(Calendar.HOUR_OF_DAY, 0);
|
||||
cal.set(Calendar.MINUTE, 0);
|
||||
cal.set(Calendar.SECOND, 0);
|
||||
cal.set(Calendar.MILLISECOND, 0);
|
||||
return cal.getTime();
|
||||
}
|
||||
|
||||
private Date getEndOfDay(Date date) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
cal.set(Calendar.HOUR_OF_DAY, 23);
|
||||
cal.set(Calendar.MINUTE, 59);
|
||||
cal.set(Calendar.SECOND, 59);
|
||||
cal.set(Calendar.MILLISECOND, 999);
|
||||
return cal.getTime();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,7 +283,7 @@ public class ApsPlanSheetServiceImpl implements IApsPlanSheetService {
|
||||
|
||||
// ================== 【核心:前7列自动合并】 ==================
|
||||
int dataEndRow = r - 1;
|
||||
if (dataStartRow <= dataEndRow) {
|
||||
if (dataStartRow <= dataEndRow && dataEndRow > dataStartRow) {
|
||||
for (int col = 0; col < 7; col++) { // 0~6 共7列
|
||||
CellRangeAddress region = new CellRangeAddress(
|
||||
dataStartRow,
|
||||
@@ -318,7 +318,7 @@ public class ApsPlanSheetServiceImpl implements IApsPlanSheetService {
|
||||
}
|
||||
|
||||
private List<ApsPlanSheetRowVo> queryListAll(ApsPlanSheetQueryReq req) {
|
||||
return baseMapper.selectList(req);
|
||||
return baseMapper.selectListByReq(req);
|
||||
}
|
||||
|
||||
private String nvl(Object v, Object fallback) {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
</resultMap>
|
||||
<select id="selectList" parameterType="com.klp.aps.domain.dto.ApsPlanSheetQueryReq" resultType="com.klp.aps.domain.vo.ApsPlanSheetRowVo">
|
||||
<select id="selectListByReq" parameterType="com.klp.aps.domain.dto.ApsPlanSheetQueryReq" resultType="com.klp.aps.domain.vo.ApsPlanSheetRowVo">
|
||||
SELECT
|
||||
d.plan_detail_id AS detailSheetId,
|
||||
s.plan_date AS planDate,
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
@@ -43,5 +43,9 @@
|
||||
<groupId>com.klp</groupId>
|
||||
<artifactId>klp-wms</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.klp</groupId>
|
||||
<artifactId>klp-aps</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
package com.klp.crm.controller;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
|
||||
import com.klp.aps.domain.bo.ApsPlanDetailBo;
|
||||
import com.klp.aps.domain.bo.ApsPlanSheetBo;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.*;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import com.klp.common.annotation.RepeatSubmit;
|
||||
import com.klp.common.annotation.Log;
|
||||
@@ -21,6 +26,10 @@ import com.klp.crm.domain.vo.CrmOrderVo;
|
||||
import com.klp.crm.domain.bo.CrmOrderBo;
|
||||
import com.klp.crm.service.ICrmOrderService;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.aps.domain.vo.ApsPlanSheetVo;
|
||||
import com.klp.aps.domain.vo.ApsPlanDetailVo;
|
||||
import com.klp.aps.service.IApsPlanSheetService;
|
||||
import com.klp.aps.service.IApsPlanDetailService;
|
||||
|
||||
/**
|
||||
* 正式订单主
|
||||
@@ -35,6 +44,8 @@ import com.klp.common.core.page.TableDataInfo;
|
||||
public class CrmOrderController extends BaseController {
|
||||
|
||||
private final ICrmOrderService iCrmOrderService;
|
||||
private final IApsPlanSheetService iApsPlanSheetService;
|
||||
private final IApsPlanDetailService iApsPlanDetailService;
|
||||
|
||||
/**
|
||||
* 查询正式订单主列表
|
||||
@@ -96,4 +107,54 @@ public class CrmOrderController extends BaseController {
|
||||
@PathVariable String[] orderIds) {
|
||||
return toAjax(iCrmOrderService.deleteWithValidByIds(Arrays.asList(orderIds), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询每日订单(根据排产计划获取今天的订单)
|
||||
*
|
||||
* @param planDate 排产日期,默认今天
|
||||
*/
|
||||
@GetMapping("/daily")
|
||||
public R<List<CrmOrderVo>> getDailyOrders(
|
||||
@RequestParam(value = "planDate", required = false)
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd") Date planDate) {
|
||||
if (planDate == null) {
|
||||
planDate = new Date();
|
||||
}
|
||||
// 将日期设置为当天的开始时间 00:00:00
|
||||
java.util.Calendar calendar = java.util.Calendar.getInstance();
|
||||
calendar.setTime(planDate);
|
||||
calendar.set(java.util.Calendar.HOUR_OF_DAY, 0);
|
||||
calendar.set(java.util.Calendar.MINUTE, 0);
|
||||
calendar.set(java.util.Calendar.SECOND, 0);
|
||||
calendar.set(java.util.Calendar.MILLISECOND, 0);
|
||||
planDate = calendar.getTime();
|
||||
|
||||
ApsPlanSheetBo bo = new ApsPlanSheetBo();
|
||||
bo.setPlanDate(planDate);
|
||||
List<ApsPlanSheetVo> planSheetList = iApsPlanSheetService.queryList(bo);
|
||||
if (planSheetList == null || planSheetList.isEmpty()) {
|
||||
return R.ok(new ArrayList<>());
|
||||
}
|
||||
List<Long> planSheetIds = new ArrayList<>();
|
||||
for (ApsPlanSheetVo sheet : planSheetList) {
|
||||
planSheetIds.add(sheet.getPlanSheetId());
|
||||
}
|
||||
ApsPlanDetailBo detailBo = new ApsPlanDetailBo();
|
||||
detailBo.setPlanSheetIds(planSheetIds);
|
||||
List<ApsPlanDetailVo> detailList = iApsPlanDetailService.queryListByPlanSheetIds(planSheetIds);
|
||||
if (detailList == null || detailList.isEmpty()) {
|
||||
return R.ok(new ArrayList<>());
|
||||
}
|
||||
List<Long> orderIds = new ArrayList<>();
|
||||
for (ApsPlanDetailVo detail : detailList) {
|
||||
if (detail.getOrderId() != null) {
|
||||
orderIds.add(detail.getOrderId());
|
||||
}
|
||||
}
|
||||
if (orderIds.isEmpty()) {
|
||||
return R.ok(new ArrayList<>());
|
||||
}
|
||||
List<CrmOrderVo> orders = iCrmOrderService.queryByIds(orderIds);
|
||||
return R.ok(orders);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,30 @@ public class CrmOrderItem extends BaseEntity {
|
||||
* 排产批次
|
||||
*/
|
||||
private String productionBatch;
|
||||
/**
|
||||
* 表面处理
|
||||
*/
|
||||
private String surfaceTreatment;
|
||||
/**
|
||||
* 切边要求
|
||||
*/
|
||||
private String edgeCuttingReq;
|
||||
/**
|
||||
* 包装要求
|
||||
*/
|
||||
private String packagingReq;
|
||||
/**
|
||||
* 宽度
|
||||
*/
|
||||
private BigDecimal width;
|
||||
/**
|
||||
* 厚度
|
||||
*/
|
||||
private BigDecimal thickness;
|
||||
/**
|
||||
* 用途
|
||||
*/
|
||||
private String purpose;
|
||||
/**
|
||||
* 删除标识 0正常 2删除
|
||||
*/
|
||||
|
||||
@@ -108,5 +108,34 @@ public class CrmOrderItemBo extends BaseEntity {
|
||||
*/
|
||||
private String productionBatch;
|
||||
|
||||
/**
|
||||
* 表面处理
|
||||
*/
|
||||
private String surfaceTreatment;
|
||||
|
||||
/**
|
||||
* 切边要求
|
||||
*/
|
||||
private String edgeCuttingReq;
|
||||
|
||||
/**
|
||||
* 包装要求
|
||||
*/
|
||||
private String packagingReq;
|
||||
|
||||
/**
|
||||
* 宽度
|
||||
*/
|
||||
private BigDecimal width;
|
||||
|
||||
/**
|
||||
* 厚度
|
||||
*/
|
||||
private BigDecimal thickness;
|
||||
|
||||
/**
|
||||
* 用途
|
||||
*/
|
||||
private String purpose;
|
||||
|
||||
}
|
||||
|
||||
@@ -131,5 +131,40 @@ public class CrmOrderItemVo {
|
||||
@ExcelProperty(value = "排产批次")
|
||||
private String productionBatch;
|
||||
|
||||
/**
|
||||
* 表面处理
|
||||
*/
|
||||
@ExcelProperty(value = "表面处理")
|
||||
private String surfaceTreatment;
|
||||
|
||||
/**
|
||||
* 切边要求
|
||||
*/
|
||||
@ExcelProperty(value = "切边要求")
|
||||
private String edgeCuttingReq;
|
||||
|
||||
/**
|
||||
* 包装要求
|
||||
*/
|
||||
@ExcelProperty(value = "包装要求")
|
||||
private String packagingReq;
|
||||
|
||||
/**
|
||||
* 宽度
|
||||
*/
|
||||
@ExcelProperty(value = "宽度")
|
||||
private BigDecimal width;
|
||||
|
||||
/**
|
||||
* 厚度
|
||||
*/
|
||||
@ExcelProperty(value = "厚度")
|
||||
private BigDecimal thickness;
|
||||
|
||||
/**
|
||||
* 用途
|
||||
*/
|
||||
@ExcelProperty(value = "用途")
|
||||
private String purpose;
|
||||
|
||||
}
|
||||
|
||||
@@ -2,12 +2,15 @@ package com.klp.crm.domain.vo;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.klp.common.annotation.ExcelDictFormat;
|
||||
import com.klp.common.convert.ExcelDictConvert;
|
||||
import com.klp.common.core.domain.BaseEntity;
|
||||
import com.klp.domain.vo.WmsMaterialCoilVo;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
@@ -292,4 +295,8 @@ public class CrmOrderVo extends BaseEntity {
|
||||
private String createByName;
|
||||
//更新人
|
||||
private String updateByName;
|
||||
/**
|
||||
* 关联的钢卷列表
|
||||
*/
|
||||
private List<WmsMaterialCoilVo> coilList;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,11 @@ public interface ICrmOrderService {
|
||||
*/
|
||||
CrmOrderVo queryById(String orderId);
|
||||
|
||||
/**
|
||||
* 根据ID列表查询正式订单
|
||||
*/
|
||||
List<CrmOrderVo> queryByIds(List<Long> orderIds);
|
||||
|
||||
/**
|
||||
* 查询正式订单主列表
|
||||
*/
|
||||
|
||||
@@ -101,6 +101,12 @@ public class CrmOrderItemServiceImpl implements ICrmOrderItemService {
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getCustomizer()), CrmOrderItem::getCustomizer, bo.getCustomizer());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getShipper()), CrmOrderItem::getShipper, bo.getShipper());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getProductionBatch()), CrmOrderItem::getProductionBatch, bo.getProductionBatch());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getSurfaceTreatment()), CrmOrderItem::getSurfaceTreatment, bo.getSurfaceTreatment());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getEdgeCuttingReq()), CrmOrderItem::getEdgeCuttingReq, bo.getEdgeCuttingReq());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getPackagingReq()), CrmOrderItem::getPackagingReq, bo.getPackagingReq());
|
||||
lqw.eq(bo.getWidth() != null, CrmOrderItem::getWidth, bo.getWidth());
|
||||
lqw.eq(bo.getThickness() != null, CrmOrderItem::getThickness, bo.getThickness());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getPurpose()), CrmOrderItem::getPurpose, bo.getPurpose());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.klp.common.utils.StringUtils;
|
||||
import com.klp.crm.domain.vo.CrmOrderOperationTraceVo;
|
||||
import com.klp.mapper.WmsCoilContractRelMapper;
|
||||
import com.klp.system.service.ISysUserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -17,6 +18,11 @@ import com.klp.crm.domain.vo.CrmOrderVo;
|
||||
import com.klp.crm.domain.CrmOrder;
|
||||
import com.klp.crm.mapper.CrmOrderMapper;
|
||||
import com.klp.crm.service.ICrmOrderService;
|
||||
import com.klp.domain.WmsCoilContractRel;
|
||||
import com.klp.domain.bo.WmsMaterialCoilBo;
|
||||
import com.klp.domain.vo.WmsMaterialCoilVo;
|
||||
import com.klp.service.IWmsCoilContractRelService;
|
||||
import com.klp.service.IWmsMaterialCoilService;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -35,6 +41,10 @@ public class CrmOrderServiceImpl implements ICrmOrderService {
|
||||
|
||||
private final ISysUserService userService;
|
||||
|
||||
private final WmsCoilContractRelMapper coilContractRelMapper;
|
||||
|
||||
private final IWmsMaterialCoilService materialCoilService;
|
||||
|
||||
/**
|
||||
* 查询正式订单主
|
||||
*/
|
||||
@@ -43,6 +53,19 @@ public class CrmOrderServiceImpl implements ICrmOrderService {
|
||||
return baseMapper.selectVoById(orderId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID列表查询正式订单
|
||||
*/
|
||||
@Override
|
||||
public List<CrmOrderVo> queryByIds(List<Long> orderIds) {
|
||||
if (orderIds == null || orderIds.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
LambdaQueryWrapper<CrmOrder> lqw = Wrappers.lambdaQuery();
|
||||
lqw.in(CrmOrder::getOrderId, orderIds);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询正式订单主列表
|
||||
*/
|
||||
@@ -76,6 +99,57 @@ public class CrmOrderServiceImpl implements ICrmOrderService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 查询订单关联的钢卷ID列表
|
||||
List<Long> contractIds = records.stream()
|
||||
.map(CrmOrderVo::getOrderId)
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (!contractIds.isEmpty()) {
|
||||
// 批量查询钢卷与合同关联关系
|
||||
LambdaQueryWrapper<WmsCoilContractRel> coilQw = Wrappers.lambdaQuery();
|
||||
coilQw.in(WmsCoilContractRel::getContractId, contractIds);
|
||||
coilQw.eq(WmsCoilContractRel::getDelFlag, 0);
|
||||
List<WmsCoilContractRel> coilRels = coilContractRelMapper.selectList(coilQw);
|
||||
|
||||
// 按contractId分组,收集coilId列表
|
||||
Map<Long, List<Long>> coilIdMap = coilRels.stream()
|
||||
.filter(rel -> rel.getContractId() != null && rel.getCoilId() != null)
|
||||
.collect(Collectors.groupingBy(
|
||||
WmsCoilContractRel::getContractId,
|
||||
Collectors.mapping(WmsCoilContractRel::getCoilId, Collectors.toList())
|
||||
));
|
||||
|
||||
// 查询所有相关钢卷的详细信息
|
||||
Set<Long> allCoilIds = coilIdMap.values().stream()
|
||||
.flatMap(List::stream)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
Map<Long, WmsMaterialCoilVo> coilVoMap = Collections.emptyMap();
|
||||
if (!allCoilIds.isEmpty()) {
|
||||
WmsMaterialCoilBo coilBo = new WmsMaterialCoilBo();
|
||||
coilBo.setCoilIds(allCoilIds.stream().map(String::valueOf).collect(Collectors.joining(",")));
|
||||
List<WmsMaterialCoilVo> allCoils = materialCoilService.queryList(coilBo);
|
||||
coilVoMap = allCoils.stream()
|
||||
.collect(Collectors.toMap(WmsMaterialCoilVo::getCoilId, c -> c, (a, b) -> a));
|
||||
}
|
||||
|
||||
// 设置到每个订单的coilIds和coilList字段
|
||||
for (CrmOrderVo vo : records) {
|
||||
if (vo.getOrderId() != null && coilIdMap.containsKey(vo.getOrderId())) {
|
||||
List<Long> coilIdList = coilIdMap.get(vo.getOrderId());
|
||||
// 设置coilList(钢卷详细信息列表)
|
||||
List<WmsMaterialCoilVo> coilList = coilIdList.stream()
|
||||
.map(coilVoMap::get)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
vo.setCoilList(coilList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="customizer" column="customizer"/>
|
||||
<result property="shipper" column="shipper"/>
|
||||
<result property="productionBatch" column="production_batch"/>
|
||||
<result property="surfaceTreatment" column="surface_treatment"/>
|
||||
<result property="edgeCuttingReq" column="edge_cutting_req"/>
|
||||
<result property="packagingReq" column="packaging_req"/>
|
||||
<result property="width" column="width"/>
|
||||
<result property="thickness" column="thickness"/>
|
||||
<result property="purpose" column="purpose"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
@@ -50,6 +56,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
customizer,
|
||||
shipper,
|
||||
production_batch,
|
||||
surface_treatment,
|
||||
edge_cutting_req,
|
||||
packaging_req,
|
||||
width,
|
||||
thickness,
|
||||
purpose,
|
||||
create_by,
|
||||
create_time,
|
||||
update_by,
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.klp.ems.controller;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.*;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import com.klp.common.annotation.RepeatSubmit;
|
||||
import com.klp.common.annotation.Log;
|
||||
import com.klp.common.core.controller.BaseController;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.klp.common.core.domain.R;
|
||||
import com.klp.common.core.validate.AddGroup;
|
||||
import com.klp.common.core.validate.EditGroup;
|
||||
import com.klp.common.enums.BusinessType;
|
||||
import com.klp.common.utils.poi.ExcelUtil;
|
||||
import com.klp.ems.domain.vo.EmsEnergyRecordVo;
|
||||
import com.klp.ems.domain.bo.EmsEnergyRecordBo;
|
||||
import com.klp.ems.service.IEmsEnergyRecordService;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 能源消耗记录
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-04-20
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/ems/energyRecord")
|
||||
public class EmsEnergyRecordController extends BaseController {
|
||||
|
||||
private final IEmsEnergyRecordService iEmsEnergyRecordService;
|
||||
|
||||
/**
|
||||
* 查询能源消耗记录列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<EmsEnergyRecordVo> list(EmsEnergyRecordBo bo, PageQuery pageQuery) {
|
||||
return iEmsEnergyRecordService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出能源消耗记录列表
|
||||
*/
|
||||
@Log(title = "能源消耗记录", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(EmsEnergyRecordBo bo, HttpServletResponse response) {
|
||||
List<EmsEnergyRecordVo> list = iEmsEnergyRecordService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "能源消耗记录", EmsEnergyRecordVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取能源消耗记录详细信息
|
||||
*
|
||||
* @param energyRecordId 主键
|
||||
*/
|
||||
@GetMapping("/{energyRecordId}")
|
||||
public R<EmsEnergyRecordVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long energyRecordId) {
|
||||
return R.ok(iEmsEnergyRecordService.queryById(energyRecordId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增能源消耗记录
|
||||
*/
|
||||
@Log(title = "能源消耗记录", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
public R<Long> add(@Validated(AddGroup.class) @RequestBody EmsEnergyRecordBo bo) {
|
||||
return R.ok(iEmsEnergyRecordService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改能源消耗记录
|
||||
*/
|
||||
@Log(title = "能源消耗记录", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody EmsEnergyRecordBo bo) {
|
||||
return toAjax(iEmsEnergyRecordService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除能源消耗记录
|
||||
*
|
||||
* @param energyRecordIds 主键串
|
||||
*/
|
||||
@Log(title = "能源消耗记录", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{energyRecordIds}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@PathVariable Long[] energyRecordIds) {
|
||||
return toAjax(iEmsEnergyRecordService.deleteWithValidByIds(Arrays.asList(energyRecordIds), true));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.klp.ems.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.klp.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
/**
|
||||
* 能源消耗记录对象 ems_energy_record
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-04-20
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("ems_energy_record")
|
||||
public class EmsEnergyRecord extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID=1L;
|
||||
|
||||
/**
|
||||
* 能耗记录主键ID
|
||||
*/
|
||||
@TableId(value = "energy_record_id")
|
||||
private Long energyRecordId;
|
||||
/**
|
||||
* 表计ID(关联计量设备表)
|
||||
*/
|
||||
private Long meterId;
|
||||
/**
|
||||
* 能源ID(关联能源类型表:电/水/气/暖等)
|
||||
*/
|
||||
private Long energyId;
|
||||
/**
|
||||
* 消耗量
|
||||
*/
|
||||
private BigDecimal consumption;
|
||||
/**
|
||||
* 统计日期(yyyy-MM-dd)
|
||||
*/
|
||||
private Date recordDate;
|
||||
/**
|
||||
* 记录人ID
|
||||
*/
|
||||
private Long recordedBy;
|
||||
/**
|
||||
* 删除标志(0=存在 2=删除)
|
||||
*/
|
||||
@TableLogic
|
||||
private String delFlag;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
}
|
||||
@@ -72,5 +72,13 @@ public class EmsMeter extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 产线(如:S1、S2、组装线、包装线等)
|
||||
*/
|
||||
private String productionLine;
|
||||
/**
|
||||
* 是否总表:0=否,1=是
|
||||
*/
|
||||
private Integer isTotalMeter;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.klp.ems.domain.bo;
|
||||
|
||||
import com.klp.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
/**
|
||||
* 能源消耗记录业务对象 ems_energy_record
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-04-20
|
||||
*/
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class EmsEnergyRecordBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 能耗记录主键ID
|
||||
*/
|
||||
private Long energyRecordId;
|
||||
|
||||
/**
|
||||
* 表计ID(关联计量设备表)
|
||||
*/
|
||||
private Long meterId;
|
||||
|
||||
/**
|
||||
* 能源ID(关联能源类型表:电/水/气/暖等)
|
||||
*/
|
||||
private Long energyId;
|
||||
|
||||
/**
|
||||
* 消耗量
|
||||
*/
|
||||
private BigDecimal consumption;
|
||||
|
||||
/**
|
||||
* 统计日期(yyyy-MM-dd)
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
private Date recordDate;
|
||||
|
||||
/**
|
||||
* 统计日期开始时间(yyyy-MM-dd,不含时分秒)
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
private Date recordStartDate;
|
||||
|
||||
/**
|
||||
* 统计日期结束时间(yyyy-MM-dd,不含时分秒)
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
private Date recordEndDate;
|
||||
/**
|
||||
* 记录人ID
|
||||
*/
|
||||
private Long recordedBy;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 表计编号(模糊查询)
|
||||
*/
|
||||
private String meterCode;
|
||||
|
||||
/**
|
||||
* 能源名称(模糊查询)
|
||||
*/
|
||||
private String energyName;
|
||||
|
||||
/**
|
||||
* 设备型号(模糊查询)
|
||||
*/
|
||||
private String model;
|
||||
|
||||
/**
|
||||
* 制造商(模糊查询)
|
||||
*/
|
||||
private String manufacturer;
|
||||
|
||||
/**
|
||||
* 设备状态:0=在用,1=停用,2=维护
|
||||
*/
|
||||
private Integer meterStatus;
|
||||
|
||||
}
|
||||
@@ -75,5 +75,15 @@ public class EmsMeterBo extends BaseEntity {
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 产线(如:S1、S2、组装线、包装线等)
|
||||
*/
|
||||
private String productionLine;
|
||||
|
||||
/**
|
||||
* 是否总表:0=否,1=是
|
||||
*/
|
||||
private Integer isTotalMeter;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
package com.klp.ems.domain.vo;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.klp.common.annotation.ExcelDictFormat;
|
||||
import com.klp.common.convert.ExcelDictConvert;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
|
||||
/**
|
||||
* 能源消耗记录视图对象 ems_energy_record
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-04-20
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class EmsEnergyRecordVo {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 能耗记录主键ID
|
||||
*/
|
||||
@ExcelProperty(value = "能耗记录主键ID")
|
||||
private Long energyRecordId;
|
||||
|
||||
/**
|
||||
* 表计ID(关联计量设备表)
|
||||
*/
|
||||
@ExcelProperty(value = "表计ID", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(readConverterExp = "关=联计量设备表")
|
||||
private Long meterId;
|
||||
|
||||
/**
|
||||
* 能源ID(关联能源类型表:电/水/气/暖等)
|
||||
*/
|
||||
@ExcelProperty(value = "能源ID", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(readConverterExp = "关=联能源类型表:电/水/气/暖等")
|
||||
private Long energyId;
|
||||
|
||||
/**
|
||||
* 消耗量
|
||||
*/
|
||||
@ExcelProperty(value = "消耗量")
|
||||
private BigDecimal consumption;
|
||||
|
||||
/**
|
||||
* 统计日期(yyyy-MM-dd)
|
||||
*/
|
||||
@ExcelProperty(value = "统计日期", converter = ExcelDictConvert.class)
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
private Date recordDate;
|
||||
|
||||
/**
|
||||
* 记录人ID
|
||||
*/
|
||||
@ExcelProperty(value = "记录人ID")
|
||||
private Long recordedBy;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@ExcelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 表计编号
|
||||
*/
|
||||
private String meterCode;
|
||||
|
||||
/**
|
||||
* 设备型号
|
||||
*/
|
||||
private String meterModel;
|
||||
|
||||
/**
|
||||
* 制造商
|
||||
*/
|
||||
private String meterManufacturer;
|
||||
|
||||
/**
|
||||
* 设备状态:0=在用,1=停用,2=维护
|
||||
*/
|
||||
private Integer meterStatus;
|
||||
|
||||
|
||||
/**
|
||||
* 能源名称
|
||||
*/
|
||||
private String energyName;
|
||||
|
||||
|
||||
/**
|
||||
* 能源单位
|
||||
*/
|
||||
private String energyUnit;
|
||||
|
||||
/**
|
||||
* 能源编号
|
||||
*/
|
||||
private String energyCode;
|
||||
|
||||
/**
|
||||
* 能源描述
|
||||
*/
|
||||
private String energyDescription;
|
||||
|
||||
}
|
||||
@@ -89,6 +89,18 @@ public class EmsMeterVo {
|
||||
@ExcelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 产线(如:S1、S2、组装线、包装线等)
|
||||
*/
|
||||
@ExcelProperty(value = "产线")
|
||||
private String productionLine;
|
||||
|
||||
/**
|
||||
* 是否总表:0=否,1=是
|
||||
*/
|
||||
@ExcelProperty(value = "是否总表")
|
||||
private Integer isTotalMeter;
|
||||
|
||||
/**
|
||||
* 库区ID
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.klp.ems.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.klp.ems.domain.EmsEnergyRecord;
|
||||
import com.klp.ems.domain.vo.EmsEnergyRecordVo;
|
||||
import com.klp.common.core.mapper.BaseMapperPlus;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 能源消耗记录Mapper接口
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-04-20
|
||||
*/
|
||||
public interface EmsEnergyRecordMapper extends BaseMapperPlus<EmsEnergyRecordMapper, EmsEnergyRecord, EmsEnergyRecordVo> {
|
||||
|
||||
Page<EmsEnergyRecordVo> selectVoPagePlus(Page<Object> build,@Param("ew") QueryWrapper<EmsEnergyRecord> qw);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.klp.ems.service;
|
||||
|
||||
import com.klp.ems.domain.EmsEnergyRecord;
|
||||
import com.klp.ems.domain.vo.EmsEnergyRecordVo;
|
||||
import com.klp.ems.domain.bo.EmsEnergyRecordBo;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 能源消耗记录Service接口
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-04-20
|
||||
*/
|
||||
public interface IEmsEnergyRecordService {
|
||||
|
||||
/**
|
||||
* 查询能源消耗记录
|
||||
*/
|
||||
EmsEnergyRecordVo queryById(Long energyRecordId);
|
||||
|
||||
/**
|
||||
* 查询能源消耗记录列表
|
||||
*/
|
||||
TableDataInfo<EmsEnergyRecordVo> queryPageList(EmsEnergyRecordBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询能源消耗记录列表
|
||||
*/
|
||||
List<EmsEnergyRecordVo> queryList(EmsEnergyRecordBo bo);
|
||||
|
||||
/**
|
||||
* 新增能源消耗记录
|
||||
*/
|
||||
Long insertByBo(EmsEnergyRecordBo bo);
|
||||
|
||||
/**
|
||||
* 修改能源消耗记录
|
||||
*/
|
||||
Boolean updateByBo(EmsEnergyRecordBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除能源消耗记录信息
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
package com.klp.ems.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.klp.common.utils.StringUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.klp.ems.domain.bo.EmsEnergyRecordBo;
|
||||
import com.klp.ems.domain.vo.EmsEnergyRecordVo;
|
||||
import com.klp.ems.domain.EmsEnergyRecord;
|
||||
import com.klp.ems.mapper.EmsEnergyRecordMapper;
|
||||
import com.klp.ems.service.IEmsEnergyRecordService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 能源消耗记录Service业务层处理
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-04-20
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class EmsEnergyRecordServiceImpl implements IEmsEnergyRecordService {
|
||||
|
||||
private final EmsEnergyRecordMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询能源消耗记录
|
||||
*/
|
||||
@Override
|
||||
public EmsEnergyRecordVo queryById(Long energyRecordId){
|
||||
return baseMapper.selectVoById(energyRecordId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询能源消耗记录列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<EmsEnergyRecordVo> queryPageList(EmsEnergyRecordBo bo, PageQuery pageQuery) {
|
||||
QueryWrapper<EmsEnergyRecord> qw = buildQueryWrapperPlus(bo);
|
||||
Page<EmsEnergyRecordVo> result = baseMapper.selectVoPagePlus(pageQuery.build(), qw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
private QueryWrapper<EmsEnergyRecord> buildQueryWrapperPlus(EmsEnergyRecordBo bo) {
|
||||
QueryWrapper<EmsEnergyRecord> qw = Wrappers.query();
|
||||
|
||||
// 主表字段查询(使用别名 er)
|
||||
qw.eq(bo.getMeterId() != null, "er.meter_id", bo.getMeterId());
|
||||
qw.eq(bo.getEnergyId() != null, "er.energy_id", bo.getEnergyId());
|
||||
qw.eq(bo.getConsumption() != null, "er.consumption", bo.getConsumption());
|
||||
qw.eq(bo.getRecordDate() != null, "er.record_date", bo.getRecordDate());
|
||||
qw.eq(bo.getRecordedBy() != null, "er.recorded_by", bo.getRecordedBy());
|
||||
|
||||
// 时间段筛选:recordStartDate <= recordDate <= recordEndDate
|
||||
qw.ge(bo.getRecordStartDate() != null, "er.record_date", bo.getRecordStartDate());
|
||||
qw.le(bo.getRecordEndDate() != null, "er.record_date", bo.getRecordEndDate());
|
||||
// 逻辑删除
|
||||
qw.eq("er.del_flag", "0");
|
||||
// 默认排序:按统计日期倒序
|
||||
qw.orderByDesc("er.record_date");
|
||||
|
||||
return qw;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询能源消耗记录列表
|
||||
*/
|
||||
@Override
|
||||
public List<EmsEnergyRecordVo> queryList(EmsEnergyRecordBo bo) {
|
||||
LambdaQueryWrapper<EmsEnergyRecord> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<EmsEnergyRecord> buildQueryWrapper(EmsEnergyRecordBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<EmsEnergyRecord> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(bo.getMeterId() != null, EmsEnergyRecord::getMeterId, bo.getMeterId());
|
||||
lqw.eq(bo.getEnergyId() != null, EmsEnergyRecord::getEnergyId, bo.getEnergyId());
|
||||
lqw.eq(bo.getConsumption() != null, EmsEnergyRecord::getConsumption, bo.getConsumption());
|
||||
lqw.eq(bo.getRecordDate() != null, EmsEnergyRecord::getRecordDate, bo.getRecordDate());
|
||||
// 时间段筛选:recordDateStart <= recordDate <= recordDateEnd
|
||||
lqw.ge(bo.getRecordStartDate() != null, EmsEnergyRecord::getRecordDate, bo.getRecordStartDate());
|
||||
lqw.le(bo.getRecordEndDate() != null, EmsEnergyRecord::getRecordDate, bo.getRecordEndDate());
|
||||
lqw.eq(bo.getRecordedBy() != null, EmsEnergyRecord::getRecordedBy, bo.getRecordedBy());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增能源消耗记录
|
||||
*/
|
||||
@Override
|
||||
public Long insertByBo(EmsEnergyRecordBo bo) {
|
||||
EmsEnergyRecord add = BeanUtil.toBean(bo, EmsEnergyRecord.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setEnergyRecordId(add.getEnergyRecordId());
|
||||
}
|
||||
return add.getEnergyRecordId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改能源消耗记录
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(EmsEnergyRecordBo bo) {
|
||||
EmsEnergyRecord update = BeanUtil.toBean(bo, EmsEnergyRecord.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(EmsEnergyRecord entity){
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除能源消耗记录
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if(isValid){
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
}
|
||||
@@ -93,6 +93,8 @@ public class EmsMeterServiceImpl implements IEmsMeterService {
|
||||
lqw.eq(bo.getStatus() != null, EmsMeter::getStatus, bo.getStatus());
|
||||
lqw.eq(bo.getLastCalibrationDate() != null, EmsMeter::getLastCalibrationDate, bo.getLastCalibrationDate());
|
||||
lqw.eq(bo.getThresholdValue() != null, EmsMeter::getThresholdValue, bo.getThresholdValue());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getProductionLine()), EmsMeter::getProductionLine, bo.getProductionLine());
|
||||
lqw.eq(bo.getIsTotalMeter() != null, EmsMeter::getIsTotalMeter, bo.getIsTotalMeter());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
|
||||
45
klp-ems/src/main/resources/mapper/EmsEnergyRecordMapper.xml
Normal file
45
klp-ems/src/main/resources/mapper/EmsEnergyRecordMapper.xml
Normal file
@@ -0,0 +1,45 @@
|
||||
<?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.klp.ems.mapper.EmsEnergyRecordMapper">
|
||||
|
||||
<resultMap type="com.klp.ems.domain.EmsEnergyRecord" id="EmsEnergyRecordResult">
|
||||
<result property="energyRecordId" column="energy_record_id"/>
|
||||
<result property="meterId" column="meter_id"/>
|
||||
<result property="energyId" column="energy_id"/>
|
||||
<result property="consumption" column="consumption"/>
|
||||
<result property="recordDate" column="record_date"/>
|
||||
<result property="recordedBy" column="recorded_by"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
<result property="delFlag" column="del_flag"/>
|
||||
<result property="remark" column="remark"/>
|
||||
</resultMap>
|
||||
<select id="selectVoPagePlus" resultType="com.klp.ems.domain.vo.EmsEnergyRecordVo">
|
||||
SELECT
|
||||
er.energy_record_id,
|
||||
er.meter_id,
|
||||
er.energy_id,
|
||||
er.consumption,
|
||||
er.record_date,
|
||||
er.recorded_by,
|
||||
er.remark,
|
||||
m.meter_code AS meterCode,
|
||||
m.model AS meterModel,
|
||||
m.manufacturer AS meterManufacturer,
|
||||
m.status AS meterStatus,
|
||||
et.name AS energyName,
|
||||
et.unit AS energyUnit,
|
||||
et.code AS energyCode,
|
||||
et.description AS energyDescription
|
||||
FROM ems_energy_record er
|
||||
LEFT JOIN ems_meter m ON er.meter_id = m.meter_id AND m.del_flag = '0'
|
||||
LEFT JOIN ems_energy_type et ON er.energy_id = et.energy_type_id AND et.del_flag = '0'
|
||||
${ew.customSqlSegment}
|
||||
</select>
|
||||
|
||||
|
||||
</mapper>
|
||||
@@ -21,6 +21,8 @@
|
||||
<result property="updateTime" column="update_time"/>
|
||||
<result property="delFlag" column="del_flag"/>
|
||||
<result property="remark" column="remark"/>
|
||||
<result property="productionLine" column="production_line"/>
|
||||
<result property="isTotalMeter" column="is_total_meter"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap type="com.klp.ems.domain.vo.EmsMeterVo" id="EmsMeterVoResult">
|
||||
@@ -35,6 +37,8 @@
|
||||
<result property="lastCalibrationDate" column="last_calibration_date"/>
|
||||
<result property="thresholdValue" column="threshold_value"/>
|
||||
<result property="remark" column="remark"/>
|
||||
<result property="productionLine" column="production_line"/>
|
||||
<result property="isTotalMeter" column="is_total_meter"/>
|
||||
<result property="warehouseId" column="warehouse_id"/>
|
||||
<result property="warehouseName" column="warehouse_name"/>
|
||||
</resultMap>
|
||||
@@ -77,6 +81,8 @@
|
||||
m.last_calibration_date,
|
||||
m.threshold_value,
|
||||
m.remark,
|
||||
m.production_line,
|
||||
m.is_total_meter,
|
||||
COALESCE(w.warehouse_id, 0) as warehouse_id,
|
||||
COALESCE(w.warehouse_name, '') as warehouse_name
|
||||
FROM ems_meter m
|
||||
@@ -95,6 +101,12 @@
|
||||
<if test="status != null">
|
||||
AND m.status = #{status}
|
||||
</if>
|
||||
<if test="productionLine != null and productionLine != ''">
|
||||
AND m.production_line LIKE CONCAT('%', #{productionLine}, '%')
|
||||
</if>
|
||||
<if test="isTotalMeter != null">
|
||||
AND m.is_total_meter = #{isTotalMeter}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="selectMeterIds" parameterType="com.klp.ems.domain.bo.MeterFilterBo" resultType="java.lang.Long">
|
||||
|
||||
@@ -3,7 +3,7 @@ gen:
|
||||
# 作者
|
||||
author: klp
|
||||
# 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool
|
||||
packageName: com.klp.system
|
||||
packageName: com.klp
|
||||
# 自动去除表前缀,默认是false
|
||||
autoRemovePre: false
|
||||
# 表前缀(生成类名不会包含表前缀,多个用逗号分隔)
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.klp.mes.eqp.controller;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.*;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import com.klp.common.annotation.RepeatSubmit;
|
||||
import com.klp.common.annotation.Log;
|
||||
import com.klp.common.core.controller.BaseController;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.klp.common.core.domain.R;
|
||||
import com.klp.common.core.validate.AddGroup;
|
||||
import com.klp.common.core.validate.EditGroup;
|
||||
import com.klp.common.enums.BusinessType;
|
||||
import com.klp.common.utils.poi.ExcelUtil;
|
||||
import com.klp.mes.eqp.domain.vo.EqpAuxiliaryConsumeVo;
|
||||
import com.klp.mes.eqp.domain.bo.EqpAuxiliaryConsumeBo;
|
||||
import com.klp.mes.eqp.service.IEqpAuxiliaryConsumeService;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 公辅消耗记录
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-04-29
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/eqp/auxiliaryConsume")
|
||||
public class EqpAuxiliaryConsumeController extends BaseController {
|
||||
|
||||
private final IEqpAuxiliaryConsumeService iEqpAuxiliaryConsumeService;
|
||||
|
||||
/**
|
||||
* 查询公辅消耗记录列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<EqpAuxiliaryConsumeVo> list(EqpAuxiliaryConsumeBo bo, PageQuery pageQuery) {
|
||||
return iEqpAuxiliaryConsumeService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出公辅消耗记录列表
|
||||
*/
|
||||
@Log(title = "公辅消耗记录", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(EqpAuxiliaryConsumeBo bo, HttpServletResponse response) {
|
||||
List<EqpAuxiliaryConsumeVo> list = iEqpAuxiliaryConsumeService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "公辅消耗记录", EqpAuxiliaryConsumeVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取公辅消耗记录详细信息
|
||||
*
|
||||
* @param consumeId 主键
|
||||
*/
|
||||
@GetMapping("/{consumeId}")
|
||||
public R<EqpAuxiliaryConsumeVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long consumeId) {
|
||||
return R.ok(iEqpAuxiliaryConsumeService.queryById(consumeId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增公辅消耗记录
|
||||
*/
|
||||
@Log(title = "公辅消耗记录", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody EqpAuxiliaryConsumeBo bo) {
|
||||
return toAjax(iEqpAuxiliaryConsumeService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改公辅消耗记录
|
||||
*/
|
||||
@Log(title = "公辅消耗记录", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody EqpAuxiliaryConsumeBo bo) {
|
||||
return toAjax(iEqpAuxiliaryConsumeService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除公辅消耗记录
|
||||
*
|
||||
* @param consumeIds 主键串
|
||||
*/
|
||||
@Log(title = "公辅消耗记录", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{consumeIds}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@PathVariable Long[] consumeIds) {
|
||||
return toAjax(iEqpAuxiliaryConsumeService.deleteWithValidByIds(Arrays.asList(consumeIds), true));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.klp.mes.eqp.controller;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.*;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import com.klp.common.annotation.RepeatSubmit;
|
||||
import com.klp.common.annotation.Log;
|
||||
import com.klp.common.core.controller.BaseController;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.klp.common.core.domain.R;
|
||||
import com.klp.common.core.validate.AddGroup;
|
||||
import com.klp.common.core.validate.EditGroup;
|
||||
import com.klp.common.enums.BusinessType;
|
||||
import com.klp.common.utils.poi.ExcelUtil;
|
||||
import com.klp.mes.eqp.domain.vo.EqpAuxiliaryTypeVo;
|
||||
import com.klp.mes.eqp.domain.bo.EqpAuxiliaryTypeBo;
|
||||
import com.klp.mes.eqp.service.IEqpAuxiliaryTypeService;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 公辅类型
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-04-29
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/eqp/auxiliaryType")
|
||||
public class EqpAuxiliaryTypeController extends BaseController {
|
||||
|
||||
private final IEqpAuxiliaryTypeService iEqpAuxiliaryTypeService;
|
||||
|
||||
/**
|
||||
* 查询公辅类型列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<EqpAuxiliaryTypeVo> list(EqpAuxiliaryTypeBo bo, PageQuery pageQuery) {
|
||||
return iEqpAuxiliaryTypeService.queryPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出公辅类型列表
|
||||
*/
|
||||
@Log(title = "公辅类型", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(EqpAuxiliaryTypeBo bo, HttpServletResponse response) {
|
||||
List<EqpAuxiliaryTypeVo> list = iEqpAuxiliaryTypeService.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "公辅类型", EqpAuxiliaryTypeVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取公辅类型详细信息
|
||||
*
|
||||
* @param typeId 主键
|
||||
*/
|
||||
@GetMapping("/{typeId}")
|
||||
public R<EqpAuxiliaryTypeVo> getInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long typeId) {
|
||||
return R.ok(iEqpAuxiliaryTypeService.queryById(typeId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增公辅类型
|
||||
*/
|
||||
@Log(title = "公辅类型", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody EqpAuxiliaryTypeBo bo) {
|
||||
return toAjax(iEqpAuxiliaryTypeService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改公辅类型
|
||||
*/
|
||||
@Log(title = "公辅类型", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody EqpAuxiliaryTypeBo bo) {
|
||||
return toAjax(iEqpAuxiliaryTypeService.updateByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除公辅类型
|
||||
*
|
||||
* @param typeIds 主键串
|
||||
*/
|
||||
@Log(title = "公辅类型", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{typeIds}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@PathVariable Long[] typeIds) {
|
||||
return toAjax(iEqpAuxiliaryTypeService.deleteWithValidByIds(Arrays.asList(typeIds), true));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.klp.mes.eqp.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.klp.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
/**
|
||||
* 公辅消耗记录对象 eqp_auxiliary_consume
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-04-29
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("eqp_auxiliary_consume")
|
||||
public class EqpAuxiliaryConsume extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID=1L;
|
||||
|
||||
/**
|
||||
* 消耗记录ID
|
||||
*/
|
||||
@TableId(value = "consume_id")
|
||||
private Long consumeId;
|
||||
/**
|
||||
* 记录日期
|
||||
*/
|
||||
private Date recordDate;
|
||||
/**
|
||||
* 公辅类型ID(关联ems_auxiliary_type)
|
||||
*/
|
||||
private Long typeId;
|
||||
/**
|
||||
* 消耗量
|
||||
*/
|
||||
private BigDecimal consume;
|
||||
/**
|
||||
* 删除标志(0=存在 2=删除)
|
||||
*/
|
||||
@TableLogic
|
||||
private String delFlag;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.klp.mes.eqp.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.klp.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
|
||||
/**
|
||||
* 公辅类型对象 eqp_auxiliary_type
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-04-29
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("eqp_auxiliary_type")
|
||||
public class EqpAuxiliaryType extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID=1L;
|
||||
|
||||
/**
|
||||
* 公辅类型ID
|
||||
*/
|
||||
@TableId(value = "type_id")
|
||||
private Long typeId;
|
||||
/**
|
||||
* 公辅类型名称
|
||||
*/
|
||||
private String typeName;
|
||||
/**
|
||||
* 产线名称
|
||||
*/
|
||||
private String lineName;
|
||||
/**
|
||||
* 删除标志(0=存在 2=删除)
|
||||
*/
|
||||
@TableLogic
|
||||
private String delFlag;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.klp.mes.eqp.domain.bo;
|
||||
|
||||
import com.klp.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
/**
|
||||
* 公辅消耗记录业务对象 eqp_auxiliary_consume
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-04-29
|
||||
*/
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class EqpAuxiliaryConsumeBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 消耗记录ID
|
||||
*/
|
||||
private Long consumeId;
|
||||
|
||||
/**
|
||||
* 记录日期
|
||||
*/
|
||||
private Date recordDate;
|
||||
|
||||
/**
|
||||
* 公辅类型ID(关联ems_auxiliary_type)
|
||||
*/
|
||||
private Long typeId;
|
||||
|
||||
/**
|
||||
* 消耗量
|
||||
*/
|
||||
private BigDecimal consume;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.klp.mes.eqp.domain.bo;
|
||||
|
||||
import com.klp.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
|
||||
/**
|
||||
* 公辅类型业务对象 eqp_auxiliary_type
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-04-29
|
||||
*/
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class EqpAuxiliaryTypeBo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 公辅类型ID
|
||||
*/
|
||||
private Long typeId;
|
||||
|
||||
/**
|
||||
* 公辅类型名称
|
||||
*/
|
||||
private String typeName;
|
||||
|
||||
/**
|
||||
* 产线名称
|
||||
*/
|
||||
private String lineName;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.klp.mes.eqp.domain.vo;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.klp.common.annotation.ExcelDictFormat;
|
||||
import com.klp.common.convert.ExcelDictConvert;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
/**
|
||||
* 公辅消耗记录视图对象 eqp_auxiliary_consume
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-04-29
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class EqpAuxiliaryConsumeVo {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 消耗记录ID
|
||||
*/
|
||||
@ExcelProperty(value = "消耗记录ID")
|
||||
private Long consumeId;
|
||||
|
||||
/**
|
||||
* 记录日期
|
||||
*/
|
||||
@ExcelProperty(value = "记录日期")
|
||||
private Date recordDate;
|
||||
|
||||
/**
|
||||
* 公辅类型ID(关联ems_auxiliary_type)
|
||||
*/
|
||||
@ExcelProperty(value = "公辅类型ID", converter = ExcelDictConvert.class)
|
||||
@ExcelDictFormat(readConverterExp = "关=联ems_auxiliary_type")
|
||||
private Long typeId;
|
||||
|
||||
/**
|
||||
* 消耗量
|
||||
*/
|
||||
@ExcelProperty(value = "消耗量")
|
||||
private BigDecimal consume;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@ExcelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.klp.mes.eqp.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.klp.common.annotation.ExcelDictFormat;
|
||||
import com.klp.common.convert.ExcelDictConvert;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
/**
|
||||
* 公辅类型视图对象 eqp_auxiliary_type
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-04-29
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class EqpAuxiliaryTypeVo {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 公辅类型ID
|
||||
*/
|
||||
@ExcelProperty(value = "公辅类型ID")
|
||||
private Long typeId;
|
||||
|
||||
/**
|
||||
* 公辅类型名称
|
||||
*/
|
||||
@ExcelProperty(value = "公辅类型名称")
|
||||
private String typeName;
|
||||
|
||||
/**
|
||||
* 产线名称
|
||||
*/
|
||||
@ExcelProperty(value = "产线名称")
|
||||
private String lineName;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@ExcelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.klp.mes.eqp.mapper;
|
||||
|
||||
import com.klp.mes.eqp.domain.EqpAuxiliaryConsume;
|
||||
import com.klp.mes.eqp.domain.vo.EqpAuxiliaryConsumeVo;
|
||||
import com.klp.common.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 公辅消耗记录Mapper接口
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-04-29
|
||||
*/
|
||||
public interface EqpAuxiliaryConsumeMapper extends BaseMapperPlus<EqpAuxiliaryConsumeMapper, EqpAuxiliaryConsume, EqpAuxiliaryConsumeVo> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.klp.mes.eqp.mapper;
|
||||
|
||||
import com.klp.mes.eqp.domain.EqpAuxiliaryType;
|
||||
import com.klp.mes.eqp.domain.vo.EqpAuxiliaryTypeVo;
|
||||
import com.klp.common.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 公辅类型Mapper接口
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-04-29
|
||||
*/
|
||||
public interface EqpAuxiliaryTypeMapper extends BaseMapperPlus<EqpAuxiliaryTypeMapper, EqpAuxiliaryType, EqpAuxiliaryTypeVo> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.klp.mes.eqp.service;
|
||||
|
||||
import com.klp.mes.eqp.domain.EqpAuxiliaryConsume;
|
||||
import com.klp.mes.eqp.domain.vo.EqpAuxiliaryConsumeVo;
|
||||
import com.klp.mes.eqp.domain.bo.EqpAuxiliaryConsumeBo;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 公辅消耗记录Service接口
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-04-29
|
||||
*/
|
||||
public interface IEqpAuxiliaryConsumeService {
|
||||
|
||||
/**
|
||||
* 查询公辅消耗记录
|
||||
*/
|
||||
EqpAuxiliaryConsumeVo queryById(Long consumeId);
|
||||
|
||||
/**
|
||||
* 查询公辅消耗记录列表
|
||||
*/
|
||||
TableDataInfo<EqpAuxiliaryConsumeVo> queryPageList(EqpAuxiliaryConsumeBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询公辅消耗记录列表
|
||||
*/
|
||||
List<EqpAuxiliaryConsumeVo> queryList(EqpAuxiliaryConsumeBo bo);
|
||||
|
||||
/**
|
||||
* 新增公辅消耗记录
|
||||
*/
|
||||
Boolean insertByBo(EqpAuxiliaryConsumeBo bo);
|
||||
|
||||
/**
|
||||
* 修改公辅消耗记录
|
||||
*/
|
||||
Boolean updateByBo(EqpAuxiliaryConsumeBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除公辅消耗记录信息
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.klp.mes.eqp.service;
|
||||
|
||||
import com.klp.mes.eqp.domain.EqpAuxiliaryType;
|
||||
import com.klp.mes.eqp.domain.vo.EqpAuxiliaryTypeVo;
|
||||
import com.klp.mes.eqp.domain.bo.EqpAuxiliaryTypeBo;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 公辅类型Service接口
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-04-29
|
||||
*/
|
||||
public interface IEqpAuxiliaryTypeService {
|
||||
|
||||
/**
|
||||
* 查询公辅类型
|
||||
*/
|
||||
EqpAuxiliaryTypeVo queryById(Long typeId);
|
||||
|
||||
/**
|
||||
* 查询公辅类型列表
|
||||
*/
|
||||
TableDataInfo<EqpAuxiliaryTypeVo> queryPageList(EqpAuxiliaryTypeBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询公辅类型列表
|
||||
*/
|
||||
List<EqpAuxiliaryTypeVo> queryList(EqpAuxiliaryTypeBo bo);
|
||||
|
||||
/**
|
||||
* 新增公辅类型
|
||||
*/
|
||||
Boolean insertByBo(EqpAuxiliaryTypeBo bo);
|
||||
|
||||
/**
|
||||
* 修改公辅类型
|
||||
*/
|
||||
Boolean updateByBo(EqpAuxiliaryTypeBo bo);
|
||||
|
||||
/**
|
||||
* 校验并批量删除公辅类型信息
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package com.klp.mes.eqp.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.klp.mes.eqp.domain.bo.EqpAuxiliaryConsumeBo;
|
||||
import com.klp.mes.eqp.domain.vo.EqpAuxiliaryConsumeVo;
|
||||
import com.klp.mes.eqp.domain.EqpAuxiliaryConsume;
|
||||
import com.klp.mes.eqp.mapper.EqpAuxiliaryConsumeMapper;
|
||||
import com.klp.mes.eqp.service.IEqpAuxiliaryConsumeService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 公辅消耗记录Service业务层处理
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-04-29
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class EqpAuxiliaryConsumeServiceImpl implements IEqpAuxiliaryConsumeService {
|
||||
|
||||
private final EqpAuxiliaryConsumeMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询公辅消耗记录
|
||||
*/
|
||||
@Override
|
||||
public EqpAuxiliaryConsumeVo queryById(Long consumeId){
|
||||
return baseMapper.selectVoById(consumeId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询公辅消耗记录列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<EqpAuxiliaryConsumeVo> queryPageList(EqpAuxiliaryConsumeBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<EqpAuxiliaryConsume> lqw = buildQueryWrapper(bo);
|
||||
Page<EqpAuxiliaryConsumeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询公辅消耗记录列表
|
||||
*/
|
||||
@Override
|
||||
public List<EqpAuxiliaryConsumeVo> queryList(EqpAuxiliaryConsumeBo bo) {
|
||||
LambdaQueryWrapper<EqpAuxiliaryConsume> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<EqpAuxiliaryConsume> buildQueryWrapper(EqpAuxiliaryConsumeBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<EqpAuxiliaryConsume> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(bo.getRecordDate() != null, EqpAuxiliaryConsume::getRecordDate, bo.getRecordDate());
|
||||
lqw.eq(bo.getTypeId() != null, EqpAuxiliaryConsume::getTypeId, bo.getTypeId());
|
||||
lqw.eq(bo.getConsume() != null, EqpAuxiliaryConsume::getConsume, bo.getConsume());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增公辅消耗记录
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(EqpAuxiliaryConsumeBo bo) {
|
||||
EqpAuxiliaryConsume add = BeanUtil.toBean(bo, EqpAuxiliaryConsume.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setConsumeId(add.getConsumeId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改公辅消耗记录
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(EqpAuxiliaryConsumeBo bo) {
|
||||
EqpAuxiliaryConsume update = BeanUtil.toBean(bo, EqpAuxiliaryConsume.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(EqpAuxiliaryConsume entity){
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除公辅消耗记录
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if(isValid){
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package com.klp.mes.eqp.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.klp.common.utils.StringUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.klp.mes.eqp.domain.bo.EqpAuxiliaryTypeBo;
|
||||
import com.klp.mes.eqp.domain.vo.EqpAuxiliaryTypeVo;
|
||||
import com.klp.mes.eqp.domain.EqpAuxiliaryType;
|
||||
import com.klp.mes.eqp.mapper.EqpAuxiliaryTypeMapper;
|
||||
import com.klp.mes.eqp.service.IEqpAuxiliaryTypeService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 公辅类型Service业务层处理
|
||||
*
|
||||
* @author klp
|
||||
* @date 2026-04-29
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class EqpAuxiliaryTypeServiceImpl implements IEqpAuxiliaryTypeService {
|
||||
|
||||
private final EqpAuxiliaryTypeMapper baseMapper;
|
||||
|
||||
/**
|
||||
* 查询公辅类型
|
||||
*/
|
||||
@Override
|
||||
public EqpAuxiliaryTypeVo queryById(Long typeId){
|
||||
return baseMapper.selectVoById(typeId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询公辅类型列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<EqpAuxiliaryTypeVo> queryPageList(EqpAuxiliaryTypeBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<EqpAuxiliaryType> lqw = buildQueryWrapper(bo);
|
||||
Page<EqpAuxiliaryTypeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询公辅类型列表
|
||||
*/
|
||||
@Override
|
||||
public List<EqpAuxiliaryTypeVo> queryList(EqpAuxiliaryTypeBo bo) {
|
||||
LambdaQueryWrapper<EqpAuxiliaryType> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<EqpAuxiliaryType> buildQueryWrapper(EqpAuxiliaryTypeBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<EqpAuxiliaryType> lqw = Wrappers.lambdaQuery();
|
||||
lqw.like(StringUtils.isNotBlank(bo.getTypeName()), EqpAuxiliaryType::getTypeName, bo.getTypeName());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getLineName()), EqpAuxiliaryType::getLineName, bo.getLineName());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增公辅类型
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(EqpAuxiliaryTypeBo bo) {
|
||||
EqpAuxiliaryType add = BeanUtil.toBean(bo, EqpAuxiliaryType.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setTypeId(add.getTypeId());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改公辅类型
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateByBo(EqpAuxiliaryTypeBo bo) {
|
||||
EqpAuxiliaryType update = BeanUtil.toBean(bo, EqpAuxiliaryType.class);
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(EqpAuxiliaryType entity){
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除公辅类型
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||||
if(isValid){
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
}
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?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.klp.mes.eqp.mapper.EqpAuxiliaryConsumeMapper">
|
||||
|
||||
<resultMap type="com.klp.mes.eqp.domain.EqpAuxiliaryConsume" id="EqpAuxiliaryConsumeResult">
|
||||
<result property="consumeId" column="consume_id"/>
|
||||
<result property="recordDate" column="record_date"/>
|
||||
<result property="typeId" column="type_id"/>
|
||||
<result property="consume" column="consume"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
<result property="delFlag" column="del_flag"/>
|
||||
<result property="remark" column="remark"/>
|
||||
</resultMap>
|
||||
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?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.klp.mes.eqp.mapper.EqpAuxiliaryTypeMapper">
|
||||
|
||||
<resultMap type="com.klp.mes.eqp.domain.EqpAuxiliaryType" id="EqpAuxiliaryTypeResult">
|
||||
<result property="typeId" column="type_id"/>
|
||||
<result property="typeName" column="type_name"/>
|
||||
<result property="lineName" column="line_name"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
<result property="delFlag" column="del_flag"/>
|
||||
<result property="remark" column="remark"/>
|
||||
</resultMap>
|
||||
|
||||
|
||||
</mapper>
|
||||
@@ -41,6 +41,11 @@ public interface ISysDictDataService {
|
||||
*/
|
||||
SysDictData selectDictDataById(Long dictCode);
|
||||
|
||||
/**
|
||||
* 按字典类型查询字典数据(直查库)。用于 HTTP `/dict/data/type/{type}`,避免 Spring Cache 在无界面操作灌数后仍返回空。
|
||||
*/
|
||||
List<SysDictData> selectDictDataByTypeRealtime(String dictType);
|
||||
|
||||
/**
|
||||
* 批量删除字典数据信息
|
||||
*
|
||||
|
||||
@@ -15,6 +15,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.cache.annotation.CachePut;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -81,6 +82,18 @@ public class SysDictDataServiceImpl implements ISysDictDataService {
|
||||
return baseMapper.selectById(dictCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按类型查字典数据(直查数据库,不走 {@link com.klp.system.service.impl.SysDictTypeServiceImpl#selectDictDataByType} 的 Spring Cache)。
|
||||
* SQL 脚本直插或外部改表后,仍需立即在「按类型」HTTP 接口中可见,避免长期使用空缓存。
|
||||
*/
|
||||
@Override
|
||||
public List<SysDictData> selectDictDataByTypeRealtime(String dictType) {
|
||||
if (StringUtils.isBlank(dictType)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return baseMapper.selectDictDataByType(dictType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除字典数据信息
|
||||
*
|
||||
|
||||
@@ -119,7 +119,7 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService
|
||||
@Cacheable(cacheNames = CacheNames.SYS_DICT, key = "#dictType")
|
||||
@Override
|
||||
public SysDictType selectDictTypeByType(String dictType) {
|
||||
return baseMapper.selectById(new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getDictType, dictType));
|
||||
return baseMapper.selectOne(new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getDictType, dictType));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -42,3 +42,11 @@ export function delPlanDetail(planDetailId) {
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询排产单对应的钢卷列表
|
||||
export function listPlanCoils(planSheetId) {
|
||||
return request({
|
||||
url: '/aps/planDetail/coils/' + planSheetId,
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
@@ -52,3 +52,14 @@ export function listOrderPackaging(orderId) {
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询今日订单
|
||||
*/
|
||||
export function listTodayOrder(query) {
|
||||
return request({
|
||||
url: '/crm/order/daily',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
44
klp-ui/src/api/ems/energyRecord.js
Normal file
44
klp-ui/src/api/ems/energyRecord.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询能源消耗记录列表
|
||||
export function listEnergyRecord(query) {
|
||||
return request({
|
||||
url: '/ems/energyRecord/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询能源消耗记录详细
|
||||
export function getEnergyRecord(energyRecordId) {
|
||||
return request({
|
||||
url: '/ems/energyRecord/' + energyRecordId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增能源消耗记录
|
||||
export function addEnergyRecord(data) {
|
||||
return request({
|
||||
url: '/ems/energyRecord',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改能源消耗记录
|
||||
export function updateEnergyRecord(data) {
|
||||
return request({
|
||||
url: '/ems/energyRecord',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除能源消耗记录
|
||||
export function delEnergyRecord(energyRecordId) {
|
||||
return request({
|
||||
url: '/ems/energyRecord/' + energyRecordId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
50
klp-ui/src/api/l2/timing.js
Normal file
50
klp-ui/src/api/l2/timing.js
Normal file
@@ -0,0 +1,50 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 计划列表(分页)
|
||||
export function getTimingPlanList(page = 1, pageSize = 20) {
|
||||
return request({
|
||||
url: '/sql-server-api/plans',
|
||||
method: 'get',
|
||||
params: { page, pageSize }
|
||||
})
|
||||
}
|
||||
|
||||
// 计划总数
|
||||
export function getTimingPlanCount() {
|
||||
return request({
|
||||
url: '/sql-server-api/plans/count',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 计划详情
|
||||
export function getTimingPlanDetail(coilId) {
|
||||
return request({
|
||||
url: '/sql-server-api/plans/' + coilId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 钢卷实际 SEG,按入口卷号查询
|
||||
export function getTimingSegByEncoilId(encoilId) {
|
||||
return request({
|
||||
url: '/sql-server-api/seg/' + encoilId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 钢卷实际 SEG,按出口卷号查询
|
||||
export function getTimingSegByExcoilId(excoilId) {
|
||||
return request({
|
||||
url: '/sql-server-api/seg-by-excoil/' + excoilId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 实时数据:Gauge + Shape
|
||||
export function getTimingRealtimeData(matId) {
|
||||
return request({
|
||||
url: '/sql-server-api/realtime/' + matId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
@@ -58,3 +58,11 @@ export function optionselect() {
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
/** 按字典类型编码精确查询 sys_dict_type(路径需编码) */
|
||||
export function getDictTypeByCode(dictType) {
|
||||
return request({
|
||||
url: '/system/dict/type/byType/' + encodeURIComponent(dictType),
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
44
klp-ui/src/api/wms/annealOperateEvent.js
Normal file
44
klp-ui/src/api/wms/annealOperateEvent.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询退火操作事件列表
|
||||
export function listAnnealOperateEvent(query) {
|
||||
return request({
|
||||
url: '/wms/annealOperateEvent/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询退火操作事件详细
|
||||
export function getAnnealOperateEvent(eventId) {
|
||||
return request({
|
||||
url: '/wms/annealOperateEvent/' + eventId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增退火操作事件
|
||||
export function addAnnealOperateEvent(data) {
|
||||
return request({
|
||||
url: '/wms/annealOperateEvent',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改退火操作事件
|
||||
export function updateAnnealOperateEvent(data) {
|
||||
return request({
|
||||
url: '/wms/annealOperateEvent',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除退火操作事件
|
||||
export function delAnnealOperateEvent(eventId) {
|
||||
return request({
|
||||
url: '/wms/annealOperateEvent/' + eventId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
56
klp-ui/src/api/wms/attendance.js
Normal file
56
klp-ui/src/api/wms/attendance.js
Normal file
@@ -0,0 +1,56 @@
|
||||
import request from '@/utils/request'
|
||||
import attendanceRequest from '@/utils/attendanceRequest'
|
||||
|
||||
// 查询考勤记录列表
|
||||
export function listRecords(query) {
|
||||
return request({
|
||||
url: '/wms/attendanceRecords/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询考勤记录详细
|
||||
export function getRecords(id) {
|
||||
return request({
|
||||
url: '/wms/attendanceRecords/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增考勤记录
|
||||
export function addRecords(data) {
|
||||
return request({
|
||||
url: '/wms/attendanceRecords',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改考勤记录
|
||||
export function updateRecords(data) {
|
||||
return request({
|
||||
url: '/wms/attendanceRecords',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除考勤记录
|
||||
export function delRecords(id) {
|
||||
return request({
|
||||
url: '/wms/attendanceRecords/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 同步考勤记录
|
||||
export function syncRecords(starttime) {
|
||||
return attendanceRequest({
|
||||
url: '/sync_attendance',
|
||||
method: 'post',
|
||||
data: {
|
||||
starttime
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -389,4 +389,38 @@ export function listTypeErrorCoil() {
|
||||
method: 'get',
|
||||
timeout: 600000
|
||||
})
|
||||
}
|
||||
|
||||
export function getCoilStatisticsList(params) {
|
||||
return request({
|
||||
url: '/wms/materialCoil/statisticsList',
|
||||
method: 'get',
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询原料材质与钢卷类型不匹配的钢卷
|
||||
*/
|
||||
export function listMismatchedItemCoil(params) {
|
||||
return request({
|
||||
url: '/wms/materialCoil/queryMaterialMismatchCoils',
|
||||
method: 'get',
|
||||
timeout: 600000,
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 修复原料材质与钢卷类型不匹配的钢卷
|
||||
*/
|
||||
export function fixMismatchedItemCoil(coilId) {
|
||||
return request({
|
||||
url: '/wms/materialCoil/fixMaterialMismatch',
|
||||
method: 'put',
|
||||
timeout: 600000,
|
||||
params: {
|
||||
coilId
|
||||
}
|
||||
})
|
||||
}
|
||||
61
klp-ui/src/api/wms/coilCache.js
Normal file
61
klp-ui/src/api/wms/coilCache.js
Normal file
@@ -0,0 +1,61 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询钢卷缓存列表
|
||||
export function listCoilCache(query) {
|
||||
return request({
|
||||
url: '/wms/coilCache/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询钢卷缓存详细
|
||||
export function getCoilCache(cacheId) {
|
||||
return request({
|
||||
url: '/wms/coilCache/' + cacheId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增钢卷缓存
|
||||
export function addCoilCache(data) {
|
||||
return request({
|
||||
url: '/wms/coilCache',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改钢卷缓存
|
||||
export function updateCoilCache(data) {
|
||||
return request({
|
||||
url: '/wms/coilCache',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除钢卷缓存
|
||||
export function delCoilCache(cacheId) {
|
||||
return request({
|
||||
url: '/wms/coilCache/' + cacheId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 存储缓存
|
||||
export function saveCoilCache(data) {
|
||||
return request({
|
||||
url: '/wms/coilCache/save',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取缓存
|
||||
export function getCoilCacheByCoilId(coilId) {
|
||||
return request({
|
||||
url: '/wms/coilCache/getByCoilId/' + coilId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
44
klp-ui/src/api/wms/coilContractRel.js
Normal file
44
klp-ui/src/api/wms/coilContractRel.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询钢卷与合同关联关系列表
|
||||
export function listCoilContractRel(query) {
|
||||
return request({
|
||||
url: '/wms/coilContractRel/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询钢卷与合同关联关系详细
|
||||
export function getCoilContractRel(relId) {
|
||||
return request({
|
||||
url: '/wms/coilContractRel/' + relId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增钢卷与合同关联关系
|
||||
export function addCoilContractRel(data) {
|
||||
return request({
|
||||
url: '/wms/coilContractRel',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改钢卷与合同关联关系
|
||||
export function updateCoilContractRel(data) {
|
||||
return request({
|
||||
url: '/wms/coilContractRel',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除钢卷与合同关联关系
|
||||
export function delCoilContractRel(relId) {
|
||||
return request({
|
||||
url: '/wms/coilContractRel/' + relId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
44
klp-ui/src/api/wms/coilQualityRejudge.js
Normal file
44
klp-ui/src/api/wms/coilQualityRejudge.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询钢卷质量改判记录列表
|
||||
export function listCoilQualityRejudge(query) {
|
||||
return request({
|
||||
url: '/wms/coilQualityRejudge/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询钢卷质量改判记录详细
|
||||
export function getCoilQualityRejudge(rejudgeId) {
|
||||
return request({
|
||||
url: '/wms/coilQualityRejudge/' + rejudgeId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增钢卷质量改判记录
|
||||
export function addCoilQualityRejudge(data) {
|
||||
return request({
|
||||
url: '/wms/coilQualityRejudge',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改钢卷质量改判记录
|
||||
export function updateCoilQualityRejudge(data) {
|
||||
return request({
|
||||
url: '/wms/coilQualityRejudge',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除钢卷质量改判记录
|
||||
export function delCoilQualityRejudge(rejudgeId) {
|
||||
return request({
|
||||
url: '/wms/coilQualityRejudge/' + rejudgeId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
@@ -5,7 +5,8 @@ export function listCoilWarehouseOperationLog(query) {
|
||||
return request({
|
||||
url: '/wms/coilWarehouseOperationLog/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
params: query,
|
||||
timeout: 100000,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -59,4 +59,15 @@ export function listBoundCoil(query) {
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 按销售员查询订单明细的卷
|
||||
export function listDeliveryWaybillDetailBySaleman(principal) {
|
||||
return request({
|
||||
url: '/wms/deliveryWaybillDetail/coilListByPrincipal',
|
||||
method: 'get',
|
||||
params: {
|
||||
principal: principal
|
||||
}
|
||||
})
|
||||
}
|
||||
39
klp-ui/src/api/wms/processPlan.js
Normal file
39
klp-ui/src/api/wms/processPlan.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function listProcessPlan(query) {
|
||||
return request({
|
||||
url: '/wms/processPlan/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function getProcessPlan(planId) {
|
||||
return request({
|
||||
url: '/wms/processPlan/' + planId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function addProcessPlan(data) {
|
||||
return request({
|
||||
url: '/wms/processPlan',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateProcessPlan(data) {
|
||||
return request({
|
||||
url: '/wms/processPlan',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function delProcessPlan(planId) {
|
||||
return request({
|
||||
url: '/wms/processPlan/' + planId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
39
klp-ui/src/api/wms/processPlanParam.js
Normal file
39
klp-ui/src/api/wms/processPlanParam.js
Normal file
@@ -0,0 +1,39 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function listProcessPlanParam(query) {
|
||||
return request({
|
||||
url: '/wms/processPlanParam/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function getProcessPlanParam(paramId) {
|
||||
return request({
|
||||
url: '/wms/processPlanParam/' + paramId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function addProcessPlanParam(data) {
|
||||
return request({
|
||||
url: '/wms/processPlanParam',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateProcessPlanParam(data) {
|
||||
return request({
|
||||
url: '/wms/processPlanParam',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function delProcessPlanParam(paramId) {
|
||||
return request({
|
||||
url: '/wms/processPlanParam/' + paramId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
44
klp-ui/src/api/wms/processSpec.js
Normal file
44
klp-ui/src/api/wms/processSpec.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询规程主表列表
|
||||
export function listProcessSpec(query) {
|
||||
return request({
|
||||
url: '/wms/processSpec/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询规程主表详细
|
||||
export function getProcessSpec(specId) {
|
||||
return request({
|
||||
url: '/wms/processSpec/' + specId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增规程主表
|
||||
export function addProcessSpec(data) {
|
||||
return request({
|
||||
url: '/wms/processSpec',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改规程主表
|
||||
export function updateProcessSpec(data) {
|
||||
return request({
|
||||
url: '/wms/processSpec',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除规程主表
|
||||
export function delProcessSpec(specId) {
|
||||
return request({
|
||||
url: '/wms/processSpec/' + specId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
46
klp-ui/src/api/wms/processSpecVersion.js
Normal file
46
klp-ui/src/api/wms/processSpecVersion.js
Normal file
@@ -0,0 +1,46 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function listProcessSpecVersion(query) {
|
||||
return request({
|
||||
url: '/wms/processSpecVersion/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function getProcessSpecVersion(versionId) {
|
||||
return request({
|
||||
url: '/wms/processSpecVersion/' + versionId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function addProcessSpecVersion(data) {
|
||||
return request({
|
||||
url: '/wms/processSpecVersion',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateProcessSpecVersion(data) {
|
||||
return request({
|
||||
url: '/wms/processSpecVersion',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function activateProcessSpecVersion(versionId) {
|
||||
return request({
|
||||
url: '/wms/processSpecVersion/activate/' + versionId,
|
||||
method: 'put'
|
||||
})
|
||||
}
|
||||
|
||||
export function delProcessSpecVersion(versionId) {
|
||||
return request({
|
||||
url: '/wms/processSpecVersion/' + versionId,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
@@ -55,6 +55,13 @@ export const defaultColumns = [
|
||||
width: '120',
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
label: '创建时间',
|
||||
align: 'center',
|
||||
prop: 'createTime',
|
||||
width: '100',
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
{
|
||||
label: '备注',
|
||||
align: 'center',
|
||||
|
||||
@@ -21,13 +21,7 @@
|
||||
@close="handleClose" append-to-body :fullscreen="orderBy">
|
||||
<!-- 搜索区域 -->
|
||||
<el-form v-if="!rangeMode" inline :model="queryParams" class="search-form">
|
||||
<!-- <el-form-item label="类型">
|
||||
<el-select v-model="queryParams.selectType" placeholder="请选择类型" size="small">
|
||||
<el-option label="成品" value="product" />
|
||||
<el-option label="原料" value="raw_material" />
|
||||
</el-select>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="入场卷号">
|
||||
<el-form-item label="入场卷号">
|
||||
<el-input v-model="queryParams.enterCoilNo" placeholder="请输入入场卷号" clearable size="small"
|
||||
@keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
@@ -74,8 +68,8 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="品质">
|
||||
<muti-select v-model="queryParams.qualityStatusCsv" :options="dict.type.coil_quality_status" placeholder="请选择品质"
|
||||
clearable />
|
||||
<muti-select v-model="queryParams.qualityStatusCsv" :options="dict.type.coil_quality_status"
|
||||
placeholder="请选择品质" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="实际库区" v-if="orderBy">
|
||||
<actual-warehouse-select v-model="queryParams.actualWarehouseId" placeholder="请选择实际库区" canSelectLevel2
|
||||
@@ -86,7 +80,8 @@
|
||||
<el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="small" @click="resetQuery">重置</el-button>
|
||||
<el-checkbox v-if="orderBy" style="margin-left: 10px;" v-model="showCoilMap" size="small">显示钢卷地图</el-checkbox>
|
||||
<el-checkbox v-if="orderBy && orderId" style="margin-left: 10px;" v-model="showOrderInfo" size="small">显示订单详情</el-checkbox>
|
||||
<el-checkbox v-if="orderBy && orderId" style="margin-left: 10px;" v-model="showOrderInfo"
|
||||
size="small">显示订单详情</el-checkbox>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
@@ -100,6 +95,7 @@
|
||||
<el-table-column v-if="orderBy" label="品质" prop="qualityStatus"></el-table-column>
|
||||
<el-table-column v-if="orderBy" label="切边" prop="trimmingRequirement"></el-table-column>
|
||||
<el-table-column v-if="orderBy" label="包装" prop="packagingRequirement"></el-table-column>
|
||||
<el-table-column v-if="orderBy" label="镀层质量" prop="zincLayer"></el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div v-else>
|
||||
@@ -118,12 +114,20 @@
|
||||
<el-table-column v-if="orderBy" label="品质" prop="qualityStatus"></el-table-column>
|
||||
<el-table-column v-if="orderBy" label="切边" prop="trimmingRequirement"></el-table-column>
|
||||
<el-table-column v-if="orderBy" label="包装" prop="packagingRequirement"></el-table-column>
|
||||
<el-table-column v-if="orderBy" label="镀层质量" prop="zincLayer"></el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-if="!rangeMode" v-show="total > 0" :total="total" :page.sync="queryParams.pageNum"
|
||||
:limit.sync="queryParams.pageSize" @pagination="getList" />
|
||||
<div style="display: flex; justify-content: flex-end; align-items: flex-end; gap: 10px;">
|
||||
<span>
|
||||
总净重:{{ coilTrimStatistics.total_net_weight || 0 }}t
|
||||
</span>
|
||||
|
||||
<pagination v-if="!rangeMode" v-show="total > 0" :total="total" :page.sync="queryParams.pageNum"
|
||||
:limit.sync="queryParams.pageSize" @pagination="getList" />
|
||||
</div>
|
||||
|
||||
|
||||
<div v-if="multiple && selectedCoils.length > 0" class="selected-stats">
|
||||
<div class="stats-content">
|
||||
@@ -145,6 +149,7 @@
|
||||
<el-table-column v-if="orderBy" label="品质" prop="qualityStatus"></el-table-column>
|
||||
<el-table-column v-if="orderBy" label="切边" prop="trimmingRequirement"></el-table-column>
|
||||
<el-table-column v-if="orderBy" label="包装" prop="packagingRequirement"></el-table-column>
|
||||
<el-table-column v-if="orderBy" label="镀层质量" prop="zincLayer"></el-table-column>
|
||||
|
||||
<el-table-column label="操作" width="50">
|
||||
<template slot-scope="scope">
|
||||
@@ -181,7 +186,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listMaterialCoil } from '@/api/wms/coil';
|
||||
import { listMaterialCoil, getCoilStatisticsList } from '@/api/wms/coil';
|
||||
import { listActualWarehouse } from "@/api/wms/actualWarehouse";
|
||||
import { treeActualWarehouseTwoLevel } from "@/api/wms/actualWarehouse";
|
||||
import MemoInput from '@/components/MemoInput/index.vue';
|
||||
@@ -312,6 +317,7 @@ export default {
|
||||
treeProps: { label: "actualWarehouseName", children: "children" },
|
||||
treeLoading: false,
|
||||
showOrderInfo: false,
|
||||
coilTrimStatistics: {},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -503,6 +509,11 @@ export default {
|
||||
queryPayload.saleId = this.currentUserId;
|
||||
}
|
||||
const response = await listMaterialCoil(queryPayload);
|
||||
const { pageNum, pageSize, excludeBound, orderBy, ...noPager } = queryPayload;
|
||||
getCoilStatisticsList(noPager).then((res) => {
|
||||
console.log('钢卷统计数据:', res);
|
||||
this.coilTrimStatistics = res.data || {};
|
||||
});
|
||||
if (response.code === 200) {
|
||||
this.coilList = response.rows || [];
|
||||
this.total = response.total || 0;
|
||||
@@ -561,11 +572,24 @@ export default {
|
||||
this.$message.warning('您没有权限选择此钢卷');
|
||||
return; // 终止后续逻辑
|
||||
}
|
||||
const disabledOList = ['O', 'C+', 'C', 'C-', 'D+', 'D', 'D-']
|
||||
if (this.disableO && disabledOList.includes(row.qualityStatus)) {
|
||||
this.$message.warning(`${row.qualityStatus}卷不能选择`);
|
||||
return;
|
||||
if (this.disableO) {
|
||||
// 并且钢卷的warehouseId不是1988150210872930306
|
||||
// 1988150380649967617
|
||||
// 1988150800092950529
|
||||
// 1988151027466170370其中之一,才不能选择
|
||||
const warehouseIds = ['1988150210872930306', '1988150380649967617', '1988150800092950529', '1988151027466170370'];
|
||||
// 如果没有判级就不能选择,除非是那分剪四个库区
|
||||
if (!row.qualityStatus && !warehouseIds.includes(row.warehouseId)) {
|
||||
this.$message.warning('未判级的钢卷不能选择');
|
||||
return;
|
||||
}
|
||||
const disabledOList = ['O', 'C+', 'C', 'C-', 'D+', 'D', 'D-']
|
||||
if (disabledOList.includes(row.qualityStatus)) {
|
||||
this.$message.warning(`${row.qualityStatus}卷不能选择`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.handleSelect(row);
|
||||
},
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<div style="display: flex; align-items: center;" v-loading="loading">
|
||||
<!-- 下拉选择器:绑定计算属性做双向绑定,保留原有样式+清空功能 -->
|
||||
<el-select
|
||||
v-if="!toolbarOnly"
|
||||
v-model="innerValue"
|
||||
:placeholder="placeholder"
|
||||
clearable filterable
|
||||
@@ -20,13 +21,13 @@
|
||||
<div
|
||||
v-if="editable"
|
||||
@click="openDictDialog"
|
||||
style="cursor: pointer; min-height: 24px; min-width: 24px; margin-top: 4px; display: flex; align-items: center; justify-content: center; border: 1px solid #828991; margin-left: 8px; border-radius: 2px;"
|
||||
:style="toolbarOnly ? 'cursor: pointer; min-height: 24px; min-width: 24px; margin-top: 4px; display: flex; align-items: center; justify-content: center; border: 1px solid #828991; border-radius: 2px;' : 'cursor: pointer; min-height: 24px; min-width: 24px; margin-top: 4px; display: flex; align-items: center; justify-content: center; border: 1px solid #828991; margin-left: 8px; border-radius: 2px;'"
|
||||
>
|
||||
<i class="el-icon-setting"></i>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="refresh"
|
||||
v-if="refresh && !toolbarOnly"
|
||||
@click="handleRefresh"
|
||||
style="cursor: pointer; min-height: 24px; min-width: 24px; margin-top: 4px; display: flex; align-items: center; justify-content: center; border: 1px solid #828991; margin-left: 8px; border-radius: 2px;"
|
||||
>
|
||||
@@ -37,7 +38,7 @@
|
||||
<el-dialog
|
||||
v-if="editable"
|
||||
:visible.sync="open"
|
||||
title="字典数据配置"
|
||||
:title="panelTitle || '字典数据配置'"
|
||||
width="600px"
|
||||
append-to-body
|
||||
>
|
||||
@@ -145,14 +146,17 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { addData, updateData, delData, listData } from '@/api/system/dict/data'
|
||||
import { listType } from '@/api/system/dict/type'
|
||||
import { addData, updateData, delData, getDicts } from '@/api/system/dict/data'
|
||||
|
||||
export default {
|
||||
name: 'DictSelectEdit',
|
||||
props: {
|
||||
dictType: { type: String, default: '' },
|
||||
editable: { type: Boolean, default: true },
|
||||
/** 仅展示字典配置入口(齿轮)与弹窗,不渲染下拉框 — 用于列表页 Tab 旁内联维护字典 */
|
||||
toolbarOnly: { type: Boolean, default: false },
|
||||
/** 字典配置弹窗标题 */
|
||||
panelTitle: { type: String, default: '' },
|
||||
kisv: { type: Boolean, default: true },
|
||||
value: { type: String, default: '' },
|
||||
placeholder: { type: String, default: '请选择' },
|
||||
@@ -163,18 +167,17 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
dictOptions: [],
|
||||
dictId: '',
|
||||
loading: false,
|
||||
btnLoading: false,
|
||||
delBtnLoading: '',
|
||||
open: false,
|
||||
editRowId: '', // 控制当前编辑行,为空则所有单元格都是文本状态
|
||||
form: {
|
||||
dictId: '',
|
||||
dictLabel: '',
|
||||
dictValue: '',
|
||||
dictType: '',
|
||||
sort: 0
|
||||
dictSort: 0,
|
||||
status: '0'
|
||||
},
|
||||
dictRules: {
|
||||
dictLabel: [{ required: true, message: '请输入字典标签', trigger: 'blur' }],
|
||||
@@ -214,16 +217,16 @@ export default {
|
||||
watch: {
|
||||
dictType: {
|
||||
async handler(newVal) {
|
||||
if (newVal) {
|
||||
this.loading = true
|
||||
try {
|
||||
const dictId = await this.getDictId(newVal)
|
||||
await this.getDictOptions(dictId)
|
||||
} catch (err) {
|
||||
console.error('加载字典失败:', err)
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
if (!newVal) return
|
||||
// toolbarOnly:仅打开弹窗时加载,避免无谓请求;下拉模式按 dict_type 加载选项
|
||||
if (this.toolbarOnly) return
|
||||
this.loading = true
|
||||
try {
|
||||
await this.loadDictRows()
|
||||
} catch (err) {
|
||||
console.error('加载字典失败:', err)
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
@@ -236,14 +239,11 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async getDictId(type) {
|
||||
const res = await listType({ dictType: type })
|
||||
if (res.rows?.length !== 1) {
|
||||
this.$message.error('字典类型异常,未查询到对应配置')
|
||||
return Promise.reject('字典类型异常')
|
||||
}
|
||||
this.dictId = res.rows[0].dictId
|
||||
return this.dictId
|
||||
/** 读字典数据行:优先 getDicts(/dict/data/type/{type}),无权限点与系统字典页 list 不一致问题 */
|
||||
async loadDictRows() {
|
||||
const res = await getDicts(this.dictType)
|
||||
this.dictOptions = res.data || []
|
||||
return this.dictOptions
|
||||
},
|
||||
disabledFormat(item) {
|
||||
if (this.disables) {
|
||||
@@ -256,27 +256,36 @@ export default {
|
||||
async handleRefresh() {
|
||||
this.loading = true
|
||||
try {
|
||||
await this.getDictOptions(this.dictId)
|
||||
await this.loadDictRows()
|
||||
} catch (err) {
|
||||
console.error('刷新字典失败:', err)
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
async getDictOptions(dictId) {
|
||||
const res = await listData({ dictType: this.dictType, pageSize: 1000 })
|
||||
this.dictOptions = res.rows || []
|
||||
return this.dictOptions
|
||||
},
|
||||
openDictDialog() {
|
||||
async openDictDialog() {
|
||||
this.open = true
|
||||
this.resetDictForm()
|
||||
this.form.dictId = this.dictId
|
||||
this.form.dictType = this.dictType
|
||||
this.editRowId = '' // 打开弹窗重置编辑状态
|
||||
this.editRowId = ''
|
||||
this.loading = true
|
||||
try {
|
||||
await this.loadDictRows()
|
||||
this.resetDictForm()
|
||||
} catch (err) {
|
||||
this.dictOptions = []
|
||||
console.error('打开字典配置失败:', err)
|
||||
this.$message.error('字典数据加载失败,请检查字典类型是否正确或稍后重试')
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
resetDictForm() {
|
||||
this.form = { dictId: this.dictId, dictLabel: '', dictValue: '', dictType: this.dictType, sort: 0 }
|
||||
this.form = {
|
||||
dictLabel: '',
|
||||
dictValue: '',
|
||||
dictType: this.dictType,
|
||||
dictSort: 0,
|
||||
status: '0'
|
||||
}
|
||||
this.$refs.dictFormRef && this.$refs.dictFormRef.clearValidate()
|
||||
},
|
||||
handleKisvTableSync(row) {
|
||||
@@ -290,7 +299,8 @@ export default {
|
||||
try {
|
||||
await addData(this.form)
|
||||
this.$message.success('字典项新增成功!')
|
||||
await this.getDictOptions(this.dictId)
|
||||
await this.loadDictRows()
|
||||
this.$emit('dict-updated')
|
||||
this.resetDictForm()
|
||||
} catch (err) {
|
||||
this.$message.error('新增失败,请稍后重试')
|
||||
@@ -309,18 +319,19 @@ export default {
|
||||
async handleSaveRow(row) {
|
||||
if (!row.dictLabel || !row.dictValue) {
|
||||
this.$message.warning('字典标签和字典值不能为空!')
|
||||
await this.getDictOptions(this.dictId)
|
||||
await this.loadDictRows()
|
||||
this.editRowId = '' // 校验失败,也必须还原单元格
|
||||
return
|
||||
}
|
||||
row.sort = 0
|
||||
if (row.dictSort == null) row.dictSort = 0
|
||||
this.loading = true
|
||||
try {
|
||||
await updateData(row)
|
||||
this.$message.success('字典项修改成功!')
|
||||
this.$emit('dict-updated')
|
||||
} catch (err) {
|
||||
this.$message.error('修改失败,请稍后重试')
|
||||
await this.getDictOptions(this.dictId)
|
||||
await this.loadDictRows()
|
||||
console.error(err)
|
||||
} finally {
|
||||
this.loading = false
|
||||
@@ -339,7 +350,8 @@ export default {
|
||||
try {
|
||||
await delData(row.dictCode)
|
||||
this.$message.success('删除成功!')
|
||||
await this.getDictOptions(this.dictId)
|
||||
await this.loadDictRows()
|
||||
this.$emit('dict-updated')
|
||||
} catch (err) {
|
||||
this.$message.error('删除失败,请稍后重试')
|
||||
console.error(err)
|
||||
|
||||
269
klp-ui/src/components/KLPService/ContractSelect/index.vue
Normal file
269
klp-ui/src/components/KLPService/ContractSelect/index.vue
Normal file
@@ -0,0 +1,269 @@
|
||||
<template>
|
||||
<div>
|
||||
<div style="display: flex; align-items: center; margin-bottom: 12px;">
|
||||
<el-select v-model="selectedValue" placeholder="请选择合同" style="width: 100%">
|
||||
<el-option v-for="item in contractList" :key="item.orderId" :value="item.orderId"
|
||||
:label="item.contractCode" />
|
||||
</el-select>
|
||||
<!-- 编辑按钮:点击打开弹窗 -->
|
||||
<el-button v-if="mode == 'today'" @click="openSelectDialog" type="primary" size="small" style="margin-left: 8px; padding: 0 12px;">
|
||||
<i class="el-icon-setting"></i>
|
||||
</el-button>
|
||||
|
||||
<!-- 刷新时不会移除手动添加的合同 -->
|
||||
<el-button @click="handleRefresh" type="info" size="small" style="margin-left: 8px; padding: 0 12px;">
|
||||
<i class="el-icon-refresh"></i>
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 查询所有的合同和当前localstorage中的合同,可以对localstorage中的合同进行新增和删除,手动新增的合同带有手动添加的标记 -->
|
||||
<el-dialog title="可选合同配置" :visible.sync="dialogVisible" width="80%" append-to-body>
|
||||
<el-tabs v-model="activeTab">
|
||||
<!-- 已配置合同tab -->
|
||||
<el-tab-pane label="可选合同" name="configured">
|
||||
<div v-if="contractList.length === 0" style="text-align: center; padding: 20px;">
|
||||
暂无已配置合同
|
||||
</div>
|
||||
<el-table v-else :data="contractList" style="width: 100%" size="mini" height="600">
|
||||
<el-table-column prop="contractCode" label="合同编号" width="160" />
|
||||
<el-table-column prop="contractName" label="合同名称" width="180" />
|
||||
<el-table-column prop="customer" label="客户" width="140" />
|
||||
<el-table-column prop="salesman" label="销售人员" width="100" />
|
||||
<el-table-column prop="deliveryDate" label="交付日期" width="110">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.deliveryDate || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remark" label="备注" show-overflow-tooltip />
|
||||
<el-table-column label="添加方式" width="90">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.isManual" type="success" size="small">手动</el-tag>
|
||||
<el-tag v-else type="info" size="small">接口</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="70">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="danger" size="mini" @click="removeContract(scope.row.orderId)" plain>
|
||||
移除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 所有合同tab -->
|
||||
<el-tab-pane label="所有合同" name="all">
|
||||
<div style="margin-bottom: 16px;">
|
||||
<el-input v-model="searchKeyword" placeholder="搜索合同" @input="handleSearch" clearable size="small">
|
||||
<el-button slot="append" icon="el-icon-search" size="small"></el-button>
|
||||
</el-input>
|
||||
</div>
|
||||
|
||||
<el-table :data="allContracts" style="width: 100%" size="mini" height="600">
|
||||
<el-table-column prop="contractCode" label="合同编号" width="160" />
|
||||
<el-table-column prop="contractName" label="合同名称" width="180" />
|
||||
<el-table-column prop="customer" label="客户" width="140" />
|
||||
<el-table-column prop="salesman" label="销售人员" width="100" />
|
||||
<el-table-column prop="deliveryDate" label="交付日期" width="110">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.deliveryDate || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remark" label="备注" show-overflow-tooltip />
|
||||
<el-table-column label="状态" width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="isContractInList(scope.row.orderId)" type="success" size="small">已添加</el-tag>
|
||||
<el-tag v-else type="info" size="small">未添加</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
v-if="!isContractInList(scope.row.orderId)"
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click="addContract(scope.row)"
|
||||
plain
|
||||
>
|
||||
添加
|
||||
</el-button>
|
||||
<el-button
|
||||
v-else
|
||||
type="danger"
|
||||
size="mini"
|
||||
@click="removeContract(scope.row.orderId)"
|
||||
plain
|
||||
>
|
||||
移除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div v-if="allContracts.length === 0" style="text-align: center; padding: 20px;">
|
||||
暂无合同数据
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listOrder, listTodayOrder } from '@/api/crm/order';
|
||||
|
||||
export default {
|
||||
name: "ContractSelect",
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
default: "today" // today 或 all
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
contractList: [],
|
||||
dialogVisible: false,
|
||||
searchKeyword: '',
|
||||
allContracts: [],
|
||||
activeTab: 'configured', // 默认显示已配置合同tab
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
selectedValue: {
|
||||
get() {
|
||||
return this.value;
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val);
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.mode == "today") {
|
||||
// 从localstorage中获取合同列表
|
||||
this.loadFromLocalStorage();
|
||||
} else {
|
||||
this.loadContractList();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 从localStorage中加载合同列表
|
||||
loadFromLocalStorage() {
|
||||
try {
|
||||
const storedContracts = localStorage.getItem('todayContracts');
|
||||
if (storedContracts) {
|
||||
this.contractList = JSON.parse(storedContracts);
|
||||
} else {
|
||||
// 如果localStorage中没有,从接口获取
|
||||
this.loadContractList();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load contracts from localStorage:', error);
|
||||
this.loadContractList();
|
||||
}
|
||||
},
|
||||
|
||||
// 保存合同列表到localStorage
|
||||
saveToLocalStorage() {
|
||||
try {
|
||||
localStorage.setItem('todayContracts', JSON.stringify(this.contractList));
|
||||
} catch (error) {
|
||||
console.error('Failed to save contracts to localStorage:', error);
|
||||
}
|
||||
},
|
||||
|
||||
// 加载合同列表
|
||||
async loadContractList(keyword) {
|
||||
if (this.mode == "all") {
|
||||
const res = await listOrder({
|
||||
pageNum: 1,
|
||||
pageSize: 1000,
|
||||
keyword: keyword || undefined,
|
||||
});
|
||||
this.contractList = res.rows || [];
|
||||
}
|
||||
else if (this.mode == "today") {
|
||||
const res = await listTodayOrder();
|
||||
// 获取现有手动添加的合同
|
||||
const existingManualContracts = this.contractList.filter(item => item.isManual);
|
||||
// 将接口返回的合同标记为非手动添加
|
||||
const apiContracts = (res.data || []).map(item => ({
|
||||
...item,
|
||||
isManual: false
|
||||
}));
|
||||
// 合并合同列表,保留手动添加的合同
|
||||
this.contractList = [...apiContracts, ...existingManualContracts];
|
||||
// 去重,避免重复合同
|
||||
this.contractList = this.contractList.filter((item, index, self) =>
|
||||
index === self.findIndex(t => t.orderId === item.orderId)
|
||||
);
|
||||
// 保存到localStorage
|
||||
this.saveToLocalStorage();
|
||||
}
|
||||
},
|
||||
// 打开选择弹窗
|
||||
async openSelectDialog() {
|
||||
this.dialogVisible = true;
|
||||
// 加载所有合同供选择
|
||||
await this.loadAllContracts();
|
||||
},
|
||||
|
||||
// 加载所有合同
|
||||
async loadAllContracts() {
|
||||
try {
|
||||
const res = await listOrder({
|
||||
pageNum: 1,
|
||||
pageSize: 1000,
|
||||
keyword: this.searchKeyword || undefined,
|
||||
});
|
||||
// 合并现有合同(包括手动添加的)
|
||||
const existingContracts = this.contractList;
|
||||
this.allContracts = [...res.rows || [], ...existingContracts].filter((item, index, self) =>
|
||||
index === self.findIndex(t => t.orderId === item.orderId)
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('Failed to load all contracts:', error);
|
||||
this.allContracts = [];
|
||||
}
|
||||
},
|
||||
|
||||
// 搜索合同
|
||||
handleSearch() {
|
||||
this.loadAllContracts();
|
||||
},
|
||||
|
||||
// 检查合同是否在列表中
|
||||
isContractInList(orderId) {
|
||||
return this.contractList.some(item => item.orderId === orderId);
|
||||
},
|
||||
|
||||
// 添加合同
|
||||
addContract(contract) {
|
||||
if (!this.isContractInList(contract.orderId)) {
|
||||
this.contractList.push({
|
||||
...contract,
|
||||
isManual: true // 标记为手动添加
|
||||
});
|
||||
this.saveToLocalStorage();
|
||||
}
|
||||
},
|
||||
|
||||
// 移除合同
|
||||
removeContract(orderId) {
|
||||
this.contractList = this.contractList.filter(item => item.orderId !== orderId);
|
||||
this.saveToLocalStorage();
|
||||
},
|
||||
|
||||
// 刷新合同列表
|
||||
handleRefresh() {
|
||||
this.loadContractList();
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -65,19 +65,19 @@
|
||||
</div>
|
||||
<div class="param-row" v-if="coil.length">
|
||||
<span class="param-label">长度:</span>
|
||||
<span class="param-value">{{ coil.length }}米</span>
|
||||
<span class="param-value">{{ coil.length }}m</span>
|
||||
</div>
|
||||
<div class="param-row" v-if="coil.actualLength">
|
||||
<span class="param-label">实测长度:</span>
|
||||
<span class="param-value">{{ coil.actualLength }}米</span>
|
||||
<span class="param-value">{{ coil.actualLength }}m</span>
|
||||
</div>
|
||||
<div class="param-row" v-if="coil.actualThickness">
|
||||
<span class="param-label">实测厚度:</span>
|
||||
<span class="param-value">{{ coil.actualThickness }}米</span>
|
||||
<span class="param-value">{{ coil.actualThickness }}mm</span>
|
||||
</div>
|
||||
<div class="param-row" v-if="coil.actualWidth">
|
||||
<span class="param-label">实测宽度:</span>
|
||||
<span class="param-value">{{ coil.actualWidth }}米</span>
|
||||
<span class="param-value">{{ coil.actualWidth }}mm</span>
|
||||
</div>
|
||||
<div class="param-row" v-if="coil.temperGrade">
|
||||
<span class="param-label">调制度:</span>
|
||||
|
||||
@@ -32,19 +32,19 @@
|
||||
</div>
|
||||
<div class="info-item" v-if="length">
|
||||
<span class="label">长度:</span>
|
||||
<span class="value">{{ length }}</span>
|
||||
<span class="value">{{ length }}m</span>
|
||||
</div>
|
||||
<div class="info-item" v-if="actualLength">
|
||||
<span class="label">实测长度:</span>
|
||||
<span class="value">{{ actualLength }}</span>
|
||||
<span class="value">{{ actualLength }}m</span>
|
||||
</div>
|
||||
<div class="info-item" v-if="actualLength">
|
||||
<span class="label">实测厚度:</span>
|
||||
<span class="value">{{ actualThickness }}</span>
|
||||
<span class="value">{{ actualThickness }}mm</span>
|
||||
</div>
|
||||
<div class="info-item" v-if="actualWidth">
|
||||
<span class="label">实测宽度:</span>
|
||||
<span class="value">{{ actualWidth }}</span>
|
||||
<span class="value">{{ actualWidth }}mm</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="label">厂家卷号:</span>
|
||||
|
||||
@@ -74,8 +74,10 @@ export default {
|
||||
console.log('仓库API返回数据:', response);
|
||||
const data = response.data || [];
|
||||
console.log('处理后的数据:', data);
|
||||
this.warehouseOptions = this.buildTreeOptions(data);
|
||||
console.log('构建的树形选项:', this.warehouseOptions);
|
||||
let options = this.buildTreeOptions(data);
|
||||
options = this.sortOptionsByUsage(options);
|
||||
this.warehouseOptions = options;
|
||||
console.log('构建并排序后的树形选项:', this.warehouseOptions);
|
||||
}).catch(error => {
|
||||
console.error("加载仓库选项失败:", error);
|
||||
this.warehouseOptions = [];
|
||||
@@ -106,7 +108,36 @@ export default {
|
||||
|
||||
return options;
|
||||
},
|
||||
getWarehouseUsage() {
|
||||
try {
|
||||
const usage = localStorage.getItem('warehouseUsage');
|
||||
return usage ? JSON.parse(usage) : {};
|
||||
} catch (error) {
|
||||
console.error('获取仓库使用记录失败:', error);
|
||||
return {};
|
||||
}
|
||||
},
|
||||
updateWarehouseUsage(warehouseId) {
|
||||
try {
|
||||
const usage = this.getWarehouseUsage();
|
||||
usage[warehouseId] = (usage[warehouseId] || 0) + 1;
|
||||
localStorage.setItem('warehouseUsage', JSON.stringify(usage));
|
||||
} catch (error) {
|
||||
console.error('更新仓库使用记录失败:', error);
|
||||
}
|
||||
},
|
||||
sortOptionsByUsage(options) {
|
||||
const usage = this.getWarehouseUsage();
|
||||
return options.sort((a, b) => {
|
||||
const usageA = usage[a.warehouseId] || 0;
|
||||
const usageB = usage[b.warehouseId] || 0;
|
||||
return usageB - usageA;
|
||||
});
|
||||
},
|
||||
onChange(val) {
|
||||
if (val) {
|
||||
this.updateWarehouseUsage(val);
|
||||
}
|
||||
this.$emit('input', val);
|
||||
this.$emit('change', val);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
<script>
|
||||
import { listWarehouse } from '@/api/wms/warehouse';
|
||||
// import { listActualWarehouse } from '@/api/wms/actualWarehouse';
|
||||
import { treeActualWarehouseTwoLevel } from '@/api/wms/actualWarehouse';
|
||||
|
||||
export default {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<transition name="el-fade-in-linear">
|
||||
<div v-if="tooltipVisible && data" class="row-tooltip" :style="adjustedTooltipStyle" ref="rowTooltip">
|
||||
<slot>
|
||||
<div class="tooltip-list">
|
||||
<div class="tooltip-list" :style="{ gridTemplateColumns: `repeat(${columnCount}, 1fr)` }">
|
||||
<div class="tooltip-item" v-for="field in visibleColumns" :key="field.prop">
|
||||
<span class="label">{{ field.label }}:</span>
|
||||
<span class="value">{{ formatTooltipValue(data, field) }}</span>
|
||||
@@ -21,6 +21,10 @@ export default {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
columnCount: {
|
||||
type: Number,
|
||||
default: 2
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
@@ -37,7 +41,20 @@ export default {
|
||||
computed: {
|
||||
// 一个列要同时有用 label 和 prop 才显示在浮层中, 并且prop有值时才显示
|
||||
visibleColumns() {
|
||||
return this.columns.filter(field => field.label && field.prop && this.data[field.prop])
|
||||
// 辅助函数:递归/迭代获取多层嵌套的属性值
|
||||
const getNestedValue = (obj, path) => {
|
||||
if (!obj || !path) return undefined;
|
||||
const pathArr = Array.isArray(path) ? path : path.split('.');
|
||||
return pathArr.reduce((current, key) => {
|
||||
return current === null || current === undefined ? undefined : current[key];
|
||||
}, obj);
|
||||
};
|
||||
|
||||
return this.columns.filter(field => {
|
||||
if (!field.label || !field.prop) return false;
|
||||
const value = getNestedValue(this.data, field.prop);
|
||||
return value !== null && value !== undefined && value !== '';
|
||||
})
|
||||
},
|
||||
// 修正后的tooltipStyle / 其实tooltipStyle只包含两个属性:top, left, 当在屏幕中无法完全展示时,需要根据实际情况调整位置
|
||||
adjustedTooltipStyle() {
|
||||
@@ -45,15 +62,47 @@ export default {
|
||||
const tooltipRect = this.$refs.rowTooltip?.getBoundingClientRect();
|
||||
if (!tooltipRect) return this.tooltipStyle;
|
||||
|
||||
// 检查是否超出底部边界
|
||||
if (parseInt(top) + tooltipRect.height > window.innerHeight) {
|
||||
return { ...this.tooltipStyle, top: `${window.innerHeight - tooltipRect.height - 12}px` };
|
||||
let adjustedTop = parseInt(top);
|
||||
let adjustedLeft = parseInt(left);
|
||||
const offset = 20;
|
||||
const scrollY = window.pageYOffset || document.documentElement.scrollTop;
|
||||
|
||||
// 考虑页面滚动的影响
|
||||
adjustedTop += scrollY;
|
||||
|
||||
// 先尝试显示在右下方
|
||||
let finalTop = adjustedTop;
|
||||
let finalLeft = adjustedLeft;
|
||||
|
||||
// 检查是否超出右边界,如果超出则显示在左方
|
||||
if (finalLeft + tooltipRect.width > window.innerWidth + (window.pageXOffset || 0)) {
|
||||
finalLeft = adjustedLeft - tooltipRect.width - offset;
|
||||
}
|
||||
// 检查是否超出右侧边界
|
||||
if (parseInt(left) + tooltipRect.width > window.innerWidth) {
|
||||
return { ...this.tooltipStyle, left: `${window.innerWidth - tooltipRect.width - 16}px` };
|
||||
|
||||
// 检查是否超出下边界,如果超出则显示在上方
|
||||
if (finalTop + tooltipRect.height > window.innerHeight + scrollY) {
|
||||
finalTop = adjustedTop - tooltipRect.height - offset;
|
||||
}
|
||||
return this.tooltipStyle;
|
||||
|
||||
// 确保浮层不会超出上边界
|
||||
if (finalTop < scrollY) {
|
||||
finalTop = scrollY + offset;
|
||||
}
|
||||
|
||||
// 确保浮层不会超出左边界
|
||||
if (finalLeft < 0) {
|
||||
finalLeft = offset;
|
||||
}
|
||||
|
||||
// 再次检查并调整右边界
|
||||
if (finalLeft + tooltipRect.width > window.innerWidth + (window.pageXOffset || 0)) {
|
||||
finalLeft = Math.max(offset, (window.innerWidth - tooltipRect.width) / 2);
|
||||
}
|
||||
|
||||
return {
|
||||
top: `${finalTop}px`,
|
||||
left: `${finalLeft}px`
|
||||
};
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -94,13 +143,39 @@ export default {
|
||||
position: absolute;
|
||||
background: #ffffff;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
padding: 12px 14px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
|
||||
padding: 16px 18px;
|
||||
pointer-events: none;
|
||||
z-index: 5;
|
||||
/* max-height: 70%; */
|
||||
z-index: 9999;
|
||||
overflow: auto;
|
||||
transition: all 0.3s ease-in-out;
|
||||
transition: all 0.25s ease-out;
|
||||
max-height: 75vh;
|
||||
min-width: 420px;
|
||||
}
|
||||
|
||||
.tooltip-list {
|
||||
display: grid;
|
||||
gap: 10px 16px;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.tooltip-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.tooltip-item .label {
|
||||
flex-shrink: 0;
|
||||
color: #909399;
|
||||
font-weight: 500;
|
||||
min-width: 90px;
|
||||
}
|
||||
|
||||
.tooltip-item .value {
|
||||
color: #303133;
|
||||
word-break: break-word;
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
@@ -18,7 +18,7 @@
|
||||
<slot name="append" v-bind="scope"></slot>
|
||||
</template>
|
||||
|
||||
<!-- 3. 透传“自定义列”插槽(直接接收<el-table-column> 嵌套的情况) -->
|
||||
<!-- 3. 透传"自定义列"插槽(直接接收<el-table-column> 嵌套的情况) -->
|
||||
<slot v-bind:tableRef="tableRef"></slot>
|
||||
|
||||
<el-table-column v-if="selectionColumn" type="selection" width="55" align="center"></el-table-column>
|
||||
@@ -27,7 +27,7 @@
|
||||
</el-table>
|
||||
<!-- 浮层组件 -->
|
||||
<KLPTableFloatLayer v-if="floatLayer" :columns="floatLayerColumns" :data="hoveredRow" :tooltipVisible="tooltipVisible"
|
||||
:tooltipStyle="tooltipStyle" />
|
||||
:tooltipStyle="tooltipStyle" :columnCount="floatLayerColumnCount" />
|
||||
</div>
|
||||
<!-- 扩展层:可后续统一添加分页(如与 MyPagination 组件联动) -->
|
||||
<slot name="pagination"></slot>
|
||||
@@ -78,7 +78,9 @@ export default {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
columns: [],
|
||||
title: '详细信息'
|
||||
title: '详细信息',
|
||||
columnCount: 2,
|
||||
excludeColumns: ['action']
|
||||
})
|
||||
},
|
||||
height: {
|
||||
@@ -101,11 +103,16 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
floatLayerColumns() {
|
||||
console.log(this.floatLayerConfig?.columns?.length > 1)
|
||||
if (this.floatLayerConfig?.columns?.length > 1) {
|
||||
return this.floatLayerConfig.columns
|
||||
}
|
||||
return this.columns;
|
||||
},
|
||||
floatLayerColumnCount() {
|
||||
return this.floatLayerConfig?.columnCount || 2;
|
||||
},
|
||||
excludeColumns() {
|
||||
return this.floatLayerConfig?.excludeColumns || ['action'];
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -157,6 +164,15 @@ export default {
|
||||
// 浮层相关
|
||||
handleCellEnter(row, column, cell, event) {
|
||||
if (!row || !event) return
|
||||
|
||||
// 检查是否是排除的列(操作列等)
|
||||
const excludeColumns = this.excludeColumns
|
||||
if (excludeColumns.includes(column.property)) {
|
||||
this.tooltipVisible = false
|
||||
this.hoveredRow = null
|
||||
return
|
||||
}
|
||||
|
||||
this.hoveredRow = row
|
||||
this.tooltipVisible = true
|
||||
this.updateTooltipPosition(event)
|
||||
|
||||
@@ -11,16 +11,17 @@
|
||||
:allow-create="allowAdd"
|
||||
:disabled="disabled"
|
||||
:size="size"
|
||||
:collapse-tags="collapseTags"
|
||||
@change="handleChange"
|
||||
>
|
||||
<!-- 全选选项 -->
|
||||
<el-option
|
||||
<!-- <el-option
|
||||
v-if="showSelectAll && options.length > 0"
|
||||
key="selectAll"
|
||||
label="全选"
|
||||
value="selectAll"
|
||||
@click="toggleSelectAll"
|
||||
/>
|
||||
/> -->
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
@@ -98,6 +99,10 @@
|
||||
showSelectAll: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
collapseTags: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
// 计算属性捕获实现双向绑定
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
<div class="right-menu">
|
||||
<template v-if="device!=='mobile'">
|
||||
<search id="header-search" class="right-menu-item" />
|
||||
<div class="right-menu-item hover-effect" @click="gotoTodo" title="代办事项">
|
||||
<el-icon class="el-icon-document-checked" />
|
||||
</div>
|
||||
|
||||
<screenfull id="screenfull" class="right-menu-item hover-effect" />
|
||||
|
||||
@@ -93,6 +96,9 @@ export default {
|
||||
window.location.reload(true)
|
||||
// this.$store.dispatch('app/refresh')
|
||||
},
|
||||
gotoTodo() {
|
||||
this.$router.push({ path: '/wms/todo' })
|
||||
},
|
||||
async logout() {
|
||||
this.$confirm('确定注销并退出系统吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
|
||||
@@ -49,6 +49,7 @@ import MemoInput from '@/components/MemoInput/index.vue'
|
||||
import MutiSelect from '@/components/MutiSelect/index.vue'
|
||||
import CurrentCoilNo from '@/components/KLPService/Renderer/CurrentCoilNo.vue'
|
||||
import DictSelect from '@/components/DictSelect'
|
||||
import CoilInfo from '@/views/wms/coil/components/CoilInfo.vue'
|
||||
|
||||
// 初始化所有列
|
||||
import { initAllColumns } from '@/views/wms/report/js/column.js'
|
||||
@@ -86,6 +87,7 @@ Vue.component('MutiSelect', MutiSelect)
|
||||
Vue.component('DictSelect', DictSelect)
|
||||
|
||||
Vue.component('CurrentCoilNo', CurrentCoilNo)
|
||||
Vue.component('CoilInfoRender', CoilInfo)
|
||||
|
||||
Vue.use(vueFlvPlayer)
|
||||
Vue.use(directive)
|
||||
|
||||
@@ -51,6 +51,7 @@ export const constantRoutes = [
|
||||
component: () => import('@/views/register'),
|
||||
hidden: true
|
||||
},
|
||||
|
||||
{
|
||||
path: '/404',
|
||||
component: () => import('@/views/error/404'),
|
||||
@@ -102,43 +103,37 @@ export const constantRoutes = [
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/aps',
|
||||
path: '/wms',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: 'lineCapability',
|
||||
component: () => import('@/views/aps/lineCapability/index'),
|
||||
name: 'ApsLineCapability',
|
||||
meta: { title: '产线能力' }
|
||||
path: 'todo',
|
||||
component: () => import('@/views/wms/todo/index'),
|
||||
name: 'Task',
|
||||
meta: { title: '待办任务', icon: 'checkbox' }
|
||||
},
|
||||
{
|
||||
path: 'processManage',
|
||||
component: () => import('@/views/aps/processManage/index'),
|
||||
name: 'ApsProcessManage',
|
||||
meta: { title: '工序管理' }
|
||||
},
|
||||
{
|
||||
path: 'factory-calendar',
|
||||
component: () => import('@/views/aps/factoryCalendar'),
|
||||
name: 'ApsFactoryCalendarPage',
|
||||
meta: { title: '工厂总日历' }
|
||||
path: 'coil/:coilId',
|
||||
component: () => import('@/views/wms/coil/info'),
|
||||
name: 'CoilInfo',
|
||||
meta: { title: '数字钢卷', icon: 'checkbox' }
|
||||
}
|
||||
]
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/wms/seal',
|
||||
component: Layout,
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: 'sealDetail/:bizId',
|
||||
component: () => import('@/views/wms/seal/sealDetail'),
|
||||
name: 'WmsSealDetail',
|
||||
meta: { title: '用印详情' }
|
||||
}
|
||||
]
|
||||
}
|
||||
// {
|
||||
// path: '/wms/seal',
|
||||
// component: Layout,
|
||||
// hidden: true,
|
||||
// children: [
|
||||
// {
|
||||
// path: 'sealDetail/:bizId',
|
||||
// component: () => import('@/views/wms/seal/sealDetail'),
|
||||
// name: 'WmsSealDetail',
|
||||
// meta: { title: '用印详情' }
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
]
|
||||
|
||||
// 动态路由,基于用户权限动态去加载
|
||||
|
||||
32
klp-ui/src/utils/attendanceRequest.js
Normal file
32
klp-ui/src/utils/attendanceRequest.js
Normal file
@@ -0,0 +1,32 @@
|
||||
import axios from 'axios'
|
||||
import { Notification, MessageBox, Message } from 'element-ui'
|
||||
|
||||
const request = axios.create({
|
||||
baseURL: 'http://140.143.206.120:18000',
|
||||
timeout: 5000
|
||||
})
|
||||
|
||||
// 响应拦截器
|
||||
request.interceptors.response.use(res => {
|
||||
if (res.data.status == 'success') {
|
||||
return res.data
|
||||
} else {
|
||||
Message({ message: res.data.message || '同步失败', type: 'error' })
|
||||
}
|
||||
},
|
||||
error => {
|
||||
console.log('err' + error)
|
||||
let { message } = error;
|
||||
if (message == "Network Error") {
|
||||
message = "后端接口连接异常";
|
||||
} else if (message.includes("timeout")) {
|
||||
message = "系统接口请求超时";
|
||||
} else if (message.includes("Request failed with status code")) {
|
||||
message = "系统接口" + message.substr(message.length - 3) + "异常";
|
||||
}
|
||||
Message({ message: message, type: 'error', duration: 5 * 1000 })
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
export default request
|
||||
@@ -11,8 +11,8 @@
|
||||
:type="formData.orderId ? 'success' : 'default'">
|
||||
{{ formData.orderId ? formData.contractCode : '选择订单' }}
|
||||
</el-button>
|
||||
<div v-if="formData.orderId" @click.stop="openOrderAttachmentDialog" style="margin-left: 10px; cursor: pointer; color: #409eff;"
|
||||
type="primary">
|
||||
<div v-if="formData.orderId" @click.stop="openOrderAttachmentDialog"
|
||||
style="margin-left: 10px; cursor: pointer; color: #409eff;" type="primary">
|
||||
查看附件
|
||||
</div>
|
||||
</template>
|
||||
@@ -68,6 +68,12 @@
|
||||
|
||||
<!-- 成品信息组 -->
|
||||
<el-collapse-item title="成品信息" name="3">
|
||||
<template slot="title">
|
||||
<!-- 如果已经绑定了订单,可以在这里选择订单明细来快速录入要生产的成品信息 -->
|
||||
<span>成品信息</span>
|
||||
<el-button type="primary" plain v-if="formData.orderId" style="margin-left: 10px;"
|
||||
@click.stop="openOrderItemDialog">选择订单明细</el-button>
|
||||
</template>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="成品名称" prop="productName">
|
||||
@@ -228,8 +234,6 @@
|
||||
<!-- 订单列表 -->
|
||||
<el-table v-loading="orderLoading" :data="orderList" style="width: 100%" @row-click="handleOrderSelect">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<!-- <el-table-column prop="orderCode" label="订单号" width="150" /> -->
|
||||
<el-table-column prop="orderType" label="订单类型" width="100" />
|
||||
<el-table-column prop="contractCode" label="合同号" width="150" />
|
||||
<el-table-column prop="signTime" label="签订时间" width="150" />
|
||||
<el-table-column prop="signLocation" label="签订地点" />
|
||||
@@ -254,6 +258,37 @@
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="选择订单明细" :visible.sync="orderItem.open" width="80%" append-to-body>
|
||||
<el-table v-loading="orderItem.loading" :data="orderItem.list" @row-click="selectOrderItem">
|
||||
<el-table-column label="产品类型" align="center" prop="productType" />
|
||||
<el-table-column label="成品宽度" align="center" prop="width" />
|
||||
<el-table-column label="成品厚度" align="center" prop="thickness" />
|
||||
<el-table-column label="成品规格" align="center" prop="finishedProductSpec" />
|
||||
<el-table-column label="宽度公差" align="center" prop="widthTolerance" />
|
||||
<el-table-column label="厚度公差" align="center" prop="thicknessTolerance" />
|
||||
|
||||
<el-table-column label="材质" align="center" prop="material" />
|
||||
<el-table-column label="重量" align="center" prop="weight" />
|
||||
<!-- <el-table-column label="含税单价(元/吨)" align="center" prop="contractPrice" />
|
||||
<el-table-column label="含税总额" align="center">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.weight * scope.row.contractPrice }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="无税单价(元/吨)" align="center" prop="itemAmount" /> -->
|
||||
<el-table-column label="卷数" align="center" prop="productNum" />
|
||||
<el-table-column label="表面处理" align="center" prop="surfaceTreatment" />
|
||||
<el-table-column label="包装要求" align="center" prop="packagingReq" />
|
||||
<el-table-column label="切边要求" align="center" prop="edgeCuttingReq" />
|
||||
<el-table-column label="用途" align="center" prop="purpose" />
|
||||
|
||||
|
||||
<el-table-column label="特殊要求" align="center" prop="specialRequire" />
|
||||
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="合同附件" :visible.sync="attachmentOpen" width="50%" append-to-body>
|
||||
<div class="attachment-section" v-loading="loading">
|
||||
<!-- <div class="attachment-item">
|
||||
@@ -275,7 +310,7 @@
|
||||
|
||||
<script>
|
||||
import { listOrder, getOrder } from '@/api/crm/order';
|
||||
import { listContract, getContract } from '@/api/crm/contract';
|
||||
import { listOrderItem } from '@/api/crm/orderItem'
|
||||
import FileList from '@/components/FileList'
|
||||
|
||||
export default {
|
||||
@@ -347,6 +382,11 @@ export default {
|
||||
attachmentOpen: false,
|
||||
contract: {},
|
||||
loading: false,
|
||||
orderItem: {
|
||||
loading: false,
|
||||
open: false,
|
||||
list: []
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
@@ -365,6 +405,34 @@ export default {
|
||||
// 加载订单列表
|
||||
this.getOrderList();
|
||||
},
|
||||
openOrderItemDialog() {
|
||||
this.orderItem.open = true;
|
||||
this.orderItem.loading = true;
|
||||
listOrderItem({ orderId: this.formData.orderId }).then(res => {
|
||||
this.orderItem.list = res.rows;
|
||||
this.orderItem.loading = false;
|
||||
})
|
||||
},
|
||||
selectOrderItem(row) {
|
||||
this.formData = {
|
||||
...this.formData,
|
||||
productName: row.productType,
|
||||
productMaterial: row.material,
|
||||
productWidth: row.width,
|
||||
rollingThick: row.thickness,
|
||||
markCoatThick: row.thickness,
|
||||
tonSteelLengthRange: 0,
|
||||
planQty: row.productNum,
|
||||
planWeight: row.weight,
|
||||
surfaceTreatment: row.surfaceTreatment,
|
||||
productPackaging: row.packagingReq,
|
||||
widthReq: row.edgeCuttingReq,
|
||||
productEdgeReq: row.widthTolerance,
|
||||
usageReq: row.purpose,
|
||||
}
|
||||
this.orderItem.open = false;
|
||||
// this.formData.orderItemId = row.orderItemId;
|
||||
},
|
||||
async openOrderAttachmentDialog() {
|
||||
this.loading = true;
|
||||
this.attachmentOpen = true;
|
||||
@@ -375,12 +443,6 @@ export default {
|
||||
return;
|
||||
}
|
||||
const order = await getOrder(this.formData.orderId);
|
||||
// if (!order.data.contractId) {
|
||||
// this.$message.error('未找到合同')
|
||||
// return;
|
||||
// }
|
||||
// 根据合同id拿到合同详情
|
||||
// const contract = await getContract(order.data.contractId);
|
||||
this.contract = order.data;
|
||||
} catch {
|
||||
this.$message.error('获取合同附件失败')
|
||||
@@ -388,12 +450,6 @@ export default {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
/** 获取合同列表 */
|
||||
// getContractList() {
|
||||
// listContract().then(response => {
|
||||
// this.contractList = response.rows;
|
||||
// });
|
||||
// },
|
||||
/** 获取订单列表 */
|
||||
getOrderList() {
|
||||
this.orderLoading = true;
|
||||
|
||||
492
klp-ui/src/views/aps/planSheet/PlanSheetList.vue
Normal file
492
klp-ui/src/views/aps/planSheet/PlanSheetList.vue
Normal file
@@ -0,0 +1,492 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="tab-container">
|
||||
<div class="select-button" @click="openPlanSheetDialog">
|
||||
<i class="el-icon-setting"></i>
|
||||
</div>
|
||||
<div class="custom-tabs">
|
||||
<div class="tab-header">
|
||||
<div
|
||||
v-for="planSheet in planSheetList"
|
||||
:key="planSheet.planSheetId"
|
||||
class="tab-item"
|
||||
:class="{ active: activeTab === planSheet.planSheetId.toString() }"
|
||||
@click="handleTabClick(planSheet)"
|
||||
>
|
||||
<div class="tab-title">{{ planSheet.planCode }}</div>
|
||||
<div class="tab-info">
|
||||
<span>{{ planSheet.lineName }}</span>
|
||||
<span class="date">{{ parseTime(planSheet.planDate, '{y}-{m}-{d}') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="planSheetList.length === 0" class="tab-item disabled">
|
||||
<div class="tab-title">暂无排产单</div>
|
||||
<div class="tab-info">请点击齿轮图标选择排产单</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 排产单选择对话框 -->
|
||||
<el-dialog :title="'选择排产单'" :visible.sync="planSheetDialogVisible" width="900px" append-to-body>
|
||||
<div class="dialog-toolbar">
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="68px">
|
||||
<el-form-item label="排产日期" prop="planDate">
|
||||
<el-date-picker clearable v-model="queryParams.planDate" type="date" value-format="yyyy-MM-dd"
|
||||
placeholder="请选择排产日期">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="产线名称" prop="lineName">
|
||||
<el-input v-model="queryParams.lineName" placeholder="请输入产线名称" clearable @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排产单号" prop="planCode">
|
||||
<el-input v-model="queryParams.planCode" placeholder="请输入排产单号" clearable @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排产人" prop="scheduler">
|
||||
<el-input v-model="queryParams.scheduler" placeholder="请输入排产人" clearable @keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-if="!readonly">新增</el-button>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-table v-loading="loading" :data="allPlanSheetList" height="350px" @row-click="handleTabClick">
|
||||
<el-table-column label="排产日期" align="center" prop="planDate" width="140">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.planDate, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="产线名称" align="center" prop="lineName" />
|
||||
<el-table-column label="排产单号" align="center" prop="planCode" />
|
||||
<el-table-column label="排产人" align="center" prop="scheduler" />
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-download" @click.stop="handleExport(scope.row)">导出</el-button>
|
||||
<el-button v-if="!readonly" size="mini" type="text" icon="el-icon-edit" @click.stop="handleUpdate(scope.row)">修改</el-button>
|
||||
<el-button v-if="!readonly" size="mini" type="text" icon="el-icon-delete" @click.stop="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
|
||||
@pagination="getList" />
|
||||
</el-dialog>
|
||||
|
||||
<!-- 添加或修改排产单对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="排产日期" prop="planDate">
|
||||
<el-date-picker clearable v-model="form.planDate" type="date" value-format="yyyy-MM-dd" placeholder="请选择排产日期">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="产线名称" prop="lineName">
|
||||
<el-select v-model="form.lineName" placeholder="请选择产线名称" filterable clearable>
|
||||
<el-option v-for="item in dict.type.sys_lines" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="排产单号" prop="planCode">
|
||||
<el-input v-model="form.planCode" placeholder="请输入排产单号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排产人" prop="scheduler">
|
||||
<el-input v-model="form.scheduler" placeholder="请输入排产人" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listPlanSheet, getPlanSheet, delPlanSheet, addPlanSheet, updatePlanSheet } from "@/api/aps/planSheet";
|
||||
|
||||
export default {
|
||||
name: "PlanSheetList",
|
||||
dicts: ['sys_lines'],
|
||||
props: {
|
||||
selectFirst: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 按钮loading
|
||||
buttonLoading: false,
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 排产单表格数据(用于tab展示)
|
||||
planSheetList: [],
|
||||
// 所有排产单数据(用于选择对话框)
|
||||
allPlanSheetList: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示添加/修改弹出层
|
||||
open: false,
|
||||
// 是否显示排产单选择弹出层
|
||||
planSheetDialogVisible: false,
|
||||
// 当前激活的tab
|
||||
activeTab: '',
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
planDate: undefined,
|
||||
lineId: undefined,
|
||||
lineName: undefined,
|
||||
planCode: undefined,
|
||||
planType: undefined,
|
||||
scheduler: undefined,
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 表单校验
|
||||
rules: {
|
||||
planSheetId: [
|
||||
{ required: true, message: "排产单键ID不能为空", trigger: "blur" }
|
||||
],
|
||||
planDate: [
|
||||
{ required: true, message: "排产日期不能为空", trigger: "blur" }
|
||||
],
|
||||
lineId: [
|
||||
{ required: true, message: "产线ID不能为空", trigger: "blur" }
|
||||
],
|
||||
lineName: [
|
||||
{ required: true, message: "产线名称不能为空", trigger: "blur" }
|
||||
],
|
||||
planCode: [
|
||||
{ required: true, message: "排产单号不能为空", trigger: "blur" }
|
||||
],
|
||||
planType: [
|
||||
{ required: true, message: "排产类型不能为空", trigger: "change" }
|
||||
],
|
||||
scheduler: [
|
||||
{ required: true, message: "排产人不能为空", trigger: "blur" }
|
||||
],
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList().then((list) => {
|
||||
// 如果有数据,选中第一个
|
||||
if (list.length > 0) {
|
||||
this.activeTab = list[0].planSheetId.toString();
|
||||
if (this.selectFirst) {
|
||||
this.handleRowClick(list[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
parseTime(time, pattern) {
|
||||
if (!time) return '';
|
||||
const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}';
|
||||
const date = new Date(time);
|
||||
const year = date.getFullYear();
|
||||
const month = date.getMonth() + 1;
|
||||
const day = date.getDate();
|
||||
const hour = date.getHours();
|
||||
const minute = date.getMinutes();
|
||||
const second = date.getSeconds();
|
||||
return format.replace('{y}', year)
|
||||
.replace('{m}', month.toString().padStart(2, '0'))
|
||||
.replace('{d}', day.toString().padStart(2, '0'))
|
||||
.replace('{h}', hour.toString().padStart(2, '0'))
|
||||
.replace('{i}', minute.toString().padStart(2, '0'))
|
||||
.replace('{s}', second.toString().padStart(2, '0'));
|
||||
},
|
||||
/** 查询排产单列表 */
|
||||
async getList() {
|
||||
this.loading = true;
|
||||
const response = await listPlanSheet(this.queryParams);
|
||||
this.allPlanSheetList = response.rows;
|
||||
this.total = response.total;
|
||||
// 默认显示所有排产单
|
||||
this.planSheetList = response.rows;
|
||||
this.loading = false;
|
||||
return this.planSheetList;
|
||||
},
|
||||
// 点击排产单行
|
||||
handleRowClick(row) {
|
||||
this.$emit('row-click', row);
|
||||
},
|
||||
// 点击tab
|
||||
handleTabClick(planSheet) {
|
||||
this.activeTab = planSheet.planSheetId.toString();
|
||||
this.planSheetDialogVisible = false;
|
||||
this.handleRowClick(planSheet);
|
||||
},
|
||||
// 打开排产单选择对话框
|
||||
openPlanSheetDialog() {
|
||||
this.getList();
|
||||
this.planSheetDialogVisible = true;
|
||||
},
|
||||
// 选择排产单行
|
||||
handlePlanSheetSelect(row) {
|
||||
this.$refs['queryForm'].$refs.table.toggleRowSelection(row);
|
||||
},
|
||||
// 确认选择排产单
|
||||
confirmSelect() {
|
||||
const selectedRows = this.$refs['queryForm'].$refs.table.selection;
|
||||
if (selectedRows.length > 0) {
|
||||
this.planSheetList = selectedRows;
|
||||
this.activeTab = selectedRows[0].planSheetId.toString();
|
||||
this.handleRowClick(selectedRows[0]);
|
||||
}
|
||||
this.planSheetDialogVisible = false;
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
// 表单重置
|
||||
reset() {
|
||||
// 日期默认选中今天 yyyy-MM-dd格式,北京时间
|
||||
// planCode与日期格式一致,添加-HHmmss
|
||||
// 排产人默认当前登录用户 this.$store.getters.nickName
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(now.getDate()).padStart(2, '0');
|
||||
const hours = String(now.getHours()).padStart(2, '0');
|
||||
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||||
const seconds = String(now.getSeconds()).padStart(2, '0');
|
||||
|
||||
const dateStr = `${year}-${month}-${day}`;
|
||||
const timeStr = `${hours}${minutes}${seconds}`;
|
||||
|
||||
this.form = {
|
||||
planSheetId: undefined,
|
||||
planDate: dateStr,
|
||||
lineId: undefined,
|
||||
lineName: undefined,
|
||||
planCode: `${dateStr}-${timeStr}`,
|
||||
planType: undefined,
|
||||
scheduler: this.$store.getters.nickName || undefined,
|
||||
remark: undefined,
|
||||
delFlag: undefined,
|
||||
createBy: undefined,
|
||||
updateBy: undefined,
|
||||
createTime: undefined,
|
||||
updateTime: undefined
|
||||
};
|
||||
this.resetForm("form");
|
||||
},
|
||||
// 重置表单
|
||||
resetForm(formName) {
|
||||
if (this.$refs[formName]) {
|
||||
this.$refs[formName].resetFields();
|
||||
}
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.open = true;
|
||||
this.title = "添加排产单";
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
this.loading = true;
|
||||
this.reset();
|
||||
const planSheetId = row.planSheetId;
|
||||
getPlanSheet(planSheetId).then(response => {
|
||||
this.loading = false;
|
||||
this.form = response.data;
|
||||
this.open = true;
|
||||
this.title = "修改排产单";
|
||||
});
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
this.buttonLoading = true;
|
||||
if (this.form.planSheetId != null) {
|
||||
updatePlanSheet(this.form).then(response => {
|
||||
this.$message({
|
||||
message: "修改成功",
|
||||
type: "success"
|
||||
});
|
||||
this.open = false;
|
||||
this.getList();
|
||||
}).finally(() => {
|
||||
this.buttonLoading = false;
|
||||
});
|
||||
} else {
|
||||
addPlanSheet(this.form).then(response => {
|
||||
this.$message({
|
||||
message: "新增成功",
|
||||
type: "success"
|
||||
});
|
||||
this.open = false;
|
||||
this.getList();
|
||||
}).finally(() => {
|
||||
this.buttonLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
const planSheetIds = row.planSheetId;
|
||||
this.$confirm('是否确认删除排产单编号为"' + planSheetIds + '"的数据项?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.loading = true;
|
||||
return delPlanSheet(planSheetIds);
|
||||
}).then(() => {
|
||||
this.loading = false;
|
||||
this.getList();
|
||||
this.$message({
|
||||
message: "删除成功",
|
||||
type: "success"
|
||||
});
|
||||
}).catch(() => {
|
||||
}).finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
handleExport(row) {
|
||||
this.download('aps/planSheet/exportAll', {
|
||||
...this.queryParams,
|
||||
planSheetId: row.planSheetId,
|
||||
}, `planSheet_${new Date().getTime()}.xlsx`);
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.tab-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.select-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 10px 16px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
background-color: #f9f9f9;
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
user-select: none;
|
||||
margin-right: 10px;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.select-button:hover {
|
||||
background-color: #ecf5ff;
|
||||
border-color: #c6e2ff;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.custom-tabs {
|
||||
flex: 1;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.tab-header {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.tab-item {
|
||||
padding: 4px 4px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-bottom: none;
|
||||
border-radius: 4px 4px 0 0;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
background-color: #f9f9f9;
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.tab-item:hover {
|
||||
background-color: #ecf5ff;
|
||||
border-color: #c6e2ff;
|
||||
}
|
||||
|
||||
.tab-item.active {
|
||||
background-color: #ffffff;
|
||||
border-color: #409eff;
|
||||
border-bottom-color: #ffffff;
|
||||
color: #409eff;
|
||||
box-shadow: 0 -2px 0 0 #409eff inset;
|
||||
}
|
||||
|
||||
.tab-item.disabled {
|
||||
cursor: not-allowed;
|
||||
background-color: #f5f7fa;
|
||||
color: #c0c4cc;
|
||||
border-color: #ebeef5;
|
||||
}
|
||||
|
||||
.tab-title {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 1px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.tab-info {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tab-info .date {
|
||||
color: #606266;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.empty-content {
|
||||
padding: 40px;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.dialog-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,219 +1,444 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-row :gutter="8">
|
||||
<el-col :span="16">
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"
|
||||
label-width="68px">
|
||||
<el-form-item label="排产日期" prop="planDate">
|
||||
<el-date-picker clearable v-model="queryParams.planDate" type="date" value-format="yyyy-MM-dd"
|
||||
placeholder="请选择排产日期">
|
||||
</el-date-picker>
|
||||
<!-- 增加操作列用于打开弹窗选择排产单,选择后展示选择的排产单的信息 -->
|
||||
<PlanSheetList @row-click="handleRowClick" />
|
||||
|
||||
<div v-if="currentPlanSheetId" class="plan-detail-container">
|
||||
<!-- 排产单信息 -->
|
||||
<div class="card-header">
|
||||
<h3>{{ currentPlanSheetInfo.planSheetName || '排产单详情' }}</h3>
|
||||
<div>
|
||||
<el-button type="primary" plain @click="handleAdd">新增明细</el-button>
|
||||
<el-button type="info" plain @click="getList">刷新</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="plan-info">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<span class="label">排产单号:</span>
|
||||
<span>{{ currentPlanSheetInfo.planCode }}</span>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<span class="label">排产人:</span>
|
||||
<span>{{ currentPlanSheetInfo.scheduler }}</span>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<span class="label">排产时间:</span>
|
||||
<span>{{ currentPlanSheetInfo.planDate }}</span>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<span class="label">产线:</span>
|
||||
<span>{{ currentPlanSheetInfo.lineName }}</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<!-- 可编辑表格 -->
|
||||
<el-table v-loading="loading" :data="planDetailList" style="width: 100%" border>
|
||||
<!-- 操作列 -->
|
||||
<el-table-column label="操作" align="center" width="120" fixed="left">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="primary" size="mini" @click="handleSave(scope.row)">保存</el-button>
|
||||
<el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="序号" align="center" prop="bizSeqNo" width="80" fixed="left">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.bizSeqNo" />
|
||||
<!-- {{ scope.$index + 1 }} -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 订单信息 -->
|
||||
<el-table-column label="订单号" align="center" prop="orderCode" width="200">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.orderCode">
|
||||
<template slot="append">
|
||||
<el-button size="mini" @click.stop="openOrderDialog(scope.row)">选择</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="合同号" align="center" prop="contractCode" width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.contractCode" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="客户" align="center" prop="customerName" width="180">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.customerName" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="业务员" align="center" prop="salesman" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.salesman" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 原料信息 -->
|
||||
<el-table-column label="原料厂家" align="center" prop="rawManufacturer" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.rawManufacturer" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="原料材质" align="center" prop="rawMaterial" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.rawMaterial" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="原料厚度" align="center" prop="rawThick" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.rawThick" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="原料宽度" align="center" prop="rawWidth" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.rawWidth" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 成品信息 -->
|
||||
<el-table-column label="成品名称" align="center" prop="productName" width="170">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.productName">
|
||||
<template slot="append">
|
||||
<el-button size="mini" @click.stop="openOrderItemDialog(scope.row)"
|
||||
:disabled="!scope.row.orderId">选择</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="成品材质" align="center" prop="productMaterial" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.productMaterial" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="成品镀层" align="center" prop="coatingG" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.coatingG" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="成品宽度" align="center" prop="productWidth" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.productWidth" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="轧制厚度" align="center" prop="rollingThick" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.rollingThick" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="标签厚度" align="center" prop="markCoatThick" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.markCoatThick" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="吨钢长度区间" align="center" prop="tonSteelLengthRange" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.tonSteelLengthRange" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="数量" align="center" prop="planQty" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.planQty" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="重量" align="center" prop="planWeight" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.planWeight" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="表面处理" align="center" prop="surfaceTreatmentDesc" width="100">
|
||||
<template slot-scope="scope">
|
||||
<MemoInput storageKey="surfaceTreatmentDesc" v-model="scope.row.surfaceTreatment" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="切边要求" align="center" prop="widthReq" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-select v-model="scope.row.widthReq" style="width: 100%">
|
||||
<el-option label="净边料" value="净边料" />
|
||||
<el-option label="毛边料" value="毛边料" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="包装要求" align="center" prop="productPackaging" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-select v-model="scope.row.productPackaging" style="width: 100%">
|
||||
<el-option label="裸包" value="裸包" />
|
||||
<el-option label="普包" value="普包" />
|
||||
<el-option label="简包" value="简包" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="宽度要求" align="center" prop="productEdgeReq" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.productEdgeReq" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="用途" align="center" prop="usageReq" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.usageReq" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 生产信息 -->
|
||||
<el-table-column label="开始时间" align="center" prop="startTime" width="180">
|
||||
<template slot-scope="scope">
|
||||
<el-date-picker v-model="scope.row.startTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss"
|
||||
style="width: 100%" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="结束时间" align="center" prop="endTime" width="180">
|
||||
<template slot-scope="scope">
|
||||
<el-date-picker v-model="scope.row.endTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss"
|
||||
style="width: 100%" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="后处理" align="center" prop="postProcess" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.postProcess" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="下工序" align="center" prop="nextProcess" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.nextProcess" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="取样" align="center" prop="sampleReq" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.sampleReq" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="备注" align="center" prop="remark">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.remark" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
|
||||
@pagination="getList" />
|
||||
</div>
|
||||
<el-empty v-else class="appempty" description="选择排产单查看详情" />
|
||||
|
||||
<!-- 选择订单对话框 -->
|
||||
<el-dialog title="选择订单" :visible.sync="orderDialogVisible" width="80%" append-to-body>
|
||||
<div class="order-dialog-content">
|
||||
<!-- 筛选条件 -->
|
||||
<el-form :model="orderQueryParams" ref="orderQueryForm" size="small" :inline="true" label-width="80px">
|
||||
<el-form-item label="合同号" prop="contractCode">
|
||||
<el-input v-model="orderQueryParams.contractCode" placeholder="请输入合同号" style="width: 180px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="产线名称" prop="lineName">
|
||||
<el-input v-model="queryParams.lineName" placeholder="请输入产线名称" clearable
|
||||
@keyup.enter.native="handleQuery" />
|
||||
<el-form-item label="客户">
|
||||
<el-input v-model="orderQueryParams.customerName" placeholder="请输入客户名称" style="width: 180px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排产单号" prop="planCode">
|
||||
<el-input v-model="queryParams.planCode" placeholder="请输入排产单号" clearable
|
||||
@keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排产人" prop="scheduler">
|
||||
<el-input v-model="queryParams.scheduler" placeholder="请输入排产人" clearable
|
||||
@keyup.enter.native="handleQuery" />
|
||||
<el-form-item label="业务员">
|
||||
<el-input v-model="orderQueryParams.salesman" placeholder="请输入业务员" style="width: 120px" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
|
||||
<!-- <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport">导出</el-button> -->
|
||||
<el-button type="primary" icon="el-icon-search" @click="getOrderList">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" @click="resetOrderQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-table v-loading="loading" :data="planSheetList" height="400px" @row-click="handleRowClick">
|
||||
<el-table-column label="排产日期" align="center" prop="planDate" width="140">
|
||||
<!-- 订单列表 -->
|
||||
<el-table v-loading="orderLoading" :data="orderList" style="width: 100%" @row-click="handleOrderSelect">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="contractCode" label="合同号" width="150" />
|
||||
<el-table-column prop="signTime" label="签订时间" width="150" />
|
||||
<el-table-column prop="signLocation" label="签订地点" />
|
||||
<el-table-column prop="companyName" label="客户" width="180" />
|
||||
<el-table-column prop="salesman" label="业务员" width="100" />
|
||||
<el-table-column prop="orderAmount" label="订单金额" width="120" align="right" />
|
||||
<el-table-column prop="deliveryDate" label="交货日期" width="150" />
|
||||
<el-table-column prop="createTime" label="创建时间" width="180" />
|
||||
<el-table-column label="操作" width="80" fixed="right">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.planDate, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column label="产线ID" align="center" prop="lineId" /> -->
|
||||
<el-table-column label="产线名称" align="center" prop="lineName" />
|
||||
<el-table-column label="排产单号" align="center" prop="planCode" />
|
||||
<!-- <el-table-column label="排产类型" align="center" prop="planType" /> -->
|
||||
<el-table-column label="排产人" align="center" prop="scheduler" />
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-download" @click="handleExport(scope.row)">导出</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||
<el-button type="text" size="small" @click.stop="selectOrder(scope.row)">选择</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum"
|
||||
:limit.sync="queryParams.pageSize" @pagination="getList" />
|
||||
|
||||
<PlanDetail v-if="currentPlanSheetId" ref="planDetail" :planSheetId="currentPlanSheetId"
|
||||
@change="handlePlanDetailChange" />
|
||||
<el-empty v-else class="appempty" description="选择排产单查看详情" />
|
||||
|
||||
<!-- 添加或修改排产单对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="排产日期" prop="planDate">
|
||||
<el-date-picker clearable v-model="form.planDate" type="date" value-format="yyyy-MM-dd"
|
||||
placeholder="请选择排产日期">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="产线名称" prop="lineName">
|
||||
<el-select v-model="form.lineName" placeholder="请选择产线名称" filterable clearable>
|
||||
<el-option v-for="item in dict.type.sys_lines" :key="item.value" :label="item.label"
|
||||
:value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="排产单号" prop="planCode">
|
||||
<el-input v-model="form.planCode" placeholder="请输入排产单号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="排产人" prop="scheduler">
|
||||
<el-input v-model="form.scheduler" placeholder="请输入排产人" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="8">
|
||||
<div class="detail-form-container">
|
||||
<div v-if="currentPlanDetail.planDetailId" class="detail-card">
|
||||
<div class="card-header">
|
||||
<span>排产明细信息</span>
|
||||
<el-button type="primary" size="mini" @click="submitDetail">保存变更</el-button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<PlanDetailForm v-model="currentPlanDetail" :plan-sheet-id="currentPlanSheetId" />
|
||||
</div>
|
||||
</div>
|
||||
<el-empty v-else description="选择排产单和明细行查看详情" />
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-container">
|
||||
<el-pagination background layout="prev, pager, next, jumper" :total="orderTotal"
|
||||
:page-size="orderQueryParams.pageSize" :current-page.sync="orderQueryParams.pageNum"
|
||||
@current-change="getOrderList" />
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 选择订单明细对话框 -->
|
||||
<el-dialog title="选择订单明细" :visible.sync="orderItemDialogVisible" width="80%" append-to-body>
|
||||
<el-table v-loading="orderItemLoading" :data="orderItemList" @row-click="selectOrderItem">
|
||||
<el-table-column label="产品类型" align="center" prop="productType" />
|
||||
<el-table-column label="成品宽度" align="center" prop="width" />
|
||||
<el-table-column label="成品厚度" align="center" prop="thickness" />
|
||||
<el-table-column label="成品规格" align="center" prop="finishedProductSpec" />
|
||||
<el-table-column label="材质" align="center" prop="material" />
|
||||
<el-table-column label="重量" align="center" prop="weight" />
|
||||
<el-table-column label="卷数" align="center" prop="productNum" />
|
||||
<el-table-column label="表面处理" align="center" prop="surfaceTreatment" />
|
||||
<el-table-column label="包装要求" align="center" prop="packagingReq" />
|
||||
<el-table-column label="切边要求" align="center" prop="edgeCuttingReq" />
|
||||
<el-table-column label="用途" align="center" prop="purpose" />
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listPlanSheet, getPlanSheet, delPlanSheet, addPlanSheet, updatePlanSheet } from "@/api/aps/planSheet";
|
||||
import { updatePlanDetail } from "@/api/aps/planDetail";
|
||||
import PlanDetail from "@/views/aps/planSheet/detail.vue";
|
||||
import PlanDetailForm from "@/views/aps/planSheet/PlanDetailForm.vue";
|
||||
import { updatePlanDetail, listPlanDetail, addPlanDetail, delPlanDetail } from "@/api/aps/planDetail";
|
||||
import { getPlanSheet } from "@/api/aps/planSheet";
|
||||
import { listOrder } from '@/api/crm/order';
|
||||
import { listOrderItem } from '@/api/crm/orderItem'
|
||||
import PlanSheetList from "@/views/aps/planSheet/PlanSheetList.vue";
|
||||
|
||||
export default {
|
||||
name: "PlanSheet",
|
||||
dicts: ['sys_lines'],
|
||||
components: {
|
||||
PlanDetail,
|
||||
PlanDetailForm
|
||||
PlanSheetList
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 按钮loading
|
||||
buttonLoading: false,
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 选中数组
|
||||
ids: [],
|
||||
// 非单个禁用
|
||||
single: true,
|
||||
// 非多个禁用
|
||||
multiple: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 当前选中的排产单ID
|
||||
currentPlanSheetId: undefined,
|
||||
// 当前选中的明细数据
|
||||
currentPlanDetail: {},
|
||||
// 排产单表格数据
|
||||
planSheetList: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 对话框可见状态
|
||||
dialogVisible: false,
|
||||
// 当前排产单详情信息
|
||||
currentPlanSheetInfo: {},
|
||||
// 最近选择的排产单列表
|
||||
recentPlanSheets: [],
|
||||
// 排产单明细表格数据
|
||||
planDetailList: [],
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 加载状态
|
||||
loading: false,
|
||||
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
planDate: undefined,
|
||||
lineId: undefined,
|
||||
lineName: undefined,
|
||||
planCode: undefined,
|
||||
planType: undefined,
|
||||
scheduler: undefined,
|
||||
pageSize: 50,
|
||||
planSheetId: undefined
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 表单校验
|
||||
rules: {
|
||||
planSheetId: [
|
||||
{ required: true, message: "排产单键ID不能为空", trigger: "blur" }
|
||||
],
|
||||
planDate: [
|
||||
{ required: true, message: "排产日期不能为空", trigger: "blur" }
|
||||
],
|
||||
lineId: [
|
||||
{ required: true, message: "产线ID不能为空", trigger: "blur" }
|
||||
],
|
||||
lineName: [
|
||||
{ required: true, message: "产线名称不能为空", trigger: "blur" }
|
||||
],
|
||||
planCode: [
|
||||
{ required: true, message: "排产单号不能为空", trigger: "blur" }
|
||||
],
|
||||
planType: [
|
||||
{ required: true, message: "排产类型不能为空", trigger: "change" }
|
||||
],
|
||||
scheduler: [
|
||||
{ required: true, message: "排产人不能为空", trigger: "blur" }
|
||||
],
|
||||
}
|
||||
// 订单对话框
|
||||
orderDialogVisible: false,
|
||||
// 订单明细对话框
|
||||
orderItemDialogVisible: false,
|
||||
// 订单列表
|
||||
orderList: [],
|
||||
// 订单总数
|
||||
orderTotal: 0,
|
||||
// 订单加载状态
|
||||
orderLoading: false,
|
||||
// 订单查询参数
|
||||
orderQueryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
contractCode: undefined,
|
||||
customerName: undefined,
|
||||
salesman: undefined
|
||||
},
|
||||
// 订单明细列表
|
||||
orderItemList: [],
|
||||
// 订单明细加载状态
|
||||
orderItemLoading: false,
|
||||
// 当前编辑的行
|
||||
currentEditingRow: null
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
// 从本地存储加载最近选择的排产单
|
||||
this.loadRecentPlanSheets();
|
||||
},
|
||||
methods: {
|
||||
/** 查询排产单列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listPlanSheet(this.queryParams).then(response => {
|
||||
this.planSheetList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
// 打开管理排产单对话框
|
||||
openDialog() {
|
||||
this.dialogVisible = true;
|
||||
},
|
||||
// 点击排产单行,显示详情
|
||||
handleRowClick(row) {
|
||||
this.currentPlanSheetId = row.planSheetId;
|
||||
this.currentPlanDetail = {};
|
||||
this.$nextTick(() => {
|
||||
this.$refs.planDetail.getList();
|
||||
})
|
||||
this.dialogVisible = false;
|
||||
|
||||
// 获取排产单详情
|
||||
this.getPlanSheetDetail(row.planSheetId);
|
||||
|
||||
// 添加到最近选择的列表
|
||||
this.addToRecentPlanSheets(row);
|
||||
|
||||
// 更新查询参数
|
||||
this.queryParams.planSheetId = row.planSheetId;
|
||||
|
||||
// 获取排产单明细列表
|
||||
this.getList();
|
||||
},
|
||||
// 获取排产单详情
|
||||
getPlanSheetDetail(planSheetId) {
|
||||
getPlanSheet(planSheetId).then(response => {
|
||||
this.currentPlanSheetInfo = response.data;
|
||||
});
|
||||
},
|
||||
// 添加到最近选择的排产单列表
|
||||
addToRecentPlanSheets(planSheet) {
|
||||
// 移除已存在的相同排产单
|
||||
this.recentPlanSheets = this.recentPlanSheets.filter(item => item.planSheetId !== planSheet.planSheetId);
|
||||
|
||||
// 添加到列表开头
|
||||
this.recentPlanSheets.unshift(planSheet);
|
||||
|
||||
// 限制最近选择的数量为5个
|
||||
if (this.recentPlanSheets.length > 5) {
|
||||
this.recentPlanSheets = this.recentPlanSheets.slice(0, 5);
|
||||
}
|
||||
|
||||
// 保存到本地存储
|
||||
this.saveRecentPlanSheets();
|
||||
},
|
||||
// 从本地存储加载最近选择的排产单
|
||||
loadRecentPlanSheets() {
|
||||
try {
|
||||
const stored = localStorage.getItem('recentPlanSheets');
|
||||
if (stored) {
|
||||
this.recentPlanSheets = JSON.parse(stored);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load recent plan sheets:', error);
|
||||
this.recentPlanSheets = [];
|
||||
}
|
||||
},
|
||||
// 保存最近选择的排产单到本地存储
|
||||
saveRecentPlanSheets() {
|
||||
try {
|
||||
localStorage.setItem('recentPlanSheets', JSON.stringify(this.recentPlanSheets));
|
||||
} catch (error) {
|
||||
console.error('Failed to save recent plan sheets:', error);
|
||||
}
|
||||
},
|
||||
// 选择最近的排产单
|
||||
selectRecentPlanSheet(item) {
|
||||
this.currentPlanSheetId = item.planSheetId;
|
||||
this.currentPlanDetail = {};
|
||||
this.currentPlanSheetInfo = item;
|
||||
|
||||
// 更新查询参数
|
||||
this.queryParams.planSheetId = item.planSheetId;
|
||||
|
||||
// 获取排产单明细列表
|
||||
this.getList();
|
||||
},
|
||||
// 处理排产明细行点击事件
|
||||
handlePlanDetailChange(row) {
|
||||
this.currentPlanDetail = row;
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
// 提交排产明细变更
|
||||
submitDetail() {
|
||||
updatePlanDetail(this.currentPlanDetail).then(response => {
|
||||
@@ -221,159 +446,212 @@ export default {
|
||||
message: "变更保存成功",
|
||||
type: "success"
|
||||
});
|
||||
this.handleQuery();
|
||||
});
|
||||
},
|
||||
// 表单重置
|
||||
reset() {
|
||||
// 日期默认选中今天 yyyy-MM-dd格式,北京时间
|
||||
// planCode与日期格式一致,添加-HHmmss
|
||||
// 排产人默认当前登录用户 this.$store.getters.nickName
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(now.getDate()).padStart(2, '0');
|
||||
const hours = String(now.getHours()).padStart(2, '0');
|
||||
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||||
const seconds = String(now.getSeconds()).padStart(2, '0');
|
||||
|
||||
const dateStr = `${year}-${month}-${day}`;
|
||||
const timeStr = `${hours}${minutes}${seconds}`;
|
||||
|
||||
this.form = {
|
||||
planSheetId: undefined,
|
||||
planDate: dateStr,
|
||||
lineId: undefined,
|
||||
lineName: undefined,
|
||||
planCode: `${dateStr}-${timeStr}`,
|
||||
planType: undefined,
|
||||
scheduler: this.$store.getters.nickName || undefined,
|
||||
remark: undefined,
|
||||
delFlag: undefined,
|
||||
createBy: undefined,
|
||||
updateBy: undefined,
|
||||
createTime: undefined,
|
||||
updateTime: undefined
|
||||
};
|
||||
this.resetForm("form");
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
},
|
||||
// 多选框选中数据
|
||||
handleSelectionChange(selection) {
|
||||
this.ids = selection.map(item => item.planSheetId)
|
||||
this.single = selection.length !== 1
|
||||
this.multiple = !selection.length
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.open = true;
|
||||
this.title = "添加排产单";
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
// 获取排产单明细列表
|
||||
getList() {
|
||||
this.loading = true;
|
||||
this.reset();
|
||||
const planSheetId = row.planSheetId || this.ids
|
||||
getPlanSheet(planSheetId).then(response => {
|
||||
this.loading = false;
|
||||
this.form = response.data;
|
||||
this.open = true;
|
||||
this.title = "修改排产单";
|
||||
});
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
this.buttonLoading = true;
|
||||
if (this.form.planSheetId != null) {
|
||||
updatePlanSheet(this.form).then(response => {
|
||||
this.$modal.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
}).finally(() => {
|
||||
this.buttonLoading = false;
|
||||
});
|
||||
} else {
|
||||
addPlanSheet(this.form).then(response => {
|
||||
this.$modal.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.getList();
|
||||
}).finally(() => {
|
||||
this.buttonLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
const planSheetIds = row.planSheetId || this.ids;
|
||||
this.$modal.confirm('是否确认删除排产单编号为"' + planSheetIds + '"的数据项?').then(() => {
|
||||
this.loading = true;
|
||||
return delPlanSheet(planSheetIds);
|
||||
}).then(() => {
|
||||
this.loading = false;
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
}).catch(() => {
|
||||
}).finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
handleExport(row) {
|
||||
this.download('aps/planSheet/exportAll', {
|
||||
listPlanDetail({
|
||||
...this.queryParams,
|
||||
planSheetId: row.planSheetId,
|
||||
}, `planSheet_${new Date().getTime()}.xlsx`)
|
||||
planSheetId: this.currentPlanSheetId,
|
||||
}).then(response => {
|
||||
// 按照序号正序排序
|
||||
this.planDetailList = response.rows.sort((a, b) => {
|
||||
return parseInt(a.bizSeqNo) - parseInt(b.bizSeqNo);
|
||||
});
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 新增明细
|
||||
handleAdd() {
|
||||
const newRow = {
|
||||
planSheetId: this.currentPlanSheetId,
|
||||
bizSeqNo: this.planDetailList.length + 1
|
||||
};
|
||||
|
||||
addPlanDetail(newRow).then(response => {
|
||||
this.$message({
|
||||
message: "新增成功",
|
||||
type: "success"
|
||||
});
|
||||
this.getList();
|
||||
});
|
||||
},
|
||||
// 保存行
|
||||
handleSave(row) {
|
||||
updatePlanDetail(row).then(response => {
|
||||
this.$message({
|
||||
message: "保存成功",
|
||||
type: "success"
|
||||
});
|
||||
}).catch(error => {
|
||||
this.$message({
|
||||
message: "保存失败,正在重新获取数据",
|
||||
type: "error"
|
||||
});
|
||||
// 保存失败时获取正确数据
|
||||
this.getList();
|
||||
});
|
||||
},
|
||||
// 删除行
|
||||
handleDelete(row) {
|
||||
this.$confirm('是否确认删除该排产单明细?', '警告', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
delPlanDetail(row.planDetailId).then(response => {
|
||||
this.$message({
|
||||
message: "删除成功",
|
||||
type: "success"
|
||||
});
|
||||
this.getList();
|
||||
});
|
||||
});
|
||||
},
|
||||
// 打开订单选择对话框
|
||||
openOrderDialog(row) {
|
||||
this.currentEditingRow = row;
|
||||
this.orderDialogVisible = true;
|
||||
this.getOrderList();
|
||||
},
|
||||
// 打开订单明细选择对话框
|
||||
openOrderItemDialog(row) {
|
||||
this.currentEditingRow = row;
|
||||
this.orderItemDialogVisible = true;
|
||||
this.orderItemLoading = true;
|
||||
listOrderItem({ orderId: row.orderId }).then(res => {
|
||||
this.orderItemList = res.rows;
|
||||
this.orderItemLoading = false;
|
||||
});
|
||||
},
|
||||
// 获取订单列表
|
||||
getOrderList() {
|
||||
this.orderLoading = true;
|
||||
listOrder(this.orderQueryParams).then(response => {
|
||||
this.orderList = response.rows;
|
||||
this.orderTotal = response.total;
|
||||
this.orderLoading = false;
|
||||
});
|
||||
},
|
||||
// 重置订单查询参数
|
||||
resetOrderQuery() {
|
||||
this.orderQueryParams = {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
contractCode: undefined,
|
||||
customerName: undefined,
|
||||
salesman: undefined
|
||||
};
|
||||
this.getOrderList();
|
||||
},
|
||||
// 选择订单
|
||||
selectOrder(row) {
|
||||
this.currentEditingRow.orderCode = row.orderCode;
|
||||
this.currentEditingRow.contractCode = row.contractCode;
|
||||
this.currentEditingRow.customerName = row.companyName;
|
||||
this.currentEditingRow.salesman = row.salesman;
|
||||
this.currentEditingRow.orderId = row.orderId;
|
||||
this.orderDialogVisible = false;
|
||||
|
||||
// 保存修改
|
||||
this.handleSave(this.currentEditingRow);
|
||||
},
|
||||
// 选择订单明细
|
||||
selectOrderItem(row) {
|
||||
this.currentEditingRow.productName = row.productType;
|
||||
this.currentEditingRow.productMaterial = row.material;
|
||||
this.currentEditingRow.productWidth = row.width;
|
||||
this.currentEditingRow.rollingThick = row.thickness;
|
||||
this.currentEditingRow.markCoatThick = row.thickness;
|
||||
this.currentEditingRow.tonSteelLengthRange = 0;
|
||||
this.currentEditingRow.planQty = row.productNum;
|
||||
this.currentEditingRow.planWeight = row.weight;
|
||||
this.currentEditingRow.surfaceTreatment = row.surfaceTreatment;
|
||||
this.currentEditingRow.productPackaging = row.packagingReq;
|
||||
this.currentEditingRow.widthReq = row.edgeCuttingReq;
|
||||
this.currentEditingRow.productEdgeReq = row.widthTolerance;
|
||||
this.currentEditingRow.usageReq = row.purpose;
|
||||
|
||||
this.orderItemDialogVisible = false;
|
||||
|
||||
// 保存修改
|
||||
this.handleSave(this.currentEditingRow);
|
||||
},
|
||||
// 处理订单行点击
|
||||
handleOrderSelect(row) {
|
||||
this.selectOrder(row);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.detail-form-container {
|
||||
height: 100%;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.detail-card {
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
padding: 12px 16px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
background-color: #fafafa;
|
||||
.header {
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 16px;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
.plan-info {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.card-header h3 {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.plan-info .label {
|
||||
font-weight: 600;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.plan-detail-container {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.el-table {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.el-table .cell {
|
||||
white-space: normal;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.order-dialog-content {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
margin-top: 20px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.appempty {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
::v-deep .el-table .cell {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* ::v-deep .el-input__inner {
|
||||
padding: 0 1px;
|
||||
} */
|
||||
</style>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user