Browse Source

游戏管理后台首次提交

master
fycode_ZF_Client 9 months ago
parent
commit
afaa7417c4
  1. 3
      backmanage/.env.pro
  2. 122
      backmanage/.gitignore
  3. 373
      backmanage/LICENSE
  4. 111
      backmanage/index.html
  5. 8973
      backmanage/package-lock.json
  6. 53
      backmanage/package.json
  7. 1
      backmanage/public/vite.svg
  8. 50
      backmanage/src/App.vue
  9. 129
      backmanage/src/api/config/index.ts
  10. 63
      backmanage/src/api/helper/axiosCancel.ts
  11. 116
      backmanage/src/api/helper/checkCode.ts
  12. 16
      backmanage/src/api/index.ts
  13. 24
      backmanage/src/api/module/auth.ts
  14. 58
      backmanage/src/api/module/carrier_list.ts
  15. 73
      backmanage/src/api/module/channel_promotion.ts
  16. 21
      backmanage/src/api/module/channel_promotion_detail.ts
  17. 54
      backmanage/src/api/module/channel_promotion_of_day.ts
  18. 12
      backmanage/src/api/module/common.ts
  19. 30
      backmanage/src/api/module/common_params.ts
  20. 55
      backmanage/src/api/module/email_info.ts
  21. 22
      backmanage/src/api/module/event_detail.ts
  22. 64
      backmanage/src/api/module/exchange_order.ts
  23. 39
      backmanage/src/api/module/game.ts
  24. 57
      backmanage/src/api/module/game_blood.ts
  25. 21
      backmanage/src/api/module/game_etrance.ts
  26. 32
      backmanage/src/api/module/game_hell.ts
  27. 38
      backmanage/src/api/module/game_maintain.ts
  28. 67
      backmanage/src/api/module/game_new.ts
  29. 33
      backmanage/src/api/module/game_notice.ts
  30. 39
      backmanage/src/api/module/goods.ts
  31. 24
      backmanage/src/api/module/hall_skin.ts
  32. 42
      backmanage/src/api/module/land_page.ts
  33. 41
      backmanage/src/api/module/menu.ts
  34. 48
      backmanage/src/api/module/payment_channel.ts
  35. 59
      backmanage/src/api/module/permission.ts
  36. 53
      backmanage/src/api/module/recharge_order.ts
  37. 15
      backmanage/src/api/module/register_gold.ts
  38. 26
      backmanage/src/api/module/short_msg.ts
  39. 68
      backmanage/src/api/module/statistics_daily_game.ts
  40. 21
      backmanage/src/api/module/statistics_day_data.ts
  41. 16
      backmanage/src/api/module/statistics_hour_data.ts
  42. 15
      backmanage/src/api/module/statistics_user_online.ts
  43. 71
      backmanage/src/api/module/sub_carrier.ts
  44. 21
      backmanage/src/api/module/sys_dep.ts
  45. 26
      backmanage/src/api/module/sys_role.ts
  46. 40
      backmanage/src/api/module/sys_user.ts
  47. 35
      backmanage/src/api/module/user_agent.ts
  48. 35
      backmanage/src/api/module/user_agent_info.ts
  49. 23
      backmanage/src/api/module/user_online.ts
  50. 14
      backmanage/src/api/module/verification_code.ts
  51. 40
      backmanage/src/api/module/vip_level_config.ts
  52. 24
      backmanage/src/api/module/withdraw_plat.ts
  53. 45
      backmanage/src/api/module/withdraw_platform_type.ts
  54. BIN
      backmanage/src/assets/icons/img_chaijin.png
  55. BIN
      backmanage/src/assets/icons/img_chongzhitixian.png
  56. BIN
      backmanage/src/assets/icons/img_huiyuan.png
  57. BIN
      backmanage/src/assets/icons/img_jinritouzhu.png
  58. BIN
      backmanage/src/assets/icons/img_jinrixinzeng.png
  59. BIN
      backmanage/src/assets/icons/language.png
  60. BIN
      backmanage/src/assets/icons/size.png
  61. BIN
      backmanage/src/assets/img/404.png
  62. BIN
      backmanage/src/assets/img/bg_denglu.webp
  63. BIN
      backmanage/src/assets/img/welcome.png
  64. 303
      backmanage/src/assets/json/menu.json
  65. 1
      backmanage/src/assets/vue.svg
  66. 16
      backmanage/src/components/common/CustomPaginate.vue
  67. 5
      backmanage/src/components/global/m_count_to/index.ts
  68. 110
      backmanage/src/components/global/m_count_to/src/m_count_to.vue
  69. 7
      backmanage/src/components/global/m_dialog/index.ts
  70. 72
      backmanage/src/components/global/m_dialog/src/dialog.vue
  71. 3
      backmanage/src/components/global/m_dialog/src/type.ts
  72. 7
      backmanage/src/components/global/m_drawer/index.ts
  73. 80
      backmanage/src/components/global/m_drawer/src/drawer.vue
  74. 3
      backmanage/src/components/global/m_drawer/src/type.ts
  75. 5
      backmanage/src/components/global/m_echarts/index.ts
  76. 36
      backmanage/src/components/global/m_echarts/src/m_echarts.vue
  77. 9
      backmanage/src/components/global/m_form/index.ts
  78. 126
      backmanage/src/components/global/m_form/src/m_form.vue
  79. 65
      backmanage/src/components/global/m_form/src/m_form_item.vue
  80. 31
      backmanage/src/components/global/m_form/src/render.tsx
  81. 104
      backmanage/src/components/global/m_form/src/type.ts
  82. 14
      backmanage/src/components/global/m_form/src/utils.ts
  83. 5
      backmanage/src/components/global/m_icon/index.ts
  84. 5
      backmanage/src/components/global/m_icon/src/const.ts
  85. 43
      backmanage/src/components/global/m_icon/src/m_icon.vue
  86. 7
      backmanage/src/components/global/m_page/index.ts
  87. 50
      backmanage/src/components/global/m_page/src/page.vue
  88. 14
      backmanage/src/components/global/m_page/src/type.ts
  89. 9
      backmanage/src/components/global/m_pagination/index.ts
  90. 29
      backmanage/src/components/global/m_pagination/src/hooks/index.ts
  91. 73
      backmanage/src/components/global/m_pagination/src/m_pagination.vue
  92. 18
      backmanage/src/components/global/m_pagination/src/type.ts
  93. 7
      backmanage/src/components/global/m_radio/index.ts
  94. 11
      backmanage/src/components/global/m_radio/src/m_radio.vue
  95. 1
      backmanage/src/components/global/m_radio/src/type.ts
  96. 7
      backmanage/src/components/global/m_select/index.ts
  97. 37
      backmanage/src/components/global/m_select/src/hooks/useSelection.ts
  98. 87
      backmanage/src/components/global/m_select/src/m_select.vue
  99. 33
      backmanage/src/components/global/m_select/src/type.ts
  100. 11
      backmanage/src/components/global/m_table/index.ts

3
backmanage/.env.pro

@ -0,0 +1,3 @@
VITE_API = http://65.2.141.248:8090
VITE_TITLE = Victory总后台

122
backmanage/.gitignore

@ -0,0 +1,122 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
<<<<<<< HEAD
=======
.pnpm-debug.log*
>>>>>>> e0b71883837c085fe8b4b8b613e7839bb9467379
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
<<<<<<< HEAD
# TypeScript v1 declaration files
typings/
=======
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
>>>>>>> e0b71883837c085fe8b4b8b613e7839bb9467379
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
<<<<<<< HEAD
=======
# Optional stylelint cache
.stylelintcache
>>>>>>> e0b71883837c085fe8b4b8b613e7839bb9467379
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
#ide setting config file
.vscode/

373
backmanage/LICENSE

@ -0,0 +1,373 @@
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

111
backmanage/index.html

