Compare commits

...

32 Commits

Author SHA1 Message Date
nili 4b4ed2753b fix: 文案 4 months ago
nili 9c96c32eaa feat: 账号可以隐藏 4 months ago
nili 4b3bd4183a 口子收入统计 5 months ago
nili 3936c14914 广告列表加口子筛选 5 months ago
nili e807fae293 加成功状态 5 months ago
nili c47c7a2fd4 广告列表加口子 5 months ago
nili 3f425c7e6a 设备上线 5 months ago
nili 4a570f095f 应用列表、人员管理,筛选 5 months ago
nili b1753932bf h5展示列 5 months ago
nili d8fc93870f 口子收入数据统计 5 months ago
nili 323a4a432e 按设备查,展示表格累计收入 6 months ago
nili 41382e6d63 设备主只能看到激励视频的数据 6 months ago
nili 3d0e402d60 换logo 6 months ago
nili d83dd20a4b 改样式 6 months ago
nili 1a501d7a71 fx 6 months ago
nili 754ef9d79f fx 6 months ago
nili 4e68217a6d 更新下overview数据 6 months ago
nili 3a0e509073 同上 6 months ago
nili 63a8a998cb 凡米游加口子相关功能 6 months ago
nili 17edac139d 图表主题换成浅色 6 months ago
nili 2a4bfbdf7c 换成浅色主题 6 months ago
nili a5116d8b8b fx 6 months ago
nili 346c62510c 数据展示 6 months ago
nili fee12c8f86 加数据展示 6 months ago
nili c430459158 管理员只能添加普通账号 6 months ago
nili acb998f415 fx 6 months ago
nili 74c844f580 加人员管理 6 months ago
nili cb0683c49e 加人员管理 6 months ago
nili 85960dd63d 调整一下登陆页布局 & 取消footer 6 months ago
nili c0f8fbfdbd 凡米游加登陆背景 6 months ago
nili e482f2bbd5 凡米游 6 months ago
nili 7a9c574cad appId筛选 6 months ago
  1. 2
      config/config.ts
  2. 8
      config/defaultSettings.ts
  3. 62
      config/routes.ts
  4. 193
      dist/104.6ba2d1be.async.js
  5. 1
      dist/134.6fc81d91.async.js
  6. 1
      dist/134.957d5baa.async.js
  7. 302
      dist/140.d86f6b29.async.js
  8. 3
      dist/169.57647c7d.async.js
  9. 14
      dist/271.5eec43d2.async.js
  10. 97
      dist/335.78ea2fbf.async.js
  11. 287
      dist/364.782d5fa1.async.js
  12. 1
      dist/397.fb5f72c1.async.js
  13. 108
      dist/491.ddc0d25a.async.js
  14. 83
      dist/51.a2ea1b3b.async.js
  15. 8
      dist/559.016bfdbb.async.js
  16. 8
      dist/559.683b9a7b.async.js
  17. 1
      dist/60.7143e42f.async.js
  18. 27
      dist/635.09454aea.async.js
  19. 57
      dist/750.d34920f3.async.js
  20. 42
      dist/822.ac7ab1f5.async.js
  21. 27
      dist/89.ee83384e.async.js
  22. 1
      dist/905.6e225d1b.async.js
  23. 1
      dist/905.745134cb.async.js
  24. 59
      dist/930.fca7adbf.async.js
  25. 97
      dist/963.fd5abb07.async.js
  26. 1
      dist/_umi_route_preload_helper.f438c131.js
  27. BIN
      dist/icons/icon-128x128.png
  28. BIN
      dist/icons/icon-192x192.png
  29. BIN
      dist/icons/icon-512x512.png
  30. BIN
      dist/icons/icon.jpg
  31. BIN
      dist/icons/icon.png
  32. 16
      dist/index.html
  33. BIN
      dist/logo.png
  34. 10
      dist/p__Admin.4451895f.async.js
  35. 1
      dist/p__AdminManagement.13887fed.async.js
  36. 1
      dist/p__AdvRecordList.0747dba9.async.js
  37. 1
      dist/p__AdvRecordList.6031b104.async.js
  38. 1
      dist/p__AppManagement.26abbc6f.async.js
  39. 10
      dist/p__Bind.bfb7c4f6.async.js
  40. 1
      dist/p__DeviceOverview.80620b07.async.js
  41. 1
      dist/p__DeviceOwnerApp.ede954ff.async.js
  42. 1
      dist/p__Overview.f1f0c4a9.async.js
  43. 1
      dist/p__User__Login__index.0020071b.async.js
  44. 1
      dist/p__User__Login__index.f3ef3531.async.js
  45. 1
      dist/p__Welcome.8c10044c.async.js
  46. BIN
      dist/static/loginBg.12a730ec.jpg
  47. BIN
      dist/static/welcome.793d2d05.jpeg
  48. 2
      dist/t__plugin-layout__Layout.bb80f58e.async.js
  49. 1
      dist/umi.1ca9308c.css
  50. 433
      dist/umi.cecb10de.js
  51. 426
      dist/umi.ee9dc4cd.js
  52. 1
      dist/umi.f9018446.css
  53. 18
      package.json
  54. BIN
      public/icons/icon-128x128.png
  55. BIN
      public/icons/icon-192x192.png
  56. BIN
      public/icons/icon-512x512.png
  57. BIN
      public/icons/icon.jpg
  58. BIN
      public/icons/icon.png
  59. BIN
      public/logo.png
  60. 8
      src/access.ts
  61. 17
      src/app.tsx
  62. BIN
      src/assets/loginBg.jpg
  63. BIN
      src/assets/welcome.jpeg
  64. 3
      src/global.less
  65. 10
      src/manifest.json
  66. 68
      src/pages/Admin/AdminHideForm.tsx
  67. 375
      src/pages/AdminManagement.tsx
  68. 346
      src/pages/AdvRecordList.tsx
  69. 162
      src/pages/AppManagement.tsx
  70. 19
      src/pages/Bind.tsx
  71. 173
      src/pages/DeviceOverview.tsx
  72. 296
      src/pages/DeviceOwnerApp.tsx
  73. 181
      src/pages/Overview.tsx
  74. 37
      src/pages/User/Login/index.tsx
  75. 164
      src/pages/Welcome.tsx
  76. 178
      src/services/matrix/admin.ts
  77. 18
      src/services/matrix/appController.ts
  78. 90
      src/services/matrix/device.ts
  79. 14
      src/services/matrix/index.ts
  80. 114
      src/services/matrix/loginController.ts
  81. 170
      src/services/matrix/matrixAppConfigController.ts
  82. 18
      src/services/matrix/matrixController.ts
  83. 27
      src/services/matrix/matrixMoneyController.ts
  84. 15
      src/services/matrix/matrixUserController.ts
  85. 420
      src/services/matrix/typings.d.ts

2
config/config.ts

