mm.config.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. /**
  2. * 配置说明请参考文档:
  3. * https://hongqiye.com/doc/mockm/config/option.html
  4. * @type {import('mockm/@types/config').Config}
  5. */
  6. module.exports = async (util) => {
  7. const joi = await util.tool.generate.initPackge(`joi`)
  8. util.libObj.mockjs.Random.extend({
  9. image2: function () {
  10. return this.pick(
  11. `https://dummyimage.com/${this.integer(100, 1000)}x${this.integer(
  12. 100,
  13. 1000
  14. )}/${this.hex()}/${this.hex()}.jpg`.replace(/#/g, ``)
  15. )
  16. },
  17. })
  18. return {
  19. plugin: [util.plugin.validate, util.plugin.apiDoc],
  20. guard: false,
  21. port: 8100,
  22. testPort: 8105,
  23. replayPort: 8101,
  24. watch: [`./apix/`],
  25. proxy: {
  26. '/': `http://192.168.1.70:8088/`, // 后端接口主域
  27. '/anything/intercept': [`origin`, `127.0.0.1`], // 修改接口返回的数据
  28. },
  29. api: {
  30. 'get /apix/currentWeather': util.side({
  31. tags: [`公用`],
  32. summary: `当前天气`,
  33. async action(req, res) {
  34. res.json(
  35. wrapApiData(
  36. util.libObj.mockjs.mock({
  37. data: {
  38. 温度: `@integer(0, 40)`,
  39. 时间: `@now()`,
  40. 天气: `@pick(多云, 少云, 晴, 雨, 雪, 雾, 暴雨)`,
  41. },
  42. })
  43. )
  44. )
  45. },
  46. }),
  47. 'post /apix/login': util.side({
  48. tags: [`公用`],
  49. summary: `登录`,
  50. schema: {
  51. body: joi
  52. .object({
  53. userName: joi
  54. .string()
  55. .default(`admin`)
  56. .required()
  57. .description(`用户名`),
  58. userPwd: joi
  59. .string()
  60. .default(`123456`)
  61. .required()
  62. .description(`密码`),
  63. })
  64. .description(`用户信息`),
  65. },
  66. async action(req, res) {
  67. const { userName, userPwd } = req.body
  68. if (userName == `admin` && userPwd == `123456`) {
  69. res.json(
  70. wrapApiData(
  71. util.libObj.mockjs.mock({
  72. data: {
  73. token: `@uuid`,
  74. },
  75. })
  76. )
  77. )
  78. } else {
  79. res.status(401).json(
  80. wrapApiData(
  81. util.libObj.mockjs.mock({
  82. code: 401,
  83. data: {
  84. message: `用户名或密码错误`,
  85. },
  86. })
  87. )
  88. )
  89. }
  90. },
  91. }),
  92. 'get /apix/mapOfTongren': util.side({
  93. tags: [`公用`],
  94. summary: `铜仁地图数据`,
  95. async action(req, res) {
  96. const data = await util.libObj.axios
  97. .get(
  98. `https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=520600_full`
  99. )
  100. .then((res) => res.data)
  101. res.json(
  102. wrapApiData(
  103. util.libObj.mockjs.mock({
  104. data,
  105. })
  106. )
  107. )
  108. },
  109. }),
  110. 'get /apix/realTimeStatistics': util.side({
  111. tags: [`综合总览`],
  112. summary: `实时统计`,
  113. async action(req, res) {
  114. res.json(
  115. wrapApiData(
  116. util.libObj.mockjs.mock({
  117. data: {
  118. 目标完成率: `@integer(0, 100)`,
  119. 年移栽数量: `@integer(9, 9e4)`,
  120. 年移栽面积: `@integer(9, 9e4)`,
  121. 移栽区域数: `@integer(9, 9e4)`,
  122. 烟农数量: `@integer(9, 9e4)`,
  123. },
  124. })
  125. )
  126. )
  127. },
  128. }),
  129. 'get /apix/analysisOfTransplantYieldInVariousRegions': util.side({
  130. tags: [`综合总览`],
  131. summary: `各区域移栽产量分析`,
  132. async action(req, res) {
  133. res.json(
  134. wrapApiData(
  135. util.libObj.mockjs.mock({
  136. 'data|10': [
  137. {
  138. 名称: `@county`,
  139. 值: `@integer(0, 1000)`,
  140. },
  141. ],
  142. })
  143. )
  144. )
  145. },
  146. }),
  147. 'get /apix/weatherForecast': util.side({
  148. tags: [`综合总览`, `种值分析详情`],
  149. summary: `天气预报, 实时天气`,
  150. async action(req, res) {
  151. res.json(
  152. wrapApiData(
  153. util.libObj.mockjs.mock({
  154. 'data|24': [
  155. {
  156. 'index|+1': 0,
  157. 时间() {
  158. return util.libObj.mockjs.Random.now(
  159. `yyyy-MM-mm ${String(this.index).padStart(
  160. 2,
  161. `0`
  162. )}:00:00`
  163. )
  164. },
  165. 温度: `@integer(0, 40)`,
  166. 天气: `@pick(多云, 少云, 晴, 雨, 雪, 雾, 暴雨)`,
  167. },
  168. ],
  169. })
  170. )
  171. )
  172. },
  173. }),
  174. 'get /apix/transplantAreaInEachRegion': util.side({
  175. tags: [`综合总览`],
  176. summary: `各区域移栽面积`,
  177. async action(req, res) {
  178. res.json(
  179. wrapApiData(
  180. util.libObj.mockjs.mock({
  181. 'data|10': [
  182. {
  183. 名称: `@county`,
  184. 今年: `@integer(0, 80)`,
  185. 去年: `@integer(0, 80)`,
  186. },
  187. ],
  188. })
  189. )
  190. )
  191. },
  192. }),
  193. 'get /apix/analysisOfTransplantingSituation': util.side({
  194. tags: [`综合总览`],
  195. summary: `移栽情况分析`,
  196. async action(req, res) {
  197. res.json(
  198. wrapApiData(
  199. util.libObj.mockjs.mock({
  200. 'data|10': [
  201. {
  202. 名称: `@county`,
  203. 已移载: `@integer(9, 9e4)`,
  204. 未移栽: `@integer(9, 9e4)`,
  205. 比率() {
  206. return (this.已移载 / (this.已移载 + this.未移栽)) * 100
  207. },
  208. },
  209. ],
  210. })
  211. )
  212. )
  213. },
  214. }),
  215. 'get /apix/transplantTrendAnalysis': util.side({
  216. tags: [`综合总览`, `种值分析详情`],
  217. summary: `移栽趋势分析, 月度移栽趋势`,
  218. async action(req, res) {
  219. res.json(
  220. wrapApiData(
  221. util.libObj.mockjs.mock({
  222. 'data|31': [
  223. {
  224. '时间|+1': 1,
  225. 今年: `@integer(0, 2000)`,
  226. 去年: `@integer(0, 2000)`,
  227. 较上日: `@integer(0, 100)`,
  228. 较去年: `@integer(0, 100)`,
  229. },
  230. ],
  231. })
  232. )
  233. )
  234. },
  235. }),
  236. 'get /apix/base': util.side({
  237. tags: [`增删改查`, `种植分析`, `种值分析详情`],
  238. summary: `基地 crud`,
  239. schema: {
  240. query: joi
  241. .object({
  242. _sort: joi.string().default(`比率`).description(`排序字段`),
  243. _order: joi
  244. .string()
  245. .default(`desc`)
  246. .description(`排序方式, asc | desc`),
  247. q: joi.string().description(`模糊搜索`),
  248. })
  249. .unknown(true)
  250. .description(`搜索项`),
  251. },
  252. async action(req, res, next) {
  253. res.redirect(req.originalUrl.replace(`/apix`, ``))
  254. },
  255. }),
  256. 'get /apix/base/:id': util.side({
  257. tags: [`增删改查`, `种植分析`, `种值分析详情`],
  258. summary: `基地详情`,
  259. schema: {
  260. path: joi.object({
  261. id: joi.string(),
  262. }),
  263. },
  264. async action(req, res, next) {
  265. res.redirect(req.originalUrl.replace(`/apix`, ``))
  266. },
  267. }),
  268. 'get /apix/holePunchingMachine': util.side({
  269. tags: [`增删改查`, `种值分析详情`],
  270. summary: `打孔机 crud`,
  271. schema: {
  272. query: joi
  273. .object({
  274. q: joi.string().description(`模糊搜索`),
  275. })
  276. .unknown(true)
  277. .description(`搜索项`),
  278. },
  279. async action(req, res, next) {
  280. res.redirect(req.originalUrl.replace(`/apix`, ``))
  281. },
  282. }),
  283. 'get /apix/transplantAreaInEachRegion2': util.side({
  284. tags: [`种植分析`],
  285. summary: `各区域移栽面积`,
  286. async action(req, res, next) {
  287. res.json(
  288. wrapApiData(
  289. util.libObj.mockjs.mock({
  290. 'data|10': [
  291. {
  292. 名称: `@county`,
  293. 已移栽: `@integer(9, 9e4)`,
  294. 未移栽: `@integer(9, 9e4)`,
  295. 比率() {
  296. return (this.已移栽 / (this.已移栽 + this.未移栽)) * 100
  297. },
  298. },
  299. ],
  300. })
  301. )
  302. )
  303. },
  304. }),
  305. 'get /apix/trendOfTransplantQuantityThisMonth': util.side({
  306. tags: [`种植分析`, `种值分析详情`],
  307. summary: `本月移栽数量趋势`,
  308. async action(req, res, next) {
  309. res.json(
  310. wrapApiData(
  311. util.libObj.mockjs.mock({
  312. 'data|31': [
  313. {
  314. 'index|+1': 1,
  315. 时间() {
  316. return util.libObj.mockjs.Random.now(
  317. `yyyy-MM-${String(this.index).padStart(2, `0`)}`
  318. )
  319. },
  320. 今年: `@integer(0, 2000)`,
  321. 去年: `@integer(0, 2000)`,
  322. 较上日: `@integer(0, 100)`,
  323. 较去年: `@integer(0, 100)`,
  324. },
  325. ],
  326. })
  327. )
  328. )
  329. },
  330. }),
  331. 'get /apix/thisYearsTransplantingDataTrend': util.side({
  332. tags: [`种植分析`, `种值分析详情`],
  333. summary: `本年移栽数据趋势, 年度移栽趋势`,
  334. async action(req, res, next) {
  335. res.json(
  336. wrapApiData(
  337. util.libObj.mockjs.mock({
  338. 'data|12': [
  339. {
  340. 'index|+1': 1,
  341. 时间() {
  342. return util.libObj.mockjs.Random.now(
  343. `yyyy-${String(this.index).padStart(2, `0`)}`
  344. )
  345. },
  346. 今年: `@integer(0, 2000)`,
  347. 去年: `@integer(0, 2000)`,
  348. 较上日: `@integer(0, 100)`,
  349. 较去年: `@integer(0, 100)`,
  350. },
  351. ],
  352. })
  353. )
  354. )
  355. },
  356. }),
  357. 'get /apix/analysisOfAnnualTransplantArea': util.side({
  358. tags: [`种植分析`, `种值分析详情`],
  359. summary: `年度移栽面积分析`,
  360. async action(req, res, next) {
  361. res.redirect(`/apix/thisYearsTransplantingDataTrend`)
  362. },
  363. }),
  364. 'get /apix/monthlyTransplantationAreaAnalysis': util.side({
  365. tags: [`种植分析`, `种值分析详情`],
  366. summary: `月度移栽面积分析`,
  367. async action(req, res, next) {
  368. res.redirect(`/apix/trendOfTransplantQuantityThisMonth`)
  369. },
  370. }),
  371. 'get /apix/transplantData': util.side({
  372. tags: [`种值分析详情`],
  373. summary: `移栽数据`,
  374. async action(req, res) {
  375. res.json(
  376. wrapApiData(
  377. util.libObj.mockjs.mock({
  378. data: {
  379. 处理率: `@integer(0, 100)`,
  380. 今日种植数: `@integer(9, 9e4)`,
  381. 目标移栽数: `@integer(9, 9e4)`,
  382. 累计移栽: `@integer(9, 9e4)`,
  383. },
  384. })
  385. )
  386. )
  387. },
  388. }),
  389. },
  390. static: [],
  391. dbCover: true,
  392. db: util.libObj.mockjs.mock({
  393. 'base|10': [
  394. {
  395. 'id|+1': 1,
  396. 区域编码() {
  397. return getAdcode(this.id)
  398. },
  399. 名称: `@county()@ctitle()基地`,
  400. 温度: [`@integer(0, 20)`, `@integer(20, 40)`],
  401. 天气: `@pick(多云, 少云, 晴, 雨, 雪, 雾, 暴雨)`,
  402. 管理人员: `@cname`,
  403. 联系电话: `@phone`,
  404. 简介: `<p>@cparagraph()</p><p>@cparagraph()</p><p>@cparagraph()</p><p>@cparagraph()</p><p>@cparagraph()</p><p>@cparagraph()</p>`,
  405. 面积: `@integer(9e3, 9e4)`,
  406. 烟农数量: `@integer(10, 999)`,
  407. 已种植: `@integer(9, 9e4)`,
  408. 未种植: `@integer(9, 9e4)`,
  409. 地址: `@county()@ctitle()`,
  410. '图片|3-5': [`@image2()`],
  411. 完成率() {
  412. return (this.已种植 / (this.已种植 + this.未种植)) * 100
  413. },
  414. },
  415. ],
  416. 'holePunchingMachine|10': [
  417. {
  418. 'id|+1': 1,
  419. 名称: `@county()@ctitle()基地打孔机`,
  420. 管理人员: `@cname`,
  421. ip: `@ip`,
  422. 投入时间: `@date`,
  423. 联系电话: `@phone`,
  424. '图片|1-5': [`@image2()`],
  425. 状态: `@pick(运行中, 关机, 故障)`,
  426. },
  427. ],
  428. }),
  429. resHandleReplay: ({ req, res }) => wrapApiData({ code: 200, data: {} }),
  430. resHandleJsonApi: ({ req, res: { statusCode: code }, data }) =>
  431. wrapApiData({ code, data }),
  432. }
  433. }
  434. /**
  435. * 包裹 api 的返回值
  436. * @param {*} param0
  437. * @param {object} param0.data - 原始数据
  438. * @param {number|string} [param0.code=200] - http状态码
  439. * @returns
  440. */
  441. function wrapApiData({ data, code = 200 }) {
  442. code = String(code)
  443. return {
  444. code,
  445. success: Boolean(code.match(/^[2]/)), // 如果状态码以2开头则为 true
  446. data,
  447. }
  448. }
  449. function getAdcode(index) {
  450. const list = [
  451. {
  452. name: `碧江区`,
  453. adcode: 520602,
  454. },
  455. {
  456. name: `万山区`,
  457. adcode: 520603,
  458. },
  459. {
  460. name: `江口县`,
  461. adcode: 520621,
  462. },
  463. {
  464. name: `玉屏侗族自治县`,
  465. adcode: 520622,
  466. },
  467. {
  468. name: `石阡县`,
  469. adcode: 520623,
  470. },
  471. {
  472. name: `思南县`,
  473. adcode: 520624,
  474. },
  475. {
  476. name: `印江土家族苗族自治县`,
  477. adcode: 520625,
  478. },
  479. {
  480. name: `德江县`,
  481. adcode: 520626,
  482. },
  483. {
  484. name: `沿河土家族自治县`,
  485. adcode: 520627,
  486. },
  487. {
  488. name: `松桃苗族自治县`,
  489. adcode: 520628,
  490. },
  491. ]
  492. return list[index % list.length].adcode
  493. }