@ -0,0 +1,111 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><%- title %></title>
<!-- <style>
* {
padding: 0;
margin: 0;
}
html, body {
overflow: hidden;
height: 100vh;
}
body {
display: flex;
background: url("./imgs/图2.jpg") no-repeat center center/ cover;
}
.login-form {
margin: auto;
padding: 20px;
border-radius: 5px;
border: 1px solid #000;
}
</style> -->
</head>
<body>
<div id="app">
<style>
.loading-box {
position: fixed;
top: 0;
left: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.loading-box .loading-wrap {
display: flex;
align-items: center;
justify-content: center;
padding: 98px;
}
.dot {
position: relative;
box-sizing: border-box;
display: inline-block;
width: 32px;
height: 32px;
font-size: 32px;
transform: rotate(45deg);
animation: ant-rotate 1.2s infinite linear;
}
.dot i {
position: absolute;
display: block;
width: 14px;
height: 14px;
background-color: #409eff;
border-radius: 100%;
opacity: 0.3;
transform: scale(0.75);
transform-origin: 50% 50%;
animation: ant-spin-move 1s infinite linear alternate;
}
.dot i:nth-child(1) {
top: 0;
left: 0;
}
.dot i:nth-child(2) {
top: 0;
right: 0;
animation-delay: 0.4s;
}
.dot i:nth-child(3) {
right: 0;
bottom: 0;
animation-delay: 0.8s;
}
.dot i:nth-child(4) {
bottom: 0;
left: 0;
animation-delay: 1.2s;
}
@keyframes ant-rotate {
to {
transform: rotate(405deg);
}
}
@keyframes ant-spin-move {
to {
opacity: 1;
}
}
</style>
<div class="loading-box">
<div class="loading-wrap">
<span class="dot dot-spin"><i></i><i></i><i></i><i></i></span>
</div>
</div>
</div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

8973
backmanage/package-lock.json

File diff suppressed because it is too large

53
backmanage/package.json

@ -0,0 +1,53 @@
{
"name": "mimetic-admin",
"private": true,
"version": "0.0.5",
"type": "module",
"scripts": {
"dev": "vue-tsc --noEmit && vite",
"test": "vue-tsc --noEmit && vite --mode test",
"pro": "vue-tsc --noEmit && vite --mode pro",
"build": "vite build --mode pro",
"build:test": "vite build --mode test",
"preview": "vite preview"
},
"dependencies": {
"@vueuse/components": "^10.2.1",
"@vueuse/core": "^10.1.2",
"axios": "^1.4.0",
"decimal.js": "^10.4.3",
"echarts": "^5.4.2",
"element-plus": "^2.3.14",
"lodash": "^4.17.21",
"moment": "^2.29.4",
"nprogress": "^0.2.0",
"pinia": "^2.1.3",
"pinia-plugin-persistedstate": "^3.1.0",
"qs": "^6.11.2",
"swiper": "^10.3.1",
"table-excel": "^2.0.4",
"vue": "^3.3.4",
"vue-i18n": "^9.2.2",
"vue-router": "^4.2.1",
"x2js": "^3.4.4",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@types/file-saver": "^2.0.5",
"@types/node": "^20.2.5",
"@types/nprogress": "^0.2.0",
"@types/qs": "^6.9.7",
"@vitejs/plugin-vue": "^4.2.3",
"@vitejs/plugin-vue-jsx": "^3.0.1",
"less": "^4.1.3",
"rollup-plugin-visualizer": "^5.9.2",
"svgo": "^3.0.2",
"typescript": "^5.0.4",
"vite": "^4.3.9",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-html": "^3.2.0",
"vite-plugin-image-optimizer": "^1.1.7",
"vite-plugin-top-level-await": "^1.3.1",
"vue-tsc": "^1.6.5"
}
}

1
backmanage/public/vite.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

50
backmanage/src/App.vue

@ -0,0 +1,50 @@
<script setup lang="ts">
import { ElConfigProvider } from "element-plus";
import zh from "element-plus/es/locale/lang/zh-cn";
import en from "element-plus/es/locale/lang/en";
import { useEventListener } from "@vueuse/core";
import { useGlobalStore } from "@/store/modules/global";
import { useMenuStore } from "@/store/modules/menu";
import { computed, onMounted } from "vue";
import { useRoute } from "vue-router";
import debounce from "lodash/debounce";
import request from "@/api/config";
const $global = useGlobalStore();
const $menu = useMenuStore();
const $route = useRoute();
const locale = computed(() => {
const langs: Record<string, any> = {
zh,
en,
};
return langs[$global.language] || langs["zh"];
});
useEventListener(
"resize",
debounce(() => {
const w = document.documentElement.offsetWidth;
if (w > 768) return;
$menu.setCollapse(true);
}, 300)
);
onMounted(() => {
const { base } = $route.query as { base: string };
base && (request.service.defaults.baseURL = base);
});
</script>
<template>
<el-config-provider :z-index="2000" :locale="locale" :size="$global.size">
<router-view></router-view>
</el-config-provider>
</template>
<style></style>

129
backmanage/src/api/config/index.ts

@ -0,0 +1,129 @@
import axios, {
AxiosInstance,
AxiosError,
AxiosRequestConfig,
AxiosResponse,
} from "axios";
import { ElMessage } from "element-plus";
import { AxiosCanceler } from "../helper/axiosCancel";
import { checkCode } from "../helper/checkCode";
import { useGlobalStore } from "@/store/modules/global";
import { useMenuStore } from "@/store/modules/menu";
import { isFunction } from "@/utils/is";
import $router from "@/config/router";
const axiosCancel = new AxiosCanceler();
const config = {
timeout: 15000,
baseURL: import.meta.env.VITE_API,
// 跨域时候允许携带凭证
// withCredentials: true,
};
class HttpRequest {
service: AxiosInstance;
constructor(config: AxiosRequestConfig) {
this.service = axios.create(config);
this.service.interceptors.request.use(
(config) => {
const { token, language } = useGlobalStore();
axiosCancel.addPending(config);
if (isFunction(config.headers.set)) {
token && config.headers.set("Authorization", "Bearer " + token);
language && config.headers.set("Accept-Language", language);
}
return config;
},
(error: AxiosError) => {
return Promise.reject(error);
}
);
/**
* @description
* -> [] -> JS获取到信息
*/
this.service.interceptors.response.use(
(response: AxiosResponse) => {
const { data, config } = response;
const $global = useGlobalStore();
const $menu = useMenuStore();
axiosCancel.removePending(config);
const { code } = data;
console.log(data);
if (!code) return data;
ElMessage.warning(checkCode(code, "API"));
if ([1000, 1001].includes(code)) {
axiosCancel.removeAllPending();
$global.setToken("");
$menu.resetMenuTag();
$router.replace("/login");
}
return Promise.reject(data);
},
async (error: AxiosError) => {
console.log(error, "error");
const { response } = error;
if (error.message.indexOf("timeout") !== -1)
ElMessage.error("请求超时!请您稍后重试");
if (error.message.indexOf("Network Error") !== -1)
ElMessage.error("网络错误!请您稍后重试");
if (response) ElMessage.error(checkCode(response.status));
return Promise.reject(error);
}
);
}
send<T>(config: AxiosRequestConfig = {}): Promise<ResultData<T>> {
return this.service(config);
}
get<T>(
url: string,
params?: any,
_object: AxiosRequestConfig = {}
): Promise<ResultData<T>> {
return this.service.get(url, { params, ..._object });
}
post<T>(
url: string,
params?: any,
_object: AxiosRequestConfig = {}
): Promise<ResultData<T>> {
return this.service.post(url, params, _object);
}
put<T>(
url: string,
params?: any,
_object: AxiosRequestConfig = {}
): Promise<ResultData<T>> {
return this.service.put(url, params, _object);
}
delete<T>(
url: string,
params?: any,
_object: AxiosRequestConfig = {}
): Promise<ResultData<T>> {
// return this.service.delete(url, { params, ..._object });
return this.service({ method: "delete", url, data: params, ..._object });
}
download(url: string, params?: object, _object = {}): Promise<BlobPart> {
return this.service.post(url, params, { ..._object, responseType: "blob" });
}
}
export default new HttpRequest(config);

63
backmanage/src/api/helper/axiosCancel.ts

@ -0,0 +1,63 @@
import axios, { AxiosRequestConfig, Canceler } from "axios";
import { isFunction } from "@/utils/is/index";
import qs from "qs"
// * 声明一个 Map 用于存储每个请求的标识 和 取消函数
let pendingMap = new Map<string, Canceler>();
// * 序列化参数
export const getPendingUrl = (config: AxiosRequestConfig) =>
[config.method, config.url, qs.stringify(config.data), qs.stringify(config.params)].join("&");
export class AxiosCanceler {
/**
* @description:
* @param {Object} config
* @return void
*/
addPending(config: AxiosRequestConfig) {
// * 在请求开始前,对之前的请求做检查取消操作
this.removePending(config);
const url = getPendingUrl(config);
config.cancelToken =
config.cancelToken ||
new axios.CancelToken(cancel => {
if (!pendingMap.has(url)) {
// 如果 pending 中不存在当前请求,则添加进去
pendingMap.set(url, cancel);
}
});
}
/**
* @description:
* @param {Object} config
*/
removePending(config: AxiosRequestConfig) {
const url = getPendingUrl(config);
if (pendingMap.has(url)) {
// 如果在 pending 中存在当前请求标识,需要取消当前请求,并且移除
const cancel = pendingMap.get(url);
cancel && cancel();
pendingMap.delete(url);
}
}
/**
* @description: pending
*/
removeAllPending() {
pendingMap.forEach(cancel => {
cancel && isFunction(cancel) && cancel();
});
pendingMap.clear();
}
/**
* @description:
*/
reset(): void {
pendingMap = new Map<string, Canceler>();
}
}

116
backmanage/src/api/helper/checkCode.ts

@ -0,0 +1,116 @@
const ERR_CODE: Record<string, string> = {
400: "请求失败!请稍后重试",
401: "登录过期!",
403: "无权限访问",
404: "资源不存在",
408: "请求超时!请您稍后再试",
500: "服务异常!",
502: "网关错误!",
503: "服务不可用!",
504: "网关超时!",
};
const API_CODE: Record<string, string> = {
1: "请求被取消",
2: "未知错误",
3: "无效参数",
4: "请求超时",
5: "未找到资源",
6: "内部错误",
7: "未授权",
8: "非法调用",
9: "非法请求",
1000: "授权已过期",
1001: "异地登录",
91: "菜单不存在",
92: "菜单已存在",
93: "权限不存在",
94: "权限已存在",
95: "角色不存在",
96: "暂无权限",
97: "无效的系统配置",
98: "非法操作",
99: "服务器已关闭",
100: "服务器维护中",
101: "账号已存在",
102: "账号不存在",
103: "账号已禁用",
104: "账号非法",
105: "无可用的网关服务器",
106: "账号或密码错误",
107: "已经参与过",
108: "机器人数量不足",
109: "资产不足",
110: "钻石不足",
111: "验证码已过期",
112: "验证码不匹配",
114: "金币低于入场限制",
115: "金币高于入场限制",
116: "房间已满",
117: "房间已空",
118: "没有可匹配的房间",
119: "没有可匹配的牌桌",
120: "牌桌已满",
121: "牌桌已空",
122: "座位已空",
123: "玩家已离线",
124: "玩家已经坐下",
125: "玩家不在座位上",
126: "玩家不在游戏中",
127: "玩家不在观战中",
128: "玩家正在游戏中",
129: "玩家正在观战中",
130: "座位已被占",
131: "不能创建牌桌",
132: "不能销毁牌桌",
133: "未发现房间",
134: "未发现牌桌",
135: "不允许观战",
136: "未初始化底池",
137: "未配置",
138: "无免费游戏",
139: "有免费游戏",
140: "无bonus游戏",
141: "有bonus游戏",
142: "无地小游戏",
143: "有地小游戏",
144: "下注信息错误",
145: "游戏已经存在",
146: "游戏不存在",
147: "游戏已关闭",
148: "游戏维护中",
149: "游戏维护中",
150: "房间已关闭",
300: "支付渠道未接入",
301: "当前充值频率过快,请稍后再试",
302: "非法充值请求",
303: "充值金额错误",
304: "无效充值类型",
305: "支付渠道繁忙,请稍后下单",
306: "支付渠道异常,请联系客服!",
307: "当前无可用渠道",
308: "无效订单",
309: "请填写付款人账号/卡号/姓名",
310: "限制用户充值",
311: "提现重复订单",
312: "提现有一笔订单未完成订单",
313: "提现金额低于下限",
314: "提现金额超出上限",
315: "该玩家产生的流水未达到提现要求",
316: "当日提现次数已达上限",
317: "提款账号未绑定",
401: "账号管理不能选择【渠道商】角色",
400: "渠道角色不存在",
501: "没有找到该代理级别的上级代理,请按照级别顺序添加数据",
503: "该代理级别的分成必须小于上级分成的百分之五(零除外)",
504: "该代理级别的分成必须大于下级分成的百分之五(零除外)",
505: "该代理有下级代理不能删除,不能操作",
};
export function checkCode(code: number, code_type: "API" | "ERROR" = "ERROR") {
const error_code = `(error_code: ${code})`;
if (code_type === "API") return API_CODE[code] || "未知错误!" + error_code;
return ERR_CODE[code] || "未知错误!" + error_code;
}

16
backmanage/src/api/index.ts

@ -0,0 +1,16 @@
export * as COMMON from "./module/common";
export * as AUTH from "./module/auth";
export * as SYSDEP from "./module/sys_dep";
export * as SYSROLE from "./module/sys_role";
export * as SYSUSER from "./module/sys_user";
export * as CARRIER from "./module/carrier_list";
export * as SUBCARRIER from "./module/sub_carrier";
export * as HALLSKIN from "./module/hall_skin";
export * as GAMEMAINTAIN from "./module/game_maintain";
export * as GAME from "./module/game";
export * as GAMEBLOOD from "./module/game_blood";
export * as LANDPAGE from "./module/land_page";
export * as GAMEENTRANCE from "./module/game_etrance";
export * as MENU from "./module/menu";
export * as PERMISSION from "./module/permission";
export * as SHORT_MSG from "./module/short_msg";

24
backmanage/src/api/module/auth.ts

@ -0,0 +1,24 @@
import request from "../config";
import MENU_LIST from "@/assets/json/menu.json";
export const verify = () => {};
// 登录
export const login = (payload: Auth.LoginDTO) => {
return request.post<Auth.LoginVO>("/login", payload);
};
// 退出
export const logOut = () => {
return request.post("/sysUser/jsonInBlacklist");
};
// 获取权限列表
export const getPermission = () => {
return request.get<Permission.PermissionVO>("/sysUser/getPermissions");
};
export const getAuthMenu = async () => {
return MENU_LIST as Menu.MenuOptions[];
};

58
backmanage/src/api/module/carrier_list.ts

@ -0,0 +1,58 @@
import request from "../config";
// 运营商列表
export function getList(payload?: Carrier.SearchParamDTO) {
return request.post<Carrier.SearchParamVO>(
"/agent/fetch-agent-list",
payload
);
}
// 币种列表
export function getCurrencyList(palyoad: Currency.SearchParamDTO) {
return request.post<Currency.SearchParamVO>(
"/currency/currencyList",
palyoad
);
}
// 菜单列表
export function getCarrierMenu(palyoad: { id: number }) {
return request.post<SysRole.RoleMenuList>(
"/currency/getCarrierMenu",
palyoad
);
}
// 运营商权限设置
export function createCarrierPermissions(
palyoad: Carrier.CarrierPermissionDTO
) {
return request.post("/currency/createSubCarrierPermissions", palyoad);
}
// 创建运营商
export function createCarrier(palyoad: Carrier.AddCarrierDTO) {
return request.post("/agent/create-agent", palyoad);
}
// 更新运营商
export function updateCarrier(palyoad: Carrier.UpdateCarrierDTO) {
return request.post("/agent/update-agent", palyoad);
}
// 获取谷歌验证信息
export function getGoogleInfo(payload: { adminID: number }) {
return request.post<SysUser.GetGoogleInfoVO>(
"/agent/fetch-authenticator-qrcode",
payload
);
}
// 刷新谷歌验证信息
export function refreshGoogleInfo(payload: { adminID: number }) {
return request.post<SysUser.GetGoogleInfoVO>(
"/agent/refresh-authenticator-qrcode",
payload
);
}

73
backmanage/src/api/module/channel_promotion.ts

@ -0,0 +1,73 @@
import request from "../config";
export interface IChannelPromotion {
id: string;
/**
*
*/
name: string;
/**
* ID
*/
pixelId: string;
/**
* token
*/
token: string;
/**
* ID
*/
landPageId: number;
/**
*
*/
landUrl: string;
/**
*
*/
downloadNum: number;
/**
*
*/
downloadUrl: string;
/**
*
*/
ifOpen: number;
/**
*
*/
createdAt: string;
/**
* ID
*/
pToken: number;
}
export interface IChannelPromotionList {
list: IChannelPromotion[]
}
// 分页查询
export function fetchPageChannelPromotion(payload: IChannelPromotion) {
return request.post<IChannelPromotion>("/channel/fetch-page-channel-promotion", payload);
}
// 新增渠道推广
export function addChannelPromotion(payload: IChannelPromotion) {
return request.post("/channel/create-channel-promotion", payload);
}
// 更新渠道推广
export function updateChannelPromotion(payload: IChannelPromotion) {
return request.post("/channel/update-channel-promotion", payload);
}
// 删除渠道推广
export function deleteChannelPromotion(payload: IChannelPromotion) {
return request.post("/channel/delete-channel-promotion", payload);
}
// 列表查询
export function fetchChannelPromotions(payload: IChannelPromotion) {
return request.post<IChannelPromotionList>("/channel/fetch-channel-promotions", payload);
}

21
backmanage/src/api/module/channel_promotion_detail.ts

@ -0,0 +1,21 @@
import request from "../config";
export interface IChannelPromotionDetail {
id: number; // 记录ID
cpId: number; // 渠道推广ID
viewNum: number; // 查看数
downloadNum: number; // 下载数
installNum: number; // 安装数
registerNum: number; // 注册数
rechargeNum:number; // 充值次数
rechargeAmount:number; // 充值总额
threePeopleNum:number; // 新增充值人数(3天内)
threePeopleAmount:number; // 新增充值金额(3天内)
morePeopleNum: number; // 新增充值人数(3天外)
morePeopleAmount: number; // 新增充值金额(3天外)
createdAt: string; // 创建时间
}
// 分页查询渠道推广统计数据
export function fetchPageChannelPromotionDetail(payload: IChannelPromotionDetail) {
return request.post<IChannelPromotionDetail>("/channel/fetch-page-channel-promotion-detail", payload);
}

54
backmanage/src/api/module/channel_promotion_of_day.ts

@ -0,0 +1,54 @@
import request from "../config";
export interface IChannelPromotionOfDay {
id: number; // 记录ID
cpId: number; // 渠道推广ID
viewNum: number; // 查看数
viewNumPrice: number; // 查看数-单价
viewNumRate: number; // 查看数-转化比
downloadNum: number; // 下载数
downloadNumPrice: number; // 下载数-单价
downloadNumRate: number; // 下载数-转化比
installNum: number; // 安装数
installNumPrice: number; // 安装数-单价
installNumRate: number; // 安装数-转化比
registerNum: number; // 注册数
registerNumPrice: number; // 注册数-单价
registerNumRate: number; // 注册数-转化比
rechargeNum:number; // 充值次数
rechargeNumPrice:number; // 充值次数-单价
rechargeNumRate:number; // 充值次数-转化比
rechargeAmount:number; // 充值总额
threePeopleNum:number; // 新增充值人数(3天内)
threePeopleAmount:number; // 新增充值金额(3天内)
morePeopleNum: number; // 新增充值人数(3天外)
morePeopleAmount: number; // 新增充值金额(3天外)
createdAt: string; // 创建时间
channelName: string; // 渠道推广名称
channelDay: string; // 渠道推广时间
costMoney: number; // 花费金额
}
// 分页查询渠道推广统计数据-每日
export function fetchPageChannelPromotionOfDay(payload: IChannelPromotionOfDay) {
return request.post<IChannelPromotionOfDay>("/channel/fetch-page-channel-promotion-of-day", payload);
}
// 新增渠道推广花费-每日
export function addChannelPromotionOfDay(payload: IChannelPromotionOfDay) {
return request.post("/channel/create-channel-promotion-cost", payload);
}
// 更新渠道推广花费-每日
export function updateChannelPromotionOfDay(payload: IChannelPromotionOfDay) {
return request.post("/channel/update-channel-promotion-cost", payload);
}
// 分页查询渠道汇总统计数据-每日
export function fetchPageAllChannelPromotionOfDay(payload: IChannelPromotionOfDay) {
return request.post<IChannelPromotionOfDay>("/channel/fetch-page-all-channel-promotion-of-day", payload);
}
// 分页查询渠道汇总统计数据
export function fetchPageChannelPromotionOfAllDay(payload: IChannelPromotionOfDay) {
return request.post<IChannelPromotionOfDay>("/channel/fetch-page-channel-promotion-of-all-day", payload);
}

12
backmanage/src/api/module/common.ts

@ -0,0 +1,12 @@
import request from "../config";
export function uploadFile(payload: FormData) {
return request.post<Upload.ImgVO>("/basic/upload-file", payload, {
headers: { "Content-Type": "application/form-data" },
});
}
export function GameList(params: any = {}) {
return request.post<any>("/person/gameList", params);
}

30
backmanage/src/api/module/common_params.ts

@ -0,0 +1,30 @@
import { GameList } from './common'
export const initPage = {
current: 1,
size: 20,
}
//点控类型
export const optionsPointControl: any[] = [
{ value: 1, label: "1000(小输)" },
{ value: 2, label: "2000(中输)" },
{ value: 3, label: "3000(大输)" },
{ value: 5, label: "-1000(小赢)" },
{ value: 6, label: "-2000(中赢)" },
{ value: 7, label: "-3000(大赢)" },
]
//格式化游戏信息和房间信息
export const GamesRoomsInfo = async () => {
const respond = await GameList()
let games = respond.data
let rooms = {} as any
for (const item of games) {
rooms[item.game_id] = item.rooms_info
}
return [games, rooms] as any
}

55
backmanage/src/api/module/email_info.ts

@ -0,0 +1,55 @@
import request from "../config";
export interface IEmailInfo {
id: number; // 记录ID
title: string; // 邮件标题
agentId: number; // 子运营商id
type: number; // 邮件类型 1群发 2指定玩家
content: string; // 邮件内容
recipient: string; // 收件人 json示例:"[44734983,42689224]"
append: string; // 附件
operatorId?:number; // 操作员
timing:string; // 定时时间
created_at: number; // 创建时间
mailType: number; // 邮件类型 1群发 2指定玩家
}
export interface IEmailInfoDo {
id?: number; // 记录ID
title?: string; // 邮件标题
agentId?: number; // 子运营商id
type?: number; // 邮件类型 1群发 2指定玩家
content?: string; // 邮件内容
recipient?: string; // 收件人 json示例:"[44734983,42689224]"
append?: string; // 附件
operatorId?:number; // 操作员
timing?:string; // 定时时间
}
// 邮件列表
export function getListEmailInfo(payload: IEmailInfo) {
return request.get<IEmailInfo>(
"/email/conf-email-list",
payload
);
}
// 新增邮件
export function createEmailInfo(payload: IEmailInfoDo) {
return request.post("/email/conf-email-create", payload);
}
// 删除邮件
export function delEmailInfo(payload: IEmailInfo) {
return request.post("/email/conf-email-delete", payload);
}
// 更新邮件
export function updateEmailInfo(payload: IEmailInfoDo) {
return request.post("/email/conf-email-update", payload);
}
// 分页查询邮件数据
export function fetchPageEmailInfos(payload: IEmailInfo) {
return request.post<IEmailInfo>("/email/fetch-page-email-infos", payload);
}

22
backmanage/src/api/module/event_detail.ts

@ -0,0 +1,22 @@
import request from "../config";
export interface IEventDetail {
id: number; // 记录ID
eventId: number; // 事件ID
uid: number; // 用户ID
userNo: string; // 用户编号
channelId: number; // 渠道ID
equipmentId: string; // 设备ID
platformId: string; // 平台ID
eventDesc:string; // 事件描述
eventStatus:number; // 事件状态
startAt: string; // 开始时间
endAt: string; // 结束时间
modelName: string; // 模块名称
functionName: string; // 功能名称
eventName: string; // 事件名称
}
// 分页查询事件打点数据
export function fetchPageEventDetails(payload: IEventDetail) {
return request.post<IEventDetail>("/event/fetch-page-event-details", payload);
}

64
backmanage/src/api/module/exchange_order.ts

@ -0,0 +1,64 @@
import request from "../config";
export interface IExchangeOrder {
id: number;
orderNo: string; //订单号
userId: number; //用户ID
agentId: number; //代理Id
payChannelId: number; //支付渠道Id
pfOrderNum: string; //平台订单号
phone: string; //电话
bankNumber: string; //银行卡号
cardHolder: string; //持卡人
bank: string; //银行
ifsc:string; //IFSC
amount: number; //兑换金额
gold: number; //消耗的金币
handCharge: number; //手续费
orderStatus: number; //兑换进度,1:待支付,2:待审合,3:完成关闭,4:已完成5:已退回,6: 支付失败,7,失败关闭,8:待发送
feedback: string; //反馈
money: number; //发送的第三方的钱
msg: string; //三方反馈信息
operator: string; //操作人员
otherInfo: string; //其他信息(json格式)
createdTime: string; //创建时间
endTime: string; //支付完成时间
userNo: string; // 用户编号
callbackInfo: string; // 回调信息
userAsset: number; // 账号余额
rechargeNumTotal: number; // 总充值次数
exchangeNumTotal: number; // 总提现次数
chargeDiff: number; // 充提差
todayFreeNumInfo: string; // 今日免费提现次数信息
todayTotalNumInfo: string; // 今日总提现次数信息
bankFeedback: string; // 银行反馈
exchangeAmount: number; // 兑换金币数
giftAmount: number; // 赠送金币数
channelId: string; // 渠道ID
userName: string; // 用户昵称
taxRate: number; // 税收比例
vipLevel: string; // VIP等级
exchangeIp: string; // 提现IP
exchangeIpNum: number; // 提现IP重复数
loginIpNum: number; // 登录IP重复数
regIpNum: number; // 注册IP重复数
}
// 分页提现订单列表
export function fetchPageExchangeOrders(payload: IExchangeOrder) {
return request.post<IExchangeOrder>("/order/fetch-page-exchange-orders", payload);
}
// 新增提现订单
export function addExchangeOrders(payload: IExchangeOrder) {
return request.post("/order/create-exchange-order", payload);
}
// 更新提现订单
export function updateExchangeOrders(payload: IExchangeOrder) {
return request.post("/order/update-exchange-order", payload);
}
// 删除提现订单
export function deleteExchangeOrders(payload: IExchangeOrder) {
return request.post("/order/delete-exchange-order", payload);
}

39
backmanage/src/api/module/game.ts

@ -0,0 +1,39 @@
import request from "../config";
// 游戏列表
export function getList(payload: Game.SearchParamDTO) {
return request.post<Game.SearchParamVO>("/game/fetch-games", payload);
}
// 新增游戏配置
export function add(payload: Game.AddDTO) {
return request.post("/game/create-game", payload);
}
// 游戏房间列表
export function getGameRoomList(palyoad: { gameID: number }) {
return request.post<BasicListType<Game.GameRoomInfoListType>>(
"/game/fetch-rooms",
palyoad
);
}
// 更新游戏房间
export function updateGameRoom(payload: Game.UpdateGameRoomDTO) {
return request.post("/game/update-rooms", payload);
}
// 更新游戏配置
export function update(payload: Game.SearchParamDTO) {
return request.post("/game/update-game", payload);
}
// 删除游戏配置
export function del(payload: { id: number }) {
return request.post("/game/delete-game", payload);
}
// 更新房间库存
export function updateRoomStock(payload: Game.UpdateRoomStockDTO) {
return request.post("/game/update-room-control-stock", payload);
}

57
backmanage/src/api/module/game_blood.ts

@ -0,0 +1,57 @@
import request from "../config";
export interface IGameBlood {
id: string;
/**
* Id
*/
gameId: number;
/**
*
*/
gameName: string;
/**
* Id
*/
roomId: string;
/**
*
*/
stockNum: number;
/**
*
*/
bloodDesc: string;
turnPointOne: number; // 拐点-1000
turnPointTwo: number; // 拐点-2000
turnPointThree: number; // 拐点-3000
turnPointFour: number; // 拐点1000
turnPointFive: number; // 拐点2000
turnPointSix: number; // 拐点3000
stockConf: string; // 去库存配置
roomGears: string; // 当前档位
}
// 游戏血池列表
export function getGameBloodList(payload: IGameBlood) {
return request.post<IGameBlood>("/game/fetch-game-bloods", payload);
}
// 新增游戏血池配置
export function addGameBlood(payload: IGameBlood) {
return request.post("/game/create-game-blood", payload);
}
// 更新游戏血池
export function updateGameBlood(payload: IGameBlood) {
return request.post("/game/update-game-blood", payload);
}
// 更新游戏血池库存
export function updateGameBloodStock(payload: IGameBlood) {
return request.post("/game/update-game-blood-stock", payload);
}
// 删除游戏血池
export function deleteGameBlood(payload: IGameBlood) {
return request.post("/game/delete-game-blood", payload);
}

21
backmanage/src/api/module/game_etrance.ts

@ -0,0 +1,21 @@
import request from "../config";
// 网关信息
export function getGateway() {
return request.post<BasicListType<string>>("/server/fetch-gates");
}
// 埋点信息
export function getfetchEvent() {
return request.post<BasicListType<string>>("/server/fetch-event-urls");
}
// 更新网关信息
export function updateGateway(payload: { list: string[] }) {
return request.post("/server/update-gates", payload);
}
// 更新埋点信息
export function updatefetchEvent(payload: { list: string[] }) {
return request.post("/server/update-event-urls", payload);
}

32
backmanage/src/api/module/game_hell.ts

@ -0,0 +1,32 @@
import request from "../config";
export interface IGameHell {
id: number; // 记录ID
agentId: number; // 代理ID
functionName: number; // 功能名称
position: number; // 位置
funSort: string; // 排序
startTime: string; // 开启时间
funStatus:string; // 状态(0:关闭,1开启)
createdAt:string; // 创建时间
updatedAt: string; // 更新时间
}
// 分页查询大厅配置
export function fetchPageGameHells(payload: IGameHell) {
return request.post<IGameHell>("/game/fetch-page-game-hells", payload);
}
// 新增大厅配置
export function addGameHell(payload: IGameHell) {
return request.post("/game/create-game-hell", payload);
}
// 更新大厅配置
export function updateGameHell(payload: IGameHell) {
return request.post("/game/update-game-hell", payload);
}
// 删除大厅配置
export function deleteGameHell(payload: IGameHell) {
return request.post("/game/delete-game-hell", payload);
}

38
backmanage/src/api/module/game_maintain.ts

@ -0,0 +1,38 @@
import request from "../config";
export function getGameMaintain() {
return request.post<{
/**
*
*/
effectTime: string;
/**
*
*/
notice: string;
/**
* 1 2
*/
state: number;
/**
* , 11,22,33
*/
whitelist: string;
}>("/server/fetch-server");
}
/**
* @param payload
*/
export function updateGameMaintain(payload?: {
effectTime?: number;
notice?: string;
type?: number;
whitelist?: string;
}) {
const uri = payload ? "/server/close-server" : "/server/start-server";
return request.post(uri, payload);
}

67
backmanage/src/api/module/game_new.ts

@ -0,0 +1,67 @@
import request from "../config";
export interface IGame {
id: number; // 记录ID
name: string; // 游戏名称
type: number; // 游戏类型
status: number; // 游戏状态(0:开启 1:关闭 2:维护中 3:敬请期待)
icon: number; // 游戏图标(1:小图标 2:大图标)
tag: number; // 游戏标签(0:无 1:火爆 2:新游 3:推荐)
sort: number; // 排序
}
export interface IGameRoom {
id: number; // 记录ID
name: string; // 房间名称
assetKind: number; // 使用的资产类型(1:金币 2:钻石 3:点券)
minEnterAsset: number; // 进入房间的最小资产限额
maxEnterAsset: number; // 进入房间的最大资产限额
minBetAsset: number; // 押注的最小资产限额
maxBetAsset: number; // 押注的最大资产限额
betAssetOptions: string; // 押注资产选项
roomStatus: number; // 房间状态
brightRate: number; // 明水税率
darkRate: number; // 暗水税率
}
export interface UpdateGameRoomInfo {
gameID: number; // 游戏ID
list: IGameRoom[]; // 房间列表
}
export interface IGameRoomInfo {
list: IGameRoom[]; // 房间列表
}
// 游戏列表
export function fetchGameList(payload: IGame) {
return request.post<IGame>("/game/fetch-games", payload);
}
// 新增游戏配置
export function addGame(payload: IGame) {
return request.post("/game/create-game", payload);
}
// 更新游戏配置
export function updateGame(payload: IGame) {
return request.post("/game/update-game", payload);
}
// 删除游戏配置
export function delGame(payload: { id: number }) {
return request.post("/game/delete-game", payload);
}
// 游戏房间列表
export function getGameRoomList(palyoad: { gameID: number }) {
return request.post<BasicListType<IGameRoom>>(
"/game/fetch-rooms-new",
palyoad
);
}
// 更新游戏房间
export function updateGameRoom(payload: UpdateGameRoomInfo) {
return request.post("/game/update-rooms", payload);
}

33
backmanage/src/api/module/game_notice.ts

@ -0,0 +1,33 @@
import request from "../config";
export interface IGameNotice {
id: number; // 记录ID
noticeType: number; // 公告类型:1关服,2维护,3开启
effectTime: string; // 影响时间
noticeInfo: string; // 公告信息
whiteInfo: string; // 白名单信息
createdId:string; // 创建人ID
createdAt:string; // 创建时间
openServerId: string; // 开服人ID
openInfo: string; // 开服信息
openTime: string; // 开服时间
}
// 分页查询游戏维护公告
export function fetchPageGameNotices(payload: IGameNotice) {
return request.post<IGameNotice>("/game/fetch-page-game-notices", payload);
}
// 新增游戏维护公告
export function addGameNotice(payload: IGameNotice) {
return request.post("/game/create-game-notice", payload);
}
// 更新游戏维护公告
export function updateGameNotice(payload: IGameNotice) {
return request.post("/game/update-game-notice", payload);
}
// 删除游戏维护公告
export function deleteGameNotice(payload: IGameNotice) {
return request.post("/game/delete-game-notice", payload);
}

39
backmanage/src/api/module/goods.ts

@ -0,0 +1,39 @@
import request from "../config";
export interface IGoods {
id: number;
agentID: number; //代理ID
name: string; //商品名称
kind: number; //商品类型(1:金币 2:钻石 3:点券 4:道具)
price: number; //商品价格
discountPrice: number; //折扣价
quantity: number; //商品数量
giveQuantity: number; //赠送数量
attributes: string; //商品属性
isHot: number; //是否热门
isNew: number; //是否新品
isRecommend: number; //是否推荐
sort: number; //商品排序
createdAt: string; //创建时间
updatedAt: string; //更新时间
IsRecommend: string; //是否推荐
}
// 分页商品列表
export function fetchPageGoods(payload: IGoods) {
return request.post<IGoods>("/shop/fetch-goods-list", payload);
}
// 新增商品配置
export function addGoods(payload: IGoods) {
return request.post("/shop/create-goods", payload);
}
// 更新商品
export function updateGoods(payload: IGoods) {
return request.post("/shop/update-goods", payload);
}
// 删除商品
export function deleteGoods(payload: IGoods) {
return request.post("/shop/delete-goods", payload);
}

24
backmanage/src/api/module/hall_skin.ts

@ -0,0 +1,24 @@
import request from "../config";
// 皮肤列表
export function getList(payload: HallSkin.SearchParamDTO) {
return request.post<HallSkin.SearchParamVO>(
"/hall-skin/get-hall-skin-list",
payload
);
}
// 新增皮肤
export function createHallSkin(payload: HallSkin.AddHallSkinDTO) {
return request.post("/hall-skin/create-hall-skin", payload);
}
// 更新皮肤
export function updateHallSkin(payload: HallSkin.UpdateHallSkin) {
return request.post("/hall-skin/update-hall-skin", payload);
}
// 删除皮肤
export function deleteHallSkin(payload: HallSkin.DeleteHallSkin) {
return request.post("/hall-skin/delete-hall-skin", payload);
}

42
backmanage/src/api/module/land_page.ts

@ -0,0 +1,42 @@
import request from "../config";
export interface ILandPage {
id: number;
/**
*
*/
name: string;
/**
*
*/
landUrl: string;
/**
*
*/
createdAt: string;
list: any;
}
// 分页落地页列表
export function fetchLandPagePage(payload: ILandPage) {
return request.post<ILandPage>("/land/fetch-land-page-page", payload);
}
// 新增落地页配置
export function addLandPage(payload: ILandPage) {
return request.post("/land/create-land-page", payload);
}
// 更新落地页
export function updateLandPage(payload: ILandPage) {
return request.post("/land/update-land-page", payload);
}
// 删除落地页
export function deleteLandPage(payload: ILandPage) {
return request.post("/land/delete-land-page", payload);
}
// 落地页列表
export function fetchListLandPage(payload: ILandPage) {
return request.post<ILandPage>("/land/fetch-list-land-page", payload);
}

41
backmanage/src/api/module/menu.ts

@ -0,0 +1,41 @@
import request from "../config";
// 菜单列表
export function getList() {
return request.post<MenuType.SearchParamVO>("/menu/fetch-menus");
}
// 创建菜单
export function create(payload: MenuType.AddDTO) {
return request.post("/menu/create-menu", payload);
}
// 删除菜单
export function remove(payload: MenuType.DeleteDTO) {
return request.post("/menu/delete-menu", payload);
}
// 更新菜单
export function update(payload: MenuType.UpdateDTO) {
return request.post("/menu/update-menu", payload);
}
// 运营商菜单列表
export function getCarrierList() {
return request.post<MenuType.SearchParamVO>("/operation/fetch-menus");
}
// 创建运营商菜单
export function createCarrierMenu(payload: MenuType.AddDTO) {
return request.post("/operation/create-menu", payload);
}
// 删除运营商菜单
export function removeCarrierMenu(payload: MenuType.DeleteDTO) {
return request.post("/operation/delete-menu", payload);
}
// 更新运营商菜单
export function updateCarrierMenu(payload: MenuType.UpdateDTO) {
return request.post("/operation/update-menu", payload);
}

48
backmanage/src/api/module/payment_channel.ts

@ -0,0 +1,48 @@
import request from "../config";
export interface IPaymentChannel {
id: number;
appType: number; //商户类型
name: string; //名称
appId: string; //商户ID
secretKey: string; //秘钥
minAmount: number; //最小金额
maxAmount: number; //最大金额
exchangeRate: number; //货币兑换汇率
supportAmount: string; //支持金额
supportInput: number; //是否可输入金额 1=是 2=否
operateUserId: number; //操作员ID
memo: string; //描述
status: number; //状态 1可以 其他不可用
channelSort: number; //渠道排序
createdAt: string; //创建时间
updatedAt: string; //更新时间
}
export interface IPaymentChannelList {
list: IPaymentChannel[]
}
// 分页支付列表
export function fetchChannels(payload: IPaymentChannel) {
return request.post<IPaymentChannel>("/pay/fetch-payment-channels", payload);
}
// 新增支付配置
export function addPaymentChannel(payload: IPaymentChannel) {
return request.post("/pay/create-payment-channel", payload);
}
// 更新支付
export function updatePaymentChannel(payload: IPaymentChannel) {
return request.post("/pay/update-payment-channel", payload);
}
// 删除支付
export function deletePaymentChannel(payload: IPaymentChannel) {
return request.post("/pay/delete-payment-channel", payload);
}
// 支付渠道列表
export function fetchPaymentChannelAll(payload: IPaymentChannel) {
return request.post<IPaymentChannelList>("/pay/fetch-payment-channel-all", payload);
}

59
backmanage/src/api/module/permission.ts

@ -0,0 +1,59 @@
import request from "../config";
// 权限列表
export function getList(payload: Permission.SearchParamDTO) {
return request.post<Permission.SearchParamVO>(
"/permission/fetch-permission-list",
payload
);
}
// 权限配置列表
export function getPermissionList() {
return request.post<Permission.SearchParamVO>(
"/permission/fetch-permissions"
);
}
// 新增权限
export function add(payload: Permission.AddDTO) {
return request.post("/permission/create-permission", payload);
}
// 删除权限
export function del(payload: { id: number }) {
return request.post("/permission/delete-permission", payload);
}
// 修改权限
export function update(payload: Permission.UpdateDTO) {
return request.post("/permission/update-permission", payload);
}
// 运营商权限列表
export function getListForCarrier(payload: Permission.SearchParamDTO) {
return request.post<Permission.SearchParamVO>(
"/operation/fetch-permission-list",
payload
);
}
// 运营商权限配置列表
export function getPermissionListForCarrier() {
return request.post<Permission.SearchParamVO>("/operation/fetch-permissions");
}
// 新增运营商权限
export function addForCarrier(payload: Permission.AddDTO) {
return request.post("/operation/create-permission", payload);
}
// 删除运营商权限
export function delForCarrier(payload: { id: number }) {
return request.post("/operation/delete-permission", payload);
}
// 修改运营商权限
export function updateForCarrier(payload: Permission.UpdateDTO) {
return request.post("/operation/update-permission", payload);
}

53
backmanage/src/api/module/recharge_order.ts

@ -0,0 +1,53 @@
import request from "../config";
export interface IRechargeOrder {
id: number;
orderNo: string; //订单号
userId: number; //用户ID
agentId: number; //代理Id
payChannelId: number; //支付渠道Id
rechargeAmount: number; //充值金额
gold: number; //获取金币
orderStatus: number; //订单状态
pfOrderNum: string; //平台订单号
urlPay: string; //充值路径
ifFirstCharge: number; //是否首充
isThatDay: number; //是否是注册当天充值
msg: string; //三方反馈信息
operator: string; //操作人员
otherInfo: string; //其他信息(json格式)
createdTime: string; //创建时间
endTime: string; //支付完成时间
userNo: string; // 用户编号
callbackInfo: string; // 回调信息
}
export interface IRechargeOrderCount {
rechargeNum: number; // 唤起充值笔数
rechargeSuccessNum: string; //成功充值笔数
rechargeSuccessAmount: number; //成功充值金额
rechargeRelSuccessNum: number; //真实充值笔数
rechargeRelSuccessAmount: number; //真实充值金额
rechargeDoSuccessNum: number; //手动充值笔数
rechargeDoSuccessAmount: number; //手动充值金额
successRate: number; //成功率
}
// 分页支付订单列表
export function FetchPageRechargeOrders(payload: IRechargeOrder) {
return request.post<IRechargeOrder>("/order/fetch-page-recharge-orders", payload);
}
// 新增支付订单
export function addRechargeOrder(payload: IRechargeOrder) {
return request.post("/order/create-recharge-order", payload);
}
// 更新支付订单
export function updateRechargeOrder(payload: IRechargeOrder) {
return request.post("/order/update-recharge-order", payload);
}
// 删除支付订单
export function deleteRechargeOrder(payload: IRechargeOrder) {
return request.post("/order/delete-recharge-order", payload);
}

15
backmanage/src/api/module/register_gold.ts

@ -0,0 +1,15 @@
import request from "../config";
export interface IRegisterGold {
id: number; // 记录ID
registerGold: string; //注册金币
}
// 拉取游戏注册金币
export function fetchGameRegisterGold(payload: IRegisterGold) {
return request.post<IRegisterGold>("/game/fetch-game-register-gold", payload);
}
// 更新大厅配置
export function updateGameRegisterGold(payload: IRegisterGold) {
return request.post("/game/update-game-register-gold", payload);
}

26
backmanage/src/api/module/short_msg.ts

@ -0,0 +1,26 @@
import request from "../config";
// 短信配置列表
export function getList(payload: ShortMsg.SearchParamDTO) {
return request.post<ShortMsg.SearchParamVO>(
"/sub-mail/fetch-allot-list",
payload
);
}
// 新增短信配置
export function add(payload: ShortMsg.AddDTO) {
return request.post("/sub-mail/allot", payload);
}
// 删除短信配置
export function del(payload: ShortMsg.DelDTO) {
return request.post("/sub-mail/delete", payload);
}
// 短信平台列表
export function getMsgPlatList() {
return request.post<{ id: number; name: string }[]>(
"/sub-mail/fetch-platform-list"
);
}

68
backmanage/src/api/module/statistics_daily_game.ts

@ -0,0 +1,68 @@
import request from "../config";
export interface IStatisticsDailyGame {
id: number;
createTime: string; //创建时间
installUser: number; //安装用户
newUser: number; //新增游客
regUser: number; //注册用户
loginUser: number; //登录人数
rechargeNumPeople: number; //当日充值人数
rechargeMoney: number; //当日充值金额
newRechargeNum: number; //新增充值人数
exchangeNumPeople: number; //当日兑换人数
exchangeMoney: number; //当日兑换金额
difference: number; //充提差
channelCost: number; //广告消耗
dailyProfitAndLoss: number; //当日盈亏
dailyRoas: number; //当日ROAS
dailyRoi: number; //当日ROI
installRegRate: number; //安装注册比例
regNewRechargeRate: number; //注册首充比例
installCost: number; //安装成本
regCost: number; //注册成本
newRechargeCost: number; //首充成本
dailyArpu: number; //当日ARPU
dailyArppu: number; //当日ARPPU
rechargeNum: number; //充值笔数
rechargeSuccNum: number; //充值成功数
rechargeSuccRate: number; //充值成功率
exchangeNum: number; //提现笔数
exchangeSuccNum: number; //提现成功数
exchangeSuccRate: number; //提现成功率
}
export interface IStatisticsUserOnline {
id: number;
countTime: string; //统计时间
onlineNum: number; //在线人数
}
export interface IStatisticsUserOnlineList {
list: IStatisticsUserOnline[]
}
// 分页每日数据统计列表
export function fetchPageDailyGameStats(payload: IStatisticsDailyGame) {
return request.post<IStatisticsDailyGame>("/statistics/fetch-page-daily-game-stats", payload);
}
// 用户在线数据统计列表
export function fetchListStatUserOnline(payload: IStatisticsUserOnline) {
return request.post<IStatisticsUserOnlineList>("/statistics/fetch-list-stat-user-online", payload);
}
export interface IStatisticsHourData {
id: number;
countTime: string; //统计时间
regNum: number; //注册人数
}
export interface IStatisticsHourDataList {
list: IStatisticsHourData[]
}
// 小时数据统计列表
export function fetchListStatHourData(payload: IStatisticsHourData) {
return request.post<IStatisticsHourDataList>("/statistics/fetch-list-stat-hour-data", payload);
}

21
backmanage/src/api/module/statistics_day_data.ts

@ -0,0 +1,21 @@
import request from "../config";
export interface IStatisticsDayData {
id: number;
channelId: number; // 渠道ID
countTime: string; //统计时间
rechargeMoney: number; //充值金额
rechargePeople: number; //充值人数
rechargeNum: number; //充值笔数
rechargeMoneyAdd: number; //新增充值金额
rechargePeopleAdd: number; //新增充值人数
rechargeNumAdd: number; //新增充值笔数
}
export interface IStatisticsDayDataList {
list: IStatisticsDayData[]
}
// 天数据统计列表
export function fetchListStatDayData(payload: IStatisticsDayData) {
return request.post<IStatisticsDayDataList>("/statistics/fetch-list-stat-day-data", payload);
}

16
backmanage/src/api/module/statistics_hour_data.ts

@ -0,0 +1,16 @@
import request from "../config";
export interface IStatisticsHourData {
id: number;
channelId: number; // 渠道ID
countTime: string; //统计时间
regNum: number; //注册人数
}
export interface IStatisticsHourDataList {
list: IStatisticsHourData[]
}
// 小时数据统计列表
export function fetchListStatHourData(payload: IStatisticsHourData) {
return request.post<IStatisticsHourDataList>("/statistics/fetch-list-stat-hour-data", payload);
}

15
backmanage/src/api/module/statistics_user_online.ts

@ -0,0 +1,15 @@
import request from "../config";
export interface IStatisticsUserOnline {
id: number;
countTime: string; //统计时间
onlineNum: number; //在线人数
}
export interface IStatisticsUserOnlineList {
list: IStatisticsUserOnline[]
}
// 用户在线数据统计列表
export function fetchListStatUserOnline(payload: IStatisticsUserOnline) {
return request.post<IStatisticsUserOnlineList>("/statistics/fetch-list-stat-user-online", payload);
}

71
backmanage/src/api/module/sub_carrier.ts

@ -0,0 +1,71 @@
import request from "../config";
// 子运营商列表
export function getList(palyoad?: SubCarrier.SearchParamDTO) {
return request.get<SubCarrier.SearchParamVO>(
"/currency/getSubCarrierList",
palyoad
);
}
// 新增子运营商
export function createSubCarrier(payload: SubCarrier.AddSubCarrierDTO) {
return request.post("/currency/createSubCarrier", payload);
}
// 更新子运营商
export function updateSubCarrier(payload: SubCarrier.UpdateSubCarrierDTO) {
return request.post("/currency/updateSubCarrier", payload);
}
// 运营商游戏设置
export function createSubCarrierGame(payload: SubCarrier.AddCarrierGameDTO) {
return request.post("/agent/create-sub-carrier-game", payload);
}
// 游戏列表
export function getCarrierGameList(payload: { id: number }) {
return request.post<CarrierGame.SearchParamVO>(
"/agent/get-sub-carrier-game-list",
payload
);
}
// 渠道总帐号详情
export function getUserInfo(payload: { id: number }) {
return request.get<{
/**
*
*/
googleAuthKey?: string;
/**
* id
*/
id?: number;
/**
*
*/
nickName?: string;
/**
*
*/
remark?: string;
/**
*
*/
roleId?: number;
/**
* 12
*/
status?: number;
/**
*
*/
username?: string;
}>("/currency/getUserInfo", payload);
}
// 创建渠道总帐号
export function createUser(payload: SubCarrier.UserDTO) {
return request.post("/currency/createUser", payload);
}

21
backmanage/src/api/module/sys_dep.ts

@ -0,0 +1,21 @@
import request from "../config";
// 部门列表
export function getList(palyoad?: SysDep.SearchParamDTO) {
return request.get<SysDep.SearchParamVO>("/sysDept/getSysDeptList", palyoad);
}
// 新增部门
export function createSysDept(payload: SysDep.AddDeptDTO) {
return request.post("/sysDept/createSysDept", payload);
}
// 更新部门
export function updateSysDept(payload: SysDep.UpdateDeptDTO) {
return request.put("/sysDept/updateSysDept", payload);
}
// 删除部门
export function deleteSysDept(payload: SysDep.DelDeptDTO) {
return request.delete("/sysDept/deleteSysDept", payload);
}

26
backmanage/src/api/module/sys_role.ts

@ -0,0 +1,26 @@
import request from "../config";
// 角色列表
export function getList(palyoad: SysRole.SearchParamDTO) {
return request.post<SysRole.SearchParamVO>("/role/fetch-role-list", palyoad);
}
// 获取角色信息
export function getRoleInfo(payload: { id: number }) {
return request.post<SysRole.GetRoleInfoVO>("/role/fetch-role", payload);
}
// 新增角色
export function createSysRole(payload: SysRole.AddRoleDTO) {
return request.post("/role/create-role", payload);
}
// 更新角色
export function updateSysRole(payload: SysRole.UpdateRoleDTO) {
return request.post("/role/update-role", payload);
}
// 删除角色
export function deleteSysRole(payload: SysRole.DelRoleDTO) {
return request.post("/role/delete-role", payload);
}

40
backmanage/src/api/module/sys_user.ts

@ -0,0 +1,40 @@
import request from "../config";
// 用户列表
export function getList(palyoad: SysUser.SearchParamDTO) {
return request.post<SysUser.SearchParamVO>(
"/admin/fetch-admin-list",
palyoad
);
}
// 新增用户
export function addSysUser(payload: SysUser.AddUserDTO) {
return request.post("/admin/create-admin", payload);
}
// 更新用户
export function updateSysUser(payload: SysUser.UpdateUserDTO) {
return request.post("/admin/update-admin", payload);
}
// 删除用户
export function deleteSysUser(payload: SysUser.DeleteUserDTO) {
return request.post("/admin/delete-admin", payload);
}
// 获取谷歌验证信息
export function getGoogleInfo(payload: SysUser.GetGoogleInfoDTO) {
return request.post<SysUser.GetGoogleInfoVO>(
"/admin/fetch-authenticator-qrcode",
payload
);
}
// 刷新谷歌验证信息
export function refreshGoogleInfo(payload: SysUser.GetGoogleInfoDTO) {
return request.post<SysUser.GetGoogleInfoVO>(
"/admin/refresh-authenticator-qrcode",
payload
);
}

35
backmanage/src/api/module/user_agent.ts

@ -0,0 +1,35 @@
import request from "../config";
export interface IUserAgent {
id: number;
name: string; // 名称
level: number; // 级别
rate: number; // 比例(百分比)
remark: string; // 备注
createdAt: string; // 创建时间
updatedAt: string; // 更新时间
}
// 分页用户代理列表
export function fetchPageUserAgent(payload: IUserAgent) {
return request.post<IUserAgent>("/agent/fetch-page-user-agents", payload);
}
// 新增用户代理配置
export function addUserAgent(payload: IUserAgent) {
return request.post("/agent/create-user-agent", payload);
}
// 更新用户代理
export function updateUserAgent(payload: IUserAgent) {
return request.post("/agent/update-user-agent", payload);
}
// 删除用户代理
export function deleteUserAgent(payload: IUserAgent) {
return request.post("/agent/delete-user-agent", payload);
}
// 计算用户佣金
export function computeUserAgentGold() {
return request.post<IUserAgent>("/agent/compute-user-agent-gold");
}

35
backmanage/src/api/module/user_agent_info.ts

@ -0,0 +1,35 @@
import request from "../config";
export interface IUserAgentInfo {
id: number;
uid: string; //用户Id
agentLevel: number; //级别
agentRate: number; //比例(百分比)
agentGold: number; //代理金币
exchangeGold: number; //代理提现金币
residueGold: number; //剩余代理金币
todayGold: number; //今日佣金
createdAt: string; //创建时间
updatedAt: string; //更新时间
agentId: number; //代理ID
userNo: string; //用户编号
}
// 分页用户代理数据
export function FetchPageUserAgentInfos(payload: IUserAgentInfo) {
return request.post<IUserAgentInfo>("/agent/fetch-page-user-agent-infos", payload);
}
// 更新用户代理数据
export function updateUserAgentInfo(payload: IUserAgentInfo) {
return request.post("/agent/update-user-agent-info", payload);
}
// 删除用户代理数据
export function deleteUserAgentInfo(payload: IUserAgentInfo) {
return request.post("/agent/delete-user-agent-info", payload);
}
// 总代理配置
export function modifyUserAgentInfoTotal(payload: IUserAgentInfo) {
return request.post("/agent/modify-user-agent-info-total", payload);
}

23
backmanage/src/api/module/user_online.ts

@ -0,0 +1,23 @@
import request from "../config";
export interface IUserOnline {
}
// 分页查询
export function fetchPageUserOnline(payload: IUserOnline) {
return request.post<IUserOnline>("/channel/fetch-page-channel-promotion", payload);
}
// 新增渠道推广
export function addUserOnline(payload: IUserOnline) {
return request.post("/channel/create-channel-promotion", payload);
}
// 更新渠道推广
export function updateUserOnline(payload: IUserOnline) {
return request.post("/channel/update-channel-promotion", payload);
}
// 删除渠道推广
export function deleteUserOnline(payload: IUserOnline) {
return request.post("/channel/delete-channel-promotion", payload);
}

14
backmanage/src/api/module/verification_code.ts

@ -0,0 +1,14 @@
import request from "../config";
export interface IVerificationCode {
id: number;
agentId: number; //代理ID
phone: number; //电话
verCode: number; //验证码
codeStatus : number; //状态
createdAt: string; //创建时间
}
// 分页验证码列表
export function fetchPageVerificationCodes(payload: IVerificationCode) {
return request.post<IVerificationCode>("/sub-mail/fetch-page-verification-codes", payload);
}

40
backmanage/src/api/module/vip_level_config.ts

@ -0,0 +1,40 @@
import request from "../config";
export interface IVipLevelConfig {
id: number;
agentId: number; //代理ID
vipLevel: number; //VIP等级
upgradeExp: number; //升级需要经验
upgradeGold : number; //升级彩金
rtp: number; //返点比例
exchangeNum: number; //提现次数
createAt: string; //创建时间
updateAt: string; //更新时间
freeNum: number; //免费次数
taxRate: number; //税收比例
}
// vip配置列表
export function getList() {
return request.get<IVipLevelConfig>("/vip/fetch-vip");
}
// 创建vip配置
export function addVipLevelConfig(data: IVipLevelConfig) {
return request.post("/vip/create-vip", data);
}
// 删除vip配置
export function delVipLevelConfig(data: { id: number }) {
return request.post("/vip/delete-vip", data);
}
// 更新vip配置
export function updateVipLevelConfig(data: IVipLevelConfig) {
return request.post("/vip/update-vip", data);
}
// 发布vip配置
export function publish() {
return request.post("/vip/publish-vip");
}

24
backmanage/src/api/module/withdraw_plat.ts

@ -0,0 +1,24 @@
import request from "../config";
// 代付平台列表
export function getList(payload?: WithdrawPlatform.SearchParamDTO) {
return request.post<WithdrawPlatform.SearchParamVO>(
"/withdraw/fetch-withdraw-channels",
payload
);
}
// 新增代付平台
export function add(payload: WithdrawPlatform.AddDTO) {
return request.post("/withdraw/create-withdraw-channel", payload);
}
// 更新代付平台
export function update(payload: WithdrawPlatform.UpdateDTO) {
return request.post("/withdraw/update-withdraw-channel", payload);
}
// 删除代付平台
export function del(payload: { id: number }) {
return request.post("/withdraw/delete-withdraw-channel", payload);
}

45
backmanage/src/api/module/withdraw_platform_type.ts

@ -0,0 +1,45 @@
import request from "../config";
// 代付类型列表
export function getList(payload: WithdrawPlatformType.SearchParamDTO) {
return request.post<WithdrawPlatformType.SearchParamVO>(
"/withdraw/fetch-withdraw-interface-type",
payload
);
}
// 新增代付类型
export function add(payload: WithdrawPlatformType.AddDTO) {
return request.post("/withdraw/create-withdraw-interface-type", payload);
}
// 更新代付类型
export function update(payload: WithdrawPlatformType.UpdateDTO) {
return request.post("/withdraw/modify-withdraw-interface-type", payload);
}
// 删除代付类型
export function del(payload: { id: number }) {
return request.post("/withdraw/delete-withdraw-interface-type", payload);
}
// 代付归类列表
export function getCategoryList() {
return request.post<WithdrawPlatformType.WithdrawListTypeVO>(
"/withdrawPlatformType/getWithdrawTypeList"
);
}
// 代付父类列表
export function getParentList() {
return request.post<
BasicListType<{ withdrawInterfaceId: number; withdrawTypeName: string }>
>("/withdraw/fetch-withdraw-interface-type-parents");
}
// 代付子类列表
export function getChildList() {
return request.post<
BasicListType<{ withdrawInterfaceId: 0; withdrawTypeName: "string" }>
>("/withdraw/fetch-withdraw-interface-type-child");
}

BIN
backmanage/src/assets/icons/img_chaijin.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

BIN
backmanage/src/assets/icons/img_chongzhitixian.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
backmanage/src/assets/icons/img_huiyuan.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
backmanage/src/assets/icons/img_jinritouzhu.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
backmanage/src/assets/icons/img_jinrixinzeng.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
backmanage/src/assets/icons/language.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 989 B

BIN
backmanage/src/assets/icons/size.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

BIN
backmanage/src/assets/img/404.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

BIN
backmanage/src/assets/img/bg_denglu.webp

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
backmanage/src/assets/img/welcome.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

303
backmanage/src/assets/json/menu.json

@ -0,0 +1,303 @@
[
{
"path": "/account_management",
"name": "account_management",
"meta": {
"icon": "Memo",
"title": "管理员菜单",
"activeMenu": "",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false,
"isKeepAlive": false
},
"children": [
{
"path": "/userManage",
"name": "userManage",
"component": "/userManage/index",
"meta": {
"icon": "Memo",
"title": "账号管理",
"activeMenu": "",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false,
"isKeepAlive": false
}
},
{
"path": "/role",
"name": "role",
"component": "/role/index",
"meta": {
"icon": "Memo",
"title": "角色管理",
"activeMenu": "",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false,
"isKeepAlive": false
}
},
{
"path": "/menu",
"name": "menu",
"component": "/menu/index",
"meta": {
"icon": "Memo",
"title": "菜单权限管理",
"activeMenu": "",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false,
"isKeepAlive": false
}
},
{
"path": "/permission",
"name": "permission",
"component": "/permission/index",
"meta": {
"icon": "Memo",
"title": "菜单行为管理",
"activeMenu": "",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false,
"isKeepAlive": false
}
},
{
"path": "/carrier_manage",
"name": "carrierManage",
"meta": {
"icon": "Memo",
"title": "运营商管理",
"activeMenu": "",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false,
"isKeepAlive": false
},
"children": [
{
"path": "/carrierList",
"name": "carrierList",
"component": "/carrierList/index",
"meta": {
"icon": "Memo",
"title": "运营商列表",
"activeMenu": "",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false,
"isKeepAlive": false
}
}
]
}
]
},
{
"path": "/game_manage",
"name": "game_manage",
"meta": {
"icon": "Memo",
"title": "游戏管理",
"activeMenu": "",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false,
"isKeepAlive": false
},
"children": [
{
"path": "/hallSkin",
"name": "hallSkin",
"component": "/hallSkin/index",
"meta": {
"icon": "Memo",
"title": "大厅皮肤选择",
"activeMenu": "",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false,
"isKeepAlive": false
}
},
{
"path": "/gameBlood",
"name": "gameBlood",
"component": "/gameBlood/index",
"meta": {
"icon": "Memo",
"title": "血池配置",
"activeMenu": "",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false,
"isKeepAlive": false
}
},
{
"path": "/landPage",
"name": "landPage",
"component": "/landPage/index",
"meta": {
"icon": "Memo",
"title": "落地页配置",
"activeMenu": "",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false,
"isKeepAlive": false
}
},
{
"path": "/channelPromotion",
"name": "channelPromotion",
"component": "/channelPromotion/index",
"meta": {
"icon": "Memo",
"title": "渠道推广配置",
"activeMenu": "",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false,
"isKeepAlive": false
}
}
]
},
{
"path": "/game_main",
"name": "game_main",
"meta": {
"icon": "Memo",
"title": "游戏控制",
"activeMenu": "",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false,
"isKeepAlive": false
},
"children": [
{
"path": "/game_maintenance",
"name": "game_maintenance",
"component": "/gameMaintenance/index",
"meta": {
"icon": "Memo",
"title": "游戏维护",
"activeMenu": "",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false,
"isKeepAlive": false
}
}
]
},
{
"path": "/gameEntrance",
"name": "gameEntrance",
"component": "/gameEntrance/index",
"meta": {
"icon": "Memo",
"title": "游戏入口配置",
"activeMenu": "",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false,
"isKeepAlive": false
}
},
{
"path": "/gameMaintenance",
"name": "gameMaintenance",
"component": "/gameMaintenance/index",
"meta": {
"icon": "Memo",
"title": "游戏维护",
"activeMenu": "",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false,
"isKeepAlive": false
}
},
{
"path": "/game/index",
"name": "game",
"component": "/game/index",
"meta": {
"icon": "Memo",
"title": "游戏列表",
"activeMenu": "",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false,
"isKeepAlive": false
}
},
{
"path": "/payInterfaceType/index",
"name": "payInterfaceType",
"component": "/payInterfaceType/index",
"meta": {
"icon": "Memo",
"title": "支付方式配置",
"activeMenu": "",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false
}
},
{
"path": "/payPlatform/index",
"name": "payPlatform",
"component": "/payPlatform/index",
"meta": {
"icon": "Memo",
"title": "支付平台配置",
"activeMenu": "",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false
}
},
{
"path": "/withdrawPlatform/index",
"name": "withdrawPlatform",
"component": "/withdrawPlatform/index",
"meta": {
"icon": "Memo",
"title": "代付平台配置",
"activeMenu": "",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false
}
}
]

1
backmanage/src/assets/vue.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

After

Width:  |  Height:  |  Size: 496 B

16
backmanage/src/components/common/CustomPaginate.vue

@ -0,0 +1,16 @@
<script setup lang="ts">
const props = defineProps(["size", "total"])
const emits = defineEmits(["newPage"])
const handleCurrentChange = (v: number) => {
emits("newPage", v)
}
</script>
<template>
<div class="paginate-center">
<el-pagination background layout="prev, pager, next" :page-size="props.size" :total="props.total"
@current-change="handleCurrentChange" />
</div>
</template>

5
backmanage/src/components/global/m_count_to/index.ts

@ -0,0 +1,5 @@
import mCountTo from "./src/m_count_to.vue";
import { withInstall } from "@/utils";
export const MCountTo = withInstall(mCountTo);

110
backmanage/src/components/global/m_count_to/src/m_count_to.vue

@ -0,0 +1,110 @@
<template>
<span :style="{ color }">
{{ value }}
</span>
</template>
<script lang="ts" setup>
import { ref, computed, watchEffect, unref, onMounted, watch } from "vue";
import { useTransition, TransitionPresets } from "@vueuse/core";
import { isNumber } from "@/utils/is";
interface Props {
startVal: number;
endVal: number;
duration: number;
autoPlay: boolean;
decimals: number;
decimal: string;
prefix: string;
suffix: string;
separator: string;
color: string;
useEasing: boolean;
transition: keyof typeof TransitionPresets;
}
interface Emits {
(e: "onStarted"): void;
(e: "onFinished"): void;
}
const $props = withDefaults(defineProps<Partial<Props>>(), {
startVal: 0,
endVal: 2023,
duration: 1500,
autoPlay: true,
decimals: 0,
decimal: ".",
prefix: "",
suffix: "",
separator: ",",
useEasing: true,
transition: "linear",
});
const $emit = defineEmits<Emits>();
defineOptions({
name: "MCountTo",
});
const source = ref($props.startVal);
const disabled = ref(false);
let outputValue = useTransition(source);
const value = computed(() => formatNumber(unref(outputValue)));
watchEffect(() => {
source.value = $props.startVal;
});
watch([() => $props.startVal, () => $props.endVal], () => {
if ($props.autoPlay) {
start();
}
});
onMounted(() => {
$props.autoPlay && start();
});
function start() {
run();
source.value = $props.endVal;
}
function reset() {
source.value = $props.startVal;
run();
}
function run() {
outputValue = useTransition(source, {
disabled,
duration: $props.duration,
onFinished: () => $emit("onFinished"),
onStarted: () => $emit("onStarted"),
...($props.useEasing ? { transition: TransitionPresets[$props.transition] } : {}),
});
}
function formatNumber(num: number | string) {
if (!num && num !== 0) {
return "";
}
const { decimals, decimal, separator, suffix, prefix } = $props;
num = Number(num).toFixed(decimals);
num += "";
const x = num.split(".");
let x1 = x[0];
const x2 = x.length > 1 ? decimal + x[1] : "";
const rgx = /(\d+)(\d{3})/;
if (separator && !isNumber(separator)) {
while (rgx.test(x1)) {
x1 = x1.replace(rgx, "$1" + separator + "$2");
}
}
return prefix + x1 + x2 + suffix;
}
</script>

7
backmanage/src/components/global/m_dialog/index.ts

@ -0,0 +1,7 @@
import mDialog from "./src/dialog.vue";
import { withInstall } from "@/utils";
export const MDialog = withInstall(mDialog);
export * from "./src/type";

72
backmanage/src/components/global/m_dialog/src/dialog.vue

@ -0,0 +1,72 @@
<template>
<el-dialog
v-model="show_dialog"
:width="width"
:append-to-body="to_body"
:draggable="can_draggable"
:align-center="dialog_is_center"
:center="align_center"
destroy-on-close
:show-close="show_close_icon"
:before-close="dialog_before_close"
:close-on-click-modal="false"
@open="$emit('dialog_open')"
@close="$emit('dialog_close')"
>
<template #header>
<slot name="header">{{ title }}</slot>
</template>
<slot></slot>
<template #footer>
<slot name="footer"></slot>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ElDialog } from "element-plus";
import type { DialogBeforeCloseFn } from "element-plus";
import { ref, CSSProperties } from "vue";
interface Props {
title?: string;
width?: string | number;
to_body?: boolean;
can_draggable?: boolean;
show_close_icon?: boolean;
align_center?: boolean;
dialog_is_center?: boolean;
dialog_before_close?: DialogBeforeCloseFn;
}
interface Emit {
(e: "dialog_open"): void;
(e: "dialog_close"): void;
}
defineOptions({
name: "MDialog",
});
withDefaults(defineProps<Props>(), {
title: "",
width: "500px",
show_close_icon: true,
});
const $emit = defineEmits<Emit>();
const show_dialog = ref(false);
const handleSetState = (payload: boolean) => {
show_dialog.value = payload;
};
defineExpose({
handleSetState,
});
</script>
<style scoped lang="less"></style>

