#include "SB_handler.h" #include "string_helper.h" using namespace std; #include #include #include #include #include #include #define debug true #define ITK_err 919012 bool inArrays(const std::vector& vec, const std::string& value) { for (const auto& item : vec) { if (item == value) { return true; } } return false; } void getVector(const char* value, std::vector& targetVector, char delimiter) { std::string strValue(value); std::stringstream ss(strValue); std::string item; // 尝试用指定的分隔符分割字符串 if (std::getline(ss, item, delimiter)) { // 如果能成功分割,则继续分割剩余部分 targetVector.push_back(item); while (std::getline(ss, item, delimiter)) { targetVector.push_back(item); } } else { // 如果不能分割,则将整个字符串添加到vector中 targetVector.push_back(strValue); } } int getPrefStrings(const char* preference, TC_preference_search_scope_t scope, vector& pref_vec) { int ifail = ITK_ok, i = 0, j = 0, k = 0, num = 0; char** values; TC_preference_search_scope_t old_scope; //ITKCALL(ifail = PREF_ask_search_scope(&old_scope)); //ITKCALL(ifail = PREF_set_search_scope(scope)); //ITKCALL(ifail = PREF_ask_char_values(preference, &num, &values)); ITKCALL(ifail = PREF_ask_char_values_at_location(preference, scope, &num, &values)); if (ifail != ITK_ok) { return ifail; } for (i = 0; i < num; i++) { pref_vec.push_back(values[i]); } MEM_free(values); //ITKCALL(ifail = PREF_set_search_scope(old_scope)); return ifail; } void setProcessPointUser(std::string uerID) { tag_t subtask; //流程节点 string id;//用户id POM_AM__set_application_bypass(true); tag_t tmp_select_signoff_task = NULLTAG; ITKCALL(EPM_ask_sub_task(subtask, EPM_select_signoff_team_task, &tmp_select_signoff_task)); tag_t user; ITKCALL(SA_find_user2(uerID.c_str(), &user)); int signoff_cnt = 0; tag_t* signoffs = NULL; tag_t member = NULL; SIGNOFF_TYPE_t type; ITKCALL(EPM_ask_signoff_member(tmp_select_signoff_task, &member, &type)); ITKCALL(EPM_remove_signoffs(tmp_select_signoff_task, 1, &member)); ITKCALL(EPM_create_adhoc_signoff(tmp_select_signoff_task, user, &signoff_cnt, &signoffs)); ITKCALL(EPM_set_adhoc_signoff_selection_done(tmp_select_signoff_task, true)); if (signoffs) { MEM_free(signoffs); signoffs = NULL; } POM_AM__set_application_bypass(false); } int SB6_PR_AutoAssign(EPM_action_message_t msg) { printf("========================= SB6_PR_AutoAssign Start ===================\n"); int ifail = ITK_ok; char* argName = NULL, * argValue = NULL, * arg = NULL; char objTypes[1024] = "", props[1024] = "",pre_str[1024] = ""; bool isExistRev = false; int arg_cnt = TC_number_of_arguments(msg.arguments); printf("参数个数为:%d\n", arg_cnt); if (arg_cnt > 0) { for (int i = 0; i < arg_cnt; i++) { arg = TC_next_argument(msg.arguments); ifail = ITK_ask_argument_named_value((const char*)arg, &argName, &argValue); if (strcmp(argName, "type") == 0) { if (argValue != NULL) { strcpy(objTypes, argValue); } } else if (stricmp(argName, "property") == 0) { if (argValue != NULL) { strcpy(props, argValue); } } else if (stricmp(argName, "Option") == 0) { if (argValue != NULL) { strcpy(pre_str, argValue); } } } } MEM_free(argName); MEM_free(argValue); std::vector typeVector, propVector; getVector(objTypes, typeVector, ';'); getVector(props, propVector, ';'); int prop_cnt = propVector.size(); vector pre_values; if (pre_str != "") { getPrefStrings(pre_str, TC_preference_site, pre_values); } else { EMH_store_error_s1(EMH_severity_error, ITK_err, "SB6_PR_AutoAssign流程Handler下Option配置的首选项为空!"); return ITK_err; } std::vector> preVectors; int pre_cnt = 0; for (const auto& value : pre_values) { printf("首选项配置值为: %s\n", value.c_str()); std::vector preVector; getVector(value.c_str(), preVector, ';'); if (pre_cnt == 0) { pre_cnt = preVector.size(); } else if(prop_cnt != pre_cnt || pre_cnt != preVector.size()) { EMH_store_error_s1(EMH_severity_error, ITK_err, "SB6_PR_AutoAssign流程Handler下Option的首选项配置长度不一致!"); return ITK_err; } preVectors.push_back(preVector); } tag_t attachmentTag = NULLTAG; int attachmentCount = 0; tag_t rootTask = NULLTAG, * attachmentTags = NULLTAG; ITKCALL(ifail = EPM_ask_root_task(msg.task, &rootTask)); ITKCALL(ifail = EPM_ask_attachments(rootTask, EPM_target_attachment, &attachmentCount, &attachmentTags)); //遍历所有的流程目标下的对象 char* itemType = NULL; for (int i = 0; i < attachmentCount; i++) { attachmentTag = attachmentTags[i]; ITKCALL(ifail = AOM_ask_value_string(attachmentTag, "object_type", &itemType)); printf("当前遍历目标下的对象类型为: %s\n", itemType); if (inArrays(typeVector, itemType)) { ITKCALL(ifail = AOM_lock(attachmentTag)); //ITKCALL(ifail = AOM_set_value_string(attachmentTag, targetPropertyName, &propertyValue)); std::vector valueVector; char* tempValue = NULL; for (const auto& prop : propVector) { printf("==>获取属性: %s\n", prop); ITKCALL(ifail = AOM_UIF_ask_value(attachmentTag, prop.c_str(), &tempValue)); printf("属性值为: %s\n", tempValue); if (tempValue != NULL) { valueVector.push_back(tempValue); } else { valueVector.push_back(""); } } MEM_free(tempValue); std::string userID; boolean isMatch = false; for (const auto& preVector : preVectors) { printf("preVector: %d\n", preVector.size()); // 对比每个属性值是否匹配 for (size_t i = 0; i < preVector.size(); ++i) { printf("比对属性值: %s || %s\n", preVector[i], valueVector[i]); if (i == preVector.size() - 1) { // 替换为分割逻辑: std::string keyValuePair = preVector.back(); std::vector tempVector; getVector(keyValuePair.c_str(), tempVector, '='); if (tempVector.size() == 2) { if (tempVector[0] == valueVector[i]) { userID = tempVector[1]; // 取等号后的部分 isMatch = true; break; } } else { // 错误处理(根据需要添加) userID = ""; printf("错误:用户ID格式不正确: %s\n", keyValuePair.c_str()); EMH_store_error_s1(EMH_severity_error, ITK_err, "用户ID格式不正确"); return ITK_err; } } else if (preVector[i] != valueVector[i]) { break; } } if (isMatch) { break; } } if (userID.empty()) { continue; } printf("UserId : %s\n", userID); //setProcessPointUser(userID); POM_AM__set_application_bypass(true); int mem_cnt = 0, signoff_cnt = 0, signmem_count = 0, * attach_type; tag_t user_tag = NULLTAG, login_group = NULLTAG, * members = NULLTAG, * signoffs = NULLTAG, select_signoff_tag = NULLTAG, * attachmentTags = NULLTAG; EPM_ask_sub_task(msg.task, EPM_select_signoff_team_task, &select_signoff_tag); EPM_ask_all_attachments(select_signoff_tag, &signmem_count, &attachmentTags, &attach_type); if (signmem_count == 0) { ITKCALL(SA_find_user2(userID.c_str(), &user_tag)); if (user_tag != NULLTAG) { ITKCALL(SA_ask_user_login_group(user_tag, &login_group)); ITKCALL(SA_find_groupmembers(user_tag, login_group, &mem_cnt, &members)); ITKCALL(EPM_create_adhoc_signoff(select_signoff_tag, user_tag, &signoff_cnt, &signoffs)); ITKCALL(EPM_set_adhoc_signoff_selection_done(select_signoff_tag, true)); printf("分配成功"); break; } else { printf("nulll\n"); ITKCALL(EPM_promote_task(msg.task, "")); } } POM_AM__set_application_bypass(false); MEM_free(members); MEM_free(signoffs); ITKCALL(ifail = AOM_unlock(attachmentTag)); } } MEM_free(attachmentTags); MEM_free(itemType); return ifail; } #define DOFREE(obj) \ { \ if(obj) \ { \ MEM_free(obj); \ obj = NULL; \ } \ } /** * 判断某个对象是否是类或者子类 * * @param objtag 要判断的对象 * @param type_name 类型的名称 * */ int checkIsTypeOrSubtype(tag_t objtag, char* type_name) { tag_t type = NULLTAG, item_type = NULLTAG; int is_type = 0; char* tag_name = NULL; ITKCALL(AOM_ask_value_string(objtag, "object_name", &tag_name)); if (tag_name == NULL) { tag_name = "NULL"; } ITKCALL(TCTYPE_ask_object_type(objtag, &type)); ITKCALL(TCTYPE_find_type(type_name, "", &item_type)); logical isok = false; if (item_type != NULLTAG) { logical isok = FALSE; ITKCALL(TCTYPE_is_type_of(type, item_type, &isok)); if (isok) { //LOG_ECHO(("是子类%s\n", type_name)); printf("%s是子类%s\n", tag_name, type_name); is_type = 1; } else { //LOG_ECHO(("不是子类%s\n", type_name)); printf("%s不是子类%s\n", tag_name, type_name); is_type = 0; } } DOFREE(tag_name); return is_type; } /** * 判断俩入参是否同源 */ bool isTypeOf1(tag_t objtag, const char* type_name) { tag_t type = NULLTAG; TCTYPE_ask_object_type(objtag, &type); tag_t item_type = NULLTAG; TCTYPE_find_type(type_name, "", &item_type); bool is_type = false; if (item_type != NULLTAG) { logical isok = FALSE; TCTYPE_is_type_of(type, item_type, &isok); if (isok) { is_type = true; } } return is_type; } /** * @brief 根据不确定类型的tag_t对象,获取item和itemRev对象 * @param check_tag * @param item_tag * @param rev_tag * @return */ int get_item_and_rev(tag_t check_tag, tag_t* item_tag, tag_t* rev_tag) { int ifail = ITK_ok; if (isTypeOf1(check_tag, "Item")) { printf("====当前处理的对象是item对象!\n"); *item_tag = check_tag; ITEM_ask_latest_rev(*item_tag, rev_tag); } else if (isTypeOf1(check_tag, "ItemRevision")) { printf("====当前处理的对象是Revision对象!\n"); *rev_tag = check_tag; ITEM_ask_item_of_rev(*rev_tag, item_tag); } return ifail; } /*=============================================================================* * FUNCTION: Origin_CheckTask_handler2 * PURPOSE : 校验交付物文件夹下数据是否发布 * INPUT: * EPM_rule_message_t msg * * RETURN: * int *============================================================================*/ int Origin_CheckTask_handler2(EPM_rule_message_t msg) { EPM_decision_t err = EPM_go; int ifail = ITK_ok; int project_attachment_cnt = 0, deliverable_cnt = 0, sc_cnt = 0, fold_cnt = 0, fold_content_cnt = 0, status_cnt = 0; bool allowPass = true; bool noItem = false; bool status_is_configured = false; tag_t* project_attachments = NULLTAG, * deliverable_list = NULLTAG, deliverable = NULLTAG, * folds = NULLTAG, * fold_contents = NULLTAG, * status_list = NULLTAG, item_tag = NULLTAG, check_item = NULLTAG; char* object_type = NULL; //状态名称 char* status_name = NULL; //流程下配置的状态参数 char status_config[1024] = ""; char *arg = NULL, *argName = NULL, *argValue = NULL; /*LOG_ECHO(("*******************************************************************************\n")); LOG_ECHO(("* Origin_CheckTask_handler is comming ! *\n")); LOG_ECHO(("*******************************************************************************\n"));*/ printf("*******************************************************************************\n"); printf("* Origin_CheckTask_handler is comming ! *\n"); printf("*******************************************************************************\n"); //TODO 获取流程下配置的参数,记得更新status_is_configured属性值为true int arg_cnt = TC_number_of_arguments(msg.arguments); if (arg_cnt > 0) { printf("流程下配置的参数个数为:%d\n", arg_cnt); for (int i = 0; i < arg_cnt; i++) { arg = TC_next_argument(msg.arguments); ITKCALL(ITK_ask_argument_named_value((const char*)arg, &argName, &argValue)); printf("参数名称-配置值 = [%s - %s]\n", argName, argValue); if (argName != NULL && argValue != NULL && strcmp(argName, "status") == 0) { printf("状态名称:%s\n", argValue); strcpy(status_config, argValue); status_is_configured = true; } DOFREE(argName); DOFREE(argValue); } } else { printf("流程下没有配置参数\n"); } ITKCALL(AOM_ask_value_tags(msg.task, "project_task_attachments", &project_attachment_cnt, &project_attachments)); if (project_attachment_cnt > 0) { ITKCALL(AOM_ask_value_tags(project_attachments[0], "sch_task_deliverable_list", &deliverable_cnt, &deliverable_list)); if (deliverable_cnt > 0) { ITKCALL(AOM_ask_value_tag(deliverable_list[0], "schedule_deliverable", &deliverable)); if (deliverable != NULL) { ITKCALL(AOM_ask_value_tags(deliverable, "deliverable_inst", &fold_cnt, &folds)); if (fold_cnt > 0) { allowPass = false; ITKCALL(AOM_ask_value_tags(folds[0], "contents", &fold_content_cnt, &fold_contents));//获取交付物文件夹下的内容 //LOG_ECHO(("交付物文件夹内容数量:%d\n", fold_content_cnt)); printf("交付物文件夹内容数量:%d\n", fold_content_cnt); if (status_is_configured) {//流程参数下配置了状态 int hi_cnt = 0; printf("流程参数下配置了状态\n"); //遍历文件夹下的交付物 for (int i = 0; i < fold_content_cnt; i++) { ITKCALL(AOM_ask_value_string(fold_contents[i], "object_type", &object_type)); //根据交付物的类型,获取check_item if (checkIsTypeOrSubtype(fold_contents[i], "Item") == 1 || checkIsTypeOrSubtype(fold_contents[i], "ItemRevision") == 1) { hi_cnt++; ITKCALL(get_item_and_rev(fold_contents[i], &item_tag, &check_item)); printf("1 \n"); } else { continue; } //判断交付物对应的check_item是否发布 if (check_item != NULL) { printf("获取最新版本对象成功!\n"); ITKCALL(AOM_ask_value_tags(check_item, "release_status_list", &status_cnt, &status_list)); if (status_cnt > 0) { for (int j = 0; j < status_cnt; j++) { //status_list[j];//发布状态对象 ITKCALL(AOM_ask_value_string(status_list[j], "object_name", &status_name)); if (status_name == NULL) { ITKCALL(EMH_store_error_s1(EMH_severity_user_error, ITK_err, "交付物没有发布,请先进行发布!")); err = EPM_nogo; break; } if (status_name == NULL) { continue; } if (strcmp(status_name, status_config) == 0) { printf("交付物发布状态:[%s]与配置的发布状态[%s]相同!\n", status_name, status_config); allowPass = true; } else { printf("交付物发布状态:[%s]与配置的发布状态[%s]不相同!\n", status_name, status_config); allowPass = false; string err_msg = "交付物文件夹下的对象或版本状态与要求的"+ string(status_config) +"不一致!"; ITKCALL(EMH_store_error_s1(EMH_severity_user_error, ITK_err, err_msg.c_str())); err = EPM_nogo; break; } } } else {//文件夹下存在未发布的对象 ITKCALL(EMH_store_error_s1(EMH_severity_user_error, ITK_err, "交付物没有发布,请先进行发布!")); err = EPM_nogo; break; } } else { printf("获取check_item 失败!"); continue; } DOFREE(status_name); DOFREE(status_list); } if (hi_cnt == 0) {//配置状态情况下,交付物文件夹下没有item\rev的子类 ITKCALL(EMH_store_error_s1(EMH_severity_user_error, ITK_err, "交付物没有提交,请先进行提交!")); err = EPM_nogo; } } else {//流程参数下未配置状态 printf("流程参数下未配置状态\n"); int ir_cnt = 0; if (fold_content_cnt > 0) { //没有配置状态参数的时候,检查文件夹下是否存在item\rev的子类,存在则通过,不存在则提示 for (int j = 0; j < fold_content_cnt; j++) { if (checkIsTypeOrSubtype(fold_contents[j], "Item") == 1 || checkIsTypeOrSubtype(fold_contents[j], "ItemRevision") == 1) { ir_cnt++; } } if (ir_cnt == 0) { ITKCALL(EMH_store_error_s1(EMH_severity_user_error, ITK_err, "交付物没有提交,请先进行提交!")); allowPass = false; err = EPM_nogo; } else { allowPass = true;//交付物文件夹 } }else {//未配置流程参数,交付物文件夹下也没有内容 printf("校验通过,未配置流程参数且交付物文件夹下没有内容!\n"); ITKCALL(EMH_store_error_s1(EMH_severity_user_error, ITK_err, "交付物没有提交,请先进行提交!")); err = EPM_nogo; } } } } } } //if (!allowPass && status_is_configured == false) //{ // //LOG_ECHO(("校验不通过,存在交付物未发布!\n")); // printf("校验不通过,存在交付物未提交!\n"); // ITKCALL(EMH_store_error_s1(EMH_severity_user_error, ITK_err, "交付物没有提交,请先进行提交!")); // err = EPM_nogo; //} //else if (!allowPass) { // printf("校验不通过,存在交付物未发布!\n"); // ITKCALL(EMH_store_error_s1(EMH_severity_user_error, ITK_err, "交付物没有发布,请先进行发布!")); // err = EPM_nogo; //} //LOG_ECHO(("*******************************************************************************\n")); //LOG_ECHO(("* Origin_CheckTask_handler is end ! *\n")); //LOG_ECHO(("*******************************************************************************\n")); printf("*******************************************************************************\n"); printf("* Origin_CheckTask_handler is end ! *\n"); printf("*******************************************************************************\n"); //DOFREE(status_config); DOFREE(object_type); DOFREE(fold_contents); DOFREE(folds); DOFREE(project_attachments); DOFREE(project_attachments); return err; }