#include "handlers.h"
#include <tc\tc_macros.h>
#include <tccore\method.h>
#include <tccore/workspaceobject.h>
#include <tccore/item.h>
#include <form\form.h>
#include <tccore\aom.h>
#include <tccore\aom_prop.h>
#include <tccore/grm.h>
#include <string>
#include <vector>
#include "tc_util.h"
#include "k_util.h"
using namespace std;


/**
* 判断俩入参是否同源
*/
bool isTypeOf1(tag_t objtag, const char* type_name) {
	tag_t type = NULLTAG;
	TCTYPE_ask_object_type(objtag, &type);
	//printf("isTypeOf1方法的type:%s\n", 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;
}

int get_last_release_rev(tag_t itemTag, tag_t* revTag) {
	int ifail = ITK_ok;
	//获取版本 
	//tag_t revTag = NULLTAG;
	int revisionNums = 0;
	tag_t* revisionTags = NULLTAG;
	ITKCALL(ifail = AOM_ask_value_tags(itemTag, "revision_list", &revisionNums, &revisionTags));
	for (int k = revisionNums - 1; k >= 0; k--) {
		int releaseNums = 0;
		tag_t* releaseTags = NULLTAG;
		ITKCALL(ifail = AOM_ask_value_tags(revisionTags[k], "release_status_list", &releaseNums, &releaseTags));
		if (releaseNums > 0) {
			*revTag = revisionTags[k];
		}
		MEM_free(releaseTags);
	}

	MEM_free(revisionTags);
	return ifail;
}

/*
* 将对象B关联/挂载到A的关系下
* @param productInfo 关联关系
* @param new_rev 关联对象A(物料)
* @param newwlrev 被关联的对象B(图纸)
* @param old_part_rev 旧的对象A（物料）
* @return bool
*/
bool createAndSaveRelation(const char* productInfo, tag_t new_rev, tag_t newwlrev, tag_t old_part_rev) {
	printf("createAndSaveRelation```开始建立图物关系\n");
	int ifail = ITK_ok;
	tag_t gx_gx_type = NULLTAG;
	tag_t relation = NULLTAG;
	tag_t old_relation = NULLTAG;
	char* design_object_name1 = NULL;
	char* design_object_name2 = NULL;
	char* design_object_name3 = NULL;

	ITKCALL(ifail = AOM_ask_value_string(new_rev, "object_string", &design_object_name1));
	ITKCALL(ifail = AOM_ask_value_string(newwlrev, "object_string", &design_object_name2));
	ITKCALL(ifail = AOM_ask_value_string(old_part_rev, "object_string", &design_object_name3));

	printf("createAndSaveRelation方法开始绑定%s到%s的%s关系下···\n", design_object_name2, design_object_name1, productInfo);

	MEM_free(design_object_name2);
	MEM_free(design_object_name1);

	POM_AM__set_application_bypass(true);
	try {
		ITKCALL(ifail = GRM_find_relation_type(productInfo, &gx_gx_type));
		// 查找关系类型
		if (gx_gx_type == NULLTAG) {
			printf("未能找到关系类型：%s\n", productInfo);
			return false; // 如果查找关系类型失败，则返回false
		}

		//ITKCALL(ifail = GRM_find_relation(old_part_rev, newwlrev, gx_gx_type, &old_relation));
		/*if (old_relation != NULLTAG) {
			ITKCALL(ifail = GRM_delete_relation(old_relation));
			printf("删除【%s】与【%s】间的【%s】关系完毕\n", design_object_name2, design_object_name3, productInfo);
		}else{
			printf("删除【%s】与【%s】间的【%s】关系不存在\n", design_object_name2, design_object_name3, productInfo);
		}*/
		
		ITKCALL(ifail = GRM_create_relation(new_rev, newwlrev, gx_gx_type, NULLTAG, &relation));
		// 创建关系
		if (relation == NULLTAG) {
			printf("创建关系失败\n");
			return false; // 如果创建关系失败，则返回false
		}
		// 保存关系
		ITKCALL(ifail = GRM_save_relation(relation));

		POM_AM__set_application_bypass(false);

		if (ifail == ITK_ok) {
			return true; // 所有操作成功完成
		}
		else
		{
			return false;
		}

	}
	catch (...) {
		// 捕获所有异常，确保任何未预见的问题也能安全返回
		return false;
	}

}