3
backmanage/src/components/global/m_dialog/src/type.ts

@ -0,0 +1,3 @@
type MDialogInstance = InstanceType<typeof import("./dialog.vue")["default"]>;
export type { MDialogInstance };

7
backmanage/src/components/global/m_drawer/index.ts

@ -0,0 +1,7 @@
import mDrawer from "./src/drawer.vue";
import { withInstall } from "@/utils";
export const MDrawer = withInstall(mDrawer);
export * from "./src/type";

80
backmanage/src/components/global/m_drawer/src/drawer.vue

@ -0,0 +1,80 @@
<template>
<el-drawer
v-model="show_dialog"
:size="width"
:direction="direction"
:with-header="with_header"
:append-to-body="to_body"
destroy-on-close
:show-close="show_close_icon"
:before-close="dialog_before_close"
:close-on-click-modal="false"
@open="$emit('dialog_open')"
@close="$emit('dialog_close')"
>
<template #header>
<div class="m-drawer__title">
<slot name="header">{{ title }}</slot>
</div>
</template>
<div class="content">
<slot></slot>
</div>
<template #footer>
<div class="flex jc-start">
<slot name="footer"></slot>
</div>
</template>
</el-drawer>
</template>
<script setup lang="ts">
import { ElDrawer } from "element-plus";
import type { DialogBeforeCloseFn } from "element-plus";
import { ref } from "vue";
interface Props {
title?: string;
width?: string | number;
direction?: "ltr" | "rtl" | "ttb" | "btt";
to_body?: boolean;
with_header?: boolean;
show_close_icon?: boolean;
align?: "center" | "left" | "right";
dialog_before_close?: DialogBeforeCloseFn;
}
interface Emit {
(e: "dialog_open"): void;
(e: "dialog_close"): void;
}
defineOptions({
name: "MDrawer",
});
withDefaults(defineProps<Props>(), {
title: "",
direction: "rtl",
width: "30%",
with_header: true,
show_close_icon: true,
});
const $emit = defineEmits<Emit>();
const show_dialog = ref(false);
const handleSetState = (payload: boolean) => {
show_dialog.value = payload;
};
defineExpose({
handleSetState,
});
</script>
<style scoped lang="less"></style>

