新增:伙伴云API对接 控制器

This commit is contained in:
2025-12-15 08:51:00 +08:00
parent 4230fa4d27
commit b3520ee98e
8 changed files with 1610 additions and 123 deletions

View File

@@ -0,0 +1,660 @@
using Common;
using LinqToDB.Common;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NPOI.SS.Formula.Functions;
using RestSharp;
using System.Collections;
using static NPOI.HSSF.UserModel.HeaderFooter;
using MySql.Data.MySqlClient;
using System.Data;
using BLW_Log.Models;
namespace BLW_Log.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class HuobanController : ControllerBase
{
private readonly string baseUrl = "https://api.huoban.com/";
private readonly string API_Key = "FIQBLpReK6nAJ0CzYOxmNgKtEpa0cApctanSZyGW";
private readonly List<string> TblSPHeader = ["审批状态", "报备编号", "项目名称", "客房数量", "所属客户", "负责人", "流程结束时间"];
/// <summary>
/// 创建返回结果的辅助方法
/// </summary>
/// <param name="isSuccess">是否成功</param>
/// <param name="message">返回消息</param>
/// <param name="statusCode">状态码</param>
/// <param name="data">返回数据</param>
/// <returns>ReturnInfo对象</returns>
private ReturnInfo CreateResult(bool isSuccess, string message, int statusCode, object? data = null)
{
return new ReturnInfo
{
isok = isSuccess,
message = message,
status = statusCode,
response = data
};
}
/// <summary>
/// 获取工作区ID内部方法
/// </summary>
/// <returns>工作区ID</returns>
private string GetHuobanSpaceList()
{
try
{
// 创建 REST 客户端
var options = new RestClientOptions(baseUrl);
var client = new RestClient(options);
// 创建请求
var request = new RestRequest("openapi/v1/space/list", Method.Get);
// 添加授权头
request.AddHeader("Open-Authorization", $"Bearer {API_Key}");
// 执行请求
var response = client.Execute(request);
string space_id = "";
if (response.IsSuccessful)
{
// 解析响应内容
var responseData = JsonConvert.DeserializeObject<dynamic>(response.Content);
foreach (var item in responseData.data.spaces)
{
if (item.name == "宝来威智能(广东)有限公司")
{
space_id = item.space_id;
break;
}
}
}
return space_id;
}
catch (Exception ex)
{
return "";
}
}
/// <summary>
/// 获取"项目报备"表格ID
/// </summary>
/// <param name="space_id">工作区ID</param>
/// <returns>表格ID</returns>
private string GetProjectReportTableId(string space_id)
{
try
{
// 创建 REST 客户端
var options = new RestClientOptions(baseUrl);
var client = new RestClient(options);
// 创建请求
var request = new RestRequest("openapi/v1/table/list", Method.Post);
// 添加授权头
request.AddHeader("Open-Authorization", $"Bearer {API_Key}");
request.AddHeader("Content-Type", "application/json");
// 添加请求体
var requestBody = new { space_id };
request.AddJsonBody(requestBody);
// 执行请求
var response = client.Execute(request);
if (response.IsSuccessful)
{
// 解析响应内容
var responseData = JsonConvert.DeserializeObject<dynamic>(response.Content);
string table_id = "";
foreach (var item in responseData.data.tables)
{
if (item.name == "项目报备")
{
table_id = item.table_id;
break;
}
}
return table_id;
}
else
{
return "";
}
}
catch (Exception ex)
{
return "";
}
}
/// <summary>
/// 获取"项目报备"表格表头
/// </summary>
/// <param name="space_id">工作区ID</param>
/// <returns>表格ID</returns>
private Dictionary<string, string> GetProjectReportTableHeader(string table_id)
{
try
{
// 创建 REST 客户端
var options = new RestClientOptions(baseUrl);
var client = new RestClient(options);
// 创建请求
var request = new RestRequest($"openapi/v1/table/{table_id}", Method.Post);
// 添加授权头
request.AddHeader("Open-Authorization", $"Bearer {API_Key}");
request.AddHeader("Content-Type", "application/json");
// 执行请求
var response = client.Execute(request);
if (response.IsSuccessful)
{
Dictionary<string, string> tabelHeader = [];
// 解析响应内容
var responseData = JsonConvert.DeserializeObject<TblRoot>(response.Content);
var dic = responseData.data.table.fields;
foreach (dynamic item in dic)
{
if (TblSPHeader.Contains(Convert.ToString(item.name)))
{
tabelHeader.Add(item.field_id.ToString(), item.name.ToString());
}
}
return tabelHeader;
}
else
{
return [];
}
}
catch (Exception ex)
{
return [];
}
}
/// <summary>
/// 查询"项目报备"数据列表
/// </summary>
/// <param name="table_id">表格ID</param>
/// <returns>数据列表</returns>
private dynamic QueryProjectReportData(string table_id, Dictionary<string, string> TblHeader, int limit = 5, int offset = 0)
{
try
{
// 创建 REST 客户端
var options = new RestClientOptions(baseUrl);
var client = new RestClient(options);
// 创建请求
var request = new RestRequest("openapi/v1/item/list", Method.Post);
// 添加授权头
request.AddHeader("Open-Authorization", $"Bearer {API_Key}");
request.AddHeader("Content-Type", "application/json");
// 构建请求体
var requestBody = new
{
table_id,
filter = new
{
and = new ArrayList
{
new
{
field = "2200000565424395",
query = new
{
eq = new List<string> { "2" }
}
}
}
},
order = new
{
field_id = "2200000565427086",
type = "desc"
},
limit = limit,
offset = offset,
with_field_config = 0
};
request.AddJsonBody(requestBody);
// 执行请求
var response = client.Execute(request);
if (response.IsSuccessful)
{
// 解析响应内容
TblListRoot resp = JsonConvert.DeserializeObject<TblListRoot>(response.Content);
TblListData responseData = resp.data;
var rs = new
{
total = responseData.total,
filtered = responseData.filtered,
hasMore = responseData.has_more,
fields = GetItemsListDic(TblHeader, responseData.items)
};
return rs;
}
else
{
return null;
}
}
catch (Exception ex)
{
return ex.Message;
}
}
/// <summary>
/// 获取元素列表
/// </summary>
private List<TblProject> GetItemsListDic(Dictionary<string, string> TblHeader, List<TblListItem> itemList)
{
List<TblProject> res = [];
try
{
foreach (var item in itemList)
{
TblProject pro = new();
var fls = item.fields;
bool isPass = true;
foreach (var flsitem in fls)
{
if (!TblHeader.ContainsKey(flsitem.Key))
{
continue;
}
if (TblHeader[flsitem.Key].Equals("审批状态"))
{
try
{
var t = Convert.ToString(fls[flsitem.Key][0].name);
if (t != "已通过")
{
isPass = false;
}
}
catch
{
isPass = false;
}
}
if (TblHeader[flsitem.Key].Equals("报备编号"))
{
pro.guid = Convert.ToString(fls[flsitem.Key]);
pro.report_id = Convert.ToString(fls[flsitem.Key]);
}
if (TblHeader[flsitem.Key].Equals("项目名称"))
{
pro.hotel_name = Convert.ToString(fls[flsitem.Key]);
}
if (TblHeader[flsitem.Key].Equals("客房数量"))
{
pro.remarks += "_" + Convert.ToString(fls[flsitem.Key]) + "间客房";
}
if (TblHeader[flsitem.Key].Equals("负责人"))
{
pro.creator = Convert.ToString(fls[flsitem.Key][0].name);
}
if (TblHeader[flsitem.Key].Equals("所属客户"))
{
try
{
pro.remarks += "_" + Convert.ToString(fls[flsitem.Key][0].title);
}
catch { }
}
if (TblHeader[flsitem.Key].Equals("流程结束时间"))
{
try
{
pro.created_at = Convert.ToDateTime(fls[flsitem.Key]);
}
catch { }
}
}
if (isPass && !string.IsNullOrEmpty(pro.hotel_name))
{
pro.remarks = pro.remarks.StartsWith('_') ? pro.remarks[1..] : pro.remarks;
res.Add(pro);
}
}
}
catch (Exception ex)
{
// 异常处理
Console.WriteLine(ex.StackTrace + ex.Message);
}
return res;
}
/// <summary>
/// 获取"项目报备"表中所有数据
/// </summary>
/// <returns>所有数据列表</returns>
[HttpPost]
public ReturnInfo GetAllProjectReportData()
{
try
{
// 1. 获取工作区ID
string space_id = GetHuobanSpaceList();
// 参数验证检查工作区ID是否为空
if (string.IsNullOrEmpty(space_id))
{
return CreateResult(false, "获取工作区ID失败", 400, null);
}
// 2. 获取"项目报备"表格ID
string table_id = GetProjectReportTableId(space_id);
// 参数验证检查表格ID是否为空
if (string.IsNullOrEmpty(table_id))
{
return CreateResult(false, "获取表格ID失败", 400, null);
}
// 3. 获取"项目报备"表格ID
var tableHeader = GetProjectReportTableHeader(table_id);
// 参数验证:检查表格表头是否为空
if (tableHeader.Count <= 0)
{
return CreateResult(false, "获取表格表头失败", 400, null);
}
int limit = 20;
int offset = 0;
bool stopFetching = false;
int totalAdded = 0;
List<TblProject> allItems = new List<TblProject>();
while (!stopFetching)
{
// 4. 查询"项目报备"数据列表
dynamic data = QueryProjectReportData(table_id, tableHeader, limit, offset);
// 结果验证:检查数据是否获取成功
if (data == null)
{
return CreateResult(false, "获取数据失败", 500, null);
}
List<TblProject> items = data.fields;
if (items == null || items.Count == 0) break;
foreach (var item in items)
{
if (CheckProjectExists(item.report_id))
{
stopFetching = true;
break;
}
// Insert
WebProjectAdd(item);
totalAdded++;
//allItems.Add(item);
}
if (stopFetching) break;
if ((bool)data.hasMore == false) break;
offset += limit;
}
// 4. 返回成功结果
return CreateResult(true, $"同步完成,新增 {totalAdded} 条记录", 200/*, allItems*/);
}
catch (Exception ex)
{
// 异常处理:返回包含异常信息的错误结果
return CreateResult(false, $"发生异常: {ex.Message}", 500, ex.ToString());
}
}
#region
/// <summary>
/// 检查项目是否存在
/// </summary>
private bool CheckProjectExists(string report_id)
{
string sql = "SELECT count(1) as count FROM `cdr_library`.`tbl_web_project` WHERE report_id = @report_id AND is_valid = 1";
var parameters = new[] { new MySqlParameter("@report_id", report_id) };
var res = ExecuteQuery(sql, parameters);
if (res.isok && res.response != null)
{
try
{
var json = JArray.Parse(res.response.ToString());
if (json.Count > 0 && json[0]["count"] != null)
{
return Convert.ToInt32(json[0]["count"]) > 0;
}
}
catch { }
}
return false;
}
/// <summary>
/// 添加项目到数据库
/// </summary>
private ReturnInfo WebProjectAdd(TblProject project)
{
string sql = @"
INSERT INTO `cdr_library`.`tbl_web_project`
(report_id, hotel_name, room_type_count, room_data_json, remarks, creator, created_at, is_valid, guid)
VALUES (@report_id, @hotel_name, @room_type_count, @room_data_json, @remarks, @creator, @created_at, 1, @guid)";
var parameters = new[]
{
new MySqlParameter("@report_id", project.report_id ?? (object)DBNull.Value),
new MySqlParameter("@hotel_name", project.hotel_name ?? (object)DBNull.Value),
new MySqlParameter("@room_type_count", project.room_type_count),
new MySqlParameter("@room_data_json", project.room_data_json ?? (object)DBNull.Value),
new MySqlParameter("@remarks", project.remarks ?? (object)DBNull.Value),
new MySqlParameter("@creator", project.creator ?? (object)DBNull.Value),
new MySqlParameter("@created_at", project.created_at),
new MySqlParameter("@guid", project.guid ?? Guid.NewGuid().ToString("N"))
};
return ExecuteNonQueryWithGuid(sql, parameters);
}
/// <summary>
/// 通用查询执行方法(参数化版本)
/// </summary>
private ReturnInfo ExecuteQuery(string sql, MySqlParameter[] parameters = null)
{
try
{
using var conn = new MySqlConnection(ReadConfig.Instance.MySQLConnectionString);
conn.Open();
using var cmd = new MySqlCommand(sql, conn);
if (parameters != null)
{
cmd.Parameters.AddRange(parameters);
}
using var adapter = new MySqlDataAdapter(cmd);
var ds = new DataSet();
adapter.Fill(ds);
if (ds.Tables.Count == 0 || ds.Tables[0].Rows.Count == 0)
{
return new ReturnInfo
{
isok = true,
message = "查询成功,但未返回数据",
status = 200,
response = null
};
}
return new ReturnInfo
{
isok = true,
message = "查询成功",
status = 200,
response = Newtonsoft.Json.JsonConvert.SerializeObject(ds.Tables[0])
};
}
catch (Exception ex)
{
return new ReturnInfo
{
isok = false,
message = ex.Message,
status = 500,
response = null
};
}
}
/// <summary>
/// 通用增删改执行方法参数化版本返回GUID
/// </summary>
private ReturnInfo ExecuteNonQueryWithGuid(string sql, MySqlParameter[] parameters, string guid = null)
{
try
{
using var conn = new MySqlConnection(ReadConfig.Instance.MySQLConnectionString);
conn.Open();
using var cmd = new MySqlCommand(sql, conn);
if (parameters != null)
{
cmd.Parameters.AddRange(parameters);
}
int affectedRows = cmd.ExecuteNonQuery();
if (affectedRows > 0)
{
return new ReturnInfo
{
isok = true,
message = "操作成功",
status = 200,
response = guid ?? GetGuidFromParameters(parameters) ?? "操作完成"
};
}
return new ReturnInfo
{
isok = false,
message = "操作未影响任何数据",
status = 400,
response = null
};
}
catch (Exception ex)
{
return new ReturnInfo
{
isok = false,
message = ex.Message,
status = 500,
response = null
};
}
}
/// <summary>
/// 从参数中提取GUID值
/// </summary>
private string GetGuidFromParameters(MySqlParameter[] parameters)
{
if (parameters == null) return null;
var guidParam = parameters.FirstOrDefault(p => p.ParameterName == "@guid");
return guidParam?.Value?.ToString();
}
#endregion
}
public class TblRoot
{
public int code { get; set; }
public string message { get; set; }
public TblData data { get; set; }
}
public class TblData
{
public TblHeader table { get; set; }
}
public class TblHeader
{
public string table_id { get; set; }
public string name { get; set; }
public string alias { get; set; }
public string space_id { get; set; }
public string created_on { get; set; }
public List<dynamic> fields { get; set; }
}
public class TblListRoot
{
public int code { get; set; }
public string message { get; set; }
public TblListData data { get; set; }
public object meta { get; set; }
}
public class TblListData
{
public int total { get; set; }
public int filtered { get; set; }
public bool has_more { get; set; }
public List<TblListItem> items { get; set; }
}
public class TblListItem
{
public string item_id { get; set; }
public string title { get; set; }
public Dictionary<string, dynamic> fields { get; set; }
public object created_by { get; set; }
public string created_on { get; set; }
public object updated_by { get; set; }
public string updated_on { get; set; }
}
public class TblProject
{
public string report_id { get; set; }
public string hotel_name { get; set; }
public int room_type_count { get; set; }
public string room_data_json { get; set; }
public string? remarks { get; set; }
public string creator { get; set; }
public DateTime created_at { get; set; }
public bool is_valid { get; set; }
public string? guid { get; set; }
public TblProject()
{
this.is_valid = true;
this.room_type_count = 1;
this.room_data_json = "[]";
}
}
}

