@ -0,0 +1,3 @@ |
|||
VITE_API = http://65.2.141.248:8090 |
|||
|
|||
VITE_TITLE = Victory总后台 |
@ -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/ |
@ -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. |
@ -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> |
@ -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" |
|||
} |
|||
} |
After Width: | Height: | Size: 1.5 KiB |
@ -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> |
@ -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); |
@ -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>(); |
|||
} |
|||
} |
@ -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; |
|||
} |
@ -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"; |
@ -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[]; |
|||
}; |
@ -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 |
|||
); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
|||
|
@ -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 |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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" |
|||
); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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; |
|||
/** |
|||
* 状态 1启用2禁用 |
|||
*/ |
|||
status?: number; |
|||
/** |
|||
* 登录用户名 |
|||
*/ |
|||
username?: string; |
|||
}>("/currency/getUserInfo", payload); |
|||
} |
|||
|
|||
// 创建渠道总帐号
|
|||
export function createUser(payload: SubCarrier.UserDTO) { |
|||
return request.post("/currency/createUser", payload); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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 |
|||
); |
|||
} |
@ -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"); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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); |
|||
} |
@ -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"); |
|||
} |
@ -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); |
|||
} |
@ -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"); |
|||
} |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 989 B |
After Width: | Height: | Size: 464 B |
After Width: | Height: | Size: 7.6 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 74 KiB |
@ -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 |
|||
} |
|||
} |
|||
] |
After Width: | Height: | Size: 496 B |
@ -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> |
@ -0,0 +1,5 @@ |
|||
import mCountTo from "./src/m_count_to.vue"; |
|||
|
|||
import { withInstall } from "@/utils"; |
|||
|
|||
export const MCountTo = withInstall(mCountTo); |
@ -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> |
@ -0,0 +1,7 @@ |
|||
import mDialog from "./src/dialog.vue"; |
|||
|
|||
import { withInstall } from "@/utils"; |
|||
|
|||
export const MDialog = withInstall(mDialog); |
|||
|
|||
export * from "./src/type"; |
@ -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> |
@ -0,0 +1,3 @@ |
|||
type MDialogInstance = InstanceType<typeof import("./dialog.vue")["default"]>; |
|||
|
|||
export type { MDialogInstance }; |
@ -0,0 +1,7 @@ |
|||
import mDrawer from "./src/drawer.vue"; |
|||
|
|||
import { withInstall } from "@/utils"; |
|||
|
|||
export const MDrawer = withInstall(mDrawer); |
|||
|
|||
export * from "./src/type"; |
@ -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> |
@ -0,0 +1,3 @@ |
|||
type MDrawerInstance = InstanceType<typeof import("./drawer.vue")["default"]>; |
|||
|
|||
export type { MDrawerInstance }; |
@ -0,0 +1,5 @@ |
|||
import mEcharts from "./src/m_echarts.vue"; |
|||
|
|||
import { withInstall } from "@/utils"; |
|||
|
|||
export const MEcharts= withInstall(mEcharts); |
@ -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> |
@ -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"; |
@ -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> |
@ -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> |
@ -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]!(),
|
|||
// }}
|
|||
// </>
|
|||
// );
|
|||
// };
|
@ -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, |
|||
}; |
@ -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 |
|||
} |
@ -0,0 +1,5 @@ |
|||
import mIcon from "./src/m_icon.vue"; |
|||
|
|||
import { withInstall } from "@/utils"; |
|||
|
|||
export const MIcon = withInstall(mIcon); |
@ -0,0 +1,5 @@ |
|||
export const ICON_SIZE: Record<string, string> = { |
|||
"small": "16px", |
|||
"default": "18px", |
|||
"large": "20px" |
|||
} |
@ -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> |
@ -0,0 +1,7 @@ |
|||
import mPage from "./src/page.vue"; |
|||
|
|||
import { withInstall } from "@/utils"; |
|||
|
|||
export const MPage = withInstall(mPage); |
|||
|
|||
export * from "./src/type"; |
@ -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> |
@ -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 }; |
@ -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"; |
@ -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, |
|||
}; |
|||
}; |
@ -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> |
@ -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 }; |
@ -0,0 +1,7 @@ |
|||
import mRadio from "./src/m_radio.vue"; |
|||
|
|||
import { withInstall } from "@/utils"; |
|||
|
|||
export const MRadio = withInstall(mRadio); |
|||
|
|||
export * from "./src/type"; |
@ -0,0 +1,11 @@ |
|||
<template> |
|||
<div></div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
defineOptions({ |
|||
name: "MRadio", |
|||
}); |
|||
</script> |
|||
|
|||
<style scoped></style> |
@ -0,0 +1 @@ |
|||
export type {} |
@ -0,0 +1,7 @@ |
|||
import mSelection from "./src/m_select.vue"; |
|||
|
|||
import { withInstall } from "@/utils"; |
|||
|
|||
export const MSelection = withInstall(mSelection); |
|||
|
|||
export * from "./src/type"; |
@ -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, |
|||
}; |
|||
} |
@ -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> |
@ -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 }; |
@ -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"; |