3
backmanage/src/components/global/m_drawer/src/type.ts

@ -0,0 +1,3 @@
type MDrawerInstance = InstanceType<typeof import("./drawer.vue")["default"]>;
export type { MDrawerInstance };

5
backmanage/src/components/global/m_echarts/index.ts

@ -0,0 +1,5 @@
import mEcharts from "./src/m_echarts.vue";
import { withInstall } from "@/utils";
export const MEcharts= withInstall(mEcharts);

36
backmanage/src/components/global/m_echarts/src/m_echarts.vue

@ -0,0 +1,36 @@
<template>
<div ref="echarts_ref" :style="{ width, height: height || '100%' }"></div>
</template>
<script setup lang="ts">
import type { ECOption } from "@/hooks/useEcharts";
import { ref, onMounted, watch } from "vue";
import { useEcharts } from "@/hooks/useEcharts";
interface Props {
height?: string;
width?: string;
options?: ECOption;
}
const $props = defineProps<Props>();
defineOptions({
name: "MEcharts",
});
const echarts_ref = ref<HTMLDivElement>();
const { init, options } = useEcharts(echarts_ref, $props.options);
watch(
() => $props.options,
(v) => {
v && (options.value = v);
}
);
onMounted(init);
</script>
<style scoped></style>

9
backmanage/src/components/global/m_form/index.ts