View File

@@ -1,10 +1,18 @@
using BLW_Log.Models;
using Common;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using MySql.Data.MySqlClient;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Org.BouncyCastle.Asn1.Ocsp;
using System.Data;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
namespace BLW_Log.Controllers
{
@@ -13,10 +21,14 @@ namespace BLW_Log.Controllers
public class PanelSelectionController : ControllerBase
{
public readonly IMemoryCache _memoryCache;
public PanelSelectionController(IMemoryCache memoryCache)
private readonly IWebHostEnvironment _webHostEnvironment;
public PanelSelectionController(IMemoryCache memoryCache, IWebHostEnvironment webHostEnvironment)
{
this._memoryCache = memoryCache;
this._webHostEnvironment = webHostEnvironment;
}
#region
/// <summary>
/// 查看预览图
@@ -26,8 +38,24 @@ namespace BLW_Log.Controllers
{
try
{
const string noticeId = "CellCorelDRAW";
CSRedisCacheHelper.Publish(noticeId, Newtonsoft.Json.JsonConvert.SerializeObject(request));
// 记录日志
LogOperation(request.User, "SendToCDR", request.ProjectName, request.PictureNum, request);
bool success = PublishToRedis(new RedisInfo
{
Type = "CellCorelDRAW",
ObjToRedis = new CellCorelDRAW() { MsgType = 1, MsgNode = request }
});
if (!success)
{
return new ReturnInfo
{
isok = false,
message = "发送到Redis失败",
status = 500,
response = null
};
}
DateTime startTime = DateTime.Now;
Dictionary<string, string> pcn = new()
@@ -57,6 +85,7 @@ namespace BLW_Log.Controllers
}
}
#endregion
#region
@@ -100,7 +129,7 @@ namespace BLW_Log.Controllers
else
{
var rs = ExecuteQuery("SELECT * FROM `cdr_library`.`tbl_cdr_file`");
_memoryCache.Set(key, rs, TimeSpan.FromHours(1));
_memoryCache.Set(key, rs, TimeSpan.FromMinutes(2));
return rs;
}
}
@@ -119,7 +148,7 @@ namespace BLW_Log.Controllers
else
{
var rs = ExecuteQuery("SELECT * FROM `cdr_library`.`tbl_cdr_file` WHERE PreviewPath IS NULL");
_memoryCache.Set(key, rs, TimeSpan.FromHours(1));
_memoryCache.Set(key, rs, TimeSpan.FromMinutes(2));
return rs;
}
@@ -140,7 +169,7 @@ namespace BLW_Log.Controllers
else
{
var rs = ExecuteQuery($@"SELECT DISTINCT f.* FROM `cdr_library`.`tbl_cdr_file` f INNER JOIN `cdr_library`.`tbl_iconlibrary` i ON f.ID = i.FID WHERE i.IconType = 1 AND f.PreviewPath IS NULL");
_memoryCache.Set(key, rs, TimeSpan.FromHours(1));
_memoryCache.Set(key, rs, TimeSpan.FromMinutes(2));
return rs;
}
@@ -162,7 +191,7 @@ namespace BLW_Log.Controllers
else
{
var rs = ExecuteQuery($"SELECT * FROM `cdr_library`.`tbl_model` WHERE FID = {Info.FID}");
_memoryCache.Set(key, rs, TimeSpan.FromHours(1));
_memoryCache.Set(key, rs, TimeSpan.FromMinutes(2));
return rs;
}
}
@@ -188,7 +217,7 @@ namespace BLW_Log.Controllers
else
{
var rs = ExecuteQuery($"SELECT * FROM `cdr_library`.`tbl_pattern` WHERE FID = {Info.FID}");
_memoryCache.Set(key, rs, TimeSpan.FromHours(1));
_memoryCache.Set(key, rs, TimeSpan.FromMinutes(2));
return rs;
}
}
@@ -215,7 +244,7 @@ namespace BLW_Log.Controllers
else
{
var rs = ExecuteQuery($"SELECT * FROM `cdr_library`.`tbl_trench` WHERE MID = {Info.MID}");
_memoryCache.Set(key, rs, TimeSpan.FromHours(1));
_memoryCache.Set(key, rs, TimeSpan.FromMinutes(2));
return rs;
}
}
@@ -236,7 +265,7 @@ namespace BLW_Log.Controllers
else
{
var rs = ExecuteQuery($"SELECT * FROM `cdr_library`.`tbl_location` WHERE PID = {Info.PID}");
_memoryCache.Set(key, rs, TimeSpan.FromHours(1));
_memoryCache.Set(key, rs, TimeSpan.FromMinutes(2));
return rs;
}
}
@@ -257,7 +286,7 @@ namespace BLW_Log.Controllers
else
{
var rs = ExecuteQuery($"SELECT * FROM `cdr_library`.`tbl_iconlibrary` WHERE IconType = 1");
_memoryCache.Set(key, rs, TimeSpan.FromHours(1));
_memoryCache.Set(key, rs, TimeSpan.FromMinutes(2));
return rs;
}
}
@@ -277,7 +306,7 @@ namespace BLW_Log.Controllers
else
{
var rs = ExecuteQuery($"SELECT * FROM `cdr_library`.`tbl_iconlibrary` WHERE IconType = 2");
_memoryCache.Set(key, rs, TimeSpan.FromHours(1));
_memoryCache.Set(key, rs, TimeSpan.FromMinutes(2));
return rs;
}
}
@@ -297,7 +326,7 @@ namespace BLW_Log.Controllers
else
{
var rs = ExecuteQuery($"SELECT * FROM `cdr_library`.`tbl_iconlibrary` WHERE IconType = 3");
_memoryCache.Set(key, rs, TimeSpan.FromHours(1));
_memoryCache.Set(key, rs, TimeSpan.FromMinutes(2));
return rs;
}
}
@@ -317,7 +346,7 @@ namespace BLW_Log.Controllers
else
{
var rs = ExecuteQuery($"SELECT * FROM `cdr_library`.`tbl_iconlibrary` WHERE IconType = 4");
_memoryCache.Set(key, rs, TimeSpan.FromHours(1));
_memoryCache.Set(key, rs, TimeSpan.FromMinutes(2));
return rs;
}
}
@@ -337,7 +366,7 @@ namespace BLW_Log.Controllers
else
{
var rs = ExecuteQuery($"SELECT * FROM `cdr_library`.`tbl_font`");
_memoryCache.Set(key, rs, TimeSpan.FromHours(1));
_memoryCache.Set(key, rs, TimeSpan.FromMinutes(2));
return rs;
}
}
@@ -354,9 +383,9 @@ namespace BLW_Log.Controllers
{
string sql = @"
INSERT INTO `cdr_library`.`tbl_web_log`
(username, action_time, action_type, hotel_name, target_type, method, target_id, user_ip, user_location, user_agent, is_valid, guid)
VALUES (@username, @action_time, @action_type, @hotel_name, @target_type, @method, @target_id, @user_ip, @user_location, @user_agent, 1, @guid)";
(username, action_time, action_type, hotel_name, target_type, method, target_id, user_ip, user_location, user_agent, is_valid, operation)
VALUES (@username, @action_time, @action_type, @hotel_name, @target_type, @method, @target_id, @user_ip, @user_location, @user_agent, 1, @operation)";
var parameters = new[]
{
new MySqlParameter("@username", log.username ?? (object)DBNull.Value),
@@ -369,7 +398,7 @@ namespace BLW_Log.Controllers
new MySqlParameter("@user_ip", log.user_ip ?? (object)DBNull.Value),
new MySqlParameter("@user_location", log.user_location ?? (object)DBNull.Value),
new MySqlParameter("@user_agent", log.user_agent ?? (object)DBNull.Value),
new MySqlParameter("@guid", Guid.NewGuid().ToString("N"))
new MySqlParameter("@operation", log.operation ?? (object)DBNull.Value)
};
return ExecuteNonQueryWithGuid(sql, parameters);
@@ -382,8 +411,8 @@ namespace BLW_Log.Controllers
UPDATE `cdr_library`.`tbl_web_log` SET
username=@username, action_time=@action_time, action_type=@action_type,
hotel_name=@hotel_name, target_type=@target_type, method=@method,
target_id=@target_id, user_ip=@user_ip, user_location=@user_location, user_agent=@user_agent
WHERE guid=@guid";
target_id=@target_id, user_ip=@user_ip, user_location=@user_location, user_agent=@user_agent, operation=@operation
WHERE id=@id";
var parameters = new[]
{
@@ -397,22 +426,24 @@ namespace BLW_Log.Controllers
new MySqlParameter("@user_ip", log.user_ip ?? (object)DBNull.Value),
new MySqlParameter("@user_location", log.user_location ?? (object)DBNull.Value),
new MySqlParameter("@user_agent", log.user_agent ?? (object)DBNull.Value),
new MySqlParameter("@guid", log.guid ?? (object)DBNull.Value)
new MySqlParameter("@operation", log.operation ?? (object)DBNull.Value)
};
return ExecuteNonQueryWithGuid(sql, parameters, log.guid);
return ExecuteNonQueryWithGuid(sql, parameters, log.id.ToString());
}
[HttpPost]
public ReturnInfo WebLogDelete([FromBody] string guid)
public ReturnInfo WebLogDelete([FromBody] string id)
{
string sql = "UPDATE `cdr_library`.`tbl_web_log` SET is_valid=0 WHERE guid=@guid";
var parameter = new MySqlParameter("@guid", guid ?? (object)DBNull.Value);
return ExecuteNonQueryWithGuid(sql, new[] { parameter }, guid);
// tbl_web_log identifies rows by `id` (bigint), not `guid`.
if (!long.TryParse(id, out long idVal))
{
return new ReturnInfo { isok = false, message = "Invalid id parameter", status = 400, response = null };
}
string sql = "UPDATE `cdr_library`.`tbl_web_log` SET is_valid=0 WHERE id=@id";
var parameter = new MySqlParameter("@id", idVal);
return ExecuteNonQueryWithGuid(sql, new[] { parameter }, id);
}
#endregion
#region tbl_web_panel_list
[HttpPost]
public ReturnInfo WebPanelListQuery() => ExecuteQuery("SELECT * FROM `cdr_library`.`tbl_web_panel_list` WHERE is_valid = 1");
@@ -422,10 +453,10 @@ namespace BLW_Log.Controllers
string sql = @"
INSERT INTO `cdr_library`.`tbl_web_panel_list`
(panel_list_name, gang_series, model_type, gang_material_id, panel_count,
panel_info_json, logo_json, cdr_filename, thumbnail_large,
carving_quantity, position, carving_filename, design_status, panel_info_json, logo_json, cdr_filename, thumbnail_large,
thumbnail_small, erp_part_number, remarks, created_at, is_valid, guid)
VALUES (@panel_list_name, @gang_series, @model_type, @gang_material_id, @panel_count,
@panel_info_json, @logo_json, @cdr_filename, @thumbnail_large,
@carving_quantity, @position, @carving_filename, @design_status, @panel_info_json, @logo_json, @cdr_filename, @thumbnail_large,
@thumbnail_small, @erp_part_number, @remarks, @created_at, 1, @guid)";
var parameters = new[]
@@ -435,6 +466,10 @@ namespace BLW_Log.Controllers
new MySqlParameter("@model_type", panel.model_type ?? (object)DBNull.Value),
new MySqlParameter("@gang_material_id", panel.gang_material_id ?? (object)DBNull.Value),
new MySqlParameter("@panel_count", panel.panel_count ?? (object)DBNull.Value),
new MySqlParameter("@carving_quantity", panel.carving_quantity ?? (object)DBNull.Value),
new MySqlParameter("@position", panel.position ?? (object)DBNull.Value),
new MySqlParameter("@carving_filename", panel.carving_filename ?? (object)DBNull.Value),
new MySqlParameter("@design_status", panel.design_status ?? (object)DBNull.Value),
new MySqlParameter("@panel_info_json", panel.panel_info_json ?? (object)DBNull.Value),
new MySqlParameter("@logo_json", panel.logo_json ?? (object)DBNull.Value),
new MySqlParameter("@cdr_filename", panel.cdr_filename ?? (object)DBNull.Value),
@@ -456,11 +491,11 @@ namespace BLW_Log.Controllers
UPDATE `cdr_library`.`tbl_web_panel_list` SET
panel_list_name=@panel_list_name, gang_series=@gang_series,
model_type=@model_type, gang_material_id=@gang_material_id,
panel_count=@panel_count, panel_info_json=@panel_info_json,
logo_json=@logo_json, cdr_filename=@cdr_filename,
panel_count=@panel_count, carving_quantity=@carving_quantity, position=@position,
carving_filename=@carving_filename, design_status=@design_status, panel_info_json=@panel_info_json, logo_json=@logo_json, cdr_filename=@cdr_filename,
thumbnail_large=@thumbnail_large, thumbnail_small=@thumbnail_small,
erp_part_number=@erp_part_number, remarks=@remarks
WHERE guid=@guid";
WHERE guid=@guid;";
var parameters = new[]
{
@@ -469,6 +504,10 @@ namespace BLW_Log.Controllers
new MySqlParameter("@model_type", panel.model_type ?? (object)DBNull.Value),
new MySqlParameter("@gang_material_id", panel.gang_material_id ?? (object)DBNull.Value),
new MySqlParameter("@panel_count", panel.panel_count ?? (object)DBNull.Value),
new MySqlParameter("@carving_quantity", panel.carving_quantity ?? (object)DBNull.Value),
new MySqlParameter("@position", panel.position ?? (object)DBNull.Value),
new MySqlParameter("@carving_filename", panel.carving_filename ?? (object)DBNull.Value),
new MySqlParameter("@design_status", panel.design_status ?? (object)DBNull.Value),
new MySqlParameter("@panel_info_json", panel.panel_info_json ?? (object)DBNull.Value),
new MySqlParameter("@logo_json", panel.logo_json ?? (object)DBNull.Value),
new MySqlParameter("@cdr_filename", panel.cdr_filename ?? (object)DBNull.Value),
@@ -545,7 +584,7 @@ namespace BLW_Log.Controllers
}
[HttpPost]
public ReturnInfo WebPanelUnitUpdate([FromBody] TblWebPanelUnit unit)
public async Task<ReturnInfo> WebPanelUnitUpdate([FromBody] TblWebPanelUnit unit)
{
string sql = @"
UPDATE `cdr_library`.`tbl_web_panel_unit` SET
@@ -609,7 +648,7 @@ namespace BLW_Log.Controllers
{
new MySqlParameter("@guid_pattern", $"%{unit.guid}%")
};
SetProjectUpdateCdr(new QueryInfo { GUID = unit.project_guid });
ExecuteNonQueryWithGuid(updateSql, updateParameters);
}
}
@@ -780,8 +819,8 @@ namespace BLW_Log.Controllers
{
string sql = @"
INSERT INTO `cdr_library`.`tbl_web_project`
(report_id, hotel_name, room_type_count, room_data_json, remarks, creator, created_at, is_valid, guid)
VALUES (@report_id, @hotel_name, @room_type_count, @room_data_json, @remarks, @creator, @created_at, 1, @guid)";
(report_id, hotel_name, room_type_count, room_data_json, remarks, creator, created_at, is_valid, guid, edit_status, cdr_filename)
VALUES (@report_id, @hotel_name, @room_type_count, @room_data_json, @remarks, @creator, @created_at, 1, @guid, @edit_status, @cdr_filename)";
var parameters = new[]
{
@@ -792,19 +831,41 @@ namespace BLW_Log.Controllers
new MySqlParameter("@remarks", project.remarks ?? (object)DBNull.Value),
new MySqlParameter("@creator", project.creator),
new MySqlParameter("@created_at", project.created_at),
new MySqlParameter("@guid", Guid.NewGuid().ToString("N"))
new MySqlParameter("@guid", Guid.NewGuid().ToString("N")),
new MySqlParameter("@edit_status", project.edit_status ?? (object)DBNull.Value),
new MySqlParameter("@cdr_filename", project.cdr_filename ?? (object)DBNull.Value)
};
return ExecuteNonQueryWithGuid(sql, parameters);
}
/// <summary>
/// 清空项目的编辑状态和cdr文件名
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
[HttpPost]
public ReturnInfo SetProjectUpdateCdr([FromBody] QueryInfo info)
{
string sql = @"
UPDATE `cdr_library`.`tbl_web_project` SET
edit_status='', cdr_filename=''
WHERE guid=@guid";
var parameters = new[]
{
new MySqlParameter("@guid", info.GUID ?? (object)DBNull.Value)
};
return ExecuteNonQueryWithGuid(sql, parameters, info.GUID);
}
[HttpPost]
public ReturnInfo WebProjectUpdate([FromBody] TblWebProject project)
{
string sql = @"
UPDATE `cdr_library`.`tbl_web_project` SET
report_id=@report_id, hotel_name=@hotel_name, room_type_count=@room_type_count,
room_data_json=@room_data_json, remarks=@remarks, creator=@creator
room_data_json=@room_data_json, remarks=@remarks, creator=@creator,
edit_status=@edit_status, cdr_filename=@cdr_filename
WHERE guid=@guid";
var parameters = new[]
@@ -815,6 +876,8 @@ namespace BLW_Log.Controllers
new MySqlParameter("@room_data_json", project.room_data_json),
new MySqlParameter("@remarks", project.remarks ?? (object)DBNull.Value),
new MySqlParameter("@creator", project.creator),
new MySqlParameter("@edit_status", project.edit_status ?? (object)DBNull.Value),
new MySqlParameter("@cdr_filename", project.cdr_filename ?? (object)DBNull.Value),
new MySqlParameter("@guid", project.guid ?? (object)DBNull.Value)
};
@@ -828,6 +891,264 @@ namespace BLW_Log.Controllers
var parameter = new MySqlParameter("@guid", guid ?? (object)DBNull.Value);
return ExecuteNonQueryWithGuid(sql, new[] { parameter }, guid);
}
[HttpPost]
public ReturnInfo GetWebProject([FromBody] QueryInfo info)
{
string sql = "SELECT * FROM `cdr_library`.`tbl_web_project` WHERE guid=@Guid;";
var parameter = new MySqlParameter("@guid", info.GUID ?? (object)DBNull.Value);
return ExecuteQuery(sql, new[] { parameter });
}
/// <summary>
/// 发送CDR文件的路径表单到Redis生成队列
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
[HttpPost]
public ReturnInfo GetAllProjectCDR([FromBody] QueryInfo info)
{
string sql = @"SELECT DISTINCT p.hotel_name, rt.room_name, pnl.model_type, pnl.gang_series,
pnl.panel_list_name,pnl.cdr_filename,pnl.position,pnl.carving_quantity,pnl.thumbnail_large,pnl.carving_filename
FROM `cdr_library`.`tbl_web_project` p
JOIN `cdr_library`.`tbl_web_room_type` rt ON p.room_data_json LIKE CONCAT('%', rt.guid, '%')
JOIN `cdr_library`.`tbl_web_panel_list` pnl ON rt.panel_group_count LIKE CONCAT('%', pnl.guid, '%')
WHERE p.guid=@guid ORDER BY rt.room_name;";
var parameter = new MySqlParameter("@guid", info.GUID ?? (object)DBNull.Value);
// 将当前项目状态置为生成中,避免重复触发或并发问题
string updateSql = "UPDATE `cdr_library`.`tbl_web_project` SET edit_status='生成中' WHERE guid=@guid";
ExecuteNonQueryWithGuid(updateSql, new[] { parameter }, info.GUID);
var eq = ExecuteQuery(sql, new[] { parameter });
// 获取tbl_web_project的整行数据
string projectSql = "SELECT * FROM `cdr_library`.`tbl_web_project` WHERE guid = @guid";
var projectQueryResult = ExecuteQuery(projectSql, new[] { parameter });
string hotel_name = JsonConvert.DeserializeObject<DataTable>(projectQueryResult.response.ToString()).Rows[0]["hotel_name"].ToString();
// 解析两个查询结果如果有为JToken以便合并发送到Redis
JToken? panelsToken = null;
JToken? projectToken = null;
try
{
if (eq != null && eq.response != null) panelsToken = JToken.Parse(eq.response!.ToString());
}
catch { panelsToken = null; }
try
{
if (projectQueryResult != null && projectQueryResult.response != null) projectToken = JToken.Parse(projectQueryResult.response!.ToString());
}
catch { projectToken = null; }
string picNum = Guid.NewGuid().ToString("N");
var combinedPayload = new
{
project = projectToken,
panels = panelsToken,
picNum
};
bool success = PublishToRedis(new RedisInfo
{
Type = "CellCorelDRAW",
ObjToRedis = new CellCorelDRAW() { MsgType = 2, MsgNode = combinedPayload }
});
Dictionary<string, string> pcn = new()
{
{ picNum, info.GUID ?? string.Empty }
};
CSRedisCacheHelper.LPush("PicNumList", pcn);
LogOperation(info.UserName, "GetAllProjectCDR", hotel_name, info.GUID, info);
return new() { isok = success, message = success ? "已提交到生成队列" : "提交到生成队列失败", status = success ? 200 : 500, response = null };
}
/// <summary>
/// 获取下载CDR文件的路径表单
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
[HttpPost]
public ReturnInfo GetWebProjectCDR([FromBody] QueryInfo info)
{
string sql = @"SELECT DISTINCT p.hotel_name, rt.room_name, pnl.model_type, pnl.gang_series,
pnl.panel_list_name,pnl.cdr_filename,pnl.position,pnl.carving_quantity,pnl.thumbnail_large,pnl.carving_filename
FROM `cdr_library`.`tbl_web_project` p
JOIN `cdr_library`.`tbl_web_room_type` rt ON p.room_data_json LIKE CONCAT('%', rt.guid, '%')
JOIN `cdr_library`.`tbl_web_panel_list` pnl ON rt.panel_group_count LIKE CONCAT('%', pnl.guid, '%')
WHERE p.guid=@guid;";
var parameter = new MySqlParameter("@guid", info.GUID ?? (object)DBNull.Value);
return ExecuteQuery(sql, new[] { parameter });
}
/// <summary>
/// 下载文件
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
[HttpPost]
public async Task<IActionResult> DownloadProjectCDR([FromBody] QueryInfo info)
{
try
{
string hotel_name = "";
string sql = @"SELECT DISTINCT p.hotel_name, rt.room_name, pnl.model_type, pnl.gang_series,
pnl.panel_list_name,pnl.cdr_filename,pnl.position,pnl.carving_quantity,pnl.thumbnail_large,pnl.carving_filename
FROM `cdr_library`.`tbl_web_project` p
JOIN `cdr_library`.`tbl_web_room_type` rt ON p.room_data_json LIKE CONCAT('%', rt.guid, '%')
JOIN `cdr_library`.`tbl_web_panel_list` pnl ON rt.panel_group_count LIKE CONCAT('%', pnl.guid, '%')
WHERE p.guid=@guid;";
var parameter = new MySqlParameter("@guid", info.GUID ?? (object)DBNull.Value);
var queryResult = ExecuteQuery(sql, new[] { parameter });
if (!queryResult.isok || queryResult.response == null)
{
return NotFound("未找到相关数据");
}
var dt = JsonConvert.DeserializeObject<DataTable>(queryResult.response.ToString());
if (dt == null || dt.Rows.Count == 0)
{
return NotFound("未找到相关数据");
}
// 先获取项目级的cdr文件路径确认存在否则直接返回错误
var projectResult = GetWebProject(info);
if (!projectResult.isok || projectResult.response == null)
{
return NotFound("未找到项目数据");
}
var projectDt = JsonConvert.DeserializeObject<DataTable>(projectResult.response.ToString());
if (projectDt == null || projectDt.Rows.Count == 0)
{
return NotFound("未找到项目数据");
}
string projectCdr = projectDt.Rows[0]["cdr_filename"]?.ToString()?.Trim() ?? string.Empty;
if (string.IsNullOrWhiteSpace(projectCdr))
{
return BadRequest("总路径不存在");
}
// 校验每条记录的必要文件是否已生成thumbnail_large, carving_filename, cdr_filename
foreach (DataRow row in dt.Rows)
{
string thumbnail = row["thumbnail_large"]?.ToString()?.Trim() ?? string.Empty;
string carving = row["carving_filename"]?.ToString()?.Trim() ?? string.Empty;
string cdr = row["cdr_filename"]?.ToString()?.Trim() ?? string.Empty;
if (string.IsNullOrEmpty(thumbnail) || string.IsNullOrEmpty(carving) || string.IsNullOrEmpty(cdr))
{
// 如果任一文件为空,则直接返回错误提示
return BadRequest("有图片尚未生成");
}
}
var memoryStream = new MemoryStream();
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{
var dateStr = DateTime.Now.ToString("yyyyMMdd");
var usedNames = new HashSet<string>();
foreach (DataRow row in dt.Rows)
{
hotel_name = row["hotel_name"]?.ToString() ?? "";
string carving_quantity = row["carving_quantity"]?.ToString() ?? "0";
string room_name = row["room_name"]?.ToString() ?? "";
string panel_list_name = row["panel_list_name"]?.ToString() ?? "";
string gang_series = row["gang_series"]?.ToString() ?? "";
string model_type = row["model_type"]?.ToString() ?? "";
string formatted_model_type = FormatNameFront12(model_type);
string baseFileName = $"数量{carving_quantity}_{hotel_name}_{room_name}_{panel_list_name}_{gang_series}_{formatted_model_type}_{dateStr}";
// CDR
string cdrPath = "\\PanelSelectionPic\\" + row["cdr_filename"]?.ToString();
if (!string.IsNullOrWhiteSpace(cdrPath))
{
AddFileToZip(archive, _webHostEnvironment.WebRootPath, cdrPath, $"CDR/{baseFileName}.cdr", usedNames);
}
// PNG
string pngPath = "\\PanelSelectionPic\\" + row["thumbnail_large"]?.ToString();
if (!string.IsNullOrWhiteSpace(pngPath))
{
AddFileToZip(archive, _webHostEnvironment.WebRootPath, pngPath, $"雕刻/{baseFileName}.png", usedNames);
}
// PLT
string pltPath = "\\PanelSelectionPic\\" + row["carving_filename"]?.ToString();
if (!string.IsNullOrWhiteSpace(pltPath))
{
AddFileToZip(archive, _webHostEnvironment.WebRootPath, pltPath, $"雕刻/{baseFileName}.plt", usedNames);
}
}
// 添加整体项目的 CDR 文件到 CDR/ 目录下
if (!string.IsNullOrWhiteSpace(projectCdr))
{
AddFileToZip(archive, _webHostEnvironment.WebRootPath, "\\PanelSelectionPic\\" + projectCdr, $"CDR/{hotel_name}_总预览图.cdr", usedNames);
}
}
// 记录日志
LogOperation(info.UserName, "DownloadProjectCDR", hotel_name, info.GUID, info);
memoryStream.Position = 0;
return File(memoryStream, "application/zip", $"{hotel_name}_{DateTime.Now:yyyyMMddHHmmss}.zip");
}
catch (Exception ex)
{
return StatusCode(500, $"打包下载失败: {ex.Message}");
}
}
private string FormatNameFront12(string model_type)
{
if (string.IsNullOrEmpty(model_type)) return "";
var parts = model_type.Split('_');
if (parts.Length <= 3) return "";
return string.Join("_", parts.Skip(1).Take(parts.Length - 3));
}
private void AddFileToZip(ZipArchive archive, string webRootPath, string filePath, string entryPath, HashSet<string> usedNames)
{
try
{
// Handle duplicates
string finalEntryPath = entryPath;
int counter = 1;
while (usedNames.Contains(finalEntryPath))
{
string ext = Path.GetExtension(entryPath);
string nameWithoutExt = Path.GetFileNameWithoutExtension(entryPath);
string dir = Path.GetDirectoryName(entryPath)?.Replace("\\", "/") ?? "";
if (!string.IsNullOrEmpty(dir)) dir += "/";
finalEntryPath = $"{dir}{nameWithoutExt}_{counter}{ext}";
counter++;
}
usedNames.Add(finalEntryPath);
// Resolve physical path
if (filePath.StartsWith("http", StringComparison.OrdinalIgnoreCase))
{
if (Uri.TryCreate(filePath, UriKind.Absolute, out Uri uri))
{
filePath = uri.LocalPath;
}
}
filePath = filePath.TrimStart('/', '\\');
string physicalPath = Path.Combine(webRootPath, filePath);
if (System.IO.File.Exists(physicalPath))
{
archive.CreateEntryFromFile(physicalPath, finalEntryPath);
}
}
catch
{
// Ignore errors for individual files
}
}
#endregion
#region tbl_web_room_type
@@ -895,7 +1216,7 @@ namespace BLW_Log.Controllers
{
var generatingItems = new
{
PanelLists = ExecuteQuery("SELECT guid, thumbnail_large FROM `cdr_library`.`tbl_web_panel_list` WHERE thumbnail_small = '生成中' AND is_valid = 1"),
PanelLists = ExecuteQuery("SELECT guid, thumbnail_large FROM `cdr_library`.`tbl_web_panel_list` WHERE design_status = '生成中' AND is_valid = 1"),
PanelUnits = ExecuteQuery("SELECT guid, thumbnail_large FROM `cdr_library`.`tbl_web_panel_unit` WHERE design_status = '生成中' AND is_valid = 1")
};
@@ -920,7 +1241,59 @@ namespace BLW_Log.Controllers
}
#endregion
#region
#region
/// <summary>
/// 记录操作日志
/// </summary>
private void LogOperation(string username, string actionType, string hotelName, string targetId, object operationData)
{
try
{
string userIp = HttpContext.Connection.RemoteIpAddress?.ToString();
string userAgent = Request.Headers["User-Agent"].ToString();
// Ensure required fields are not null to satisfy DB constraints
var safeUsername = string.IsNullOrEmpty(username) ? (User?.Identity?.Name ?? "system") : username;
var log = new TblWebLog
{
username = safeUsername,
action_type = actionType,
hotel_name = hotelName,
target_id = targetId,
operation = JsonConvert.SerializeObject(operationData),
user_ip = userIp,
user_agent = userAgent,
user_location = "", // 默认空字符串
method = actionType, // 使用actionType作为method
target_type = "Project" // 默认为Project可根据需要调整
};
WebLogAdd(log);
}
catch (Exception ex)
{
// 记录日志失败不应影响主流程,仅打印错误
Console.WriteLine($"记录日志失败: {ex.Message}");
}
}
/// <summary>
/// Publish到Redis
/// </summary>
public bool PublishToRedis(RedisInfo request)
{
try
{
CSRedisCacheHelper.Publish(request.Type, Newtonsoft.Json.JsonConvert.SerializeObject(request.ObjToRedis));
return true;
}
catch (Exception)
{
return false;
}
}
/// <summary>
/// 通用查询执行方法(参数化版本)
/// </summary>
@@ -1061,6 +1434,7 @@ namespace BLW_Log.Controllers
public int? PID { get; set; }
public int? MID { get; set; }
public string? GUID { get; set; }
public string? UserName { get; set; }
}
public class TblWebLog
{
@@ -1071,12 +1445,12 @@ namespace BLW_Log.Controllers
public string? hotel_name { get; set; }
public string? target_type { get; set; }
public string? method { get; set; }
public long? target_id { get; set; }
public string? target_id { get; set; }
public string? user_ip { get; set; }
public string? user_location { get; set; }
public string? user_agent { get; set; }
public bool? is_valid { get; set; }
public string? guid { get; set; }
public string? operation { get; set; }
public TblWebLog()
{
this.action_time = DateTime.Now;
@@ -1091,6 +1465,10 @@ namespace BLW_Log.Controllers
public string? gang_series { get; set; }
public string? model_type { get; set; }
public int? panel_count { get; set; } // 新增字段
public int? carving_quantity { get; set; } // 新增字段:雕刻数量
public string? position { get; set; } // 新增字段:位置
public string? carving_filename { get; set; } // 新增字段:雕刻图
public string? design_status { get; set; } // 新增字段:设计状态
public long? gang_material_id { get; set; }
public string? panel_info_json { get; set; }
public string? logo_json { get; set; }
@@ -1159,6 +1537,8 @@ namespace BLW_Log.Controllers
public DateTime created_at { get; set; }
public bool is_valid { get; set; }
public string? guid { get; set; }
public string? edit_status { get; set; }
public string? cdr_filename { get; set; }
public TblWebProject()
{
this.created_at = DateTime.Now;
@@ -1209,5 +1589,4 @@ public class CopyPanelUnitRequest
/// </summary>
public string NewProjectGuid { get; set; }
}
#endregion

View File

@@ -5,6 +5,7 @@ using NLog;
using Org.BouncyCastle.Asn1.Ocsp;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Threading;
using static Google.Protobuf.Reflection.SourceCodeInfo.Types;
@@ -13,11 +14,11 @@ namespace BLW_Log.Models
public class PanelSelectionClass : BackgroundService
{
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
public static ConcurrentBag<Dictionary<string, string>> PicNumList = new();
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await Task.Factory.StartNew(async () =>
{
//return; // 老服务器需要注释此行代码
while (!stoppingToken.IsCancellationRequested)
{
try
@@ -26,7 +27,7 @@ namespace BLW_Log.Models
Dictionary<string, string> PicNum = CSRedisCacheHelper.BRPop<Dictionary<string, string>>("PicNumList");
_logger.Info("开始执行Redis轮询");
if(PicNum != null)
if (PicNum != null)
{
var pair = PicNum.ElementAt(0);
_logger.Info($"开始处理{pair.Key}");
@@ -36,63 +37,70 @@ namespace BLW_Log.Models
try
{
// 反序列化Redis返回的数据
var redisResult = JsonConvert.DeserializeObject<RedisSendNode>(RS);
if (redisResult != null)
var rss = JsonConvert.DeserializeObject<TypeNode>(RS);
var redisResult = rss.MsgNode;
if (rss.MsgType == 1)
{
bool isUnitPanel = pair.Key.StartsWith("Unit");
bool updateSuccess = false;
if (redisResult.Process == 0)
if (redisResult != null)
{
// Process=0: 预览小图
bool isUnitPanel = pair.Key.StartsWith("Unit");
bool updateSuccess = false;
// Process=0: 预览小图 1: CDR
updateSuccess = UpdatePanelThumbnail(
pair.Value,
redisResult.ImagePath,
redisResult.Process == 0 ? redisResult.ImagePath : redisResult.CdrPath,
isUnitPanel,
0
redisResult.Process
);
if (updateSuccess)
{
CSRedisCacheHelper.Del(pair.Key);
_logger.Info($"成功更新{pair.Value}的thumbnail_large");
}
else
{
Dictionary<string, string> newDic = new()
{
{ pair.Key, pair.Value }
};
CSRedisCacheHelper.LPush("PicNumList", newDic);
}
}
else if (redisResult.Process == 1)
}
else if (rss.MsgType == 2)
{
if (redisResult != null)
{
// Process=1: 生成文件
updateSuccess = UpdatePanelThumbnail(
bool isUnitPanel = pair.Key.StartsWith("Unit");
bool updateSuccess = false;
updateSuccess = UpdatePorjectCdrpath(
pair.Value,
redisResult.CdrPath,
isUnitPanel,
1
redisResult.CdrPath
);
if (updateSuccess)
{
CSRedisCacheHelper.Del(pair.Key);
_logger.Info($"成功更新{pair.Value}的cdr_filename");
}
}
// 无论成功与否都从Redis中删除该键
CSRedisCacheHelper.Del(pair.Key);
// 如果更新bu成功可以从PicNumList中移除该项
if (!updateSuccess)
{
Dictionary<string, string> newDic = new()
else
{
{ pair.Key, pair.Value }
};
CSRedisCacheHelper.LPush("PicNumList", newDic);
Dictionary<string, string> newDic = new()
{
{ pair.Key, pair.Value }
};
CSRedisCacheHelper.LPush("PicNumList", newDic);
}
}
}
}
catch (Exception ex)
{
_logger.Error($"处理Redis消息失败: {ex.Message}");
// 发生异常时也删除Redis键避免重复处理
CSRedisCacheHelper.Del(pair.Key);
}
}
else
@@ -104,17 +112,81 @@ namespace BLW_Log.Models
CSRedisCacheHelper.LPush("PicNumList", newDic);
}
}
await Task.Delay(1000);
await Task.Delay(1145);
}
catch (Exception ex)
{
_logger.Info("Redis轮询err" + ex.StackTrace + " | " + ex.Message);
}
}
}, TaskCreationOptions.LongRunning);
}
private bool UpdatePanelThumbnail(string guid, string imagePath, bool isUnitPanel, int process)
private bool UpdatePanelThumbnail(string guid, string imagePathPlt, bool isUnitPanel, int? process)
{
try
{
string imagePath = Regex.Replace(imagePathPlt, @"\.plt$", ".cdr", RegexOptions.IgnoreCase);
using var conn = new MySqlConnection(ReadConfig.Instance.MySQLConnectionString);
conn.Open();
string sql;
using var cmd = new MySqlCommand();
cmd.Connection = conn;
if (isUnitPanel)
{
sql = $@"UPDATE `cdr_library`.`tbl_web_panel_unit`
SET thumbnail_large = @ImagePath, design_status = ''
WHERE guid = @Guid";
cmd.CommandText = sql;
}
else
{
if (process == 0)
{
// Process=0: 更新thumbnail_large设置design_status为空
sql = $@"UPDATE `cdr_library`.`tbl_web_panel_list`
SET thumbnail_large = @ImagePath, design_status = ''
WHERE guid = @Guid";
cmd.CommandText = sql;
}
else
{
// Process=1: 更新cdr_filename设置design_status为空
sql = $@"UPDATE `cdr_library`.`tbl_web_panel_list`
SET cdr_filename = @ImagePath, carving_filename = @carving_filename, design_status = ''
WHERE guid = @Guid";
cmd.CommandText = sql;
cmd.Parameters.AddWithValue("@carving_filename", imagePathPlt);
}
}
cmd.Parameters.AddWithValue("@ImagePath", imagePath);
cmd.Parameters.AddWithValue("@Guid", guid);
using var cmdRt = new MySqlCommand("SELECT design_status FROM `cdr_library`.`tbl_web_panel_list` WHERE guid=@Guid;", conn);
cmdRt.Parameters.AddWithValue("@Guid", guid);
int affectedRows = cmd.ExecuteNonQuery();
var affectedRowsRt = cmdRt.ExecuteScalar() != null ? cmdRt.ExecuteScalar().ToString() : "";
if (string.IsNullOrEmpty(affectedRowsRt))
{
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
// 记录日志
_logger.Error($"更新面板数据失败: {ex.Message}");
return false;
}
}
private bool UpdatePorjectCdrpath(string guid, string imagePath)
{
try
{
@@ -122,47 +194,27 @@ namespace BLW_Log.Models
conn.Open();
string sql;
if (isUnitPanel)
using var cmd = new MySqlCommand();
cmd.Connection = conn;
sql = $@"UPDATE `cdr_library`.`tbl_web_project`
SET cdr_filename = @ImagePath, edit_status = ''
WHERE guid = @Guid";
cmd.CommandText = sql;
cmd.Parameters.AddWithValue("@ImagePath", imagePath);
cmd.Parameters.AddWithValue("@Guid", guid);
using var cmdRt = new MySqlCommand("SELECT edit_status FROM `cdr_library`.`tbl_web_project` WHERE guid=@Guid;", conn);
cmdRt.Parameters.AddWithValue("@Guid", guid);
int affectedRows = cmd.ExecuteNonQuery();
var affectedRowsRt = cmdRt.ExecuteScalar() != null ? cmdRt.ExecuteScalar().ToString() : "";
if (string.IsNullOrEmpty(affectedRowsRt))
{
if (process == 0)
{
// Process=0: 更新thumbnail_large设置design_status为空
sql = $@"UPDATE `cdr_library`.`tbl_web_panel_unit`
SET thumbnail_large = @ImagePath, design_status = ''
WHERE guid = @Guid";
}
else
{
// Process=1: 更新cdr_filename设置thumbnail_small为空
sql = $@"UPDATE `cdr_library`.`tbl_web_panel_unit`
SET cdr_filename = @ImagePath, thumbnail_small = ''
WHERE guid = @Guid";
}
return true;
}
else
{
if (process == 0)
{
// Process=0: 更新thumbnail_large设置thumbnail_small为空
sql = $@"UPDATE `cdr_library`.`tbl_web_panel_list`
SET thumbnail_large = @ImagePath, thumbnail_small = ''
WHERE guid = @Guid";
}
else
{
// Process=1: 更新cdr_filename设置thumbnail_small为空
sql = $@"UPDATE `cdr_library`.`tbl_web_panel_list`
SET cdr_filename = @ImagePath, thumbnail_small = ''
WHERE guid = @Guid";
}
return false;
}
using var cmd = new MySqlCommand(sql, conn);
cmd.Parameters.AddWithValue("@ImagePath", imagePath);
cmd.Parameters.AddWithValue("@Guid", guid);
int affectedRows = cmd.ExecuteNonQuery();
return affectedRows > 0;
}
catch (Exception ex)
{
@@ -172,7 +224,14 @@ namespace BLW_Log.Models
}
}
}
public class RedisInfo
{
/// <summary>
/// 列表
/// </summary>
public object ObjToRedis { get; set; }
public string Type { get; set; }
}
public class RedisInfoNode
{
/// <summary>
@@ -314,7 +373,11 @@ namespace BLW_Log.Models
/// </summary>
public string LineNumber { get; set; }
}
public class TypeNode
{
public int MsgType { get; set; }
public RedisSendNode MsgNode { get; set; }
}
public class RedisSendNode
{
/// <summary>
@@ -353,7 +416,7 @@ namespace BLW_Log.Models
/// 流程
/// 0-预览小图 1-生成文件
/// </summary>
public int Process { get; set; }
public int? Process { get; set; } = 0;
/// <summary>
/// 图号
@@ -388,6 +451,11 @@ namespace BLW_Log.Models
/// <summary>
/// 返回信息
/// </summary>
public string Msg { get; set; }
public string? Msg { get; set; }
}
public class CellCorelDRAW
{
public int MsgType { get; set; }
public object MsgNode { get; set; }
}
}

