using Furion.DependencyInjection; using Newtonsoft.Json.Linq; using RoadFlow.Utility; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Caching.Memory; using Furion; using Ewide.Core; using Microsoft.Extensions.Localization; using Ewide.RoadFlowLite.Utility; using System.Web; using System.Data.Common; using Furion.FriendlyException; using System.IO; using SqlSugar; namespace RoadFlow.Data { public class Form:RoadFlowRepository,IForm, ITransient { /// /// 获取表单运行时HTML /// /// 表单ID /// 预览表单时传 /// 预览表单时传 /// 表单相关属性json public JObject GetRunJObject(string formId, string attrJson = "", string eventJson = "") { if (formId.IsNullOrEmpty())//如果是空GUID返回一个空对象。防止有些程序没有设置表单。 { JObject emptyObject = new JObject(); emptyObject.Add("id", formId.ToString()); emptyObject.Add("form_iscustomeform", 0); emptyObject.Add("conn", string.Empty); emptyObject.Add("table", string.Empty); emptyObject.Add("primaryKey", string.Empty); emptyObject.Add("titleField", string.Empty); emptyObject.Add("titleExpression", string.Empty); emptyObject.Add("validatePromptType", string.Empty); emptyObject.Add("formatJson", new JArray()); emptyObject.Add("eventJson", new JArray()); emptyObject.Add("valueTypeJson", new JObject()); emptyObject.Add("defaultValueJson", new JObject()); emptyObject.Add("linkageJson", new JArray()); emptyObject.Add("serialnumberJson", new JArray()); emptyObject.Add("editorJson", new JArray()); emptyObject.Add("datatableJson", new JArray()); emptyObject.Add("subtableJson", new JArray()); emptyObject.Add("html", string.Empty); emptyObject.Add("script", string.Empty); return emptyObject; } bool isPreview = !attrJson.IsNullOrWhiteSpace() && !eventJson.IsNullOrWhiteSpace();//是否是预览 string cacheKey = "roadflow_form_runobject_" + formId.ToLower(); if (!isPreview) { object obj = _memoryCache.Get(cacheKey); if (obj != null && (obj is JObject jobj)) { return jobj; } } JObject jObject = new JObject(); var formModel = GetOneById(formId); if (formModel == null) { return jObject; } JObject attrObject = JObject.Parse(attrJson.IsNullOrWhiteSpace() ? formModel.attribute : attrJson); jObject.Add("id", formId.ToString()); jObject.Add("form_iscustomeform", 0); jObject.Add("conn", attrObject.Value("dbConn")); jObject.Add("table", attrObject.Value("dbTable")); jObject.Add("primaryKey", attrObject.Value("dbTablePrimaryKey")); jObject.Add("titleField", attrObject.Value("dbTableTitle")); jObject.Add("titleExpression", attrObject.Value("dbTableTitleExpression")); jObject.Add("validatePromptType", attrObject.Value("validatePromptType")); jObject.Add("formatJson", attrObject.Value("formatJson")); jObject.Add("eventJson", eventJson.IsNullOrWhiteSpace() ? formModel.EventJSON.ToJArray() : eventJson.ToJArray()); jObject.Add("valueTypeJson", attrObject.Value("valueTypeJson")); jObject.Add("defaultValueJson", attrObject.Value("defaultValueJson")); jObject.Add("linkageJson", attrObject.Value("linkageJson")); jObject.Add("serialnumberJson", attrObject.ContainsKey("serialnumber") ? attrObject.Value("serialnumber") : new JArray()); jObject.Add("editorJson", attrObject.ContainsKey("editor") ? attrObject.Value("editor") : new JArray()); jObject.Add("datatableJson", attrObject.ContainsKey("datatable") ? attrObject.Value("datatable") : new JArray()); jObject.Add("subtableJson", attrObject.ContainsKey("subtable") ? attrObject.Value("subtable") : new JArray()); jObject.Add("html", formModel.RunHtml); jObject.Add("script", attrObject.Value("script")); if (!isPreview) { _memoryCache.Set(cacheKey, jObject); } return jObject; } /// /// 查询表单数据 /// /// /// /// /// /// /// /// /// 动态步骤模式时用于获取步骤字段状态 /// public string GetFormData(string connId, string tableName, string primaryKey, string instanceId, string stepId, string flowId, string formatJSON, out string fieldStatusJSON, string groupId = "") { fieldStatusJSON = "[]"; #region 查询字段状态 List stepFieldStatuses = new List(); if (flowId.IsGuid(out Guid flowGuid)) { var (dynamicTask, currentTask, groupTasks) = new FlowTask().GetDynamicTask(groupId, null); var flowrunModel = new Flow().GetFlowRunModel(flowId, true, dynamicTask); if (null != flowrunModel) { Guid stepGuid = stepId.IsGuid(out Guid sid) ? sid : flowrunModel.FirstStepId; var stepModel = flowrunModel.Steps.Find(p => p.Id == stepGuid); if (null != stepModel) { JArray fArray = new JArray(); stepFieldStatuses = stepModel.StepFieldStatuses; foreach (var fieldStatus in stepFieldStatuses) { string[] fileds = fieldStatus.Field.Split('.'); if (fileds.Length != 3) { continue; } JObject fObject = new JObject { { "name", (fileds[1] + "-" + fileds[2]).ToUpper() }, { "status", fieldStatus.Status }, { "check", fieldStatus.Check } }; fArray.Add(fObject); } fieldStatusJSON = fArray.ToString(Newtonsoft.Json.Formatting.None); } } } else if (Tools.HttpContext.Request.Querys("programid").IsGuid(out Guid pId)) //生成程序获取字段状态 { var programRunModel = RoadFlow.Utility.Config.IsVue ? new Program().VueGetRunModel(pId.ToString(), null, string.Empty) : new Program().GetRunModel(pId.ToString()); if (null != programRunModel) { var fieldStatusList = programRunModel.ProgramValidates; JArray fArray = new JArray(); foreach (var fieldStatus in fieldStatusList) { JObject fObject = new JObject { { "name", (fieldStatus.TableName + "-" + fieldStatus.FieldName).ToUpper() }, { "status", fieldStatus.Status }, { "check", fieldStatus.ValidateType } }; fArray.Add(fObject); } fieldStatusJSON = fArray.ToString(Newtonsoft.Json.Formatting.None); } } #endregion if (!connId.IsGuid(out Guid connGuid)) { return "[]"; } DbConnection dbConnection = new DbConnection(); var dbconnectionModel = dbConnection.GetOneById(connId); if (null == dbconnectionModel) { return "[]"; } JArray formatArray = null; try { formatArray = JArray.Parse(formatJSON); } catch { } DataTable dataTable = GetFormDataTable(dbconnectionModel, tableName, primaryKey, instanceId); if (dataTable.Rows.Count == 0) { return "[]"; } JArray jArray = new JArray(); foreach (DataColumn column in dataTable.Columns) { //检查字段状态,如果是隐藏则不返回数据 var fieldStatus = stepFieldStatuses.Find(p => p.Field.EqualsIgnoreCase(dbconnectionModel.Id + "." + tableName + "." + column.ColumnName)); if (null != fieldStatus && fieldStatus.Status == 2) { continue; } string name = (tableName + "-" + column.ColumnName).ToUpper(); string value = dataTable.Rows[0][column.ColumnName].ToString(); #region 格式化 if (formatArray != null) { foreach (JObject formatObject in formatArray) { if (name.Equals(formatObject.Value("id"))) { string type = formatObject.Value("type"); string format = formatObject.Value("format"); if (!format.IsNullOrWhiteSpace()) { switch (type) { case "datetime": value = value.IsDateTime(out DateTime dt) ? dt.ToString(format) : ""; break; default: if (value.IsDecimal(out decimal d)) { value = d.ToString(format); } break; } } } } } #endregion JObject jObject = new JObject { { "name", name }, { "value", value } }; jArray.Add(jObject); } return jArray.ToString(Newtonsoft.Json.Formatting.None); } /// /// 根据字符串表达式得到选项 /// /// 选项文本1,选项值1;选项文本2,选项值2 /// public string GetOptionsByStringExpression(string expression, string defaultValue = "") { if (expression.IsNullOrWhiteSpace()) { return string.Empty; } string[] array = expression.Split(';'); StringBuilder stringBuilder = new StringBuilder(); foreach (string arr in array) { if (arr.IsNullOrWhiteSpace()) { continue; } string[] array1 = arr.Split(','); string title = array1[0]; string value = array1.Length > 1 ? array1[1] : title; stringBuilder.Append(""); } return stringBuilder.ToString(); } /// /// 根据SQL得到下拉选项 /// /// /// /// /// public string GetOptionsBySQL(string connId, string sql, string value) { if (!connId.IsGuid(out Guid cid) || sql.IsNullOrWhiteSpace()) { return ""; } DbConnection dbConnection = new DbConnection(); DataTable dt; try { dt = dbConnection.GetDataTable(dbConnection.GetOneById(connId), RoadFlow.Business.Wildcard.Filter(sql.FilterSelectSql())); } catch { dt = new DataTable(); } StringBuilder stringBuilder = new StringBuilder(); foreach (DataRow dr in dt.Rows) { string value1 = string.Empty; string title = string.Empty; if (dt.Columns.Count > 0) { value1 = dr[0].ToString(); } if (dt.Columns.Count > 1) { title = dr[1].ToString(); } else { title = value1; } if (value1.IsNullOrWhiteSpace() || title.IsNullOrWhiteSpace()) { continue; } stringBuilder.Append(""); } return stringBuilder.ToString(); } /// /// 查询表单数据 /// /// /// /// /// /// public DataTable GetFormDataTable(Model.rf_dbconnection dbConnectionModel, string tableName, string primaryKey, string instanceId) { return new DbConnection().GetDataTable(dbConnectionModel, tableName, primaryKey, instanceId); } /// /// 得到一个连接SQL的数据表JArray /// /// /// /// (rows, cols) public (JArray, JArray) GetDataTablJArray(string connId, string sql) { JArray rowsArray = new JArray(); JArray colsArray = new JArray(); if (sql.IsNullOrWhiteSpace()) { return (rowsArray, colsArray); } DbConnection dbcn = new DbConnection(); DataTable dt = dbcn.GetDataTable(dbcn.GetOneById(connId), sql); if (dt == null || dt.Rows.Count == 0) { return (rowsArray, colsArray); } //添加一列KEY string keyColName = "key_" + Tools.GetRandomString(4); colsArray.Add(new JObject() { { "name", keyColName}, { "show", 0 }, { "key", true }, }); foreach (DataColumn col in dt.Columns) { colsArray.Add(new JObject() { { "name", col.ColumnName }, { "title", col.ColumnName }, }); } int i = 0; foreach (DataRow dr in dt.Rows) { JObject rowObject = new JObject { { keyColName, i++ } }; foreach (DataColumn col in dt.Columns) { rowObject.Add(col.ColumnName, dr[col.ColumnName].ToString()); } rowsArray.Add(rowObject); } return (rowsArray, colsArray); } /// /// 得到子表行数据 /// /// /// 连接id /// 实例id /// public JArray GetSubTableJarray(JObject jObject, string connId, string instanceId) { JArray rowsArray = new JArray(); if (connId.IsNullOrWhiteSpace() || instanceId.IsNullOrEmpty()) { return rowsArray; } //string id = jObject.Value("id"); string subTable = jObject.Value("subTable"); string subTableKey = jObject.Value("subTableKey"); string linkField = jObject.Value("linkField"); string sort = jObject.Value("sort").Trim1(); JArray selectRows = jObject.Value("selectRows"); StringBuilder fields = new StringBuilder(subTableKey + ","); foreach (JValue selectRow in selectRows) { fields.Append(selectRow.ToString()); fields.Append(","); } string sql = "select " + fields.ToString().TrimEnd(',') + " from " + subTable + " where " + linkField + "={0} " + (sort.IsNullOrWhiteSpace() ? "" : sort.StartsWith("order by", StringComparison.CurrentCultureIgnoreCase) ? sort : "order by " + sort); var dbcon = new DbConnection(); DataTable dt = dbcon.GetDataTable(dbcon.GetOneById(connId), sql, instanceId); foreach (DataRow dr in dt.Rows) { JObject rowObject = new JObject { { subTableKey, dr[subTableKey].ToString() } }; JArray rowsJArray = jObject.Value("rows"); foreach (JValue selectRow in selectRows) { string field = selectRow.ToString(); string val = dr[field].ToString(); //检查是否需要格式化 foreach (JObject rowsObject in rowsJArray) { if (rowsObject.Value("field").Equals(field)) { string ctlformat = rowsObject.Value("ctlformat"); if (!ctlformat.IsNullOrWhiteSpace()) { val = val.IsDecimal(out decimal dec) ? dec.ToString(ctlformat) : val; } break; } } rowObject.Add(field, val); } rowsArray.Add(rowObject); } return rowsArray; } /// /// 得到子表默认值json /// /// /// public JArray GetSubTableDefaultValueJArray(JArray jArray, SysUser userModel = null) { JArray valueObject = new JArray(); foreach (JObject jObject in jArray) { string id = jObject.Value("id"); JObject jObject1 = new JObject() { { "id", id } }; JObject jObject2 = new JObject(); foreach (JObject rowObject in jObject.Value("rows")) { string ctlDefault = rowObject.Value("ctldefault"); string field = rowObject.Value("field"); if (ctlDefault.IsNullOrEmpty()) { continue; } string defaultValue = RoadFlow.Business.Wildcard.Filter(ctlDefault, userModel); jObject2.Add(field, defaultValue); } jObject1.Add("value", jObject2); valueObject.Add(jObject1); } return valueObject; } /// /// 保存表单数据(vue前后分离方式) /// /// 业务表主键值, 错误信息 /// 当前请求 public (string, string) SaveDataVue(JObject args, IStringLocalizer localizer = null) { string form_id = args.GetJsonValue("form_id"); JObject formObject = GetRunJObject(form_id); string form_dbconnid = formObject.Value("conn");// request.Forms("form_dbconnid"); string form_dbtable = formObject.Value("table");//request.Forms("form_dbtable"); string form_dbtableprimarykey = formObject.Value("primaryKey");//request.Forms("form_dbtableprimarykey"); string form_instanceid = args.GetJsonValue("form_instanceid"); string form_fieldstatus = args.GetJsonValue("form_fieldstatus"); JArray serialnumberJson = formObject.Value("serialnumberJson");//取出流水号设置 JArray subtableJson = formObject.Value("subtableJson");//取出子表 //如果是自定义表单iframe加载的,不在这里保存 if ("1".Equals(args.GetJsonValue("form_iscustomeform"))) { return (form_instanceid, string.Empty); } if (form_instanceid.IsNullOrWhiteSpace()) { form_instanceid = args.GetJsonValue("instanceid"); } if (form_instanceid.IsNullOrWhiteSpace()) { form_instanceid = args.GetJsonValue("instanceid"); } if (!form_dbconnid.IsGuid(out Guid connId)) { return (string.Empty, localizer == null ? "连接ID为空" : localizer["Execute_SaveDataConnIdEmpty"]); } if (form_dbtable.IsNullOrWhiteSpace() || form_dbtableprimarykey.IsNullOrWhiteSpace()) { return (string.Empty, localizer == null ? "表名为空" : localizer["Execute_SaveDataTableNameEmpty"]); } DbConnection dbConnection = new DbConnection(); Model.rf_dbconnection dbConnectionModel = dbConnection.GetOneById(form_dbconnid); if (null == dbConnectionModel) { return (string.Empty, localizer == null ? "未找到连接实体" : localizer["Execute_SaveDataConnModelNotFound"]); } var tableFields = dbConnection.GetTableFields(dbConnectionModel, form_dbtable); if (tableFields.Count == 0) { return (string.Empty, localizer == null ? "表没有字段" : localizer["Execute_SaveDataTableNotField"]); } JArray fieldStatusArray = null; try { fieldStatusArray = JArray.Parse(form_fieldstatus); } catch { } object newInstanceId = form_instanceid;//主键值 bool isIdentity = false; string seqName = string.Empty;//数据库为oracle时的序列名称 #region 保存主表 bool isAdd = form_instanceid.IsNullOrWhiteSpace(); DataTable oldData = null; if (!isAdd)//如果不是新增,要查询旧数据,以便值为空时填充旧数据 { oldData = GetFormDataTable(dbConnectionModel, form_dbtable, form_dbtableprimarykey, form_instanceid); } //dicts 字段名称,字段值字典,tableName 表名, primaryKey 主键, flag 0删除 1新增 2修改 List<(Dictionary dicts, string tableName, string primaryKey, int flag)> tuples = new List<(Dictionary dicts, string tableName, string primaryKey, int flag)>(); Dictionary tableDict = new Dictionary(); foreach (var field in tableFields) { string controlName = (form_dbtable + "-" + field.FieldName).ToUpper(); string value = args.GetJsonValue(controlName); bool isPrimaryKey = form_dbtableprimarykey.EqualsIgnoreCase(field.FieldName); int fieldStatus = 0;//字段状态 0编辑 1只读 2隐藏 if (fieldStatusArray != null) { foreach (JObject jObject in fieldStatusArray) { if (jObject.Value("name").Equals(controlName)) { fieldStatus = jObject.Value("status"); break; } } } if (isPrimaryKey &&value.IsNullOrWhiteSpace())//如果是主键 { #region 主键 if (!isAdd)//如果是修改则直接添加主键值 { tableDict.Add(field.FieldName, newInstanceId); continue; } if (field.Type.EqualsIgnoreCase("uniqueidentifier") || field.Type.ContainsIgnoreCase("char") || field.Type.ContainsIgnoreCase("uuid"))//如果是字符串,则自动生成GUID, postgresql为uuid { newInstanceId = GuidExtensions.NewGuid(); tableDict.Add(field.FieldName, newInstanceId); } //由于oracle无法判断列是否是使用了序列,所以这里如果是主键并且数据类型是数字,则认为是自增类型 else if (field.IsIdentity || field.Type.ContainsIgnoreCase("number") || field.Type.StartsWith("int", StringComparison.CurrentCultureIgnoreCase) || field.Type.ContainsIgnoreCase("long")) { isIdentity = true; seqName = form_dbtable + "_" + field.FieldName + "_SEQ";//oracle和postgresql规定序列名称为表名_字段名_SEQ } continue; #endregion } else { #region 流水号 if (value.IsNullOrEmpty() && fieldStatus == 0) { JObject serialnumber_config = null; foreach (JObject jObject in serialnumberJson) { if (jObject.Value("id").EqualsIgnoreCase(controlName)) { serialnumber_config = jObject; break; } } if (serialnumber_config != null) { var (searialNumber, maxField, maxValue) = GetSerialNumber(dbConnectionModel, form_dbtable, string.Empty, serialnumber_config); tableDict.Add(field.FieldName, searialNumber); if (!maxField.IsNullOrWhiteSpace() && !tableDict.Keys.Any(p => p.EqualsIgnoreCase(maxField))) { tableDict.Add(maxField, maxValue); } continue; } } #endregion if (fieldStatus != 0) { continue; } if (tableDict.ContainsKey(field.FieldName) || tableDict.Keys.Any(p => p.EqualsIgnoreCase(field.FieldName))) { continue; } if (field.Type.ContainsIgnoreCase("date"))//如果是日期时间要验证数据 { if (value.IsDateTime(out DateTime dt)) { tableDict.Add(field.FieldName, dt); } else { if (oldData != null && oldData.Rows.Count > 0) { tableDict.Add(field.FieldName, oldData.Rows[0][field.FieldName]); } else if (field.IsNull && !field.IsDefault) { tableDict.Add(field.FieldName, DBNull.Value); } } } else { if (null == value) { //2020-2-15注释掉,解决如果这里是checkbox时全不选会用旧数据填充。 //2020-10-20取消注释 if (oldData != null && oldData.Rows.Count > 0) { tableDict.Add(field.FieldName, oldData.Rows[0][field.FieldName]); } //======下面增加了else else if (field.IsNull && !field.IsDefault) { tableDict.Add(field.FieldName, DBNull.Value); } } else if (value.IsNullOrWhiteSpace() && field.IsNull && !field.IsDefault)//如果值是空字符串,数据表字段又可为空,则设置为NULL { tableDict.Add(field.FieldName, DBNull.Value); } else if (value.IsNullOrWhiteSpace() && !field.IsNull && field.IsDefault)//如果值是空字符串,数据表字段不能为空,又设置了默认值,则不添加,采用默认值 { continue; } else { //判断如果是数字类型,要把值的,号去掉,有的设置了千分符 if (IsNumber(field)) { value = value.Replace(",", "").Replace(",", ""); } tableDict.Add(field.FieldName, value); } } } } if (tableDict.Any(p => !p.Key.EqualsIgnoreCase(form_dbtableprimarykey))) { tuples.Add((tableDict, form_dbtable, form_dbtableprimarykey, isAdd ? 1 : 2));//1新增 2修改 } #endregion #region 保存子表 foreach (JObject subTableObject in subtableJson) { string secondtable = subTableObject.Value("subTable"); string primarytablefiled = subTableObject.Value("primaryTableField"); string secondtableprimarykey = subTableObject.Value("subTableKey"); string secondtablerelationfield = subTableObject.Value("linkField"); if (secondtable.IsNullOrWhiteSpace() || primarytablefiled.IsNullOrWhiteSpace() || secondtableprimarykey.IsNullOrWhiteSpace() || secondtablerelationfield.IsNullOrWhiteSpace()) { continue; } if (isAdd && isIdentity)//如果主表是自增,这里要先得到值 { string identityValue = dbConnection.SaveData(dbConnectionModel, tuples, true, seqName); if (identityValue.IsInt()) { newInstanceId = identityValue; seqName = string.Empty;//这里获取了,最后保存的时候不获取identity,把seqName设置为空。 } else { return (string.Empty, identityValue); } tuples.Clear(); } string subTableId = subTableObject.Value("id"); int rowLength = args.GetJsonValue(subTableId + "_length").ToInt(0); DataTable subtableDt = dbConnection.GetDataTable(dbConnectionModel, secondtable, secondtablerelationfield, newInstanceId.ToString()); var subtableFields = dbConnection.GetTableFields(dbConnectionModel, secondtable); for (int i = 0; i < rowLength; i++) { string rowIndex = args.GetJsonValue(subTableId + "[rows][" + i.ToString() + "][" + secondtableprimarykey + "]"); bool subtableIsAdd = subtableDt.Rows.Count == 0; if (!subtableIsAdd) { try { subtableIsAdd = subtableDt.Select(secondtableprimarykey + "='" + rowIndex + "'").Length == 0; } catch { subtableIsAdd = true; } } Dictionary subtableDict = new Dictionary(); foreach (var subtableField in subtableFields) { bool subTableIsPrimaryKey = secondtableprimarykey.EqualsIgnoreCase(subtableField.FieldName); string value = args.GetJsonValue(subTableId + "[rows][" + i.ToString() + "][" + subtableField.FieldName + "]"); int subfieldStatus = 0;//字段状态 if (fieldStatusArray != null) { foreach (JObject jObject in fieldStatusArray) { if (jObject.Value("name").Equals((secondtable + "-" + subtableField.FieldName).ToUpper())) { subfieldStatus = jObject.Value("status"); break; } } } if (null == value && secondtablerelationfield.EqualsIgnoreCase(subtableField.FieldName))//关联字段 { subtableDict.Add(subtableField.FieldName, newInstanceId); } //如果是主键 (subtableField.IsIdentity && !value.IsInt()) 是判断如果是自增主键,而客户端提交的value是guid //如果不是identity,但是是主键并且是int等数字类型,也认为是自增主键(oracle或pgsql设置了自增,但有可能identity也为0)。 else if (subTableIsPrimaryKey && (null == value || (subtableField.IsIdentity || subtableField.Type.StartsWith("int", StringComparison.CurrentCultureIgnoreCase) || subtableField.Type.StartsWith("serial", StringComparison.CurrentCultureIgnoreCase) || subtableField.Type.Equals("numeric") || subtableField.Type.Equals("number") || subtableField.Type.Equals("long")) && !value.IsInt())) { if (!subtableIsAdd)//如果是修改,直接赋值 { subtableDict.Add(subtableField.FieldName, rowIndex); } else if (subtableField.Type.EqualsIgnoreCase("uniqueidentifier") || subtableField.Type.ContainsIgnoreCase("char") || subtableField.Type.ContainsIgnoreCase("uuid"))//如果是字符串,则自动生成GUID, postgresql为uuid { subtableDict.Add(subtableField.FieldName, GuidExtensions.NewGuid()); } } else { if (subfieldStatus != 0) { continue; } if (subtableDict.ContainsKey(subtableField.FieldName) || subtableDict.Keys.Any(p => p.EqualsIgnoreCase(subtableField.FieldName))) { continue; } if (subtableField.Type.ContainsIgnoreCase("date"))//如果是日期时间要验证数据 { if (value.IsDateTime(out DateTime dt)) { subtableDict.Add(subtableField.FieldName, dt); } else { if (subtableField.IsNull && !subtableField.IsDefault) { subtableDict.Add(subtableField.FieldName, DBNull.Value); } } } else { if (null == value) { if (subtableField.IsNull && !subtableField.IsDefault) { subtableDict.Add(subtableField.FieldName, DBNull.Value); } } else if (value.IsNullOrWhiteSpace() && subtableField.IsNull && !subtableField.IsDefault)//如果值是空字符串,数据表字段又可为空,则设置为NULL { subtableDict.Add(subtableField.FieldName, DBNull.Value); } else { //判断如果是数字类型,要把值的,号去掉,有的设置了千分符 if (IsNumber(subtableField)) { value = value.Replace(",", "").Replace(",", ""); } subtableDict.Add(subtableField.FieldName, value); } } } } if (subtableDict.Any(p => !p.Key.EqualsIgnoreCase(secondtableprimarykey))) { tuples.Add((subtableDict, secondtable, secondtableprimarykey, subtableIsAdd ? 1 : 2)); } } //标记要删除的行 foreach (DataRow dr in subtableDt.Rows) { bool isIn = false; for (int i = 0; i < rowLength; i++) { string rowIndex = args.GetJsonValue(subTableId + "[rows][" + i.ToString() + "][" + secondtableprimarykey + "]"); if (dr[secondtableprimarykey].ToString().EqualsIgnoreCase(rowIndex)) { isIn = true; break; } } if (!isIn) { Dictionary subtableDict = new Dictionary { { secondtableprimarykey, dr[secondtableprimarykey].ToString() } }; tuples.Add((subtableDict, secondtable, secondtableprimarykey, 0)); } } } #endregion #region 获取设计应用程序时的事件 List<(string, SqlSugar.SugarParameter[])> sqlList = new List<(string, SqlSugar.SugarParameter[])>(); string programId = args.GetJsonValue("programid"); string saveDataEvent = string.Empty; if (programId.IsGuid(out Guid programGuid)) { var programeRunModel = new Program().GetRunModel(programId); if (programeRunModel != null) { saveDataEvent = programeRunModel.EditEvents.Trim1(); //如果事件是以[sql]开头,则加入sqlList,sql有事务。 if (!saveDataEvent.IsNullOrEmpty() && saveDataEvent.StartsWith("[sql]")) { sqlList.Add((RoadFlow.Business.Wildcard.Filter(saveDataEvent, null, tableDict), null)); } } } #endregion string returnValue = dbConnection.SaveData(dbConnectionModel, tuples, isIdentity, seqName, sqlList: sqlList); int returnId = returnValue.IsInt(out int id) ? id : -1; if ((newInstanceId == null || newInstanceId.ToString().IsNullOrWhiteSpace()) && returnId != -1) { newInstanceId = returnId.ToString(); } string errMsg = returnId == -1 ? returnValue : string.Empty; #region 判断是否有事件 if (!saveDataEvent.IsNullOrEmpty() && !saveDataEvent.StartsWith("[sql]")) { Dictionary eventParams = new Dictionary { { "ProgramId", programGuid },//设计的应用程序ID { "InstanceId", newInstanceId },//主表主键值 { "EditModel", isAdd ? 0 : 1 } //编辑方式 0 新增 1修改 }; var (result, err) = Tools.ExecuteMethod(saveDataEvent, eventParams); if (err != null) { errMsg = err.Message; new Log().Add(err, "执行表单数据修改后事件发生错误-" + programId); } } #endregion return (newInstanceId.ToString().ToUpper(), errMsg); } /// /// 得到流水号 /// /// 连接实体 /// 表名 /// 流水号配置JSON字符串 /// 流水号配置JSON,传了JSON以JSON为准, serialnumberConfig不用 /// 返回当前最大编号 /// searialNumber 当前流水号, maxField最大编号字段,maxValue最大编号 public (string searialNumber, string maxField, int maxValue) GetSerialNumber(Model.rf_dbconnection dbConnectionModel, string tableName, string serialnumberConfig, JObject serialnumberConfigJson = null) { JObject jObject = serialnumberConfigJson ?? serialnumberConfig.ToJObject(); string maxfiled = jObject.Value("maxfiled"); string length = jObject.Value("length"); string formatstring = jObject.Value("formatstring"); string sqlwhere = jObject.Value("sqlwhere"); StringBuilder sql = new StringBuilder(); sql.Append("SELECT MAX(" + maxfiled + ") FROM " + tableName + " "); if (!sqlwhere.IsNullOrWhiteSpace()) { //2020-5-9修改了条件中包含中文时的问题,添加HttpUtility.UrlDecode(sqlwhere.UrlDecode(), System.Text.Encoding.GetEncoding("GB2312") string sqlwhere1 = RoadFlow.Business.Wildcard.Filter(HttpUtility.UrlDecode(sqlwhere.UrlDecode(), System.Text.Encoding.GetEncoding("GB2312")).Trim()); if (sqlwhere1.StartsWith("where", StringComparison.CurrentCultureIgnoreCase)) { sql.Append(sqlwhere1); } else { sql.Append("WHERE " + sqlwhere1); } } int max = 1; try { DataTable dt = new DbConnection().GetDataTable(dbConnectionModel, sql.ToString()); if (dt.Rows.Count > 0) { max = dt.Rows[0][0].ToString().ToInt(0) + 1; } string number = max.ToString().PadLeft(length.ToInt(1), '0'); string format = RoadFlow.Business.Wildcard.Filter(formatstring); number = format.ContainsIgnoreCase("{serialnumber}") ? format.ReplaceIgnoreCase("{serialnumber}", number) : format + number; return (number, maxfiled, max); } catch (Exception err) { new Log().Add(err); return (string.Empty, maxfiled, max); } } /// /// 判断一个字段是否是数字型 /// /// public bool IsNumber(Model.TableField field) { return field.Type.ContainsIgnoreCase("decimal") || field.Type.ContainsIgnoreCase("int") || field.Type.ContainsIgnoreCase("numeric") || field.Type.ContainsIgnoreCase("number") || field.Type.ContainsIgnoreCase("money") || field.Type.ContainsIgnoreCase("float") || field.Type.ContainsIgnoreCase("double") || field.Type.EqualsIgnoreCase("long"); } /// /// 替换标题表达式 /// /// /// /// /// public string ReplaceTitleExpression(string titleExpression, string tableName, string instanceId, JObject formBody) { titleExpression = RoadFlow.Business.Wildcard.Filter(titleExpression); List keys = new List(); string[] array = titleExpression.Split('{'); foreach (string key in array) { if (key.Contains("}")) { keys.Add(key.Substring(0, key.IndexOf("}"))); } } foreach (string key in keys) { string controlName = (tableName + "-" + key).ToUpper(); string value = formBody.GetJsonValue(controlName); string serialnumber_config = formBody.GetJsonValue("rf_serialnumber_config_" + controlName); //流水号要从数据表中查询 if ((!serialnumber_config.IsNullOrWhiteSpace() || value.IsNullOrEmpty()) && !instanceId.IsNullOrWhiteSpace() && !tableName.IsNullOrWhiteSpace()) { string form_dbconnid = formBody.GetJsonValue("form_dbconnid"); string form_dbtableprimarykey = formBody.GetJsonValue("form_dbtableprimarykey"); var formData = GetFormDataTable(new DbConnection().GetOneById(form_dbconnid), tableName, form_dbtableprimarykey, instanceId); if (formData.Rows.Count > 0) { value = formData.Rows[0][key].ToString(); } } titleExpression = titleExpression.ReplaceIgnoreCase("{" + key + "}", value); } return titleExpression; } /// /// 删除一个表单对应的数据 /// /// 表单Id(RF_Form表Id) /// 实例Id /// 设计的应用程序实体(用于判断数据删除后事件) /// 语言包 /// 是否是VUE版本 /// 返回1表单成功,其它为错误信息 public string DeleteFormData(string formId, string instanceId, Model.ProgramRun programRunModel = null, IStringLocalizer localizer = null, bool isVue = false) { if (instanceId.IsNullOrWhiteSpace()) { return "1"; } List<(string, string, int, string, string)> conns = new List<(string, string, int, string, string)>(); var from = GetOneById(formId); var attrObject = JObject.Parse(from.attribute); if (attrObject != null) { JArray subArray = attrObject.Value("subtable"); conns.Add((attrObject.Value("dbConn"), attrObject.Value("dbTable"), 1, attrObject.Value("dbTablePrimaryKey"), string.Empty)); if (subArray!=null &&subArray.Count > 0) { foreach (JObject o in subArray) { conns.Add((attrObject.Value("dbConn"), o.Value("secondtable"), 0, o.Value("secondtableprimarykey"), o.Value("secondtablerelationfield"))); } } } if (null == conns || conns.Count == 0) { throw Oops.Oh(localizer == null ? "表单未绑定表!" : localizer["FormNotBindTable"].Value); //return localizer == null ? "表单未绑定表!" : localizer["FormNotBindTable"].Value; } List<(string, IEnumerable)> sqlList = new List<(string, IEnumerable)>(); foreach (var (dbConnId, tableName, isPrimary, primaryKey, relField) in conns) { if (1 == isPrimary) { string sql = "DELETE FROM " + tableName + " WHERE " + primaryKey + "=@pk"; sqlList.Add((sql, new List() { new SugarParameter("pk",instanceId) })); } else { string sql = "DELETE FROM " + tableName + " WHERE " + relField + "=@val"; sqlList.Add((sql, new List() { new SugarParameter("val", instanceId) })); } } string connId = conns.First().Item1; string msg = (new DbConnection().executeSqlByConnection(connId, sqlList)>0?1:0).ToString(); #region 设计的应用程序数据事件 if (null != programRunModel && !programRunModel.EditEvents.IsNullOrWhiteSpace()) { Dictionary eventParams = new Dictionary { { "ProgramId", programRunModel.Id },//设计的应用程序ID { "InstanceId", instanceId },//主表主键值 { "EditModel", 2} //编辑方式 0 新增 1修改 2删除 }; var (result, err) = Tools.ExecuteMethod(programRunModel.EditEvents.Trim(), eventParams); if (err != null) { new Log().Add(err, "执行应用程序设计数据修改后事件发生错误-" + programRunModel.Id.ToString()); } } #endregion return msg.IsInt() ? "1" : msg; } /// /// 查询一页数据 /// /// /// /// /// 当前人员ID /// /// /// /// 状态,默认为查询没有删除的表单 /// public List GetPagerList(out int count, int size, int number, string userId, string name, string type, string order, int status = -1) { int total = 0; string[] formtypes = !type.IsNullOrWhiteSpace() ? type.FilterSelectSql().Split(",") : null; var rtn = db.Queryable() .Where(x => x.ManageUser.Contains(IOrganize.PREFIX_USER+userId)) .WhereIF(status == -1, x => x.Status != 2) .WhereIF(status != -1, x => x.Status == status) .WhereIF(!name.IsNullOrWhiteSpace(), x => x.Name.Contains(name.Trim())) .WhereIF(formtypes != null && formtypes.Length != 0, x => formtypes.Contains(x.FormType)) .OrderByIF(!order.IsNullOrWhiteSpace(), order.FilterSelectSql()) .ToPageList(number, size, ref total) .ToList(); count = total; return rtn; } /// /// 删除表单同时删除应用程序库中记录 /// /// 表单实体 /// 是否彻底删除 0不 1彻底删除 /// public int DeleteAndApplibrary(Model.rf_form form, int delete = 0) { if (form == null) return 0; Model.rf_applibrary libr = new Applibrary().GetByCode(form.Id); if (delete == 0) { form.Status = 2; Update(form); } else { Delete(form); } if (libr != null) new Applibrary().Delete(libr); return 1; } /// /// 清除表单运行时HTML缓存 /// /// 表单ID public void ClearRunJObjectCache(string formId) { _memoryCache.Remove("roadflow_form_runobject_" + formId.ToLower()); } /// /// 根据SQL得到下拉选项(vue项目用) /// /// /// /// /// public JArray GetJArrayOptionsBySQL(string connId, string sql, string value) { JArray jArray = new JArray(); if (!connId.IsGuid(out Guid cid) || sql.IsNullOrWhiteSpace()) { return jArray; } DbConnection dbConnection = new DbConnection(); DataTable dt; try { var conn = dbConnection.GetOneById(connId); dt = dbConnection.GetDataTable(conn, RoadFlow.Business.Wildcard.Filter(sql.FilterSelectSql())); } catch { dt = new DataTable(); } foreach (DataRow dr in dt.Rows) { string value1 = string.Empty; if (dt.Columns.Count > 0) { value1 = dr[0].ToString(); } string title; if (dt.Columns.Count > 1) { title = dr[1].ToString(); } else { title = value1; } if (value1.IsNullOrWhiteSpace() || title.IsNullOrWhiteSpace()) { continue; } jArray.Add(new JObject() { { "value", value1 }, { "title", title }, { "selected", value1.EqualsIgnoreCase(value) }, }); } return jArray; } /// /// 根据URL得到下拉选项 /// /// /// public string GetOptionsByUrl(string url) { url = RoadFlow.Business.Wildcard.Filter(url); if (!url.ContainsIgnoreCase("http") && !url.ContainsIgnoreCase("https")) { url = Tools.GetHttpHost() + url; } return HttpHelper.HttpGet(url); } /// /// 导入表单 /// /// /// 是否需要创建文件,VUE不需要创建文件 /// 返回1表示成功,其它为错误信息 public string ImportForm(string json, bool createFile = true) { if (json.IsNullOrWhiteSpace()) { return "要导入的JSON为空!"; } JObject jObject = null; try { jObject = JObject.Parse(json); } catch { return "json解析错误!"; } var forms = jObject.Value("forms"); if (null != forms) { foreach (JObject formObject in forms) { Model.rf_form formModel = formObject.ToObject(); if (null == formModel) { continue; } if (GetOneById(formModel.Id) != null) { Update(formModel); } else { Add(formModel); } //如果表单状态是发布,要发布表单 if (createFile && formModel.Status == 1) { #region 写入文件 string webRootPath = Tools.GetWebRootPath(); string path = webRootPath + "/RoadFlowResources/scripts/formDesigner/form/"; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } string file = path + formModel.Id + ".rfhtml"; Stream stream = File.Open(file, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); stream.SetLength(0); StreamWriter sw = new StreamWriter(stream, Encoding.UTF8); sw.Write(formModel.RunHtml); sw.Close(); stream.Close(); #endregion } } } //加入应用程序库 var applibarys = jObject.Value("applibrarys"); Applibrary appLibrary = new Applibrary(); if (null != applibarys) { foreach (JObject app in applibarys) { Model.rf_applibrary appLibraryModel = app.ToObject(); if (null == appLibraryModel) { continue; } if (appLibrary.GetOneById(appLibraryModel.Id) != null) { appLibrary.Update(appLibraryModel); } else { appLibrary.Add(appLibraryModel); } } } return "1"; } } }