refactor: 统一字段命名并优化字典树查询逻辑
将字段名从下划线命名法改为驼峰命名法,如 `sort_no` 改为 `sortNo`。同时优化了字典树查询逻辑,使用 `Map<String, Object>` 替代 `Dict` 实体类,简化了数据处理流程。
This commit is contained in:
parent
1e9ab24918
commit
77c9943703
@ -59,7 +59,7 @@ public abstract class BaseRepository {
|
||||
for (Map.Entry<String, Object> entry : params.entrySet()) {
|
||||
try {
|
||||
if (entry.getValue() == null) continue;
|
||||
String key = entry.getKey();
|
||||
String key = entry.getKey().replaceAll("([a-z])([A-Z]+)", "$1_$2").toLowerCase();
|
||||
Map<String, Object> condition;
|
||||
if (entry.getValue() instanceof String) {
|
||||
condition = objectMapper.readValue((String) entry.getValue(), Map.class);
|
||||
@ -102,7 +102,11 @@ public abstract class BaseRepository {
|
||||
params = preprocessParams(params);
|
||||
String orderBy = pageable.getSort().isEmpty()
|
||||
? ""
|
||||
: pageable.getSort().stream().map(order -> order.getProperty() + " " + order.getDirection()).collect(Collectors.joining(", "));
|
||||
: pageable
|
||||
.getSort()
|
||||
.stream()
|
||||
.map(order -> order.getProperty().replaceAll("([a-z])([A-Z]+)", "$1_$2").toLowerCase() + " " + order.getDirection())
|
||||
.collect(Collectors.joining(", "));
|
||||
long page = pageable.getPageNumber();
|
||||
long size = pageable.getPageSize();
|
||||
Map<String, Object> bindMap = new HashMap<>();
|
||||
@ -113,7 +117,8 @@ public abstract class BaseRepository {
|
||||
for (Map.Entry<String, Object> entry : params.entrySet()) {
|
||||
try {
|
||||
if (entry.getValue() == null) continue;
|
||||
String key = entry.getKey();
|
||||
String keyOrg = entry.getKey();
|
||||
String key = keyOrg.replaceAll("([a-z])([A-Z]+)", "$1_$2").toLowerCase();
|
||||
Map<String, Object> condition;
|
||||
if (entry.getValue() instanceof String) {
|
||||
condition = objectMapper.readValue((String) entry.getValue(), Map.class);
|
||||
@ -128,7 +133,7 @@ public abstract class BaseRepository {
|
||||
.append(fields.isEmpty() ? "" : ", ")
|
||||
.append(key)
|
||||
.append(" as ")
|
||||
.append(name.toString().isEmpty() ? key : name.toString());
|
||||
.append(name.toString().isEmpty() ? keyOrg : name.toString());
|
||||
}
|
||||
String operator = condition.get("op").toString();
|
||||
Object value = condition.get("value");
|
||||
@ -167,6 +172,7 @@ public abstract class BaseRepository {
|
||||
}
|
||||
|
||||
// 执行查询并返回结果
|
||||
//return executeSpec.fetch().all().map(this::convertKeysToCamelCase);
|
||||
return executeSpec.fetch().all();
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,9 @@ package com.vxnet.pms.service;
|
||||
import com.vxnet.pms.domain.Dict;
|
||||
import com.vxnet.pms.repository.DictRepository;
|
||||
import com.vxnet.pms.security.SecurityUtils;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import reactor.core.publisher.Flux;
|
||||
@ -71,35 +73,6 @@ public class DictService {
|
||||
);
|
||||
}
|
||||
|
||||
public Mono<Long> countDicts(String table, Map<String, Object> params) {
|
||||
return SecurityUtils.getCurrentOrganization().flatMap(organization -> dictRepository.countRows(organization, table, params));
|
||||
}
|
||||
|
||||
public Flux<Map<String, Object>> getDicts(String table, Map<String, Object> params, Pageable pageable) {
|
||||
return SecurityUtils.getCurrentOrganization()
|
||||
.map(organization -> dictRepository.getRows(organization, table, params, pageable))
|
||||
.flatMapMany(dicts -> dicts);
|
||||
}
|
||||
|
||||
public Mono<Long> countRootDicts(Map<String, Object> params) {
|
||||
return SecurityUtils.getCurrentOrganization().flatMap(organization -> dictRepository.countRootDicts(organization, params));
|
||||
}
|
||||
|
||||
public Flux<Dict> getDictTree(Map<String, Object> params, Pageable pageable) {
|
||||
return SecurityUtils.getCurrentOrganization()
|
||||
.map(organization -> dictRepository.findRootDicts(organization, params, pageable))
|
||||
.flatMapMany(rootDicts ->
|
||||
rootDicts.flatMap(rootDict ->
|
||||
Mono.just(rootDict)
|
||||
.zipWith(getChildren(rootDict.getOrganization(), rootDict.getNumber()).collectList())
|
||||
.map(tuple -> {
|
||||
rootDict.setChildren(tuple.getT2());
|
||||
return rootDict;
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private Flux<Dict> getChildren(String organization, String number) {
|
||||
return dictRepository
|
||||
.findByParentNumber(organization, number)
|
||||
@ -112,4 +85,46 @@ public class DictService {
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
public Mono<Long> countDicts(String table, Map<String, Object> params) {
|
||||
return SecurityUtils.getCurrentOrganization().flatMap(organization -> dictRepository.countRows(organization, table, params));
|
||||
}
|
||||
|
||||
public Flux<Map<String, Object>> getDicts(String table, Map<String, Object> params, Pageable pageable) {
|
||||
return SecurityUtils.getCurrentOrganization()
|
||||
.map(organization -> dictRepository.getRows(organization, table, params, pageable))
|
||||
.flatMapMany(dicts -> dicts);
|
||||
}
|
||||
|
||||
public Flux<Map<String, Object>> getDictsTree(String table, Map<String, Object> params, Pageable pageable) {
|
||||
return SecurityUtils.getCurrentOrganization()
|
||||
.flatMapMany(organization ->
|
||||
dictRepository
|
||||
.getRows(organization, table, params, pageable)
|
||||
.flatMap(dict -> {
|
||||
params.put("parentNumber[op]", "=");
|
||||
params.put("parentNumber[value]", dict.get("number").toString());
|
||||
return Mono.just(dict)
|
||||
.zipWith(getRowsChildren(organization, table, params).collectList())
|
||||
.map(tuple -> {
|
||||
dict.put("children", tuple.getT2());
|
||||
return dict;
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private Flux<Map<String, Object>> getRowsChildren(String organization, String table, Map<String, Object> params) {
|
||||
return dictRepository
|
||||
.getRows(organization, table, params, PageRequest.of(0, Integer.MAX_VALUE))
|
||||
.flatMap(dict -> {
|
||||
params.put("parentNumber[value]", dict.get("number").toString());
|
||||
return Mono.just(dict)
|
||||
.zipWith(getRowsChildren(organization, table, params).collectList())
|
||||
.map(tuple -> {
|
||||
dict.put("children", tuple.getT2());
|
||||
return dict;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ public class CompanyResource {
|
||||
"property",
|
||||
"remark",
|
||||
"status",
|
||||
"sort_no",
|
||||
"sortNo",
|
||||
"createdBy",
|
||||
"createdDate",
|
||||
"updatedBy",
|
||||
|
||||
@ -32,8 +32,8 @@ public class DictResource {
|
||||
"property",
|
||||
"remark",
|
||||
"status",
|
||||
"parent_number",
|
||||
"sort_no",
|
||||
"parentNumber",
|
||||
"sortNo",
|
||||
"createdBy",
|
||||
"createdDate",
|
||||
"updatedBy",
|
||||
@ -82,16 +82,18 @@ public class DictResource {
|
||||
}
|
||||
|
||||
@GetMapping("/dicts/tree")
|
||||
public Mono<ResponseEntity<Flux<Dict>>> getDictTree(
|
||||
public Mono<ResponseEntity<Flux<Map<String, Object>>>> getDictsTree(
|
||||
@RequestParam Map<String, Object> params,
|
||||
@org.springdoc.core.annotations.ParameterObject Pageable pageable
|
||||
) {
|
||||
String table = "jhi_dict";
|
||||
if (!onlyContainsAllowedProperties(pageable)) {
|
||||
return Mono.just(ResponseEntity.badRequest().build());
|
||||
}
|
||||
return dictService
|
||||
.countRootDicts(params)
|
||||
.map(total -> ResponseEntity.ok().header("X-Total-Count", String.valueOf(total)).body(dictService.getDictTree(params, pageable))
|
||||
.countDicts(table, params)
|
||||
.map(total ->
|
||||
ResponseEntity.ok().header("X-Total-Count", String.valueOf(total)).body(dictService.getDictsTree(table, params, pageable))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,8 +39,8 @@ public class StockResource {
|
||||
"property",
|
||||
"remark",
|
||||
"status",
|
||||
"parent_number",
|
||||
"sort_no",
|
||||
"parentNumber",
|
||||
"sortNo",
|
||||
"createdBy",
|
||||
"createdDate",
|
||||
"updatedBy",
|
||||
|
||||
@ -41,18 +41,18 @@ export default defineComponent({
|
||||
const [parentDictsRes, statusDictsRes] = await Promise.all([
|
||||
axios.get('api/dicts', {
|
||||
params: {
|
||||
number: { name: 'number' },
|
||||
name: { name: 'name' },
|
||||
parent_number: { op: 'IFNULL', value: '' },
|
||||
number: { name: '' },
|
||||
name: { name: '' },
|
||||
parentNumber: { op: 'IFNULL', value: '' },
|
||||
status: { op: '=', value: '1' },
|
||||
},
|
||||
}),
|
||||
axios.get('api/dicts', {
|
||||
params: {
|
||||
number: { name: 'number' },
|
||||
name: { name: 'name' },
|
||||
property: { name: 'property' },
|
||||
parent_number: { op: '=', value: 'StatusType' },
|
||||
number: { name: '' },
|
||||
name: { name: '' },
|
||||
property: { name: '' },
|
||||
parentNumber: { op: '=', value: 'StatusType' },
|
||||
status: { op: '=', value: '1' },
|
||||
},
|
||||
}),
|
||||
|
||||
@ -26,12 +26,23 @@ export default defineComponent({
|
||||
const statusDicts = ref([]);
|
||||
const showFilter = ref(false);
|
||||
const filterParams = ref({
|
||||
number: null,
|
||||
name: null,
|
||||
property: null,
|
||||
status: null,
|
||||
number: { op: '=', value: null },
|
||||
name: { op: '=', value: null },
|
||||
property: { op: '=', value: null },
|
||||
status: { op: '=', value: null },
|
||||
});
|
||||
|
||||
const operatorSelect = [
|
||||
{ value: '=', text: t$('entity.operator.equal') },
|
||||
{ value: '>', text: t$('entity.operator.greaterThan') },
|
||||
{ value: '<', text: t$('entity.operator.lessThan') },
|
||||
{ value: '>=', text: t$('entity.operator.greaterOrEqual') },
|
||||
{ value: '<=', text: t$('entity.operator.lessOrEqual') },
|
||||
{ value: '!=', text: t$('entity.operator.notEqual') },
|
||||
{ value: 'like', text: t$('entity.operator.like') },
|
||||
{ value: 'not like', text: t$('entity.operator.notLike') },
|
||||
];
|
||||
|
||||
// 父级字典选项
|
||||
const numberOptions = ref<SelectOption[]>([]);
|
||||
const isLoadingNumberOptions = ref(false);
|
||||
@ -94,9 +105,9 @@ export default defineComponent({
|
||||
isLoadingNumberOptions.value = true;
|
||||
try {
|
||||
const params = {
|
||||
number: { name: 'number' },
|
||||
name: { name: 'name' },
|
||||
parent_number: { op: 'IFNULL', value: '' },
|
||||
number: { name: '' },
|
||||
name: { name: '' },
|
||||
parentNumber: { op: 'IFNULL', value: '' },
|
||||
status: { op: '=', value: '1' },
|
||||
};
|
||||
//// 如果有查询条件,添加到请求参数中
|
||||
@ -126,7 +137,7 @@ export default defineComponent({
|
||||
handleSyncList();
|
||||
};
|
||||
|
||||
const propOrder = ref('sort_no');
|
||||
const propOrder = ref('sortNo');
|
||||
const reverse = ref(false);
|
||||
|
||||
const sort = () => {
|
||||
@ -151,30 +162,40 @@ export default defineComponent({
|
||||
const handleSyncList = async () => {
|
||||
isFetching.value = true;
|
||||
try {
|
||||
const processedParams = showFilter.value
|
||||
? Object.entries(filterParams.value).reduce((acc, [key, value]) => {
|
||||
acc[key] = value === '' ? null : value;
|
||||
return acc;
|
||||
}, {})
|
||||
: {};
|
||||
|
||||
let params = Object.entries(dict.value).reduce((acc, [key]) => {
|
||||
acc[`${key}[name]`] = '';
|
||||
if (key === 'parentNumber') {
|
||||
acc[`${key}[op]`] = 'IFNULL';
|
||||
acc[`${key}[value]`] = '';
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
if (showFilter.value) {
|
||||
params = Object.entries(filterParams.value).reduce((acc, [key, filterParam]) => {
|
||||
if (filterParam.value !== null && filterParam.value !== '') {
|
||||
acc[`${key}[op]`] = filterParam.op;
|
||||
acc[`${key}[value]`] = filterParam.value;
|
||||
}
|
||||
return acc;
|
||||
}, params);
|
||||
}
|
||||
console.log('params', params);
|
||||
// 获取分页数据
|
||||
const paginationQuery = {
|
||||
page: page.value - 1,
|
||||
size: itemsPerPage.value,
|
||||
sort: sort(),
|
||||
};
|
||||
|
||||
// 获取状态字典列表
|
||||
const [dictsRes, statusDictsRes] = await Promise.all([
|
||||
axios.get(`api/dicts/tree?${buildPaginationQuery(paginationQuery)}`, {
|
||||
params: processedParams,
|
||||
params: params,
|
||||
}),
|
||||
axios.get('api/dicts', {
|
||||
params: {
|
||||
number: { name: 'number' },
|
||||
name: { name: 'name' },
|
||||
parent_number: { op: '=', value: 'StatusType' },
|
||||
number: { name: '' },
|
||||
name: { name: '' },
|
||||
parentNumber: { op: '=', value: 'StatusType' },
|
||||
status: { op: '=', value: '1' },
|
||||
},
|
||||
}),
|
||||
@ -246,6 +267,7 @@ export default defineComponent({
|
||||
propOrder,
|
||||
reverse,
|
||||
changeOrder,
|
||||
operatorSelect,
|
||||
handlePageSizeChange,
|
||||
};
|
||||
},
|
||||
|
||||
@ -31,32 +31,38 @@
|
||||
<vue-select
|
||||
class="form-control"
|
||||
id="filter-number"
|
||||
v-model="filterParams.number"
|
||||
v-model="filterParams.number.value"
|
||||
:options="numberOptions"
|
||||
:is-loading="isLoadingNumberOptions"
|
||||
:placeholder="$t('entity.action.select')"
|
||||
@search="loadNumberOptions"
|
||||
@select="option => (filterParams.number = option.value)"
|
||||
@select="option => (filterParams.number.value = option.value)"
|
||||
/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-control-label" for="filter-name">{{ $t('jewpmsApp.dict.name') }}</label>
|
||||
<input type="text" class="form-control" id="filter-name" v-model="filterParams.name" />
|
||||
<b-input-group class="form-control-group">
|
||||
<b-form-select id="filter-op" v-model="filterParams.name.op" :options="operatorSelect"></b-form-select>
|
||||
<b-form-input id="filter-name" v-model="filterParams.name.value"></b-form-input>
|
||||
</b-input-group>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-control-label" for="filter-property">{{ $t('jewpmsApp.dict.property') }}</label>
|
||||
<input type="text" class="form-control" id="filter-property" v-model="filterParams.property" />
|
||||
<b-input-group class="form-control-group">
|
||||
<b-form-select id="filter-op" v-model="filterParams.property.op" :options="operatorSelect"></b-form-select>
|
||||
<b-form-input id="filter-property" v-model="filterParams.property.value"></b-form-input>
|
||||
</b-input-group>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-control-label">{{ $t('jewpmsApp.dict.status') }}</label>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" id="status-active" :value="1" v-model="filterParams.status" />
|
||||
<label class="form-check-label" for="status-active">生效</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" id="status-inactive" :value="0" v-model="filterParams.status" />
|
||||
<label class="form-check-label" for="status-inactive">失效</label>
|
||||
</div>
|
||||
<b-input-group class="form-control-group">
|
||||
<b-form-select id="filter-op" v-model="filterParams.status.op" :options="operatorSelect"></b-form-select>
|
||||
<b-form-select id="filter-status" v-model="filterParams.status.value">
|
||||
<option :value="null">{{ $t('entity.action.select') }}</option>
|
||||
<option :value="1">生效</option>
|
||||
<option :value="0">失效</option>
|
||||
</b-form-select>
|
||||
</b-input-group>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -70,23 +70,27 @@ export default defineComponent({
|
||||
const handleSyncList = async () => {
|
||||
isFetching.value = true;
|
||||
try {
|
||||
const processedParams = showFilter.value
|
||||
? Object.entries(filterParams.value).reduce((acc, [key, filterParam]) => {
|
||||
if (filterParam.value !== null && filterParam.value !== '') {
|
||||
acc[`${key}[op]`] = filterParam.op;
|
||||
acc[`${key}[value]`] = filterParam.value;
|
||||
}
|
||||
return acc;
|
||||
}, {})
|
||||
: {};
|
||||
let params = Object.entries(stock.value).reduce((acc, [key]) => {
|
||||
acc[`${key}[name]`] = '';
|
||||
return acc;
|
||||
}, {});
|
||||
if (showFilter.value) {
|
||||
params = Object.entries(filterParams.value).reduce((acc, [key, filterParam]) => {
|
||||
if (filterParam.value !== null && filterParam.value !== '') {
|
||||
acc[`${key}[op]`] = filterParam.op;
|
||||
acc[`${key}[value]`] = filterParam.value;
|
||||
}
|
||||
return acc;
|
||||
}, params);
|
||||
}
|
||||
|
||||
const stocksRes = await axios.get(
|
||||
`api/stocks?${buildPaginationQuery({
|
||||
page: page.value - 1,
|
||||
size: itemsPerPage.value,
|
||||
sort: sort(),
|
||||
...processedParams,
|
||||
})}`,
|
||||
{ params: params },
|
||||
);
|
||||
stocks.value = stocksRes.data;
|
||||
totalItems.value = stocksRes.headers['x-total-count'] || stocksRes.data.length;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user