utils.js 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. import moment from 'moment';
  2. import {
  3. getDeviceRealData,
  4. getDeviceRealDataByTime,
  5. queryFormCurrentData,
  6. queryFormHistoryData,
  7. } from '@/services/ProjectAdmin';
  8. const computePrefixExpression = (function() {
  9. var s1 = [],
  10. result;
  11. return function(prefixExpression) {
  12. s1.length = 0;
  13. //计算
  14. while (prefixExpression.length > 0) {
  15. var o = prefixExpression.shift();
  16. if (operator_map.indexOf(o) == -1) {
  17. s1.push(Number(o));
  18. } else {
  19. switch (o) {
  20. case '+': {
  21. result = s1.pop() + s1.pop();
  22. break;
  23. }
  24. case '-': {
  25. result = s1.pop() - s1.pop();
  26. break;
  27. }
  28. case '*': {
  29. result = s1.pop() * s1.pop();
  30. break;
  31. }
  32. case '/': {
  33. result = s1.pop() / s1.pop();
  34. break;
  35. }
  36. }
  37. s1.push(result);
  38. }
  39. }
  40. return s1[0];
  41. };
  42. })();
  43. export async function getOptions(values, datas, formula, projectId) {
  44. let allDatas = getAllParams(datas, formula);
  45. let optionsData = getOptionsData(datas, formula, values);
  46. // 请求接口
  47. const { plcData, formData } = await queryData(values, allDatas, projectId);
  48. optionsData = optionsData.map(item => {
  49. const paramsInfo = item.paramsInfo;
  50. let res;
  51. if (paramsInfo.data_type == 0) {
  52. // plc数据
  53. res = findPlcData(paramsInfo, plcData, values.timeType);
  54. } else if (paramsInfo.data_type == 1) {
  55. // form数据
  56. res = findFormData(paramsInfo, formData, values.timeType);
  57. } else if (paramsInfo.data_type == 2) {
  58. // 获取公式的值
  59. res = getFormulaData(item.paramsInfo, plcData, formData, values.timeType);
  60. }
  61. return { ...item, ...res };
  62. });
  63. return {
  64. ...values,
  65. data: optionsData,
  66. };
  67. }
  68. // 根据表单的数据项获取请求参数
  69. function getFormParams(datas, projectId) {
  70. let params = {};
  71. datas.forEach(item => {
  72. if (!params[item.data_name]) params[item.data_name] = [];
  73. params[item.data_name].push(item.data_title);
  74. });
  75. return Object.keys(params).map(data_name => ({
  76. formName: data_name,
  77. titles: params[data_name],
  78. projectId,
  79. }));
  80. }
  81. async function queryData(values, datas, projectId) {
  82. let plcDatas = [],
  83. formDatas = [];
  84. datas.forEach(item => {
  85. if (item.data_type == 0) {
  86. plcDatas.push(item);
  87. } else {
  88. formDatas.push(item);
  89. }
  90. });
  91. // 根据params获取form的数据
  92. var formData = await getFormData(values, formDatas, projectId);
  93. var plcData = await getPlcData(values, plcDatas);
  94. if (values.timeType) {
  95. // 获得时间轴全集
  96. let times = getTimes(plcData[0]?.data, formData[0]?.data);
  97. // 根据时间全集补填数据
  98. formatData(plcData, times);
  99. formatData(formData, times);
  100. }
  101. return {
  102. plcData,
  103. formData,
  104. };
  105. }
  106. // 根据时间进行格式化数据
  107. function formatData(datas, times) {
  108. datas.forEach(item => {
  109. // 默认数据
  110. let newItemData = [];
  111. let i = 0;
  112. times.forEach(t => {
  113. if (item.data[i]?.htime != t) {
  114. // 空缺时间要补0
  115. newItemData.push({
  116. htime: t,
  117. val: 0,
  118. });
  119. } else {
  120. newItemData.push(item.data[i]);
  121. i++;
  122. }
  123. });
  124. // 使用新值
  125. item.data = newItemData;
  126. });
  127. }
  128. function getTimes(plcTimes = [], formTimes = []) {
  129. let times = {};
  130. plcTimes.forEach(item => {
  131. times[item.htime] = true;
  132. });
  133. formTimes.forEach(item => {
  134. times[item.htime] = true;
  135. });
  136. return Object.keys(times).sort((a, b) => new Date(a) - new Date(b));
  137. }
  138. async function getFormData(values, datas, projectId) {
  139. let arrtData = values.data || [];
  140. const params = getFormParams(datas, projectId);
  141. if (!values.timeType) {
  142. // 请求最新数据
  143. return await getFormCurrentData(params, values);
  144. } else {
  145. // 请求历史数据
  146. return await getFormHistoryData(params, values);
  147. }
  148. }
  149. // 请求表单最新数据
  150. async function getFormCurrentData(params, values) {
  151. const { timeType, date } = values;
  152. let data = [];
  153. for (let i = 0; i < params.length; i++) {
  154. const resData = await queryFormCurrentData(params[i]);
  155. data = [...data, ...resData];
  156. }
  157. return data;
  158. }
  159. // 请求表单历史数据
  160. async function getFormHistoryData(params, values) {
  161. const { timeType, date } = values;
  162. let sTime, eTime;
  163. let data = [];
  164. // -1为自选日期 从date内获取时间
  165. if (timeType == -1) {
  166. let clear = { hour: 0, minute: 0, second: 0, millisecond: 0 };
  167. eTime = moment(date[1])
  168. .set(clear)
  169. .format('YYYY-MM-DD HH:mm:ss');
  170. sTime = moment(date[0])
  171. .set(clear)
  172. .format('YYYY-MM-DD HH:mm:ss');
  173. } else {
  174. let currentDate = moment();
  175. eTime = currentDate.format('YYYY-MM-DD HH:mm:ss');
  176. sTime = currentDate.add(-1 * timeType, 'hour').format('YYYY-MM-DD HH:mm:ss');
  177. }
  178. for (let i = 0; i < params.length; i++) {
  179. const resData = await queryFormHistoryData({ ...params[i], eTime, sTime });
  180. data = [...data, ...resData];
  181. }
  182. return data;
  183. }
  184. async function getPlcData(values, datas) {
  185. let arrtData = values.data || [];
  186. let params = getSingleData(datas);
  187. if (!values.timeType) {
  188. let res = await getData(params, values);
  189. return res.data;
  190. } else {
  191. let singleData = [];
  192. for (let i = 0; i < params.length; i++) {
  193. const item = params[i];
  194. let res = await getData(item, values);
  195. singleData.push({
  196. paramsInfo: item,
  197. name: item.deviceName,
  198. data: (res.data || []).map(item => {
  199. return {
  200. val: Number(item.val),
  201. htime: moment(item.htime_at).format('YYYY-MM-DD HH:mm:ss'),
  202. };
  203. }),
  204. });
  205. }
  206. return singleData;
  207. }
  208. }
  209. // 根据数据项获取请求参数
  210. function getSingleData(datas) {
  211. let params = [];
  212. datas.forEach(({ device_id, device_items, seq }) => {
  213. if (device_id && device_items) {
  214. params.push({
  215. deviceName: seq,
  216. deviceId: device_id,
  217. deviceItems: device_items,
  218. });
  219. }
  220. });
  221. return params;
  222. }
  223. function findPlcData(paramsInfo, plcData, timeType) {
  224. // 实时数据与历史数据结构不一致 需判断
  225. if (timeType) {
  226. return plcData.find(resItem => resItem.paramsInfo.deviceName == paramsInfo.seq);
  227. } else {
  228. let res = plcData.find(resItem => resItem.alias == paramsInfo.seq);
  229. return {
  230. name: res.alias,
  231. value: res.val,
  232. };
  233. }
  234. }
  235. function findFormData(paramsInfo, formData, timeType) {
  236. // 实时数据与历史数据结构不一致 需判断
  237. if (timeType) {
  238. return formData.find(resItem => resItem.name == paramsInfo.data_title);
  239. } else {
  240. let res = formData.find(resItem => resItem.title == paramsInfo.data_title);
  241. return {
  242. name: res.title,
  243. value: res.value,
  244. };
  245. }
  246. }
  247. function getAllParams(datas, formula) {
  248. let allDatas = [...datas];
  249. formula.forEach(f => {
  250. f.params.forEach(params => {
  251. if (params.data_type == 0) {
  252. if (!datas.find(item => item.seq == params.seq)) {
  253. allDatas.push(params);
  254. }
  255. } else {
  256. if (!datas.find(item => item.data_title == params.data_title)) {
  257. allDatas.push(params);
  258. }
  259. }
  260. });
  261. });
  262. return allDatas;
  263. }
  264. function getOptionsData(datas, formula, values) {
  265. let valuesData = values.data || [];
  266. let optionsData = [];
  267. formula.forEach((item, index) => {
  268. var arrData = valuesData[index] || {};
  269. item.data_type = 2;
  270. arrData.paramsInfo = item;
  271. optionsData.push(arrData);
  272. });
  273. datas.forEach((data, index) => {
  274. var arrData = valuesData[index + formula.length] || {};
  275. arrData.paramsInfo = data;
  276. optionsData.push(arrData);
  277. });
  278. return optionsData;
  279. }
  280. var DATA_CACHE = {};
  281. // 请求plc数据
  282. async function getData(params, values) {
  283. const { timeType, date, size, interval, aggregator } = values;
  284. let key, etime, stime;
  285. if (!timeType) {
  286. key = `${params.map(item => item.deviceItems).join(',')}-${timeType}`;
  287. } else if (timeType != -1) {
  288. key = `${params.deviceItems}-${timeType}-${size}-${interval}-${aggregator}`;
  289. } else {
  290. let clear = { hour: 0, minute: 0, second: 0, millisecond: 0 };
  291. etime = moment(date[1]).set(clear) * 1;
  292. stime = moment(date[0]).set(clear) * 1;
  293. key = `${params.deviceItems}-${stime}-${etime}-${size}-${interval}-${aggregator}`;
  294. }
  295. if (!DATA_CACHE[key]) {
  296. if (!timeType) {
  297. DATA_CACHE[key] = await getDeviceRealData(params);
  298. } else {
  299. if (timeType != -1) {
  300. let currentDate = moment();
  301. etime = currentDate * 1;
  302. stime = currentDate.add(-1 * timeType, 'hour') * 1;
  303. }
  304. DATA_CACHE[key] = await getDeviceRealDataByTime({
  305. deviceid: params.deviceId * 1,
  306. dataitemid: params.deviceItems,
  307. stime,
  308. etime,
  309. size,
  310. interval,
  311. aggregator,
  312. });
  313. }
  314. }
  315. return DATA_CACHE[key];
  316. }
  317. function getFormulaData(formula, plcData, formData, timeType) {
  318. let expression = [...formula.expression];
  319. let resDatas = formula.params.map(params => {
  320. let res;
  321. if (params.data_type == 0) {
  322. res = findPlcData(params, plcData, timeType);
  323. return {
  324. ...params,
  325. ...res,
  326. };
  327. } else {
  328. res = findFormData(params, formData, timeType);
  329. return {
  330. ...params,
  331. ...res,
  332. };
  333. }
  334. });
  335. if (timeType) {
  336. let optionsData = [];
  337. // 获取时间
  338. let time = resDatas[0].data.map(item => item.htime);
  339. time.forEach((htime, index) => {
  340. resDatas.forEach(params => {
  341. // 根据index去替换表达式中对应的值
  342. expression[params.index] = params.data[index].val || 0;
  343. });
  344. optionsData.push({
  345. htime: moment(htime).format('YYYY-MM-DD HH:mm:ss'),
  346. val: computePrefixExpression([...expression]),
  347. });
  348. });
  349. return {
  350. data: optionsData,
  351. name: formula.FormulaName,
  352. };
  353. } else {
  354. resDatas.forEach(params => {
  355. // 根据index去替换表达式中对应的值
  356. expression[params.index] = params.value || 0;
  357. });
  358. return {
  359. value: computePrefixExpression([...expression]),
  360. name: formula.FormulaName,
  361. };
  362. }
  363. }