This commit is contained in:
YunaiV 2025-05-13 19:30:11 +08:00
commit f3b897ea5d
11 changed files with 100 additions and 67 deletions

View File

@ -4,7 +4,6 @@ import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.toolkit.MPJWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.springframework.util.StringUtils;
@ -15,94 +14,94 @@ import java.util.function.Consumer;
* 拓展 MyBatis Plus Join QueryWrapper 主要增加如下功能
* <p>
* 1. 拼接条件的方法增加 xxxIfPresent 方法用于判断值不存在的时候不要拼接到条件中
*
* 2. SFunction<S, ?> column + <S> 泛型支持任意类字段主表子表三表推荐写法, 让编译器自动推断 S 类型
* @param <T> 数据类型
*/
public class MPJLambdaWrapperX<T> extends MPJLambdaWrapper<T> {
public <R> MPJLambdaWrapperX<T> likeIfPresent(SFunction<R, ?> column, String val) {
MPJWrappers.lambdaJoin().like(column, val);
public <S> MPJLambdaWrapperX<T> likeIfPresent(SFunction<S, ?> column, String val) {
if (StringUtils.hasText(val)) {
return (MPJLambdaWrapperX<T>) super.like(column, val);
}
return this;
}
public <R> MPJLambdaWrapperX<T> inIfPresent(SFunction<R, ?> column, Collection<?> values) {
public <S> MPJLambdaWrapperX<T> inIfPresent(SFunction<S, ?> column, Collection<?> values) {
if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
return (MPJLambdaWrapperX<T>) super.in(column, values);
}
return this;
}
public <R> MPJLambdaWrapperX<T> inIfPresent(SFunction<R, ?> column, Object... values) {
public <S> MPJLambdaWrapperX<T> inIfPresent(SFunction<S, ?> column, Object... values) {
if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
return (MPJLambdaWrapperX<T>) super.in(column, values);
}
return this;
}
public <R> MPJLambdaWrapperX<T> eqIfPresent(SFunction<R, ?> column, Object val) {
public <S> MPJLambdaWrapperX<T> eqIfPresent(SFunction<S, ?> column, Object val) {
if (ObjectUtil.isNotEmpty(val)) {
return (MPJLambdaWrapperX<T>) super.eq(column, val);
}
return this;
}
public <R> MPJLambdaWrapperX<T> neIfPresent(SFunction<R, ?> column, Object val) {
public <S> MPJLambdaWrapperX<T> neIfPresent(SFunction<S, ?> column, Object val) {
if (ObjectUtil.isNotEmpty(val)) {
return (MPJLambdaWrapperX<T>) super.ne(column, val);
}
return this;
}
public <R> MPJLambdaWrapperX<T> gtIfPresent(SFunction<R, ?> column, Object val) {
public <S> MPJLambdaWrapperX<T> gtIfPresent(SFunction<S, ?> column, Object val) {
if (val != null) {
return (MPJLambdaWrapperX<T>) super.gt(column, val);
}
return this;
}
public <R> MPJLambdaWrapperX<T> geIfPresent(SFunction<R, ?> column, Object val) {
public <S> MPJLambdaWrapperX<T> geIfPresent(SFunction<S, ?> column, Object val) {
if (val != null) {
return (MPJLambdaWrapperX<T>) super.ge(column, val);
}
return this;
}
public <R> MPJLambdaWrapperX<T> ltIfPresent(SFunction<R, ?> column, Object val) {
public <S> MPJLambdaWrapperX<T> ltIfPresent(SFunction<S, ?> column, Object val) {
if (val != null) {
return (MPJLambdaWrapperX<T>) super.lt(column, val);
}
return this;
}
public <R> MPJLambdaWrapperX<T> leIfPresent(SFunction<R, ?> column, Object val) {
public <S> MPJLambdaWrapperX<T> leIfPresent(SFunction<S, ?> column, Object val) {
if (val != null) {
return (MPJLambdaWrapperX<T>) super.le(column, val);
}
return this;
}
public <R> MPJLambdaWrapperX<T> betweenIfPresent(SFunction<R, ?> column, Object val1, Object val2) {
if (val1 != null && val2 != null) {
return (MPJLambdaWrapperX<T>) super.between(column, val1, val2);
}
if (val1 != null) {
return (MPJLambdaWrapperX<T>) ge(column, val1);
}
if (val2 != null) {
return (MPJLambdaWrapperX<T>) le(column, val2);
}
return this;
}
public <R> MPJLambdaWrapperX<T> betweenIfPresent(SFunction<R, ?> column, Object[] values) {
public <S> MPJLambdaWrapperX<T> betweenIfPresent(SFunction<S, ?> column, Object[] values) {
Object val1 = ArrayUtils.get(values, 0);
Object val2 = ArrayUtils.get(values, 1);
return betweenIfPresent(column, val1, val2);
}
public <S> MPJLambdaWrapperX<T> betweenIfPresent(SFunction<S, ?> column, Object val1, Object val2) {
if (val1 != null && val2 != null) {
return (MPJLambdaWrapperX<T>) super.between(column, val1, val2);
}
if (val1 != null) {
return (MPJLambdaWrapperX<T>) super.ge(column, val1);
}
if (val2 != null) {
return (MPJLambdaWrapperX<T>) super.le(column, val2);
}
return this;
}
// ========== 重写父类方法方便链式调用 ==========
@Override
@ -310,4 +309,41 @@ public class MPJLambdaWrapperX<T> extends MPJLambdaWrapper<T> {
return this;
}
// ========== 关键重写使 leftJoin 返回当前类型 this ==========
@Override
public <A, B> MPJLambdaWrapperX<T> leftJoin(Class<A> clazz, SFunction<A, ?> left, SFunction<B, ?> right) {
super.leftJoin(clazz, left, right);
return this;
}
@Override
public <A, B> MPJLambdaWrapperX<T> rightJoin(Class<A> clazz, SFunction<A, ?> left, SFunction<B, ?> right) {
super.rightJoin(clazz, left, right);
return this;
}
@Override
public <A, B> MPJLambdaWrapperX<T> innerJoin(Class<A> clazz, SFunction<A, ?> left, SFunction<B, ?> right) {
super.innerJoin(clazz, left, right);
return this;
}
// ========== 添加扩展 Join 支持 ext 函数式参数 ==========
public <A, B> MPJLambdaWrapperX<T> leftJoin(Class<A> clazz, SFunction<A, ?> left, SFunction<B, ?> right, Consumer<MPJLambdaWrapperX<T>> ext) {
super.leftJoin(clazz, left, right);
if (ext != null) ext.accept(this);
return this;
}
public <A, B> MPJLambdaWrapperX<T> rightJoin(Class<A> clazz, SFunction<A, ?> left, SFunction<B, ?> right, Consumer<MPJLambdaWrapperX<T>> ext) {
super.rightJoin(clazz, left, right);
if (ext != null) ext.accept(this);
return this;
}
public <A, B> MPJLambdaWrapperX<T> innerJoin(Class<A> clazz, SFunction<A, ?> left, SFunction<B, ?> right, Consumer<MPJLambdaWrapperX<T>> ext) {
super.innerJoin(clazz, left, right);
if (ext != null) ext.accept(this);
return this;
}
}

View File

@ -64,7 +64,6 @@ public class AiUtils {
return OpenAiChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens)
.toolNames(toolNames).toolContext(toolContext).build();
case AZURE_OPENAI:
// TODO 芋艿貌似没 model 字段
return AzureOpenAiChatOptions.builder().deploymentName(model).temperature(temperature).maxTokens(maxTokens)
.toolNames(toolNames).toolContext(toolContext).build();
case OLLAMA:

View File

@ -2,9 +2,9 @@ package cn.iocoder.yudao.module.bpm.convert.task;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.iocoder.yudao.framework.common.core.KeyValue;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO;
@ -53,6 +53,7 @@ public interface BpmTaskConvert {
taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class));
AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId()));
taskVO.getProcessInstance().setStartUser(BeanUtils.toBean(startUser, UserSimpleBaseVO.class));
taskVO.getProcessInstance().setCreateTime(DateUtils.of(processInstance.getStartTime()));
// 摘要
taskVO.getProcessInstance().setSummary(FlowableUtils.getSummary(processDefinitionInfoMap.get(processInstance.getProcessDefinitionId()),
processInstance.getProcessVariables()));

View File

@ -14,6 +14,7 @@ import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior;
import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import java.util.List;
import java.util.Set;
@ -82,4 +83,13 @@ public class BpmSequentialMultiInstanceBehavior extends SequentialMultiInstanceB
return super.resolveNrOfInstances(execution);
}
@Override
protected void executeOriginalBehavior(DelegateExecution execution, ExecutionEntity multiInstanceRootExecution, int loopCounter) {
// 参见 https://gitee.com/zhijiantianya/yudao-cloud/issues/IC239F
super.collectionExpression = null;
super.collectionVariable = FlowableUtils.formatExecutionCollectionVariable(execution.getCurrentActivityId());
super.collectionElementVariable = FlowableUtils.formatExecutionCollectionElementVariable(execution.getCurrentActivityId());
super.executeOriginalBehavior(execution, multiInstanceRootExecution, loopCounter);
}
}

View File

@ -597,6 +597,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
* @param nextAssignees 下一个节点审批人集合参数
* @param processInstance 流程实例
*/
@SuppressWarnings("unchecked")
private Map<String, Object> validateAndSetNextAssignees(String taskDefinitionKey, Map<String, Object> variables, BpmnModel bpmnModel,
Map<String, List<Long>> nextAssignees, ProcessInstance processInstance) {
// simple 设计器第一个节点默认为发起人节点不校验是否存在审批人
@ -646,6 +647,11 @@ public class BpmTaskServiceImpl implements BpmTaskService {
approveUserSelectAssignees = new HashMap<>();
}
approveUserSelectAssignees.put(nextFlowNode.getId(), assignees);
Map<String,List<Long>> existingApproveUserSelectAssignees = (Map<String,List<Long>>) variables.get(
BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_APPROVE_USER_SELECT_ASSIGNEES);
if (CollUtil.isNotEmpty(existingApproveUserSelectAssignees)) {
approveUserSelectAssignees.putAll(existingApproveUserSelectAssignees);
}
variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_APPROVE_USER_SELECT_ASSIGNEES, approveUserSelectAssignees);
}
}

View File

@ -214,7 +214,7 @@ public class CrmContactServiceImpl implements CrmContactService {
}
}
@LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_UPDATE_OWNER_USER_SUB_TYPE, bizNo = "{{#contact.id}",
@LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_UPDATE_OWNER_USER_SUB_TYPE, bizNo = "{{#contact.id}}",
success = CRM_CONTACT_UPDATE_OWNER_USER_SUCCESS)
public void receiveContactLog(CrmContactDO contact, Long ownerUserId) {
// 记录操作日志上下文

View File

@ -1,6 +1,6 @@
<script lang="ts" setup>
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
import type { VxeTableInstance } from 'vxe-table';
import type { VxeTableInstance } from '#/adapter/vxe-table';
import { Page, useVbenModal } from '@vben/common-ui';
import { cloneDeep, formatDateTime } from '@vben/utils';
@ -9,9 +9,10 @@ import { DictTag } from '#/components/dict-tag';
import { DICT_TYPE, getDictOptions, getRangePickerDefaultProps } from '#/utils';
import ${simpleClassName}Form from './modules/form.vue';
import { Download, Plus, RefreshCw, Search } from '@vben/icons';
import { ContentWrap } from "#/components/content-wrap";
import { VxeColumn, VxeTable } from 'vxe-table';
import { ContentWrap } from '#/components/content-wrap';
import { VxeColumn, VxeTable } from '#/adapter/vxe-table';
import { TableToolbar } from '#/components/table-toolbar';
import { useTableToolbar } from '#/hooks';
## 特殊:主子表专属逻辑
#if ( $table.templateType == 11 || $table.templateType == 12 )
@ -167,11 +168,6 @@ try {
}
}
/** 隐藏搜索栏 */
const hiddenSearchBar = ref(false);
const tableToolbarRef = ref<InstanceType<typeof TableToolbar>>();
const tableRef = ref<VxeTableInstance>();
#if (${table.templateType} == 2)
/** 切换树形展开/收缩状态 */
const isExpanded = ref(true);
@ -182,15 +178,9 @@ function toggleExpand() {
#end
/** 初始化 */
onMounted(async () => {
await getList();
await nextTick();
// 挂载 toolbar 工具栏
const table = tableRef.value;
const tableToolbar = tableToolbarRef.value;
if (table && tableToolbar) {
await table.connect(tableToolbar.getToolbarRef()!);
}
const { hiddenSearchBar, tableToolbarRef, tableRef } = useTableToolbar();
onMounted(() => {
getList();
});
</script>

View File

@ -13,9 +13,9 @@
import { DICT_TYPE, getDictOptions } from '#/utils';
#if ($subTable.subJoinMany) ## 一对多
import type { VxeTableInstance } from 'vxe-table';
import type { VxeTableInstance } from '#/adapter/vxe-table';
import { Plus } from "@vben/icons";
import { VxeColumn, VxeTable } from 'vxe-table';
import { VxeColumn, VxeTable } from '#/adapter/vxe-table';
import { get${subSimpleClassName}ListBy${SubJoinColumnName} } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
#else
import type { Rule } from 'ant-design-vue/es/form';

View File

@ -7,14 +7,14 @@
#set ($SubJoinColumnName = $subJoinColumn.javaField.substring(0,1).toUpperCase() + ${subJoinColumn.javaField.substring(1)})##首字母大写
<script lang="ts" setup>
import type { ${simpleClassName}Api } from '#/api/${table.moduleName}/${simpleClassName_strikeCase}';
import type { VxeTableInstance } from 'vxe-table';
import type { VxeTableInstance } from '#/adapter/vxe-table';
import { DictTag } from '#/components/dict-tag';
import { DICT_TYPE, getDictOptions } from '#/utils';
import { VxeColumn, VxeTable } from 'vxe-table';
import { VxeColumn, VxeTable } from '#/adapter/vxe-table';
import { reactive,ref, h, nextTick,watch,onMounted } from 'vue';
import { cloneDeep, formatDateTime } from '@vben/utils';
import { ContentWrap } from "#/components/content-wrap";
import { ContentWrap } from '#/components/content-wrap';
#if ($table.templateType == 11) ## erp
import { useVbenModal } from '@vben/common-ui';
@ -26,6 +26,7 @@
import { Plus } from '@vben/icons';
import { $t } from '#/locales';
import { TableToolbar } from '#/components/table-toolbar';
import { useTableToolbar } from '#/hooks';
#end
#if ($table.templateType == 11) ## erp
@ -165,21 +166,10 @@ const resetQuery = () => {
);
#if ($table.templateType == 11) ## erp
/** 隐藏搜索栏 */
const hiddenSearchBar = ref(false);
const tableToolbarRef = ref<InstanceType<typeof TableToolbar>>();
const tableRef = ref<VxeTableInstance>();
/** 初始化 */
onMounted(async () => {
await getList();
await nextTick();
// 挂载 toolbar 工具栏
const table = tableRef.value;
const tableToolbar = tableToolbarRef.value;
if (table && tableToolbar) {
await table.connect(tableToolbar.getToolbarRef()!);
}
const { hiddenSearchBar, tableToolbarRef, tableRef } = useTableToolbar();
onMounted(() => {
getList();
});
#end
</script>

View File

@ -92,6 +92,7 @@ public class KeFuMessageServiceImpl implements KeFuMessageService {
MemberUserRespDTO user = memberUserApi.getUser(kefuMessage.getSenderId());
KeFuMessageRespVO message = BeanUtils.toBean(kefuMessage, KeFuMessageRespVO.class).setSenderAvatar(user.getAvatar());
getSelf().sendAsyncMessageToAdmin(KEFU_MESSAGE_TYPE, message);
getSelf().sendAsyncMessageToMember(conversation.getUserId(), KEFU_MESSAGE_TYPE, message);
return kefuMessage.getId();
}

View File

@ -395,7 +395,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
// 3. 记录订单日志
TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), TradeOrderStatusEnum.DELIVERED.getStatus(),
MapUtil.<String, Object>builder().put("deliveryName", express != null ? express.getName() : "")
MapUtil.<String, Object>builder().put("expressName", express != null ? express.getName() : "")
.put("logisticsNo", express != null ? deliveryReqVO.getLogisticsNo() : "").build());
// 4.1 发送站内信