int Method(METHOD_message_t msg, va_list args) {
	int ifail = ITK_ok;
	int rfCount = 0;
	tag_t relation_tag = NULLTAG, * rfTags = NULL;
	tag_t new_rev = va_arg(args, tag_t);
	char* operation = va_arg(args, char*);
	char* prop = nullptr;
	prop = "ysr8_FinishedDate";

	printf("这是清除属性值Method\n");
	if (strcmp(operation, "Revise") != 0) {
		return ifail;
	}
	printf("升版\n");
	ITKCALL(ifail = GRM_find_relation_type("IMAN_master_form", &relation_tag));
	if (relation_tag == NULLTAG) {
		return ifail;
	}
	ITKCALL(ifail = GRM_list_secondary_objects_only(new_rev, relation_tag, &rfCount, &rfTags));
	if (rfCount == 0) {
		return ifail;
	}
	AOM_lock(rfTags[0]);
	AOM_set_value_date(rfTags[0], prop, NULLDATE);
	AOM_save(rfTags[0]);
	AOM_unlock(rfTags[0]);
	AOM_refresh(rfTags[0], true);
	printf("属性%s清除\n", prop);
	return ITK_ok;
}

/*
* 判断当前tag对象是否可以进行升版操作
* @param wl_tag tag
* @return bool
*/
bool canUpgrade(tag_t wl_tag) {
	tag_t child_wl_item_tag = NULLTAG;
	tag_t last_wl_rev_tag = NULLTAG;
	date_t last_wl_rev_release_time = NULLDATE;
	int ifail = ITK_ok;

	// 获取当前待升版物料的item对象
	ITKCALL(ifail = ITEM_ask_item_of_rev(wl_tag, &child_wl_item_tag));
	if (ifail != ITK_ok) {
		return false;
	}

	// 获取item对象的最新版本对象
	ITKCALL(ifail = ITEM_ask_latest_rev(child_wl_item_tag, &last_wl_rev_tag));
	if (ifail != ITK_ok) {
		return false;
	}

	// 获取最新版本对象的发布日期
	ITKCALL(ifail = AOM_ask_value_date(last_wl_rev_tag, "date_released", &last_wl_rev_release_time));
	if (ifail != ITK_ok) {
		return false;
	}

	// 判断最新版本对象是否未发布（即working状态）
	if (last_wl_rev_release_time.year == 0) {
		return false; // 未发布
	}
	else {
		return true; // 已发布
	}
}

/*
* 打印图纸版本对象在此时‘表示’- representation_for 关系下的的物料
* @param design_rev_tag 图纸版本对象
*/
int show_parts(tag_t design_rev_tag) {
	int ifail = ITK_ok;
	int count = 0;
	tag_t* tags = NULL;
	char* designName = NULL,
		* partName = NULL;

	ITKCALL(ifail = AOM_ask_value_string(design_rev_tag, "object_string", &designName));
	ITKCALL(ifail = AOM_ask_value_tags(design_rev_tag, "representation_for", &count, &tags));
	if (count == 0)
	{
		printf("设计图纸【%s】的表示关系下没有对象！\n",designName);
	}
	else
	{
		printf("开始打印设计图纸【%s】的表示关系下的%d个对象！=======================================================\n",designName,count);
		for (size_t i = 0; i < count; i++)
		{
			//图纸版本对象的表示关系下的对象：tags[i]
			ITKCALL(ifail = AOM_ask_value_string(tags[i], "object_string", &partName));
			printf("===>>>【%s】对象！\n", partName);
		}
		printf("end 打印完毕！===================================================================================================\n");
	}
	MEM_free(partName);
	MEM_free(tags);
	MEM_free(designName);
	return ifail;
}

