前端
src\views\review\Index.vue 评审列表
src\views\review\HandleReview.vue 评审详情
src\views\review\AddReview.vue 发起评审
src\components\customForm\widgets\review 评审定制自定义表单
src\components\customForm\widgets\review\ReviewCheck 评审要素
src\components\customForm\widgets\review\ReviewCommentList 评审意见
src\components\customForm\widgets\review\ReviewExpectDocCheck 阶段交付物
src\components\customForm\widgets\review\ReviewIssue 评审问题
src\components\customForm\widgets\review\ReviewMemberGroup 评审组
src\components\customForm\widgets\review\ReviewResultId 评审最终结论
src\components\customForm\widgets\review\ReviewRisk 风险
src\components\customForm\widgets\自定义控件添加说明.txt 针对自定义表单控件的说明文档
src\utils\objectForm\widgetTemplate.ts 注册页面路由
src\utils\workflow\widgetTemplate.ts 注册页面路由
后端
PowerProject.WebHelpers\WorkflowDynamicInvokers\ReviewDynamicInvoker.cs 评审流程动态调用:一般是走流程的时候会用,例如流程通过后要处理某种接口调用
PowerProject.Business\Metadatas\EventHandlers\Common\ReviewMetadataEventHandler.cs 评审元数据事件处理:包含“当向数据库新增记录方法之前触发”、“当向数据库新增记录方法完成后触发”等
PowerProject.Web\Controllers\Flows\ReviewDefinitionController.cs 评审定义的控制器:流程Link步骤、评审节点
PowerProject.WebHelpers\CustomForms\Widgets\Review 针对自定义表单控件的配置定义,搭配前端的“评审定制自定义表单”
PowerProject.WebHelpers\CustomForms\Widgets\Review\CustomWidgetReviewCheck.cs 评审要素
PowerProject.WebHelpers\CustomForms\Widgets\Review\CustomWidgetReviewCommentList.cs 评审意见
PowerProject.WebHelpers\CustomForms\Widgets\Review\CustomWidgetReviewIssue.cs 评审问题
PowerProject.WebHelpers\CustomForms\Widgets\Review\CustomWidgetReviewMemberGroup.cs 评审组
PowerProject.WebHelpers\CustomForms\Widgets\Review\CustomWidgetReviewResultId.cs 评审最终结论
PowerProject.WebHelpers\CustomForms\Widgets\Review\CustomWidgetReviewRisk.cs 风险
PowerProject5-Backend\PowerProject.Web\Code\Metadatas 元数据相关
PowerProject5-Backend\PowerProject.Web\Code\Metadatas\Common\StartupMetadata.Review.cs 评审基本属性例如包含:“创建人”、“当前处理人”等
PowerProject5-Backend\PowerProject.Web\Controllers\OpenApis 对外的OpenApi接口:第三方调用本系统
#region 自定义字段存储值
Dictionary<string, object> keyValues = new Dictionary<string, object>();
PropertyDefinitionModel itemNo_propertyDefinitionModel = CustomPropertyHelper.GetCustomProperties(nameof(Project), project.Id).FirstOrDefault(e => e.Name == "行项目号");
if (itemNo_propertyDefinitionModel != null)
{
if (itemNo_propertyDefinitionModel.InputType == "单行文本")
{
keyValues.Add(itemNo_propertyDefinitionModel.ColumnName, param.ItemNo);
CustomPropertyHelper.SaveCustomProperty<Project>(project.Id, keyValues);
}
}
#endregion
#region 发送飞书
string contentFeiShu = $@"在{review.Title}评审中,{examinerName.Name}对要素{title}的检查结果为:不通过,请知悉。";
CommonAction commonActionFeiShu = new CommonAction()
{
Title = $"“评审要素检查不通过”消息通知",
LongContent = contentFeiShu,
ShortContent = contentFeiShu.Replace("<br/>", "\r\n"),
InformModes = InformModes.FeiShu,
User = PrincipalConverter.Convert(AppConfig.AdminId),
PcUrl = $"/{shortCode}",
MobileUrl = $"/#/{shortCode}",
};
commonActionFeiShu.To.AddRange(Users);
if (commonActionFeiShu.To.Any())
TriggerCentralHandlerWrapper.HandleSystemActionAsync(commonActionFeiShu);
#endregion
#region 发送邮件
string userNames = string.Join(", ", Users.Select(u => u.Name));
string content = $@"<span style='color:gray;'>接收人员: </span>{userNames}<br/>
<span style='color:gray;'>发送主题: </span>检查结论: 不通过 - 【{title}】<br/>
<span style='color:gray;'>邮件内容: </span>在“【<a href='{pcUrl}' style='color:blue;'>{review.Title}</a>】”评审,编号:“【{review.Code}】”,“【{examinerName.Name}】”对要素“【{title}】”的检查结论为: 不通过, 请知悉。";
CommonAction commonAction = new CommonAction()
{
Title = $"“评审要素检查不通过”消息通知",
LongContent = content,
ShortContent = content.Replace("<br/>", "\r\n"),
InformModes = InformModes.Mail,
User = PrincipalConverter.Convert(AppConfig.AdminId),
PcUrl = $"/{shortCode}",
MobileUrl = $"/#/{shortCode}"
};
commonAction.To.AddRange(Users);
if (commonAction.To.Any())
TriggerCentralHandlerWrapper.HandleSystemActionAsync(commonAction);
#endregion
后端:---------------------------------------------------------------------------------------------------------------------------------------------------
Triggers<TriggerMessage, TriggerMessageContext>.Inserted += Inserted; 触发
TriggerMessages.Add 发送飞书
CommonAction commonAction = new CommonAction() 发送邮件、飞书等
SendMessageSingle
UserAgencyReview 人员替换 FinalNextHandlerIds
MetadataEventHandler 元数据
ReviewMetadataEventHandler 元数据
RecodealCreateProjectMetadataEventHandler 元数据创建
PowerProject.Web\Code\Metadatas\StartupMetadata.cs 元数据对象建模
ReviewDynamicInvoker 评审流程
WorkflowInvoker.cs 通用流程
ProjectWorkflowHandler
StartupMetadata.Review.cs 评审内置字段
WorkflowEventHandler 通用流程
ReviewFlowChartLinkConfig 评审流程Link步骤
FlowChartNodeConfig 评审流程Node节点
ReviewContext reviewContext = ObjectFinder.GetDbContext<ReviewContext>(); 评审上下文
CustomWidgetReviewIssue 评审问题组件
this.AutoInitiateFlow(flow, transformContext) WorkflowAutoSubmitFlowInvoker.cs
var visitor = review.GetVisitor(); 自定义jsoninfo
YappProjectInfoHelper.cs //用户获取自定义字段等可以参考
manager.UpdateObject() 修改自定义字段
CustomFormWidget widget = customForm?.Widgets.FirstOrDefault(item => item.Type == "ApprovalResult"); // 评审意见,正浩
this.SystemLogServices.AddBizLog<Review>(review.Id, review.Title, "删除", $"{CurrentUser.GetLocalizedName()} 删除了一个评审要素,标题:{checkItem.Name}", review.ProjectId, CurrentUser.Id);
C:\我的文件\联合动力5.0(New)\InovanceAutomotive5-Backend\PowerProject.Business\DisplayColumns\ 自定义列
//定制关键字
if (CustomManager.CurrentCustom == CustomManager.Ecoflow)
{
}
export enum LimiterMode {
// 自由选择
No = 'free',
// 选择根节点
Root = 'root',
// 选择叶子节点
Leaf = 'leaf',
}
selectLimiter
User user = UserManager.GetById(userId);
// 人员集合
List<string> userIds = new List<string>();
LightFlow lightFlow = ObjectFinder.Find("Review", review.Id) as LightFlow;
FlowReaderService flowReaderService = FlowReaderServiceFactory.Create();
IList<UserReader> userReaders = flowReaderService.GetRecords(flow);
foreach (var step in lightFlow.Steps.OrderBy(item => item.StepInTime))
{
// 接收人
userIds.AddRange(step.Handlers
.OrderBy(item => item.HandleTime ?? DateTime.MaxValue)
.Select(item => item.UserId));
// 抄送人
userIds.AddRange(userReaders.Where(item => item.FlowStepId.HasValue && item.FlowStepId == step.Id).Select(item => item.UserId));
}
userIds = userIds.Distinct().ToList();
//短链接
[HttpGet]
public async Task<IActionResult> GetReviewRoleList([FromQuery] GetReviewRoleListParam param,[FromServices] IShortCodeService m_shortCodeService)
{
Review review = await this.m_ReviewContext.Reviews.FindAsync(param.ReviewId);
string shortCode = m_shortCodeService.GetShortCodeForEntity(review);
string sso = WebUtility.UrlEncode(SsoManager.Encrypt(review.CreatorId.AsUser().LoginId));
string shortUrl = m_shortCodeService.GetPcShortUrl(review);
string pcUrl = $"{shortUrl}?{SsoManager.SsoKey}={sso}";
AppConfig appConfig = ConfigManager.Find<AppConfig>();
string shortUrl = appConfig.PcAuthority?.TrimEnd('/') + "/workflow/" + workflow.Id;
return this.Ok(list.Select(m => new { Id = m.Id, RoleName = m.RoleName, m.RoleType, UserIds = m.UserIds }));
}
取表单里面的值
CustomForm customForm = workflow.GetFormOfCurrentActivity(_customFormContext);
WorkflowFormOutViewModel flowForms = WorkflowFormOutViewModel.CreateAsync(_customFormContext, customForm).Result;
flowForms.InitWidgetModel(workflow);
步骤中的业务参数
TransitionInfo transitionResult = this.GetTransformResult(lightflow, param.TransitionId, options);
bool ifElementCheckFailedNotification = transitionResult.Transition.GetIfElementCheckFailedNotification() == true;
#region 自定义字段存储值
Dictionary<string, object> keyValues = new Dictionary<string, object>();
PropertyDefinitionModel itemNo_propertyDefinitionModel = CustomPropertyHelper.GetCustomProperties(nameof(Project), project.Id).FirstOrDefault(e => e.Name == "行项目号");
if (itemNo_propertyDefinitionModel != null)
{
if (itemNo_propertyDefinitionModel.InputType == "单行文本")
{
keyValues.Add(itemNo_propertyDefinitionModel.ColumnName, param.ItemNo);
CustomPropertyHelper.SaveCustomProperty<Project>(project.Id, keyValues);
}
}
#endregion
#region 获取自定义表列的值
string fieldBelongingProductLine = "String6";
var table = await dbClient.Definition.GetTableAsync("CP_Project", true);
var dbTableClient = dbClient.Table(table);
var dbTableQuery = dbTableClient.Query();
var belongingProductLineColumn = dbTableClient.Table.Columns.Single(e => e.ColumnName == fieldBelongingProductLine);
var ownerIdColumn = dbTableClient.Table.Columns.FirstOrDefault(p => p.ColumnName == "OwnerId");
var customPropItems = (await dbTableQuery.Where(DbCondition.IsNotNull(belongingProductLineColumn)).Select([ownerIdColumn, belongingProductLineColumn]).GetResultAsync()).ToList(); ;
List<Guid> projectIds = new List<Guid>();
foreach (IDictionary<string, object> item in customPropItems)
{
var projectId = item[ownerIdColumn.ColumnName].ToString();
var belongingProductLineId = item[belongingProductLineColumn.ColumnName].ToString();
if (!string.IsNullOrEmpty(belongingProductLineId) && this.BelongingProductLineIds.Contains(belongingProductLineId))
{
projectIds.Add(Guid.Parse(projectId));
}
}
#endregion
Updating5
Updater2025110310 修改
Updater2025103016 新增
ReviewVisitorSuofeiya
InovanceAutomotive5-Backend\PowerProject.Business\LightCalculators\Calculators\TaskProgressLightCalculators\TaskProgressLightCalculator.cs 任务进度亮灯计算器
culture.TwoLetterISOLanguageName == "en" 翻译
this.m_Localizer[""]
workflow.ActivityState == ActivityState.Passed //流程状态
前端: -----------------------------------------------------------------------------------------------------------------------------------------------------
$custom.isYuwei() 自定义关键字
import { $tpp } from '@/language/language'; 翻译
$language.isEN()
src\pages\workflow\widgets\common\components\DatagridEditor.vue 自定义属性
src\components\customForm\widgets\Common\GridLayout\Display.vue 自定义组件
detailForm.ref()?.setValues({ ['cP.Double3']: 90 }); 前端自定义字段赋值
C:\我的文件\PowerProject5\Phone\PowerProject5-Mobile\src\pages\review\info.vue 详细信息
InovanceAutomotive5-Frontend\src\components\customForm\widgets\Common\ProjectSelector\Display.vue select项目选择
<a-empty description="项目阶段与质量阀(功能开发中)" />
InovanceAutomotive5-Frontend\src\components\customForm\eventHandler\eventHandlers\custom\InovanceAutomotive\InovanceAutomotiveReviewGroupEventHandler.ts 事件
InovanceAutomotive5-Frontend\src\components\workflow\WorkflowCreateDrawer\index.vue 流程的提交
npm config list //来列出当前 npm 配置的详细信息的命令
npm config get cache //查看当前 npm 缓存的位置
npm config set cache "<new-cache-path>" //更改 npm 缓存的位置
npm config get prefix //查看npm 全局安装路径
npm config set prefix "<new-prefix-path>" //更改 npm 全局安装路径
npm config get registry //软件包管理器使用的中央存储库
npm config set registry "<registry-url>" //换 “下载源 / 下载服务器地址”
1、https://registry.npmjs.org(官方原版仓库)
2、https://registry.npmmirror.com(淘宝镜像)
npm install --legacy-peer-deps //忽略同伴依赖的冲突问题,继续安装
npm run build //打包