helper.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747
  1. 'use strict';
  2. const moment = require('moment');
  3. // 实销用户id
  4. exports.saledRoleId = 90;// '90'
  5. exports.timeMonthSeven = 1593532800000;// '2020年7月1日时间戳'
  6. // 远控行为ID
  7. exports.rcBehaviorId = 6016;
  8. // 远控结果
  9. exports.rcResult = {
  10. FAILED: { $in: [ 'false', 'FAILED', '请求超时,请稍后再试!' ] },
  11. SUCCEED: { $in: [ 'true', 'SUCCEED' ] },
  12. };
  13. // 车型车系
  14. exports.carType = {
  15. 电动车: [ 'E-HS3', 'E-HS9', 'E115', 'C105', 'NAT' ],
  16. 燃油车: [ 'H5', 'TEST_H9', 'H9', 'D357', 'HS7', 'HS730V', 'D365', 'HS5' ],
  17. };
  18. // 自动化测试类型
  19. exports.applicationDict = {
  20. 0: '连接认证',
  21. 1: '连接保持',
  22. 2: '远程控制',
  23. 3: '车况查询',
  24. 4: '远程配置',
  25. 5: '密钥更换',
  26. 6: '远程升级',
  27. 7: '紧急救援数据上报',
  28. 8: '车况数据上报',
  29. 9: '车辆定位',
  30. 10: '车辆告警',
  31. 11: '远程诊断',
  32. 12: '车辆延时控制状态上报',
  33. 13: '消息推送',
  34. 14: '用户问询',
  35. 15: '自动驾驶车辆控制',
  36. 16: '司机乘客报警处理状态反馈',
  37. 20: '证书申请',
  38. 21: 'CA连接认证',
  39. };
  40. // 远控类型
  41. exports.rcDict = {
  42. 车门解锁: { op: 'UNLOCK', behavior_id: 60160001 },
  43. 车门上锁: { op: 'LOCK', behavior_id: 60160001 },
  44. 车辆启动: { op: 'OPEN', behavior_id: 60160002 },
  45. 车辆熄火: { op: 'CLOSE', behavior_id: 60160002 },
  46. 空调开启: { op: 'OPEN', behavior_id: 60160003 },
  47. 空调关闭: { op: 'CLOSE', behavior_id: 60160003 },
  48. 空调温度控制: { behavior_id: 60160004 },
  49. 空调风量档位设置: { behavior_id: 60160005 },
  50. 前除霜模式开启: { op: 'OPEN', behavior_id: 60160006 },
  51. 前除霜模式关闭: { op: 'CLOSE', behavior_id: 60160006 },
  52. 后风窗加热开启: { op: 'OPEN', behavior_id: 60160007 },
  53. 后风窗加热关闭: { op: 'CLOSE', behavior_id: 60160007 },
  54. 空调运行时长设置: { behavior_id: 60160008 },
  55. 一键调温: { behavior_id: 60160009 },
  56. 主驾座椅加热开启: { behavior_id: 60160010, op: 'OPEN', opType: 'HOSTSEAT_HEAT' },
  57. 主驾座椅加热关闭: { behavior_id: 60160010, op: 'CLOSE', opType: 'HOSTSEAT_HEAT' },
  58. 副驾座椅加热开启: { behavior_id: 60160010, op: 'OPEN', opType: 'VICESEAT_HEAT' },
  59. 副驾座椅加热关闭: { behavior_id: 60160010, op: 'CLOSE', opType: 'VICESEAT_HEAT' },
  60. 左后座椅加热开启: { behavior_id: 60160010, op: 'OPEN', opType: 'LEFT_REAR_HEAT' },
  61. 左后座椅加热关闭: { behavior_id: 60160010, op: 'CLOSE', opType: 'LEFT_REAR_HEAT' },
  62. 右后座椅加热开启: { behavior_id: 60160010, op: 'OPEN', opType: 'RIGHT_REAR_HEAT' },
  63. 右后座椅加热关闭: { behavior_id: 60160010, op: 'CLOSE', opType: 'RIGHT_REAR_HEAT' },
  64. 空调预约: { behavior_id: 60160011 },
  65. 方向盘加热开启: { op: 'OPEN', behavior_id: 60160012 },
  66. 方向盘加热关闭: { op: 'CLOSE', behavior_id: 60160012 },
  67. 通风开启: { op: 'OPEN', behavior_id: 60160013 },
  68. 通风关闭: { op: 'CLOSE', behavior_id: 60160013 },
  69. 天窗开启: { op: 'OPEN', behavior_id: 60160014 },
  70. 天窗关闭: { op: 'CLOSE', behavior_id: 60160014 },
  71. 车灯开启: { op: 'OPEN', behavior_id: 60160015 },
  72. 车灯关闭: { op: 'CLOSE', behavior_id: 60160015 },
  73. 远程寻车: { behavior_id: 60160016 },
  74. 设置充电限值: { behavior_id: 60160017 },
  75. 设置放电电量限值: { behavior_id: 60160018 },
  76. 开始充电: { behavior_id: 60160019 },
  77. 结束充电: { behavior_id: 60160020 },
  78. 定时充电: { behavior_id: 60160021 },
  79. 充电完成提醒开启: { op: 'OPEN', behavior_id: 60160022 },
  80. 充电完成提醒关闭: { op: 'CLOSE', behavior_id: 60160022 },
  81. 充电状态查询: { behavior_id: 60160023 },
  82. 远程监控开启: { behavior_id: 60160024 },
  83. 远程监控正常关闭: { closeType: 'NORMAL', behavior_id: 60160025 },
  84. 远程监控异常关闭: { closeType: 'EXCEPTION', behavior_id: 60160025 },
  85. '控制充电桩(基于蓝牙)TBD': { behavior_id: 60160026 },
  86. 代客泊车: { behavior_id: 60160027 },
  87. 代客模式: { behavior_id: 60160028 },
  88. };
  89. // 故障类型
  90. exports.faultDict = {
  91. _S0100: '发动机管理系统故障',
  92. _S0101: '变速箱控制单元故障',
  93. _S0102: '排放系统故障',
  94. _S0103: '安全气囊系统故障',
  95. _S0104: '电子稳定系统故障',
  96. _S0105: '防抱死刹车系统故障',
  97. _S0107: '机油压力报警',
  98. _S0108: '油量低报警',
  99. _S0109: '制动液位报警',
  100. _S0110: '蓄电池充电故障',
  101. _S0111: '制动系统故障',
  102. _S0112: '胎压系统故障',
  103. _S0114: '外部灯光故障',
  104. _S0115: '电子转向柱锁故障',
  105. _S0116: '发动机水温过高报警',
  106. _S0117: '电子驻车单元系统故障',
  107. _S0118: '智能远光系统故障',
  108. _S0119: '自适应巡航系统故障',
  109. _S0121: '道路偏离预警系统故障',
  110. _S0122: '盲区检测系统故障',
  111. _S0123: '空调人为操作',
  112. _S0124: '高压系统故障',
  113. _S0125: '高压绝缘故障',
  114. _S0126: '高压互锁故障',
  115. _S0128: '动力电池故障',
  116. _S0129: '动力电机故障',
  117. _S0130: 'E-Park 故障',
  118. _S0131: '动力电池电量过低报警',
  119. _S0132: '动力电池温度过高报警',
  120. _S0133: '动力电机温度过高报警',
  121. _S0135: '充电机故障',
  122. _S0136: '空调故障',
  123. _S0137: '换道辅助系统故障',
  124. _S0138: '自动紧急制动系统故障',
  125. _S0139: '倒车雷达系统故障',
  126. _S0140: '电子换挡器系统故障',
  127. _S0142: '直流-直流转换器故障',
  128. _S0143: '整车控制器故障',
  129. _S0144: '纯电动继电器及线圈相关故障',
  130. _S0145: '自动驻车系统故障',
  131. _S0146: '陡坡缓降系统故障',
  132. _S0147: '灯具故障',
  133. _S0149: '12V 蓄电池系统故障',
  134. _S0150: '冷却液温度报警',
  135. _S0151: '冷却液液位低报警',
  136. _S0152: '机油温度报警',
  137. _S0153: 'HBB 故障',
  138. _S0154: '驾驶员安全带未系报警',
  139. _S0156: '清洗液液位低报警',
  140. _S0157: '制动摩擦片磨损过度报警',
  141. _S0158: '变速器温度过高报警',
  142. _S0159: 'DSM 故障',
  143. _S0160: 'DMS 故障',
  144. _S0161: '空气悬架系统故障',
  145. _S0163: '车桩通信故障',
  146. _S0164: '空调冷凝催化剂不足报警',
  147. _S0165: '动力电池SOC低无法启动放电报警',
  148. _S0166: '充放电枪连接时试图Ready报警',
  149. _S0167: '直流充电设备Station 故障',
  150. _S0168: '直流充电桩不匹配报警',
  151. _S0170: '交流充电设备供电异常',
  152. _S0171: '动力电池温度过低报警',
  153. _S0172: '动力电池温度差过大报警',
  154. _S0106: '电子助力转向系统故障',
  155. _S0113: '启停系统故障',
  156. _S0120: '前碰撞预警系统故障',
  157. _S0127: '动力电池充放电系统故障',
  158. _S0134: '定速巡航系统故障',
  159. _S0141: '轮胎报警',
  160. _S0148: '12V 蓄电池电量低报警',
  161. _S0155: '副驾驶安全带未系报警',
  162. _S0162: '暖风PTC故障',
  163. _S0169: '交流充电设备CP故障',
  164. // _S0100:'发动机常见故障',
  165. // _S0102:'发动机常见故障',
  166. // _S0116:'发动机常见故障',
  167. // _S0107:'发动机常见故障',
  168. // _S0152:'发动机常见故障',
  169. //
  170. // _S0149:'电气系统常见故障',
  171. // _S0148:'电气系统常见故障',
  172. // _S0110:'电气系统常见故障',
  173. // _S0123:'电气系统常见故障',
  174. // _S0136:'电气系统常见故障',
  175. // _S0164:'电气系统常见故障',
  176. // _S0147:'电气系统常见故障',
  177. // _S0130:'电气系统常见故障',
  178. // _S0135:'电气系统常见故障',
  179. // _S0118:'电气系统常见故障',
  180. // _S0169:'电气系统常见故障',
  181. // _S0104:'电气系统常见故障',
  182. // _S0114:'电气系统常见故障',
  183. // _S0162:'电气系统常见故障',
  184. // _S0170:'电气系统常见故障',
  185. // _S0165:'电气系统常见故障',
  186. // _S0171:'电气系统常见故障',
  187. // _S0172:'电气系统常见故障',
  188. // _S0127:'电气系统常见故障',
  189. // _S0131:'电气系统常见故障',
  190. // _S0132:'电气系统常见故障',
  191. // _S0159:'电气系统常见故障',
  192. // _S0160:'电气系统常见故障',
  193. // _S0166:'电气系统常见故障',
  194. // _S0167:'电气系统常见故障',
  195. // _S0168:'电气系统常见故障',
  196. // _S0126:'电气系统常见故障',
  197. //
  198. //
  199. // _S0101:'发动机常见故障',
  200. // _S0158:'发动机常见故障',
  201. //
  202. // _S0106:'传动系常见故障',
  203. // _S0115:'传动系常见故障',
  204. //
  205. // _S0105:'制动系常见故障',
  206. // _S0109:'制动系常见故障',
  207. // _S0111:'制动系常见故障',
  208. // _S0157:'制动系常见故障',
  209. // _S0145:'制动系常见故障',
  210. // _S0113:'制动系常见故障',
  211. // _S0117:'制动系常见故障',
  212. //
  213. // _S0141:'行驶系常见故障',
  214. // _S0112:'行驶系常见故障',
  215. // _S0161:'行驶系常见故障',
  216. //
  217. // _S0103:'车身常见故障',
  218. // _S0143:'车身常见故障',
  219. };
  220. // 用户出行评分 安全,节能评分
  221. exports.scoreDict = {
  222. 0: { $gte: 0, $lt: 60 },
  223. 1: { $gte: 60, $lt: 75 },
  224. 2: { $gte: 75, $lt: 90 },
  225. 3: { $gte: 90, $lte: 100 },
  226. };
  227. // 用户出行评分 安全评分mongo
  228. exports.drivingSafetyScoreProject = {
  229. driving_safety_score: 1,
  230. acceleration_score: 1,
  231. decelerate_score: 1,
  232. speeding_score: 1,
  233. fa_score: 1,
  234. fd_score: 1,
  235. turn_score: 1,
  236. clu_score: 1,
  237. flc_score: 1,
  238. io_score: 1,
  239. hs_turn_score: 1,
  240. at_night_drive_score: 1,
  241. un_tie_sb_score: 1,
  242. leave_sw_score: 1,
  243. dsm_score: 1,
  244. fcw_score: 1,
  245. bsd_score: 1,
  246. lka_score: 1,
  247. ldw_score: 1,
  248. };
  249. // 用户出行评分 节能评分mongo
  250. exports.energyConservationScoreProject = {
  251. energyConservationScore: '$energy_conservation_score',
  252. acceleration_score: 1,
  253. decelerate_score: 1,
  254. idling_score: 1,
  255. drive_anticipation_score: 1,
  256. oil_score: 1,
  257. sa_score: 1,
  258. sd_score: 1,
  259. steady_score: 1,
  260. };
  261. // 格式化时间
  262. exports.formatTime = time => moment(time).format('YYYY-MM-DD HH:mm:ss');
  263. exports.formatTime1 = time => moment(time).format('YYYY-MM-DD');
  264. exports.formatTime2 = time => moment(time).format('YYYY-MM-DD HH:mm:ss.SSS');
  265. exports.formatTime3 = time => moment(time).format('YYMM');
  266. // 获取昨日0:0:0
  267. exports.yesterday = () => moment().subtract(1, 'days').set('hour', 0)
  268. .set('minute', 0)
  269. .set('second', 0)
  270. .set('millisecond', 0)
  271. .valueOf();
  272. // 获取今日0:0:0
  273. exports.today = () => moment().set('hour', 0)
  274. .set('minute', 0)
  275. .set('second', 0)
  276. .set('millisecond', 0)
  277. .valueOf();
  278. // 解析时间字符串YYYY-MM-DD为时间戳
  279. exports.parse = str => moment(str, 'YYYY-MM-DD').valueOf();
  280. exports.parseS = str => parseInt(moment(str, 'YYYY-MM-DD HH:mm:ss.SSS').valueOf() / 1000);
  281. // 解析时间字符串为moment对象
  282. exports.momentDate = str => moment(str, 'YYYY-MM-DD');
  283. // 判断是否是今日
  284. exports.isToday = time => moment(new Date()).isSame(moment(time));
  285. // 当前年 今年
  286. exports.nowYear = time => moment(time).set('month', 0)
  287. .set('date', 1)
  288. .set('hour', 0)
  289. .set('minute', 0)
  290. .set('second', 0)
  291. .set('millisecond', 0)
  292. .valueOf();
  293. // 获取月头
  294. exports.getMonthTop = time => moment(time).set('date', 1)
  295. .set('hour', 0)
  296. .set('minute', 0)
  297. .set('second', 0)
  298. .set('millisecond', 0)
  299. .valueOf();
  300. // 上个月月头
  301. exports.preMonth = time => moment(time)
  302. .subtract(1, 'months')
  303. .set('date', 1)
  304. .set('hour', 0)
  305. .set('minute', 0)
  306. .set('second', 0)
  307. .set('millisecond', 0)
  308. .valueOf();
  309. // 获取转换时间戳对象project 默认转换字段$create_date
  310. exports.getTimeGenProject = (type, dateStr = 'create_date') => {
  311. // dateString: { $dateToString: { format: '%Y-%m-%d', date: { $toDate: dateStr } } },
  312. switch (type) {
  313. case '0':
  314. return {
  315. day: { $dayOfMonth: { date: { $toDate: `$${dateStr}` }, timezone: 'Asia/Shanghai' } },
  316. month: { $month: { date: { $toDate: `$${dateStr}` }, timezone: 'Asia/Shanghai' } },
  317. year: { $year: { date: { $toDate: `$${dateStr}` }, timezone: 'Asia/Shanghai' } },
  318. };
  319. case '1':
  320. return {
  321. month: { $month: { date: { $toDate: `$${dateStr}` }, timezone: 'Asia/Shanghai' } },
  322. year: { $year: { date: { $toDate: `$${dateStr}` }, timezone: 'Asia/Shanghai' } },
  323. };
  324. case '2':
  325. return {
  326. year: { $year: { date: { $toDate: `$${dateStr}` }, timezone: 'Asia/Shanghai' } },
  327. };
  328. default:
  329. break;
  330. }
  331. };
  332. // 获取转换时间戳范围match 默认字段$create_date
  333. exports.getTimeRangMatch = (startTime, endTime, dateStr = 'create_date') => {
  334. const match = {};
  335. match[dateStr] = { $gte: startTime, $lt: endTime };
  336. return match;
  337. };
  338. // 获取区域分组语句 (之前的前置语句或者结果必须存在 元素属性:city_name,area_name,provice_name,count)
  339. exports.getLocationMongo = () => {
  340. return [
  341. { $group: { _id: { area_name: '$area_name', provice_name: '$provice_name', city_name: '$city_name' },
  342. count: { $sum: '$count' } } },
  343. { $group: { _id: { area_name: '$_id.area_name', provice_name: '$_id.provice_name' },
  344. cities: { $push: { city_name: '$_id.city_name', count: '$count' } },
  345. count: { $sum: '$count' } } },
  346. { $group: { _id: { area_name: '$_id.area_name' },
  347. provinces: { $push: { provice_name: '$_id.provice_name', cities: '$cities', count: '$count' } },
  348. count: { $sum: '$count' } } },
  349. { $group: { _id: null,
  350. areas: { $push: { area_name: '$_id.area_name', provinces: '$provinces', count: '$count' } },
  351. count: { $sum: '$count' } } },
  352. ];
  353. };
  354. // 获取年龄和性别分组语句 (之前的前置语句或者结果必须存在 元素属性: id_card,gender)
  355. exports.getAggAndSexMongo = () => {
  356. return [
  357. {
  358. $bucket: {
  359. groupBy: { $cond: [ '$id_card',
  360. { $subtract: [{ $year: { date: { $toDate: new Date() }, timezone: 'Asia/Shanghai' } },
  361. { $convert: {
  362. input: { $substr: [ '$id_card', 6, 4 ] },
  363. to: 'int',
  364. onError: { $add: [{ $year: { date: { $toDate: new Date() }, timezone: 'Asia/Shanghai' } }, 1 ] } } },
  365. ] }, -1 ] },
  366. boundaries: [ 0, 25, 30, 35, 40, 200 ],
  367. default: 'Other',
  368. output: {
  369. mCount: { $sum: {
  370. $cond: [{ $eq: [ '$gender', 'M' ] }, 1, 0 ],
  371. } },
  372. fCount: { $sum: {
  373. $cond: [{ $eq: [ '$gender', 'F' ] }, 1, 0 ],
  374. } },
  375. count: { $sum: 1 },
  376. },
  377. },
  378. },
  379. ];
  380. };
  381. // 去重
  382. exports.unionArray = (a, b) => {
  383. return [ ...new Set([ ...a, ...b ]) ];
  384. };
  385. // 获取消息类型 时间分组语句
  386. exports.getMsgTimeGroupMongo = type => {
  387. switch (type) {
  388. case '0':
  389. return [
  390. { $group: { _id: { year: '$year', month: '$month', day: '$day', msgType: '$msgType._id' },
  391. count: { $sum: '$msgType.count' } } },
  392. { $group: { _id: { year: '$_id.year', month: '$_id.month', day: '$_id.day' },
  393. msgType: { $push: { _id: '$_id.msgType', count: '$count' } } } },
  394. ];
  395. case '1':
  396. return [
  397. { $group: { _id: { year: '$year', month: '$month', msgType: '$msgType._id' },
  398. count: { $sum: '$msgType.count' } } },
  399. { $group: { _id: { year: '$_id.year', month: '$_id.month' },
  400. msgType: { $push: { _id: '$_id.msgType', count: '$count' } } } },
  401. ];
  402. case '2':
  403. return [
  404. { $group: { _id: { year: '$year', msgType: '$msgType._id' },
  405. count: { $sum: '$msgType.count' } } },
  406. { $group: { _id: { year: '$_id.year' },
  407. msgType: { $push: { _id: '$_id.msgType', count: '$count' } } } },
  408. ];
  409. default:
  410. return [];
  411. }
  412. };
  413. // 获取车辆出行和疲劳次数分布 时间分组语句
  414. exports.getCarDSMTimeGroupMongo = type => {
  415. switch (type) {
  416. case '0':
  417. return [
  418. { $group: {
  419. _id: { year: '$year', month: '$month', day: '$day', _id: '$mileageStartTimeAndDsm._id._id' },
  420. count: { $sum: '$mileageStartTimeAndDsm.count' }, dsmCount: { $sum: '$mileageStartTimeAndDsm.dsmCount' } } },
  421. { $group: { _id: { year: '$_id.year', month: '$_id.month', day: '$_id.day' },
  422. data: { $push: { _id: '$_id._id', count: '$count', dsmCount: '$dsmCount' } } } },
  423. ];
  424. case '1':
  425. return [
  426. { $group: { _id: { year: '$year', month: '$month', _id: '$mileageStartTimeAndDsm._id._id' },
  427. count: { $sum: '$mileageStartTimeAndDsm.count' }, dsmCount: { $sum: '$mileageStartTimeAndDsm.dsmCount' } } },
  428. { $group: { _id: { year: '$_id.year', month: '$_id.month' },
  429. data: { $push: { _id: '$_id._id', count: '$count', dsmCount: '$dsmCount' } } } },
  430. ];
  431. case '2':
  432. return [
  433. { $group: { _id: { year: '$year', _id: '$mileageStartTimeAndDsm._id._id' },
  434. count: { $sum: '$mileageStartTimeAndDsm.count' }, dsmCount: { $sum: '$mileageStartTimeAndDsm.dsmCount' } } },
  435. { $group: { _id: { year: '$_id.year' },
  436. data: { $push: { _id: '$_id._id', count: '$count', dsmCount: '$dsmCount' } } } },
  437. ];
  438. default:
  439. return [];
  440. }
  441. };
  442. // 获取车辆根据 某个维度字段求和 进行时间分组语句
  443. exports.getCarTimeGroupMongo = (type, value) => {
  444. switch (type) {
  445. case '0':
  446. return [
  447. { $group: {
  448. _id: { year: '$year', month: '$month', day: '$day', _id: `$${value}._id._id` },
  449. count: { $sum: `$${value}.count` } } },
  450. { $group: { _id: { year: '$_id.year', month: '$_id.month', day: '$_id.day' },
  451. data: { $push: { _id: '$_id._id', count: '$count' } } } },
  452. ];
  453. case '1':
  454. return [
  455. { $group: { _id: { year: '$year', month: '$month', _id: `$${value}._id._id` },
  456. count: { $sum: `$${value}.count` } } },
  457. { $group: { _id: { year: '$_id.year', month: '$_id.month' },
  458. data: { $push: { _id: '$_id._id', count: '$count' } } } },
  459. ];
  460. case '2':
  461. return [
  462. { $group: { _id: { year: '$year', _id: `$${value}._id._id` },
  463. count: { $sum: `$${value}.count` } } },
  464. { $group: { _id: { year: '$_id.year' },
  465. data: { $push: { _id: '$_id._id', count: '$count' } } } },
  466. ];
  467. default:
  468. return [];
  469. }
  470. };
  471. // 获取车辆根据 某个维度字段求和 进行时间分组语句
  472. exports.getCarTimeGroupMongo2 = type => {
  473. switch (type) {
  474. case '0':
  475. return [
  476. { $group: {
  477. _id: { year: '$_id.year', month: '$_id.month', day: '$_id.day', _id: '$count._id._id' },
  478. count: { $sum: '$count.count' } } },
  479. { $group: { _id: { year: '$_id.year', month: '$_id.month', day: '$_id.day' },
  480. data: { $push: { _id: '$_id._id', count: '$count' } } } },
  481. ];
  482. case '1':
  483. return [
  484. { $group: { _id: { year: '$_id.year', month: '$_id.month', _id: '$count._id._id' },
  485. count: { $sum: '$count.count' } } },
  486. { $group: { _id: { year: '$_id.year', month: '$_id.month' },
  487. data: { $push: { _id: '$_id._id', count: '$count' } } } },
  488. ];
  489. case '2':
  490. return [
  491. { $group: { _id: { year: '$_id.year', _id: '$count._id._id' },
  492. count: { $sum: '$count.count' } } },
  493. { $group: { _id: { year: '$_id.year' },
  494. data: { $push: { _id: '$_id._id', count: '$count' } } } },
  495. ];
  496. default:
  497. return [];
  498. }
  499. };
  500. // 获取车辆根据 某个维度字段求平均值 进行时间分组语句
  501. exports.getCarAvgTimeGroupMongo = (type, value) => {
  502. switch (type) {
  503. case '0':
  504. return [
  505. { $group: {
  506. _id: { year: '$year', month: '$month', day: '$day', _id: `$${value}._id._id` },
  507. count: { $avg: `$${value}.count` } } },
  508. { $group: { _id: { year: '$_id.year', month: '$_id.month', day: '$_id.day' },
  509. data: { $push: { _id: '$_id._id', count: '$count' } } } },
  510. ];
  511. case '1':
  512. return [
  513. { $group: { _id: { year: '$year', month: '$month', _id: `$${value}._id._id` },
  514. count: { $avg: `$${value}.count` } } },
  515. { $group: { _id: { year: '$_id.year', month: '$_id.month' },
  516. data: { $push: { _id: '$_id._id', count: '$count' } } } },
  517. ];
  518. case '2':
  519. return [
  520. { $group: { _id: { year: '$year', _id: `$${value}._id._id` },
  521. count: { $avg: `$${value}.count` } } },
  522. { $group: { _id: { year: '$_id.year' },
  523. data: { $push: { _id: '$_id._id', count: '$count' } } } },
  524. ];
  525. default:
  526. return [];
  527. }
  528. };
  529. // 获取分页语句
  530. exports.getPageMongo = (pageNumber, pageSize) => {
  531. return [
  532. { $skip: (pageNumber - 1) * pageSize },
  533. { $limit: pageSize },
  534. ];
  535. };
  536. // 获取根据某个维度字段进行桶分组语句 -(区分车型车系)
  537. exports.getBucketMongo = (group, boundaries, sum = { $sum: 1 }, bucketF = {}) => {
  538. return [
  539. {
  540. $bucket: {
  541. groupBy: group,
  542. boundaries,
  543. default: 'Other',
  544. output: {
  545. v: { $push: { vin: '$vin', ...bucketF } },
  546. },
  547. },
  548. },
  549. { $unwind: '$v' },
  550. { $lookup: { from: 't_vehicle_record', localField: 'v.vin', foreignField: 'vin', as: 'car' } },
  551. { $unwind: { path: '$car', preserveNullAndEmptyArrays: true } },
  552. { $group: {
  553. _id: { series_code: '$car.series_code', model_code: '$car.model_code', _id: '$_id' },
  554. count: sum,
  555. } },
  556. ];
  557. };
  558. // 获取时间分组 type 0日 1月 2年
  559. exports.getTimeGroup = (type, baseCond = { count: { $sum: 1 } }) => {
  560. switch (type) {
  561. case '0':
  562. return {
  563. ...baseCond, _id: { year: '$year', month: '$month', day: '$day' },
  564. };
  565. case '1':
  566. return {
  567. ...baseCond, _id: { year: '$year', month: '$month' },
  568. };
  569. case '2':
  570. return {
  571. ...baseCond, _id: { year: '$year' },
  572. };
  573. default:
  574. break;
  575. }
  576. };
  577. // 通用的时间范围匹配 + 时间分组求和
  578. exports.getCommonAggSum = ({ type, startTime, endTime, value }) => {
  579. return [
  580. { $match: this.getTimeRangMatch(startTime, endTime) },
  581. { $group: this.getTimeGroup(type, { count: { $sum: `$${value}` } }) },
  582. ];
  583. };
  584. // 通用的时间范围匹配 + 时间分组平均值
  585. exports.getCommonAggAvg = ({ type, startTime, endTime, value }) => {
  586. return [
  587. { $match: this.getTimeRangMatch(startTime, endTime) },
  588. { $group: this.getTimeGroup(type, { count: { $avg: `$${value}` } }) },
  589. { $project: { count: { $trunc: '$count' } } },
  590. ];
  591. };
  592. // 通用的时间范围匹配 + 时间分组求最大(最近)时间数据
  593. exports.getCommonAggMax = ({ type, startTime, endTime, value }) => {
  594. return [
  595. { $match: this.getTimeRangMatch(startTime, endTime) },
  596. { $sort: { create_date: -1 } },
  597. { $group: this.getTimeGroup(type, { count: { $first: `$${value}` } }) },
  598. ];
  599. };
  600. // 车辆基本信息 字典字段映射
  601. exports.statusInfoDict = {
  602. statsAcceCnt: { k: 'stats_acce_cnt', num: 10, v: 'ar=' },
  603. statsSpRange: { k: 'stats_sp_range', num: 13, v: 'range=_cnt' },
  604. statsDece: { k: 'stats_dece', num: 10, v: 'dece=' },
  605. statsRotate: { k: 'stats_rotate', num: 8, v: 'rotate=' },
  606. statsSpRotate: { k: 'stats_sp_rotate', num: 8, v: 'rotate=', mode: [ 'sp_1_cnt', 'sp_2_cnt', 'sp_3_cnt' ] },
  607. statsHighSp: { k: 'stats_high_sp', num: 3, v: 'high_sp=' },
  608. statsStartSp: { k: 'stats_start_sp', num: 14, v: 'start_sp=' },
  609. yawPortraitAcces: { k: 'yaw_portrait_acces', num: 10, v: 'acce=' },
  610. statsDeceOther: { k: 'stats_dece_other', num: 16, v: 'dece=' },
  611. sidePortraitAcces: { k: 'side_portrait_acces', num: 10, v: 'acce=' },
  612. spPowerConsumption: { k: 'sp_power_consumption', num: 13, v: 'range=_cnt' },
  613. statsSpDeceCnt: { k: 'stats_sp_dece_cnt', num: 10, superNum: 7, v: 'sp_=_cnt.dece.dece=',
  614. mode: [ 'dr_mode_auto', 'dr_mode_eco', 'dr_mode_sport', 'dr_mode_confort' ] },
  615. statsSpAcceCnt: {
  616. multi: {
  617. acce: { k: 'stats_sp_acce_cnt', num: 10, superNum: 7, v: 'sp_=_cnt.acce.acce=' },
  618. as: { k: 'stats_sp_acce_cnt', num: 12, superNum: 7, v: 'sp_=_cnt.as.as=' },
  619. },
  620. },
  621. };
  622. // 根据车辆基本信息 字典字段映射 获取计算数组
  623. exports.getStatusInfoArr = () => {
  624. const arr = [];
  625. Object.keys(this.statusInfoDict).forEach(item => {
  626. const obj = this.statusInfoDict[item];
  627. if (obj.multi) {
  628. Object.keys(obj.multi).forEach(m => {
  629. const multiObj = obj.multi[m];
  630. if (multiObj.mode) {
  631. multiObj.mode.forEach(mode => {
  632. arr.push({ dbStr: `${multiObj.k}.${mode}.${multiObj.v}`, num: multiObj.num, superNum: multiObj.superNum });
  633. });
  634. } else {
  635. arr.push({ dbStr: `${multiObj.k}.${multiObj.v}`, num: multiObj.num, superNum: multiObj.superNum });
  636. }
  637. });
  638. } else {
  639. if (obj.mode) {
  640. obj.mode.forEach(mode => {
  641. arr.push({ dbStr: `${obj.k}.${mode}.${obj.v}`, num: obj.num, superNum: obj.superNum });
  642. });
  643. } else {
  644. arr.push({ dbStr: `${obj.k}.${obj.v}`, num: obj.num, superNum: obj.superNum });
  645. }
  646. }
  647. });
  648. return arr;
  649. };
  650. // 弃用 来源唯一
  651. exports.statusInfo = [
  652. [
  653. { dbStr: 'stats_acce_cnt.dr_mode_auto.ar=', num: 10 },
  654. { dbStr: 'stats_acce_cnt.dr_mode_eco.ar=', num: 10 },
  655. { dbStr: 'stats_acce_cnt.dr_mode_sport.ar=', num: 10 },
  656. { dbStr: 'stats_acce_cnt.dr_mode_confort.ar=', num: 10 },
  657. { dbStr: 'stats_sp_range.range=_cnt', num: 13 },
  658. { dbStr: 'stats_dece.dece=', num: 10 },
  659. { dbStr: 'stats_rotate.rotate=', num: 8 },
  660. { dbStr: 'stats_sp_rotate.sp_1_cnt.rotate=', num: 8 },
  661. { dbStr: 'stats_sp_rotate.sp_2_cnt.rotate=', num: 8 },
  662. { dbStr: 'stats_sp_rotate.sp_3_cnt.rotate=', num: 8 },
  663. { dbStr: 'stats_high_sp.high_sp=', num: 3 },
  664. { dbStr: 'stats_start_sp.start_sp=', num: 14 },
  665. { dbStr: 'stats_sp_dece_cnt.dr_mode_auto.sp_=_cnt.dece.dece=', superNum: 7, num: 10 },
  666. { dbStr: 'stats_sp_dece_cnt.dr_mode_eco.sp_=_cnt.dece.dece=', superNum: 7, num: 10 },
  667. { dbStr: 'stats_sp_dece_cnt.dr_mode_sport.sp_=_cnt.dece.dece=', superNum: 7, num: 10 },
  668. { dbStr: 'stats_sp_dece_cnt.dr_mode_confort.sp_=_cnt.dece.dece=', superNum: 7, num: 10 },
  669. { dbStr: 'stats_sp_acce_cnt.sp_=_cnt.acce.acce=', superNum: 6, num: 10 },
  670. { dbStr: 'stats_sp_acce_cnt.sp_=_cnt.as.as=', superNum: 6, num: 12 },
  671. ],
  672. ];
  673. // 测试使用 以下
  674. // 明年
  675. exports.nextYear = () => moment().add(1, 'year').set('month', 0)
  676. .set('date', 1)
  677. .set('hour', 0)
  678. .set('minute', 0)
  679. .set('second', 0)
  680. .set('millisecond', 0)
  681. .valueOf();
  682. // 3年前
  683. exports.before3Year = () => moment().subtract(2, 'year').set('month', 0)
  684. .set('date', 1)
  685. .set('hour', 0)
  686. .set('minute', 0)
  687. .set('second', 0)
  688. .set('millisecond', 0)
  689. .valueOf();
  690. // 下个月月头
  691. exports.nextMonth = time => moment(time).add(1, 'months').set('date', 1)
  692. .set('hour', 0)
  693. .set('minute', 0)
  694. .set('second', 0)
  695. .set('millisecond', 0)
  696. .valueOf();
  697. // 前一年的月
  698. exports.yMonth = () => moment().subtract(1, 'year')
  699. .add(1, 'months')
  700. .set('date', 1)
  701. .set('hour', 0)
  702. .set('minute', 0)
  703. .set('second', 0)
  704. .set('millisecond', 0)
  705. .valueOf();
  706. // 3个月月头
  707. exports.before3Month = time => moment(time).subtract(2, 'months').set('date', 1)
  708. .set('hour', 0)
  709. .set('minute', 0)
  710. .set('second', 0)
  711. .set('millisecond', 0)
  712. .valueOf();
  713. // 获取今日距离上个月
  714. exports.mToday = () => moment().subtract(1, 'months')
  715. .add(1, 'days')
  716. .set('hour', 0)
  717. .set('minute', 0)
  718. .set('second', 0)
  719. .set('millisecond', 0)
  720. .valueOf();