int delete_oldRelation(tag_t old_design_rev_tag,tag_t new_design_rev_tag) {
	//物料下的“提供者”关系-TC_Is_Represented_By下存放图纸
	//图纸下的“表示”关系-representation_for下存放物料
	char* relation = "TC_Is_Represented_By";
	//char* relation = "representation_for";
    int ifail = ITK_ok;
	int old_count = 0, new_count = 0;
    tag_t* old_tags = NULL, * new_tags = NULL;
	char* old_designName = NULL,
		* new_designName = NULL;
	char* new_design_uid = NULL,
		* old_design_uid = NULL;
	tag_t gx_gx_type = NULLTAG,
		old_relation = NULLTAG;

	ITKCALL(ifail = AOM_ask_value_tags(old_design_rev_tag, "representation_for", &old_count, &old_tags));
	ITKCALL(ifail = AOM_ask_value_tags(new_design_rev_tag, "representation_for", &new_count, &new_tags));
	ITKCALL(ifail = AOM_ask_value_string(old_design_rev_tag, "object_string", &old_designName));
	ITKCALL(ifail = AOM_ask_value_string(new_design_rev_tag, "object_string", &new_designName));
	printf("开始删除新图纸【%s】下的旧物料···\n", new_designName);

	if (old_count == 0)
	{
		printf("【%s】对象的表示关系下没有对象！\n", old_designName);
	}
	if (new_count == 0)
	{
		printf("【%s】对象的表示关系下没有对象！\n", new_designName);
	}
	if (old_count > 0 && new_count > 0)
	{
		POM_AM__set_application_bypass(true);
		//遍历升版后的新图纸对象关系下的对象uid
		for (int i = 0; i < new_count; i++)
		{
			ITK__convert_tag_to_uid(new_tags[i], &new_design_uid);
			char* n_part_name = NULL;
			ITKCALL(ifail = AOM_ask_value_string(new_tags[i], "object_string", &n_part_name));
			//遍历升版前的旧图纸对象关系下的对象uid
			for (int t = 0; t < old_count; t++)
			{
				printf("1\n");
				ITK__convert_tag_to_uid(old_tags[t], &old_design_uid);
				char* old_part_name = NULL;
				ITKCALL(ifail = AOM_ask_value_string(old_tags[t], "object_string", &old_part_name));

				printf("开始比较新图纸下的物料【%s】（uid=%s）与旧图纸下的物料【%s】（uid=%s）是否为同一个对象\n", n_part_name, new_design_uid, old_part_name, old_design_uid);
				//如果升版后的新图纸对象关系下的对象uid与升版前的旧图纸对象关系下的对象uid相等，则删除该(旧物料与新图纸)关系TC_Is_Represented_By
				if (strcmp(new_design_uid, old_design_uid) == 0)
				{

					printf("2\n");
					
					ITKCALL(ifail = GRM_find_relation_type(relation, &gx_gx_type));//未能找到关系类型：representation_for未能找到关系类型：representation_for
					// 查找关系类型
					if (gx_gx_type == NULLTAG) {
						printf("未能找到关系类型：%s\n", relation);
						continue;
					}
					printf("3\n");
					ITKCALL(ifail = GRM_find_relation(old_tags[t], new_design_rev_tag, gx_gx_type, &old_relation));
					printf("开始获取图纸【%s】和物料【%s】间的【%s】关系！\n", new_designName, old_part_name,relation);
					//ITKCALL(ifail = GRM_find_relation(new_design_rev_tag, old_tags[t], gx_gx_type, &old_relation));
					if (ifail != ITK_ok) {
						printf("未能找到【%s】与【%s】间的【%s】关系！\n", new_designName, old_part_name, relation);
						continue;
					}

					if (old_relation != NULLTAG) {
						ITKCALL(ifail = GRM_delete_relation(old_relation));
						ITKCALL(ifail = GRM_save_relation(old_relation));
						printf("end 删除【%s】与【%s】间的【%s】关系完毕\n", new_designName, old_part_name, relation);
					}
					else
					{
						printf("物料【%s】的【%s】关系下不存在图纸【%s】\n", old_part_name, new_designName, relation);
					}
					break;
				}

				MEM_free(old_part_name);
			}

			MEM_free(n_part_name);
		}

		POM_AM__set_application_bypass(false);
	}



	MEM_free(old_design_uid);
	MEM_free(new_design_uid);
	MEM_free(old_designName);
	MEM_free(new_tags);
	MEM_free(old_tags);
	return ifail;
}