View File

@@ -199,7 +199,7 @@ namespace BLW_Log
OnPrepareResponse = context =>
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CDR<44>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ
if (context.File.Name.EndsWith(".cdr"))
if (context.File.Name.EndsWith(".cdr") || context.File.Name.EndsWith(".png"))
{
context.Context.Response.Headers.Append("Content-Disposition", "attachment");
}

View File

@@ -0,0 +1,71 @@
<link href="~/css/bulma.css" rel="stylesheet" />
<link href="~/css/bulma.min.css" rel="stylesheet" />
<script src="~/js/jquery.min.js"></script>
<script>
$(function()
{
$("#btnsend").click(function()
{
let cmdtype=$("#txtcmd").val();
let id=$("#txtid").val();
let data=$("#txtdata").val();
console.log(data)
let aaa= {
Cmd: "tcp_send_data_clientid",
Parameterlist: {
"device_clientid": id,
"command_word":cmdtype,
"data":data
}
};
let YUI= JSON.stringify(aaa);
$.ajax({
//url: 'http://localhost:5116/api/sockettcp/send_data_to_targetnew',
url: 'http://iot-manage.uts-data.com:5001/api/sockettcp/send_data_to_targetnew',
type: 'Post',
//contentType: 'application/x-www-form-urlencoded',
contentType: 'application/json',
data: JSON.stringify(aaa),
success: function(response) {
console.log(response);
},
error: function(xhr, status, error) {
console.log(error);
},
beforeSend: function(xhr) {
console.log('Sending request...');
},
complete: function(xhr, status) {
console.log('Request completed.');
}
});
});
});
</script>
<div class="field">
<label class="label">设备CID</label>
<div class="control">
<input id="txtid" class="input is-primary"
type="text"
placeholder="Primary input" />
</div>
</div>
<div class="field">
<label class="label">命令字:</label>
<div class="control">
<input id="txtcmd" class="input is-primary"
type="text"
placeholder="Primary input" />
</div>
</div>
<div class="field">
<label class="label">数据:</label>
<div class="control">
<textarea id="txtdata" class="textarea"
placeholder="10 lines of textarea"
rows="10"></textarea>
</div>
</div>
<button id="btnsend" class="button is-link">发送</button>