@ -15,6 +15,8 @@ export default defineConfig({
*/
hash: true,
favicons : ['logo.png'],
/**
* @name
* @description ie11 使

8
config/defaultSettings.ts

@ -9,15 +9,15 @@ const Settings: ProLayoutProps & {
} = {
navTheme: 'light',
// 拂晓蓝
colorPrimary: '#1890ff',
layout: 'mix',
colorPrimary: '#eb0fcc',
layout: 'top',
contentWidth: 'Fluid',
fixedHeader: false,
fixSiderbar: true,
colorWeak: false,
title: 'Matrix',
title: 'Magic',
pwa: true,
logo: 'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg',
logo: '/logo.png',
iconfontUrl: '',
token: {
// 参见ts声明,demo 见文档,通过token 修改样式

62
config/routes.ts

@ -1,4 +1,5 @@
/**
import { layout } from '../src/app';
/**
* @name umi
* @description path,component,routes,redirect,wrappers,name,icon
* @param path path 第一种是动态参数 :id *
@ -21,33 +22,62 @@ export default [
component: './User/Login',
},
],
},
{
path: '/welcome',
name: '欢迎',
icon: 'smile',
component: './Welcome',
},
{
path: '/overview',
name: '数据概览',
icon: 'dashboard',
access: 'canAdmin',
component: './Overview',
},
{
path: '/advList',
name: '广告列表',
icon: 'smile',
access: 'canAdmin',
component: './AdvRecordList',
},
{
path: '/admin',
name: 'admin',
icon: 'crown',
path: '/appList',
name: '应用列表',
icon: 'smile',
access: 'canDeviceOwner',
component: './DeviceOwnerApp',
},
{
path: '/incomeOverview',
name: '数据概览',
icon: 'smile',
access: 'canDeviceOwner',
component: './DeviceOverview',
},
{
path: '/adminList',
name: '人员管理',
access: 'canAdmin',
routes: [
{
path: '/admin',
redirect: '/admin/sub-page',
},
{
path: '/admin/sub-page',
name: 'sub-page',
component: './Admin',
},
],
component: './AdminManagement'
},
{
path: '/bind',
name: '绑定设备',
access: 'canDeviceOwner',
component: './Bind'
},
{
path: '/appManage',
name: '应用管理',
access: 'canAdmin',
component: './AppManagement'
},
{
path: '/',
redirect: '/advList',
redirect: '/welcome',
},
{
path: '*',

193
dist/104.6ba2d1be.async.js

File diff suppressed because one or more lines are too long

1
dist/134.6fc81d91.async.js

File diff suppressed because one or more lines are too long

1
dist/134.957d5baa.async.js

File diff suppressed because one or more lines are too long

302
dist/140.d86f6b29.async.js

File diff suppressed because one or more lines are too long

3
dist/169.57647c7d.async.js

File diff suppressed because one or more lines are too long

14
dist/271.5eec43d2.async.js

File diff suppressed because one or more lines are too long

97
dist/335.78ea2fbf.async.js

File diff suppressed because one or more lines are too long

287
dist/364.782d5fa1.async.js

File diff suppressed because one or more lines are too long

1
dist/397.fb5f72c1.async.js

File diff suppressed because one or more lines are too long

108
dist/491.ddc0d25a.async.js

File diff suppressed because one or more lines are too long

83
dist/51.a2ea1b3b.async.js

File diff suppressed because one or more lines are too long

8
dist/559.016bfdbb.async.js

File diff suppressed because one or more lines are too long

8
dist/559.683b9a7b.async.js

File diff suppressed because one or more lines are too long

1
dist/60.7143e42f.async.js

File diff suppressed because one or more lines are too long

27
dist/635.09454aea.async.js

File diff suppressed because one or more lines are too long

57
dist/750.d34920f3.async.js

File diff suppressed because one or more lines are too long

42
dist/822.ac7ab1f5.async.js

File diff suppressed because one or more lines are too long

27
dist/89.ee83384e.async.js

File diff suppressed because one or more lines are too long

1
dist/905.6e225d1b.async.js

File diff suppressed because one or more lines are too long

1
dist/905.745134cb.async.js

File diff suppressed because one or more lines are too long

59
dist/930.fca7adbf.async.js

File diff suppressed because one or more lines are too long

97
dist/963.fd5abb07.async.js

File diff suppressed because one or more lines are too long

1
dist/_umi_route_preload_helper.f438c131.js

@ -0,0 +1 @@
!function(){"use strict";var t="/".replace(/([^/])$/,"$1/"),e=location.pathname,n=e.startsWith(t)&&decodeURI("/".concat(e.slice(t.length)));if(n){var a=document,c=a.head,r=a.createElement.bind(a),i=function(t,e,n){var a,c=e.r[t]||(null===(a=Object.entries(e.r).find((function(e){var n=e[0];return new RegExp("^".concat(n.replace(/\/:[^/]+/g,"/[^/]+").replace("/*","/.+"),"$")).test(t)})))||void 0===a?void 0:a[1]);return null==c?void 0:c.map((function(t){var a=e.f[t][1],c=e.f[t][0];return{type:c.split(".").pop(),url:"".concat(n.publicPath).concat(c),attrs:[["data-".concat(e.b),"".concat(e.p,":").concat(a)]]}}))}(n,{"p":"ant-design-pro","b":"webpack","f":[["p__AppManagement.26abbc6f.async.js",39],["51.a2ea1b3b.async.js",51],["60.7143e42f.async.js",60],["89.ee83384e.async.js",89],["134.6fc81d91.async.js",134],["169.57647c7d.async.js",169],["p__Welcome.8c10044c.async.js",185],["t__plugin-layout__Layout.6cae69f5.chunk.css",301],["t__plugin-layout__Layout.bb80f58e.async.js",301],["335.78ea2fbf.async.js",335],["364.782d5fa1.async.js",364],["p__User__Login__index.0020071b.async.js",366],["p__DeviceOwnerApp.ede954ff.async.js",371],["390.41467286.async.js",390],["397.fb5f72c1.async.js",397],["491.ddc0d25a.async.js",491],["p__Bind.bfb7c4f6.async.js",557],["559.016bfdbb.async.js",559],["p__404.0c100574.async.js",571],["p__DeviceOverview.80620b07.async.js",581],["p__Overview.f1f0c4a9.async.js",628],["750.d34920f3.async.js",750],["p__AdminManagement.13887fed.async.js",816],["822.ac7ab1f5.async.js",822],["p__AdvRecordList.6031b104.async.js",857],["905.6e225d1b.async.js",905],["930.fca7adbf.async.js",930]],"r":{"/*":[18,25],"/":[3,4,7,8,17,25],"/welcome":[2,6,3,4,7,8,17,25],"/overview":[2,4,5,10,15,17,20,21,23,26,3,7,8,25],"/advList":[1,2,4,5,9,10,21,23,24,25,26,3,7,8,17],"/appList":[1,2,4,5,9,10,12,21,23,25,26,3,7,8,17],"/incomeOverview":[2,4,5,10,15,17,19,21,23,26,3,7,8,25],"/adminList":[1,5,22,23,3,4,7,8,17,25],"/bind":[4,5,14,16,17,26,3,7,8,25],"/appManage":[0,1,2,4,5,9,10,14,21,23,25,26,3,7,8,17],"/user/login":[2,4,5,10,11,23]}},{publicPath:"/"});null==i||i.forEach((function(t){var e,n=t.type,a=t.url;if("js"===n)(e=r("script")).src=a,e.async=!0;else{if("css"!==n)return;(e=r("link")).href=a,e.rel="preload",e.as="style"}t.attrs.forEach((function(t){e.setAttribute(t[0],t[1]||"")})),c.appendChild(e)}))}}();

BIN
dist/icons/icon-128x128.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

BIN
dist/icons/icon-192x192.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

BIN
dist/icons/icon-512x512.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

BIN
dist/icons/icon.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

BIN
dist/icons/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

16
dist/index.html

@ -1,13 +1,17 @@
<!DOCTYPE html><html><head>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="shortcut icon" href="logo.png">
<title>Ant Design Pro</title>
<link rel="stylesheet" href="/umi.1ca9308c.css">
<script async="" src="/scripts/loading.js"></script>
<link rel="stylesheet" href="/umi.f9018446.css">
<script async src="/scripts/loading.js"></script>
<script src="/_umi_route_preload_helper.f438c131.js"></script>
</head>
<body>
<div id="root"></div>
<script src="/umi.cecb10de.js"></script>
</body></html>
<script src="/umi.ee9dc4cd.js"></script>
</body>
</html>

BIN
dist/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

10
dist/p__Admin.4451895f.async.js

File diff suppressed because one or more lines are too long

1
dist/p__AdminManagement.13887fed.async.js

File diff suppressed because one or more lines are too long

1
dist/p__AdvRecordList.0747dba9.async.js

@ -1 +0,0 @@
"use strict";(self.webpackChunkant_design_pro=self.webpackChunkant_design_pro||[]).push([[857],{46701:function(D,s,e){e.r(s);var l=e(15009),d=e.n(l),o=e(99289),m=e.n(o),c=e(48357),v=e(90930),p=e(76104),x=e(35312),E=e(67294),u=e(85893),I=function(){var h=(0,E.useRef)(),T=(0,x.useIntl)(),f=[{title:"\u8BBE\u5907Id",dataIndex:"deviceId",valueType:"textarea",ellipsis:!0,copyable:!0},{title:"\u5E94\u7528\u540D\u79F0",hideInSearch:!0,dataIndex:"appName",valueType:"textarea"},{title:"\u5E73\u53F0",dataIndex:"platform",valueEnum:{1:{text:"\u7A7F\u5C71\u7532"},2:{text:"\u817E\u8BAF"},3:{text:"\u767E\u5EA6\u8054\u76DF"},4:{text:"Mintegral"},5:{text:"\u5FEB\u624B"},6:{text:"\u6E38\u53EF\u8D62"},7:{text:"Sigmob"},8:{text:"Admob"}}},{title:"\u5E7F\u544A\u7C7B\u578B",dataIndex:"advType",valueEnum:{1:{text:"\u6A2A\u5E45",status:"Default"},2:{text:"\u63D2\u9875",status:"Processing"},3:{text:"\u6FC0\u52B1\u89C6\u9891",status:"Success"}}},{title:"ecpm(\u5143)",dataIndex:"ecpm",hideInSearch:!0,renderText:function(a){return a/100}},{title:"\u8BBE\u5907\u54C1\u724C",dataIndex:"deviceBrand",hideInSearch:!0,valueType:"textarea"},{title:"\u8BBE\u5907\u540D",dataIndex:"deviceName",hideInSearch:!0,valueType:"textarea"},{title:"ip",dataIndex:"ip",hideInSearch:!0,valueType:"textarea"},{title:"\u65F6\u95F4",hideInSearch:!0,dataIndex:"createdAt",valueType:"dateTime"},{title:"\u65F6\u95F4",hideInTable:!0,dataIndex:"createdAt",valueType:"dateRange"}];return(0,u.jsx)(v._z,{children:(0,u.jsx)(p.Z,{headerTitle:T.formatMessage({id:"pages.searchTable.title",defaultMessage:"Enquiry form"}),actionRef:h,rowKey:"key",search:{labelWidth:120},request:function(){var i=m()(d()().mark(function a(M){var _,r,n;return d()().wrap(function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,(0,c._5)(M);case 2:return n=t.sent,t.abrupt("return",{data:(_=n.data)===null||_===void 0?void 0:_.data,total:(r=n.data)===null||r===void 0?void 0:r.total,success:!0});case 4:case"end":return t.stop()}},a)}));return function(a){return i.apply(this,arguments)}}(),columns:f})})};s.default=I}}]);

1
dist/p__AdvRecordList.6031b104.async.js

File diff suppressed because one or more lines are too long

1
dist/p__AppManagement.26abbc6f.async.js

@ -0,0 +1 @@
"use strict";(self.webpackChunkant_design_pro=self.webpackChunkant_design_pro||[]).push([[39],{40110:function(y,c,e){var E=e(1413),s=e(67294),P=e(509),m=e(91146),h=function(D,O){return s.createElement(m.Z,(0,E.Z)((0,E.Z)({},D),{},{ref:O,icon:P.Z}))},u=s.forwardRef(h);c.Z=u},84702:function(y,c,e){e.r(c);var E=e(15009),s=e.n(E),P=e(99289),m=e.n(P),h=e(5574),u=e.n(h),A=e(90930),D=e(25335),O=e(35312),i=e(8232),o=e(55102),Z=e(42075),M=e(14726),L=e(71230),I=e(10397),W=e(55241),g=e(17788),p=e(67294),x=e(48357),F=e(40110),n=e(85893),S=function(){var b=(0,p.useState)(!1),U=u()(b,2),V=U[0],v=U[1],$=i.Z.useForm(),z=u()($,1),f=z[0],G=(0,p.useState)([]),T=u()(G,2),N=T[0],J=T[1],X=(0,O.useModel)("@@initialState"),j=X.initialState,d=j==null?void 0:j.currentUser,H=d&&d.role&&d.role<2,Q=function(r){f.setFieldsValue(r),v(!0)},B=[{title:"\u6E38\u620F",dataIndex:"name",filterDropdown:function(r){var a=r.setSelectedKeys,l=r.selectedKeys,t=r.confirm,ne=r.clearFilters;return(0,n.jsxs)("div",{style:{padding:8},children:[(0,n.jsx)(o.Z,{placeholder:"\u641C\u7D22\u8D26\u53F7",value:l[0],onChange:function(R){return a(R.target.value?[R.target.value]:[])},onPressEnter:function(){return t()},style:{marginBottom:8,display:"block"}}),(0,n.jsxs)(Z.Z,{children:[(0,n.jsx)(M.ZP,{onClick:function(){return t()},type:"primary",children:"\u641C\u7D22"}),(0,n.jsx)(M.ZP,{onClick:function(){return ne()},type:"link",children:"\u6E05\u9664"})]})]})},onFilter:function(r,a){var l;return a==null||(l=a.name)===null||l===void 0?void 0:l.includes(r)},filterIcon:function(r){return(0,n.jsx)(F.Z,{style:{color:r?"#1890ff":void 0},onPointerEnterCapture:void 0,onPointerLeaveCapture:void 0})}},{title:"\u4E0B\u8F7D\u5730\u5740",dataIndex:"url",renderText:function(r){return r&&(0,n.jsxs)(L.Z,{align:"middle",children:[(0,n.jsx)(I.Z,{size:80,value:r||"",bordered:!1}),(0,n.jsx)(W.Z,{overlayInnerStyle:{padding:0},content:(0,n.jsx)(I.Z,{size:300,value:r||"",bordered:!1}),children:(0,n.jsx)("a",{children:"\u67E5\u770B\u5927\u56FE"})})]})}}],Y=[].concat(B,[{title:"secret",dataIndex:"secret",ellipsis:!0,copyable:!0},{title:"\u64CD\u4F5C",width:80,renderText:function(r){return(0,n.jsx)("a",{onClick:function(){return Q(r)},children:"\u7F16\u8F91"},"edit")}}]),k=function(){f.submit()},w=function(){v(!1)},K=function(){var _=m()(s()().mark(function r(){var a;return s()().wrap(function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,(0,x.ln)();case 2:a=t.sent,a.data&&J(a.data);case 4:case"end":return t.stop()}},r)}));return function(){return _.apply(this,arguments)}}();(0,p.useEffect)(function(){K()},[]);var q=function(){f.resetFields(),v(!0)},ee=function(){var _=m()(s()().mark(function r(a){return s()().wrap(function(t){for(;;)switch(t.prev=t.next){case 0:return t.prev=0,t.next=3,(0,x.XJ)(a);case 3:t.next=8;break;case 5:return t.prev=5,t.t0=t.catch(0),t.abrupt("return");case 8:v(!1),K();case 10:case"end":return t.stop()}},r,null,[[0,5]])}));return function(a){return _.apply(this,arguments)}}();return(0,n.jsxs)(A._z,{children:[d&&d.role&&d.role<2&&(0,n.jsx)(M.ZP,{style:{marginBottom:"20px"},onClick:q,children:"\u65B0\u5EFA\u5E94\u7528"}),(0,n.jsx)(D.Z,{search:!1,columns:H?Y:B,dataSource:N}),(0,n.jsx)(g.Z,{title:"\u7F16\u8F91",visible:V,onOk:k,onCancel:w,children:(0,n.jsxs)(i.Z,{form:f,onFinish:ee,children:[(0,n.jsx)(i.Z.Item,{name:"id",style:{display:"none"},children:(0,n.jsx)(o.Z,{type:"hidden"})}),(0,n.jsx)(i.Z.Item,{name:"code",style:{display:"none"},children:(0,n.jsx)(o.Z,{type:"hidden"})}),(0,n.jsx)(i.Z.Item,{label:"\u5E94\u7528\u540D",name:"name",children:(0,n.jsx)(o.Z,{})}),(0,n.jsx)(i.Z.Item,{label:"\u4E0B\u8F7D\u5730\u5740",name:"url",children:(0,n.jsx)(o.Z,{})})]})})]})};c.default=S}}]);

10
dist/p__Bind.bfb7c4f6.async.js

File diff suppressed because one or more lines are too long

1
dist/p__DeviceOverview.80620b07.async.js

File diff suppressed because one or more lines are too long

1
dist/p__DeviceOwnerApp.ede954ff.async.js

File diff suppressed because one or more lines are too long

1
dist/p__Overview.f1f0c4a9.async.js

@ -0,0 +1 @@
"use strict";(self.webpackChunkant_design_pro=self.webpackChunkant_design_pro||[]).push([[628],{58451:function(_e,p,_){_.r(p);var U=_(97857),A=_.n(U),C=_(15009),r=_.n(C),T=_(99289),E=_.n(T),R=_(5574),u=_.n(R),f=_(48357),I=_(92713),x=_(90930),m=_(39615),B=_(57470),v=_(64317),W=_(34540),g=_(27484),K=_.n(g),L=_(9220),i=_(67294),y=_(96974),a=_(85893),S=function(){var F=(0,i.useState)(),D=u()(F,2),o=D[0],Z=D[1],V=(0,i.useState)([]),P=u()(V,2),O=P[0],z=P[1],G=(0,i.useState)([]),h=u()(G,2),$=h[0],H=h[1],J=(0,i.useState)(!1),M=u()(J,2),N=M[0],Q=M[1],X=(0,y.UO)(),j=X.code,Y=function(){var t=E()(r()().mark(function e(){var n;return r()().wrap(function(s){for(;;)switch(s.prev=s.next){case 0:return s.next=2,(0,f.d1)({appCode:j});case 2:n=s.sent,n.data&&Z(n.data);case 4:case"end":return s.stop()}},e)}));return function(){return t.apply(this,arguments)}}(),w=function(){var t=E()(r()().mark(function e(){var n;return r()().wrap(function(s){for(;;)switch(s.prev=s.next){case 0:return s.next=2,(0,f.ln)();case 2:n=s.sent,n.data&&H(n.data);case 4:case"end":return s.stop()}},e)}));return function(){return t.apply(this,arguments)}}(),b=function(){var t=E()(r()().mark(function e(n){var l;return r()().wrap(function(d){for(;;)switch(d.prev=d.next){case 0:return d.next=2,(0,f.Zb)(n);case 2:l=d.sent,l.data&&z(l.data);case 4:case"end":return d.stop()}},e)}));return function(n){return t.apply(this,arguments)}}();(0,i.useEffect)(function(){Y(),w(),b({code:j})},[]);var c=function(e){return e?parseFloat((e/1e5).toFixed(2)):0},k=function(e){var n=e+"";return n.slice(4,6)+"/"+n.slice(6,8)},q=O.map(function(t){return{date:k(t.date),income:c(t.income)}}),ee={data:q,xField:"date",yField:"income",tooltip:{name:"\u6536\u5165",field:"income"},axis:{date:{title:"\u65E5\u671F"},income:{title:"\u6536\u5165\uFF08\u5143\uFF09"}},title:"\u533A\u95F4\u7D2F\u8BA1"+c(O.reduce(function(t,e){return t+(e.income?e.income:0)},0))+"\u5143",height:400,label:{text:function(e){return e.income>0?e.income:""},textBaseline:"bottom",visible:!0,type:"point"},line:{style:{stroke:"#eb0fcc",strokeWidth:2},shapeField:"smooth"},shapeField:"smooth",style:{fill:"linear-gradient(-90deg, white 0%, #eb0fcc 100%)"}};return(0,a.jsxs)(x._z,{children:[(0,a.jsx)(L.Z,{onResize:function(e){Q(e.width<596)},children:(0,a.jsx)(m.Z,{children:(0,a.jsxs)(m.Z.Group,{direction:N?"column":"row",children:[(0,a.jsx)(m.Z,{statistic:{title:"\u7D2F\u8BA1\u6536\u5165\uFF08\u5143\uFF09",value:c(o==null?void 0:o.totalIncome)}}),(0,a.jsx)(m.Z,{statistic:{title:"\u6628\u65E5\u6536\u5165\uFF08\u5143\uFF09",value:c(o==null?void 0:o.yesterdayIncome)}})]})})},"resize-observer"),(0,a.jsxs)("div",{style:{marginTop:"20px",padding:"40px",backgroundColor:"white"},children:[(0,a.jsxs)(B.t,{defaultCollapsed:!0,split:!0,onFinish:b,children:[(0,a.jsx)(v.Z,{name:"code",label:"\u5E94\u7528",options:$.map(function(t){return{label:t.name,value:t.code}})}),(0,a.jsx)(v.Z,{label:"\u5E73\u53F0",name:"platform",valueEnum:{1:"\u7A7F\u5C71\u7532",2:"\u817E\u8BAF",5:"\u5FEB\u624B",7:"Sigmob"}}),(0,a.jsx)(v.Z,{name:"advType",label:"\u5E7F\u544A\u7C7B\u578B",valueEnum:{1:"\u6A2A\u5E45",2:"\u63D2\u9875",3:"\u6FC0\u52B1\u89C6\u9891"}}),(0,a.jsx)(W.Z,{fieldProps:{disabledDate:function(e){return e&&e>=K()().startOf("day")}},name:"date",label:"\u65F6\u95F4"})]}),(0,a.jsx)(I.Z,A()({},ee))]})]})};p.default=S}}]);

1
dist/p__User__Login__index.0020071b.async.js

File diff suppressed because one or more lines are too long

1
dist/p__User__Login__index.f3ef3531.async.js

File diff suppressed because one or more lines are too long

1
dist/p__Welcome.8c10044c.async.js

File diff suppressed because one or more lines are too long

BIN
dist/static/loginBg.12a730ec.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 KiB

BIN
dist/static/welcome.793d2d05.jpeg

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

2
dist/t__plugin-layout__Layout.afe80231.async.js → dist/t__plugin-layout__Layout.bb80f58e.async.js

File diff suppressed because one or more lines are too long

1
dist/umi.1ca9308c.css

@ -1 +0,0 @@
html,body,#root{height:100%;margin:0;padding:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"}.colorWeak{filter:invert(80%)}.ant-layout{min-height:100vh}.ant-pro-sider.ant-layout-sider.ant-pro-sider-fixed{left:unset}canvas{display:block}body{text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}ul,ol{list-style:none}@media (max-width: 768px){.ant-table{width:100%;overflow-x:auto}.ant-table-thead>tr>th,.ant-table-tbody>tr>th,.ant-table-thead>tr>td,.ant-table-tbody>tr>td{white-space:pre}.ant-table-thead>tr>th>span,.ant-table-tbody>tr>th>span,.ant-table-thead>tr>td>span,.ant-table-tbody>tr>td>span{display:block}}html,body{width:100%;height:100%}input::-ms-clear,input::-ms-reveal{display:none}*,*:before,*:after{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{margin:0}[tabindex="-1"]:focus{outline:none}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5em;font-weight:500}p{margin-top:0;margin-bottom:1em}abbr[title],abbr[data-original-title]{text-decoration:underline;text-decoration:underline dotted;border-bottom:0;cursor:help}address{margin-bottom:1em;font-style:normal;line-height:inherit}input[type=text],input[type=password],input[type=number],textarea{-webkit-appearance:none}ol,ul,dl{margin-top:0;margin-bottom:1em}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:500}dd{margin-bottom:.5em;margin-left:0}blockquote{margin:0 0 1em}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}pre,code,kbd,samp{font-size:1em;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace}pre{margin-top:0;margin-bottom:1em;overflow:auto}figure{margin:0 0 1em}img{vertical-align:middle;border-style:none}a,area,button,[role=button],input:not([type="range"]),label,select,summary,textarea{touch-action:manipulation}table{border-collapse:collapse}caption{padding-top:.75em;padding-bottom:.3em;text-align:left;caption-side:bottom}input,button,select,optgroup,textarea{margin:0;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}button,html [type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{padding:0;border-style:none}input[type=radio],input[type=checkbox]{box-sizing:border-box;padding:0}input[type=date],input[type=time],input[type=datetime-local],input[type=month]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;margin:0;padding:0;border:0}legend{display:block;width:100%;max-width:100%;margin-bottom:.5em;padding:0;color:inherit;font-size:1.5em;line-height:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item}template{display:none}[hidden]{display:none!important}mark{padding:.2em;background-color:#feffe6}

433
dist/umi.cecb10de.js

File diff suppressed because one or more lines are too long

426
dist/umi.ee9dc4cd.js

File diff suppressed because one or more lines are too long

1
dist/umi.f9018446.css

@ -0,0 +1 @@
html,body,#root{height:100%;margin:0;padding:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"}.colorWeak{filter:invert(80%)}.ant-layout{min-height:100vh}.ant-pro-sider.ant-layout-sider.ant-pro-sider-fixed{left:unset}.ant-menu-item-selected{background:#f0f8ff!important}canvas{display:block}body{text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}ul,ol{list-style:none}@media (max-width: 768px){.ant-table{width:100%;overflow-x:auto}.ant-table-thead>tr>th,.ant-table-tbody>tr>th,.ant-table-thead>tr>td,.ant-table-tbody>tr>td{white-space:pre}.ant-table-thead>tr>th>span,.ant-table-tbody>tr>th>span,.ant-table-thead>tr>td>span,.ant-table-tbody>tr>td>span{display:block}}html,body{width:100%;height:100%}input::-ms-clear,input::-ms-reveal{display:none}*,*:before,*:after{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{margin:0}[tabindex="-1"]:focus{outline:none}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5em;font-weight:500}p{margin-top:0;margin-bottom:1em}abbr[title],abbr[data-original-title]{text-decoration:underline;text-decoration:underline dotted;border-bottom:0;cursor:help}address{margin-bottom:1em;font-style:normal;line-height:inherit}input[type=text],input[type=password],input[type=number],textarea{-webkit-appearance:none}ol,ul,dl{margin-top:0;margin-bottom:1em}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:500}dd{margin-bottom:.5em;margin-left:0}blockquote{margin:0 0 1em}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}pre,code,kbd,samp{font-size:1em;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace}pre{margin-top:0;margin-bottom:1em;overflow:auto}figure{margin:0 0 1em}img{vertical-align:middle;border-style:none}a,area,button,[role=button],input:not([type="range"]),label,select,summary,textarea{touch-action:manipulation}table{border-collapse:collapse}caption{padding-top:.75em;padding-bottom:.3em;text-align:left;caption-side:bottom}input,button,select,optgroup,textarea{margin:0;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}button,html [type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{padding:0;border-style:none}input[type=radio],input[type=checkbox]{box-sizing:border-box;padding:0}input[type=date],input[type=time],input[type=datetime-local],input[type=month]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;margin:0;padding:0;border:0}legend{display:block;width:100%;max-width:100%;margin-bottom:.5em;padding:0;color:inherit;font-size:1.5em;line-height:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item}template{display:none}[hidden]{display:none!important}mark{padding:.2em;background-color:#feffe6}

18
package.json

@ -4,7 +4,7 @@
"private": true,
"description": "An out-of-box UI solution for enterprise applications",
"scripts": {
"openapi": "umi openapi",
"openapi": "max openapi",
"analyze": "cross-env ANALYZE=1 max build",
"build": "max build",
"deploy": "npm run build && npm run gh-pages",
@ -19,7 +19,6 @@
"lint:fix": "eslint --fix --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./src ",
"lint:js": "eslint --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./src",
"lint:prettier": "prettier -c --write \"**/**.{js,jsx,tsx,ts,less,md,json}\" --end-of-line auto",
"openapi": "max openapi",
"prepare": "husky install",
"prettier": "prettier -c --write \"**/**.{js,jsx,tsx,ts,less,md,json}\"",
"preview": "npm run build && max preview --port 8000",
@ -37,10 +36,17 @@
},
"lint-staged": {
"**/*.{js,jsx,ts,tsx}": "npm run lint-staged:js",
"**/*.{js,jsx,tsx,ts,less,md,json}": ["prettier --write"]
"**/*.{js,jsx,tsx,ts,less,md,json}": [
"prettier --write"
]
},
"browserslist": ["> 1%", "last 2 versions", "not ie <= 10"],
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 10"
],
"dependencies": {
"@ant-design/charts": "^2.0.3",
"@ant-design/icons": "^4.8.1",
"@ant-design/pro-components": "^2.6.48",
"@umijs/route-utils": "^2.2.2",
@ -88,5 +94,7 @@
"umi-presets-pro": "^2.0.3",
"umi-serve": "^1.9.11"
},
"engines": { "node": ">=12.0.0" }
"engines": {
"node": ">=12.0.0"
}
}