/*
*	升版二开：后操处理一图多物情况
*/
int JD_RevUpgrade(METHOD_message_t* msg, va_list va)
{
	printf("升版后操方法开始执行 \n");
	int ifail = ITK_ok;
	tag_t check_tag = va_arg(va, tag_t);//获取操作的tag对象（升版前的对象）
	tag_t item = NULLTAG;
	//升版后的新物料版本对象
	tag_t new_part_tag = NULLTAG;
	//升版的新图纸版本对象
	tag_t new_design_tag = NULLTAG;
	//物料的最新版本对象
	tag_t last_partRev_tag = NULLTAG;
	//(old)图纸版本对象
	tag_t design_rev_tag = NULLTAG;
	//图纸对象
	tag_t design_item_tag = NULLTAG;
	//（new）图纸的最新版本对象
    tag_t last_designRev_tag = NULLTAG;
	char* type = NULL;
	char* name = NULL;
	char* design_object = NULL;//升版物料对应的图纸对象
	char* design_object2 = NULL;//升版物料对应的图纸对象
	char* part_object = NULL;//升版对象
	//物料下的图纸主表示对象
	tag_t* primary_tag = NULLTAG;
	//图纸下的物料版本对象
	tag_t* wl_tags = NULL;
	int count = 0;
	int count_wl = 0;
	int primary_tag_count = 0;
    char* revString1 = NULL;
	char* revString2 = NULL;
	date_t release_time = NULLDATE;
	int fb_count = 0;
	tag_t* fb_tags = NULL;
	//后操物料对象的uid
	char* wl_uid = NULL;

	char* rev_type = NULL;
	ITKCALL(ifail = AOM_ask_value_string(check_tag, "object_type", &rev_type));//获取待保存信息的类型
	ITKCALL(ifail = AOM_ask_value_string(check_tag, "object_string", &part_object));//获取待保存信息的类型
	
	printf("升版对象[%s]的类型：rev_type=[%s] \n", part_object,rev_type);
	//TODO 判断对象类型：图纸or物料
	ITKCALL(ifail = ITEM_ask_item_of_rev(check_tag, &item));
	ITKCALL(ifail = ITEM_ask_latest_rev(item, &new_part_tag));
	if (item != NULLTAG) {
		ITKCALL(ifail = AOM_ask_value_string(item, "object_type", &type));//获取待保存信息的类型
		ITKCALL(ifail = AOM_ask_value_string(item, "object_name", &name));//获取待保存信息的名称
		
		printf("操作对象的Item对象：【%s】的类型=【%s】\n", name, type);
		//如果升版对象为物料，则获取其关联的图纸进行升版
		if (isTypeOf1(item, "Part")) {
			printf("升版对象：【%s】为物料，获取其关联图纸进行后续升版操作\n", part_object);
			//获取对应的物料版本对象关联的图纸
			ITKCALL(ifail = AOM_ask_value_tags(check_tag, "TC_Primary_Design_Representation",&primary_tag_count, &primary_tag));
			ITK__convert_tag_to_uid(check_tag, &wl_uid);
			if (primary_tag_count > 0){
				printf("升版对象下的：主设计表示[primary_tag_count]属性存在%d个对象\n", primary_tag_count);
				//一图多物场景下，当前物料关联的图纸只有一个，因此默认取第一个对象为图纸对象
				for (int t = 0; t < primary_tag_count; t++)
				{
					design_rev_tag = primary_tag[t];
					//判断对应图纸是否升版？
					ITKCALL(ifail = ITEM_ask_item_of_rev(design_rev_tag, &design_item_tag));
					//根据图纸item对象获取最新版本对象，与当前图纸版本对象比较。如果两者不相等，即：升版了
					ITKCALL(ifail = ITEM_ask_latest_rev(design_item_tag, &last_designRev_tag));
					//item_revision_id
					ITKCALL(ifail = AOM_ask_value_string(design_rev_tag, "item_revision_id", &revString1));
					ITKCALL(ifail = AOM_ask_value_string(design_rev_tag, "object_string", &design_object));
					printf("物料[%s]对应的图纸对象：%s\n", part_object,design_object);
					ITKCALL(ifail = AOM_ask_value_string(last_designRev_tag, "item_revision_id", &revString2));

					ITKCALL(ifail = show_parts(design_rev_tag));
					ITKCALL(ifail = show_parts(last_designRev_tag));


					//手动解除升版后新图纸last_designRev_tag下关联的旧版物料
					ITKCALL(ifail = delete_oldRelation(design_rev_tag, last_designRev_tag));
					ITKCALL(ifail = show_parts(last_designRev_tag));

					//TODO 判断对应图纸是否升版？
					if (strcmp(revString1, revString2) == 0) {//物料对应的图纸版本与最新图纸版本相同，则：未升版
						printf("物料[%s]对应的图纸版本[%s]未升版，即将对图纸进行升版！\n", part_object, design_object);
						//对图纸升版
						ITKCALL(ifail = ITEM_copy_rev(design_rev_tag, NULL, &new_design_tag));
						if (new_design_tag != NULLTAG) {
							printf("图纸升版成功\n");
							//对图纸下关联的多个物料进行升版
							ITKCALL(ifail = AOM_ask_value_tags(design_rev_tag, "representation_for", &count_wl, &wl_tags));
							if (count_wl > 0) {
								printf("原图纸版本对象=【%s】关联的物料数量为%d\n", design_object, count_wl);
								for (int i = 0; i < count_wl; i++) {//将图纸下的物料版本对象进行升版，并和新图纸重新绑定关系
									char* wl_uid1 = NULL;
									char* wl_object_name = NULL;
									ITK__convert_tag_to_uid(wl_tags[i], &wl_uid1);
									tag_t new_part_tag_c = NULLTAG;
									ITKCALL(ifail = AOM_ask_value_string(wl_tags[i], "object_string", &wl_object_name));
									printf("图纸[%s]下关联的当前物料对象 = 【%s】！\n", design_object,wl_object_name);
									MEM_free(wl_object_name);
									if (strcmp(wl_uid, wl_uid1) == 0)//如果当前图纸下的物料版本对象与当前操作升版的(原)物料版本对象相同，则跳过（已经升版过了）
									{
										if (new_part_tag == NULLTAG)
										{
											printf("new_part_tag is NULLTAG，此时还无法(通过升版对象)获取升版后的新对象！\n");
										}
										else
										{
											new_part_tag_c = new_part_tag;
										}

									}
									else
									{
										ITKCALL(ifail = ITEM_copy_rev(wl_tags[i], NULL, &new_part_tag_c));//升版物料

									}

									if (new_part_tag_c != NULLTAG) {
										char* new_part_object_string = NULL;
										char* new_design_object_string = NULL;
										ITKCALL(ifail = AOM_ask_value_string(new_part_tag_c, "object_string", &new_part_object_string));
										ITKCALL(ifail = AOM_ask_value_string(new_design_tag, "object_string", &new_design_object_string));


										printf("旧图纸[%s]下的物料[%s]升版成功！开始将升版后的新物料[%s]与新图纸[%s]绑定关系\n", design_object, wl_object_name, new_part_object_string, new_design_object_string);
										//;//挂载关系、
										if (createAndSaveRelation("TC_Is_Represented_By", new_part_tag_c, new_design_tag, wl_tags[i])) {
											printf("a挂载关系成功\n");
										}
										else {
											printf("a挂载关系失败\n");
										}
										MEM_free(new_design_object_string);
										MEM_free(new_part_object_string);
									}
									MEM_free(wl_uid1);
								}
							}
						}
						MEM_free(wl_tags);
					}
					else {//物料对应的图纸版本已升版
						

						ITKCALL(ifail = AOM_ask_value_string(last_designRev_tag, "object_string", &design_object2));
						printf("物料[%s]对应的图纸版本[%s]已升版为【%s】，无需再升版！\n", part_object, design_object, design_object2);
						//获取升版后的新图纸版本对象last_designRev_tag，判断其是否发布
						ITKCALL(ifail = AOM_ask_value_date(last_designRev_tag, "date_released", &release_time));
						if (release_time.year != 0) {
							printf("当前物料关联的图纸已升版且发布，不进行后续操作。\n");
						}
						else {
							printf("当前物料[%s]关联的图纸[%s]已升版后的对象且未发布，进行后续操作···\n", part_object, design_object2);
							//升版后的图纸对象last_designRev_tag关联的全部物料都升版（包括当前物料）
							ITKCALL(ifail = AOM_ask_value_tags(last_designRev_tag, "representation_for", &count_wl, &wl_tags));
							printf("当前物料[%s]关联的图纸[%s]关联的物料有%d个，进行后续操作···\n", part_object, design_object2, count_wl);
							if (count_wl > 0) {
								printf("开始遍历关联图纸下的物料对象···\n");
								for (int i = 0; i < count_wl; i++) {//将图纸下的物料版本对象进行升版，并和新图纸重新绑定关系
									char* wl_uid1 = NULL;
									char* wl_object_name = NULL;
									tag_t new_part_tag_c = NULLTAG;
									ITK__convert_tag_to_uid(wl_tags[i], &wl_uid1);
									if (strcmp(wl_uid, wl_uid1) == 0)
									{
										ITKCALL(ifail = AOM_ask_value_string(wl_tags[i], "object_string", &wl_object_name));
										printf("图纸[%s]下关联的当前物料对象 = 【%s】，为升版操作对象，无需升版！\n", design_object2, wl_object_name);
										MEM_free(wl_object_name);

										if (new_part_tag == NULLTAG)
										{
											printf("new_part_tag is NULLTAG，此时还无法(通过升版对象)获取升版后的新对象！\n");
										}
										else
										{
											new_part_tag_c = new_part_tag;
										}

										//continue;//如果当前图纸下的物料版本对象与当前图纸的物料版本对象相同，则跳过（已经升版过了）
									}
									else
									{
										
										if (canUpgrade(wl_tags[i])) {
											ITKCALL(ifail = AOM_ask_value_string(wl_tags[i], "object_string", &wl_object_name));
											printf("图纸[%s]下关联的当前物料对象 = 【%s】，非升版操作对象，即将对当前物料进行升版！\n", design_object2, wl_object_name);
											MEM_free(wl_object_name);

											ITKCALL(ifail = ITEM_copy_rev(wl_tags[i], NULL, &new_part_tag_c));//升版物料
											printf("图纸[%s]下关联的当前物料对象 = 【%s】升版后，打印图纸对象的表示关系下的对象：\n", design_object2, wl_object_name);
										}
										else
										{
											printf("当前物料 %s 存在未发布的版本对象，无法进行升版！\n", wl_object_name);
										}
									}

									if (new_part_tag_c != NULLTAG) {
										char* new_part_object_string = NULL;
										ITKCALL(ifail = AOM_ask_value_string(new_part_tag_c, "object_string", &new_part_object_string));

										printf("(已升版)图纸【%s】下的物料【%s】升版成功！开始将升版后的新物料【%s】与图纸【%s】绑定关系\n", design_object2, wl_object_name, new_part_object_string,design_object2);
										
										if (createAndSaveRelation("TC_Is_Represented_By", new_part_tag_c, last_designRev_tag, wl_tags[i])) {
											printf("n挂载关系成功\n");
											ITKCALL(ifail = show_parts(last_designRev_tag));
										}
										else
										{
											printf("n挂载关系失败\n");
											ITKCALL(ifail = show_parts(last_designRev_tag));
										}

										MEM_free(new_part_object_string);
									}
									MEM_free(wl_uid1);
								}
							}
							else {
								printf("没有在设计图纸的‘representation_for’关系下找到符合要求的物料！\n");
							}
						}
						//MEM_free(fb_tags);
					}
					MEM_free(revString2);
					MEM_free(design_object);
					MEM_free(revString1);
				}
				
				
				
			}
			else
			{
				printf("获取物料下关联的图纸主表示失败！\n");
			}
			MEM_free(wl_uid);
			MEM_free(primary_tag);
		}
		else {
			printf("操作对象：【%s】的类型=【%s】，非物料对象不触发升版二开后操函数。\n", name, type);
		}
		MEM_free(name);
		MEM_free(type);
	}
	MEM_free(part_object);
	MEM_free(rev_type);
	return ifail;
}

