#include #include #include "dfl_custom.h" //#include "ocilib.h" #include #include #include #include #include #include #include #include #include #include #include "corecrt_io.h" #include "direct.h" #include #include #pragma comment(lib, "Wininet") #define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING #include #pragma comment(lib, "ws2_32.lib") #include using namespace std; #include #include #include "cJSON.h" #include #include #include #include "common_itk_util.h" //#include "dfl_custom.h" //#include "util.h" //#include #include "ocilib.h" //using namespace std; #include #include #include #include "curlToFtp.h" //#include "httplib.h" //引入minIO需要的库 #define USE_IMPORT_EXPORT #include"iostream" #include "aws\s3\S3Client.h" #include "aws\core\Aws.h" #include "aws\core\auth\AWSCredentialsProvider.h" #include #include using namespace Aws::S3; using namespace Aws::S3::Model; using namespace std; #include "aws\s3\model\PutObjectRequest.h" #include "aws\s3\model\GetObjectRequest.h" #include #include //#include "base64.h" extern "C" int POM_AM__set_application_bypass(logical bypass); /* 判断对象objtag是否属于type_name类型 */ bool isTypeOf(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; } // 声明 std::string base64_encode(unsigned char const* bytes_to_encode, size_t in_len, bool url = false); static const char* base64_chars[2] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789" "+/", "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789" "-_" }; // 定义 std::string base64_encode(unsigned char const* bytes_to_encode, size_t in_len, bool url) { size_t len_encoded = (in_len + 2) / 3 * 4; unsigned char trailing_char = url ? '.' : '='; const char* base64_chars_ = base64_chars[url]; std::string ret; ret.reserve(len_encoded); unsigned int pos = 0; while (pos < in_len) { ret.push_back(base64_chars_[(bytes_to_encode[pos + 0] & 0xfc) >> 2]); if (pos + 1 < in_len) { ret.push_back(base64_chars_[((bytes_to_encode[pos + 0] & 0x03) << 4) + ((bytes_to_encode[pos + 1] & 0xf0) >> 4)]); if (pos + 2 < in_len) { ret.push_back(base64_chars_[((bytes_to_encode[pos + 1] & 0x0f) << 2) + ((bytes_to_encode[pos + 2] & 0xc0) >> 6)]); ret.push_back(base64_chars_[bytes_to_encode[pos + 2] & 0x3f]); } else { ret.push_back(base64_chars_[(bytes_to_encode[pos + 1] & 0x0f) << 2]); ret.push_back(trailing_char); } } else { ret.push_back(base64_chars_[(bytes_to_encode[pos + 0] & 0x03) << 4]); ret.push_back(trailing_char); ret.push_back(trailing_char); } pos += 3; } return ret; } /* * system函数是阻塞调用,如果FTP服务器响应缓慢或网络不稳定,会导致程序长时间等待。 */ bool UploadFileToFtp(const std::string& filePath, const std::string& ftpTargetPath, const std::string& ftpServer, const std::string& ftpUsername, const std::string& ftpPassword) { printf("UploadFileToFtp方法开始执行~\n"); printf("=> filePath: %s\n", filePath.c_str()); printf("=> ftpTargetPath: %s\n", ftpTargetPath.c_str()); printf("=> ftpServer: %s\n", ftpServer.c_str()); printf("=> ftpUsername: %s\n", ftpUsername.c_str()); printf("=> ftpPassword: %s\n", ftpPassword.c_str()); //std::string ftpUrl = "ftp://" + ftpUsername + ":" + ftpPassword + "@" + ftpServer + ftpTargetPath; std::string ftpUrl = "ftp://" + ftpServer + ftpTargetPath; if (!ftpTargetPath.empty() && ftpTargetPath.back() != '/') { ftpUrl += "/"; } size_t lastSlashPos = filePath.find_last_of("\\/"); std::string fileName = (lastSlashPos == std::string::npos) ? filePath : filePath.substr(lastSlashPos + 1); //ftpUrl += fileName; //std::string command = "curl --max-time 30 -T \"" + filePath + "\" \"" + ftpUrl + "\""; // 构建curl命令,包含用户名和密码 std::string command = "curl --max-time 60 -u \"" + ftpUsername + ":" + ftpPassword + "\" -T \"" + filePath + "\" \"" + ftpUrl + "\""; int result = system(command.c_str()); if (result == 0) { std::cout << "File uploaded successfully." << std::endl; return true; } else { std::cerr << "There was an error uploading the file." << std::endl; return false; } } bool is_utf8(const char* str) { int c; while (*str) { c = (unsigned char)*str; if (c > 0 && c < 128) { str++; } else if ((c & 0xE0) == 0xC0) { if ((*(str + 1) & 0xC0) != 0x80) return false; str += 2; } else if ((c & 0xF0) == 0xE0) { if ((*(str + 1) & 0xC0) != 0x80 || (*(str + 2) & 0xC0) != 0x80) return false; str += 3; } else if ((c & 0xF8) == 0xF0) { if ((*(str + 1) & 0xC0) != 0x80 || (*(str + 2) & 0xC0) != 0x80 || (*(str + 3) & 0xC0) != 0x80) return false; str += 4; } else { return false; } } return true; } size_t write_data(void* ptr, size_t size, size_t nmemb, void* stream) { string data((const char*)ptr, (size_t)size * nmemb); *((stringstream*)stream) << data << endl; return size * nmemb; } string GbkToUtf8(const std::string& strGbk)//传入的strGbk是GBK编码 { //gbk转unicode int len = MultiByteToWideChar(CP_ACP, 0, strGbk.c_str(), -1, NULL, 0); wchar_t* strUnicode = new wchar_t[len]; wmemset(strUnicode, 0, len); MultiByteToWideChar(CP_ACP, 0, strGbk.c_str(), -1, strUnicode, len); //unicode转UTF-8 len = WideCharToMultiByte(CP_UTF8, 0, strUnicode, -1, NULL, 0, NULL, NULL); char* strUtf8 = new char[len]; WideCharToMultiByte(CP_UTF8, 0, strUnicode, -1, strUtf8, len, NULL, NULL); std::string strTemp(strUtf8);//此时的strTemp是UTF-8编码 delete[]strUnicode; delete[]strUtf8; strUnicode = NULL; strUtf8 = NULL; return strTemp; } string GBKToUTF8_2(const char* data) { string GBK = ""; //1、GBK转unicode //1.1 统计转换后的字节数 int len = MultiByteToWideChar(CP_ACP, //转换的格式 0, //默认的转换方式 data, //输入的字节 -1, //输入的字符串大小 -1找\0结束 自己去算 0, //输出(不输出,统计转换后的字节数) 0 //输出的空间大小 ); if (len <= 0) { return GBK; } wstring udata; //用wstring存储的 udata.resize(len);//分配大小 //开始写进去 MultiByteToWideChar(CP_ACP, 0, data, -1, (wchar_t*)udata.data(), len); //2 unicode 转 utf8 len = WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)udata.data(), -1, 0, 0, 0, //失败替代默认字符 0 //是否使用默认替代 0 false ); if (len <= 0) { return GBK; } GBK.resize(len); WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)udata.data(), -1, (char*)GBK.data(), len, 0, 0); return GBK; } string UTF8ToGBK_2(const char* data) { string utf8 = ""; //1、UTF8 先要转为unicode windows utf16 //1.1 统计转换后的字节数 int len = MultiByteToWideChar(CP_UTF8, //转换的格式 0, //默认的转换方式 data, //输入的字节 -1, //输入的字符串大小 -1找\0结束 自己去算 0, //输出(不输出,统计转换后的字节数) 0 //输出的空间大小 ); if (len <= 0) { return utf8; } wstring udata; //用wstring存储的 udata.resize(len);//分配大小 //开始写进去 MultiByteToWideChar(CP_UTF8, 0, data, -1, (wchar_t*)udata.data(), len); //2 unicode 转 GBK len = WideCharToMultiByte(CP_ACP, 0, (wchar_t*)udata.data(), -1, 0, 0, 0, //失败替代默认字符 0 //是否使用默认替代 0 false ); if (len <= 0) { return utf8; } utf8.resize(len); WideCharToMultiByte(CP_ACP, 0, (wchar_t*)udata.data(), -1, (char*)utf8.data(), len, 0, 0); return utf8; } char* U2G(const char* utf8) { int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0); wchar_t* wstr = new wchar_t[len + 1]; memset(wstr, 0, len + 1); MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len); len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL); char* str = new char[len + 1]; memset(str, 0, len + 1); WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL); if (wstr) delete[] wstr; return str; } std::wstring s2ws(const std::string& s) { int len; int slength = (int)s.length() + 1; len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); wchar_t* buf = new wchar_t[len]; MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len); std::wstring r(buf); delete[] buf; return r; } // 函数用于转义需要在JSON中使用的字符串,不然在处理JSON数据时遇到了不认识的字符转义错误 std::string escapeJson(const std::string& input) { std::string output; output.reserve(input.size() * 2); // 预分配足够的空间以提高性能 for (unsigned char c : input) { // 使用unsigned char来避免符号扩展问题 switch (c) { case '"': output += "\\\""; break; case '\\': output += "\\\\"; break; case '\b': output += "\\b"; break; case '\f': output += "\\f"; break; case '\n': output += "\\n"; break; case '\r': output += "\\r"; break; case '\t': output += "\\t"; break; default: // 对于ASCII控制字符(0x00-0x1F),使用Unicode转义序列 if (std::iscntrl(c)) { char buffer[7]; snprintf(buffer, sizeof(buffer), "\\u%04X", c); output += buffer; } else { // 直接添加非ASCII控制字符(包括中文) output += c; } } } return output; } // 回调函数,用于处理服务器返回的数据 size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) { ((std::string*)userp)->append((char*)contents, size * nmemb); return size * nmemb; } bool uploadFileToMinIO(const std::string& filePath, const std::string& bucketFileName) { CURL* curl; CURLcode res; std::string readBuffer; curl = curl_easy_init(); if (curl) { curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:8080/minio/upload"); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https"); struct curl_slist* headers = NULL; headers = curl_slist_append(headers, "Content-Type: multipart/form-data"); //headers = curl_slist_append(headers, "Accept-Charset: GBK"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); printf("C++上传文件到minIO方法入参:localFilePath=【%s】,bucketPath=【%s】\n", filePath.c_str(), bucketFileName.c_str()); curl_mime* mime; curl_mimepart* part; mime = curl_mime_init(curl); //string filePathString = GBKToUTF8_2(filePath.c_str()); part = curl_mime_addpart(mime); curl_mime_name(part, "filePath"); curl_mime_filedata(part, filePath.c_str()); //string gbkString = UTF8ToGBK_2(bucketFileName.c_str()); string utf8String = GBKToUTF8_2(bucketFileName.c_str()); part = curl_mime_addpart(mime); curl_mime_name(part, "bucketFileName"); curl_mime_data(part, utf8String.c_str(), CURL_ZERO_TERMINATED); curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); res = curl_easy_perform(curl); if (res != CURLE_OK) { printf("C++上传文件到minIO方法失败,错误码:%d,错误信息:%s\n", res, curl_easy_strerror(res)); } else { printf("C++上传文件到minIO方法成功,成功码:%d,响应信息:%s\n", res, curl_easy_strerror(res)); } curl_mime_free(mime); curl_slist_free_all(headers); } curl_easy_cleanup(curl); return true; } //上传文件到MinIO的方法SS //bool uploadFileToMinIO(const std::string& filePath, const std::string& bucketFileName) { // CURL* curl; // CURLcode res; // printf("C++上传文件到minIO方法入参:localFilePath=【%s】,bucketPath=【%s】\n", filePath.c_str(), bucketFileName.c_str()); // // 初始化curl // curl_global_init(CURL_GLOBAL_DEFAULT); // curl = curl_easy_init(); // if (curl) { // // 设置URL // std::string url = "http://localhost:8080/minio/upload"; // curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); // curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); // struct curl_slist* headers = NULL; // headers = curl_slist_append(headers, "Accept-Charset: GBK"); // headers = curl_slist_append(headers, "Content-Type: application/json;charset=GBK"); // curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); // // // 准备POST数据 // std::string postFields = "file=" + filePath + "&bucketFileName=" + bucketFileName; // const char* data = U2G(postFields.c_str()); // curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data); // curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10); // curl_easy_setopt(curl, CURLOPT_TIMEOUT, 20); // printf("06\n"); // // 执行请求 // res = curl_easy_perform(curl); // printf("06\n"); // // 检查错误 // if (res != CURLE_OK) { // std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl; // curl_easy_cleanup(curl); // curl_global_cleanup(); // return false; // } // // // 清理 // curl_easy_cleanup(curl); // } // curl_global_cleanup(); // // return true; //} //==================================================================== //std::string escapeJson(const std::string& input) { // std::ostringstream ss; // for (unsigned char c : input) { // switch (c) { // case '"': ss << "\\\""; break; // case '\\': ss << "\\\\"; break; // case '\b': ss << "\\b"; break; // case '\f': ss << "\\f"; break; // case '\n': ss << "\\n"; break; // case '\r': ss << "\\r"; break; // case '\t': ss << "\\t"; break; // default: ss << c; // 直接添加其他字符 // } // } // return ss.str(); //} // //void cleanup(CURL* curl, struct curl_slist* headers) { // if (curl) curl_easy_cleanup(curl); // if (headers) curl_slist_free_all(headers); // curl_global_cleanup(); //} // //bool uploadFileToMinIO(const std::string& filePath, const std::string& bucketFileName) { // CURL* curl; // CURLcode res; // // printf("C++上传文件到minIO方法入参:localFilePath=【%s】,bucketPath=【%s】\n", // filePath.c_str(), bucketFileName.c_str()); // // 将字符串转换为 unsigned char* 类型,因为 base64_encode 需要这种类型的输入 // const unsigned char* bytes_to_encode_filePath = reinterpret_cast(filePath.c_str()); // size_t in_len1 = filePath.size(); // // 调用 base64_encode 函数进行编码,默认不使用 URL 安全字符 // std::string encoded_str_filePath = base64_encode(bytes_to_encode_filePath, in_len1); // // const unsigned char* bytes_to_encode_bucketFileName = reinterpret_cast(bucketFileName.c_str()); // size_t in_len2 = bucketFileName.size(); // // 调用 base64_encode 函数进行编码,默认不使用 URL 安全字符 // std::string encoded_str_bucketFileName = base64_encode(bytes_to_encode_bucketFileName, in_len2); // // curl_global_init(CURL_GLOBAL_DEFAULT); // curl = curl_easy_init(); // if (!curl) { // std::cerr << "curl初始化失败!" << std::endl; // return false; // } // // printf("curl初始化完成!开始发送请求···\n"); // // std::string url = "http://localhost:8080/minio/upload"; // curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); // // std::string jsonPayload = "{\"filePath\":\"" + encoded_str_filePath // + "\",\"bucketFileName\":\"" + encoded_str_bucketFileName // + "\"}"; // // curl_easy_setopt(curl, CURLOPT_POST, 1L); // curl_easy_setopt(curl, CURLOPT_POSTFIELDS, jsonPayload.c_str()); // curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, jsonPayload.size()); // // struct curl_slist* headers = NULL; // headers = curl_slist_append(headers, "Content-Type: application/json; charset=UTF-8"); // curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); // // res = curl_easy_perform(curl); // // if (res != CURLE_OK) { // std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl; // cleanup(curl, headers); // return false; // } // // long http_code = 0; // curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); // if (http_code != 200) { // std::cerr << "HTTP request failed with code: " << http_code << std::endl; // cleanup(curl, headers); // return false; // } // // cleanup(curl, headers); // return true; //} /* * 创建FTP层级目录 */ int createFTPDir(HINTERNET session, char* dir) { int ifail = ITK_ok; std::string str(dir); // 将 char* 转换为 std::string std::istringstream iss(str); std::vector parts; std::string part; std::string createPath; while (std::getline(iss, part, '/')) { if (!part.empty()) { // 忽略空字符串 parts.push_back(part); } } for (const auto& p : parts) { std::cout << p << std::endl; createPath += "/" + p; if (FtpCreateDirectoryA(session, createPath.c_str())) { WriteLog("提示:创建FTP文件夹成功== %s\n", createPath.c_str()); } else { WriteLog("提示:创建FTP文件夹失败== %s,若已存在此文件夹请忽略!\n", createPath.c_str()); } } // 创建成功后尝试切换到新建目录下 BOOL dirChangeResult = FtpSetCurrentDirectoryA(session, dir); if (!dirChangeResult) { WriteLog("》》》提示:切换到新建目录 %s 失败!\n", dir); return false; } else { WriteLog("》》》提示:成功切换到新建目录 %s。\n", dir); } return ifail; } /* * 清空远程目录下所有文件 */ bool DeleteLRDirectory(const char* directory) { CURL* curl; CURLcode res; std::string readBuffer; curl = curl_easy_init(); if (curl) { curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:8080/minio/deleteByDir"); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https"); struct curl_slist* headers = NULL; headers = curl_slist_append(headers, "Content-Type: multipart/form-data"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); printf("C++清空minIO目录方法入参:directory=【%s】\n", directory); curl_mime* mime; curl_mimepart* part; mime = curl_mime_init(curl); part = curl_mime_addpart(mime); curl_mime_name(part, "directory"); curl_mime_data(part, directory, CURL_ZERO_TERMINATED); curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); res = curl_easy_perform(curl); if (res != CURLE_OK) { printf("C++清空minIO目录失败,错误码:%d,错误信息:%s\n", res, curl_easy_strerror(res)); } else { printf("C++清空minIO目录成功,成功码:%d,响应信息:%s\n", res, curl_easy_strerror(res)); } curl_mime_free(mime); curl_slist_free_all(headers); } curl_easy_cleanup(curl); return true; } /*o * 判断dpath路径是否存在,存在则清空该文件夹下的所有文件和子目录,否则创建该文件夹 * @param dPath:文件夹路径 */ void clearDir(string dPath) { string command = ""; if (_access(dPath.c_str(), 0) == 0) {//文件已存在,则清空该文件夹下的所有文件和子目录 command.append("del /q "); command.append(dPath); command.append("*"); system(command.c_str()); printf("提示:清空文件夹命令:%s!\n",command.c_str()); } else { string mdCommand = "md "; mdCommand.append(dPath); system(mdCommand.c_str()); printf("提示:新建文件夹成功!"); } } // 函数定义 std::string removeLastFileName(const std::string& path) { // 查找最后一个反斜杠的位置 size_t lastSlashPos = path.find_last_of('\\'); // 如果找到了反斜杠,并且它不是最后一个字符,则返回该位置之前的子字符串 if (lastSlashPos != std::string::npos && lastSlashPos != path.length() - 1) { return path.substr(0, lastSlashPos); } // 如果最后一个字符是反斜杠,或者没有找到反斜杠,返回原字符串 return path; } void Split(string strArg, string spliter, vector& ans) { ans.clear(); size_t index0; string one_arg; if (strArg.find_first_not_of(" ") == string::npos) strArg = ""; while (strArg.size() > 0) { index0 = strArg.find(spliter); if (index0 != string::npos) { one_arg = strArg.substr(0, index0); strArg = strArg.substr(index0 + spliter.size()); ans.push_back(one_arg); } else { ans.push_back(strArg); break; } } } /*o * 异步任务处理完成时,根据流程id变更状态为“已完成” * @param flow_uid:流程id * @param field_name:要更新的字段名 * @param new_value:要更新的字段值 * */ int setAttrForTask(const char* flow_uid, const char* field_name, const char* new_value) { char sql_changeStatus[1024] = "\0"; sprintf(sql_changeStatus, "update WHBH_CAPP_TASK set %s='%s' where FLOWID='%s'", field_name, new_value, flow_uid); printf("提示:sql_changeStatus==%s \n", sql_changeStatus); if (ExecuteSQLNoInputParam(sql_changeStatus) == -1) { printf("》》》异常提示:更新流程状态失败!sql_changeStatus == %s\n", sql_changeStatus); return 1; }else { printf("》》》提示:更新流程状态成功!sql_changeStatus == %s\n", sql_changeStatus); ExecuteSQLNoInputParam("commit"); } return 0; } /*o * 获取当前yyyy-MM-dd HH-mm-ss格式的日期 */ void get_current_time(char* updatetime) { // 获取当前时间的秒数 time_t rawtime; time(&rawtime); // 将秒数转换为本地时间结构体 struct tm* timeinfo; timeinfo = localtime(&rawtime); // 格式化时间为字符串 sprintf(updatetime, "%04d-%02d-%02d %02d:%02d:%02d", timeinfo->tm_year + 1900, // 年份从1900年开始计算 timeinfo->tm_mon + 1, // 月份从0开始计算 timeinfo->tm_mday, // 日 timeinfo->tm_hour, // 小时 timeinfo->tm_min, // 分钟 timeinfo->tm_sec); // 秒 } /*o * 保存物料相关信息到数据库表-WHBH_CAPP_PART */ int savePart(tag_t revisionTag, char* username) { printf("提示:开始执行savePart方法,得到username==%s \n", username); tag_t itemTag = NULLTAG; printf("提示:开始保存物料信息到数据库表 \n"); //TODO 根据版本获取对象 ITKCALL(ITEM_ask_item_of_rev(revisionTag, &itemTag)); int ifail = ITK_ok; int return_tag = 0; char* materialno = NULL,//物料编码 * name = NULL,//物料名称 * version = NULL,//物料版本 * unit = NULL,//单位 * specification = NULL,//物料规格 * designno = (char*)MEM_alloc(1028 * sizeof(char)),//图号 * dversion = (char*)MEM_alloc(1028 * sizeof(char)),//图纸版本 * orderno = NULL,//令号 * source = NULL,//物料来源 * purchase = NULL,//品牌说明 * issuedtime = (char*)MEM_alloc(1028 * sizeof(char)),//下发时间 * updatetime = (char*)MEM_alloc(1028 * sizeof(char));//更新时间 char* userid; tag_t* revMasterTags = NULL;//表单对象 tag_t tuzTag = NULLTAG;//图纸对象 tag_t* tuzTags = NULL; char*** flowUID_values = NULL; int outputValueCount; char* type = NULL; printf("提示:开始组织物料表信息 \n"); ITKCALL(ifail = AOM_ask_value_string(itemTag, "item_id", &materialno)); ITKCALL(ifail = AOM_ask_value_string(itemTag, "object_name", &name)); ITKCALL(ifail = AOM_ask_value_string(itemTag, "object_type", &type)); ITKCALL(ifail = AOM_UIF_ask_value(itemTag, "uom_tag", &unit)); printf("===>提示:物料【%s】类型【%s】的单位==%s \n",name,type, unit); ITKCALL(ifail = AOM_ask_value_string(revisionTag, "item_revision_id", &version)); //组织版本表单属性:根据版本对象获取表单对象 int revMasterNum = 0; ITKCALL(ifail = AOM_ask_value_tags(revisionTag, "IMAN_master_form_rev", &revMasterNum, &revMasterTags)); if (revMasterNum > 0) { printf("=============================>>>提示:获取表单对象成功,共有%d个表单对象 \n", revMasterNum); for (int i = 0; i < revMasterNum; i++) { ITKCALL(ifail = AOM_ask_value_string(revMasterTags[i], "h8_specification", &specification)); ITKCALL(ifail = AOM_ask_value_string(revMasterTags[i], "h8_linghao", &orderno)); ITKCALL(ifail = AOM_ask_value_string(revMasterTags[i], "h8_material_source", &source)); ITKCALL(ifail = AOM_ask_value_string(revMasterTags[i], "h8_ppsm", &purchase)); } } else { printf("提示:表单对象为空,无法获取物料表单信息 \n"); } int tuz_count = 0; //组织物料下的图纸属性:根据版本对象获取"提供者"关系文件夹下的图纸版本对象 char* wlbb = NULL; ITKCALL(ifail = AOM_ask_value_tags(revisionTag, "TC_Is_Represented_By", &tuz_count, &tuzTags)); ITKCALL(ifail = AOM_ask_value_string(revisionTag, "item_id", &wlbb)); printf("=============>>>提示:物料::%s提供者关系文件夹下的图纸版本对象数量为::%d \n", wlbb, tuz_count); if (tuz_count > 0) { printf("提示:获取‘提供者’关系下的图纸对象成功,个数为%d \n", tuz_count); char* classification = NULL; //对加密图纸的令号designno和版本dversion隐藏:空字符串 AOM_ask_value_string(tuzTags[0], "ip_classification", &classification); if (stricmp(classification, "内部") == 0) { printf("提示:图纸对象为非密图纸,令号and版本号正常写入 \n"); tag_t* revisionTags = NULLTAG; int revisionNums = 0; ITKCALL(ITEM_ask_item_of_rev(tuzTags[0], &itemTag));//根据图纸版本获取图纸对象 ITKCALL(ifail = AOM_ask_value_tags(itemTag, "revision_list", &revisionNums, &revisionTags)); //TODO 图纸对象为空时插入异常 ITKCALL(ifail = AOM_ask_value_string(itemTag, "item_id", &designno)); ITKCALL(ifail = AOM_ask_value_string(revisionTags[revisionNums - 1], "item_revision_id", &dversion)); printf("提示:图纸对象:%s 的最新版本对象为:%s \n", designno, dversion); MEM_free(revisionTags); } else { printf("提示:图纸对象为加密图纸,令号和版本号置空 \n"); strcpy(designno, " "); strcpy(dversion, " "); } } else { printf("》》》异常提示:图纸对象为空,无法获取关系文件夹下的图纸信息,令号和版本号置空 \n"); strcpy(designno, " "); printf("111"); strcpy(dversion, " "); } printf("物料表表信息组织完成,开始插入or更新数据到数据库"); int outputColumn = 0; char sql1[1024] = "\0"; sprintf(sql1, "select * from WHBH_CAPP_PART where materialno = '%s' and version = '%s'", materialno, version); printf("提示:sql1==%s\n", sql1); printf("Tt:查询结果判断是否·已存在数据==%d\n", QuerySQLNoInputParam(sql1, &outputColumn, &outputValueCount, &flowUID_values)); if (QuerySQLNoInputParam(sql1, &outputColumn, &outputValueCount, &flowUID_values) == -1) { printf("提示:查询数据 失败, %s \n", sql1); //return 1; } else { if (outputValueCount == 0) { printf("提示:未查询到数据, %s \n", sql1); printf("》》》开始插入数据 \n");//插入更新时间和下发时间 get_current_time(issuedtime); get_current_time(updatetime); char sql2[1024] = "\0"; sprintf(sql2, "insert into WHBH_CAPP_PART(materialno,name,version,unit,specification,designno,dversion,orderno,source,purchase,username,issuedtime,updatetime) values('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')", materialno, name, version, unit, specification, designno, dversion, orderno, source, purchase, username, issuedtime, updatetime); printf("提示:sql2==%s\n", sql2); if (ExecuteSQLNoInputParam(sql2) == -1) { printf("提示:sql2数据插入 失败, %s \n", sql2); //return 1; } else { ExecuteSQLNoInputParam("commit"); } } else { printf("提示:查询到已存在数据, %s \n", sql1); printf("==========:outputColumn == %d \n", outputColumn); printf("==========:outputValueCount == %d \n", outputValueCount); printf("》》》开始更新数据 \n");//只更新更新时间 get_current_time(updatetime); char sql3[1024] = "\0"; sprintf(sql3, "update WHBH_CAPP_PART set name = '%s',unit = '%s',specification = '%s',designno = '%s',dversion = '%s',orderno = '%s',source = '%s',purchase = '%s',username = '%s',updatetime = '%s' where materialno = '%s' and version = '%s'", name, unit, specification, designno, dversion, orderno, source, purchase, username, updatetime, materialno, version); printf("提示:sql3==%s\n", sql3); if (ExecuteSQLNoInputParam(sql3) == -1) { printf("提示:数据更新 失败, %s \n", sql3); //return 1; } else { ExecuteSQLNoInputParam("commit"); } } } /*MEM_free(userid); MEM_free(username);*/ MEM_free(dversion); MEM_free(designno); MEM_free(tuzTags); MEM_free(purchase); MEM_free(source); MEM_free(orderno); MEM_free(specification); MEM_free(revMasterTags); MEM_free(version); MEM_free(unit); MEM_free(type); MEM_free(name); MEM_free(materialno); return ifail; } /*o * 提取时间字符串中的年月日 */ int extract_date_components(const char* issuedtime, char* year, char* month, char* day) { int ifail = ITK_ok; // 提取年 strncpy(year, issuedtime, 4); year[4] = '\0'; // 确保字符串正确终止 // 提取月 strncpy(month, issuedtime + 5, 2); month[2] = '\0'; // 确保字符串正确终止 // 提取日 strncpy(day, issuedtime + 8, 2); day[2] = '\0'; // 确保字符串正确终止 return ifail; } /*o * 保存图纸相关信息到数据库表中-WHBH_CAPP_DESIGN * 保存版本下关联的数据集存到服务器目录下 * revisionTag:版本对象 */ int saveDrawing(tag_t revisionTag, char* username) { printf("方法-saveDrawing开始执行,接受到参数username==%s \n", username); int ifail = ITK_ok; char* designno, * version, * weight, * materials, * specification, * name, * address = (char*)malloc(128), * userid, * issuedtime = (char*)MEM_alloc(1028 * sizeof(char)), * updatetime = (char*)MEM_alloc(1028 * sizeof(char)), * nowTime = (char*)MEM_alloc(1028 * sizeof(char)); tag_t itemTag = NULLTAG;//图纸对象 tag_t* revMasterTags = NULL;//版本表单 tag_t revMasterTag = NULLTAG; int dataset_num = 0; tag_t* dataset_tags = NULL; char* file_type = NULL; char* origin_file_name = NULL, * ref_file_name = NULL, * ref_type = NULL, * dataset_name = NULL; // 为年、月、日分配存储空间 char year[5]; // "yyyy" + null 终止符 char month[3]; // "MM" + null 终止符 char day[3]; // "dd" + null 终止符 tag_t* ref_object = NULL; int n_found = 0; //get_current_time(nowTime); string addressv; ITKCALL(ITEM_ask_item_of_rev(revisionTag, &itemTag)); int revMasterNum = 0; ITKCALL(ifail = AOM_ask_value_tags(revisionTag, "IMAN_master_form_rev", &revMasterNum, &revMasterTags));//获取图纸版本对象下的版本表单 if (revMasterNum > 0) { printf(">>>>>提示:图纸版本对象下有版本表单,开始获取版本表单信息 \n"); for (int i = 0; i < revMasterNum; i++) { char* typevalue; AOM_ask_value_string(revMasterTags[i], "object_type", &typevalue); printf("》》》版本表单类型:%s\n", typevalue); //1.组织图纸对象属性 ITKCALL(ifail = AOM_ask_value_string(itemTag, "item_id", &designno)); ITKCALL(ifail = AOM_ask_value_string(revisionTag, "item_revision_id", &version)); ITKCALL(ifail = AOM_ask_value_string(revMasterTags[i], "h8_weight", &weight)); ITKCALL(ifail = AOM_ask_value_string(revMasterTags[i], "h8_materials", &materials)); ITKCALL(ifail = AOM_ask_value_string(revMasterTags[i], "h8_material_specification", &specification)); printf("获取到的weight==%s继续后续流程\n", weight); if (weight == NULL || weight[0] == '\0') { strcpy(weight, ""); printf("提示:获取weight失败,请检查属性值是否存在!\n"); } if (materials == NULL || materials[0] == '\0') { strcpy(materials, ""); printf("提示:获取materials失败,请检查属性值是否存在!\n"); } if (specification == NULL || specification[0] == '\0') { strcpy(specification, ""); printf("提示:获取specification失败,请检查属性值是否存在!\n"); } ITKCALL(ifail = AOM_ask_value_string(itemTag, "object_name", &name)); printf("》》》当前正在保存的图纸信息为:图号==%s,图纸名称==%s,版本==%s\n", designno, name, version); /*tag_t user; POM_get_user(&username, &user); POM_get_user_id(&userid);*/ //------------开始判断存入图纸信息到数据库----------------------------------------------------------------------------- int outputValueCount, outputColumn; char*** result_values; char sql_cx[1024] = "\0"; sprintf(sql_cx, "select ADDRESS from WHBH_CAPP_DESIGN where designno='%s' and version='%s' ", designno, version); printf("提示:cxsql==%s\n", sql_cx); if (QuerySQLNoInputParam(sql_cx, &outputColumn, &outputValueCount, &result_values) == -1) { printf("提示:cxsql查询失败\n"); return 1; } get_current_time(issuedtime); get_current_time(updatetime); printf(">>>>>查询结构:outputColumn==%d ,outputValueCount==%d \n", outputColumn, outputValueCount); //--------------获取首选项中的FTP信息并与FTP建立连接---------------------------------------------------------------------------------------------------- //获取首选项中配置的连接FTP的IP地址、用户名、密码 int ftp_value_count = 0; char** ftp_option_values; char* ftp_ip = (char*)MEM_alloc(64*sizeof(char)), * ftp_user = (char*)MEM_alloc(64 * sizeof(char)), * ftp_password = (char*)MEM_alloc(64 * sizeof(char)); //struct tm* lt2; ITKCALL(PREF_ask_char_values("BH_CAPP_FTP", &ftp_value_count, &ftp_option_values)); if (ftp_value_count != 3) { printf("首选项配置项错误:配置数量==%d,请核查!\n", ftp_value_count); return ifail; } //printf("===>开始连接FTP服务器···"); ////连接FTP服务器 //HINTERNET hInternet = NULL, hFtpSession = NULL; //hInternet = InternetOpenA(NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); //hFtpSession = InternetConnectA( // hInternet, // ftp_option_values[0], // INTERNET_DEFAULT_FTP_PORT, // ftp_option_values[1], // ftp_option_values[2], // INTERNET_SERVICE_FTP, // INTERNET_FLAG_PASSIVE, // 0 //); //if (hFtpSession == NULL) { // printf("连接FTP服务器失败\n"); //} //else //{ // strcpy(ftp_ip, ftp_option_values[0]); // strcpy(ftp_user, ftp_option_values[1]); // strcpy(ftp_password, ftp_option_values[2]); // printf("连接FTP服务器成功\n"); //} printf("===>>>开始判断是否存在原始数据\n"); if (outputValueCount == 0) {//不存在图纸原始数据,开始插入图纸数据 WriteLog("===>不存在图纸原始数据,开始插入图纸数据\n"); //提取年月日组件 extract_date_components(issuedtime, year, month, day); string exportName = "C:\\Design_temp\\"; string ftpFilePath = "/Design/"; exportName.append(year).append("\\").append(month).append("\\").append(day).append("\\").append(designno).append("-").append(version); ftpFilePath.append(year).append("/").append(month).append("/").append(day).append("/").append(designno).append("-").append(version); strcpy(address, ftpFilePath.c_str());//存储地址 exportName.append("\\"); //准备数据集存放目录 clearDir(exportName); //获取图纸版本下关联的数据集,并存储到服务器目录下 ITKCALL(AOM_ask_value_tags(revisionTag, "IMAN_specification", &dataset_num, &dataset_tags)); if (dataset_num > 0) { DeleteLRDirectory(ftpFilePath.c_str()); //在FTP上提前创建存放数据集文件的文件夹,ftpFilePath路径形如:/Design/2022/01/25/000022-A //ITKCALL(ifail = createFTPDir(hFtpSession, &ftpFilePath[0])); printf("提示:图纸版本下有数据集:%d个,开始保存数据集下的引用文件 \n", dataset_num); for (int i = 0; i < dataset_num; i++) { printf("reforbegin\n"); WriteLog("提示:开始循环遍历处理数据集[%d]\n", i); //获取数据集文件名称 ITKCALL(AOM_ask_value_string(dataset_tags[i], "current_name", &dataset_name)); //数据集对象dataset_tags[i],数据集下的引用文件数量n_found,数据集下的引用文件ref_object ITKCALL(AE_ask_dataset_named_refs(dataset_tags[i],&n_found, &ref_object)); printf("提示:数据集名称==%s,引用文件数量==%d\n", dataset_name, n_found); if (n_found > 0) { for (int j = 0; j < n_found;j++) { //获取数据集下引用文件的类型 ITKCALL(AOM_ask_value_string(ref_object[j], "object_type", &ref_type)); printf("提示:当前引用文件类型==%s\n", ref_type); if (strcmp(ref_type, "ImanFile") == 0) { ITKCALL(AOM_ask_value_string(ref_object[j], "original_file_name", &ref_file_name)); if (ref_file_name != NULL && ref_file_name[0] != '\0') { string ftpFilePathTrue = ftpFilePath; //每次拼接文件路径时,去掉最后一个\\符号后的内容(保留\\) string final_exportName = removeLastFileName(exportName); final_exportName.append(ref_file_name);//C:\Design\2022\01\25\000022-A\111.dwg printf("》》》提示:数据集下引用文件导出路径==%s \n 开始导出文件:%s》》》 \n", exportName.c_str(), ref_file_name); ITKCALL(ifail = IMF_export_file(ref_object[j], final_exportName.c_str())); printf("=======OVER成功导出文件到本地缓存目录:%s======================== \n", final_exportName.c_str()); printf("\n"); printf("\n"); printf("\n"); ftpFilePathTrue.append("/"); std::cout << "==== upload test ====" << std::endl; string ip = ftp_ip; string user = ftp_user; string password = ftp_password; /*bool success = UploadFileToFtp(final_exportName, ftpFilePathTrue, ip, user, password);*/ ftpFilePathTrue.append(ref_file_name); bool success = uploadFileToMinIO(final_exportName, ftpFilePathTrue); if (success) { printf("提示:FTP上传成功==%s\n", ftpFilePath.c_str()); } else { printf("提示:FTP上传失败==%s\n", ftpFilePath.c_str()); } } else { printf("提示:数据集[%s]下ImanFile类型的引用文件中不存在origin_file_name属性,获取引用文件名失败!不导出文件\n", dataset_name); } printf("3\n"); } printf("4\n"); } printf("5\n"); } else { printf("提示:数据集下不存在引用文件,不导出文件\n"); } printf("6\n"); } printf("7\n"); MEM_free(ref_object); MEM_free(ftp_password); MEM_free(ftp_user); MEM_free(ftp_ip); MEM_free(ref_type); MEM_free(dataset_name); } else { printf("提示:数据集不存在,不导出文件\n"); } //删除本地临时文件夹上的所有内容 WriteLog("》》》FTP上传数据集完成,开始清空本地临时文件夹\n"); //clearDir(exportName); printf("提示:不存在原始数据,开始插入数据》》》\n"); char sql_ins[1024] = "\0"; sprintf(sql_ins, "insert into WHBH_CAPP_DESIGN(designno,version,weight,name,address,username,issuedtime,updatetime,materials,specification) values('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')", designno, version, weight, name, address, username, issuedtime, updatetime,materials,specification); printf("提示:sqlins==%s\n", sql_ins); if (ExecuteSQLNoInputParam(sql_ins) == -1) { printf("提示:数据插入 失败, %s \n", sql_ins); return 1; } else { ExecuteSQLNoInputParam("commit"); } } else if (outputValueCount > 0) { // 存在,更新数据 printf("提示:数据已存在,开始更新数据》》》\n"); //获取原始数据的数据集物理文件保存地址 string ftpExportName = result_values[0][0];// "/Design/2022/01/25/000022-C" string zscfPath = "C:\\Design_temp\\";//暂时存放位置 clearDir(zscfPath); ITKCALL(AOM_ask_value_tags(revisionTag, "IMAN_specification", &dataset_num, &dataset_tags)); if (dataset_num > 0) { //更新 WriteLog("已存在原始图纸记录,且更新后的图纸下存在数据集,开始更新FTP文件"); // 清空ftp上的ftpExportName目录下的所有文件,为下面循环遍历取得数据集存放做准备 DeleteLRDirectory(ftpExportName.c_str()); //在FTP上提前创建存放数据集文件的文件夹,ftpFilePath路径形如:/Design/2022/01/25/000022-A/ ftpExportName.append("/"); //ITKCALL(ifail = createFTPDir(hFtpSession, &ftpExportName[0])); printf("提示:图纸版本下有数据集:%d个,开始保存数据集下的引用文件 \n", dataset_num); for (int i = 0; i < dataset_num; i++) { //获取数据集文件名称 ITKCALL(AOM_ask_value_string(dataset_tags[i], "current_name", &origin_file_name)); //数据集对象dataset_tags[i],数据集下的引用文件数量n_found,数据集下的引用文件ref_object ITKCALL(AE_ask_dataset_named_refs(dataset_tags[i], &n_found, &ref_object)); printf("提示:数据集名称==%s,引用文件数量==%d\n", origin_file_name, n_found); if (n_found > 0) { for (int t = 0; t < n_found;t++) { ITKCALL(AOM_ask_value_string(ref_object[t], "object_type", &ref_type)); printf("提示:当前引用文件类型==%s\n", ref_type); if (strcmp(ref_type, "ImanFile") == 0) { //获取数据集下引用文件的名称 ITKCALL(AOM_ask_value_string(ref_object[t], "original_file_name", &ref_file_name)); if (ref_file_name != NULL && ref_file_name[0] != '\0') { printf("提示:数据集下存在引用文件,开始导出文件》》》\n"); string final_exportName = zscfPath;// C:\Design_temp\111.dwg final_exportName.append(ref_file_name); //导出当前数据集下存在的引用文件到服务器目录下 ITKCALL(ifail = IMF_export_file(ref_object[t], final_exportName.c_str())); printf("=======OVER成功导出文件到本地缓存目录:%s,导出文件:%s======================== \n", final_exportName.c_str(), ref_file_name); printf("\n"); printf("\n"); printf("\n"); string ftpFilePath = ftpExportName; ftpFilePath.append(ref_file_name); printf("mao2 \n"); string ip = ftp_ip; string user = ftp_user; string password = ftp_password; /*bool success = UploadFileToFtp(final_exportName, ftpExportName, ip, user, password);*/ bool success = uploadFileToMinIO(final_exportName, ftpFilePath); if (success) { printf("提示:FTP上传成功==%s\n", ftpFilePath.c_str()); } else { printf("提示:FTP上传失败==%s\n", ftpFilePath.c_str()); } } } else { printf("提示:数据集[%s]下ImanFile类型的引用文件中不存在origin_file_name属性,获取引用文件名失败!不导出文件\n", origin_file_name); } } } else { printf("提示:数据集下不存在引用文件,不导出文件\n"); } } MEM_free(ftp_password); MEM_free(ftp_user); MEM_free(ftp_ip); MEM_free(ref_file_name); MEM_free(ref_type); MEM_free(ref_object); MEM_free(origin_file_name); //clearDir(zscfPath); } else { printf("提示:数据集不存在,不导出文件\n"); } char sql_upd[1024] = "\0"; sprintf(sql_upd, "update WHBH_CAPP_DESIGN set weight = '%s',name = '%s',username = '%s',updatetime = '%s' where designno='%s' and version='%s' and materials='%s' and specification='%s' ", weight,name, username, updatetime, designno, version, materials, specification); printf("提示:sqlupd==%s\n", sql_upd); if (ExecuteSQLNoInputParam(sql_upd) == -1) { printf("提示:数据插入 失败, %s \n", sql_upd); return 1; } else { ExecuteSQLNoInputParam("commit"); } } MEM_free(dataset_tags); MEM_free(ftp_option_values); MEM_free(name); MEM_free(specification); MEM_free(materials); MEM_free(weight); MEM_free(version); MEM_free(designno); MEM_free(typevalue); } } MEM_free(revMasterTags); return ifail; } /*o * 递归BOMLine取得相应的数据存到数据库表中 * @param topLineTag:当前BOMLine,即为父项 */ int throughAllBom(tag_t topLineTag,char* username) { printf("开始执行方法=>throughAllBom,获取的参数username==%s\n",username); int ifail = ITK_ok; //BOM表中的数据条目 char* parent, * parentversion, * parentname, * sub, * subversion = NULL, * subname, * lineno, * quantity, * issuedtime = (char*)MEM_alloc(1028 * sizeof(char)), * updatetime = (char*)MEM_alloc(1028 * sizeof(char)); tag_t itemTag = NULLTAG, itemRevisionTag = NULLTAG, partItemRevisionTag = NULLTAG,//物料版本对象 partItemTag = NULLTAG, drawingItemRevisionTag = NULLTAG,//物料版本对象 drawingItemTag = NULLTAG;//物料对象 tag_t childItemRevisionTag, childItemTag; char* userid = NULL; tag_t user; int outputColumnQ = 0; int outputCountQ; char*** outputValuesQ; ITKCALL(ifail = AOM_ask_value_tag(topLineTag, bomAttr_lineItemRevTag, &itemRevisionTag)); ITKCALL(ifail = AOM_ask_value_tag(topLineTag, bomAttr_lineItemTag, &itemTag)); //获取BOM信息 ITKCALL(ifail = AOM_ask_value_string(itemTag, "item_id", &parent)); ITKCALL(ifail = AOM_ask_value_string(itemRevisionTag, "item_revision_id", &parentversion)); ITKCALL(ifail = AOM_ask_value_string(itemTag, "object_name", &parentname)); printf("获取到当前物料版本对象的BOM信息:父项版本及名称==%s,%s,%s\n", parent, parentversion, parentname); //获取用户名称、id /*POM_get_user(&username, &user); POM_get_user_id(&userid);*/ tag_t* childLines = NULL; int lineCount = 0; //获取当前bom行-bomline的所有子行 BOM_line_ask_child_lines(topLineTag, &lineCount, &childLines); if (lineCount > 0) { for (int i = 0; i < lineCount; i++) { printf("提示:存在子项,开始处理子项信息》》》\n"); //在进入下一次递归前保存当前子项的物料相关信息 ITKCALL(ifail = AOM_ask_value_tag(childLines[i], bomAttr_lineItemRevTag, &childItemRevisionTag)); ITKCALL(ifail = AOM_ask_value_tag(childLines[i], bomAttr_lineItemTag, &childItemTag)); char* objType; AOM_ask_value_string(childItemRevisionTag, "object_type", &objType); //getStringProperty printf("SB提示:当前版本对象类型==%s\n", objType); if (stricmp(objType, "H8_wuliaoRevision") == 0)//物料BOM { printf("提示:当前子项为物料,开始获取物料信息》》》\n"); //保存当前子项的物料信息 ITKCALL(ifail = savePart(childItemRevisionTag,username)); } else if (stricmp(objType, "H8_frockItemRevision") == 0 || stricmp(objType, "H8_drawingRevision") == 0 || stricmp(objType, "H8_frockItemRevision") == 0 || stricmp(objType, "H8_standardPartsRevision") == 0 || stricmp(objType, "H8_ComponentRevision") == 0) {//图纸BOM char* classification; printf("提示:当前子项为图纸,开始获取图纸信息》》》\n"); //判断 密级程度 AOM_ask_value_string(childItemRevisionTag, "ip_classification", &classification); if (stricmp(classification, "内部") == 0) { printf(">>>当前图纸为非密图纸,允许下发:%s \n", classification); ITKCALL(ifail = saveDrawing(childItemRevisionTag,username)); } MEM_free(classification); } //在每个子行中执行save操作,然后将当前子行作为topLineTag递归 //从bom子行中获取物料信息 //对子项版本特殊处理:物料和图纸的“子项版本”内容不是同一个数据来源 ITKCALL(ifail = AOM_ask_value_string(childItemRevisionTag, "item_revision_id", &subversion)); ITKCALL(ifail = AOM_ask_value_string(childItemTag, "item_id", &sub)); ITKCALL(ifail = AOM_ask_value_string(childItemTag, "object_name", &subname)); ITKCALL(ifail = AOM_ask_value_string(childLines[i], "bl_sequence_no", &lineno)); ITKCALL(ifail = AOM_ask_value_string(childLines[i], "bl_quantity", &quantity)); //插入BOM数据到数据库表中 char sql_query[1024] = "\0"; sprintf(sql_query, "select * from WHBH_CAPP_BOM where parent = '%s' and parentversion = '%s' and sub = '%s' and subversion = '%s'",parent,parentversion,sub,subversion); printf("Info:sql_query==%s\n", sql_query); if (QuerySQLNoInputParam(sql_query,&outputColumnQ,&outputCountQ,&outputValuesQ) == -1){ printf("提示:sql_query==%s查询失败\n", sql_query); return NULL; } if (outputCountQ <= 0) { //如果当前BOM不存在原始数据,则插入 printf("提示:sql_query==%s无记录\n", sql_query); get_current_time(issuedtime); get_current_time(updatetime); char sql1[1024] = "\0"; sprintf(sql1, "insert into WHBH_CAPP_BOM(parent,parentversion,parentname,sub,subversion,subname,lineno,quantity,username,issuedtime,updatetime) values('%s','%s','%s','%s','%s','%s',%s,'%s','%s','%s','%s')", parent, parentversion, parentname, sub, subversion, subname, lineno, quantity, username, issuedtime, updatetime); printf("提示:sql1==%s\n", sql1); if (ExecuteSQLNoInputParam(sql1) == -1) { printf("提示:数据插入 失败, %s \n", sql1); return 1; } else { ExecuteSQLNoInputParam("commit"); } }else{ //如果当前BOM数据已存在,则更新 get_current_time(updatetime); char sql5[1024] = "\0"; sprintf(sql5, "update WHBH_CAPP_BOM set parentname='%s',subname='%s',lineno='%s',quantity='%s',username='%s',updatetime='%s' where parent = '%s' and parentversion = '%s' and sub = '%s' and subversion = '%s'", parentname, subname, lineno, quantity, username,updatetime, parent, parentversion, sub,subversion); printf("提示:sql5==%s\n", sql5); if (ExecuteSQLNoInputParam(sql5) == -1) { printf("提示:数据插入 失败, %s \n", sql5); return 1; } else { ExecuteSQLNoInputParam("commit"); } } // 递归 throughAllBom(childLines[i],username); MEM_free(quantity); MEM_free(lineno); MEM_free(subname); MEM_free(sub); MEM_free(subversion); MEM_free(objType); } } else { printf("》》》异常提示:当前BOM不存在子项,即不存在BOM结构,不处理\n"); } MEM_free(childLines); /*MEM_free(userid); MEM_free(username);*/ MEM_free(parentname); MEM_free(parentversion); MEM_free(parent); return ifail; } /*o * (exe)服务:获取流程下的对象,判断对象类型:物料or图纸,分别处理 * @param c_sql_values: 数据库连接信息 * @param flow_uid: 从“异步任务表”WHBH_CAPP_TASK 中查询出的待处理的流程ID */ int DFL_WL_TO_CAPP(char** c_sql_values, const char* flow_uid,char* username) { printf("DFL_WL_TO_CAPP方法开始执行,当前流程:%s的username==%s\n",flow_uid,username); //char logFilePath[128] = "C:\\Users\\Administrator\\Desktop\\TC_LOG.txt"; //CreateLogFile(logFilePath); char* log_file = NULL; printf("创建日志文件\n"); //char logFilePath[128] = "C:\\Users\\Administrator\\Desktop\\TC_LOG.txt"; //CreateLogFile(logFilePath, &log_file); printf("===================================\n"); printf("WL to CAPP begin\n"); printf("===================================\n"); int ifail = ITK_ok; printf("Open super privilege\n"); POM_AM__set_application_bypass(true); //流程的状态 int status1 = 2; int att_cnt = 0, i = 0; int attachmentCount = 0; tag_t root_task_tag = NULLTAG, *attachments; tag_t rootTask = NULLTAG, windowTag = NULLTAG, topLineTag = NULLTAG; tag_t executor; tag_t query_tag1 = NULLTAG; tag_t* attachmentTags = NULL, revisionTag = NULLTAG, itemTag = NULLTAG; char* user_uid; char dwg[] = "DWG"; char T2_dwg[] = "T2_DWG"; char AIDrawing[] = "AIDrawing"; char t2_AIDrawing[] = "T2_AIDrawing"; const char query_name_product[1][QRY_name_size_c + 1] = { "零组件版本" }; //uid转tag对象:将流程uid转换为tag对象 ITK__convert_uid_to_tag(flow_uid, &root_task_tag); tag_t root = NULLTAG; EPM_ask_root_task(root_task_tag,&root); if (ifail != ITK_ok) { printf("this workflow is not exist!\n"); return ifail; } printf("》》》开始获取流程下的对象\n"); //---------------------------------------------------------------------------------------------------------------------------- //获取流程下的对象数组-attachments ITKCALL(EPM_ask_attachments(root, EPM_target_attachment, &att_cnt, &attachments)); printf("当前流程:%s 下的对象数量为:%d \n", flow_uid, att_cnt); if (att_cnt > 0) { for (i = 0; i < att_cnt; i++) { //获得流程下的物料版本对象kuma revisionTag = attachments[i]; if (!isTypeOf(revisionTag, "ItemRevision")) {//如果不是版本对象,则跳过 printf("流程:%s 下的当前对象不是版本对象,跳过\n", flow_uid); continue; } //根据流程目标下的版本对象,获取版本对象对应的item对象 ITKCALL(ITEM_ask_item_of_rev(revisionTag, &itemTag)); //TODO 判断流程目标下的版本对象是物料还是图纸 char* objType; char* objName; char* publishStatus; char* classification; date_t publishDate; AOM_ask_value_string(revisionTag, "object_type", &objType); AOM_ask_value_string(revisionTag, "object_name", &objName); printf("SB当前流程下对象版本类型为:%s \n", objType); //------------------------------《开始判断流程下的对象类型:物料or图纸》----------------------------------------------------------------------------------------------------------- if (stricmp(objType, "H8_wuliaoRevision") == 0)//如果此流程下的当前对象为:物料版本 { printf("当前流程下对象版本为物料版本\n"); // 进入BOM递归前存一次物料,在递归过程中只存子项物料即可 if (revisionTag != NULL) { savePart(revisionTag,username); } else { printf("当前流程下对象版本为空,无法保存物料信息到数据库"); } //1.获取当前流程对象的bom行 //创建Window BOM_create_window(&windowTag); //设置顶层BOMline BOM_set_window_top_line(windowTag, itemTag, revisionTag, NULLTAG, &topLineTag); throughAllBom(topLineTag,username); printf("》》》BOM递归结束"); //关闭BOMwindow BOM_close_window(windowTag); }else if (stricmp(objType, "H8_frockItemRevision") == 0 || stricmp(objType, "H8_drawingRevision") == 0 || stricmp(objType, "H8_frockItemRevision") == 0 || stricmp(objType, "H8_standardPartsRevision") == 0 || stricmp(objType, "H8_ComponentRevision") == 0) {//如果此流程下的当前对象为:图纸版本 printf("当前流程下对象版本为图纸版本:%s \n",objType); //校验发布状态,未发布则不执行并提示:当前版本未发布 AOM_ask_value_date(revisionTag, "date_released", &publishDate); if (publishDate.year == NULL) { printf("当前版本未发布,不执行 \n"); return ifail; } else { printf(">>>当前版本已发布,发布时间为: \n"); printf("Date: %04hd-%02hhd-%02hhd\n", publishDate.year, publishDate.month, publishDate.day); printf("Time: %02hhd:%02hhd:%02hhd\n", publishDate.hour, publishDate.minute, publishDate.second); } //判断 密级程度 AOM_ask_value_string(revisionTag, "ip_classification", &classification); if (stricmp(classification,"内部") == 0) { printf(">>>当前图纸为非密图纸,允许下发:%s \n", classification); // 进入BOM递归前第一次存图纸,递归中再存一次给:将图纸版本对象属性以及表单属性记录到图纸数据表中 ITKCALL(ifail = saveDrawing(revisionTag,username)); } else { printf(">>>当前图纸:%s为加密图纸,不允许下发:%s \n", objName, classification); } //1.获取当前流程对象的bom行 //创建Window BOM_create_window(&windowTag); //设置顶层BOMline BOM_set_window_top_line(windowTag, itemTag, revisionTag, NULLTAG, &topLineTag); throughAllBom(topLineTag,username); //关闭BOMwindow BOM_close_window(windowTag); MEM_free(classification); }else{ printf("不满足要求:流程 ==> %s 下的 %s 对象类型为:%s\n", flow_uid, objName, objType); } MEM_free(objName); MEM_free(objType); } }else { printf("》》》流程下没有对象,无法执行"); } MEM_free(attachments); CloseLog(); return ifail; } /*分割MSG“000022-A”为两个部分*/ int split_msg(const char* msg, char* item_id, char* item_revision_id) { int ifail = ITK_ok; char* buffer; char* token; // 计算字符串长度并分配足够的内存 size_t len = strlen(msg); //buffer = malloc(len + 1); // +1 是为了容纳字符串终止符 '\0' buffer = (char*)MEM_alloc(1028 * sizeof(char)); if (buffer == NULL) { fprintf(stderr, "Memory allocation failed\n"); return 1; } // 复制字符串到缓冲区 strcpy(buffer, msg); // 使用 strtok 分割字符串 token = strtok(buffer, "-"); if (token != NULL) { strcpy(item_id, token); printf("拆分得到item_id: %s\n", token); // 输出 "000022" } token = strtok(NULL, "-"); if (token != NULL) { strcpy(item_revision_id, token); printf("拆分msg得到item_revision_id: %s\n", token); // 输出 "A" } // 释放分配的内存 MEM_free(buffer); return ifail; } /* * (exe)服务:手动下发 */ int SD_TO_CAPP(const char* msg,char* username) { printf("》》》开始执行手动下发SD_TO_CAPP方法,接受到入参MSG==%s,username==%s\n",msg,username); char* log_file = NULL; int ifail = ITK_ok; char* item_id = (char*)MEM_alloc(1028 * sizeof(char)); char* item_revision_id = (char*)MEM_alloc(1028 * sizeof(char)); ITKCALL(ifail = split_msg(msg, item_id, item_revision_id)); //1.通过MSG(“000022-A”)调用查询构建器获取具体的零组件版本对象 tag_t query = NULL; int n_found; ITKCALL(ifail = QRY_find2("CAPP_Serch", &query)); //ITKCALL(ifail = QRY_find2("零组件 ID", &query)); tag_t* tags; tag_t windowTag; tag_t itemTag; tag_t topLineTag; date_t publishDate; boolean saveFlag = true; char* qry_entries[2] = { "ItemI" ,"Revisio" }, * qry_values[2] = { item_id ,item_revision_id }, * errorId = ""; /*char* qry_entries[1] = { "零组件 ID"}, * qry_values[1] = { item_id }, * errorId = "";*/ char* classification; if (query == NULL) { printf(">>>>>>>查询不到CAPP构建器对象!"); } else { char* uid; POM_tag_to_uid(query,&uid); printf("uid======%s\n",uid); printf(">>>>>查询到CAPP构建器对象,开始执行查询"); printf(">>>查询条目:零组件 ID==%s,版本==%s\n", item_id, item_revision_id); } ITKCALL(ifail = QRY_execute(query, 2, qry_entries, qry_values, &n_found, &tags)); printf("查询到%d个零组件版本结果\n", n_found); if (n_found == 0) { printf("未找到对应的零组件版本对象,请检查MSG信息是否正确!"); return ifail; } else { for (int i = 0; i < n_found; i++) { char* itemIdC; char* item_revision_idC; AOM_ask_value_string(tags[i], "item_id", &itemIdC); AOM_ask_value_string(tags[i], "item_revision_id", &item_revision_idC); printf("查询到的零组件版本对象==> %s - %s\n", itemIdC, item_revision_idC); MEM_free(item_revision_idC); MEM_free(itemIdC); } //-----------------------判断获取到的零组件版本对象tags[0](理论上只能查询出一个结果),是物料or图纸---------------- //2.根据版本对象获取版本类型 char* objType; char* objName; AOM_ask_value_string(tags[0], "object_type", &objType); AOM_ask_value_string(tags[0], "object_name", &objName); //根据版本对象,获取版本对象对应的item对象 ITKCALL(ITEM_ask_item_of_rev(tags[0], &itemTag)); //3.获取到版本类型:图纸版本/物料版本,分别复用上面自动下发的代码 if (stricmp(objType, "H8_wuliaoRevision") == 0)//如果此流程下的当前对象为:物料版本 { printf("当前流程下对象版本为物料版本\n"); // 进入BOM递归前存一次物料,在递归过程中只存子项物料即可 if (tags[0] != NULL) { savePart(tags[0], username); } else { printf("当前流程下对象版本为空,无法保存物料信息到数据库"); } //1.获取当前流程对象的bom行 //创建Window BOM_create_window(&windowTag); //设置顶层BOMline BOM_set_window_top_line(windowTag, itemTag, tags[0], NULLTAG, &topLineTag); throughAllBom(topLineTag, username); printf("》》》BOM递归结束"); //关闭BOMwindow BOM_close_window(windowTag); } else if (stricmp(objType, "H8_frockItemRevision") == 0 || stricmp(objType, "H8_drawingRevision") == 0 || stricmp(objType, "H8_frockItemRevision") == 0 || stricmp(objType, "H8_standardPartsRevision") == 0 || stricmp(objType, "H8_ComponentRevision") == 0) {//如果此流程下的当前对象为:图纸版本 printf("当前流程下对象版本为图纸版本 \n"); //校验发布状态,未发布则不执行并提示:当前版本未发布 AOM_ask_value_date(tags[0], "date_released", &publishDate); if (publishDate.year == NULL) { printf("当前版本未发布,不执行 \n"); return ifail; } else { printf(">>>当前版本已发布,发布时间为: \n"); printf("Date: %04hd-%02hhd-%02hhd\n", publishDate.year, publishDate.month, publishDate.day); printf("Time: %02hhd:%02hhd:%02hhd\n", publishDate.hour, publishDate.minute, publishDate.second); } //判断 密级程度 AOM_ask_value_string(tags[0], "ip_classification", &classification); if (stricmp(classification, "内部") == 0) { printf(">>>当前图纸为非密图纸,允许下发:%s \n", classification); // 进入BOM递归前第一次存图纸,递归中再存一次给:将图纸版本对象属性以及表单属性记录到图纸数据表中 ITKCALL(ifail = saveDrawing(tags[0], username)); } else { printf(">>>当前图纸:%s为加密图纸,不允许下发:%s \n", objName, classification); } //1.获取当前流程对象的bom行 //创建Window BOM_create_window(&windowTag); //设置顶层BOMline BOM_set_window_top_line(windowTag, itemTag, tags[0], NULLTAG, &topLineTag); throughAllBom(topLineTag, username); //关闭BOMwindow BOM_close_window(windowTag); MEM_free(classification); } else { printf("不满足要求:当前MSG包含的 %s 对象类型为:%s\n", objName, objType); } MEM_free(objName); MEM_free(objType); } MEM_free(tags); return ifail; } 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)); ITKCALL(ITEM_list_all_revs(itemTag, &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; } /* * 变更通知单自动下发 * @param msg 变更通知单的item_id * @param usernamev 下发用户名 * TODO 尚未释放内存 */ int DFL_CHANGE_TO_CAPP(char** c_sql_values, char* msg, char* usernamev) { printf("》》》开始执行变更单下发DFL_CHANGE_TO_CAPP方法,接受到入参MSG==%s,username==%s\n", msg, usernamev); int ifail = ITK_ok; tag_t item = NULLTAG; tag_t revTag = NULLTAG; char* changeno;//更改通知单号1 tag_t user;//申请人 char* username = NULL;//申请人名称 char* solution;//解决方案项 char* version;//解决方案项版本 char* name;//更改单名称/概要 char* address = (char*)MEM_alloc(1028 * sizeof(char));//变更单通知单物理文件地址 char* issuedtime = (char*)MEM_alloc(1028 * sizeof(char));//下发时间1 char* updatetime = (char*)MEM_alloc(1028 * sizeof(char));//更新时间1 int pdcount = 0; int count = 0; tag_t* pdtags = NULLTAG;//“解决方案”项下的图纸and物料版本对象 tag_t* dataset_tags = NULLTAG; char* origin_file_name = NULL, * ref_file_name = NULL, * ref_type = NULL, * dataset_name = NULL; int n_found; tag_t* ref_object = NULL; // 为年、月、日分配存储空间 char year[5]; // "yyyy" + null 终止符 char month[3]; // "MM" + null 终止符 char day[3]; // "dd" + null 终止符 char* ftp_ip = (char*)MEM_alloc(64 * sizeof(char)); char* ftp_user = (char*)MEM_alloc(64 * sizeof(char)); char* ftp_password = (char*)MEM_alloc(64 * sizeof(char)); // 1.获取变更通知单对象(变更单item_id获取对象) ITKCALL(ifail = ITEM_find_item(msg, &item)); if (item == NULLTAG) { printf(">>>提示:获取变更通知单对象失败!\n"); return ifail; } ITKCALL(ifail = AOM_ask_value_string(item, "item_id", &changeno)); ITKCALL(ifail = AOM_ask_value_tag(item, "owning_user", &user)); ITKCALL(ifail = AOM_ask_value_string(user, "user_name", &username)); ITKCALL(ifail = AOM_ask_value_string(item, "object_name", &name)); get_current_time(issuedtime); get_current_time(updatetime); //1.获取变更单下的最新发布版本-revTag ITKCALL(ifail = get_last_release_rev(item, &revTag)); if (revTag == NULLTAG) { printf(">>>获取变更单下的最新发布版本失败!\n 不存在已发布的变更单版本!\n"); return ifail; } //获取变更通知单物理文件 //提取年月日组件 extract_date_components(issuedtime, year, month, day); //处理“解决方案”文件夹下的图纸or物料,并获取BOM //获取“解决方案”项下的图纸and物料版本对象,并遍历处理(遍历处理到“叶子结点”时存入数据库) ITKCALL(ifail = AOM_ask_value_tags(revTag, "CMHasSolutionItem", &pdcount, &pdtags)); if (pdcount > 0) {//“解决方案”项下有版本对象 for (int i = 0; i < pdcount; i++) { printf("================“解决方案”项下有版本对象 \n"); tag_t revisionTag = NULLTAG; char* objType; char* objName; tag_t windowTag; tag_t itemTag; tag_t topLineTag; date_t publishDate; char* classification = NULL; //判断物料or图纸pdtags[i]; revisionTag = pdtags[i]; ITKCALL(ifail = AOM_ask_value_string(revisionTag, "object_type", &objType)); ITKCALL(ifail = AOM_ask_value_string(revisionTag, "object_name", &objName)); ITKCALL(ifail = AOM_ask_value_string(revisionTag, "item_id", &solution)); ITKCALL(ifail = AOM_ask_value_string(revisionTag, "item_revision_id", &version)); ITKCALL(ifail = ITEM_ask_item_of_rev(revisionTag, &itemTag)); printf("=========================>>>>>>>>解决方案下的当前版本对象为::%s\n", objType); if (stricmp(objType, "H8_wuliaoRevision") == 0) {//如果当前对象为:物料版本 printf("当前对象版本:%s为物料版本 \n", objName); if (revisionTag != NULLTAG) { savePart(revisionTag, usernamev); } BOM_create_window(&windowTag); BOM_set_window_top_line(windowTag, itemTag, revisionTag, NULLTAG, &topLineTag); throughAllBom(topLineTag, usernamev); BOM_close_window(windowTag); } else if (stricmp(objType, "H8_frockItemRevision") == 0 || stricmp(objType, "H8_drawingRevision") == 0 || stricmp(objType, "H8_frockItemRevision") == 0 || stricmp(objType, "H8_standardPartsRevision") == 0 || stricmp(objType, "H8_ComponentRevision") == 0) { printf("当前对象版本:%s为图纸版本 \n", objName); //校验发布状态,未发布则不执行并提示:当前版本未发布 AOM_ask_value_date(revisionTag, "date_released", &publishDate); if (publishDate.year == NULL) { printf("当前版本未发布,不执行 \n"); return ifail; } else { printf(">>>当前版本已发布,发布时间为: \n"); printf("Date: %04hd-%02hhd-%02hhd\n", publishDate.year, publishDate.month, publishDate.day); printf("Time: %02hhd:%02hhd:%02hhd\n", publishDate.hour, publishDate.minute, publishDate.second); } //判断图纸密级程度 ITKCALL(ifail = AOM_ask_value_string(revisionTag, "ip_classification", &classification)); if (stricmp(classification, "内部") == 0) { printf(">>>当前图纸为非密图纸,允许下发:%s \n", classification); ITKCALL(ifail = saveDrawing(revisionTag, usernamev)); } else { printf(">>>当前图纸为加密图纸,不允许下发:%s \n", classification); } //处理图纸对象的BOM BOM_create_window(&windowTag); BOM_set_window_top_line(windowTag, itemTag, revisionTag, NULLTAG, &topLineTag); throughAllBom(topLineTag, usernamev); BOM_close_window(windowTag); MEM_free(classification); } else { WriteLog(">>>当前对象版本:%s类型为:%s,不满足条件,请核查!\n", objName, objType); continue; } //============================ 3.保存(新增or更新)变更通知单信息到数据库表中 int outputValueCount, outputColumn; char*** result_values; char sql_cx[1024] = "\0"; sprintf(sql_cx, "select ADDRESS from WHBH_CAPP_CHANGE where solution='%s' and version='%s' ", solution, version); printf("提示:cxsql==%s\n", sql_cx); if (QuerySQLNoInputParam(sql_cx, &outputColumn, &outputValueCount, &result_values) == -1) { printf("提示:cxsql查询变更通知单信息失败\n"); return 1; } //--------------获取首选项中的FTP信息并与FTP建立连接---------------------------------------------------------------------------------------------------- //获取首选项中配置的连接FTP的IP地址、用户名、密码 int ftp_value_count = 0; char** ftp_option_values; //struct tm* lt2; ITKCALL(PREF_ask_char_values("BH_CAPP_FTP", &ftp_value_count, &ftp_option_values)); if (ftp_value_count != 3) { printf("首选项配置项错误:配置数量==%d,请核查!\n", ftp_value_count); return ifail; } printf("===>开始连接FTP服务器···"); //连接FTP服务器 HINTERNET hInternet = NULL, hFtpSession = NULL; hInternet = InternetOpenA(NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); hFtpSession = InternetConnectA(hInternet, ftp_option_values[0], INTERNET_DEFAULT_FTP_PORT, ftp_option_values[1], ftp_option_values[2], INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0); if (hFtpSession == NULL) { printf("连接FTP服务器失败\n"); } else { strcpy(ftp_ip, ftp_option_values[0]); strcpy(ftp_user, ftp_option_values[1]); strcpy(ftp_password, ftp_option_values[2]); printf("连接FTP服务器成功\n"); } if (outputValueCount == 0) {//不存在change原始数据 printf("提示:不存在变更通知单原始数据,新增变更通知单数据\n"); string Change_temp_path = "C:\\Change_temp\\"; string ftpFilePath = "/Change/"; ftpFilePath.append(year).append("/").append(month).append("/").append(day).append("/").append(changeno); strcpy(address, ftpFilePath.c_str());//存储地址 printf(">>>=================变更通知单:%s的物理文件地址address:%s,ftpFilePath:%s\n", changeno, address, ftpFilePath.c_str()); //准备数据集存放目录:存放数据集要根据是否存在原始数据进行更新或新增 //clearDir(Change_temp_path); ITKCALL(ifail = AOM_ask_value_tags(revTag, "IMAN_specification", &count, &dataset_tags)); if (count > 0) { printf(">>>变更通知单:%s的“更改引用项”下物理文件的个数:%d\n", changeno, count); DeleteLRDirectory(ftpFilePath.c_str()); //createFTPDir(hFtpSession, &ftpFilePath[0]); for (int t = 0; t < count; t++) { ITKCALL(AOM_ask_value_string(dataset_tags[t], "current_name", &origin_file_name)); ITKCALL(AE_ask_dataset_named_refs(dataset_tags[i], &n_found, &ref_object)); printf("提示:数据集名称==%s,引用文件数量==%d\n", origin_file_name, n_found); if (n_found > 0) { for (int i = 0; i < n_found;i++) { ITKCALL(AOM_ask_value_string(ref_object[i], "object_type", &ref_type)); printf("提示:当前引用文件类型==%s\n", ref_type); if (strcmp(ref_type, "ImanFile") == 0) { ITKCALL(AOM_ask_value_string(ref_object[i], "original_file_name", &ref_file_name)); if (ref_file_name != NULL && ref_file_name[0] != '\0') { string final_exportName = Change_temp_path; final_exportName.append(ref_file_name); //导出当前数据集下存在的引用文件到服务器目录下 ITKCALL(ifail = IMF_export_file(ref_object[i], final_exportName.c_str())); printf("=======OVER成功导出文件到本地缓存目录:%s======================== \n \n \n", final_exportName.c_str()); //参数2:原始文件路径,参数3:FTP服务器文件路径。两者都精确到具体的文件路径,形如:/Design/2022/01/25/000022-A/111.dwg string final_ftpFilePath = ftpFilePath; final_ftpFilePath.append("/").append(ref_file_name); string ip = ftp_ip; string user = ftp_user; string password = ftp_password; /*bool success = UploadFileToFtp(final_exportName, ftpFilePath.append("/"), ip, user, password);*/ bool success = uploadFileToMinIO(final_exportName, final_ftpFilePath); if (success) { printf("提示:FTP上传成功==%s\n", ftpFilePath.c_str()); } else { printf("提示:FTP上传失败==%s\n", ftpFilePath.c_str()); } } } else { printf("提示:数据集[%s]下ImanFile类型的引用文件中不存在origin_file_name属性,获取引用文件名失败!不导出文件\n", origin_file_name); } } } } MEM_free(ftp_password); MEM_free(ftp_user); MEM_free(ftp_ip); } //clearDir(Change_temp_path); printf(">>>变更通知单导出完成!!!\n"); //插入数据 printf("提示:当前变更单不存在原始数据,开始插入\n"); char sql_insert_change[1024] = "\0"; sprintf(sql_insert_change, "insert into WHBH_CAPP_CHANGE(changeno,username,solution,version,name,address,issuedtime,updatetime) values('%s','%s','%s','%s','%s','%s','%s','%s')", changeno, username, solution, version, name, address, issuedtime, updatetime); printf("提示:sql_insert_change==%s\n", sql_insert_change); if (ExecuteSQLNoInputParam(sql_insert_change) == -1) { printf("提示:sql_insert_change数据插入 失败, %s \n", sql_insert_change); return 1; } else { ExecuteSQLNoInputParam("commit"); } } else { printf("提示:存在变更通知单原始数据,更新变更通知单原始数据\n"); //准备数据集存放目录:存放数据集要根据是否存在原始数据进行更新或新增 string ftp_file_path = result_values[0][0]; string Change_temp_path = "C:\\Change_temp\\"; printf("============>更新变更单物理文件的存放路径为:%s \n", result_values[0][0]); clearDir(Change_temp_path); ITKCALL(ifail = AOM_ask_value_tags(revTag, "IMAN_specification", &count, &dataset_tags)); if (count > 0) { printf(">>>变更通知单:%s的“更改引用项”下物理文件的个数:%d\n", changeno, count); // 清空ftp上的ftpExportName目录下的所有文件,为下面循环遍历取得数据集存放做准备 DeleteLRDirectory(ftp_file_path.c_str()); //在FTP上提前创建存放数据集文件的文件夹,ftpFilePath路径形如:/Design/2022/01/25/000022-A/ ftp_file_path.append("/"); //ITKCALL(ifail = createFTPDir(hFtpSession, &ftp_file_path[0])); for (int t = 0; t < count; t++) { ITKCALL(AOM_ask_value_string(dataset_tags[t], "current_name", &dataset_name)); ITKCALL(AE_ask_dataset_named_refs(dataset_tags[i], &n_found, &ref_object)); printf("提示:数据集名称==%s,引用文件数量==%d\n", dataset_name, n_found); if (n_found > 0) { for (int i = 0; i < n_found;i++) { ITKCALL(AOM_ask_value_string(ref_object[i], "object_type", &ref_type)); //ITKCALL(AOM_ask_value_string(ref_object[i], "file_size", &file_size)); printf("提示:当前引用文件类型==%s\n", ref_type); if (strcmp(ref_type, "ImanFile") == 0) { ITKCALL(AOM_ask_value_string(ref_object[i], "original_file_name", &ref_file_name)); if (ref_file_name != NULL && ref_file_name[0] != '\0') { string final_change_temp_path = Change_temp_path; final_change_temp_path.append(ref_file_name); //导出当前数据集下存在的引用文件到服务器目录下 ITKCALL(ifail = IMF_export_file(ref_object[i], final_change_temp_path.c_str())); printf("=======OVER成功导出文件到本地缓存目录:%s======================== \n \n \n", final_change_temp_path.c_str()); string ftpFilePath = ftp_file_path; ftpFilePath.append(ref_file_name); string ip = ftp_ip; string user = ftp_user; string password = ftp_password; /*bool success = UploadFileToFtp(final_change_temp_path, ftp_file_path, ip, user, password);*/ bool success = uploadFileToMinIO(final_change_temp_path, ftpFilePath); if (success) { printf("提示:FTP上传成功==%s\n", ftpFilePath.c_str()); } else { printf("提示:FTP上传失败==%s\n", ftpFilePath.c_str()); } } else { printf("提示:数据集:【%s】下的引用文件[%d]不存在“original_file_name”属性,获取引用文件名称失败,无法导出文件\n", origin_file_name,i); } } } } } MEM_free(ftp_password); MEM_free(ftp_user); MEM_free(ftp_ip); } //clearDir(Change_temp_path); printf(">>>变更通知单导出完成!!!\n"); //更新数据 printf("提示:当前变更单存在原始数据,开始更新\n"); char sql_update_change[1024] = "\0"; sprintf(sql_update_change, "update WHBH_CAPP_CHANGE set changeno = '%s',username = '%s',name = '%s',updatetime = '%s' where solution = '%s' and version = '%s'", changeno, username, name, updatetime, solution, version); printf("提示:sql_update_change==%s\n", sql_update_change); if (ExecuteSQLNoInputParam(sql_update_change) == -1) { printf("提示:sql_update_change数据插入 失败, %s \n", sql_update_change); return 1; } else { ExecuteSQLNoInputParam("commit"); } } MEM_free(version); MEM_free(solution); MEM_free(objName); MEM_free(objType); cout << "Closing FTP Session" << endl; InternetCloseHandle(hFtpSession); cout << "Closing connection" << endl; InternetCloseHandle(hInternet); // Close hInternet } } MEM_free(ref_file_name); MEM_free(ref_type); MEM_free(ref_object); MEM_free(dataset_name); MEM_free(dataset_tags); MEM_free(pdtags); MEM_free(name); MEM_free(username); MEM_free(changeno); CloseLog(); return ifail; } int ITK_user_main(int argc, char* argv[]) { char* log_file = NULL; printf("创建日志文件\n"); char log_path[128] = "C:\\Temp\\KUMA_LOG.txt"; CreateLogFile(log_path, &log_file); int ifail = ITK_ok; int len; int outputValueCount; char* pbuf = NULL; char* tc_name, * tc_pwd, * tc_group; int c_sql_value_count = 0; char** option_values = NULL; tc_name = ITK_ask_cli_argument("-u="); tc_pwd = ITK_ask_cli_argument("-p="); tc_group = ITK_ask_cli_argument("-g="); const char* flowuid = NULL; const char* msg = NULL; const char* user_id = NULL; char* msgv = NULL; char*** flowUID_values = NULL; char*** taskSource_values = NULL; char*** outputValue = NULL; int countResultNum; char* connIP = (char*)MEM_alloc(32 * sizeof(char)); printf("name= %s\n", tc_name); printf("pwd= %s\n", tc_pwd); printf("group= %s\n", tc_group); ifail = TC_init_module(tc_name, tc_pwd, tc_group);//初始化 Integration Tool Kit (ITK),并同时登录到 POM。 if (ifail != ITK_ok) { printf("login fail! \n"); return ifail; } else{ printf("login>>>>> \n"); } //获取首选项的值:连接数据库的参数 ITKCALL(PREF_ask_char_values("BH_CAPP_Oracle", &c_sql_value_count, &option_values)); if (c_sql_value_count != 4) { printf("BH_CAPP_Oracle 首选项配置异常!\n"); /*ITK_exit_module(true); return ifail;*/ } else { //组织连接数据库的ip和服务名 strcpy(connIP, option_values[0]); strcat(connIP, "/"); strcat(connIP, option_values[1]); WriteLog("连接数据库的IP和端口为:%s\n", connIP); printf("===================================\n"); printf("get flowUID begin\n"); printf("===================================\n"); int outputColumn = 0; POM_AM__set_application_bypass(true); if (ConnServer(option_values[2], option_values[3], connIP))//"tc11","infodba","//172.16.50.40/tc11" "TC12","infodba","172.16.68.13/tc1" { printf("Info: Failed to access the data table\n"); } else { //连接数据库成功时 printf("Info: The data table is accessed successfully\n"); //查询本次下发的(未完成Task的)来源 char sql_getSource[1024] = "\0"; sprintf(sql_getSource, "select TASKSOURCE,FLOWID,MSG from WHBH_CAPP_TASK where status = '未开始' ORDER BY code DESC"); printf("Info:sql_getSource==%s\n", sql_getSource); int outputColumnS = 0; int outputValueCountS = 0; if (QuerySQLNoInputParam(sql_getSource, &outputColumnS, &outputValueCountS, &taskSource_values) == -1) { printf("Info: 查询TASKSOURCE任务来源失败. %s \n", sql_getSource); } else { if (outputValueCountS <= 0) { printf("Info:未查到任何待处理的任务!\n"); } else { printf("Info: 查询任务来源成功!\n"); for (int t = 0; t < outputValueCountS; t++) { printf("taskSource_values[%d][0]=%s\n", t, taskSource_values[t][0]); if (stricmp(taskSource_values[t][0], "工作流程") == 0) { WriteLog("Info:查询结果依次为任务来源 = %s,流程ID = %s,MSG = %s \n", taskSource_values[t][0], taskSource_values[t][1], taskSource_values[t][2]); if (strlen(taskSource_values[t][2]) != 0) { //自动下发=》存在msg=》说明是:变更通知单自动下发(因为只有变更通知单的任务来源为“工作流程”但存在msg) WriteLog("Info:当前异步任务存在流程ID==%s和MSG==%s,任务来源:变更通知单自动下发!\n", taskSource_values[t][1], taskSource_values[t][2]); msgv = taskSource_values[t][2]; if (msgv == NULL || strlen(taskSource_values[t][2]) == 0) { printf("》》》ERROR变更通知单数据异常:Task表中的msg为空,无法下发!请核查%s流程数据\n", taskSource_values[t][1]); } else { //查询下发发起人作为参数和msg中携带的变更通知单id一起传递给下发函数 char sql_getUser[1024] = "\0"; sprintf(sql_getUser, "select username from WHBH_CAPP_TASK where msg = '%s'", msgv); printf("Info:sql_getUser==%s\n", sql_getUser); int outputValueCountU = 0; int outputColumnU = 0; char*** username_values = NULL; if (QuerySQLNoInputParam(sql_getUser, &outputColumnU, &outputValueCountU, &username_values) == -1) { printf("Info: 查询用户名失败. %s \n", sql_getUser); }else { if (outputValueCountU <= 0) { printf("Info:当前变更通知单Task:%s不存在username!\n", msgv); } else { char* username = username_values[0][0]; printf("Info:当前变更通知单:%s的username是:%s!\n开始执行下发逻辑···", msgv, username); ITKCALL(ifail = DFL_CHANGE_TO_CAPP(option_values, msgv, username)); //下发完成,更新状态为已完成 //---------------------------------------------------------根据msg更新状态和完成时间---------------------------- char* currentTime = (char*)MEM_alloc(1028 * sizeof(char)); get_current_time(currentTime); char sql_changeStatus[1024] = "\0"; sprintf(sql_changeStatus, "update WHBH_CAPP_TASK set STATUS='%s',ENDINGTIME='%s' where MSG='%s'", "已完成", currentTime, msgv); printf("提示:sql_changeStatus==%s \n", sql_changeStatus); if (ExecuteSQLNoInputParam(sql_changeStatus) == -1) { printf("》》》异常提示:更新流程状态失败!sql_changeStatus == %s\n", sql_changeStatus); } else { printf("》》》提示:更新流程状态成功!sql_changeStatus == %s\n", sql_changeStatus); ExecuteSQLNoInputParam("commit"); } } } } } else {//自动下发,但不存在msg,说明是:图纸or物料自动下发 flowuid = taskSource_values[t][1]; char* currentTime = (char*)MEM_alloc(1028 * sizeof(char)); printf("开始处理未完成状态的流程-flowUID is:%s\n", flowuid); char sql_getUser[1024] = "\0"; sprintf(sql_getUser, "select username from WHBH_CAPP_TASK where flowid = '%s'", flowuid); printf("Info:sql_getUser==%s\n", sql_getUser); int outputValueCountU = 0; int outputColumnU = 0; char*** username_values = NULL; if (QuerySQLNoInputParam(sql_getUser, &outputColumnU, &outputValueCountU, &username_values) == -1) { printf("Info: 查询用户名失败. %s \n", sql_getUser); } else { if (outputValueCountU <= 0) { printf("Info:当前流程:%s不存在username!\n", flowuid); } else { char* username = username_values[0][0]; printf("Info:当前流程:%s的username是:%s\n", flowuid, username); ITKCALL(ifail = DFL_WL_TO_CAPP(option_values, flowuid, username)); //下发完成,更新状态为已完成 printf("》》》处理未完成状态的流程-flowUID is:%s 结束\n", flowuid); ITKCALL(ifail = setAttrForTask(flowuid, "STATUS", "已完成")); get_current_time(currentTime); ITKCALL(ifail = setAttrForTask(flowuid, "ENDINGTIME", currentTime)); } } } } else if (stricmp(taskSource_values[t][0], "手动下发") == 0) { printf("》》》任务类型:手动下发"); //1.查询数据,获取手动下发的未完成任务中的MSG msg = taskSource_values[t][2]; printf("》》》手动下发的未完成任务中的MSG是:%s\n", msg); char sql_getUser[1024] = "\0"; sprintf(sql_getUser, "select username from WHBH_CAPP_TASK where msg = '%s'", msg); printf("Info:sql_getUser==%s\n", sql_getUser); int outputValueCountU = 0; int outputColumnU = 0; char*** username_values = NULL; if (QuerySQLNoInputParam(sql_getUser, &outputColumnU, &outputValueCountU, &username_values) == -1) { printf("Info: 查询用户名失败. %s \n", sql_getUser); }else { if (outputValueCountU <= 0) { printf("Info:当前流程:%s不存在username!\n", flowuid); } else { char* username = username_values[0][0]; ITKCALL(ifail = SD_TO_CAPP(msg, username)); //---------------------------------------------------------根据msg更新状态和完成时间---------------------------- char* currentTime = (char*)MEM_alloc(1028 * sizeof(char)); get_current_time(currentTime); char sql_changeStatus[1024] = "\0"; sprintf(sql_changeStatus, "update WHBH_CAPP_TASK set STATUS='%s',ENDINGTIME='%s' where MSG='%s'", "已完成", currentTime, msg); printf("提示:sql_changeStatus==%s \n", sql_changeStatus); if (ExecuteSQLNoInputParam(sql_changeStatus) == -1) { printf("》》》异常提示:更新流程状态失败!sql_changeStatus == %s\n", sql_changeStatus); } else { printf("》》》提示:更新流程状态成功!sql_changeStatus == %s\n", sql_changeStatus); ExecuteSQLNoInputParam("commit"); } MEM_free(currentTime); } } } else { printf("当前任务来源异常:%s,无法执行下发操作!\n", taskSource_values[t][0]); } } MEM_free(option_values); } } } DisConnServer(); POM_AM__set_application_bypass(false); } ITK_exit_module(true); return ifail; }