224 subparam compute fix

This commit is contained in:
2026-04-02 12:38:30 +03:00
parent b42aa109f0
commit 9409b2cd74
5 changed files with 62 additions and 57 deletions
+11 -3
View File
@@ -260,13 +260,20 @@ arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //In
<!--- Секретность игнорируется. Все секреты доступны, как есть --->
<!--- правда, мы тут можем работать только с сохраненными параметрами. Можем попробовать полагаться на правило: зависимые параметры всегда позже (не факт, что это получится при конкурентном сохранении) --->
<!--- проблема: нам нужен тут instance_operation_uid, но таскать его в аргументах по всей цепочке вызовов неудобно. Если бы это у нас был метод CFS параметра, все было бы просто - это у нас поле параметра --->
<cfif structKeyExists(this.params,arguments.param)><!--- AND len(this.params[arguments.param]) --->
<!--- ошибка: в строке параметров у нас ключ param.subparam, а в аргументах он разобран по частям
при этом мы ожидаем в параметрах структуру paramName:{subparamName:subparamValue}
но почему не находим в сохраненных? возможно такое совпадение, что в сценарии у нас как раз надо выбрать svcId а они не --->
<!--- {"startupConfiguration":{"vdcUid":"ea81db31-2197-407d-b32b-e60577c2671c"}} --->
<!--- this.params <cfdump var=#this.params#/>
arguments <cfdump var=#arguments# /> --->
<cfif structKeyExists(this.params,arguments.param)><!--- AND len(this.params[arguments.param]) --->
<cfif structKeyExists(arguments,"subparam")><!--- *** не изящно, но просто и понятно --->
<cfreturn deserializeJson(this.params[arguments.param])[arguments.subparam]/>
<cfelse>
<cfreturn (this.params[arguments.param])[arguments.subparam]/>
<cfelse>this.params[arguments.param] <!--- <cfdump var=#this.params[arguments.param]#/> --->
<cfreturn this.params[arguments.param]/>
</cfif>
</cfif>
<!--- не нашли параметра в запросе, ищем в сохраненных --->
<cfquery name="local.qCfsParam">
select p.param_value
from instance_operation_cfs_param p
@@ -274,6 +281,7 @@ arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //In
where p.instance_operation_uid = <cfqueryparam cfsqltype="cf_sql_other" value=#this.instance_operation_uid# null=#!isValid('guid',this.instance_operation_uid)#/>
AND s.svc_operation_cfs_param = <cfqueryparam cfsqltype="cf_sql_varchar" value=#arguments.param#/>
</cfquery>
<!--- <cfdump var=#this.keys#/> --->
<cfif structKeyExists(arguments,"subparam")><!--- *** не изящно, но просто и понятно --->
<cfset var value = deserializeJson(local.qCfsParam.param_value)/>
<cfif isStruct(value) AND structKeyExists(value, arguments.subparam)>
+36 -38
View File
@@ -187,45 +187,42 @@
order by sp.sort
</cfquery>
<cfif len(local.qSubparam.func)><!--- приоритет отдается функции перед списком значений--->
<cfset var args = {
"functionName":"#local.qSubparam.func#",
"svcId":#local.qSvcOperation.svc_id#,
"contractId":#arguments.contractId#
}/>
<cfinvoke component="instance_operation_cfs_param" method="generateValueList" argumentCollection=#args# returnVariable="local.qSubparam.value_list"/>
<cfif len(trim(local.qSubparam.value_list)) AND listLen(local.qSubparam.value_list) EQ 1>
<cfset local.qSubparam.default_value=local.qSubparam.value_list/><!--- *** не очень красиво перетирать query, но делаем это довольно часто --->
</cfif>
<!--- <cfelseif len(local.qSubparam.nested_ref)>
<cfset var args = {
"functionName":"#local.qSubparam.nested_ref#",
"config":"#local.qSubparam.config#"
}/>
<cfinvoke component="instance_operation_cfs_param" method="generateClosure" argumentCollection=#args# returnVariable="local.fNestedRef"/>
<cfset local.qSubparam.nested_ref_data = local.fNestedRef() /> --->
<!--- <cfelseif len(local.qSubparam.state_path) AND isStruct(currentState)>
<cfset var args = {
"state":#currentState#,
"path":"#local.qSubparam.state_path#"
}/>
<cfinvoke component="instance_operation_cfs_param"
method="getListFromState"
argumentCollection=#args#
returnVariable="local.qSubparam.value_list"
/> --->
</cfif>
<cfif (len(local.qSubparam.func) OR len(local.qSubparam.expression) <!--- OR len(local.qSubparam.state_path) OR len(local.qSubparam.nested_ref)---> )
AND len(local.qSubparam.value_list) EQ 0>
<cfset local.qSubparam.value_list = []/>
</cfif>
<cfset var mapDescriptor=structNew("linked")/>
<!--- *** выдавать на фронт expression нам ни к чему, это временное явление --->
<cfloop query="local.qSubparam">
<cfif len(local.qSubparam.func)><!--- приоритет отдается функции перед списком значений--->
<cfset var args = {
"functionName":"#local.qSubparam.func#",
"svcId":#local.qSvcOperation.svc_id#,
"contractId":#arguments.contractId#
}/>
<cfinvoke component="instance_operation_cfs_param" method="generateValueList" argumentCollection=#args# returnVariable="local.qSubparam.value_list"/>
<cfif len(trim(local.qSubparam.value_list)) AND listLen(local.qSubparam.value_list) EQ 1>
<cfset local.qSubparam.default_value=local.qSubparam.value_list/><!--- *** не очень красиво перетирать query, но делаем это довольно часто --->
</cfif>
</cfif>
<cfif (len(local.qSubparam.func) OR len(local.qSubparam.expression) )
AND len(local.qSubparam.value_list) EQ 0>
<cfset local.qSubparam.value_list = []/>
</cfif>
<cfset var def = computeDefault(local.qSubparam.default_compute, local.qSubparam.default_value, qSvcOperation.svc_id, arguments.usrId)/>
<!--- *** пока не пытаемся восстановить значения из стейта
<cfif len(local.qSubparam.default_value) EQ 0>
<!--- и вот наконец мы извлекаем старое значение из стейта --->
<cfset var paramName = this.helper.snake2camel(local.qSubparam.svc_operation_cfs_subparam)/>
<cfif structKeyExists(local.instanceDataParams, paramName)>
<cfset var oldValue = structFind(local.instanceDataParams, paramName)/>
<cfset def = isStruct(oldValue) ? serializeJson(oldValue) : oldValue/> <!--- потому что передаем строку, а не объект --->
</cfif>
</cfif> --->
<cfset structInsert(mapDescriptor, local.qSubparam.svc_operation_cfs_subparam,
{
"svcOperationCfsSubparamId":"#local.qSubparam.svc_operation_cfs_subparam_id#",
@@ -240,7 +237,7 @@
"regex":"#local.qSubparam.regex#",
"man":"#local.qSubparam.man#",
"descr":"#local.qSubparam.descr#",
"defaultValue":"#local.qSubparam.default_value#",
"defaultValue":"#def#",
"isRequired":#request.castToBool(local.qSubparam.is_required)#,
"isSensitive":#request.castToBool(local.qSubparam.is_sensitive)#,
"refSvcId":#local.qSubparam.ref_svc_id#,
@@ -250,8 +247,9 @@
"isModifiableDefinition":false
}, true
)
/>
</cfloop> <!--- *** вообще-то передавать в дескриптор func и default_compute не нужно, это для не забыть --->
/><!--- *** вообще-то передавать в дескриптор func и default_compute не нужно, это для не забыть --->
</cfloop>
<cfset local.qCfsParam.data_descriptor = mapDescriptor/>
</cfif><!---/map --->
@@ -31,7 +31,6 @@ arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //In
<!--- Вероятно, нам не очень нужно вычислять набор значений для инстанса параметра, мы всегда знаем класс --->
<!--- контест: --->
<cfargument name="svcOperationCfsParamId" type="string" required=true hint="type:integer"/>
<!--- <cfargument name="svcOperationCfsSubparamId" type="string" required=false hint="type:integer"/> --->
<cfargument name="keys" type="string" default={} hint="type:json keys we depend on: of the param uid itself, or operation uid, instance uid, service operation cfs param - if not all entities intstantiated yet"/>
<cfargument name="params" type="string" default="{}" hint="type:json any parameters we depend on"/>
@@ -53,7 +52,7 @@ arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //In
<cfset local.keys.svcOperationCfsParamId=arguments.svcOperationCfsParamId/><!--- дополняем --->
<cfset local.params = deserializeJson(arguments.params)/>
<cfset local.keys.svcOperationCfsParamId = arguments.svcOperationCfsParamId/> <!--- *** сомнительное дело гонять аргументы туда-сюда --->
<!--- <cfset local.keys.svcOperationCfsParamId = arguments.svcOperationCfsParamId/> ---> <!--- *** сомнительное дело гонять аргументы туда-сюда --->
<!--- Нам нужен либо класс и параметры, либо инстанс с сохраненными параметрами (при этом в контексте параметры имеют приоритет перед сохраненными, но если их нет - хватит нам и сохраненных) --->
@@ -30,11 +30,10 @@ arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //In
<!--- *** Важно: мы должны уметь посчитать параметр, если он не сохранен, то есть мы знаем его класс, а не инстанс --->
<!--- Вероятно, нам не очень нужно вычислять набор значений для инстанса параметра, мы всегда знаем класс --->
<!--- контест: --->
<cfargument name="svcOperationCfsSubparamId" type="string" required=false hint="type:integer"/>
<cfargument name="svcOperationCfsSubparamId" type="string" required=true hint="type:integer"/>
<cfargument name="keys" type="string" default={} hint="type:json keys we depend on: of the param uid itself, or operation uid, instance uid, service operation cfs param - if not all entities intstantiated yet"/>
<cfargument name="params" type="string" default="{}" hint="type:json any posted parameters we depend on"/>
<cftry>
<cfset this.helper.validateField(arguments, "svcOperationCfsSubparamId", "integer")/>
<cfset this.helper.validateField(arguments, "keys", "json")/> <!--- *** может, не лучшая идея передавать ключ в контексте --->
@@ -45,12 +44,12 @@ arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //In
</cftry>
<cfset local={}/>
<cfset local.expression = ""/> <!--- нет смысла выносить это в поля класса, оно нужно только локально --->
<cfset local.calculatedValueList = ""/>
<cfset local.keys = deserializeJson(arguments.keys)/>
<cfset local.params = deserializeJson(arguments.params)/>
<cfset "local.expression" = ""/> <!--- нет смысла выносить это в поля класса, оно нужно только локально --->
<cfset "local.calculatedValueList" = ""/>
<cfset "local.keys" = deserializeJson(arguments.keys)/>
<cfset "local.params" = deserializeJson(arguments.params)/>
<cfset local.keys.svcOperationCfsSubparamId = arguments.svcOperationCfsSubparamId/> <!--- *** сомнительное дело гонять аргументы туда-сюда ---><!--- *** по-моему, не используется, поэтому достанем svcOperationCfsParamId прямо тут --->
<cfset "local.keys.svcOperationCfsSubparamId" = arguments.svcOperationCfsSubparamId/> <!--- *** сомнительное дело гонять аргументы туда-сюда ---><!--- *** по-моему, не используется, поэтому достанем svcOperationCfsParamId прямо тут --->
<cfquery name="local.qCfsSubparam" result="local.result">
select
@@ -69,12 +68,12 @@ arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //In
<cfreturn representationOf(this.helper.formatMessage("Service Operation CFS Parameter Not Found")).withStatus(404)/>
</cfif>
<cfset local.expression=local.qCfsSubparam.expression/>
<cfset local.keys.svcOperationCfsParamId = local.qCfsSubparam.svc_operation_cfs_param_id/>
<cfset "local.expression"=local.qCfsSubparam.expression/>
<cfset "local.keys.svcOperationCfsParamId" = local.qCfsSubparam.svc_operation_cfs_param_id/>
<!--- *** можно обратить внимание, что мы инстанциируем не субпараметр, а параметр (цинично пользуясь их функциональной идентичностью... но некрасиво) --->
<cfif len(local.expression)>
<cfset calculatedValueList=createObject("component","lib.expression_parser")
<cfset local.calculatedValueList=createObject("component","lib.expression_parser")
.eval(
local.expression,
{/*context*/
@@ -87,7 +86,9 @@ arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //In
<cfelse>
<cfreturn representationOf(this.helper.formatMessage("Expression Not Found")).withStatus(404)/>
</cfif>
<!--- <cfdump var=#local.keys#/>
<cfdump var=#local.params#/>
<cfdump var=#local.calculatedValueList# abort=true/> --->
<!--- Тут нам еще придется сформатировать лист в массив. Но обошлось довольно просто --->
<cfset var out=structNew("linked")/>
<cfset "out.queryDurationMs"=getTickCount() - request.startTickCount/>
@@ -95,6 +96,5 @@ arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //In
<cfset "out.runDurationMs"=getTickCount() - request.startTickCount/>
<cfreturn representationOf(out) />
</cffunction><!--- get --->
</cfcomponent>