/*
* userservice方法 - 更改单位
*/
int USERSERVICE_changeUnit(void* returnValue) {
	int ifail = ITK_ok;
	tag_t tag = NULL_TAG;
	char* uomName = NULL;
	tag_t* release_objs = NULL;

	USERARG_get_tag_argument(&tag);
	USERARG_get_string_argument(&uomName);

	int num_could = 0;
	tag_t* uoms = NULL, uom = NULLTAG;
	ITKCALL(UOM_extent(&num_could, &uoms));
	for (int i = 0; i < num_could; i++)
	{
		char* name = NULL;
		UOM_ask_name(uoms[i], &name);
		if (strcmp(name, uomName) == 0)
		{
			uom = uoms[i];
			break;
		}
	}
	char* class_id = NULL;
	tag_t attr_id = NULLTAG, class_tag = NULLTAG, tag_instance = NULLTAG;
	ITKCALL(AOM_lock(tag));//加锁
	ITKCALL(POM_class_of_instance(tag, &class_tag));//获取入参对象的类对象
	ITKCALL(POM_name_of_class(class_tag, &class_id));//获取类对象的属性id
	ITKCALL(POM_attr_id_of_attr("uom_tag", class_id, &attr_id));//获取uom_tag属性id
	ITKCALL(POM_refresh_instances_any_class(1, &tag, POM_modify_lock));
	ITKCALL(POM_set_attr_tag(1, &tag, attr_id, uom));
	ITKCALL(POM_save_instances(1, &tag, true));
	ITKCALL(AOM_unlock(tag));//解锁
	ITKCALL(AOM_refresh(tag, false));

	return ITK_ok;
}