@ -0,0 +1,9 @@
import mForm from "./src/m_form.vue";
import mFormItem from "./src/m_form_item.vue";
import { withInstall } from "@/utils";
export const MForm = withInstall(mForm);
export const MFormItem = withInstall(mFormItem);
export * from "./src/type";

126
backmanage/src/components/global/m_form/src/m_form.vue

@ -0,0 +1,126 @@
<template>
<ElForm
:model="params"
v-bind="form_base_config"
ref="form_ref"
:scroll-into-view-options="{
behavior: 'smooth',
block: 'center',
inline: 'nearest',
}"
>
<slot> </slot>
<template v-for="item in formItems" :key="item.unique_key">
<ElFormItem
:label="item.label"
:prop="item.prop"
:label-width="item.labelWidth"
:rules="item.rule"
>
<template #label="{ label }">
<el-space :size="2">
<slot :name="`${item.unique_key}_label`">{{ label }}</slot>
<el-tooltip v-if="item.tips" placement="top">
<template #content>
<component :is="getTips(item.tips)" />
</template>
<MIcon name="Warning" />
</el-tooltip>
</el-space>
</template>
<slot :name="`${item.unique_key}_form_item`" :param="params">
<MFormItem :config="item" :params="params" />
</slot>
</ElFormItem>
</template>
</ElForm>
</template>
<script setup lang="ts">
import { ElForm, ElFormItem, ElTooltip, ElSpace } from "element-plus";
import MFormItem from "./m_form_item.vue";
import type { FormInstance, FormItemProp } from "element-plus";
import type { Arrayable } from "@vueuse/core";
import type { FormConfigPropType, BaseType } from "./type";
import { watch, ref, unref } from "vue";
import { isFunction } from "@/utils/is";
const $props = withDefaults(defineProps<FormConfigPropType>(), {
params: () => ({}),
formItems: () => [],
});
defineOptions({
name: "MForm",
});
const getTips = (tips: Required<BaseType>["tips"]) => {
return isFunction(tips) ? tips : () => tips;
};
const form_ref = ref<FormInstance>();
const handleResetFields = (prop?: Arrayable<FormItemProp>) => {
unref(form_ref)?.resetFields(prop);
};
const handleValidate = (): Promise<boolean> => {
return new Promise((resolve, reject) => {
unref(form_ref)?.validate((valid) => {
resolve(valid);
});
});
};
const handleClearValidate = (key: string) => {
unref(form_ref)?.clearValidate(key);
};
const handleValidateField = (key: string): Promise<boolean> => {
return new Promise(async (resolve, reject) => {
const valid = await unref(form_ref)?.validateField(key);
if (!valid) {
reject();
return;
}
resolve(true);
});
};
watch(
() => $props.formItems,
(v) => {
const { params } = $props;
v.forEach(({ defaultValue, prop }) => {
if (!defaultValue) return;
if (Object.prototype.hasOwnProperty.call(params, prop)) {
params[prop] = defaultValue;
}
});
},
{
immediate: true,
}
);
defineExpose({
handleResetFields,
handleValidate,
handleValidateField,
handleClearValidate,
});
</script>
<style scoped lang="less">
.el-form {
--input-min-width: 180px;
:deep(.el-input) {
min-width: var(--input-min-width);
}
:deep(.el-textarea) {
min-width: var(--input-min-width);
}
}
</style>

