MedicinalView.vue 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862
  1. <script setup>
  2. import { ref, onMounted, computed, unref, watch } from 'vue';
  3. import { NScrollbar, useMessage, NTabs, NTabPane, c } from 'naive-ui';
  4. import { TheChatView } from '@/components';
  5. import { controlApi } from "@/api/control";
  6. import BaseTitle from './components/BaseTitle.vue';
  7. import BaseRadioCard from './components/BaseRadioCard.vue';
  8. import BaseCard from './components/BaseCard.vue';
  9. import BaseChooseItem from './components/BaseChooseItem.vue';
  10. import BaseInput from './components/BaseInput.vue';
  11. import TheResultPanel from './components/TheResultPanel.vue';
  12. import TheEchartPanel from './components/TheEchartPanel.vue';
  13. const message = useMessage();
  14. const isVisibleBtn = ref(true);
  15. const isVisibleUpdateInfo = ref(false);
  16. const systemStatus = ref(0);
  17. const columnData = ref([
  18. { label: '后反馈设定', key: 'htfksd', value: '' },
  19. { label: '基准系数', key: 'jzxs', value: '' },
  20. { label: '修正系数', key: 'xzxs', value: '' },
  21. { label: '控制系数', key: 'kzxs', value: '' },
  22. { label: '水量分配系数', key: 'slfpxs', value: '' },
  23. { label: '碳源当量', key: 'tydl', value: '' },
  24. { label: '转换系数', key: 'zhxs', value: '' },
  25. { label: '稀释倍数', key: 'sxps', value: '' },
  26. { label: '药剂密度', key: 'yymd', value: '' },
  27. { label: '最小启动流量', key: 'zxqdll', value: '' },
  28. { label: '碳氮比', key: 'tdb', value: '' }
  29. ])
  30. const doseNum = ref(null);
  31. const flowNum = ref(null);
  32. const updateNum = ref(null);
  33. const tabKeyEnum = {
  34. 0: 'auto',
  35. 1: 'onePool',
  36. 2: 'twoPool',
  37. 3: 'worker'
  38. }
  39. // water实时数据
  40. const waterConfigParams = ref({});
  41. // 基础数据
  42. const dataSourceParams = ref({
  43. auto: {},
  44. onePool: {},
  45. twoPool: {},
  46. worker: {
  47. medicineAmount: null
  48. }
  49. })
  50. // 系数
  51. const baseSourceParams = ref({
  52. numberBeng: 0,
  53. type: 0
  54. })
  55. // 当前Tab选中的key
  56. const tabActiveKey = computed(() => tabKeyEnum[baseSourceParams.value.type]);
  57. // 计算碳氮比
  58. const tdbNum = computed(() => {
  59. const type = tabActiveKey.value;
  60. const [ r1, r2, rOne, rTwo] = getTotalNum();
  61. const {
  62. jsLlOne, jsLlTwo,
  63. jsCodOne, jsCodTwo,
  64. jsTnOne, jsTnTwo
  65. } = dataSourceParams.value[type];
  66. const {
  67. tydl, zhxs
  68. } = baseSourceParams.value
  69. if ( type === 'auto' || type === 'worker' ) {
  70. const rNum = Math.max( r1, r2 );
  71. const jsll = rNum == r1 ? jsLlOne: jsLlTwo;
  72. const cod = rNum == r1 ? jsCodOne: jsCodTwo;
  73. const jsTn = rNum == r1 ? jsTnOne: jsTnTwo;
  74. const n = rNum == r1 ? rOne : rOne
  75. return Number(((n*1000/jsll*tydl+cod*zhxs*tydl)/jsTn).toFixed(2)) + "%";
  76. }
  77. if ( type === 'onePool' ) {
  78. return Number(((rOne*1000/jsLlOne*tydl+jsCodOne*zhxs*tydl)/jsTnOne).toFixed(2)) + "%";
  79. }
  80. if ( type === 'twoPool' ) {
  81. return Number(((rTwo*1000/jsLlTwo*tydl+jsCodTwo*zhxs*tydl)/jsTnTwo).toFixed(2)) + "%";
  82. }
  83. })
  84. watch(() => tdbNum.value , tdb => {
  85. columnData.value[columnData.value.length - 1].value = tdb;
  86. })
  87. // 编辑系数 - confirm
  88. const onEditConfirm = () => {
  89. isVisibleBtn.value = true;
  90. columnData.value = columnData.value.map(item => {
  91. Object.entries(baseSourceParams.value).forEach(([key, value]) => {
  92. if (key === item.key) {
  93. item.value = value;
  94. }
  95. })
  96. return item;
  97. })
  98. handleMedicateAmount();
  99. }
  100. // 编辑系数 - 取消
  101. const onEditCancel = () => {
  102. isVisibleBtn.value = true;
  103. columnData.value.map(({ key, value }) => {
  104. baseSourceParams.value[key] = value;
  105. })
  106. }
  107. const onFinalResult = () => {
  108. const addStatus = systemStatus.value === 0 ? 1 : 0;
  109. controlApi.putSystemStatus({ addStatus });
  110. systemStatus.value = addStatus;
  111. message.warning(addStatus === 0 ? '当前投药状态:已停用' : '当前投药状态:投放中');
  112. }
  113. const onUpdateTab = (index) => {
  114. const currentData = dataSourceParams.value[tabKeyEnum[index]];
  115. baseSourceParams.value.type = index;
  116. if ( !Object.keys(currentData).length ) {
  117. isVisibleUpdateInfo.value = false;
  118. return;
  119. }
  120. handleMedicateAmount();
  121. }
  122. function getTotalNum() {
  123. const {
  124. hycXsyOne = 0, hycXsyTwo = 0,
  125. qycAdOne = 0, qycAdTwo = 0,
  126. qycYxyOne = 0, qycYxyTwo = 0,
  127. jsLlOne = 0, jsLlTwo = 0,
  128. jsCodOne = 0, jsCodTwo = 0
  129. } = dataSourceParams.value[tabActiveKey.value];
  130. const {
  131. htfksd, xzxs, kzxs, slfpxs, zhxs, tydl, jzxs, yymd, sxps
  132. } = baseSourceParams.value;
  133. const rOne1 = (((2*hycXsyOne-htfksd)+((qycAdOne+qycYxyOne)*xzxs-htfksd))*(jzxs-1))*(jsLlOne*slfpxs)/1000;
  134. const rOne2 = (rOne1*kzxs-(jsLlOne*slfpxs*jsCodOne*zhxs/1000))/tydl;
  135. const rOne3 = rOne2/yymd/1000*sxps
  136. const rTwo1 = (((2*hycXsyTwo-htfksd)+((qycAdTwo+qycYxyTwo)*xzxs-htfksd))*(jzxs-1))*(jsLlTwo*slfpxs)/1000;
  137. const rTwo2 = (rTwo1*kzxs-(jsLlTwo*slfpxs*jsCodTwo*zhxs/1000))/tydl;
  138. const rTwo3 = rTwo2/yymd/1000*sxps
  139. const r1 = Number((rOne3 < 0 || !rOne3) ? 0 : rOne3.toFixed(3)) || 0;
  140. const r2 = Number((rTwo3 < 0 || !rTwo3) ? 0 : rTwo3.toFixed(3)) || 0;
  141. return [ r1, r2, rOne2, rTwo2 ];
  142. }
  143. const onConfirmUpdate = async () => {
  144. await controlApi.postAddRecord({
  145. ...dataSourceParams.value[tabKeyEnum[baseSourceParams.value.type]],
  146. ...baseSourceParams.value,
  147. });
  148. isVisibleUpdateInfo.value = false;
  149. message.success("系统加药量,更新成功");
  150. doseNum.value = updateNum.value;
  151. }
  152. // 更新投药结果
  153. const handleMedicateAmount = () => {
  154. const type = tabActiveKey.value;
  155. const lastNum = unref(updateNum);
  156. const tdb = tdbNum.value;
  157. if ( type === 'worker' ) {
  158. const medicineNum = dataSourceParams.value.worker.medicineAmount;
  159. if ( medicineNum || medicineNum == 0 ) {
  160. updateNum.value = medicineNum;
  161. isVisibleUpdateInfo.value = true;
  162. baseSourceParams.value.tdb = tdb;
  163. message.warning("有新投放方案, 请查看")
  164. } else {
  165. updateNum.value = null;
  166. isVisibleUpdateInfo.value = false;
  167. }
  168. return;
  169. }
  170. const [r1, r2] = getTotalNum();
  171. const maxR = Math.max( r1, r2 );
  172. if ( type === 'auto' && maxR !== lastNum) {
  173. updateNum.value = maxR;
  174. isVisibleUpdateInfo.value = true;
  175. baseSourceParams.value.tdb = tdb;
  176. message.warning("有新的投放方案, 请查看");
  177. }
  178. if ( type === 'onePool' && r1 != lastNum) {
  179. updateNum.value = r1;
  180. isVisibleUpdateInfo.value = true;
  181. baseSourceParams.value.tdb = tdb;
  182. message.warning("有新的投放方案, 请查看");
  183. }
  184. if ( type === 'twoPool' && r2 != lastNum ) {
  185. updateNum.value = r2;
  186. isVisibleUpdateInfo.value = true;
  187. baseSourceParams.value.tdb = tdb;
  188. message.warning("有新的投放方案, 请查看");
  189. }
  190. }
  191. onMounted(async () => {
  192. // 获取最后一条记录 getSystemStatus
  193. await controlApi.getBaseData().then(({ data }) => {
  194. const {
  195. numberBeng = 0, type = 0,
  196. htfksd, jzxs, xzxs, kzxs, slfpxs, tydl, zhxs, sxps, yymd, zxqdll,
  197. medicineAmount,
  198. addType,
  199. tytjTransientLL
  200. } = data;
  201. baseSourceParams.value = {
  202. ...baseSourceParams.value,
  203. numberBeng, type,
  204. htfksd, jzxs, xzxs, kzxs, slfpxs, tydl, zhxs, sxps, yymd, zxqdll,
  205. addType
  206. };
  207. updateNum.value = medicineAmount;
  208. doseNum.value = medicineAmount;
  209. flowNum.value = tytjTransientLL;
  210. dataSourceParams.value[tabActiveKey.value] = data;
  211. })
  212. // 获取实时数据
  213. controlApi.getNumValue().then(({ data }) => {
  214. Object.entries(data).forEach(([key, val]) => {
  215. data[key] = val;
  216. });
  217. // water实时数据
  218. waterConfigParams.value = data;
  219. // 重新计算碳氮比
  220. const tdb = tdbNum.value;
  221. baseSourceParams.value.tdb = tdb;
  222. columnData.value = columnData.value.map(item => {
  223. item.value = item.key === 'tdb' ? tdb : dataSourceParams.value[tabActiveKey.value][item.key];
  224. return item;
  225. })
  226. const params = {
  227. jsLlType: 1,
  228. jsLlOne: data.jslYB,
  229. jsLlTwo: data.jslYB,
  230. jsCodType: 1,
  231. jsCodOne: data.jsCodYB,
  232. jsCodTwo: data.jsCodYB,
  233. hycXsyType: 1,
  234. hycXsyOne: data.hyXsyHYOne,
  235. hycXsyTwo: data.hyXsyHYTwo,
  236. qycYxyType: 1,
  237. qycYxyOne: data.qyXsyHYOne,
  238. qycYxyTwo: data.qyXsyHYTwo,
  239. qycAdType: 1,
  240. qycAdOne: data.qyAdHYOne,
  241. qycAdTwo: data.qyAdHYTwo,
  242. jsTnType: 1,
  243. jsTnOne: data.jsTnYB,
  244. jsTnTwo: data.jsTnYB
  245. }
  246. Object.keys(dataSourceParams.value).forEach(key => {
  247. const item = dataSourceParams.value[key];
  248. if ( !Object.keys(item).length ) {
  249. dataSourceParams.value[key] = { ...params };
  250. }
  251. })
  252. })
  253. // 获取是否允许投药开关
  254. controlApi.getSystemStatus().then(({ data }) => {
  255. // 0不允许 1允许
  256. systemStatus.value = data;
  257. });
  258. })
  259. </script>
  260. <template>
  261. <section class="flex items-start h-full">
  262. <TheChatView leftTitle="智适应碳源投加" :isChatSlot="false" :isFooter="false">
  263. <template #control>
  264. <div class="control-container space-x-[12px]">
  265. <div class="left-section">
  266. <BaseTitle title="智能投加计算"></BaseTitle>
  267. <n-scrollbar class="scrollbar" style="height: 100%;">
  268. <div class="form-content">
  269. <BaseCard title="选择加药泵">
  270. <BaseRadioCard v-model="baseSourceParams.numberBeng"></BaseRadioCard>
  271. </BaseCard>
  272. <BaseCard title="投加运行方式">
  273. <span class="status-bar">
  274. <i>{{ baseSourceParams.addType === 0 ? '启用智适应碳源投加' : '手动碳源投加' }}</i>
  275. </span>
  276. </BaseCard>
  277. <BaseCard title="选择池组手自动方式">
  278. <n-tabs justify-content="space-between" type="line" :bar-width="40"
  279. tab-style="min-width: 89px;" tab-class="custom-tab_item" animated :on-update:value="onUpdateTab" :value="baseSourceParams.type">
  280. <n-tab-pane :name="0" tab="自动">
  281. <div class="panel-header_main">
  282. <p>设置数据来源</p>
  283. <p class="space-x-[20px] text-center">
  284. <span>1号池</span>
  285. <span>2号池</span>
  286. </p>
  287. </div>
  288. <div class="space-y-[12px]">
  289. <BaseChooseItem
  290. tab-key="auto"
  291. title="进水流量"
  292. unit="m³"
  293. isDouble
  294. @on-update="handleMedicateAmount"
  295. v-model:type="dataSourceParams.auto.jsLlType"
  296. v-model:value1="dataSourceParams.auto.jsLlOne"
  297. v-model:value2="dataSourceParams.auto.jsLlTwo"
  298. :btn-group="[
  299. { label: '手动', value1: '', value2: '' },
  300. { label: '仪表', value1: waterConfigParams.jslYB, value2: waterConfigParams.jslYB }
  301. ]"
  302. ></BaseChooseItem>
  303. <BaseChooseItem
  304. tab-key="auto"
  305. title="进水COD"
  306. unit="mg/L"
  307. isDouble
  308. @on-update="handleMedicateAmount"
  309. v-model:type="dataSourceParams.auto.jsCodType"
  310. v-model:value1="dataSourceParams.auto.jsCodOne"
  311. v-model:value2="dataSourceParams.auto.jsCodTwo"
  312. :btn-group="[
  313. { label: '手动', value1: '', value2: '' },
  314. { label: '仪表', value1: waterConfigParams.jsCodYB, value2: waterConfigParams.jsCodYB },
  315. { label: '化验', value1: waterConfigParams.jsCodHY, value2: waterConfigParams.jsCodHY }
  316. ]"
  317. ></BaseChooseItem>
  318. <BaseChooseItem
  319. tab-key="auto"
  320. title="好氧池硝酸盐"
  321. unit="mg/L"
  322. isDouble
  323. @on-update="handleMedicateAmount"
  324. v-model:type="dataSourceParams.auto.hycXsyType"
  325. v-model:value1="dataSourceParams.auto.hycXsyOne"
  326. v-model:value2="dataSourceParams.auto.hycXsyTwo"
  327. :btn-group="[
  328. { label: '手动', value1: '', value2: '' },
  329. { label: '化验', value1: waterConfigParams.hyXsyHYOne, value2: waterConfigParams.hyXsyHYTwo },
  330. { label: '预测', value1: waterConfigParams.hyXsyYCOne, value2: waterConfigParams.hyXsyYCTwo }
  331. ]"
  332. ></BaseChooseItem>
  333. <BaseChooseItem
  334. tab-key="auto"
  335. title="缺氧池硝酸盐"
  336. unit="mg/L"
  337. isDouble
  338. @on-update="handleMedicateAmount"
  339. v-model:type="dataSourceParams.auto.qycYxyType"
  340. v-model:value1="dataSourceParams.auto.qycYxyOne"
  341. v-model:value2="dataSourceParams.auto.qycYxyTwo"
  342. :btn-group="[
  343. { label: '手动', value1: '', value2: '' },
  344. { label: '化验', value1: waterConfigParams.qyXsyHYOne, value2: waterConfigParams.qyXsyHYTwo }
  345. ]"
  346. ></BaseChooseItem>
  347. <BaseChooseItem
  348. tab-key="auto"
  349. title="缺氧池氨氮"
  350. unit="mg/L"
  351. isDouble
  352. @on-update="handleMedicateAmount"
  353. v-model:type="dataSourceParams.auto.qycAdType"
  354. v-model:value1="dataSourceParams.auto.qycAdOne"
  355. v-model:value2="dataSourceParams.auto.qycAdTwo"
  356. :btn-group="[
  357. { label: '手动', value1: '', value2: '' },
  358. { label: '化验', value1: waterConfigParams.qyAdHYOne, value2: waterConfigParams.qyAdHYTwo }
  359. ]"
  360. ></BaseChooseItem>
  361. <BaseChooseItem
  362. tab-key="auto"
  363. title="进水总氮"
  364. unit="mg/L"
  365. isDouble
  366. @on-update="handleMedicateAmount"
  367. v-model:type="dataSourceParams.auto.jsTnType"
  368. v-model:value1="dataSourceParams.auto.jsTnOne"
  369. v-model:value2="dataSourceParams.auto.jsTnTwo"
  370. :btn-group="[
  371. { label: '手动', value1: '', value2: '' },
  372. { label: '仪表', value1: waterConfigParams.jsTnYB, value2: waterConfigParams.jsTnYB }
  373. ]"
  374. ></BaseChooseItem>
  375. </div>
  376. </n-tab-pane>
  377. <n-tab-pane :name="1" tab="1号池">
  378. <div class="panel-header_main">
  379. <p>设置数据来源</p>
  380. <p class="space-x-[20px] text-center">
  381. <span>1号池</span>
  382. </p>
  383. </div>
  384. <div class="space-y-[12px]">
  385. <BaseChooseItem
  386. tab-key="onePool"
  387. title="进水流量"
  388. unit="m³"
  389. @on-update="handleMedicateAmount"
  390. v-model:type="dataSourceParams.onePool.jsLlType"
  391. v-model:value1="dataSourceParams.onePool.jsLlOne"
  392. :btn-group="[
  393. { label: '手动', value1: '', value2: '' },
  394. { label: '仪表', value1: waterConfigParams.jslYB, value2: waterConfigParams.jslYB }
  395. ]"
  396. ></BaseChooseItem>
  397. <BaseChooseItem
  398. tab-key="onePool"
  399. title="进水COD"
  400. unit="mg/L"
  401. @on-update="handleMedicateAmount"
  402. v-model:type="dataSourceParams.onePool.jsCodType"
  403. v-model:value1="dataSourceParams.onePool.jsCodOne"
  404. :btn-group="[
  405. { label: '手动', value1: '', value2: '' },
  406. { label: '仪表', value1: waterConfigParams.jsCodYB, value2: waterConfigParams.jsCodYB },
  407. { label: '化验', value1: waterConfigParams.jsCodHY, value2: waterConfigParams.jsCodHY }
  408. ]"
  409. ></BaseChooseItem>
  410. <BaseChooseItem
  411. tab-key="onePool"
  412. title="好氧池硝酸盐"
  413. unit="mg/L"
  414. @on-update="handleMedicateAmount"
  415. v-model:type="dataSourceParams.onePool.hycXsyType"
  416. v-model:value1="dataSourceParams.onePool.hycXsyOne"
  417. :btn-group="[
  418. { label: '手动', value1: '', value2: '' },
  419. { label: '化验', value1: waterConfigParams.hyXsyHYOne, value2: waterConfigParams.hyXsyHYTwo },
  420. { label: '预测', value1: waterConfigParams.hyXsyYCOne, value2: waterConfigParams.hyXsyYCTwo }
  421. ]"
  422. ></BaseChooseItem>
  423. <BaseChooseItem
  424. tab-key="onePool"
  425. title="缺氧池硝酸盐"
  426. unit="mg/L"
  427. @on-update="handleMedicateAmount"
  428. v-model:type="dataSourceParams.onePool.qycYxyType"
  429. v-model:value1="dataSourceParams.onePool.qycYxyOne"
  430. v-model:value2="dataSourceParams.onePool.qycYxyTwo"
  431. :btn-group="[
  432. { label: '手动', value1: '', value2: '' },
  433. { label: '化验', value1: waterConfigParams.qyXsyHYOne, value2: waterConfigParams.qyXsyHYTwo }
  434. ]"
  435. ></BaseChooseItem>
  436. <BaseChooseItem
  437. tab-key="onePool"
  438. title="缺氧池氨氮"
  439. unit="mg/L"
  440. @on-update="handleMedicateAmount"
  441. v-model:type="dataSourceParams.onePool.qycAdType"
  442. v-model:value1="dataSourceParams.onePool.qycAdOne"
  443. :btn-group="[
  444. { label: '手动', value1: '', value2: '' },
  445. { label: '化验', value1: waterConfigParams.qyAdHYOne, value2: waterConfigParams.qyAdHYTwo }
  446. ]"
  447. ></BaseChooseItem>
  448. <BaseChooseItem
  449. tab-key="onePool"
  450. title="进水总氮"
  451. unit="mg/L"
  452. @on-update="handleMedicateAmount"
  453. v-model:type="dataSourceParams.onePool.jsTnType"
  454. v-model:value1="dataSourceParams.onePool.jsTnOne"
  455. :btn-group="[
  456. { label: '手动', value1: '', value2: '' },
  457. { label: '仪表', value1: waterConfigParams.jsTnYB, value2: waterConfigParams.jsTnYB }
  458. ]"
  459. ></BaseChooseItem>
  460. </div>
  461. </n-tab-pane>
  462. <n-tab-pane :name="2" tab="2号池">
  463. <div class="panel-header_main">
  464. <p>设置数据来源</p>
  465. <p class="space-x-[20px] text-center">
  466. <span>2号池</span>
  467. </p>
  468. </div>
  469. <div class="space-y-[12px]">
  470. <BaseChooseItem
  471. tab-key="twoPool"
  472. title="进水流量"
  473. unit="m³"
  474. @on-update="handleMedicateAmount"
  475. v-model:type="dataSourceParams.twoPool.jsLlType"
  476. v-model:value1="dataSourceParams.twoPool.jsLlTwo"
  477. :btn-group="[
  478. { label: '手动', value1: '', value2: '' },
  479. { label: '仪表', value1: waterConfigParams.jslYB, value2: waterConfigParams.jslYB }
  480. ]"
  481. ></BaseChooseItem>
  482. <BaseChooseItem
  483. tab-key="twoPool"
  484. title="进水COD"
  485. unit="mg/L"
  486. @on-update="handleMedicateAmount"
  487. v-model:type="dataSourceParams.twoPool.jsCodType"
  488. v-model:value1="dataSourceParams.twoPool.jsCodTwo"
  489. :btn-group="[
  490. { label: '手动', value1: '', value2: '' },
  491. { label: '仪表', value1: waterConfigParams.jsCodYB, value2: waterConfigParams.jsCodYB },
  492. { label: '化验', value1: waterConfigParams.jsCodHY, value2: waterConfigParams.jsCodHY }
  493. ]"
  494. ></BaseChooseItem>
  495. <BaseChooseItem
  496. tab-key="twoPool"
  497. title="好氧池硝酸盐"
  498. unit="mg/L"
  499. @on-update="handleMedicateAmount"
  500. v-model:type="dataSourceParams.twoPool.hycXsyType"
  501. v-model:value1="dataSourceParams.twoPool.hycXsyTwo"
  502. :btn-group="[
  503. { label: '手动', value1: '', value2: '' },
  504. { label: '化验', value1: waterConfigParams.hyXsyHYTwo },
  505. { label: '预测', value1: waterConfigParams.hyXsyYCTwo }
  506. ]"
  507. ></BaseChooseItem>
  508. <BaseChooseItem
  509. tab-key="twoPool"
  510. title="缺氧池硝酸盐"
  511. unit="mg/L"
  512. @on-update="handleMedicateAmount"
  513. v-model:type="dataSourceParams.twoPool.qycYxyType"
  514. v-model:value1="dataSourceParams.twoPool.qycYxyTwo"
  515. :btn-group="[
  516. { label: '手动', value1: '', value2: '' },
  517. { label: '化验', value1: waterConfigParams.qyXsyHYTwo }
  518. ]"
  519. ></BaseChooseItem>
  520. <BaseChooseItem
  521. tab-key="twoPool"
  522. title="缺氧池氨氮"
  523. unit="mg/L"
  524. @on-update="handleMedicateAmount"
  525. v-model:type="dataSourceParams.twoPool.qycAdType"
  526. v-model:value1="dataSourceParams.twoPool.qycAdTwo"
  527. :btn-group="[
  528. { label: '手动', value1: '', value2: '' },
  529. { label: '化验', value1: waterConfigParams.qyAdHYTwo }
  530. ]"
  531. ></BaseChooseItem>
  532. <BaseChooseItem
  533. tab-key="twoPool"
  534. title="进水总氮"
  535. unit="mg/L"
  536. @on-update="handleMedicateAmount"
  537. v-model:type="dataSourceParams.twoPool.jsTnType"
  538. v-model:value1="dataSourceParams.twoPool.jsTnTwo"
  539. :btn-group="[
  540. { label: '手动', value1: '', value2: '' },
  541. { label: '仪表', value1: waterConfigParams.jsTnYB }
  542. ]"
  543. ></BaseChooseItem>
  544. </div>
  545. </n-tab-pane>
  546. <n-tab-pane :name="3" tab="人工投放">
  547. <div class="panel-header_main">
  548. <p>设置数据来源</p>
  549. <p class="space-x-[20px] text-center">
  550. <span>人工投放</span>
  551. </p>
  552. </div>
  553. <div class="w-full flex items-center justify-between">
  554. <span>人工投放:</span>
  555. <div class="w-[200px]">
  556. <BaseInput
  557. :isCloseIcon="false"
  558. v-model="dataSourceParams.worker.medicineAmount"
  559. @on-blur="handleMedicateAmount"
  560. ></BaseInput>
  561. </div>
  562. </div>
  563. </n-tab-pane>
  564. </n-tabs>
  565. </BaseCard>
  566. <BaseCard title="设定参数系数" style="margin: 0" tips="建议使用默认值,非必要不修改">
  567. <template #titleRight>
  568. <div>
  569. <div class="flex items-center space-x-[4px] cursor-pointer text-[#2454FF] text-[13px]"
  570. v-show="isVisibleBtn" @click="isVisibleBtn = false">
  571. <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
  572. <path d="M2.33337 14H14.3334" stroke="#2454FF" stroke-linecap="round"
  573. stroke-linejoin="round" />
  574. <path d="M3.66663 8.90663V11.3333H6.10569L13 4.43603L10.565 2L3.66663 8.90663Z"
  575. stroke="#2454FF" stroke-linejoin="round" />
  576. </svg>
  577. <span>编辑</span>
  578. </div>
  579. <ul class="flex items-center text-[13px] space-x-[8px] cursor-pointer" v-show="!isVisibleBtn">
  580. <li class="cursor-pointer" @click="onEditConfirm" style="color: #2454FF">确定</li>
  581. <li class="cursor-pointer text-[#B0B7C0]" @click="onEditCancel">取消</li>
  582. </ul>
  583. </div>
  584. </template>
  585. <ul class="data-source-list space-y-[12px]">
  586. <li class="data-soruce-item" v-for="item, index in columnData">
  587. <span>{{ item.label }}:</span>
  588. <span class="unit" v-show="isVisibleBtn">
  589. {{ item.value }}
  590. {{ index === 0 ? 'mg/L' : '' }}
  591. </span>
  592. <div style="width: 140px;" v-show="!isVisibleBtn">
  593. <BaseInput :unit="index === 0 ? 'mg/L' : ''" size='small' :isNeedFlotBtn="false"
  594. v-model="baseSourceParams[item.key]" isCenter placeholder="" :readonly="index === columnData.length - 1"></BaseInput>
  595. </div>
  596. </li>
  597. </ul>
  598. </BaseCard>
  599. </div>
  600. </n-scrollbar>
  601. </div>
  602. <div class="right-section">
  603. <TheResultPanel
  604. :updateNum="updateNum"
  605. :flowNum="flowNum"
  606. :doseNum="doseNum"
  607. :configuration-status="baseSourceParams.addType"
  608. v-model:system="systemStatus"
  609. v-model="isVisibleUpdateInfo"
  610. @on-click="onFinalResult"
  611. @on-update="onConfirmUpdate"
  612. ></TheResultPanel>
  613. <TheEchartPanel></TheEchartPanel>
  614. </div>
  615. </div>
  616. </template>
  617. </TheChatView>
  618. </section>
  619. </template>
  620. <style lang="scss" scoped>
  621. .control-container {
  622. @include flex(x, start, start);
  623. height: 100%;
  624. .left-section {
  625. display: flex;
  626. flex-flow: column;
  627. flex-shrink: 0;
  628. width: 440px;
  629. height: 100%;
  630. border-radius: 10px;
  631. background: #fff;
  632. .status-bar {
  633. display: inline-block;
  634. padding: 4px 14px;
  635. margin-left: 20px;
  636. border-top: 0.5px solid rgba(212, 241, 255, 0.00);
  637. border-bottom: 0.5px solid rgba(212, 241, 255, 0.00);
  638. background: linear-gradient(90deg, rgba(240, 250, 255, 0.00) 0%, #E9F8FF 27.27%, rgba(240, 250, 255, 0.00) 100%);
  639. i {
  640. line-height: 24px;
  641. background: linear-gradient(92deg, #5ABBF2 12.24%, #2454FF 63.2%);
  642. background-clip: text;
  643. -webkit-background-clip: text;
  644. -webkit-text-fill-color: transparent;
  645. font-weight: bold;
  646. }
  647. }
  648. .scrollbar {
  649. height: 100%;
  650. }
  651. .form-content {
  652. padding: 0 16px 24px 16px;
  653. }
  654. .panel-header_main {
  655. @include flex(x, center, between);
  656. margin-bottom: 12px;
  657. color: #86909C;
  658. span {
  659. display: inline-block;
  660. width: 60px;
  661. }
  662. }
  663. }
  664. .data-source-list {
  665. .data-soruce-item {
  666. @include flex(x, center, between);
  667. .inp-inner {
  668. width: 112px;
  669. }
  670. .unit {
  671. font-family: "D-DIN-PRO-700-Bold";
  672. font-weight: bold;
  673. font-size: 12px;
  674. color: #333;
  675. }
  676. }
  677. }
  678. }
  679. .right-section {
  680. width: 100%;
  681. height: 100%;
  682. border-radius: 8px;
  683. background: #fff;
  684. overflow: hidden;
  685. // .top {
  686. // flex-shrink: 1;
  687. // height: 214px;
  688. // border-radius: 8px;
  689. // border: 0.5px solid #FFF;
  690. // background: linear-gradient(90deg, #E0E8FC 0%, #F2F4FF 100%);
  691. // }
  692. // .bottom {
  693. // height: 100%;
  694. // background: pink;
  695. // }
  696. }
  697. // 通用区域的样式
  698. .btn {
  699. width: 80px;
  700. height: 32px;
  701. border-radius: 4px;
  702. border: 1px solid #D3D7DD;
  703. text-align: center;
  704. font-size: 14px;
  705. line-height: 32px;
  706. color: #1A2029;
  707. }
  708. .btn-primary {
  709. border: 0;
  710. background: var(--Linear, linear-gradient(270deg, #3BD6E3 0%, #019AFE 100%));
  711. font-weight: bold;
  712. color: #fff;
  713. }
  714. .btn-info {
  715. width: 44px;
  716. height: 28px;
  717. border-radius: 4px;
  718. border: 1px solid #D3D7DD;
  719. background: #fff;
  720. font-size: 12px;
  721. text-align: center;
  722. line-height: 28px;
  723. color: #1A2029;
  724. cursor: pointer;
  725. }
  726. .btn-info_active {
  727. color: #2454FF;
  728. border: 1px solid #2454FF;
  729. background: #EBF0FF;
  730. }
  731. .radio {
  732. display: block;
  733. width: 12px;
  734. height: 12px;
  735. border-radius: 100%;
  736. border: 1px solid #ccc;
  737. cursor: pointer;
  738. }
  739. .radio_big {
  740. width: 16px;
  741. height: 16px;
  742. }
  743. .radio-active {
  744. transition: all .1s;
  745. border: 3px solid #2454FF;
  746. }
  747. .radio_big.radio-active {
  748. border: 4px solid #2454FF;
  749. }
  750. </style>
  751. <style lang="scss">
  752. .custom-tab_item {
  753. @include flex (x, center, center);
  754. height: 35px;
  755. border-radius: 4px;
  756. background: #F3F5FA;
  757. &.n-tabs-tab--active {
  758. transition: none !important;
  759. border-radius: 4px;
  760. transition: none !important;
  761. background: url('https://static.fuxicarbon.com/bigModel/pc/tab-border-item-2x.png') -3px 0px no-repeat, linear-gradient(180deg, #F1F3FE 0%, #FFF 100%);
  762. background-size: 107% 100%;
  763. }
  764. }
  765. .control-container .left-section {
  766. .n-tabs-nav-scroll-content {
  767. padding-bottom: 10px;
  768. }
  769. }
  770. </style>