typedef struct {
	string prop_location;
	string prop_name;
} Prop_Config;

typedef struct {
	string rev_type;
	string title_block_names;
	map<string, Prop_Config> prop_config_map;
} Sign_Config;


#define PROP_LOCATION_ITEM "item"
#define PROP_LOCATION_REV "rev"
#define PROP_LOCATION_ITEMMASTER "itemmaster"
#define PROP_LOCATION_REVMASTER "revmaster"

#define PREF_SIGNATURE "Connor_MCAD_Signature"
#define ITK_err 919011


/**
 * 从偏好设置中解析签名配置
 *
 * 此函数通过查询偏好设置来获取签名配置信息，并将其解析到一个映射表中
 * 每个签名类型对应一个配置对象，包含标题块名称和属性配置映射
 *
 * @param sign_config_map 用于存储解析后的签名配置的映射表
 * @return 返回执行结果，0表示成功，非0表示失败
 */
int ParseConfigFromPreference(map<string, Sign_Config>& sign_config_map) {
	int ifail = ITK_ok, pref_cnt = 0;
	char** pref_values = NULL;

	// 调用偏好设置接口获取签名相关的偏好值
	ITKCALL(ifail = PREF_ask_char_values(PREF_SIGNATURE, &pref_cnt, &pref_values));
	if (ifail != ITK_ok) { goto end; }

	for (int i = 0; i < pref_cnt; i++) {

		string value, rev_type, title_block_names;
		map<string, Prop_Config> prop_config_map;
		vector<string> prop_configs;

		value.assign(pref_values[i]);
		printf("1111\n");

		// 解析偏好值字符串，首先获取修订类型
		int ind = value.find(":");
		if (ind == string::npos || ind == 0) {
			continue;
		}

		printf("2222\n");
		rev_type = value.substr(0, ind);
		printf("rev_type:%s\n", rev_type.c_str());

		// 如果修订类型已存在，则跳过当前配置
		if (sign_config_map.count(rev_type) > 0) {
			continue;
		}

		printf("3333\n");

		// 继续解析标题块名称和属性配置
		value = value.substr(ind + 1);
		ind = value.find(":");
		if (ind == string::npos || ind == 0) {
			continue;
		}

		printf("4444\n");
		title_block_names = value.substr(0, ind);
		value = value.substr(ind + 1);

		// 分割属性配置字符串，并逐个解析
		Splits(value, ";", prop_configs);
		int size = prop_configs.size();

		for (int j = 0; j < size; j++) {
			string cad_prop_name, prop_location, prop_name;
			value = prop_configs[j];

			// 解析每个属性配置，获取CAD属性名称、属性位置和属性名称
			ind = value.find("=");
			if (ind == string::npos || ind == 0) {
				continue;
			}

			cad_prop_name = value.substr(0, ind);
			if (prop_config_map.count(cad_prop_name) > 0) {
				continue;
			}

			value = value.substr(ind + 1);
			ind = value.find(".");
			if (ind == string::npos || ind == 0) {
				continue;
			}

			prop_location = value.substr(0, ind);
			prop_name = value.substr(ind + 1);
			if (prop_name.empty()) {
				continue;
			}

			// 将属性位置转换为小写，以便后续比较
			transform(prop_location.begin(), prop_location.end(), prop_location.begin(), ::tolower);

			// 根据属性位置判断是否为有效的配置，并创建属性配置对象
			if (prop_location == PROP_LOCATION_ITEM ||
				prop_location == PROP_LOCATION_REV ||
				prop_location == PROP_LOCATION_ITEMMASTER ||
				prop_location == PROP_LOCATION_REVMASTER) {
				Prop_Config prop_config;
				prop_config.prop_location = prop_location;
				prop_config.prop_name = prop_name;
				prop_config_map[cad_prop_name] = prop_config; // 或使用 insert 方法，但直接使用下标操作更简洁
			}
		}

		// 如果属性配置映射不为空，则创建签名配置对象，并添加到签名配置映射中
		if (prop_config_map.size() > 0) {
			Sign_Config sign_config;
			sign_config.rev_type = rev_type;
			sign_config.title_block_names = title_block_names;
			sign_config.prop_config_map = prop_config_map;
			sign_config_map.insert(make_pair(rev_type, sign_config));
			printf("次数%d\n", i);
		}
	}

	// 如果签名配置映射为空，则存储错误信息并返回错误代码
	if (sign_config_map.size() < 1) {
		ITKCALL(ifail = EMH_store_error_s2(EMH_severity_error, ITK_err, ("首选项配置错误"), PREF_SIGNATURE));
		ifail = ITK_err;
	}

end:
	DOFREE(pref_values);
	return ifail;
}

