You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2486 lines
89 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <iostream>
#include <vector>
#include "dfl_custom.h"
//#include "ocilib.h"
#include <unidefs.h>
#include <tc/preferences.h>
#include <ics/ics.h>
#include <ics/ics2.h>
#include <tc/tc_macros.h>
#include <tccore/aom_prop.h>
#include <tccore/aom.h>
#include <time.h>
#include <base_utils/TcResultStatus.hxx>
#include <base_utils/IFail.hxx>
#include "corecrt_io.h"
#include "direct.h"
#include <ae/ae.h>
#include <wininet.h>
#pragma comment(lib, "Wininet")
#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING
#include <experimental\filesystem>
#pragma comment(lib, "ws2_32.lib")
#include <iostream>
using namespace std;
#include <ctime>
#include <fclasses/tc_date.h>
#include "cJSON.h"
#include <curl\curl.h>
#include <sstream>
#include <iostream>
#include "common_itk_util.h"
//#include "dfl_custom.h"
//#include "util.h"
//#include <ics/ics2.h>
#include "ocilib.h"
//using namespace std;
#include <string>
#include <cstdio>
#include <filesystem>
#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 <iostream>
#include <fstream>
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 <aws/s3/model/ListObjectsRequest.h>
#include <iomanip>
//#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<const unsigned char*>(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<const unsigned char*>(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<std::string> 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<string>& 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==%susername==%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==%susername==%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原始文件路径参数3FTP服务器文件路径。两者都精确到具体的文件路径形如/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;
}