65
backmanage/src/components/global/m_form/src/m_form_item.vue

@ -0,0 +1,65 @@
<template>
<component v-model="params[config.prop]"
:is="config.type == 'selection' ? 'm-selection' : `el-${config.el_type}`"
v-bind="searchProps">
<!-- <template #prefix>
<template v-if="['text', 'selection'].includes(config.type)">
<component v-if="config.prefix" :is='config.prefix'></component>
<slot v-else :name="`${config.prop}_prefix`"></slot>
</template>
</template>
<template #suffix>
<template v-if="config.type == 'text'">
<component v-if="config.suffix" :is='config.suffix'></component>
<slot v-else :name="`${config.prop}_suffix`"></slot>
</template>
</template>
<template v-if="config.prepend" #prepend>
<template v-if="config.type == 'text'">
<component :is='config.prepend'></component>
</template>
</template>
<template v-if="config.append" #append>
<template v-if="config.type == 'text'">
<component :is='config.append'></component>
</template>
</template> -->
</component>
<!-- <component v-else :is=''></component> -->
</template>
<script setup lang="ts">
import type { FormItemPropType } from "./type";
import { computed, toRaw } from "vue";
import { omit } from "lodash";
defineOptions({
name: "MFormItem"
})
const $props = withDefaults(defineProps<FormItemPropType>(), {
params: () => ({}),
});
const searchProps = computed(() => {
const { config } = $props;
const exclude_prop = [
"prefix",
"suffix",
"append",
"prepend",
"tips",
"rule",
"modifer",
"default",
"label",
"prop",
"unique_key",
"el_type",
];
return omit(toRaw(config), ...exclude_prop);
});
</script>
<style scoped></style>