#define PREF_REMOVE_FILE "Connor_MCAD_RemoveTempFile"
#define PREF_UPLOAD_FILE "Connor_MCAD_UploadFile"

/**
* actionHandler：调用exe程序启动cad同步数据集
*/
int SynchronizeDataSet(EPM_action_message_t msg)
{
	int ifail = ITK_ok, att_cnt = 0, pref_cnt = 0;
	tag_t root_task = NULLTAG, * attachments = NULL;
	map<string, Sign_Config> sign_config_map;
	char* object_string = NULL, * object_type = NULL, ** pref_values = NULL;
	string dataset_rel, dataset_type, dataset_ref;
	bool has_err = false;
	logical remove_file = true;

	// 获取当前任务标签，并根据当前任务获取根任务标签。
	tag_t current_task = msg.task;
	ITKCALL(ifail = EPM_ask_root_task(current_task, &root_task));
	if (ifail != ITK_ok) { goto end; }

	// 日志输出，标志着函数开始执行。
	Log("=====================================================");
	Log("Connor_CAD_Signature 开始执行");
	Log("=====================================================");

	// 官方API：查询根任务的附件（数据集），获取附件数量和附件标签数组。
	ITKCALL(ifail = EPM_ask_attachments(root_task, EPM_target_attachment, &att_cnt, &attachments));
	if (att_cnt == 0) {
		Log("目标下无引用对象");
		goto end;
	}

	// 设置绕过某些检查的标志。
	set_bypass(true);

	// 官方API：查询是否需要删除临时文件的偏好设置。
	ITKCALL(ifail = PREF_ask_logical_value(PREF_REMOVE_FILE, 0, &remove_file));
	if (ifail != ITK_ok) {
		EMH_clear_last_error(ifail);
	}
	if (remove_file) {
		Log("不保留临时文件");
	}
	else {
		Log("保留临时文件");
	}

	// 官方API：解析上传配置，包括数据集的相关信息。
	ITKCALL(ifail = PREF_ask_char_values(PREF_UPLOAD_FILE, &pref_cnt, &pref_values));
	if (ifail != ITK_ok) { goto end; }
	if (pref_cnt < 3) {
		//ITKCALL(ifail = EMH_store_error_s2(EMH_severity_error, ITK_err, ("首选项配置错误"), PREF_SIGNATURE));
		ifail = ITK_err;
		goto end;
	}
	dataset_rel.assign(pref_values[0]);
	dataset_type.assign(pref_values[1]);
	dataset_ref.assign(pref_values[2]);
	Log("数据集配置: [%s][%s][%s]", dataset_rel.c_str(), dataset_type.c_str(), dataset_ref.c_str());
	DOFREE(pref_values);

	// 解析签名配置，从偏好设置中读取并解析签名配置信息。
	ITKCALL(ifail = ParseConfigFromPreference(sign_config_map));
	if (ifail != ITK_ok) { goto end; }







end:
	// 日志输出，标志着函数执行结束。
	Log("=====================================================");
	Log("Connor_CAD_Signature 执行结束");
	Log("=====================================================");

	// 清理标志，恢复某些检查的执行。
	set_bypass(false);

	// 如果有错误发生，则返回错误代码。
	if (has_err) {
		ifail = ITK_err;
	}

	// 释放分配的内存。
	DOFREE(pref_values);
	DOFREE(object_string);
	DOFREE(object_type);
	DOFREE(attachments);

	// 返回执行结果。
	return ifail;

}