View File

@@ -10,9 +10,9 @@ namespace Common
public class ReturnInfo
{
public bool isok { set; get; } // 是否成功true成功
public string message { set; get; } // 传递接口信息or报错信息
public string? message { set; get; } // 传递接口信息or报错信息
public int status { set; get; } // 服务器报错信息正确为200错误404/500等
public object response { set; get; } // 获取到的信息本体若报错则为null
public object? response { set; get; } // 获取到的信息本体若报错则为null
}
public class Http
{

260
cdr_library.sql Normal file
View File

@@ -0,0 +1,260 @@
/*
Navicat Premium Dump SQL
Source Server : blv-rd.tech
Source Server Type : MySQL
Source Server Version : 80040 (8.0.40)
Source Host : 10.8.8.212:16036
Source Schema : cdr_library
Target Server Type : MySQL
Target Server Version : 80040 (8.0.40)
File Encoding : 65001
Date: 09/12/2025 09:41:14
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for tbl_cdr_file
-- ----------------------------
DROP TABLE IF EXISTS `tbl_cdr_file`;
CREATE TABLE `tbl_cdr_file` (
`ID` int NOT NULL AUTO_INCREMENT,
`Series` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '系列名称',
`FileName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '文件名',
`Version` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '版本',
`Remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`User` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '上传用户',
`UpdateTime` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '上传时间',
`PreviewPath` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '预览路径',
`Active` int NULL DEFAULT 1 COMMENT '启用状态1启用0禁用',
`Company` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '公司名称',
PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 124 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for tbl_font
-- ----------------------------
DROP TABLE IF EXISTS `tbl_font`;
CREATE TABLE `tbl_font` (
`ID` int NOT NULL AUTO_INCREMENT,
`FontName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '字體名稱',
`UserName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '上傳者',
`UploadTime` datetime NULL DEFAULT NULL COMMENT '上傳時間',
`Remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '備注',
PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for tbl_iconlibrary
-- ----------------------------
DROP TABLE IF EXISTS `tbl_iconlibrary`;
CREATE TABLE `tbl_iconlibrary` (
`ID` int NOT NULL AUTO_INCREMENT,
`FID` int NULL DEFAULT NULL COMMENT 'cdr_file_id',
`IconType` int NULL DEFAULT NULL COMMENT '素材类型(1 Icon 2 Txt 3 TxtEn 4 Logo)',
`KeyName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '素材名称',
`ShapeNumber` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '位置信息',
`Remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
`PreviewPath` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '预览路径',
`NameCN` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '中文名',
`NameEn` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '英文名',
PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1901 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Table structure for tbl_location
-- ----------------------------
DROP TABLE IF EXISTS `tbl_location`;
CREATE TABLE `tbl_location` (
`ID` int NOT NULL AUTO_INCREMENT,
`PID` int NULL DEFAULT NULL COMMENT 'pattern_id',
`LocationName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '名称',
`Type` int NULL DEFAULT NULL COMMENT '类型',
`SizeH` double NULL DEFAULT NULL COMMENT '高度',
`SizeW` double NULL DEFAULT NULL COMMENT '宽度',
`IndexNum` int NULL DEFAULT NULL COMMENT '相对位置',
`lineNumber` int NULL DEFAULT NULL COMMENT '行號',
`Keygroup` int NULL DEFAULT NULL COMMENT '按键组号',
PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2495 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for tbl_model
-- ----------------------------
DROP TABLE IF EXISTS `tbl_model`;
CREATE TABLE `tbl_model` (
`ID` int NOT NULL AUTO_INCREMENT,
`FID` int NULL DEFAULT NULL COMMENT 'cdr_file_id',
`ModelName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '模型名(几连体)',
`Direction` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '方向',
`SizeH` double NULL DEFAULT NULL COMMENT '高度',
`SizeW` double NULL DEFAULT NULL COMMENT '宽度',
`Color` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '颜色',
`PanelCount` int NULL DEFAULT NULL COMMENT '面板数',
`ShapeNumber` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '位置信息',
`PreviewPath` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '预览路径',
`Remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
`LOGO_L` int NULL DEFAULT NULL COMMENT '左下logo',
`LOGO_R` int NULL DEFAULT NULL COMMENT '右下logo',
`LOGO_L_W` int NULL DEFAULT NULL,
`LOGO_L_H` int NULL DEFAULT NULL,
`LOGO_R_W` int NULL DEFAULT NULL,
`LOGO_R_H` int NULL DEFAULT NULL,
PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 159 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for tbl_pattern
-- ----------------------------
DROP TABLE IF EXISTS `tbl_pattern`;
CREATE TABLE `tbl_pattern` (
`ID` int NOT NULL AUTO_INCREMENT,
`FID` int NULL DEFAULT NULL COMMENT 'cdr_file_id',
`PatternName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '单体名称',
`ShapeNumber` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '位置信息',
`SizeH` double NULL DEFAULT NULL COMMENT '高度',
`SizeW` double NULL DEFAULT NULL COMMENT '宽度',
`PreviewPath` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '预览路径',
`Remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 465 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for tbl_trench
-- ----------------------------
DROP TABLE IF EXISTS `tbl_trench`;
CREATE TABLE `tbl_trench` (
`ID` int NOT NULL AUTO_INCREMENT,
`MID` int NULL DEFAULT NULL,
`TrenchName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`SizeW` double NULL DEFAULT NULL,
`SizeH` double NULL DEFAULT NULL,
`IndexNum` int NULL DEFAULT NULL,
PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 285 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for tbl_web_log
-- ----------------------------
DROP TABLE IF EXISTS `tbl_web_log`;
CREATE TABLE `tbl_web_log` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '日志ID',
`username` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户名',
`action_time` datetime(3) NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '操作时间',
`action_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '行为:登录、切换酒店、编辑、保存、发布、登出、下载等',
`hotel_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '操作时打开的酒店',
`target_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '操作对象:面板组、面板',
`method` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '操作方法:被调用的接口名称',
`target_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '操作对象如房型GUID、面板GUID等',
`operation` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '接口请求内容',
`user_ip` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户IP地址',
`user_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户所在位置通过IP解析',
`user_agent` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '用户浏览器信息',
`is_valid` tinyint(1) NULL DEFAULT 1 COMMENT '有效状态1=有效0=删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '操作日志表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for tbl_web_panel_list
-- ----------------------------
DROP TABLE IF EXISTS `tbl_web_panel_list`;
CREATE TABLE `tbl_web_panel_list` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '面板组ID',
`panel_list_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '面板组名称',
`gang_series` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '面板组系列',
`model_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '面板类型(二联体 之类)',
`panel_count` int NULL DEFAULT NULL COMMENT '面板数量',
`gang_material_id` bigint NULL DEFAULT NULL COMMENT '面板组素材ID关联tbl_dict_gang_panel.id',
`panel_info_json` json NULL COMMENT '面板单元GUID数组',
`logo_json` json NULL,
`cdr_filename` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '面板组CDR文件名',
`thumbnail_large` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '大缩略图',
`thumbnail_small` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '小缩略图',
`erp_part_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'ERP料号',
`remarks` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '备注说明',
`created_at` datetime(3) NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '生成日期',
`is_valid` tinyint(1) NULL DEFAULT 1 COMMENT '有效状态1=有效0=删除',
`guid` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'GUID',
`position` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '位置',
`carving_quantity` int NULL DEFAULT NULL COMMENT '雕刻数量',
`carving_filename` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '雕刻图',
`design_status` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '设计状态',
PRIMARY KEY (`id`) USING BTREE,
INDEX `GUID`(`guid` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 37 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '面板组列表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for tbl_web_panel_unit
-- ----------------------------
DROP TABLE IF EXISTS `tbl_web_panel_unit`;
CREATE TABLE `tbl_web_panel_unit` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '单体面板ID',
`panel_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '单体面板名称',
`product_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '单体面板产品类型(从模型继承)',
`element_count` int NULL DEFAULT 0 COMMENT '元素数量',
`elements_json` json NULL COMMENT '元素数组JSON格式',
`cdr_filename` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '单体面板CDR文件名',
`thumbnail_large` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '大缩略图路径',
`thumbnail_small` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '小缩略图路径',
`remarks` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '备注说明',
`erp_part_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'ERP料号',
`design_status` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '设计状态',
`owner` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '所有者(账户名)',
`created_at` datetime(3) NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '生成日期',
`published_at` datetime(3) NULL DEFAULT NULL COMMENT '发布日期',
`share_type` enum('公共','私有','指定用户组','指定用户') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '公共' COMMENT '分享类型',
`series_id` int NULL DEFAULT NULL COMMENT '系列',
`pattern_id` int NULL DEFAULT NULL COMMENT '面板类型',
`direction` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '方向',
`color` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '颜色',
`is_valid` tinyint(1) NULL DEFAULT 1 COMMENT '有效状态1=有效0=删除',
`guid` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'GUID',
`project_guid` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '关联项目的GUID',
PRIMARY KEY (`id`) USING BTREE,
INDEX `GUID`(`guid` ASC) USING BTREE,
INDEX `idx_project_guid`(`project_guid` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 71 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '单体面板列表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for tbl_web_project
-- ----------------------------
DROP TABLE IF EXISTS `tbl_web_project`;
CREATE TABLE `tbl_web_project` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '酒店项目ID',
`report_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '报备ID从报备平台装载',
`hotel_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '酒店名称',
`room_type_count` int NULL DEFAULT 0 COMMENT '房型数量',
`room_data_json` json NULL COMMENT '房型数据JSON数组包含房型ID等',
`remarks` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '备注说明',
`creator` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '生成者',
`created_at` datetime(3) NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '生成日期',
`is_valid` tinyint(1) NULL DEFAULT 1 COMMENT '有效状态1=有效0=删除',
`guid` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'GUID',
`cdr_filename` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '酒店整体CDR路径',
`edit_status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '编辑状态',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2913 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '酒店项目数据' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for tbl_web_room_type
-- ----------------------------
DROP TABLE IF EXISTS `tbl_web_room_type`;
CREATE TABLE `tbl_web_room_type` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '房型ID',
`room_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '房型名称',
`room_description` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '房型说明',
`panel_group_count` varchar(225) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '面板组ID',
`remarks` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT '备注说明',
`creator` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '生成者(账户名)',
`created_at` datetime(3) NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '生成日期',
`is_valid` tinyint(1) NULL DEFAULT 1 COMMENT '有效状态1=有效0=删除',
`guid` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'GUID',
PRIMARY KEY (`id`) USING BTREE,
INDEX `GUID`(`guid` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 75 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '房型数据表' ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;

View File

@@ -0,0 +1,49 @@
# 伙伴云OpenAPI
## Docs
- 开发指南 [开发前必读](https://openapi.huoban.com/doc-661255.md):
- 开发指南 [申请 API Key](https://openapi.huoban.com/doc-661256.md):
- 开发指南 [基本概念介绍](https://openapi.huoban.com/doc-661257.md):
- 开发指南 [数据筛选器](https://openapi.huoban.com/doc-661258.md):
- 开发指南 [更新日志](https://openapi.huoban.com/doc-752983.md):
- 订阅 [订阅事件概述](https://openapi.huoban.com/doc-830149.md):
- 订阅 [Encrypt Key 加解密](https://openapi.huoban.com/doc-830150.md):
- 订阅 [订阅回调事件](https://openapi.huoban.com/doc-830151.md):
## API Docs
- 工作区 [获取工作区列表](https://openapi.huoban.com/api-17851166.md): 获取 API Key 授权范围内的企业工作区列表。
- 工作区 [获取工作区成员列表](https://openapi.huoban.com/api-17851167.md): 获取指定工作区内的成员列表。
- 表格数据 [获取表格列表](https://openapi.huoban.com/api-17851168.md): 获取指定工作区内的表格列表。
- 表格数据 [获取表格配置](https://openapi.huoban.com/api-17851169.md): 获取指定表格的详细字段配置。
- 表格数据 [查询数据列表](https://openapi.huoban.com/api-17851170.md): 获取指定表格的数据列表。
- 表格数据 [获取数据详情](https://openapi.huoban.com/api-17851171.md): 获取指定数据的数据详情。
- 表格数据 [创建数据](https://openapi.huoban.com/api-17851172.md): 在指定表格中创建新数据。
- 表格数据 [更新数据](https://openapi.huoban.com/api-17851173.md): 更新指定数据。
- 表格数据 [删除数据](https://openapi.huoban.com/api-17851174.md): 删除指定数据。
- 表格数据 [批量创建数据](https://openapi.huoban.com/api-47403602.md): 在指定表格中创建新数据,支持传入数据的数组做批量创建,单次最多批量创建 100 条数据。
- 表格数据 [批量更新或创建数据](https://openapi.huoban.com/api-72074325.md): 根据指定的依据字段,找到一条数据后,用其他字段更新数据,单次最多批量处理 100 条数据。
- 表格数据 [批量删除数据](https://openapi.huoban.com/api-75852335.md): 在指定表格中删除数据,支持根据传入的 item_ids 批量删除数据,单次最多批量删除 1000 条数据。
- 数据仓库数据 [获取数据仓库表格列表](https://openapi.huoban.com/api-27468361.md): 获取指定工作区内的数据仓库表格列表。
- 数据仓库数据 [获取数据仓库表格配置](https://openapi.huoban.com/api-27468358.md): 获取数据仓库中指定表格的详细字段配置。
- 数据仓库数据 [查询数据列表](https://openapi.huoban.com/api-27468364.md): 获取数据仓库中指定表格的数据列表。
- 数据仓库数据 [获取数据详情](https://openapi.huoban.com/api-27468360.md): 获取数据仓库中指定数据的数据详情。
- 数据仓库数据 [批量创建数据](https://openapi.huoban.com/api-27468359.md): 在数据仓库的指定表格中创建新数据,支持传入数据的数组做批量创建,单次最多批量创建 100 条数据。
- 数据仓库数据 [批量更新数据](https://openapi.huoban.com/api-27468365.md): 在数据仓库的指定表格中,根据指定的依据字段,找到一条数据后,用其他字段更新数据,单次最多批量处理 100 条数据。
- 数据仓库数据 [根据数据ID列表更新成相同数据](https://openapi.huoban.com/api-27468362.md): 在数据仓库的指定表格中更新数据,支持根据传入的 item_ids 批量更新成相同的 fields 字段值结果,只会更新 fields 结构中指定的字段,单次最多批量更新 1000 条数据。
- 数据仓库数据 [批量删除数据](https://openapi.huoban.com/api-27468363.md): 在数据仓库的指定表格中删除数据,支持根据传入的 item_ids 批量删除数据,单次最多批量删除 1000 条数据。
- 流程 [获取流程列表](https://openapi.huoban.com/api-288390793.md): 获取指定工作区内的流程列表。
- 流程 [查询流程实例列表](https://openapi.huoban.com/api-288430234.md): 查询指定范围内的流程实例列表,即用户发起的流程。
- 流程 [获取流程实例详情](https://openapi.huoban.com/api-289039041.md): 获取指定流程实例的详情。
- 流程 [获取流程实例的执行记录](https://openapi.huoban.com/api-289066739.md): 获取指定流程实例的执行记录。
- 流程 [查询流程任务列表](https://openapi.huoban.com/api-289138343.md): 查询指定范围内的流程任务列表,即用户执行的任务。
- 流程 [获取流程任务详情](https://openapi.huoban.com/api-289189688.md): 获取指定流程任务的详情。
- 文件 [批量获取文件详情](https://openapi.huoban.com/api-144471795.md): 用于获取文件详情,单次最多批量获取 100 个文件。
- 文件 [上传文件](https://openapi.huoban.com/api-17851175.md): 单文件上传返回的文件ID需要放入字段中进行存储无法单独使用。
- 订阅 [添加订阅](https://openapi.huoban.com/api-21987345.md): 可以对指定的一个表格订阅数据的创建、修改、删除事件,当数据发生订阅的数据变化后,会将数据内容推送到回调地址。
- 订阅 [取消订阅](https://openapi.huoban.com/api-21987343.md): 可以对指定的一个表格取消已经订阅的数据创建、修改、删除事件。
- 订阅 [获取订阅列表](https://openapi.huoban.com/api-21987344.md): 返回所有订阅的事件。
- 服务商 [获取 access_token](https://openapi.huoban.com/api-21987346.md): access_token 有效期为 2 小时,在此期间调用该接口 access_token 不会改变。当 access_token 有效期小于 30 分的时候,再次请求获取 access_token 的时候,会生成一个新的 access_token与此同时老的 access_token 依然有效。
- 服务商 [获取服务商的 api_key](https://openapi.huoban.com/api-21987347.md): 服务商需要通过 access_token 来将客户的 api_key 换成服务商级别的 api_key之后可正常代客户调用相关业务接口。
- 服务商 [获取服务商信息](https://openapi.huoban.com/api-21987341.md): 服务商需要通过 access_token 获取服务商的基本信息。
- 服务商 [设置订阅回调地址](https://openapi.huoban.com/api-21987342.md): 通过服务商的 access_token 获得的企业 api_key 进行事件订阅后,当订阅的表格数据发生增、删、改后,会回调服务商通过该接口设置的订阅回调地址。
- 服务商 [获取订阅回调地址](https://openapi.huoban.com/api-22648922.md): 获取服务商设置的回调地址