other.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. 'use strict';
  2. const Service = require('egg').Service;
  3. class OtherService extends Service {
  4. async selectUserByAuth(query) {
  5. const { ctx, app } = this;
  6. query.role = app.mongoose.Types.ObjectId('5d0c41046a0a730a44fe06b5');
  7. const resultList = await ctx.model.SysUserModel.aggregate([
  8. { $match: ctx.alterDeptId(query) },
  9. { $project: {
  10. _id: 1,
  11. authentication: {
  12. $cond: { if: { $ifNull: [ '$file', false ] }, then:
  13. { $cond:
  14. [{ $ne: [{ $ifNull: [ '$file', '' ] }, '' ] }, 0, 1 ],
  15. }, else: 1,
  16. },
  17. },
  18. } },
  19. {
  20. $group: {
  21. _id: '$authentication',
  22. count: { $sum: 1 },
  23. },
  24. },
  25. { $sort: { _id: 1 } },
  26. ]);
  27. const resultArr = [];
  28. try {
  29. resultList.forEach(item => {
  30. switch (item._id) {
  31. case 0:
  32. resultArr.push({ authentication: item._id.toString(), count: item.count });
  33. break;
  34. case 1:
  35. resultArr.push({ authentication: item._id.toString(), count: item.count });
  36. break;
  37. default:
  38. console.log('其他接口--采集员认证统计查询!');
  39. }
  40. });
  41. } catch (e) {
  42. ctx.logger.error('catch--------error', e);
  43. ctx.error(e);
  44. } finally {
  45. return resultArr;
  46. }
  47. }
  48. async fourquan(query) {
  49. const { ctx, app } = this;
  50. // 1.子女绑定个数(公众号输入老人身份证,点击查询老人信息就绑定了)
  51. const familyCount = await ctx.model.FamilyModel.find(ctx.alterDeptId(query)).countDocuments();
  52. const bindFamilyChildCount = await ctx.model.FamilyModel.aggregate([
  53. { $match: ctx.alterDeptId(query) },
  54. { $project: {
  55. _id: 1,
  56. child: {
  57. $cond:
  58. [{ $ne: [{ $ifNull: [ '$openId', []] }, []] }, 0, 1 ],
  59. },
  60. },
  61. },
  62. { $match: { child: 0 } },
  63. ]);
  64. // 2.积分存量
  65. const resultList2 = await ctx.model.ValueModel.aggregate([
  66. { $match: ctx.alterDeptId(query) },
  67. {
  68. $group: {
  69. _id: '$type',
  70. count: {
  71. $sum: 1,
  72. },
  73. },
  74. },
  75. ]);
  76. let allValue = 0;
  77. resultList2.forEach(item => {
  78. if (item._id === '0') { // 采集5积分
  79. allValue += item.count * 5;
  80. } else { // 探访1积分
  81. allValue += item.count * 1;
  82. }
  83. });
  84. // 3.巡访平均周期
  85. const resultList3 = await ctx.model.VisitModel.aggregate([
  86. { $match: ctx.alterDeptId(query) },
  87. {
  88. $group: {
  89. _id: '$infoId',
  90. mintime: {
  91. $min: '$visitTime',
  92. },
  93. maxtime: {
  94. $max: '$visitTime',
  95. },
  96. sum: {
  97. $sum: 1,
  98. },
  99. },
  100. },
  101. {
  102. $project: {
  103. avgtime: {
  104. $divide: [{
  105. $subtract: [{
  106. $toDouble: '$maxtime',
  107. }, {
  108. $toDouble: '$mintime',
  109. }],
  110. }, '$sum' ],
  111. },
  112. },
  113. },
  114. {
  115. $match: {
  116. avgtime: {
  117. $ne: 0,
  118. },
  119. },
  120. },
  121. {
  122. $group: {
  123. _id: null,
  124. allAvgTime: { $sum: '$avgtime' },
  125. count: { $sum: 1 },
  126. avgTime: { $avg: '$avgtime' },
  127. },
  128. },
  129. {
  130. $project: {
  131. _id: 0, allAvgTime: 1, count: 1, avgTime: 1,
  132. visitAvgDay: { $divide: [ '$avgTime', 1000 * 60 * 60 * 24 ] },
  133. visitAvgDayString: { $toString: { $divide: [ '$avgTime', 1000 * 60 * 60 * 24 ] } },
  134. },
  135. },
  136. {
  137. $project: {
  138. visitAvgDay: { // 自定义字段
  139. $substr: [ '$visitAvgDayString', 0, // substr,截取字符串
  140. { $cond: [ // 三元运算
  141. { $gte: [{ $indexOfCP: [ '$visitAvgDayString', '.' ] }, 0 ] }, // 是否存在小数点
  142. { $add: [{ $indexOfCP: [ '$visitAvgDayString', '.' ] }, 3 ] }, // 存在时,多向后取3位
  143. { $strLenCP: '$visitAvgDayString' }, // 不存在,取字符串的长度
  144. ] },
  145. ] },
  146. },
  147. },
  148. ]);
  149. let collection1 = {};
  150. if (resultList3.length > 0) {
  151. collection1 = { label: '巡访平均周期', value: resultList3[0].visitAvgDay + '天' };
  152. } else {
  153. collection1 = { label: '巡访平均周期', value: 0 + '天' };
  154. }
  155. const collection2 = { label: '子女绑定占比', value: Math.round(bindFamilyChildCount.length / familyCount * 100000) / 1000 };
  156. const collection3 = { label: '积分存量', value: allValue.toString() };
  157. const collection4 = { label: '兑换比例', value: 0 + '%' };
  158. const collectionResult = { data1: collection1, data2: collection2, data3: collection3, data4: collection4 };
  159. return collectionResult;
  160. }
  161. async infomonth(query) {
  162. const { ctx } = this;
  163. query.status = '3';
  164. // 当前年份【采集】数据(按月份组)
  165. const resultList1 = await ctx.model.InfoModel.aggregate([
  166. { $match: ctx.alterDeptId(query) },
  167. { $project: {
  168. _id: 1,
  169. // 这里需要加8小时,数据库里面的时间是ISO类型
  170. infoMonth: { $dateToString: { format: '%m', date: { $add: [ '$time', 1000 * 60 * 60 * 8 ] } } },
  171. infoTypeOfYear: { $sum: {
  172. $cond: [{ $eq: [
  173. { $dateToString: { format: '%Y', date: { $add: [ '$time', 1000 * 60 * 60 * 8 ] } } },
  174. { $dateToString: { format: '%Y', date: { $add: [ new Date(), 1000 * 60 * 60 * 8 ] } } },
  175. ] }, 1, 0 ],
  176. } },
  177. },
  178. },
  179. { $match: { infoTypeOfYear: 1 } },
  180. {
  181. $group: {
  182. _id: '$infoMonth',
  183. count: { $sum: 1 },
  184. },
  185. },
  186. { $sort: { _id: 1 } },
  187. ]);
  188. // 当前年份【探访】数据(按月份组)
  189. delete query.status;
  190. const resultList2 = await ctx.model.VisitModel.aggregate([
  191. { $match: ctx.alterDeptId(query) },
  192. { $project: {
  193. _id: 1,
  194. // 这里需要加8小时,数据库里面的时间是ISO类型
  195. visitMonth: { $dateToString: { format: '%m', date: { $add: [ '$visitTime', 1000 * 60 * 60 * 8 ] } } },
  196. visitTypeOfYear: { $sum: {
  197. $cond: [{ $eq: [
  198. { $dateToString: { format: '%Y', date: { $add: [ '$visitTime', 1000 * 60 * 60 * 8 ] } } },
  199. { $dateToString: { format: '%Y', date: { $add: [ new Date(), 1000 * 60 * 60 * 8 ] } } },
  200. ] }, 1, 0 ],
  201. } },
  202. },
  203. },
  204. { $match: { visitTypeOfYear: 1 } },
  205. {
  206. $group: {
  207. _id: '$visitMonth',
  208. count: { $sum: 1 },
  209. },
  210. },
  211. { $sort: { _id: 1 } },
  212. ]);
  213. const infoResultArr = [];
  214. const visitResultArr = [];
  215. let infoCollection;
  216. let visitCollection;
  217. const resultArr = [];
  218. const result1 = [];
  219. const result2 = [];
  220. try {
  221. // 采集数据
  222. resultList1.forEach(item => {
  223. infoResultArr.push({ label: item._id.toString(), value: item.count });
  224. });
  225. const monthNowArrInfo = ctx.monthNowArr();
  226. monthNowArrInfo.forEach(item => {
  227. result1.push({ label: item, value: 0 });
  228. });
  229. result1.forEach(itemA => {
  230. infoResultArr.forEach(item => {
  231. if (item.label == itemA.label) {
  232. itemA.value = item.value;
  233. }
  234. });
  235. });
  236. infoCollection = { label: '采集数据', data: result1 };
  237. resultArr.push(infoCollection);
  238. // 寻访数据
  239. resultList2.forEach(item => {
  240. visitResultArr.push({ label: item._id.toString(), value: item.count });
  241. });
  242. const monthNowArrVisit = ctx.monthNowArr();
  243. monthNowArrVisit.forEach(item => {
  244. result2.push({ label: item, value: 0 });
  245. });
  246. result2.forEach(itemA => {
  247. visitResultArr.forEach(item => {
  248. if (item.label == itemA.label) {
  249. itemA.value = item.value;
  250. }
  251. });
  252. });
  253. visitCollection = { label: '巡访数据', data: result2 };
  254. resultArr.push(visitCollection);
  255. } catch (e) {
  256. ctx.logger.error('catch--------error', e);
  257. ctx.error(e);
  258. } finally {
  259. return resultArr;
  260. }
  261. }
  262. async selectSexAndLook(query) {
  263. const { ctx, app } = this;
  264. query.role = app.mongoose.Types.ObjectId('5d0c41046a0a730a44fe06b5');
  265. query.$and = [
  266. { $and: [{ politicalOutlook: { $ne: null } }, { politicalOutlook: { $ne: '' } }] },
  267. { $and: [{ sex: { $ne: null } }, { sex: { $ne: '' } }] },
  268. ];
  269. const resultList = await ctx.model.SysUserModel.aggregate([
  270. { $match: ctx.alterDeptId(query) },
  271. { $project: {
  272. _id: 1, sex: 1, politicalOutlook: 1,
  273. },
  274. },
  275. {
  276. $group: {
  277. _id: {
  278. sex: '$sex',
  279. politicalOutlook: '$politicalOutlook',
  280. },
  281. count: { $sum: 1 },
  282. },
  283. },
  284. {
  285. $project: {
  286. _id: 0,
  287. label: { $concat: [ '$_id.sex', '$_id.politicalOutlook' ] },
  288. sex: '$_id.sex', politicalOutlook: '$_id.politicalOutlook', count: 1,
  289. },
  290. },
  291. ]);
  292. const partyMemberArr = []; // 党员
  293. const thMassesArr = []; // 群众
  294. let partyMemberCollection = {};
  295. let thMassesCollection = {};
  296. const resultArr = [];
  297. const result1 = [];
  298. const result2 = [];
  299. try {
  300. resultList.forEach(item => {
  301. switch (item.label) {
  302. case '男中共党员':
  303. partyMemberArr.push({ label: item.sex, value: item.count.toString() });
  304. break;
  305. case '女中共党员':
  306. partyMemberArr.push({ label: item.sex, value: item.count.toString() });
  307. break;
  308. case '男群众':
  309. thMassesArr.push({ label: item.sex, value: item.count.toString() });
  310. break;
  311. case '女群众':
  312. thMassesArr.push({ label: item.sex, value: item.count.toString() });
  313. break;
  314. default:
  315. console.log('其他接口--采集员 性别,政治面貌查询出现脏数据,但不影响本接口,请查看user表的politicalOutlook字段!');
  316. }
  317. });
  318. // 党员
  319. const partyMemberSexArr = ctx.sex();
  320. partyMemberSexArr.forEach(item => {
  321. result1.push({ label: item, value: 0 });
  322. });
  323. result1.forEach(itemA => {
  324. partyMemberArr.forEach(item => {
  325. if (item.label == itemA.label) {
  326. itemA.value = item.value;
  327. }
  328. });
  329. });
  330. partyMemberCollection = { label: '党员', arr: result1 };
  331. // 群众
  332. const thMassesSexArr = ctx.sex();
  333. thMassesSexArr.forEach(item => {
  334. result2.push({ label: item, value: 0 });
  335. });
  336. result2.forEach(itemA => {
  337. thMassesArr.forEach(item => {
  338. if (item.label == itemA.label) {
  339. itemA.value = item.value;
  340. }
  341. });
  342. });
  343. thMassesCollection = { label: '群众', arr: result2 };
  344. resultArr.push(partyMemberCollection);
  345. resultArr.push(thMassesCollection);
  346. } catch (e) {
  347. ctx.logger.error('catch--------error', e);
  348. ctx.error(e);
  349. } finally {
  350. return resultArr;
  351. }
  352. }
  353. async oldType(data) {
  354. const matchStr = {};
  355. matchStr.fid = data.deptFid;
  356. matchStr.level = data.deptLevel + '';
  357. const abilityCond = this.getOldAbiltyCond(matchStr);
  358. const OldTypeCond = this.getOldTypeCond(matchStr);
  359. const facet = {};
  360. facet.oldTypeResult = OldTypeCond;
  361. facet.abiltyResult = abilityCond;
  362. const result = await this.ctx.model.SysDeptModel.aggregate([{ $facet: facet }]).allowDiskUse(true);// 允许使用磁盘缓存
  363. const oldTypeResult = result[0].oldTypeResult;
  364. const abiltyResult = result[0].abiltyResult;
  365. for (let i = 0; i < abiltyResult.length; i++) {
  366. // 获取当前元素
  367. const abilityItem = abiltyResult[i];
  368. // 获取对应的oldTypeResult元素
  369. const oldTypeItem = oldTypeResult[i];
  370. // 将ability字段添加到oldTypeResult元素中,并命名为'oldType9'
  371. oldTypeItem.oldType9 = abilityItem.ability;
  372. }
  373. delete result[0].abiltyResult;
  374. return result[0].oldTypeResult;
  375. }
  376. // 统计各地区老人类别
  377. getOldTypeCond(matchStr) {
  378. return [
  379. { $match: matchStr },
  380. { $lookup: { from: 'info', localField: '_id', foreignField: 'dept' + matchStr.level, as: 'infos' } },
  381. { $unwind: { path: '$infos', preserveNullAndEmptyArrays: true } },
  382. { $unwind: { path: '$infos.oldType', preserveNullAndEmptyArrays: true } },
  383. { $unwind: { path: '$infos.status', preserveNullAndEmptyArrays: true } },
  384. // { $match: { 'infos.status': '3' } },
  385. { $group:
  386. { _id: '$_id',
  387. deptName: { $first: '$name' },
  388. deptCode: { $first: '$code' },
  389. level: { $first: '$level' },
  390. fid: { $first: '$fid' },
  391. order: { $first: '$order' },
  392. oldType1: { $sum: {
  393. $cond: [
  394. { $and:
  395. [
  396. { $eq: [ '$infos.oldType', '农村留守老年人' ] },
  397. { $eq: [ '$infos.status', '3' ] },
  398. ],
  399. }, 1, 0 ],
  400. } },
  401. oldType2: { $sum: {
  402. $cond: [
  403. { $and:
  404. [
  405. { $eq: [ '$infos.oldType', '分散供养特困老年人' ] },
  406. { $eq: [ '$infos.status', '3' ] },
  407. ],
  408. }, 1, 0 ],
  409. } },
  410. oldType3: { $sum: {
  411. $cond: [
  412. { $and:
  413. [
  414. { $eq: [ '$infos.oldType', '计划生育特殊家庭老人' ] },
  415. { $eq: [ '$infos.status', '3' ] },
  416. ],
  417. }, 1, 0 ],
  418. } },
  419. oldType4: { $sum: {
  420. $cond: [
  421. { $and:
  422. [
  423. { $eq: [ '$infos.oldType', '空巢老年人' ] },
  424. { $eq: [ '$infos.status', '3' ] },
  425. ],
  426. }, 1, 0 ],
  427. } },
  428. oldType5: { $sum: {
  429. $cond: [
  430. { $and:
  431. [
  432. { $eq: [ '$infos.oldType', '独居老年人' ] },
  433. { $eq: [ '$infos.status', '3' ] },
  434. ],
  435. }, 1, 0 ],
  436. } },
  437. oldType6: { $sum: {
  438. $cond: [
  439. { $and:
  440. [
  441. { $eq: [ '$infos.oldType', '重残老人' ] },
  442. { $eq: [ '$infos.status', '3' ] },
  443. ],
  444. }, 1, 0 ],
  445. } },
  446. oldType7: { $sum: {
  447. $cond: [
  448. { $and:
  449. [
  450. { $eq: [ '$infos.oldType', '高龄老人' ] },
  451. { $eq: [ '$infos.status', '3' ] },
  452. ],
  453. }, 1, 0 ],
  454. } },
  455. oldType8: { $sum: {
  456. $cond: [
  457. { $and:
  458. [
  459. { $eq: [ '$infos.oldType', '居家老年人' ] },
  460. { $eq: [ '$infos.status', '3' ] },
  461. ],
  462. }, 1, 0 ],
  463. } },
  464. },
  465. },
  466. { $sort: { order: 1 } },
  467. ];
  468. }
  469. // 统计各地区失能老人情况
  470. getOldAbiltyCond(matchStr) {
  471. return [
  472. { $match: matchStr },
  473. { $lookup: { from: 'info', localField: '_id', foreignField: 'dept' + matchStr.level, as: 'infos' } },
  474. { $unwind: { path: '$infos', preserveNullAndEmptyArrays: true } },
  475. { $unwind: { path: '$infos.status', preserveNullAndEmptyArrays: true } },
  476. { $group:
  477. {
  478. _id: '$_id',
  479. deptName: { $first: '$name' },
  480. deptCode: { $first: '$code' },
  481. level: { $first: '$level' },
  482. fid: { $first: '$fid' },
  483. order: { $first: '$order' },
  484. ability: {
  485. $sum: {
  486. $cond: [
  487. { $and:
  488. [
  489. { $eq: [ '$infos.ability', '失能' ] },
  490. { $eq: [ '$infos.status', '3' ] },
  491. ],
  492. }, 1, 0 ],
  493. },
  494. },
  495. },
  496. },
  497. {
  498. $sort: { order: 1 },
  499. },
  500. ];
  501. }
  502. }
  503. module.exports = OtherService;