AlgorithmEditing.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751
  1. <script setup lang="ts">
  2. import { onMounted, ref, useTemplateRef } from 'vue';
  3. import dayjs, { Dayjs } from 'dayjs';
  4. import SvgIcon from '@/components/SvgIcon.vue';
  5. import { useDictData } from '@/hooks/dict-data';
  6. import { useRequest } from '@/hooks/request';
  7. import { t } from '@/i18n';
  8. import { addAlgorithmConfigUpdate } from '@/api';
  9. import { DictCode } from '@/constants';
  10. import EquipmentControl from './EquipmentControl.vue';
  11. import MonthSetting from './MonthSetting.vue';
  12. import SetInterval from './SetInterval.vue';
  13. import type { FormInstance, Rule } from 'ant-design-vue/es/form';
  14. import type { AlgorithmConfigInfo, AlgorithmForm, ChillersItem, TemperatureRange, TemperatureRangeItem } from '@/types';
  15. const { dictData: algTempCtrlMinStep, getDictData: getAlgTempCtrlMinStep } = useDictData(DictCode.AlgTempCtrlMinStep);
  16. const { dictData: algTempHumCollectPeriod, getDictData: getAlgTempHumCollectPeriod } = useDictData(
  17. DictCode.AlgTempHumCollectPeriod,
  18. );
  19. const { dictData: algWtTempCtrlMode, getDictData: getAlgWtTempCtrlMode } = useDictData(DictCode.AlgWtTempCtrlMode);
  20. const { dictData: algAlways, getDictData: getAlgAlways } = useDictData(DictCode.AlgAlways);
  21. const { dictData: algWtTempSetStep, getDictData: getAlgWtTempSetStep } = useDictData(DictCode.AlgWtTempSetStep);
  22. const formRef = ref<FormInstance>();
  23. const monthSettingRefs = useTemplateRef('monthSetting');
  24. const emit = defineEmits(['confirmClick', 'cancelClick']);
  25. const setIntervalRefs = ref<InstanceType<typeof SetInterval>[]>([]);
  26. const equipmentControlRefs = ref<InstanceType<typeof EquipmentControl>[]>([]);
  27. const { handleRequest } = useRequest();
  28. const activeKey = ref<string[]>(['intelligentControl', 'functionSettings']);
  29. const customStyle = 'border-radius: 4px;;border: 0;background: #F5F6F7;margin-bottom: 4px';
  30. const analysisOpen = ref<boolean>(false);
  31. const setOpen = ref<boolean>(false);
  32. const temperatureSettingValue = ref<string>('');
  33. const analysisTypeDisplay = ref<number>(0);
  34. const coolingPipeDynamicOffsetDisplay = ref<number>(0);
  35. const coolingPipeDynamicSetDisplay = ref<number>(0);
  36. const coolingPipeDynamicDeadZoneDisplay = ref<number>(0);
  37. const coolingPipeDynamicLowerDisplay = ref<number>(0);
  38. const coolingPipeDynamicUpperDisplay = ref<number>(0);
  39. const temperatureRangeList = ref<TemperatureRange[]>([]);
  40. const chillersList = ref<ChillersItem[]>([]);
  41. const algorithmId = ref<number>();
  42. const groupId = ref<number>();
  43. const algorithmForm = ref<AlgorithmForm>({
  44. enabled: false,
  45. sendCtrlCmd: true,
  46. msgBox: true,
  47. tempRiseCtrlPeriod: 10,
  48. tempReductionCtrlPeriod: 3,
  49. minCtrlStep: '',
  50. intelligentMode: 0,
  51. controlBasis: 0,
  52. period: 0,
  53. tempSafetyMargin: 0,
  54. humiditySafetyMargin: 0,
  55. tempHumidityCollectPeriod: '',
  56. waterSupplyTempSource: 0,
  57. analysis: true,
  58. analysisType: 0,
  59. enableRefrigerationPipeDynamicSet: true,
  60. enableCoolingPipeDynamicSet: false,
  61. coolingPipeDynamicOffset: 0,
  62. coolingPipeDynamicSet: 0,
  63. coolingPipeDynamicDeadZone: 0,
  64. coolingPipeDynamicLower: 0,
  65. coolingPipeDynamicUpper: 0,
  66. });
  67. const addClick = () => {
  68. temperatureRangeList.value.push({
  69. time: undefined,
  70. lower: 0,
  71. upper: 0,
  72. });
  73. };
  74. const deleteClick = (index: number) => {
  75. temperatureRangeList.value.splice(index, 1);
  76. };
  77. const rules: Record<string, Rule[]> = {
  78. sendCtrlCmd: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  79. msgBox: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  80. tempRiseCtrlPeriod: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  81. tempReductionCtrlPeriod: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  82. minCtrlStep: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  83. intelligentMode: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  84. controlBasis: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  85. period: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  86. tempSafetyMargin: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  87. humiditySafetyMargin: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  88. tempHumidityCollectPeriod: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  89. waterSupplyTempSource: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  90. };
  91. const editorAlgorithmChange = (info: AlgorithmConfigInfo) => {
  92. temperatureRangeList.value = [];
  93. chillersList.value = [];
  94. handleRequest(async () => {
  95. const {
  96. id: algId,
  97. enabled,
  98. sendCtrlCmd,
  99. msgBox,
  100. tempRiseCtrlPeriod,
  101. minCtrlStep,
  102. intelligentMode,
  103. controlBasis,
  104. period,
  105. tempSafetyMargin,
  106. humiditySafetyMargin,
  107. tempHumidityCollectPeriod,
  108. waterSupplyTempSource,
  109. tempReductionCtrlPeriod,
  110. analysis,
  111. analysisType,
  112. enableRefrigerationPipeDynamicSet,
  113. enableCoolingPipeDynamicSet,
  114. coolingPipeDynamicOffset,
  115. coolingPipeDynamicSet,
  116. coolingPipeDynamicDeadZone,
  117. coolingPipeDynamicLower,
  118. coolingPipeDynamicUpper,
  119. chillers,
  120. chilledWaterOutletTempRangeList,
  121. chilledWaterOutletTempSet,
  122. devGroupId,
  123. } = info;
  124. groupId.value = devGroupId;
  125. algorithmId.value = algId;
  126. Object.assign(algorithmForm.value, {
  127. enabled,
  128. sendCtrlCmd,
  129. msgBox,
  130. tempRiseCtrlPeriod,
  131. tempReductionCtrlPeriod,
  132. minCtrlStep: String(minCtrlStep),
  133. intelligentMode,
  134. controlBasis,
  135. period,
  136. tempSafetyMargin,
  137. humiditySafetyMargin,
  138. tempHumidityCollectPeriod: String(tempHumidityCollectPeriod),
  139. waterSupplyTempSource,
  140. analysis,
  141. analysisType,
  142. enableRefrigerationPipeDynamicSet,
  143. enableCoolingPipeDynamicSet,
  144. coolingPipeDynamicOffset,
  145. coolingPipeDynamicSet,
  146. coolingPipeDynamicDeadZone,
  147. coolingPipeDynamicLower,
  148. coolingPipeDynamicUpper,
  149. });
  150. analysisTypeDisplay.value = analysisType;
  151. coolingPipeDynamicOffsetDisplay.value = coolingPipeDynamicOffset;
  152. coolingPipeDynamicSetDisplay.value = coolingPipeDynamicSet;
  153. coolingPipeDynamicDeadZoneDisplay.value = coolingPipeDynamicDeadZone;
  154. coolingPipeDynamicLowerDisplay.value = coolingPipeDynamicLower;
  155. coolingPipeDynamicUpperDisplay.value = coolingPipeDynamicUpper;
  156. temperatureSettingValue.value = chilledWaterOutletTempSet;
  157. chilledWaterOutletTempRangeList.forEach((item) => {
  158. const { startTime, endTime, lower, upper } = item;
  159. temperatureRangeList.value.push({
  160. time: [dayjs(startTime, 'HH:mm'), dayjs(endTime, 'HH:mm')],
  161. lower,
  162. upper,
  163. });
  164. });
  165. chillers.forEach((item) => {
  166. const {
  167. id,
  168. devId,
  169. waterTempControlMode,
  170. continuous,
  171. stopCompensate,
  172. restartCompensate,
  173. safeDiffPressureLower,
  174. safeLoadLower,
  175. waterTempStep,
  176. deviceName,
  177. } = item;
  178. chillersList.value.push({
  179. id,
  180. algId,
  181. devId,
  182. waterTempControlMode: String(waterTempControlMode),
  183. continuous: String(continuous),
  184. stopCompensate,
  185. restartCompensate,
  186. safeDiffPressureLower,
  187. safeLoadLower,
  188. waterTempStep: String(waterTempStep),
  189. deviceName,
  190. });
  191. });
  192. });
  193. };
  194. const analysisEditor = () => {
  195. analysisTypeDisplay.value = algorithmForm.value.analysisType;
  196. analysisOpen.value = true;
  197. };
  198. const setEditor = () => {
  199. const {
  200. coolingPipeDynamicOffset,
  201. coolingPipeDynamicSet,
  202. coolingPipeDynamicDeadZone,
  203. coolingPipeDynamicLower,
  204. coolingPipeDynamicUpper,
  205. } = algorithmForm.value;
  206. coolingPipeDynamicOffsetDisplay.value = coolingPipeDynamicOffset;
  207. coolingPipeDynamicSetDisplay.value = coolingPipeDynamicSet;
  208. coolingPipeDynamicDeadZoneDisplay.value = coolingPipeDynamicDeadZone;
  209. coolingPipeDynamicLowerDisplay.value = coolingPipeDynamicLower;
  210. coolingPipeDynamicUpperDisplay.value = coolingPipeDynamicUpper;
  211. setOpen.value = true;
  212. };
  213. const okConfirm = () => {
  214. algorithmForm.value.analysisType = analysisTypeDisplay.value;
  215. analysisOpen.value = false;
  216. };
  217. const okSetConfirm = () => {
  218. algorithmForm.value.coolingPipeDynamicOffset = coolingPipeDynamicOffsetDisplay.value;
  219. algorithmForm.value.coolingPipeDynamicSet = coolingPipeDynamicSetDisplay.value;
  220. algorithmForm.value.coolingPipeDynamicDeadZone = coolingPipeDynamicDeadZoneDisplay.value;
  221. algorithmForm.value.coolingPipeDynamicLower = coolingPipeDynamicLowerDisplay.value;
  222. algorithmForm.value.coolingPipeDynamicUpper = coolingPipeDynamicUpperDisplay.value;
  223. setOpen.value = false;
  224. };
  225. // 添加格式转换
  226. const formatDate = (date: Dayjs) => date.format('HH:mm');
  227. const addAlgorithm = async () => {
  228. try {
  229. // 创建校验任务队列(包含所有子组件+父组件自身)
  230. const allTasks = [
  231. ...setIntervalRefs.value.map((c) => c.formRefSubmit()),
  232. ...equipmentControlRefs.value.map((c) => c.formRefSubmit()),
  233. formRef.value?.validate() || Promise.resolve(),
  234. monthSettingRefs.value?.formRefSubmit(),
  235. ];
  236. // 并行执行所有校验(父+子)
  237. await Promise.all(allTasks);
  238. handleRequest(async () => {
  239. const timeList: TemperatureRangeItem[] = [];
  240. temperatureRangeList.value.forEach((item) => {
  241. const { time, lower, upper } = item;
  242. const data = time?.map(formatDate) || [];
  243. timeList.push({
  244. startTime: data[0],
  245. endTime: data[1],
  246. lower,
  247. upper,
  248. });
  249. });
  250. await addAlgorithmConfigUpdate({
  251. ...algorithmForm.value,
  252. id: algorithmId.value,
  253. chillers: chillersList.value,
  254. chilledWaterOutletTempRangeList: timeList,
  255. chilledWaterOutletTempSet: monthSettingRefs.value ? monthSettingRefs.value.stringConversion() : '',
  256. });
  257. if (groupId.value) {
  258. emit('confirmClick', groupId.value);
  259. }
  260. });
  261. } catch {
  262. console.log('存在验证未通过的表单');
  263. }
  264. };
  265. const canceladd = () => {
  266. emit('cancelClick');
  267. };
  268. defineExpose({
  269. editorAlgorithmChange,
  270. });
  271. onMounted(() => {
  272. handleRequest(async () => {
  273. await getAlgTempCtrlMinStep();
  274. algorithmForm.value.minCtrlStep = algTempCtrlMinStep.value[0].dictEngValue;
  275. await getAlgTempHumCollectPeriod();
  276. algorithmForm.value.tempHumidityCollectPeriod = algTempHumCollectPeriod.value[0].dictEngValue;
  277. await getAlgWtTempCtrlMode();
  278. await getAlgAlways();
  279. await getAlgWtTempSetStep();
  280. });
  281. });
  282. </script>
  283. <template>
  284. <div>
  285. <!-- <AFlex justify="space-between">
  286. <div class="title-text">{{ $t('algorithmManage.algorithmConfiguration') }}</div>
  287. <DeviceGroupSelect @change="handleDevGroupChange" />
  288. </AFlex> -->
  289. <div class="algorithm-content">
  290. <ACollapse v-model:active-key="activeKey" style="border: 0" collapsible="icon">
  291. <ACollapsePanel key="intelligentControl" :style="customStyle">
  292. <template #header>
  293. <AFlex align="center" class="header-heigth">
  294. <span class="header-text">{{ $t('algorithmManage.intelligentControlChilledWater') }}</span>
  295. <ASwitch v-model:checked="algorithmForm.enabled" />
  296. </AFlex>
  297. </template>
  298. <div>
  299. <AForm
  300. ref="formRef"
  301. class="algorithm-form"
  302. :model="algorithmForm"
  303. label-align="left"
  304. layout="vertical"
  305. :rules="rules"
  306. >
  307. <AFlex class="flex-bottom" :gap="40">
  308. <AFormItem :label="t('algorithmManage.controlInstruction')" name="sendCtrlCmd">
  309. <ARadioGroup v-model:value="algorithmForm.sendCtrlCmd">
  310. <ARadio class="radio-right" :value="true">{{ $t('common.yes') }}</ARadio>
  311. <ARadio :value="false">{{ $t('common.no') }}</ARadio>
  312. </ARadioGroup>
  313. </AFormItem>
  314. <AFormItem :label="$t('algorithmManage.popupReminder')" name="msgBox">
  315. <ARadioGroup v-model:value="algorithmForm.msgBox">
  316. <ARadio class="radio-right" :value="true">{{ $t('common.yes') }}</ARadio>
  317. <ARadio :value="false">{{ $t('common.no') }}</ARadio>
  318. </ARadioGroup>
  319. </AFormItem>
  320. <AFormItem :label="t('algorithmManage.regulationCycle')" name="tempRiseCtrlPeriod">
  321. <AInputNumber
  322. v-model:value="algorithmForm.tempRiseCtrlPeriod"
  323. class="input-width"
  324. addon-after="min"
  325. :min="1"
  326. :max="99999"
  327. :placeholder="t('common.pleaseEnter')"
  328. />
  329. </AFormItem>
  330. <AFormItem :label="t('algorithmManage.coolingOffPeriod')" name="tempReductionCtrlPeriod">
  331. <AInputNumber
  332. v-model:value="algorithmForm.tempReductionCtrlPeriod"
  333. class="input-width"
  334. addon-after="min"
  335. :min="1"
  336. :max="99999"
  337. :placeholder="t('common.pleaseEnter')"
  338. />
  339. </AFormItem>
  340. <AFormItem
  341. class="input-width"
  342. :label="t('algorithmManage.controlStepSize') + '(℃)'"
  343. name="minCtrlStep"
  344. >
  345. <ASelect
  346. v-model:value="algorithmForm.minCtrlStep"
  347. :options="algTempCtrlMinStep"
  348. :field-names="{ label: 'dictValue', value: 'dictEngValue' }"
  349. :placeholder="$t('common.plzSelect')"
  350. />
  351. </AFormItem>
  352. </AFlex>
  353. <div class="analysis-style interval-style">
  354. <span>* </span>{{ $t('algorithmManage.effluentInterval') }}
  355. </div>
  356. <div v-for="(item, index) in temperatureRangeList" :key="index">
  357. <SetInterval
  358. ref="setIntervalRefs"
  359. :index="index"
  360. :form="item"
  361. @addClick="addClick"
  362. @deleteClick="deleteClick"
  363. />
  364. </div>
  365. <div class="analysis-style"><span>* </span>{{ $t('algorithmManage.waterOutletSetting') }}</div>
  366. <MonthSetting ref="monthSetting" :temperature-setting-value="temperatureSettingValue" />
  367. <AFlex class="flex-bottom" wrap="wrap" :gap="40">
  368. <AFormItem :label="t('algorithmManage.intelligentMode')" name="intelligentMode">
  369. <ARadioGroup v-model:value="algorithmForm.intelligentMode">
  370. <ARadio class="radio-right" :value="0">
  371. <AFlex align="center">
  372. <div>{{ $t('algorithmManage.intelligentEnergyConservation') }}</div>
  373. <SvgIcon class="icon-style" name="question-circle-o" />
  374. </AFlex>
  375. </ARadio>
  376. <ARadio :value="1">
  377. <AFlex align="center">
  378. <div>{{ $t('algorithmManage.prioritizeRequirements') }}</div>
  379. <SvgIcon class="icon-style" name="question-circle-o" />
  380. </AFlex>
  381. </ARadio>
  382. </ARadioGroup>
  383. </AFormItem>
  384. <AFormItem :label="t('algorithmManage.controlBasis')" name="controlBasis">
  385. <ARadioGroup v-model:value="algorithmForm.controlBasis">
  386. <ARadio class="radio-right" :value="0">{{ $t('envMonitor.temperature') }}</ARadio>
  387. <ARadio class="radio-right" :value="1">{{ $t('envMonitor.humidity') }}</ARadio>
  388. <ARadio :value="2">{{ $t('algorithmManage.temperatureHumidity') }}</ARadio>
  389. </ARadioGroup>
  390. </AFormItem>
  391. <AFormItem :label="t('algorithmManage.computingCycle')" name="period">
  392. <AInputNumber
  393. :placeholder="t('common.pleaseEnter')"
  394. v-model:value="algorithmForm.period"
  395. class="input-width"
  396. addon-after="min"
  397. />
  398. </AFormItem>
  399. <AFormItem :label="t('algorithmManage.temperatureSafetyMargin')" name="tempSafetyMargin">
  400. <AInputNumber
  401. :placeholder="t('common.pleaseEnter')"
  402. v-model:value="algorithmForm.tempSafetyMargin"
  403. class="input-width"
  404. addon-after="℃"
  405. />
  406. </AFormItem>
  407. <AFormItem :label="t('algorithmManage.humiditySafetyMargin')" name="humiditySafetyMargin">
  408. <AInputNumber
  409. v-model:value="algorithmForm.humiditySafetyMargin"
  410. class="input-width"
  411. addon-after="%"
  412. :placeholder="t('common.pleaseEnter')"
  413. />
  414. </AFormItem>
  415. <AFormItem
  416. :label="t('algorithmManage.temperatureHumidityAcquisitionCycle') + '(min)'"
  417. name="tempHumidityCollectPeriod"
  418. >
  419. <ASelect
  420. class="input-width"
  421. v-model:value="algorithmForm.tempHumidityCollectPeriod"
  422. :options="algTempHumCollectPeriod"
  423. :field-names="{ label: 'dictValue', value: 'dictEngValue' }"
  424. :placeholder="$t('common.plzSelect')"
  425. />
  426. </AFormItem>
  427. <AFormItem :label="t('algorithmManage.sourceTemperature')" name="waterSupplyTempSource">
  428. <ARadioGroup v-model:value="algorithmForm.waterSupplyTempSource">
  429. <ARadio class="radio-right" :value="0">{{ $t('algorithmManage.weighted') }} </ARadio>
  430. <ARadio :value="1"> {{ $t('algorithmManage.read') }} </ARadio>
  431. </ARadioGroup>
  432. </AFormItem>
  433. </AFlex>
  434. </AForm>
  435. </div>
  436. </ACollapsePanel>
  437. <ACollapsePanel
  438. v-show="chillersList.length > 0"
  439. :style="customStyle"
  440. v-for="item in chillersList"
  441. :key="item.id"
  442. >
  443. <template #header>
  444. <AFlex align="center" class="header-heigth">
  445. <span class="header-text">{{ item.deviceName }}</span>
  446. </AFlex>
  447. </template>
  448. <EquipmentControl
  449. ref="equipmentControlRefs"
  450. :alg-wt-temp-ctrl-mode="algWtTempCtrlMode"
  451. :alg-always="algAlways"
  452. :alg-wt-temp-set-step="algWtTempSetStep"
  453. :form="item"
  454. />
  455. </ACollapsePanel>
  456. <ACollapsePanel key="functionSettings" :style="customStyle">
  457. <template #header>
  458. <AFlex align="center" class="header-heigth">
  459. <span class="header-text">{{ $t('algorithmManage.systemFunctionSettings') }}</span>
  460. </AFlex>
  461. </template>
  462. <div>
  463. <AFlex align="center" class="analysis-bottom">
  464. <div class="text">{{ $t('energyAnalysis.energyEfficiencyAnalysis') }}</div>
  465. <ASwitch class="analysis-margin" v-model:checked="algorithmForm.analysis" />
  466. <div @click="analysisEditor" class="editor-style">{{ $t('common.editor') }}</div>
  467. </AFlex>
  468. <AFlex align="center">
  469. <div class="div-width">{{ $t('algorithmManage.dynamicAdjustment') }}</div>
  470. <AFlex align="center" class="adjustment-div">
  471. <div class="adjustment-text">{{ $t('algorithmManage.freezingSetValue') }}</div>
  472. <ASwitch v-model:checked="algorithmForm.enableRefrigerationPipeDynamicSet" />
  473. <div class="adjustment-text adjustment-left">{{ $t('algorithmManage.coolingSetValue') }}</div>
  474. <ASwitch v-model:checked="algorithmForm.enableCoolingPipeDynamicSet" />
  475. <div @click="setEditor" class="editor-style editor-left">{{ $t('common.editor') }}</div>
  476. </AFlex>
  477. </AFlex>
  478. </div>
  479. </ACollapsePanel>
  480. </ACollapse>
  481. <AFlex justify="space-between" class="bottom-style">
  482. <AButton type="text" @click="canceladd">{{ $t('common.cancel') }}</AButton>
  483. <AButton type="primary" class="button-width" @click="addAlgorithm">{{ $t('common.certain') }}</AButton>
  484. </AFlex>
  485. </div>
  486. <AModal
  487. v-model:open="analysisOpen"
  488. :title="t('algorithmManage.energyEfficiencyAnalysisSettings')"
  489. width="460px"
  490. :mask-closable="false"
  491. @ok="okConfirm"
  492. >
  493. <div class="analysis-style">
  494. <span>* </span>{{ $t('algorithmManage.energyEfficiencyAnalysisCalculationMethod') }}
  495. </div>
  496. <ARadioGroup v-model:value="analysisTypeDisplay">
  497. <ARadio class="radio-right" :value="0">{{ $t('algorithmManage.thermometer') }}</ARadio>
  498. <ARadio class="radio-right" :value="1">{{ $t('algorithmManage.flowChart') }}</ARadio>
  499. <ARadio :value="2">{{ $t('algorithmManage.copAlgorithm') }}</ARadio>
  500. </ARadioGroup>
  501. </AModal>
  502. <AModal
  503. v-model:open="setOpen"
  504. :title="t('common.settings')"
  505. width="460px"
  506. :mask-closable="false"
  507. @ok="okSetConfirm"
  508. >
  509. <AFlex align="center" class="set-top set-bottom">
  510. <div class="text">
  511. {{ $t('algorithmManage.backwaterTemperatureSettingValue') }} &nbsp;=&nbsp;
  512. {{ $t('algorithmManage.outdoorWetBulbTemperature') }} +
  513. </div>
  514. &nbsp;&nbsp;
  515. <AInputNumber v-model:value="coolingPipeDynamicOffsetDisplay" :min="-99999.99999" :max="99999" />
  516. </AFlex>
  517. <AFlex align="center" class="set-bottom">
  518. <div class="text set-text">{{ $t('algorithmManage.initialValue') }}(℃)</div>
  519. <AInputNumber
  520. class="set-input-width set-input-right"
  521. v-model:value="coolingPipeDynamicSetDisplay"
  522. :min="-99999.99999"
  523. :max="99999"
  524. />
  525. <div class="set-text text">{{ $t('algorithmManage.deadZone') }}(℃)</div>
  526. <AInputNumber
  527. class="set-input-width"
  528. v-model:value="coolingPipeDynamicDeadZoneDisplay"
  529. :min="-99999.99999"
  530. :max="99999"
  531. />
  532. </AFlex>
  533. <AFlex align="center" class="set-bottom">
  534. <div class="text lower-limit">{{ $t('algorithmManage.lowerLimit') }}(℃)</div>
  535. <AInputNumber
  536. class="set-input-width set-input-right"
  537. v-model:value="coolingPipeDynamicLowerDisplay"
  538. :min="-99999.99999"
  539. :max="99999"
  540. />
  541. <div class="set-text text">{{ $t('algorithmManage.upperLimit') }}(℃)</div>
  542. <AInputNumber
  543. class="set-input-width"
  544. v-model:value="coolingPipeDynamicUpperDisplay"
  545. :min="-99999.99999"
  546. :max="99999"
  547. />
  548. </AFlex>
  549. </AModal>
  550. </div>
  551. </template>
  552. <style lang="scss" scoped>
  553. .button-width {
  554. width: 128px;
  555. height: 40px;
  556. }
  557. .bottom-style {
  558. width: 55%;
  559. padding-left: 28px;
  560. margin-top: 8px;
  561. }
  562. .set-top {
  563. margin-top: 20px;
  564. }
  565. .set-bottom {
  566. margin-bottom: 24px;
  567. }
  568. .lower-limit {
  569. margin-right: 26px;
  570. }
  571. .set-input-right {
  572. margin-right: 40px;
  573. }
  574. .algorithm-form :deep(.ant-form-item-label > label) {
  575. color: #666;
  576. }
  577. .set-text {
  578. margin-right: 12px;
  579. }
  580. .text {
  581. font-size: 14px;
  582. font-style: normal;
  583. font-weight: 400;
  584. line-height: 22px;
  585. color: #666;
  586. }
  587. .set-input-width {
  588. width: 96px;
  589. }
  590. .editor-left {
  591. margin-left: 16px;
  592. }
  593. .adjustment-left {
  594. margin-left: 82px;
  595. }
  596. .adjustment-text {
  597. margin-right: 16px;
  598. font-size: 14px;
  599. font-style: normal;
  600. font-weight: 400;
  601. line-height: 22px;
  602. color: #666;
  603. text-align: left;
  604. }
  605. .analysis-style {
  606. margin-top: 16px;
  607. margin-bottom: 13px;
  608. color: #666;
  609. }
  610. .analysis-style span {
  611. color: red;
  612. }
  613. .analysis-bottom {
  614. margin-bottom: 24px;
  615. }
  616. .div-width {
  617. width: 72px;
  618. color: #666;
  619. }
  620. .adjustment-div {
  621. width: 100%;
  622. height: 72px;
  623. padding-left: 16px;
  624. background: #f5f7fa;
  625. border-radius: 4px;
  626. }
  627. .editor-style {
  628. color: #32bac0;
  629. text-decoration: underline;
  630. cursor: pointer;
  631. }
  632. .analysis-margin {
  633. margin: 0 18px 0 17px;
  634. }
  635. .header-heigth {
  636. height: 32px;
  637. }
  638. .icon-style {
  639. margin-left: 4px;
  640. }
  641. .flex-margin {
  642. margin: 16px 0;
  643. }
  644. .radio-right {
  645. margin-right: 16px;
  646. }
  647. .flex-bottom {
  648. row-gap: 0 !important;
  649. }
  650. .input-width {
  651. width: 192px;
  652. }
  653. .header-text {
  654. margin-right: 18px;
  655. font-size: 16px;
  656. font-style: normal;
  657. font-weight: 500;
  658. line-height: 24px;
  659. color: #000;
  660. text-align: left;
  661. }
  662. :deep(.algorithm-content) {
  663. .ant-collapse > .ant-collapse-item > .ant-collapse-header .ant-collapse-expand-icon {
  664. margin-top: 6px;
  665. }
  666. .ant-input-number-group .ant-input-number-group-addon {
  667. background-color: #fff;
  668. }
  669. .ant-collapse .ant-collapse-content {
  670. border: 0;
  671. .ant-collapse-content-box {
  672. padding: 16px 0;
  673. }
  674. }
  675. }
  676. .algorithm-content {
  677. width: 100%;
  678. height: 100%;
  679. padding: 24px;
  680. margin-top: 16px;
  681. background: #fff;
  682. border-radius: 16px;
  683. }
  684. .title-text {
  685. font-size: 20px;
  686. font-style: normal;
  687. font-weight: 500;
  688. line-height: 32px;
  689. color: rgb(0 0 0 / 85%);
  690. text-align: left;
  691. }
  692. .interval-style {
  693. margin-top: 0;
  694. }
  695. </style>