31
backmanage/src/components/global/m_form/src/render.tsx

@ -0,0 +1,31 @@
// import { VNode, useSlots } from "vue";
// import type { InputType, TextAreaType } from "./type";
// import config from "@/api/config";
// export const RenderSlot = (props: {
// config: InputType | TextAreaType;
// slotKey: string;
// }) => {
// const { config, slotKey } = props;
// return (
// <>
// {config.type == "text" && (
// <RenderInput config={config} slotKey={slotKey} />
// )}
// </>
// );
// };
// const RenderInput = (props: { config: InputType; slotKey: string }) => {
// const $slot = useSlots();
// const { config, slotKey } = props;
// if (config[slotKey]) return config[slotKey]() as VNode;
// const prop_name = `${config.prop}_${slotKey}`
// return (
// <>
// {{
// [prop_name]: () => $slot[prop_name]!(),
// }}
// </>
// );
// };

104
backmanage/src/components/global/m_form/src/type.ts

@ -0,0 +1,104 @@
import type { FormProps, FormRules } from "element-plus";
import type { Component, VNode } from "vue";
import type { SelectionPropType } from "../../m_select/src/type";
interface BaseType {
prop: string;
label?: string;
defaultValue?: ArrayLike<string | number> | number;
rule?: FormRules[keyof FormRules];
disabled?: boolean;
readonly?: boolean;
size?: "default" | "large" | "size";
tips?: string | (() => VNode);
clearable?: boolean;
unique_key: string;
labelWidth?: string | number;
[x: string]: any;
}
type RenderSlotType = (...arg: any[]) => VNode;
interface BaseInputType extends BaseType {
el_type: "input";
maxlength?: string | number;
minlength?: string;
placeholder?: string;
showWordLimit?: boolean;
formatter?: (value: string | number) => string;
}
interface InputType extends BaseInputType {
type: "text";
prefixIcon?: string | Component;
suffixIcon?: string | Component;
// prefix?: RenderSlotType;
// suffix?: RenderSlotType;
// prepend?: RenderSlotType;
// append?: RenderSlotType;
}
interface TextAreaType extends Omit<BaseInputType, "size"> {
type: "textarea";
rows?: number;
autosize?: boolean | { minRows: number; maxRows: number };
}
interface SelectionType extends SelectionPropType, BaseType {
el_type: "select";
type: "selection";
}
interface DataPickerType extends BaseType {
type: "date";
el_type: "date-picker";
date_type:
| "year"
| "month"
| "date"
| "dates"
| "datetime"
| "week"
| "datetimerange"
| "daterange"
| "monthrange";
rangeSeparator?: string;
}
interface FormBaseConfigType {
labelWidth: string | number;
labelPosition: "top" | "left" | "right";
inline: boolean;
labelSuffix: string;
hideRequiredAsterisk: boolean;
requireAsteriskPosition: "left" | "right";
size: "default" | "large" | "small";
rules: FormRules;
scrollToError: boolean;
}
type FormItemType = InputType | TextAreaType | SelectionType | DataPickerType;
interface FormConfigPropType {
form_base_config?: Partial<FormBaseConfigType>;
params?: Record<string, any>;
formItems?: FormItemType[];
validOnRuleChange?: boolean;
}
interface FormItemPropType {
params: Record<string, any>;
config: FormItemType;
}
type MFormInstance = InstanceType<typeof import("./m_form.vue")["default"]>;
export type {
MFormInstance,
FormConfigPropType,
FormItemPropType,
TextAreaType,
InputType,
RenderSlotType,
BaseType,
};

