ApiInfoService.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. using Attribute;
  2. using Model;
  3. using Model.Base;
  4. using Repository;
  5. using Service;
  6. using Microsoft.AspNetCore.Mvc;
  7. using Vo.Admin;
  8. using Dto.Admin;
  9. using Infrastructure;
  10. using Common;
  11. using System.Linq;
  12. using Util;
  13. using Custom;
  14. using LitJson;
  15. using Feign;
  16. using Util.Logic;
  17. using Mapster;
  18. using Newtonsoft.Json.Linq;
  19. namespace Services
  20. {
  21. /// <summary>
  22. /// 接口信息Service业务层处理
  23. /// </summary>
  24. [AppService(ServiceType = typeof(IApiInfoService), ServiceLifetime = LifeTime.Transient)]
  25. public class ApiInfoService : BaseService<ApiInfo>, IApiInfoService
  26. {
  27. /// <summary>
  28. /// 接口信息-列表
  29. /// </summary>
  30. /// <param name="param">参数请求体</param>
  31. /// <param name="page">分页参数</param>
  32. /// <returns>列表</returns>
  33. public PagedInfo<GetApiInfoListVo> getApiInfoList([FromQuery] PagerInfo page, [FromQuery] ApiInfo param)
  34. {
  35. //拼装查询条件
  36. var predicate = Expressionable.Create<ApiInfo>();
  37. predicate = predicate.AndIF(param.serviceId > 0, m => m.serviceId == param.serviceId);
  38. predicate = predicate.AndIF(param.groupId > 0, m => m.groupId == param.groupId);
  39. predicate = predicate.AndIF(!string.IsNullOrEmpty(param.tabName), m => m.tabName.Contains(param.tabName));
  40. predicate = predicate.AndIF(!string.IsNullOrEmpty(param.apiName), m => (m.apiName.Contains(param.apiName) || m.tabName.Contains(param.apiName)));
  41. predicate = predicate.AndIF(param.apiKind > 0, m => m.apiKind == param.apiKind);
  42. var response = Queryable()
  43. .Where(predicate.ToExpression())
  44. .OrderByDescending(m => m.tabName)
  45. .OrderByDescending(m => m.apiName)
  46. .OrderByDescending(m => m.id)
  47. .ToPage<ApiInfo, GetApiInfoListVo>(page);
  48. return response;
  49. }
  50. /// <summary>
  51. /// 接口信息-字段关联接口列表
  52. /// </summary>
  53. /// <param name="param">参数请求体</param>
  54. /// <param name="page">分页参数</param>
  55. /// <returns>字段关联接口列表</returns>
  56. public PagedInfo<GetApiInfoListByProIdVo> getApiInfoListByProId([FromQuery] PagerInfo page, [FromQuery] ApiInfo param)
  57. {
  58. //拼装查询条件
  59. var predicate = Expressionable.Create<ApiInfo>();
  60. predicate = predicate.AndIF(param.serviceId > 0, m => m.serviceId == param.serviceId);
  61. var response = Queryable()
  62. .Where(predicate.ToExpression())
  63. .OrderByDescending(m => m.id)
  64. .ToPage<ApiInfo, GetApiInfoListByProIdVo>(page);
  65. return response;
  66. }
  67. /// <summary>
  68. /// 克隆接口
  69. /// </summary>
  70. /// <param name="param">参数请求体</param>
  71. public void copyApiInfo([FromBody] CopyApiInfoDto param, ApiGroup group)
  72. {
  73. // var group = _ApiGroupService.GetFirst(m => m.id == param.targetGroupId) ?? new ApiGroup();
  74. var user = JwtUtil.GetLoginUser(App.HttpContext);
  75. List<int> apiIdList = Tools.SpitIntArrary(param.sourceApiId).ToList();
  76. var sourceApis = GetList(m => apiIdList.Contains(m.id)).ToList();
  77. foreach(ApiInfo sourceApi in sourceApis)
  78. {
  79. ApiInfo newApi = new ApiInfo();
  80. newApi.serviceId = group.serviceId;
  81. newApi.groupId = param.targetApiGroupId;
  82. newApi.tabName = sourceApi.tabName;
  83. newApi.apiName = sourceApi.apiName;
  84. newApi.controllerFilePath = sourceApi.controllerFilePath;
  85. newApi.usageScenarios = sourceApi.usageScenarios;
  86. newApi.apiKind = sourceApi.apiKind;
  87. newApi.methodName = sourceApi.methodName;
  88. newApi.apiDetail = sourceApi.apiDetail;
  89. newApi.apiParam = sourceApi.apiParam;
  90. newApi.createTime = DateTime.Now;
  91. newApi.createBy = user.username ?? "";
  92. newApi.linkTableId = sourceApi.linkTableId;
  93. newApi.pageFlag = sourceApi.pageFlag;
  94. Add(newApi);
  95. }
  96. }
  97. /// <summary>
  98. /// 初始化接口
  99. /// </summary>
  100. public void initApiInfo([FromBody] InitApiInfoDto param)
  101. {
  102. var user = JwtUtil.GetLoginUser(App.HttpContext);
  103. var _DatabaseInfoService = App.GetService<IDatabaseInfoService>();
  104. var _DatabaseTableService = App.GetService<IDatabaseTableService>();
  105. var _DatabaseFieldService = App.GetService<IDatabaseFieldService>();
  106. var _ApiGroupService = App.GetService<IApiGroupService>();
  107. var apiGroup = _ApiGroupService.GetFirst(m => m.id == param.groupId) ?? new ApiGroup();
  108. foreach(int tableId in param.sourceTableId)
  109. {
  110. var table = _DatabaseTableService.GetById(tableId) ?? new DatabaseTable();
  111. var database = _DatabaseInfoService.GetFirst(m => m.id == table.databaseId) ?? new DatabaseInfo();
  112. var fields = _DatabaseFieldService.GetList(m => m.tableId == table.id);
  113. for (int apiKind = 1; apiKind <= 5; apiKind++)
  114. {
  115. var apiParam = new List<ApiParamObject>();
  116. foreach(var field in fields)
  117. {
  118. bool reqParam = false;
  119. bool resParam = false;
  120. if((field.showQuery && apiKind == 1) || (field.showEdit && (apiKind == 3 || apiKind == 4)))
  121. {
  122. reqParam = true;
  123. }
  124. if((apiKind == 2 || apiKind == 4 || apiKind == 5) && field.primaryKey)
  125. {
  126. reqParam = true;
  127. }
  128. if(field.showList && (apiKind == 1 || apiKind == 2))
  129. {
  130. resParam = true;
  131. }
  132. apiParam.Add(new ApiParamObject()
  133. {
  134. id = field.id,
  135. fieldTitle = field.fieldTitle ?? "",
  136. fieldName = field.fieldName ?? "",
  137. fieldType = field.fieldType ?? "",
  138. reqParam = reqParam,
  139. resParam = resParam,
  140. resType = "字段值",
  141. checkAttribute = !string.IsNullOrEmpty(field.validateAttribute) ? field.validateAttribute.Split(',') : Array.Empty<string>(),
  142. fieldDetail = field.fieldDetail ?? "",
  143. });
  144. }
  145. Add(new ApiInfo()
  146. {
  147. serviceId = apiGroup.serviceId,
  148. groupId = param.groupId,
  149. tabName = "基本信息",
  150. apiName = table.tableTitle + (apiKind == 1 ? "列表" : apiKind == 2 ? "详情" : apiKind == 3 ? "添加" : apiKind == 4 ? "修改" : "删除"),
  151. controllerFilePath = table.tableNameUpper,
  152. apiKind = apiKind,
  153. methodName = apiKind == 1 ? "get" + table.tableNameFirstUpper + "List" :
  154. apiKind == 2 ? "get" + table.tableNameFirstUpper + "Query" :
  155. apiKind == 3 ? "add" + table.tableNameFirstUpper :
  156. apiKind == 4 ? "update" + table.tableNameFirstUpper :
  157. "delete" + table.tableNameFirstUpper,
  158. apiDetail = apiKind == 1 ? "根据条件查询" + table.tableTitle + "列表数据" :
  159. apiKind == 2 ? "根据Id查询" + table.tableTitle + "某一条详情数据" :
  160. apiKind == 3 ? "添加" + table.tableTitle + "数据" :
  161. apiKind == 4 ? "修改" + table.tableTitle + "数据" :
  162. "根据Id删除" + table.tableTitle + "数据",
  163. apiParam = apiParam,
  164. createTime = DateTime.Now,
  165. linkTableId = tableId,
  166. pageFlag = apiKind == 1,
  167. createBy = user.username ?? "",
  168. });
  169. }
  170. }
  171. }
  172. /// <summary>
  173. /// 获取编辑组件类型
  174. /// </summary>
  175. /// <param name="fieldTitle">字段标题</param>
  176. /// <param name="fieldType">字段类型</param>
  177. /// <returns>编辑组件类型</returns>
  178. public EditTypeFrontend getEditType(string fieldTitle, string fieldType)
  179. {
  180. List<EditTypeFrontend> editType = getEditTypes();
  181. try
  182. {
  183. if (fieldTitle.Contains("密码"))
  184. {
  185. return editType.FirstOrDefault(m => m.name == "password") ?? new EditTypeFrontend() { name = "input", tag = "ElInput", title = "输入框" };
  186. }
  187. else if (fieldTitle.Contains("验证码"))
  188. {
  189. return editType.FirstOrDefault(m => m.name == "phonecode") ?? new EditTypeFrontend() { name = "input", tag = "ElInput", title = "输入框" };
  190. }
  191. else if (fieldTitle.Contains("图片") || fieldTitle.Contains("头像") || fieldTitle.Contains("照片"))
  192. {
  193. return editType.FirstOrDefault(m => m.name == "image") ?? new EditTypeFrontend() { name = "input", tag = "ElInput", title = "输入框" };
  194. }
  195. else if (fieldTitle.Contains("文件") || fieldTitle.Contains("附件"))
  196. {
  197. return editType.FirstOrDefault(m => m.name == "file") ?? new EditTypeFrontend() { name = "input", tag = "ElInput", title = "输入框" };
  198. }
  199. else if (fieldTitle.Contains("内容") || fieldTitle.Contains("详情") || fieldTitle.Contains("描述"))
  200. {
  201. return editType.FirstOrDefault(m => m.name == "editor") ?? new EditTypeFrontend() { name = "input", tag = "ElInput", title = "输入框" };
  202. }
  203. else if (fieldTitle.Contains("类型") || fieldTitle.Contains("分类") || fieldTitle.Contains("状态"))
  204. {
  205. return editType.FirstOrDefault(m => m.name == "select") ?? new EditTypeFrontend() { name = "input", tag = "ElInput", title = "输入框" };
  206. }
  207. else if (fieldTitle.Contains("日期") || fieldTitle.Contains("时间"))
  208. {
  209. return editType.FirstOrDefault(m => m.name == "datePicker") ?? new EditTypeFrontend() { name = "input", tag = "ElInput", title = "输入框" };
  210. }
  211. else if (fieldTitle.Contains("开关") || fieldTitle.Contains("是否") || fieldTitle.Contains("启用") || fieldTitle.Contains("禁用"))
  212. {
  213. return editType.FirstOrDefault(m => m.name == "switch") ?? new EditTypeFrontend() { name = "input", tag = "ElInput", title = "输入框" };
  214. }
  215. if (fieldType == "varchar" || fieldType == "nvarchar" || fieldType == "text")
  216. {
  217. return editType.FirstOrDefault(m => m.name == "input") ?? new EditTypeFrontend() { name = "input", tag = "ElInput", title = "输入框" };
  218. }
  219. else if (fieldType == "int" || fieldType == "bigint" || fieldType == "decimal" || fieldType == "float")
  220. {
  221. return editType.FirstOrDefault(m => m.name == "number") ?? new EditTypeFrontend() { name = "input", tag = "ElInput", title = "输入框" };
  222. }
  223. else if (fieldType == "datetime" || fieldType == "date")
  224. {
  225. return editType.FirstOrDefault(m => m.name == "datePicker") ?? new EditTypeFrontend() { name = "input", tag = "ElInput", title = "输入框" };
  226. }
  227. else if (fieldType == "bit")
  228. {
  229. return editType.FirstOrDefault(m => m.name == "switch") ?? new EditTypeFrontend() { name = "input", tag = "ElInput", title = "输入框" };
  230. }
  231. else if (fieldType == "json")
  232. {
  233. return editType.FirstOrDefault(m => m.name == "json") ?? new EditTypeFrontend() { name = "input", tag = "ElInput", title = "输入框" };
  234. }
  235. }
  236. catch (Exception ex)
  237. {
  238. Utils.WriteLog(ex.ToString());
  239. return new EditTypeFrontend() { name = "input", tag = "ElInput", title = "输入框" };
  240. }
  241. return new EditTypeFrontend() { name = "input", tag = "ElInput", title = "输入框" };
  242. }
  243. public List<EditTypeFrontend> getEditTypes()
  244. {
  245. List<EditTypeFrontend> editType = new List<EditTypeFrontend>();
  246. editType.Add(new EditTypeFrontend() { name = "input", tag = "ElInput", title = "输入框" });
  247. editType.Add(new EditTypeFrontend() { name = "password", tag = "ElInput", title = "密码输入框" });
  248. editType.Add(new EditTypeFrontend() { name = "phonecode", tag = "PhoneCode", title = "手机验证码组件" });
  249. editType.Add(new EditTypeFrontend() { name = "select", tag = "ElSelect", title = "选择器" });
  250. editType.Add(new EditTypeFrontend() { name = "picker", tag = "ElDatePicker", title = "日期选择器" });
  251. editType.Add(new EditTypeFrontend() { name = "datePicker", tag = "ElDatePicker", title = "日期选择器" });
  252. editType.Add(new EditTypeFrontend() { name = "timePicker", tag = "ElTimePicker", title = "时间选择器" });
  253. editType.Add(new EditTypeFrontend() { name = "number", tag = "ElInputNumber", title = "数字输入框" });
  254. editType.Add(new EditTypeFrontend() { name = "cascader", tag = "ElCascader", title = "级联选择器" });
  255. editType.Add(new EditTypeFrontend() { name = "Json", tag = "JsonEditor", title = "JSON" });
  256. editType.Add(new EditTypeFrontend() { name = "editor", tag = "TextEditor", title = "富文本编辑器" });
  257. editType.Add(new EditTypeFrontend() { name = "image", tag = "OmegaUpload", title = "图片上传" });
  258. editType.Add(new EditTypeFrontend() { name = "file", tag = "OmegaUpload", title = "文件上传" });
  259. editType.Add(new EditTypeFrontend() { name = "switch", tag = "ElSwitch", title = "开关" });
  260. editType.Add(new EditTypeFrontend() { name = "transfer", tag = "ElTransfer", title = "穿梭框" });
  261. editType.Add(new EditTypeFrontend() { name = "autocomplete", tag = "ElAutocomplete", title = "自动完成" });
  262. editType.Add(new EditTypeFrontend() { name = "treeSelect", tag = "ElTreeSelect", title = "树形选择器" });
  263. editType.Add(new EditTypeFrontend() { name = "tree", tag = "ElTree", title = "树形控件" });
  264. editType.Add(new EditTypeFrontend() { name = "radio", tag = "ElRadio", title = "单选框" });
  265. editType.Add(new EditTypeFrontend() { name = "radioGroup", tag = "ElRadioGroup", title = "单选框组" });
  266. editType.Add(new EditTypeFrontend() { name = "checkbox", tag = "ElCheckbox", title = "复选框" });
  267. editType.Add(new EditTypeFrontend() { name = "checkboxGroup", tag = "ElCheckboxGroup", title = "复选框组" });
  268. editType.Add(new EditTypeFrontend() { name = "slider", tag = "ElSlider", title = "滑块" });
  269. editType.Add(new EditTypeFrontend() { name = "rate", tag = "ElRate", title = "评分" });
  270. editType.Add(new EditTypeFrontend() { name = "colorPicker", tag = "ElColorPicker", title = "颜色选择器" });
  271. return editType;
  272. }
  273. /// <summary>
  274. /// 测试接口
  275. /// </summary>
  276. public TestApiInfoVo testApiInfo([FromBody] TestApiInfoDto param, List<ApiGroup> groups)
  277. {
  278. if (string.IsNullOrEmpty(param.idList))
  279. {
  280. return new TestApiInfoVo()
  281. {
  282. testResult = "没有传入接口ID"
  283. };
  284. }
  285. Utils.WriteLog("1", "测试接口");
  286. List<Dictionary<string, object>> testResult = new List<Dictionary<string, object>>();
  287. List<Dictionary<string, object>> testResultSuccess = new List<Dictionary<string, object>>();
  288. List<int> ids = Tools.SpitIntArrary(param.idList).ToList();
  289. var apiList = GetList(m => ids.Contains(m.id));
  290. var service = IProject.getProjectService(apiList.FirstOrDefault().serviceId);
  291. Utils.WriteLog(JsonMapper.ToJson(service), "测试接口");
  292. var project = IProject.getProject(service.projectId);
  293. Utils.WriteLog(JsonMapper.ToJson(project), "测试接口");
  294. string encryptKind = project.encryptKind ?? "";
  295. string encryptParam = project.encryptParam ?? "{}";
  296. JsonData jsonEncryptParam = JsonMapper.ToObject(encryptParam);
  297. string gatewayHost = project.gatewayHostDev ?? "";
  298. if(gatewayHost.Contains(":"))
  299. {
  300. var gatewayHostArray = gatewayHost.Split(":");
  301. gatewayHost = gatewayHostArray[0];
  302. string port = gatewayHostArray[1];
  303. if (port == "443")
  304. {
  305. gatewayHost = "https://" + gatewayHost;
  306. }
  307. else if (port == "80")
  308. {
  309. gatewayHost = "http://" + gatewayHost;
  310. }
  311. else
  312. {
  313. gatewayHost = "http://" + gatewayHost + ":" + port;
  314. }
  315. }
  316. else
  317. {
  318. gatewayHost = "http://" + gatewayHost;
  319. }
  320. Utils.WriteLog(gatewayHost, "测试接口");
  321. Dictionary<string, string> headers = new Dictionary<string, string>(); //请求头
  322. if(!string.IsNullOrEmpty(param.headers))
  323. {
  324. headers = JsonMapper.ToObject<Dictionary<string, string>>(param.headers);
  325. }
  326. Utils.WriteLog(JsonMapper.ToJson(headers), "测试接口");
  327. foreach (var apiInfo in apiList)
  328. {
  329. Utils.WriteLog(JsonMapper.ToJson(apiInfo), "测试接口");
  330. var group = groups.FirstOrDefault(m => m.id == apiInfo.groupId) ?? new ApiGroup();
  331. var apiInfoItem = apiInfo.Adapt<ApiTreeInfo>();
  332. apiInfoItem.apiPath = gatewayHost + "/v1/" + group.groupName + "/" + apiInfo.controllerNameUpper + "/" + apiInfoItem.methodName;
  333. Dictionary<string, object> apiItem = new Dictionary<string, object>();
  334. Dictionary<string, string> reqParams = new Dictionary<string, string>();
  335. if(string.IsNullOrEmpty(param.reqData))
  336. {
  337. if(apiInfo.apiParam != null)
  338. {
  339. reqParams = apiInfo.apiParam.Where(m => m.reqParam).ToDictionary(m => m.fieldName, m => TestDataGenerator.GenerateValue(m.fieldType));
  340. }
  341. }
  342. else
  343. {
  344. reqParams = JsonMapper.ToObject<Dictionary<string, string>>(param.reqData);
  345. }
  346. string response = ApiTestHelper.apiTestRequest(apiInfoItem, encryptKind, encryptParam, reqParams, headers);
  347. string reqParamEncrypt = "";
  348. string statusCode = "未知";
  349. if(response.Contains("|"))
  350. {
  351. reqParamEncrypt = response.Split("|")[0];
  352. response = response.Split("|")[1];
  353. if(response.Split("|").Length > 2)
  354. {
  355. statusCode = response.Split("|")[2];
  356. }
  357. }
  358. apiItem.Add("接口名称", apiInfoItem.tabName + "-" + apiInfoItem.apiName);
  359. apiItem.Add("请求头", headers);
  360. apiItem.Add("请求参数", reqParams);
  361. apiItem.Add("请求参数加密", reqParamEncrypt);
  362. apiItem.Add("返回状态码", statusCode);
  363. apiItem.Add("返回报文", response);
  364. apiItem.Add("请求地址", apiInfoItem.apiPath);
  365. if(statusCode == "200")
  366. {
  367. testResultSuccess.Add(apiItem);
  368. }
  369. else
  370. {
  371. testResult.Add(apiItem);
  372. }
  373. }
  374. if(testResultSuccess.Count > 0)
  375. {
  376. testResult = testResultSuccess.Concat(testResult).ToList();
  377. }
  378. return new TestApiInfoVo()
  379. {
  380. testResult = JsonMapper.ToJson(testResult)
  381. };
  382. }
  383. }
  384. }