index.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. const _Http = getApp().globalData.http,
  2. currency = require("../../utils/currency"),
  3. CNY = (value, symbol = "", precision = 2) => currency(value, {
  4. symbol,
  5. precision
  6. }).format(),
  7. conversion = n => {
  8. const integer = (n + '').split(".")[0] + '',
  9. length = integer.length,
  10. regexp = /(?:\.0*|(\.\d+?)0+)$/
  11. if (length <= 4) {
  12. const index = 4 - length;
  13. return { //元
  14. show: CNY(n, "¥", index).replace(regexp, '$1'),
  15. value: CNY(n, '¥')
  16. }
  17. } else if (length <= 8) {
  18. return { //万-千万
  19. show: CNY(currency(n).divide(wx.getStorageSync('languagecode') == 'ZH' ? 10000 : 1000)).replace(regexp, '$1') + getApp().globalData.Language.getMapText('万元'),
  20. value: CNY(n)
  21. }
  22. } else {
  23. return { //亿
  24. show: CNY(currency(n).divide(100000000)).replace(regexp, '$1') + getApp().globalData.Language.getMapText('亿'),
  25. value: CNY(n)
  26. }
  27. }
  28. };
  29. import {
  30. createElement
  31. } from '@antv/f2';
  32. import Chart from './modules/chart';
  33. import barChart from './modules/barChart';
  34. import {
  35. jsx as _jsx
  36. } from "@antv/f2/jsx-runtime";
  37. Page({
  38. data: {
  39. onRenderChart: () => {},
  40. onRenderBarChart: () => {},
  41. showFiltrate: false,
  42. "where": {
  43. "begindate": "",
  44. "enddate": "",
  45. "departmentid": ""
  46. },
  47. content: {
  48. nocache: true,
  49. dataid: wx.getStorageSync('userMsg').userid,
  50. type: 0,
  51. dateType: 0,
  52. where: {
  53. begdate: "",
  54. enddate: "",
  55. tradefield: "",
  56. isleave: 1,
  57. unfinish: 1
  58. }
  59. },
  60. showComingYear: true,
  61. filtratelist: [{
  62. label: "是否包含失败、结案项目",
  63. showName: "name", //显示字段
  64. valueKey: "unfinish", //返回Key
  65. selectKey: "value",
  66. index: 1,
  67. default: 1,
  68. list: [{
  69. name: "包含",
  70. value: 0
  71. }, {
  72. name: "不包含",
  73. value: 1
  74. }]
  75. }, {
  76. label: "时间筛选",
  77. showName: "name", //显示字段
  78. valueKey: "dateType", //返回Key
  79. selectKey: "id",
  80. value: "id", //选中值
  81. index: 0,
  82. default: 0,
  83. interrupt: true,
  84. relevance: "dateRange",
  85. list: [{
  86. name: "全部",
  87. id: 0,
  88. queryMonths: -1
  89. }, {
  90. name: "近一年",
  91. id: 1,
  92. queryMonths: 12
  93. }, {
  94. name: "近九个月",
  95. id: 2,
  96. queryMonths: 9
  97. }, {
  98. name: "近六个月",
  99. id: 3,
  100. queryMonths: 6
  101. }, {
  102. name: "近三个月",
  103. id: 4,
  104. queryMonths: 3
  105. }]
  106. }],
  107. firstTwelveMonths: {
  108. dealaccuracyrate: '0%',
  109. totaldealamount: 0,
  110. totaldeviationamount: 0,
  111. totalsignamount_due: 0
  112. },
  113. projectPhases: [],
  114. stagename: ['全部'],
  115. showStagename: [],
  116. projectPhasesShow: false
  117. },
  118. onLoad(options) {
  119. _Http.basic({
  120. "id": 20221223141802,
  121. "content": {
  122. "pageNumber": 1,
  123. "pageSize": 9999,
  124. "where": {
  125. "condition": ""
  126. }
  127. }
  128. }, false).then(res => {
  129. console.log("获取领域", res)
  130. let filtratelist = this.data.filtratelist
  131. if (res.code == '1') {
  132. filtratelist.splice(filtratelist.length - 2, 0, {
  133. label: "领域",
  134. index: null,
  135. showName: "tradefield", //显示字段
  136. valueKey: "tradefield", //返回Key
  137. selectKey: "tradefield", //传参 代表选着字段 不传参返回整个选择对象
  138. value: "", //选中值
  139. list: res.data
  140. })
  141. this.setData({
  142. filtratelist
  143. })
  144. }
  145. })
  146. getApp().globalData.Language.getLanguagePackage(this, '销售漏斗');
  147. _Http.basic({
  148. "id": 20221128143604,
  149. "content": {
  150. "pageNumber": 1,
  151. "pageSize": 99,
  152. "where": {
  153. "condition": "",
  154. "allprojecttype": "",
  155. "projecttype": ""
  156. }
  157. }
  158. }).then(res => {
  159. if (res.code == 1) {
  160. let list = res.data;
  161. list.unshift({
  162. stagename: '全部'
  163. })
  164. this.setData({
  165. projectPhases: [{
  166. label: "项目阶段",
  167. index: [0],
  168. type: "checkbox",
  169. interrupt: true,
  170. showName: "stagename", //显示字段
  171. valueKey: "stagename", //返回Key
  172. selectKey: "stagename", //传参 代表选着字段 不传参返回整个选择对象
  173. value: ['全部'], //选中值
  174. list
  175. }],
  176. showStagename: [getApp().globalData.Language.getMapText('全部')]
  177. })
  178. }
  179. })
  180. },
  181. onReady() {
  182. this.setChartData();
  183. this.selectComponent("#organization").setData({
  184. isleave: 1
  185. })
  186. this.selectComponent("#organization").initDepAndUser();
  187. // this.selectComponent("#Yl_Filtrate1").queryMonths(12)
  188. },
  189. interrupt({
  190. detail
  191. }) {
  192. if (detail.data.label == "时间筛选") this.selectComponent("#Yl_Filtrate1").queryMonths(detail.item.queryMonths)
  193. },
  194. openFiltrate() {
  195. this.setData({
  196. showFiltrate: true
  197. })
  198. },
  199. handleFilter({
  200. detail
  201. }) {
  202. console.log(detail)
  203. if (detail.name == "close") return;
  204. if (detail.name == 'reset') {
  205. this.selectComponent("#organization").setData({
  206. isleave: 1
  207. })
  208. this.selectComponent("#organization").initDepAndUser()
  209. this.setData({
  210. 'content.dataid': wx.getStorageSync('userMsg').userid,
  211. 'content.type': 0,
  212. 'content.where.isleave': 1,
  213. 'content.where.tradefield': "",
  214. 'content.where.unfinish': 1,
  215. })
  216. } else {
  217. let active = this.selectComponent("#organization").data.result,
  218. isleave = this.selectComponent("#organization").data.isleave;
  219. let type = active.userid ? 0 : 1,
  220. dataid = type == 0 ? active.userid : active.departmentid
  221. console.log(isleave)
  222. this.setData({
  223. 'content.dataid': dataid,
  224. 'content.type': type,
  225. 'content.where.tradefield': detail.tradefield,
  226. 'content.where.isleave': isleave || 1,
  227. 'content.where.unfinish': detail.unfinish || 0,
  228. })
  229. }
  230. this.data.content.where.begdate = detail.startdate;
  231. this.data.content.where.enddate = detail.enddate;
  232. if (detail.startdate && detail.enddate) {
  233. this.data.content.dateType = 0;
  234. } else {
  235. this.data.content.dateType = detail.dateType && detail.dateType != 'id' ? dateType : 0
  236. }
  237. this.setChartData();
  238. },
  239. setChartData() {
  240. this.setData({
  241. statistics: [],
  242. comingYear: []
  243. })
  244. _Http.basic({
  245. "id": 20230630151504,
  246. "content": this.data.content
  247. }).then(res => {
  248. console.log("漏斗数据", res)
  249. if (res.code != '1') return wx.showToast({
  250. title: res.msg,
  251. icon: "none"
  252. })
  253. if (res.data.length) res.data.pop();
  254. let full = Math.max(...res.data.map(v => v.wide));
  255. let statistics = res.data.map((v, i) => {
  256. v.action = getApp().globalData.Language.getMapText(v.stagename)
  257. v.zhl = i == 0 ? '' : getApp().globalData.Language.getMapText('转换率') + `:${(v.zhl * 100).toFixed(2)}%`
  258. v.percent = v.wide / full;
  259. v.totalinvestment = conversion(v.totalinvestment).value
  260. v.budgetary = conversion(v.budgetary).value
  261. v.signamount_due = conversion(v.signamount_due).value
  262. if (i == 0) {
  263. v.totaldealamount = CNY(v.totaldealamount, '¥')
  264. v.totalsignamount_due = CNY(v.totalsignamount_due, '¥')
  265. }
  266. return v
  267. })
  268. let cHeight = statistics.length * 74;
  269. if (cHeight < 200) cHeight = 200;
  270. this.setData({
  271. statistics,
  272. full,
  273. cHeight: cHeight + 'rpx',
  274. onRenderChart: res.data.length == 0 ? () => {} : () => {
  275. return this.renderChart();
  276. }
  277. });
  278. })
  279. this.setComingYear()
  280. },
  281. setComingYear() {
  282. this.setData({
  283. showComingYear: false
  284. })
  285. let content = JSON.parse(JSON.stringify(this.data.content))
  286. content.stagename = this.data.stagename[0] == '全部' ? [] : this.data.stagename;
  287. _Http.basic({
  288. "id": 20241028162104,
  289. content
  290. }).then(res => {
  291. console.log("前12个月总数据", res)
  292. this.setData({
  293. showComingYear: true
  294. })
  295. if (res.code != '1') return wx.showToast({
  296. title: res.msg,
  297. icon: "none"
  298. })
  299. const comingYear = res.data.array.map(v => {
  300. return {
  301. name: getApp().globalData.Language.getMapText('预计签约金额'),
  302. value: (v.signamount_due / (wx.getStorageSync('languagecode') == 'ZH' ? 10000 : 1000)).toFixed(0) - 0,
  303. date: v.signdate_due
  304. }
  305. }).concat(res.data.array.map(v => {
  306. return {
  307. name: getApp().globalData.Language.getMapText('预计成交金额'),
  308. value: (v.dealamount_due / (wx.getStorageSync('languagecode') == 'ZH' ? 10000 : 1000)).toFixed(0) - 0,
  309. date: v.signdate_due
  310. }
  311. }))
  312. console.log("comingYear", comingYear)
  313. let data = res.data;
  314. this.setData({
  315. firstTwelveMonths: {
  316. "dealTotalCount": data.dealTotalCount, //成交项目数
  317. "failTotalCount": data.failTotalCount, //失败项目数
  318. "dealRate": (data.dealRate * 100).toFixed(2) + '%', //项目成交率
  319. "positiveCount": data.positiveCount, //预计成交正偏差项目数合计
  320. "positiveOffsetAmount": CNY(((data.positiveOffsetAmount || 0) / (wx.getStorageSync('languagecode') == 'ZH' ? 10000 : 1000)).toFixed(2), ''), //预计成交正偏差金额合计
  321. "negativeCount": data.negativeCount, //预计成交负偏差项目数合计
  322. "negativeOffsetAmount": CNY(((data.negativeOffsetAmount || 0) / (wx.getStorageSync('languagecode') == 'ZH' ? 10000 : 1000)).toFixed(2), ''), //预计成交负偏差金额合计
  323. "offsetCount": data.offsetCount, //预计成交准确项目数
  324. "rightRate": (data.rightRate * 100).toFixed(2) + '%', //预测额成交准确率
  325. "dealAmount": CNY(((data.dealAmount || 0) / (wx.getStorageSync('languagecode') == 'ZH' ? 10000 : 1000)).toFixed(2), ''), //项目成交金额合计
  326. "signAmount": CNY(((data.signAmount || 0) / (wx.getStorageSync('languagecode') == 'ZH' ? 10000 : 1000)).toFixed(2), ''), //预计签约金额合计
  327. },
  328. comingYear,
  329. onRenderBarChart: res.data.length == 0 ? () => {} : () => {
  330. return this.renderBarChart();
  331. }
  332. })
  333. })
  334. },
  335. openProjectPhases() {
  336. this.setData({
  337. projectPhasesShow: true
  338. })
  339. },
  340. phasesInterrupt({
  341. detail
  342. }) {
  343. if (detail.item.stagename == '全部') {
  344. detail.list[0].index = [0];
  345. detail.list[0].value = ['全部'];
  346. } else {
  347. if (detail.list[0].index.length) {
  348. detail.list[0].index = detail.list[0].index.filter(v => v);
  349. detail.list[0].value = detail.list[0].index.filter(v => v != '全部');
  350. } else {
  351. detail.list[0].index = [0];
  352. detail.list[0].value = ['全部'];
  353. }
  354. }
  355. this.setData({
  356. projectPhases: detail.list
  357. })
  358. },
  359. phasesHandleFilter({
  360. detail
  361. }) {
  362. if (detail.name != "confirm") return;
  363. let stagename = ['全部']
  364. try {
  365. if (detail.stagename[0] != 0) {
  366. stagename = detail.stagename.map(v => this.data.projectPhases[0].list[v].stagename)
  367. }
  368. } catch (error) {
  369. }
  370. this.setData({
  371. stagename,
  372. showStagename: stagename.map(v => getApp().globalData.Language.getMapText(v))
  373. })
  374. this.setComingYear()
  375. },
  376. renderChart() {
  377. console.log("renderChart")
  378. return createElement(Chart, {
  379. data: this.data.statistics
  380. });
  381. },
  382. renderBarChart() {
  383. console.log("renderBarChart")
  384. return createElement(barChart, {
  385. data: this.data.comingYear
  386. });
  387. }
  388. })