14
backmanage/src/components/global/m_form/src/utils.ts

@ -0,0 +1,14 @@
export function pickObject(target: Record<string, any>, ...keys: string[]) {
const obj = {...target};
for (let key in obj) {
console.log(key);
if (Object.hasOwnProperty.call(obj, key)) {
if (!keys.includes(key)) {
debugger
delete obj[key];
}
}
}
return obj
}

5
backmanage/src/components/global/m_icon/index.ts

@ -0,0 +1,5 @@
import mIcon from "./src/m_icon.vue";
import { withInstall } from "@/utils";
export const MIcon = withInstall(mIcon);

5
backmanage/src/components/global/m_icon/src/const.ts

@ -0,0 +1,5 @@
export const ICON_SIZE: Record<string, string> = {
"small": "16px",
"default": "18px",
"large": "20px"
}

43
backmanage/src/components/global/m_icon/src/m_icon.vue

@ -0,0 +1,43 @@
<template>
<ElIcon :size="icon_size" :color="color">
<slot>
<template v-if="name">
<component :is="name"></component>
</template>
</slot>
</ElIcon>
</template>
<script setup lang="ts">
import { ElIcon } from "element-plus";
import type { GlobalState } from "@/store/interface";
import { computed } from "vue";
import { useGlobalStore } from "@/store/modules/global";
import { ICON_SIZE } from "./const";
interface Props {
name?: string;
size?: GlobalState["size"] | number | (string & {});
color?: string;
injectGSize?: boolean;
}
const $props = withDefaults(defineProps<Props>(), {
injectGSize: true,
});
defineOptions({
name: "MIcon",
});
const $global = useGlobalStore();
const icon_size = computed<Props["size"]>(() => {
const { size, injectGSize } = $props;
return size ? size : injectGSize ? ICON_SIZE[$global.size] || "" : "";
});
</script>
<style scoped></style>

7
backmanage/src/components/global/m_page/index.ts

@ -0,0 +1,7 @@
import mPage from "./src/page.vue";
import { withInstall } from "@/utils";
export const MPage = withInstall(mPage);
export * from "./src/type";

50
backmanage/src/components/global/m_page/src/page.vue

@ -0,0 +1,50 @@
<template>
<transition appear name="fade-transform" mode="out-in">
<div class="full-page p-20 page-content flex fd-column" v-if="modelValue">
<el-page-header @back="handleBack" class="mb-20">
<template #content>
<slot name="header">
{{ title }}
</slot>
</template>
<template #extra>
<slot name="extra" />
</template>
</el-page-header>
<main class="pt-20 flex-1 min-w-0 min-h-0">
<el-scrollbar height="100%">
<slot />
</el-scrollbar>
</main>
</div>
</transition>
</template>
<script setup lang="ts">
import { ElPageHeader } from "element-plus";
import type { MPagePropType, MPageEmitsType } from "./type";
defineOptions({
name: "MPage",
});
const $props = withDefaults(defineProps<MPagePropType>(), {
zIndex: 2000,
});
const $emit = defineEmits<MPageEmitsType>();
const handleBack = () => {
$emit("update:modelValue", false);
$props.back && $props.back();
};
</script>
<style scoped lang="less">
.page-content {
position: absolute;
inset: 0;
z-index: v-bind(zIndex);
}
</style>

14
backmanage/src/components/global/m_page/src/type.ts

@ -0,0 +1,14 @@
interface MPagePropType {
modelValue?: boolean;
title?: string;
back?: () => void;
zIndex?: number;
}
interface MPageEmitsType {
(e: "update:modelValue", value: MPagePropType["modelValue"]): void;
}
type MPageInstance = InstanceType<typeof import("./page.vue")["default"]>;
export type { MPageInstance, MPageEmitsType, MPagePropType };

9
backmanage/src/components/global/m_pagination/index.ts

@ -0,0 +1,9 @@
import mPagination from "./src/m_pagination.vue";
import { withInstall } from "@/utils";
export const MPagiantion = withInstall(mPagination);
export * from "./src/type";
export * from "./src/hooks";

29
backmanage/src/components/global/m_pagination/src/hooks/index.ts

@ -0,0 +1,29 @@
import { reactive } from "vue";
import type { PaginationType } from "../type";
export const usePagination = (config?: Partial<PaginationType>) => {
const DEFAULT_PAGINATION = {
currentPage: 1,
pageSize: 20,
pageSizes: [20, 50, 100, 500, 1000, 10000],
total: 0,
layout: ["sizes", "prev", "pager", "next", "jumper", "total"],
};
const pagination = reactive<PaginationType>(
Object.assign({}, DEFAULT_PAGINATION, config)
);
const handleSetPagenation = <K extends keyof PaginationType>(
payload: Partial<PaginationType>
) => {
for (let [key, val] of Object.entries(payload)) {
if (!pagination.hasOwnProperty(key)) continue;
pagination[key as K] = val as PaginationType[K];
}
};
return {
pagination,
handleSetPagenation,
};
};

73
backmanage/src/components/global/m_pagination/src/m_pagination.vue

@ -0,0 +1,73 @@
<template>
<div class="m-pagination">
<div class="m-paginaiton__wrapper">
<div class="m-pagination__content">
<ElScrollbar>
<ElPagination
background
:class="[align]"
:current-page="currentPage"
:page-size="pageSize"
:total="total"
:page-sizes="pageSizes"
:layout="handleParsePaginationLayout(layout)"
@size-change="onSizeChange"
@current-change="onCurrentChange"
>
</ElPagination>
</ElScrollbar>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ElPagination, ElScrollbar } from "element-plus";
import type { PaginationEmitType, PaginationPropType } from "./type";
defineOptions({
name: "MPagination",
});
withDefaults(defineProps<PaginationPropType>(), {
config: () => ({
currentPage: 1,
pageSize: 10,
pageSizes: [10, 20, 30, 50, 100],
total: 1000,
layout: ["sizes", "prev", "pager", "next", "jumper", "total"],
}),
align: "center",
});
const $emit = defineEmits<PaginationEmitType>();
const handleParsePaginationLayout = (layout: any[]) => {
return layout ? layout.join(",") : "";
};
const onSizeChange = (v: number) => {
$emit("sizeChange", v);
console.log("size", v);
};
const onCurrentChange = (v: number) => {
$emit("currentChange", v);
console.log("currentpage", v);
};
</script>
<style scoped lang="less">
.m-pagination {
.el-pagination {
&.right {
justify-content: flex-end;
}
&.center {
justify-content: safe center;
}
}
}
</style>

18
backmanage/src/components/global/m_pagination/src/type.ts

@ -0,0 +1,18 @@
interface PaginationType {
currentPage: number;
pageSize: number;
pageSizes: number[];
total: number;
layout: string[];
}
interface PaginationPropType extends PaginationType {
align?: "left" | "center" | "right";
}
interface PaginationEmitType {
(e: "sizeChange", v: number): void;
(e: "currentChange", v: number): void;
}
export type { PaginationType, PaginationPropType, PaginationEmitType };

7
backmanage/src/components/global/m_radio/index.ts

@ -0,0 +1,7 @@
import mRadio from "./src/m_radio.vue";
import { withInstall } from "@/utils";
export const MRadio = withInstall(mRadio);
export * from "./src/type";

11
backmanage/src/components/global/m_radio/src/m_radio.vue

@ -0,0 +1,11 @@
<template>
<div></div>
</template>
<script setup lang="ts">
defineOptions({
name: "MRadio",
});
</script>
<style scoped></style>

1
backmanage/src/components/global/m_radio/src/type.ts

@ -0,0 +1 @@
export type {}

7
backmanage/src/components/global/m_select/index.ts

@ -0,0 +1,7 @@
import mSelection from "./src/m_select.vue";
import { withInstall } from "@/utils";
export const MSelection = withInstall(mSelection);
export * from "./src/type";

37
backmanage/src/components/global/m_select/src/hooks/useSelection.ts

@ -0,0 +1,37 @@
import { isArray } from "lodash";
import type { SelectionPropType } from "../type";
import { ref } from "vue";
export function useSelection(
$props: Pick<
SelectionPropType,
"filterMethod" | "remoteMethod" | "optionEnumFn"
>
) {
const { optionEnumFn } = $props;
const loading = ref(false);
const option = ref<any[]>([]);
const handleFetchData = async (...arg: any[]) => {
if (isArray(optionEnumFn)) {
return;
}
loading.value = true;
option.value = [];
try {
if (!optionEnumFn) return;
const data = await optionEnumFn(arg);
option.value = data;
} finally {
loading.value = false;
}
};
return {
loading,
option,
handleFetchData,
};
}

87
backmanage/src/components/global/m_select/src/m_select.vue

@ -0,0 +1,87 @@
<template>
<el-select
v-model="value"
v-bind="bindProps"
@change="selectChange"
:remote-method="onRemoteMethod"
:loading="loading"
>
<el-option
v-for="item in selectOptions"
:key="item[fileds_Props.value]"
:label="item[fileds_Props.label]"
:value="item[fileds_Props.value]"
:disabled="!!item?.disabled"
/>
</el-select>
</template>
<script setup lang="ts">
import type { SelectionPropType, SelectionEmitsType } from "./type";
import { computed } from "vue";
import { Omit, isArray, omit } from "lodash";
import { useSelection } from "./hooks/useSelection";
defineOptions({
name: "MSelection",
});
const $props = withDefaults(defineProps<SelectionPropType>(), {
immediate: true,
filterMethod: undefined,
remoteMethod: undefined,
optionEnumFn: undefined,
clearable: true,
});
const $emit = defineEmits<SelectionEmitsType>();
const { loading, handleFetchData, option } = useSelection($props);
const value = computed({
get() {
return $props.modelValue;
},
set(v) {
$emit("update:modelValue", v);
},
});
const selectOptions = computed(() => {
if (isArray($props.optionEnumFn)) return $props.optionEnumFn;
return option.value;
});
const fileds_Props = computed(() => {
const DEFAULT_FIELDS = { value: "value", label: "label" };
const { props } = $props;
if (!props) return DEFAULT_FIELDS;
return Object.assign({}, DEFAULT_FIELDS, props);
});
const bindProps = computed(() =>
omit(
$props,
"optionEnumFn",
"modelValue",
"prefix",
"remoteMethod",
"props",
"unique_key",
"selectChange"
)
);
const onRemoteMethod = (val: string) => {
const { remoteMethod } = $props;
if (!remoteMethod) return;
remoteMethod(val, option, loading, handleFetchData);
};
if ($props.immediate && !$props.remoteMethod) {
handleFetchData();
}
</script>
<style scoped></style>

33
backmanage/src/components/global/m_select/src/type.ts

@ -0,0 +1,33 @@
import type { Ref } from "vue";
import type { Arrayable } from "@vueuse/core";
interface SelectionPropType {
modelValue?: Arrayable<string | number>;
multiple?: boolean;
collapseTags?: boolean;
collapseTagsTooltip?: boolean;
multipleLimit?: number;
allowCreate?: boolean;
filterable?: boolean;
props?: Partial<{ value: string; label: string }>;
filterMethod?: (val: string) => void;
remoteMethod?: (
val: string,
options: Ref<any[]>,
loading: Ref<boolean>,
fetch?: (...arg: any[]) => void
) => void;
clearable?: boolean;
defaultFirstOption?: boolean;
fitInputWidth?: boolean;
maxCollapseTags?: number;
optionEnumFn?: any[] | EnumFnType<any>;
selectChange?: (...arg: any[]) => void;
immediate?: boolean;
}
interface SelectionEmitsType {
(e: "update:modelValue", v: SelectionPropType["modelValue"]): void;
}
export type { SelectionPropType, SelectionEmitsType };

11
backmanage/src/components/global/m_table/index.ts

@ -0,0 +1,11 @@
import mTable from "./src/m_table.vue";
import { MTableColumn as mTableColumn } from "./src/render";
import { withInstall } from "@/utils";
export const MTable = withInstall(mTable);
export const MTableColumn = withInstall(mTableColumn);
export * from "./src/type";
export * from "./src/hooks";

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save