BIN
public/icons/icon-128x128.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

BIN
public/icons/icon-192x192.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

BIN
public/icons/icon-512x512.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

BIN
public/icons/icon.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

BIN
public/icons/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
public/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

8
src/access.ts

@ -1,9 +1,11 @@
/**
* @see https://umijs.org/docs/max/access#access
* */
export default function access(initialState: { currentUser?: API.CurrentUser } | undefined) {
export default function access(initialState: { currentUser?: API.MatrixAdmin } | undefined) {
const { currentUser } = initialState ?? {};
return {
canAdmin: currentUser && currentUser.access === 'admin',
let data = {
canAdmin: currentUser && currentUser.role && currentUser.role <= 3,
canDeviceOwner: currentUser && currentUser.role && currentUser.role > 3,
};
return data;
}

17
src/app.tsx

@ -1,9 +1,8 @@
import { AvatarDropdown, AvatarName, Footer, Question, SelectLang } from '@/components';
import { AvatarDropdown, AvatarName } from '@/components';
import { current } from '@/services/matrix/admin';
import { LinkOutlined } from '@ant-design/icons';
import { SettingDrawer } from '@ant-design/pro-components';
import { history, Link } from '@umijs/max';
import React from 'react';
import { Link, history } from '@umijs/max';
import defaultSettings from '../config/defaultSettings';
import { errorConfig } from './requestErrorConfig';
@ -52,7 +51,7 @@ export async function getInitialState(): Promise<{
// ProLayout 支持的api https://procomponents.ant.design/components/layout
export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) => {
return {
actionsRender: () => [<Question key="doc" />, <SelectLang key="SelectLang" />],
// actionsRender: () => [<Question key="doc" />, <SelectLang key="SelectLang" />],
avatarProps: {
// src: initialState?.currentUser?.avatar,
title: <AvatarName />,
@ -60,10 +59,10 @@ export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) =
return <AvatarDropdown>{avatarChildren}</AvatarDropdown>;
},
},
waterMarkProps: {
content: initialState?.currentUser?.name,
},
footerRender: () => <Footer />,
// waterMarkProps: {
// content: initialState?.currentUser?.name,
// },
// footerRender: () => <Footer />,
onPageChange: () => {
const { location } = history;
// 如果没有登录,重定向到 login
@ -94,7 +93,7 @@ export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) =
links: isDev
? [
<Link key="openapi" to="/umi/plugin/openapi" target="_blank">
<LinkOutlined />
<LinkOutlined onPointerEnterCapture={undefined} onPointerLeaveCapture={undefined} />
<span>OpenAPI </span>
</Link>,
]

BIN
src/assets/loginBg.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 KiB

BIN
src/assets/welcome.jpeg

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

3
src/global.less

@ -20,6 +20,9 @@ body,
left: unset;
}
.ant-menu-item-selected{
background: #f0f8ff !important
}
canvas {
display: block;
}

10
src/manifest.json

@ -1,21 +1,21 @@
{
"name": "Ant Design Pro",
"short_name": "Ant Design Pro",
"name": "Magic",
"short_name": "Magic",
"display": "standalone",
"start_url": "./?utm_source=homescreen",
"theme_color": "#002140",
"background_color": "#001529",
"icons": [
{
"src": "icons/icon-192x192.png",
"src": "icons/icon.png",
"sizes": "192x192"
},
{
"src": "icons/icon-128x128.png",
"src": "icons/icon.png",
"sizes": "128x128"
},
{
"src": "icons/icon-512x512.png",
"src": "icons/icon.png",
"sizes": "512x512"
}
]

68
src/pages/Admin/AdminHideForm.tsx

@ -0,0 +1,68 @@
import { Modal, Switch, Table } from 'antd';
import { ColumnsType } from 'antd/es/table';
import React from 'react';
import { changeAdminHide } from '../../services/matrix/admin';
export type AdminHideFormProps = {
onSubmit: () => void;
data: API.MatrixAdminBo[];
};
const AdminHideForm: React.FC<AdminHideFormProps> = (props) => {
const handleOk = () => {
props.onSubmit();
};
const columns: ColumnsType<API.MatrixAdminBo> = [
{
title: '账号',
dataIndex: 'name',
ellipsis: true,
},
{
title: '角色',
dataIndex: 'role',
render: (r: number) => {
let roleText = '';
switch (r) {
case 1:
roleText = '超级管理员';
break;
case 2:
roleText = '管理员';
break;
case 3:
roleText = '普通账号';
break;
case 4:
roleText = '口子';
break;
default:
roleText = '';
}
return roleText;
},
},
{
title: '隐藏',
render: (record: API.MatrixAdminBo) => (
<Switch
defaultValue={record.hide !== 0}
onClick={(val) => {
if (record.id) {
changeAdminHide({ adminId: record.id, hide: val ? 1 : 0 });
}
}}
/>
),
},
];
return (
<Modal title="批量编辑" visible footer={[]} onCancel={handleOk}>
<Table columns={columns} dataSource={props.data} />
</Modal>
);
};
export default AdminHideForm;

375
src/pages/AdminManagement.tsx

@ -0,0 +1,375 @@
import { useModel } from '@umijs/max';
import {
Button,
Col,
Form,
Input,
InputNumber,
Modal,
Row,
Select,
Space,
Table,
Tabs,
Tag,
} from 'antd';
import { ColumnsType } from 'antd/es/table';
import { useEffect, useState } from 'react';
import { SearchOutlined } from '@ant-design/icons';
import TabPane from 'antd/es/tabs/TabPane';
import { adminList, appList, saveAdmin } from '../services/matrix/admin';
import AdminHideForm from './Admin/AdminHideForm';
const AdminManagement = () => {
const [data, setData] = useState<API.MatrixAdminBo[]>([]);
const [visible, setVisible] = useState(false);
const [hideFormVisible, setHideFormVisible] = useState(false);
const [editing, setEditing] = useState(false);
const [role, setRole] = useState<number>(0);
const [form] = Form.useForm();
const [appArr, setAppArr] = useState<API.MatrixApp[]>([]);
const { initialState } = useModel('@@initialState');
const currentUser = initialState?.currentUser;
const formatIncome = (v: number | undefined) => {
if (!v) {
return 0;
}
return parseFloat((v / 1000_00).toFixed(2));
};
const getAppNameById = (appId: number) => {
const app = appArr.find((app) => app.id === appId);
return app ? app.name : '';
};
const handleEdit = (record: API.MatrixAdminBo) => {
form.setFieldsValue(record);
setVisible(true);
setEditing(true);
setRole(record.role ? record.role : 0);
};
const columns: ColumnsType<API.MatrixAdminBo> = [
{
title: '账号',
dataIndex: 'name',
ellipsis: true,
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
<div style={{ padding: 8 }}>
<Input
placeholder="搜索账号"
value={selectedKeys[0]}
onChange={(e) => setSelectedKeys(e.target.value ? [e.target.value] : [])}
onPressEnter={() => confirm()}
style={{ marginBottom: 8, display: 'block' }}
/>
<Space>
<Button onClick={() => confirm()} type="primary">
</Button>
<Button onClick={clearFilters} type="link">
</Button>
</Space>
</div>
),
onFilter: (value, record) => (record?.name && record.name.includes(String(value))) || false,
filterIcon: (filtered) => (
<SearchOutlined
style={{ color: filtered ? '#1890ff' : undefined }}
onPointerOverCapture={undefined}
onPointerMoveCapture={undefined}
/>
),
},
{
title: '游戏',
dataIndex: 'appIds',
render: (text: []) => (
<div>
{text?.map((appId) => (
<Tag color="blue" key={appId}>
{getAppNameById(appId)}
</Tag>
))}
</div>
),
},
{
title: '角色',
dataIndex: 'role',
render: (r: number) => {
let roleText = '';
switch (r) {
case 1:
roleText = '超级管理员';
break;
case 2:
roleText = '管理员';
break;
case 3:
roleText = '普通账号';
break;
case 4:
roleText = '口子';
break;
default:
roleText = '';
}
return roleText;
},
},
{
title: '操作',
render: (record: API.MatrixAdminBo) => [
<a key="edit" onClick={() => handleEdit(record)}>
</a>,
],
},
];
const deviceColumns: ColumnsType<API.MatrixAdminBo> = [
{
title: '账号',
dataIndex: 'name',
ellipsis: true,
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
<div style={{ padding: 8 }}>
<Input
placeholder="搜索账号"
value={selectedKeys[0]}
onChange={(e) => setSelectedKeys(e.target.value ? [e.target.value] : [])}
onPressEnter={() => confirm()}
style={{ marginBottom: 8, display: 'block' }}
/>
<Space>
<Button onClick={() => confirm()} type="primary">
</Button>
<Button onClick={clearFilters} type="link">
</Button>
</Space>
</div>
),
onFilter: (value, record) => (record?.name && record.name.includes(String(value))) || false,
filterIcon: (filtered) => (
<SearchOutlined style={{ color: filtered ? '#1890ff' : undefined }} />
),
},
{
title: '游戏',
dataIndex: 'appIds',
render: (text: []) => (
<div>
{text?.map((appId) => (
<Tag color="blue" key={appId}>
{getAppNameById(appId)}
</Tag>
))}
</div>
),
},
{
title: '角色',
dataIndex: 'role',
render: (r: number) => {
let roleText = '';
switch (r) {
case 1:
roleText = '超级管理员';
break;
case 2:
roleText = '管理员';
break;
case 3:
roleText = '普通账号';
break;
case 4:
roleText = '口子';
break;
default:
roleText = '';
}
return roleText;
},
},
{
title: '本月收入(元)',
dataIndex: 'incomeThisMonth',
render: (_, r: API.MatrixAdminBo) => {
return formatIncome(r.overview?.thisMonthIncome);
},
},
{
title: '上月收入(元)',
dataIndex: 'incomeLastMonth',
render: (_, r: API.MatrixAdminBo) => {
return formatIncome(r.overview?.lastMonthIncome);
},
},
{
title: '累计收入(元)',
dataIndex: 'incomeTotal',
render: (_, r: API.MatrixAdminBo) => {
return formatIncome(r.overview?.totalIncome);
},
},
{
title: '当前分成比例',
dataIndex: 'incomeRate',
},
{
title: '操作',
render: (record: API.MatrixAdminBo) => [
<a key="edit" onClick={() => handleEdit(record)}>
</a>,
],
},
];
const handleOk = () => {
form.submit();
};
const handleCancel = () => {
setVisible(false);
};
const fetchData = async () => {
const res = await adminList();
if (res.data) {
setData(res.data);
}
};
const fetchApp = async () => {
const res = await appList();
if (res.data) {
setAppArr(res.data);
}
};
useEffect(() => {
fetchData();
fetchApp();
}, []);
const handleNew = () => {
form.resetFields(); // 重置表单字段
setVisible(true);
setEditing(false);
setRole(0);
};
const handleSaveAdmin = async (values: API.MatrixAdminBo) => {
try {
await saveAdmin(values);
} catch (e) {
return;
}
setVisible(false);
fetchData();
};
return (
<div>
<Row align="stretch" gutter={20}>
<Col>
<Button onClick={handleNew}></Button>
</Col>
<Col>
<Button
onClick={() => {
setHideFormVisible(true);
}}
>
</Button>
</Col>
</Row>
<Tabs centered style={{ backgroundColor: 'white', padding: '20px' }}>
{currentUser?.role && currentUser.role < 3 && (
<TabPane tab="普通账号" key="1">
<Table
columns={columns}
dataSource={data.filter((x) => x.role === 3 && x.hide === 0)}
/>
</TabPane>
)}
<TabPane tab="口子" key="2">
<Table
columns={deviceColumns}
dataSource={data.filter((x) => x.role === 4 && x.hide === 0)}
/>
</TabPane>
</Tabs>
<Modal title="编辑" visible={visible} onOk={handleOk} onCancel={handleCancel}>
<Form form={form} onFinish={handleSaveAdmin}>
<Form.Item name="id" style={{ display: 'none' }}>
<Input type="hidden" />
</Form.Item>
<Form.Item label="账号" name="name">
<Input disabled={editing} maxLength={32} />
</Form.Item>
<Form.Item label="密码" name="password">
<Input.Password disabled={editing} />
</Form.Item>
<Form.Item label="游戏" name="appIds">
<Select mode="multiple">
{appArr.map((app) => (
<Select.Option key={app.id} value={app.id}>
{app.name}
</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item label="角色" name="role">
<Select disabled={editing} onSelect={setRole}>
<Select.Option disabled={currentUser?.role && currentUser.role > 1} value={2}>
</Select.Option>
<Select.Option disabled={currentUser?.role && currentUser.role > 2} value={3}>
</Select.Option>
<Select.Option value={4}></Select.Option>
</Select>
</Form.Item>
{role > 3 && (
<Row>
<Col span={12}>
<Form.Item label="收入比例" name="incomeRate">
<InputNumber placeholder="1-100整数" style={{ width: '80%' }} />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="设备数" name="deviceCnt">
<InputNumber style={{ width: '80%' }} />
</Form.Item>
</Col>
</Row>
)}
</Form>
</Modal>
{hideFormVisible && (
<AdminHideForm
data={data}
onSubmit={() => {
setHideFormVisible(false);
fetchData();
}}
/>
)}
</div>
);
};
export default AdminManagement;

346
src/pages/AdvRecordList.tsx

@ -1,148 +1,206 @@
import { advList } from '@/services/matrix/admin';
import { PageContainer, ProColumns, ProTable } from '@ant-design/pro-components';
import { useIntl } from '@umijs/max';
import React, { useRef } from 'react';
import { ColumnsState, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components';
import { ProFieldRequestData, RequestOptionsType } from '@ant-design/pro-utils';
import { Tag } from 'antd';
import React, { useRef, useState } from 'react';
import { adminList } from '../services/matrix/admin';
import { advList, appList } from '@/services/matrix/admin';
import type { ActionType } from '@ant-design/pro-components';
const AdvRecordList: React.FC = () => {
const actionRef = useRef<ActionType>();
/**
* @en-US International configuration
* @zh-CN
* */
const intl = useIntl();
const columns: ProColumns<API.MatrixAdvRecordBo>[] = [
{
title: "设备Id",
dataIndex: 'deviceId',
valueType: 'textarea',
ellipsis: true,
copyable: true
},
{
title: "应用名称",
hideInSearch: true,
dataIndex: 'appName',
valueType: 'textarea',
},
{
title: "平台",
dataIndex: 'platform',
valueEnum: {
1: {
text:"穿山甲" ,
},
2: {
text: "腾讯",
},
3: {
text: "百度联盟",
},
4: {
text:"Mintegral",
},
5: {
text:"快手",
},
6: {
text:"游可赢",
},
7: {
text:"Sigmob",
},
8: {
text:"Admob",
},
},
},
{
title: "广告类型",
dataIndex: 'advType',
valueEnum: {
1: {
text:"横幅" ,
status: 'Default',
},
2: {
text: "插页",
status: 'Processing',
},
3: {
text: "激励视频",
status: 'Success',
},
},
},
{
title: "ecpm(元)",
dataIndex: 'ecpm',
hideInSearch: true,
renderText: (x) => {
return x / 100;
}
},
{
title: "设备品牌",
dataIndex: 'deviceBrand',
hideInSearch: true,
valueType: 'textarea',
},
{
title: "设备名",
dataIndex: 'deviceName',
hideInSearch: true,
valueType: 'textarea',
},
{
title: "ip",
dataIndex: 'ip',
hideInSearch: true,
valueType: 'textarea',
},
{
title: "时间",
hideInSearch: true,
dataIndex: 'createdAt',
valueType: 'dateTime'
},
{
title: "时间",
hideInTable: true,
dataIndex: 'createdAt',
valueType: 'dateRange'
},
];
return (
<PageContainer>
<ProTable<API.MatrixAdvRecordBo, API.AdvRecordQuery>
headerTitle={intl.formatMessage({
id: 'pages.searchTable.title',
defaultMessage: 'Enquiry form',
})}
actionRef={actionRef}
rowKey="key"
search={{
labelWidth: 120,
}}
request={async (params: any) => {
const res = await advList(params);
return {
data: res.data?.data,
total: res.data?.total,
success: true
}
}}
columns={columns}
/>
</PageContainer>
);
const actionRef = useRef<ActionType>();
const [income, setIncome] = useState<number | undefined>(undefined);
const appNameMap: ProFieldRequestData = async () => {
let res = await appList();
let data: RequestOptionsType[] = [];
res.data?.forEach((x: API.MatrixApp) => {
data.push({ label: x.name, value: x.code });
});
return data;
};
const adminNameMap: ProFieldRequestData = async () => {
let res = await adminList();
let data: RequestOptionsType[] = [];
res.data?.forEach((x: API.MatrixAdminBo) => {
if (x.role !== 4) {
return;
}
data.push({ label: x.name, value: x.id });
});
return data;
};
const isMobile = () => {
return window.innerWidth <= 768;
};
export default AdvRecordList;
const [columnsState, setColumnsState] = useState<Record<string, ColumnsState>>({
deviceId: { show: !isMobile() },
appName: { show: !isMobile() },
platform: { show: !isMobile() },
device: { show: !isMobile() },
ip: { show: !isMobile() },
advType: { show: !isMobile() },
});
const columns: ProColumns<API.MatrixAdvRecordBo>[] = [
{
title: '应用名称',
hideInTable: true,
dataIndex: 'code',
valueType: 'select',
request: appNameMap,
},
{
title: '口子',
hideInTable: true,
dataIndex: 'adminId',
valueType: 'select',
request: adminNameMap,
},
{
title: '设备id',
dataIndex: 'deviceId',
valueType: 'textarea',
ellipsis: true,
copyable: true,
},
{
title: '应用名称',
hideInSearch: true,
dataIndex: 'appName',
valueType: 'textarea',
},
{
title: '平台',
dataIndex: 'platform',
valueEnum: {
1: {
text: '穿山甲',
},
2: {
text: '腾讯',
},
5: {
text: '快手',
},
7: {
text: 'Sigmob',
},
},
},
{
title: '广告类型',
dataIndex: 'advType',
valueEnum: {
1: {
text: '横幅',
// status: 'Default',
},
2: {
text: '插页',
// status: 'Processing',
},
3: {
text: '激励视频',
// status: 'Success',
},
},
},
{
title: 'ecpm(元)',
dataIndex: 'ecpm',
hideInSearch: true,
renderText: (x) => {
return x / 100;
},
},
{
title: '设备',
dataIndex: 'device',
hideInSearch: true,
valueType: 'textarea',
renderText: (_, r) => {
return (
<p>
{r.deviceBrand} <br /> {r.deviceName}
</p>
);
},
},
{
title: 'ip',
dataIndex: 'ip',
hideInSearch: true,
valueType: 'textarea',
},
{
title: '口子',
dataIndex: 'adminName',
hideInSearch: true,
valueType: 'textarea',
},
{
title: '状态',
dataIndex: 'status',
hideInSearch: true,
renderText: () => {
return <Tag color="#eb0fcc"></Tag>;
},
},
{
title: '时间',
hideInSearch: true,
dataIndex: 'createdAt',
valueType: 'dateTime',
},
{
title: '时间',
hideInTable: true,
dataIndex: 'createdAt',
valueType: 'dateRange',
},
];
const formatIncome = (v: number | undefined) => {
if (!v) {
return 0;
}
return parseFloat((v / 1000_00).toFixed(2));
};
return (
<PageContainer>
<ProTable<API.MatrixAdvRecordBo, API.AdvRecordQuery>
headerTitle={income ? '表格累计:' + formatIncome(income) + '元' : ''}
actionRef={actionRef}
rowKey="key"
search={{
labelWidth: 120,
}}
request={async (params: API.AdvRecordQuery) => {
const res = await advList(params);
if (params.current === 1) {
setIncome(res.data?.sum);
}
return {
data: res.data?.data,
total: res.data?.total,
success: true,
};
}}
columns={columns}
columnsState={{
value: columnsState,
onChange: (newState) => {
setColumnsState(newState);
},
}}
/>
</PageContainer>
);
};
export default AdvRecordList;

162
src/pages/AppManagement.tsx

@ -0,0 +1,162 @@
import { PageContainer, ProColumns, ProTable } from '@ant-design/pro-components';
import { useModel } from '@umijs/max';
import { Button, Form, Input, Modal, Popover, QRCode, Row, Space } from 'antd';
import { useEffect, useState } from 'react';
import { appList, saveApp } from '@/services/matrix/admin';
import { SearchOutlined } from '@ant-design/icons';
const AppManagement = () => {
const [visible, setVisible] = useState(false);
const [form] = Form.useForm();
const [appArr, setAppArr] = useState<API.MatrixApp[]>([]);
const { initialState } = useModel('@@initialState');
const currentUser = initialState?.currentUser;
const canUpdate = currentUser && currentUser.role && currentUser.role < 2;
const handleEdit = (record: API.MatrixApp) => {
form.setFieldsValue(record);
setVisible(true);
};
const columns: ProColumns<API.MatrixApp>[] = [
{
title: '游戏',
dataIndex: 'name',
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
<div style={{ padding: 8 }}>
<Input
placeholder="搜索账号"
value={selectedKeys[0]}
onChange={(e) => setSelectedKeys(e.target.value ? [e.target.value] : [])}
onPressEnter={() => confirm()}
style={{ marginBottom: 8, display: 'block' }}
/>
<Space>
<Button onClick={() => confirm()} type="primary">
</Button>
<Button onClick={() => clearFilters()} type="link">
</Button>
</Space>
</div>
),
onFilter: (value, record) => record?.name?.includes(value),
filterIcon: (filtered) => (
<SearchOutlined
style={{ color: filtered ? '#1890ff' : undefined }}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/>
),
},
// {
// title: 'code',
// dataIndex: 'code',
// },
{
title: '下载地址',
dataIndex: 'url',
renderText: (url: string) =>
url && (
<Row align="middle">
<QRCode size={80} value={url || ''} bordered={false} />
<Popover
overlayInnerStyle={{ padding: 0 }}
content={<QRCode size={300} value={url || ''} bordered={false} />}
>
<a></a>
</Popover>
</Row>
),
},
];
const columnsWithOperation: ProColumns<API.MatrixApp>[] = [
...columns,
{
title: 'secret',
dataIndex: 'secret',
ellipsis: true,
copyable: true,
},
{
title: '操作',
width: 80,
renderText: (record: API.MatrixApp) => (
<a key="edit" onClick={() => handleEdit(record)}>
</a>
),
},
];
const handleOk = () => {
form.submit();
};
const handleCancel = () => {
setVisible(false);
};
const fetchApp = async () => {
const res = await appList();
if (res.data) {
setAppArr(res.data);
}
};
useEffect(() => {
fetchApp();
}, []);
const handleNew = () => {
form.resetFields(); // 重置表单字段
setVisible(true);
};
const handleSaveApp = async (values: API.MatrixApp) => {
try {
await saveApp(values);
} catch (e) {
return;
}
setVisible(false);
fetchApp();
};
return (
<PageContainer>
{currentUser && currentUser.role && currentUser.role < 2 && (
<Button style={{ marginBottom: '20px' }} onClick={handleNew}>
</Button>
)}
<ProTable
search={false}
columns={canUpdate ? columnsWithOperation : columns}
dataSource={appArr}
/>
<Modal title="编辑" visible={visible} onOk={handleOk} onCancel={handleCancel}>
<Form form={form} onFinish={handleSaveApp}>
<Form.Item name="id" style={{ display: 'none' }}>
<Input type="hidden" />
</Form.Item>
<Form.Item name="code" style={{ display: 'none' }}>
<Input type="hidden" />
</Form.Item>
<Form.Item label="应用名" name="name">
<Input />
</Form.Item>
<Form.Item label="下载地址" name="url">
<Input />
</Form.Item>
</Form>
</Modal>
</PageContainer>
);
};
export default AppManagement;

19
src/pages/Bind.tsx

@ -0,0 +1,19 @@
import { PageContainer } from '@ant-design/pro-components';
import { useModel } from '@umijs/max';
import { Card, QRCode } from 'antd';
const Bind: React.FC = () => {
const { initialState } = useModel('@@initialState');
const currentUser = initialState?.currentUser;
return (
<PageContainer>
<Card>
<QRCode style={{ margin: 'auto' }} value={currentUser?.name || ''} />
<p style={{ textAlign: 'center', marginTop: '20px' }}>使app扫码绑定设备</p>
</Card>
</PageContainer>
);
};
export default Bind;

173
src/pages/DeviceOverview.tsx

@ -0,0 +1,173 @@
import { appList } from '@/services/matrix/admin';
import { incomeDaily1, incomeOverview1 } from '@/services/matrix/device';
import { Area } from '@ant-design/charts';
import {
PageContainer,
ProFormDateRangePicker,
ProFormSelect,
QueryFilter,
StatisticCard,
} from '@ant-design/pro-components';
import moment from 'moment';
import RcResizeObserver from 'rc-resize-observer';
import { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
const Overview: React.FC = () => {
const [overview, setOverview] = useState<API.OverviewBo>();
const [daily, setDaily] = useState<API.DateIncome[]>([]);
const [appArr, setAppArr] = useState<API.MatrixApp[]>([]);
const [responsive, setResponsive] = useState(false);
const { code } = useParams();
const fetchData = async () => {
const res = await incomeOverview1({ appCode: code });
if (res.data) {
setOverview(res.data);
}
};
const fetchApp = async () => {
const res = await appList();
if (res.data) {
setAppArr(res.data);
}
};
const fetchDaily = async (params: API.IncomeQuery) => {
const res = await incomeDaily1(params);
if (res.data) {
setDaily(res.data);
}
};
useEffect(() => {
fetchData();
fetchApp();
fetchDaily({ code: code });
}, []);
const formatIncome = (v: number | undefined) => {
if (!v) {
return 0;
}
return parseFloat((v / 1000_00).toFixed(2));
};
const formatDate = (x: number | undefined) => {
const str = x + '';
return str.slice(4, 6) + '/' + str.slice(6, 8);
};
// 在渲染折线图组件时,对数据进行处理
const processedChartData: { date: string | number; income: number }[] = daily.map((item) => ({
date: formatDate(item.date),
income: formatIncome(item.income),
}));
const config = {
data: processedChartData,
// theme: 'Light',
xField: 'date',
yField: 'income',
// theme: 'classicDark',
tooltip: {
name: '收入',
field: 'income',
},
axis: {
date: {
title: '日期',
},
income: {
title: '收入(元)',
},
},
title:
'区间累计' +
formatIncome(daily.reduce((acc, data) => acc + (data.income ? data.income : 0), 0)) +
'元',
height: 400,
label: {
text: (d: any) => (d.income > 0 ? d.income : ''),
textBaseline: 'bottom',
visible: true,
type: 'point',
},
line: {
style: {
stroke: '#eb0fcc',
strokeWidth: 2,
},
shapeField: 'smooth',
},
shapeField: 'smooth',
style: {
fill: 'linear-gradient(-90deg, white 0%, #eb0fcc 100%)',
},
// point: { visible: true },
};
return (
<PageContainer>
<RcResizeObserver
key="resize-observer"
onResize={(offset) => {
setResponsive(offset.width < 596);
}}
>
<StatisticCard>
<StatisticCard.Group direction={responsive ? 'column' : 'row'}>
<StatisticCard
statistic={{
title: '累计收入(元)',
value: formatIncome(overview?.totalIncome),
}}
/>
<StatisticCard
statistic={{
title: '昨日收入(元)',
value: formatIncome(overview?.yesterdayIncome),
}}
/>
</StatisticCard.Group>
</StatisticCard>
</RcResizeObserver>
<div style={{ marginTop: '20px', padding: '40px', backgroundColor: 'white' }}>
<QueryFilter defaultCollapsed split onFinish={fetchDaily}>
<ProFormSelect
name="code"
label="应用"
options={appArr.map((x) => ({
label: x.name,
value: x.code,
}))}
/>
<ProFormSelect
label="平台"
name="platform"
valueEnum={{
1: '穿山甲',
2: '腾讯',
5: '快手',
7: 'Sigmob',
}}
/>
<ProFormDateRangePicker
fieldProps={{
disabledDate: (current: any) => current && current >= moment().startOf('day'),
}}
name="date"
label="时间"
/>
</QueryFilter>
<Area {...config} />
</div>
</PageContainer>
);
};
export default Overview;

296
src/pages/DeviceOwnerApp.tsx

@ -0,0 +1,296 @@
import { advList, appList } from '@/services/matrix/admin';
import {
ColumnsState,
PageContainer,
ProColumns,
ProFieldRequestData,
ProTable,
RequestOptionsType,
} from '@ant-design/pro-components';
import { useIntl, useModel } from '@umijs/max';
import { Tabs } from 'antd';
import TabPane from 'antd/es/tabs/TabPane';
import React, { useRef, useState } from 'react';
import { online } from '../services/matrix/device';
// import { RequestOptionsType, ProFieldRequestData } from "@ant-design/pro-utils";
import { deviceList, offline } from '@/services/matrix/device';
import type { ActionType } from '@ant-design/pro-components';
const DeviceOwnerApp: React.FC = () => {
const actionRef = useRef<ActionType>();
const deviceRef = useRef<ActionType>();
const [usedDeviceCnt, setUsedDeviceCnt] = useState(0);
/**
* @en-US International configuration
* @zh-CN
* */
const intl = useIntl();
const { initialState } = useModel('@@initialState');
const currentUser = initialState?.currentUser;
const appNameMap: ProFieldRequestData = async () => {
let res = await appList();
let data: RequestOptionsType[] = [];
res.data?.forEach((x) => {
data.push({ label: x.name, value: x.code });
});
return data;
};
const isMobile = () => {
return window.innerWidth <= 768;
};
const fetchDevice = async (params: any) => {
if (!params.appName) {
return {
data: [],
total: 0,
success: true,
};
}
const res = await deviceList({ appCode: params.appName ? params.appName : '' });
if (res.data) {
setUsedDeviceCnt(res.data?.filter((device) => device.status === 0).length);
}
return {
data: res.data,
total: res.data?.length,
success: true,
};
};
const handleSetOffline = async (deviceId: string | undefined) => {
if (!deviceId) {
return;
}
await offline({ deviceId: deviceId });
deviceRef.current?.reload();
};
const handleSetOnline = async (deviceId: string | undefined) => {
if (!deviceId) {
return;
}
try {
await online({ deviceId: deviceId });
deviceRef.current?.reload();
} catch {}
};
const [columnsState, setColumnsState] = useState<Record<string, ColumnsState>>({
deviceId: { show: !isMobile() },
appName: { show: !isMobile() },
platform: { show: !isMobile() },
deviceBrand: { show: !isMobile() },
deviceName: { show: !isMobile() },
ip: { show: !isMobile() },
});
const columns: ProColumns<API.MatrixAdvRecordBo>[] = [
{
title: '应用名称',
dataIndex: 'appName',
valueType: 'textarea',
request: appNameMap,
},
{
title: '设备id',
dataIndex: 'deviceId',
valueType: 'textarea',
ellipsis: true,
copyable: true,
},
{
title: '平台',
dataIndex: 'platform',
valueEnum: {
1: {
text: '穿山甲',
},
2: {
text: '腾讯',
},
5: {
text: '快手',
},
7: {
text: 'Sigmob',
},
},
},
{
title: 'ecpm(元)',
dataIndex: 'ecpm',
hideInSearch: true,
renderText: (x) => {
return x / 100;
},
},
{
title: 'ecpm-抽成后(元)',
dataIndex: 'deductEcpm',
hideInSearch: true,
renderText: (x, record) => {
if (currentUser?.incomeRate && record.ecpm) {
return Math.floor((record.ecpm * currentUser.incomeRate) / 100) / 100;
}
return '-';
},
},
{
title: '设备品牌',
dataIndex: 'deviceBrand',
hideInSearch: true,
valueType: 'textarea',
},
{
title: '设备名',
dataIndex: 'deviceName',
hideInSearch: true,
valueType: 'textarea',
},
{
title: 'ip',
dataIndex: 'ip',
hideInSearch: true,
valueType: 'textarea',
},
{
title: '时间',
hideInSearch: true,
dataIndex: 'createdAt',
valueType: 'dateTime',
},
{
title: '时间',
hideInTable: true,
dataIndex: 'createdAt',
valueType: 'dateRange',
},
// {
// title: "应用名称",
// hideInTable: true,
// dataIndex: 'appId',
// valueType: "select",
// request: appNameMap
// }
];
const deviceColumns: ProColumns<API.MatrixAdminDevice>[] = [
{
title: '应用名称',
dataIndex: 'appName',
valueType: 'textarea',
request: appNameMap,
hideInTable: true,
},
{
title: '设备id',
dataIndex: 'deviceId',
valueType: 'text',
ellipsis: true,
width: 400,
copyable: true,
hideInSearch: true,
},
{
title: '状态',
dataIndex: 'status',
valueEnum: {
0: {
text: '正常',
},
'-1': {
text: '已下线',
},
},
filters: true,
onFilter: true,
hideInSearch: true,
},
{
title: '绑定时间',
hideInSearch: true,
dataIndex: 'createdAt',
valueType: 'dateTime',
},
{
title: '操作',
dataIndex: 'operation',
hideInSearch: true,
render: (_, record) => {
if (record.status === 0) {
return <a onClick={() => handleSetOffline(record.deviceId)}>线</a>;
}
if (record.status === -1) {
return <a onClick={() => handleSetOnline(record.deviceId)}>线</a>;
}
return null;
},
},
];
const fetchData = async (params: any) => {
if (!params.appName) {
return {
data: [],
total: 0,
success: true,
};
}
const res = await advList({ ...params, code: params.appName });
return {
data: res.data?.data,
total: res.data?.total,
success: true,
};
};
return (
<PageContainer>
<Tabs defaultActiveKey="1" centered style={{ backgroundColor: 'white', padding: '20px' }}>
<TabPane tab="设备列表" key="1">
<p style={{ textAlign: 'center' }}>
{'正常使用设备数:' +
usedDeviceCnt +
',剩余可绑定设备数:' +
Math.max(0, (currentUser?.deviceCnt ? currentUser.deviceCnt : 0) - usedDeviceCnt)}
</p>
<ProTable<API.MatrixAdminDevice>
actionRef={deviceRef}
rowKey="id"
request={fetchDevice}
columns={deviceColumns}
/>
</TabPane>
<TabPane tab="广告详情" key="2">
<ProTable<API.MatrixAdvRecordBo, API.AdvRecordQuery>
headerTitle={intl.formatMessage({
id: 'pages.searchTable.title',
defaultMessage: 'Enquiry form',
})}
actionRef={actionRef}
rowKey="id"
search={{
labelWidth: 120,
}}
request={fetchData}
columns={columns}
columnsState={{
value: columnsState,
onChange: (newState) => {
setColumnsState(newState);
},
}}
/>
</TabPane>
</Tabs>
</PageContainer>
);
};
export default DeviceOwnerApp;

181
src/pages/Overview.tsx

@ -0,0 +1,181 @@
import { appList, incomeDaily, incomeOverview } from '@/services/matrix/admin';
import { Area } from '@ant-design/charts';
import {
PageContainer,
ProFormDateRangePicker,
ProFormSelect,
QueryFilter,
StatisticCard,
} from '@ant-design/pro-components';
import moment from 'moment';
import RcResizeObserver from 'rc-resize-observer';
import { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
const Overview: React.FC = () => {
const [overview, setOverview] = useState<API.OverviewBo>();
const [daily, setDaily] = useState<API.DateIncome[]>([]);
const [appArr, setAppArr] = useState<API.MatrixApp[]>([]);
const [responsive, setResponsive] = useState(false);
const { code } = useParams();
const fetchData = async () => {
const res = await incomeOverview({ appCode: code });
if (res.data) {
setOverview(res.data);
}
};
const fetchApp = async () => {
const res = await appList();
if (res.data) {
setAppArr(res.data);
}
};
const fetchDaily = async (params: API.IncomeQuery) => {
const res = await incomeDaily(params);
if (res.data) {
setDaily(res.data);
}
};
useEffect(() => {
fetchData();
fetchApp();
fetchDaily({ code: code });
}, []);
const formatIncome = (v: number | undefined) => {
if (!v) {
return 0;
}
return parseFloat((v / 1000_00).toFixed(2));
};
const formatDate = (x: number | undefined) => {
const str = x + '';
return str.slice(4, 6) + '/' + str.slice(6, 8);
};
// 在渲染折线图组件时,对数据进行处理
const processedChartData: { date: string | number; income: number }[] = daily.map((item) => ({
date: formatDate(item.date),
income: formatIncome(item.income),
}));
const config = {
data: processedChartData,
// theme: 'Light',
xField: 'date',
yField: 'income',
// theme: 'classicDark',
tooltip: {
name: '收入',
field: 'income',
},
axis: {
date: {
title: '日期',
},
income: {
title: '收入(元)',
},
},
title:
'区间累计' +
formatIncome(daily.reduce((acc, data) => acc + (data.income ? data.income : 0), 0)) +
'元',
height: 400,
label: {
text: (d: any) => (d.income > 0 ? d.income : ''),
textBaseline: 'bottom',
visible: true,
type: 'point',
},
line: {
style: {
stroke: '#eb0fcc',
strokeWidth: 2,
},
shapeField: 'smooth',
},
shapeField: 'smooth',
style: {
fill: 'linear-gradient(-90deg, white 0%, #eb0fcc 100%)',
},
// point: { visible: true },
};
return (
<PageContainer>
<RcResizeObserver
key="resize-observer"
onResize={(offset) => {
setResponsive(offset.width < 596);
}}
>
<StatisticCard>
<StatisticCard.Group direction={responsive ? 'column' : 'row'}>
<StatisticCard
statistic={{
title: '累计收入(元)',
value: formatIncome(overview?.totalIncome),
}}
/>
<StatisticCard
statistic={{
title: '昨日收入(元)',
value: formatIncome(overview?.yesterdayIncome),
}}
/>
</StatisticCard.Group>
</StatisticCard>
</RcResizeObserver>
<div style={{ marginTop: '20px', padding: '40px', backgroundColor: 'white' }}>
<QueryFilter defaultCollapsed split onFinish={fetchDaily}>
<ProFormSelect
name="code"
label="应用"
options={appArr.map((x) => ({
label: x.name,
value: x.code,
}))}
/>
<ProFormSelect
label="平台"
name="platform"
valueEnum={{
1: '穿山甲',
2: '腾讯',
5: '快手',
7: 'Sigmob',
}}
/>
<ProFormSelect
name="advType"
label="广告类型"
valueEnum={{
1: '横幅',
2: '插页',
3: '激励视频',
}}
/>
<ProFormDateRangePicker
fieldProps={{
disabledDate: (current: any) => current && current >= moment().startOf('day'),
}}
name="date"
label="时间"
/>
</QueryFilter>
<Area {...config} />
</div>
</PageContainer>
);
};
export default Overview;

37
src/pages/User/Login/index.tsx

@ -1,9 +1,9 @@
import { Footer } from '@/components';
import loginBg from '@/assets/loginBg.jpg';
import { adminLogin as login } from '@/services/matrix/admin';
import { LockOutlined, UserOutlined } from '@ant-design/icons';
import { LoginForm, ProFormCheckbox, ProFormText } from '@ant-design/pro-components';
import { FormattedMessage, Helmet, history, SelectLang, useIntl, useModel } from '@umijs/max';
import { message, Tabs } from 'antd';
import { FormattedMessage, Helmet, SelectLang, history, useIntl, useModel } from '@umijs/max';
import { Tabs, message } from 'antd';
import { createStyles } from 'antd-style';
import React, { useState } from 'react';
import { flushSync } from 'react-dom';
@ -39,8 +39,7 @@ const useStyles = createStyles(({ token }) => {
flexDirection: 'column',
height: '100vh',
overflow: 'auto',
backgroundImage:
"url('https://mdn.alipayobjects.com/yuyan_qk0oxh/afts/img/V-_oS6r-i7wAAAAAAAAAAAAAFl94AQBr')",
backgroundImage: `url(${loginBg})`,
backgroundSize: '100% 100%',
},
};
@ -86,8 +85,9 @@ const Login: React.FC = () => {
});
message.success(defaultLoginSuccessMessage);
await fetchUserInfo();
const urlParams = new URL(window.location.href).searchParams;
history.push(urlParams.get('redirect') || '/');
// const urlParams = new URL(window.location.href).searchParams;
// history.push(urlParams.get('redirect') || '/');
history.push('/');
// 如果失败去设置用户错误信息
// setUserLoginState(msg);
} catch (error) {
@ -115,6 +115,9 @@ const Login: React.FC = () => {
style={{
flex: '1',
padding: '32px 0',
position: 'absolute',
left: '10vw',
bottom: '10vh',
}}
>
<LoginForm
@ -122,8 +125,8 @@ const Login: React.FC = () => {
minWidth: 280,
maxWidth: '75vw',
}}
logo={<img alt="logo" src="/logo.svg" />}
title="Matrix"
logo={<img alt="logo" src="/logo.png" />}
// title="Magic"
// subTitle={intl.formatMessage({ id: 'pages.layouts.userLayout.title' })}
initialValues={{
autoLogin: true,
@ -152,7 +155,12 @@ const Login: React.FC = () => {
name="name"
fieldProps={{
size: 'large',
prefix: <UserOutlined />,
prefix: (
<UserOutlined
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/>
),
}}
placeholder={intl.formatMessage({
id: 'pages.login.username.placeholder',
@ -174,7 +182,12 @@ const Login: React.FC = () => {
name="pwd"
fieldProps={{
size: 'large',
prefix: <LockOutlined />,
prefix: (
<LockOutlined
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
/>
),
}}
placeholder={intl.formatMessage({
id: 'pages.login.password.placeholder',
@ -206,7 +219,7 @@ const Login: React.FC = () => {
</div>
</LoginForm>
</div>
<Footer />
{/* <Footer /> */}
</div>
);
};

164
src/pages/Welcome.tsx

@ -1,163 +1,29 @@
import { PageContainer } from '@ant-design/pro-components';
import { useModel } from '@umijs/max';
import { Card, theme } from 'antd';
import { Flex, Image, theme } from 'antd';
import React from 'react';
import welcome from '../assets/welcome.jpeg';
/**
*
* @param param0
* @returns
*/
const InfoCard: React.FC<{
title: string;
index: number;
desc: string;
href: string;
}> = ({ title, href, index, desc }) => {
const { useToken } = theme;
const { token } = useToken();
return (
<div
style={{
backgroundColor: token.colorBgContainer,
boxShadow: token.boxShadow,
borderRadius: '8px',
fontSize: '14px',
color: token.colorTextSecondary,
lineHeight: '22px',
padding: '16px 19px',
minWidth: '220px',
flex: 1,
}}
>
<div
style={{
display: 'flex',
gap: '4px',
alignItems: 'center',
}}
>
<div
style={{
width: 48,
height: 48,
lineHeight: '22px',
backgroundSize: '100%',
textAlign: 'center',
padding: '8px 16px 16px 12px',
color: '#FFF',
fontWeight: 'bold',
backgroundImage:
"url('https://gw.alipayobjects.com/zos/bmw-prod/daaf8d50-8e6d-4251-905d-676a24ddfa12.svg')",
}}
>
{index}
</div>
<div
style={{
fontSize: '16px',
color: token.colorText,
paddingBottom: 8,
}}
>
{title}
</div>
</div>
<div
style={{
fontSize: '14px',
color: token.colorTextSecondary,
textAlign: 'justify',
lineHeight: '22px',
marginBottom: 8,
}}
>
{desc}
</div>
<a href={href} target="_blank" rel="noreferrer">
{'>'}
</a>
</div>
);
};
const Welcome: React.FC = () => {
const { token } = theme.useToken();
const { initialState } = useModel('@@initialState');
// const { initialState } = useModel('@@initialState');
return (
<PageContainer>
<Card
style={{
borderRadius: 8,
}}
bodyStyle={{
backgroundImage:
initialState?.settings?.navTheme === 'realDark'
? 'background-image: linear-gradient(75deg, #1A1B1F 0%, #191C1F 100%)'
: 'background-image: linear-gradient(75deg, #FBFDFF 0%, #F5F7FF 100%)',
}}
>
<div
style={{
backgroundPosition: '100% -30%',
backgroundRepeat: 'no-repeat',
backgroundSize: '274px auto',
backgroundImage:
"url('https://gw.alipayobjects.com/mdn/rms_a9745b/afts/img/A*BuFmQqsB2iAAAAAAAAAAAAAAARQnAQ')",
}}
>
<div
style={{
fontSize: '20px',
color: token.colorTextHeading,
}}
>
使 Ant Design Pro
</div>
<p
style={{
fontSize: '14px',
color: token.colorTextSecondary,
lineHeight: '22px',
marginTop: 16,
marginBottom: 32,
width: '65%',
}}
>
Ant Design Pro umiAnt Design ProComponents
//
</p>
<div
style={{
display: 'flex',
flexWrap: 'wrap',
gap: 16,
}}
>
<InfoCard
index={1}
href="https://umijs.org/docs/introduce/introduce"
title="了解 umi"
desc="umi 是一个可扩展的企业级前端应用框架,umi 以路由为基础的,同时支持配置式路由和约定式路由,保证路由的功能完备,并以此进行功能扩展。"
/>
<InfoCard
index={2}
title="了解 ant design"
href="https://ant.design"
desc="antd 是基于 Ant Design 设计体系的 React UI 组件库,主要用于研发企业级中后台产品。"
/>
<InfoCard
index={3}
title="了解 Pro Components"
href="https://procomponents.ant.design"
desc="ProComponents 是一个基于 Ant Design 做了更高抽象的模板组件,以 一个组件就是一个页面为开发理念,为中后台开发带来更好的体验。"
/>
</div>
</div>
</Card>
</PageContainer>
<Flex
align="center"
justify="center"
vertical
style={{ width: '100%', backgroundColor: 'white', padding: 20 }}
>
<Image preview={false} width={300} src={welcome} />
<p style={{ marginTop: 20, fontSize: 20, color: token.colorTextBase }}>
使Magic后台管理系统
</p>
</Flex>
);
};

178
src/services/matrix/admin.ts

@ -2,6 +2,41 @@
/* eslint-disable */
import { request } from '@umijs/max';
/** 此处后端没有提供注释 POST /api/admin/addSchedule */
export async function addSchedule(body: API.AddMockScheduleReq, options?: { [key: string]: any }) {
return request<API.RVoid>('/api/admin/addSchedule', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/admin/addWhiteList */
export async function addWhiteList(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.addWhiteListParams,
options?: { [key: string]: any },
) {
return request<API.RVoid>('/api/admin/addWhiteList', {
method: 'POST',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 GET /api/admin/adminList */
export async function adminList(options?: { [key: string]: any }) {
return request<API.RListMatrixAdminBo>('/api/admin/adminList', {
method: 'GET',
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/admin/advList */
export async function advList(body: API.AdvRecordQuery, options?: { [key: string]: any }) {
return request<API.RPageResultMatrixAdvRecordBo>('/api/admin/advList', {
@ -14,6 +49,29 @@ export async function advList(body: API.AdvRecordQuery, options?: { [key: string
});
}
/** 此处后端没有提供注释 GET /api/admin/appList */
export async function appList(options?: { [key: string]: any }) {
return request<API.RListMatrixAppBo>('/api/admin/appList', {
method: 'GET',
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/admin/changeAdminHide */
export async function changeAdminHide(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.changeAdminHideParams,
options?: { [key: string]: any },
) {
return request<API.RVoid>('/api/admin/changeAdminHide', {
method: 'POST',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 GET /api/admin/current */
export async function current(options?: { [key: string]: any }) {
return request<API.RMatrixAdmin>('/api/admin/current', {
@ -22,6 +80,71 @@ export async function current(options?: { [key: string]: any }) {
});
}
/** 此处后端没有提供注释 POST /api/admin/deleteWhiteList */
export async function deleteWhiteList(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.deleteWhiteListParams,
options?: { [key: string]: any },
) {
return request<API.RVoid>('/api/admin/deleteWhiteList', {
method: 'POST',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 GET /api/admin/getSTS */
export async function getSts(options?: { [key: string]: any }) {
return request<API.RSTSInfo>('/api/admin/getSTS', {
method: 'GET',
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/admin/grantApp */
export async function grantApp(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.grantAppParams,
options?: { [key: string]: any },
) {
return request<API.RVoid>('/api/admin/grantApp', {
method: 'POST',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/admin/incomeDaily */
export async function incomeDaily(body: API.IncomeQuery, options?: { [key: string]: any }) {
return request<API.RListDateIncome>('/api/admin/incomeDaily', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** 此处后端没有提供注释 GET /api/admin/incomeOverview */
export async function incomeOverview(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.incomeOverviewParams,
options?: { [key: string]: any },
) {
return request<API.ROverviewBo>('/api/admin/incomeOverview', {
method: 'GET',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/admin/login */
export async function adminLogin(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
@ -36,3 +159,58 @@ export async function adminLogin(
...(options || {}),
});
}
/** 此处后端没有提供注释 GET /api/admin/mock */
export async function mock(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.mockParams,
options?: { [key: string]: any },
) {
return request<API.RVoid>('/api/admin/mock', {
method: 'GET',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/admin/saveAdmin */
export async function saveAdmin(body: API.MatrixAdminBo, options?: { [key: string]: any }) {
return request<API.RVoid>('/api/admin/saveAdmin', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/admin/saveApp */
export async function saveApp(body: API.MatrixApp, options?: { [key: string]: any }) {
return request<API.RVoid>('/api/admin/saveApp', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** 此处后端没有提供注释 GET /api/admin/scheduleList */
export async function scheduleList(options?: { [key: string]: any }) {
return request<API.RListMatrixMockSchedule>('/api/admin/scheduleList', {
method: 'GET',
...(options || {}),
});
}
/** 此处后端没有提供注释 GET /api/admin/whiteList */
export async function whiteList(options?: { [key: string]: any }) {
return request<API.RListMatrixWhiteDevice>('/api/admin/whiteList', {
method: 'GET',
...(options || {}),
});
}

18
src/services/matrix/appController.ts

@ -1,18 +0,0 @@
// @ts-ignore
/* eslint-disable */
import { request } from '@umijs/max';
/** 此处后端没有提供注释 GET /api/game/app/info */
export async function getAppInfo(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.getAppInfoParams,
options?: { [key: string]: any },
) {
return request<API.RAppInfo>('/api/game/app/info', {
method: 'GET',
params: {
...params,
},
...(options || {}),
});
}

90
src/services/matrix/device.ts

@ -0,0 +1,90 @@
// @ts-ignore
/* eslint-disable */
import { request } from '@umijs/max';
/** 此处后端没有提供注释 GET /api/admin/device/calc */
export async function calc(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.calcParams,
options?: { [key: string]: any },
) {
return request<API.RVoid>('/api/admin/device/calc', {
method: 'GET',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/admin/device/incomeDaily */
export async function incomeDaily1(body: API.IncomeQuery, options?: { [key: string]: any }) {
return request<API.RListDateIncome>('/api/admin/device/incomeDaily', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** 此处后端没有提供注释 GET /api/admin/device/incomeOverview */
export async function incomeOverview1(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.incomeOverview1Params,
options?: { [key: string]: any },
) {
return request<API.ROverviewBo>('/api/admin/device/incomeOverview', {
method: 'GET',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 GET /api/admin/device/list */
export async function deviceList(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.deviceListParams,
options?: { [key: string]: any },
) {
return request<API.RListMatrixAdminDevice>('/api/admin/device/list', {
method: 'GET',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/admin/device/offline */
export async function offline(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.offlineParams,
options?: { [key: string]: any },
) {
return request<API.RString>('/api/admin/device/offline', {
method: 'POST',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/admin/device/online */
export async function online(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.onlineParams,
options?: { [key: string]: any },
) {
return request<API.RString>('/api/admin/device/online', {
method: 'POST',
params: {
...params,
},
...(options || {}),
});
}

14
src/services/matrix/index.ts

@ -3,12 +3,14 @@
// API 更新时间:
// API 唯一标识:
import * as admin from './admin';
import * as appController from './appController';
import * as loginController from './loginController';
import * as matrixController from './matrixController';
import * as device from './device';
import * as matrixAppConfigController from './matrixAppConfigController';
import * as matrixMoneyController from './matrixMoneyController';
import * as matrixUserController from './matrixUserController';
export default {
matrixController,
loginController,
matrixUserController,
admin,
appController,
matrixMoneyController,
device,
matrixAppConfigController,
};

114
src/services/matrix/loginController.ts

@ -1,114 +0,0 @@
// @ts-ignore
/* eslint-disable */
import { request } from '@umijs/max';
/** 此处后端没有提供注释 GET /api/game/auth/current */
export async function currentUser(options?: { [key: string]: any }) {
return request<API.RCurrentUser>('/api/game/auth/current', {
method: 'GET',
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/game/auth/login */
export async function wxLogin(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.wxLoginParams,
options?: { [key: string]: any },
) {
return request<API.RString>('/api/game/auth/login', {
method: 'POST',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/game/auth/loginV2 */
export async function wxLoginV2(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.wxLoginV2Params,
options?: { [key: string]: any },
) {
return request<API.RLoginBo>('/api/game/auth/loginV2', {
method: 'POST',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/game/auth/loginV3 */
export async function loginV3(body: API.LoginReq, options?: { [key: string]: any }) {
return request<API.RLoginBo>('/api/game/auth/loginV3', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** 此处后端没有提供注释 GET /api/game/auth/myInviteRecord */
export async function myInviteRecord(options?: { [key: string]: any }) {
return request<API.RInviteInfo>('/api/game/auth/myInviteRecord', {
method: 'GET',
...(options || {}),
});
}
/** 此处后端没有提供注释 GET /api/game/auth/rankList */
export async function rankList(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.rankListParams,
options?: { [key: string]: any },
) {
return request<API.RRankList>('/api/game/auth/rankList', {
method: 'GET',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 GET /api/game/auth/test */
export async function setInviteCode(options?: { [key: string]: any }) {
return request<API.RVoid>('/api/game/auth/test', {
method: 'GET',
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/game/auth/updateScore */
export async function updateScore(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.updateScoreParams,
options?: { [key: string]: any },
) {
return request<API.RVoid>('/api/game/auth/updateScore', {
method: 'POST',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/game/auth/updateUserInfo */
export async function updateUserInfo(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.updateUserInfoParams,
options?: { [key: string]: any },
) {
return request<API.RVoid>('/api/game/auth/updateUserInfo', {
method: 'POST',
params: {
...params,
},
...(options || {}),
});
}

170
src/services/matrix/matrixAppConfigController.ts

@ -0,0 +1,170 @@
// @ts-ignore
/* eslint-disable */
import { request } from '@umijs/max';
/** 此处后端没有提供注释 GET /api/admin/app/aliPayConfig */
export async function getAliPayConfig(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.getAliPayConfigParams,
options?: { [key: string]: any },
) {
return request<API.RAliPayConfigBo>('/api/admin/app/aliPayConfig', {
method: 'GET',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/admin/app/aliPayConfig */
export async function saveAliPayConfig(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.saveAliPayConfigParams,
body: API.AliPayConfigBo,
options?: { [key: string]: any },
) {
return request<API.RVoid>('/api/admin/app/aliPayConfig', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
params: {
...params,
},
data: body,
...(options || {}),
});
}
/** 此处后端没有提供注释 GET /api/admin/app/basicConfig */
export async function getBasicConfig(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.getBasicConfigParams,
options?: { [key: string]: any },
) {
return request<API.RAppBasicConfig>('/api/admin/app/basicConfig', {
method: 'GET',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/admin/app/basicConfig */
export async function saveBasicConfig(body: API.AppBasicConfig, options?: { [key: string]: any }) {
return request<API.RVoid>('/api/admin/app/basicConfig', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** 此处后端没有提供注释 GET /api/admin/app/normalConfig */
export async function getAppNormalConfig(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.getAppNormalConfigParams,
options?: { [key: string]: any },
) {
return request<API.RAppNormalConfig>('/api/admin/app/normalConfig', {
method: 'GET',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/admin/app/normalConfig */
export async function saveNormalConfig(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.saveNormalConfigParams,
body: API.AppNormalConfig,
options?: { [key: string]: any },
) {
return request<API.RVoid>('/api/admin/app/normalConfig', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
params: {
...params,
},
data: body,
...(options || {}),
});
}
/** 此处后端没有提供注释 GET /api/admin/app/uMengConfig */
export async function getUMengConfig(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.getUMengConfigParams,
options?: { [key: string]: any },
) {
return request<API.RUmengConfigBo>('/api/admin/app/uMengConfig', {
method: 'GET',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/admin/app/uMengConfig */
export async function saveUMengConfig(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.saveUMengConfigParams,
body: API.UmengConfigBo,
options?: { [key: string]: any },
) {
return request<API.RVoid>('/api/admin/app/uMengConfig', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
params: {
...params,
},
data: body,
...(options || {}),
});
}
/** 此处后端没有提供注释 GET /api/admin/app/wxConfig */
export async function getWxConfig(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.getWxConfigParams,
options?: { [key: string]: any },
) {
return request<API.RWxConfig>('/api/admin/app/wxConfig', {
method: 'GET',
params: {
...params,
},
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/admin/app/wxConfig */
export async function saveWxConfig(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.saveWxConfigParams,
body: API.WxConfig,
options?: { [key: string]: any },
) {
return request<API.RVoid>('/api/admin/app/wxConfig', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
params: {
...params,
},
data: body,
...(options || {}),
});
}

18
src/services/matrix/matrixController.ts

@ -1,18 +0,0 @@
// @ts-ignore
/* eslint-disable */
import { request } from '@umijs/max';
/** 此处后端没有提供注释 POST /api/game/matrix/saveAdvRecord */
export async function saveAdvRecord(
body: API.MatrixAdvRecordEditBo,
options?: { [key: string]: any },
) {
return request<API.RVoid>('/api/game/matrix/saveAdvRecord', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}

27
src/services/matrix/matrixMoneyController.ts

@ -0,0 +1,27 @@
// @ts-ignore
/* eslint-disable */
import { request } from '@umijs/max';
/** 此处后端没有提供注释 POST /api/admin/money/audit */
export async function audit(body: API.MoneyBo, options?: { [key: string]: any }) {
return request<API.RVoid>('/api/admin/money/audit', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** 此处后端没有提供注释 POST /api/admin/money/list */
export async function moneyApplyList(body: API.MoneyQuery, options?: { [key: string]: any }) {
return request<API.RPageResultMoneyBo>('/api/admin/money/list', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}

15
src/services/matrix/matrixUserController.ts

@ -0,0 +1,15 @@
// @ts-ignore
/* eslint-disable */
import { request } from '@umijs/max';
/** 此处后端没有提供注释 POST /api/admin/user/list */
export async function list(body: API.UserQuery, options?: { [key: string]: any }) {
return request<API.RPageResultUserBo>('/api/admin/user/list', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}

420
src/services/matrix/typings.d.ts

@ -1,4 +1,15 @@
declare namespace API {
type AddMockScheduleReq = {
appId?: number[];
incomeYuan?: number;
scheduleTime?: number[];
};
type addWhiteListParams = {
deviceId: string;
channel: string;
};
type adminLoginParams = {
name: string;
pwd: string;
@ -10,56 +21,141 @@ declare namespace API {
advType?: number;
platform?: number;
deviceId?: string;
code?: string;
createdAt?: string[];
adminId?: number;
};
type AppInfo = {
type AliPayConfigBo = {
aliPayPublicCert?: string;
aliPayRootCert?: string;
aliPayAppCert?: string;
aliPayPrivateKey?: string;
aliPayAppId?: string;
};
type AppBasicConfig = {
id?: number;
code?: string;
secret?: string;
name?: string;
icon?: string;
appId?: string;
inAudit?: number;
recommend?: AppInfo[];
img?: string;
url?: string;
hide?: number;
channel?: string;
version?: number;
};
type CurrentUser = {
avatarUrl?: string;
nickName?: string;
score?: number;
openId?: string;
type AppNormalConfig = {
moneyLadder?: number[];
noAuditMoney?: number;
qqUrl?: string;
dayLimit?: number;
maxIncomeEachVideo?: number;
dayRates?: DayRate[];
defaultRate?: number;
};
type getAppInfoParams = {
appId?: string;
type calcParams = {
date: number;
};
type InviteInfo = {
inviteCnt?: number;
list?: InviteUserInfo[];
type changeAdminHideParams = {
adminId: number;
hide: number;
};
type InviteUserInfo = {
avatarUrl?: string;
nickName?: string;
score?: number;
nextTime?: number;
type DateIncome = {
date?: number;
income?: number;
};
type LoginBo = {
jwtToken?: string;
inviteCode?: string;
signature?: string;
type DayRate = {
day?: number;
rate?: number;
};
type deleteWhiteListParams = {
deviceId: string;
};
type deviceListParams = {
appCode: string;
};
type getAliPayConfigParams = {
appCode: string;
};
type LoginReq = {
type getAppNormalConfigParams = {
appCode: string;
};
type getBasicConfigParams = {
appCode: string;
};
type getUMengConfigParams = {
appCode: string;
};
type getWxConfigParams = {
appCode: string;
};
type grantAppParams = {
appIds: string;
adminId: number;
};
type incomeOverview1Params = {
appCode?: string;
};
type incomeOverviewParams = {
appCode?: string;
};
type IncomeQuery = {
code?: string;
appId?: string;
inviteCode?: string;
rawData?: string;
platform?: number;
advType?: number;
date?: string[];
};
type MatrixAdmin = {
id?: number;
name?: string;
password?: string;
appIds?: string;
role?: number;
channel?: string;
parentAdminId?: number;
deviceCnt?: number;
incomeRate?: number;
hide?: number;
};
type MatrixAdminBo = {
id?: number;
name?: string;
password?: string;
appIds?: number[];
hide?: number;
role?: number;
deviceCnt?: number;
incomeRate?: number;
overview?: OverviewBo;
};
type MatrixAdminDevice = {
id?: number;
deviceId?: string;
appId?: number;
adminId?: number;
status?: number;
createdAt?: string;
updatedAt?: string;
};
type MatrixAdvRecordBo = {
@ -71,62 +167,183 @@ declare namespace API {
deviceBrand?: string;
deviceName?: string;
ip?: string;
advId?: number;
sign?: string;
timestamp?: number;
appName?: string;
appId?: number;
createdAt?: number;
id?: number;
user?: UserBo;
adminName?: string;
};
type MatrixApp = {
id?: number;
name?: string;
code?: string;
img?: string;
url?: string;
income?: number;
channel?: string;
hide?: number;
secret?: string;
version?: number;
umeng?: string;
aliPay?: string;
wx?: string;
moneyLadder?: string;
noAuditMoney?: number;
qqUrl?: string;
dayLimit?: number;
maxIncomeEachVideo?: number;
dayRates?: string;
defaultRate?: number;
};
type MatrixAppBo = {
id?: number;
name?: string;
code?: string;
img?: string;
url?: string;
channel?: string;
hide?: number;
secret?: string;
enableCash?: boolean;
};
type MatrixAdvRecordEditBo = {
type MatrixMockSchedule = {
id?: number;
appId?: number;
channel?: string;
incomeYuan?: number;
mockIncome?: number;
status?: number;
scheduleTime?: string;
createdAt?: string;
updatedAt?: string;
};
type MatrixWhiteDevice = {
id?: number;
deviceId?: string;
channel?: string;
createdAt?: string;
};
type mockParams = {
start: number;
end: number;
};
type MoneyBo = {
user?: UserBo;
id?: number;
cent?: number;
aliPayAccount?: string;
name?: string;
reason?: string;
orderId?: string;
payFundOrderId?: string;
transDate?: string;
status?: number;
createdAt?: number;
};
type MoneyQuery = {
current?: number;
pageSize?: number;
appCode?: string;
platform?: number;
advType?: number;
ecpm?: number;
deviceBrand?: string;
deviceName?: string;
ip?: string;
status?: number;
};
type offlineParams = {
deviceId: string;
};
type onlineParams = {
deviceId: string;
};
type OverviewBo = {
todayIncome?: number;
totalIncome?: number;
yesterdayIncome?: number;
lastMonthIncome?: number;
thisMonthIncome?: number;
};
type PageResultMatrixAdvRecordBo = {
data?: MatrixAdvRecordBo[];
total?: number;
sum?: number;
};
type PageResultMoneyBo = {
data?: MoneyBo[];
total?: number;
sum?: number;
};
type PageResultUserBo = {
data?: UserBo[];
total?: number;
sum?: number;
};
type RAliPayConfigBo = {
code?: number;
message?: string;
data?: AliPayConfigBo;
};
type RAppBasicConfig = {
code?: number;
message?: string;
data?: AppBasicConfig;
};
type RankList = {
list?: UserInfo[];
myRank?: string;
myScore?: number;
myAvatarUrl?: string;
myNickName?: string;
type RAppNormalConfig = {
code?: number;
message?: string;
data?: AppNormalConfig;
};
type rankListParams = {
size: number;
type RListDateIncome = {
code?: number;
message?: string;
data?: DateIncome[];
};
type RListMatrixAdminBo = {
code?: number;
message?: string;
data?: MatrixAdminBo[];
};
type RAppInfo = {
type RListMatrixAdminDevice = {
code?: number;
message?: string;
data?: AppInfo;
data?: MatrixAdminDevice[];
};
type RCurrentUser = {
type RListMatrixAppBo = {
code?: number;
message?: string;
data?: CurrentUser;
data?: MatrixAppBo[];
};
type RInviteInfo = {
type RListMatrixMockSchedule = {
code?: number;
message?: string;
data?: InviteInfo;
data?: MatrixMockSchedule[];
};
type RLoginBo = {
type RListMatrixWhiteDevice = {
code?: number;
message?: string;
data?: LoginBo;
data?: MatrixWhiteDevice[];
};
type RMatrixAdmin = {
@ -135,16 +352,28 @@ declare namespace API {
data?: MatrixAdmin;
};
type ROverviewBo = {
code?: number;
message?: string;
data?: OverviewBo;
};
type RPageResultMatrixAdvRecordBo = {
code?: number;
message?: string;
data?: PageResultMatrixAdvRecordBo;
};
type RRankList = {
type RPageResultMoneyBo = {
code?: number;
message?: string;
data?: RankList;
data?: PageResultMoneyBo;
};
type RPageResultUserBo = {
code?: number;
message?: string;
data?: PageResultUserBo;
};
type RString = {
@ -153,36 +382,89 @@ declare namespace API {
data?: string;
};
type RSTSInfo = {
code?: number;
message?: string;
data?: STSInfo;
};
type RUmengConfigBo = {
code?: number;
message?: string;
data?: UmengConfigBo;
};
type RVoid = {
code?: number;
message?: string;
data?: Record<string, any>;
};
type updateScoreParams = {
score: number;
type RWxConfig = {
code?: number;
message?: string;
data?: WxConfig;
};
type updateUserInfoParams = {
rawData: string;
signature: string;
type saveAliPayConfigParams = {
appCode: string;
};
type UserInfo = {
avatarUrl?: string;
nickName?: string;
score?: number;
type saveNormalConfigParams = {
appCode: string;
};
type wxLoginParams = {
code: string;
appId: string;
type saveUMengConfigParams = {
appCode: string;
};
type wxLoginV2Params = {
code: string;
appId: string;
type saveWxConfigParams = {
appCode: string;
};
type STSInfo = {
securityToken?: string;
expiration?: string;
accessKeySecret?: string;
accessKeyId?: string;
stsRole?: string;
bucket?: string;
endpoint?: string;
};
type UmengConfigBo = {
umengAppKeyAli?: string;
umengAppSecret?: string;
umengAppCode?: string;
umengAppKey?: string;
linkId?: string;
bindWx?: boolean;
};
type UserBo = {
id?: number;
mobile?: string;
name?: string;
nickname?: string;
avatar?: string;
money?: number;
aliPayAccount?: string;
income?: number;
goldCoin?: number;
inviteCode?: string;
rawData?: string;
inviteUrl?: string;
wxOpenId?: string;
createdAt?: number;
};
type UserQuery = {
current?: number;
pageSize?: number;
appCode?: string;
};
type WxConfig = {
appId?: string;
appSecret?: string;
};
}

Loading…
Cancel
Save