Compare commits
79 Commits
main
...
feature/BE
Author | SHA1 | Date | |
---|---|---|---|
86998f183d | |||
c3b1ad2023 | |||
aa44d6aab1 | |||
4b3ad14674 | |||
ad97b8b550 | |||
17e993955c | |||
654d98aa13 | |||
b142831820 | |||
3a203ad2db | |||
496c22af81 | |||
ccc3e0c9f1 | |||
dfc328b636 | |||
dc10f5b8c4 | |||
d7ddfe5c46 | |||
ee98a22899 | |||
f828b707a9 | |||
33b4baccf5 | |||
67ee99ab60 | |||
20c4490eec | |||
72bd1ffad8 | |||
62b501d6bb | |||
6edcc2d615 | |||
0b16750e01 | |||
0ec47aba30 | |||
ca75319f20 | |||
e9e4a148fa | |||
605daab740 | |||
bcf0c819ad | |||
f9f245f2a2 | |||
4c785f2542 | |||
3ad73b26d3 | |||
cd36f9eada | |||
c4d8c03541 | |||
d89d93c9d0 | |||
0460aca0d3 | |||
ee76ced214 | |||
4637972b10 | |||
a1210b7881 | |||
d01a9d2ea4 | |||
93569bc247 | |||
57be0b3a6b | |||
74e28dcb95 | |||
ec834d8e8e | |||
0ba303a454 | |||
e55adae3dc | |||
40e687c5d9 | |||
60eef0a1a2 | |||
7fd0d9024f | |||
7adc6da480 | |||
7b207909c7 | |||
51d3e6648f | |||
9d0f9f1f34 | |||
e87060a940 | |||
a26d5bb6bc | |||
bbced41e62 | |||
b90b54ba2d | |||
7502f066fc | |||
61bab7ef6a | |||
0142b2ead3 | |||
2584bf8a55 | |||
e1cf3ebd54 | |||
6151ddf478 | |||
e7bc00c4c6 | |||
ea2664577a | |||
64364946cc | |||
4f6a445617 | |||
21436b69a7 | |||
30555e9773 | |||
6b9b7e6b24 | |||
02fe71a486 | |||
72f3d63eb5 | |||
b2c439de7c | |||
0db6f75d61 | |||
88fc45b7c8 | |||
ee705fe250 | |||
b867964d65 | |||
918183c190 | |||
8e182c0a55 | |||
273bbd69fc |
11
.devcontainer/Dockerfile
Normal file
11
.devcontainer/Dockerfile
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.245.0/containers/debian/.devcontainer/base.Dockerfile
|
||||||
|
|
||||||
|
# [Choice] Debian version (use bullseye on local arm64/Apple Silicon): bullseye, buster
|
||||||
|
ARG VARIANT="buster"
|
||||||
|
FROM mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT}
|
||||||
|
|
||||||
|
# ** [Optional] Uncomment this section to install additional packages. **
|
||||||
|
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||||
|
# && apt-get -y install --no-install-recommends <your-package-list-here>
|
||||||
|
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||||
|
&& apt-get -y install --no-install-recommends libpq-dev
|
66
.devcontainer/devcontainer.json
Normal file
66
.devcontainer/devcontainer.json
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
||||||
|
// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.0/containers/ubuntu
|
||||||
|
{
|
||||||
|
"name": "beteran-api-kgon-server-service",
|
||||||
|
"build": {
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
"args": {
|
||||||
|
// Use the VARIANT arg to pick a Debian OS version: buster, bullseye
|
||||||
|
// Use bullseye when on local on arm64/Apple Silicon.
|
||||||
|
"VARIANT": "bullseye"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runArgs": [
|
||||||
|
"--cap-add=SYS_PTRACE",
|
||||||
|
"--security-opt",
|
||||||
|
"seccomp=unconfined"
|
||||||
|
],
|
||||||
|
// Use this environment variable if you need to bind mount your local source code into a new container.
|
||||||
|
"remoteEnv": {
|
||||||
|
"LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}"
|
||||||
|
},
|
||||||
|
// Configure tool-specific properties.
|
||||||
|
"customizations": {
|
||||||
|
// Configure properties specific to VS Code.
|
||||||
|
"vscode": {
|
||||||
|
// Set *default* container specific settings.json values on container create.
|
||||||
|
"settings": {
|
||||||
|
"lldb.verboseLogging": true,
|
||||||
|
"lldb.executable": "/usr/bin/lldb",
|
||||||
|
// VS Code don't watch files under ./target
|
||||||
|
"files.watcherExclude": {
|
||||||
|
"**/.git/objects/**": true,
|
||||||
|
"**/.git/subtree-cache/**": true,
|
||||||
|
"**/target/**": true
|
||||||
|
},
|
||||||
|
"rust-analyzer.checkOnSave.command": "clippy",
|
||||||
|
"editor.tabSize": 2,
|
||||||
|
"editor.insertSpaces": true,
|
||||||
|
"editor.formatOnSave": true
|
||||||
|
},
|
||||||
|
// Add the IDs of extensions you want installed when the container is created.
|
||||||
|
"extensions": [
|
||||||
|
"donjayamanne.githistory",
|
||||||
|
"eamodio.gitlens",
|
||||||
|
"mhutchie.git-graph",
|
||||||
|
"ms-azuretools.vscode-docker",
|
||||||
|
"mutantdino.resourcemonitor",
|
||||||
|
"rust-lang.rust-analyzer",
|
||||||
|
"serayuzgur.crates",
|
||||||
|
"tamasfe.even-better-toml",
|
||||||
|
"vadimcn.vscode-lldb"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||||
|
// "forwardPorts": [],
|
||||||
|
// Use 'postCreateCommand' to run commands after the container is created.
|
||||||
|
// "postCreateCommand": "uname -a",
|
||||||
|
"postCreateCommand": "bash ./.devcontainer/scripts/postCreateCommand.sh",
|
||||||
|
// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
||||||
|
"remoteUser": "vscode",
|
||||||
|
"features": {
|
||||||
|
"git": "latest",
|
||||||
|
"rust": "latest"
|
||||||
|
}
|
||||||
|
}
|
5
.devcontainer/rust-toolchain.toml
Normal file
5
.devcontainer/rust-toolchain.toml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[toolchain]
|
||||||
|
channel = "stable"
|
||||||
|
profile = "minimal"
|
||||||
|
components = ["clippy", "rustfmt"]
|
||||||
|
targets = []
|
4
.devcontainer/scripts/postCreateCommand.sh
Normal file
4
.devcontainer/scripts/postCreateCommand.sh
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
.DS_Store
|
||||||
|
/build
|
||||||
|
|
||||||
|
# Added by cargo
|
||||||
|
|
||||||
|
/target
|
||||||
|
Cargo.lock
|
75
.rustfmt.toml
Normal file
75
.rustfmt.toml
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
# https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=
|
||||||
|
array_width = 60
|
||||||
|
attr_fn_like_width = 70
|
||||||
|
binop_separator = "Front" # "Front", "Back"
|
||||||
|
blank_lines_lower_bound = 0
|
||||||
|
blank_lines_upper_bound = 1
|
||||||
|
brace_style = "SameLineWhere" #"AlwaysNextLine", "PreferSameLine", "SameLineWhere"
|
||||||
|
chain_width = 60
|
||||||
|
color = "Auto" #"Auto", "Always", "Never"
|
||||||
|
combine_control_expr = true # true, false
|
||||||
|
comment_width = 80
|
||||||
|
condense_wildcard_suffixes = false # true, false
|
||||||
|
control_brace_style = "AlwaysSameLine" # "AlwaysNextLine", "AlwaysSameLine", "ClosingNextLine"
|
||||||
|
disable_all_formatting = false # true, false
|
||||||
|
edition = "2015" # "2015", "2018", "2021"
|
||||||
|
empty_item_single_line = true # true, false
|
||||||
|
enum_discrim_align_threshold = 0
|
||||||
|
error_on_line_overflow = false # true, false
|
||||||
|
error_on_unformatted = false # true, false
|
||||||
|
fn_args_layout = "Tall" # "Compressed", "Tall", "Vertical"
|
||||||
|
fn_call_width = 60
|
||||||
|
fn_single_line = false # true, false
|
||||||
|
force_explicit_abi = true # true, false
|
||||||
|
force_multiline_blocks = false # true, false
|
||||||
|
format_code_in_doc_comments = false # true, false
|
||||||
|
format_generated_files = false # true, false
|
||||||
|
format_macro_matchers = false # true, false
|
||||||
|
format_macro_bodies = true # true, false
|
||||||
|
format_strings = false # true, false
|
||||||
|
group_imports = "Preserve" # "Preserve", "StdExternalCrate"
|
||||||
|
hard_tabs = false # true, false
|
||||||
|
hex_literal_case = "Preserve" # "Upper", "Lower"
|
||||||
|
hide_parse_errors = false # true, false
|
||||||
|
ignore = []
|
||||||
|
imports_indent = "Block" # "Block", "Visual"
|
||||||
|
imports_layout = "Mixed" # "Horizontal", "HorizontalVertical", "Mixed", "Vertical"
|
||||||
|
indent_style = "Block" # "Block", "Visual"
|
||||||
|
inline_attribute_width = 0
|
||||||
|
license_template_path = ""
|
||||||
|
match_arm_blocks = true # true, false
|
||||||
|
match_arm_leading_pipes = "Never" # "Always", "Never", "Preserve"
|
||||||
|
match_block_trailing_comma = false # true, false
|
||||||
|
max_width = 100
|
||||||
|
merge_derives = true # true, false
|
||||||
|
imports_granularity = "Preserve" # "Preserve", "Crate", "Module", "Item", "One"
|
||||||
|
merge_imports = false # true, false
|
||||||
|
newline_style = "Auto" # "Auto", "Native", "Unix", "Windows"
|
||||||
|
normalize_comments = false # true, false
|
||||||
|
normalize_doc_attributes = false # true, false
|
||||||
|
overflow_delimited_expr = false # true, false
|
||||||
|
remove_nested_parens = true # true, false
|
||||||
|
reorder_impl_items = false # true, false
|
||||||
|
reorder_imports = true # true, false
|
||||||
|
reorder_modules = true # true, false
|
||||||
|
report_fixme = "Never" # "Always", "Unnumbered", "Never"
|
||||||
|
report_todo = "Never" # "Always", "Unnumbered", "Never"
|
||||||
|
skip_children = false # true, false
|
||||||
|
single_line_if_else_max_width = 50
|
||||||
|
space_after_colon = true # true, false
|
||||||
|
space_before_colon = false # true, false
|
||||||
|
spaces_around_ranges = false # true, false
|
||||||
|
struct_field_align_threshold = 0
|
||||||
|
struct_lit_single_line = true # true, false
|
||||||
|
struct_lit_width = 18
|
||||||
|
struct_variant_width = 35
|
||||||
|
tab_spaces = 2
|
||||||
|
trailing_comma = "Vertical" # "Always", "Never", "Vertical"
|
||||||
|
trailing_semicolon = true # true, false
|
||||||
|
type_punctuation_density = "Wide" # "Compressed", "Wide"
|
||||||
|
unstable_features = false # true, false
|
||||||
|
use_field_init_shorthand = false # true, false
|
||||||
|
use_small_heuristics = "Default" # "Default", "Off", "Max"
|
||||||
|
use_try_shorthand = false # true, false
|
||||||
|
where_single_line = false # true, false
|
||||||
|
wrap_comments = false # true, false
|
61
.vscode/launch.json
vendored
Normal file
61
.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug executable 'beteran-api-kgon-server-service'",
|
||||||
|
"cargo": {
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"--bin=beteran-api-kgon-server-service",
|
||||||
|
"--package=beteran-api-kgon-server-service"
|
||||||
|
],
|
||||||
|
"filter": {
|
||||||
|
"name": "beteran-api-kgon-server-service",
|
||||||
|
"kind": "bin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"URL_DATABASE": "postgresql://beteran:qwer5795QWER@192.168.50.205:25432/beteran",
|
||||||
|
"URL_BROKER": "nats://192.168.50.205:4222",
|
||||||
|
"QUEUE_BROKER": "bet.beteran",
|
||||||
|
"K_URL": "https://dev-mw.kgonapi.com",
|
||||||
|
"K_USERNAME": "turbo78",
|
||||||
|
"K_SECRET": "561b6f4d6e4c5f1b8a3473c43c3caa84",
|
||||||
|
},
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug unit tests in executable 'beteran-api-kgon-server-service'",
|
||||||
|
"cargo": {
|
||||||
|
"args": [
|
||||||
|
"test",
|
||||||
|
"--no-run",
|
||||||
|
"--bin=beteran-api-kgon-server-service",
|
||||||
|
"--package=beteran-api-kgon-server-service"
|
||||||
|
],
|
||||||
|
"filter": {
|
||||||
|
"name": "beteran-api-kgon-server-service",
|
||||||
|
"kind": "bin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"URL_DATABASE": "postgresql://beteran:qwer5795QWER@192.168.50.205:25432/beteran",
|
||||||
|
"URL_BROKER": "nats://192.168.50.205:4222",
|
||||||
|
"QUEUE_BROKER": "bet.beteran",
|
||||||
|
"K_URL": "https://dev-mw.kgonapi.com",
|
||||||
|
"K_USERNAME": "turbo78",
|
||||||
|
"K_SECRET": "561b6f4d6e4c5f1b8a3473c43c3caa84",
|
||||||
|
},
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
42
Cargo.toml
Normal file
42
Cargo.toml
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
[package]
|
||||||
|
name = "beteran-api-kgon-server-service"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
[[bin]]
|
||||||
|
name = "beteran-api-kgon-server-service"
|
||||||
|
path = "./src/main.rs"
|
||||||
|
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
chrono = { version = "0" }
|
||||||
|
diesel = { version = "1", features = [
|
||||||
|
"chrono",
|
||||||
|
"r2d2",
|
||||||
|
"uuidv07",
|
||||||
|
"postgres",
|
||||||
|
"serde_json",
|
||||||
|
"64-column-tables",
|
||||||
|
] }
|
||||||
|
diesel_migrations = { version = "1" }
|
||||||
|
diesel-derive-enum = { version = "1", features = ["postgres"] }
|
||||||
|
futures = { version = "0", default-features = false, features = [
|
||||||
|
"async-await",
|
||||||
|
] }
|
||||||
|
nats = { version = "0" }
|
||||||
|
once_cell = { version = "1" }
|
||||||
|
openssl = { version = "0", features = ["vendored"] }
|
||||||
|
prost = { version = "0" }
|
||||||
|
reqwest = { version = "0", features = ["json"] }
|
||||||
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
serde_json = { version = "1", features = ["raw_value"] }
|
||||||
|
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
|
||||||
|
tokio-cron-scheduler = { version = "0" }
|
||||||
|
uuid = { version = "0", features = ["serde", "v4", "v5"] }
|
||||||
|
|
||||||
|
beteran-protobuf-rust = { git = "https://gitlab.loafle.net/bet/beteran-protobuf-rust.git", tag = "v0.1.99-snapshot" }
|
||||||
|
beteran-common-rust = { git = "https://gitlab.loafle.net/bet/beteran-common-rust.git", tag = "v0.1.85-snapshot" }
|
||||||
|
|
||||||
|
[build-dependencies]
|
1
migrations/202208041000_initialize/down.sql
Normal file
1
migrations/202208041000_initialize/down.sql
Normal file
|
@ -0,0 +1 @@
|
||||||
|
DROP FUNCTION update_synchronizations;
|
16
migrations/202208041000_initialize/up.sql
Normal file
16
migrations/202208041000_initialize/up.sql
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
CREATE OR REPLACE FUNCTION update_synchronizations()
|
||||||
|
RETURNS TRIGGER AS $$
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO api_kgon_synchronizations
|
||||||
|
(item, last_code, synchronized_at)
|
||||||
|
VALUES
|
||||||
|
(NEW.item, NEW.code, (extract(epoch from now()) * 1000))
|
||||||
|
ON CONFLICT (item)
|
||||||
|
DO UPDATE
|
||||||
|
SET
|
||||||
|
last_code = NEW.code,
|
||||||
|
synchronized_at = (extract(epoch from now()) * 1000);
|
||||||
|
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$ language 'plpgsql';
|
|
@ -0,0 +1,2 @@
|
||||||
|
CREATE UNIQUE INDEX uidx_api_kgon_synchronizations_item;
|
||||||
|
DROP TABLE api_kgon_synchronization_members;
|
8
migrations/202208051000_api_kgon_synchronization/up.sql
Normal file
8
migrations/202208051000_api_kgon_synchronization/up.sql
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
CREATE TABLE IF NOT EXISTS api_kgon_synchronizations (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
item TEXT NOT NULL,
|
||||||
|
last_code BIGINT NOT NULL,
|
||||||
|
synchronized_at BIGINT NOT NULL DEFAULT (extract(epoch from now()) * 1000)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE UNIQUE INDEX uidx_api_kgon_synchronizations_item ON api_kgon_synchronizations (item);
|
|
@ -0,0 +1,3 @@
|
||||||
|
DROP TRIGGER tg_api_kgon_synchronization_history_synchronizations;
|
||||||
|
DROP INDEX idx_api_kgon_synchronization_history_item;
|
||||||
|
DROP TABLE api_kgon_synchronization_members;
|
|
@ -0,0 +1,21 @@
|
||||||
|
CREATE TABLE IF NOT EXISTS api_kgon_synchronization_history (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
item TEXT NOT NULL,
|
||||||
|
start_at BIGINT NOT NULL,
|
||||||
|
complete_at BIGINT NOT NULL,
|
||||||
|
code BIGINT NOT NULL,
|
||||||
|
message TEXT,
|
||||||
|
data TEXT,
|
||||||
|
created_at BIGINT NOT NULL DEFAULT (extract(epoch from now()) * 1000)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_api_kgon_synchronization_history_item ON api_kgon_synchronization_history (item);
|
||||||
|
CREATE INDEX idx_api_kgon_synchronization_history_created_at ON api_kgon_synchronization_history (created_at);
|
||||||
|
|
||||||
|
|
||||||
|
-- trigger (synchronized_at)
|
||||||
|
CREATE TRIGGER tg_api_kgon_synchronization_history_synchronizations
|
||||||
|
AFTER INSERT
|
||||||
|
ON api_kgon_synchronization_history
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE PROCEDURE update_synchronizations();
|
3
migrations/202208051200_api_kgon_member/down.sql
Normal file
3
migrations/202208051200_api_kgon_member/down.sql
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
DROP INDEX idx_api_kgon_members_member_id;
|
||||||
|
DROP TRIGGER tg_api_kgon_members_updated_at;
|
||||||
|
DROP TABLE api_kgon_members;
|
24
migrations/202208051200_api_kgon_member/up.sql
Normal file
24
migrations/202208051200_api_kgon_member/up.sql
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
CREATE TABLE IF NOT EXISTS api_kgon_members (
|
||||||
|
id BIGINT NOT NULL,
|
||||||
|
balance DOUBLE PRECISION NOT NULL DEFAULT 0.00,
|
||||||
|
balance_bota DOUBLE PRECISION NOT NULL DEFAULT 0.00,
|
||||||
|
balance_sum DOUBLE PRECISION NOT NULL DEFAULT 0.00,
|
||||||
|
companies TEXT,
|
||||||
|
oriental_play CHAR(1) NOT NULL DEFAULT 'n',
|
||||||
|
member_id UUID NOT NULL,
|
||||||
|
created_at BIGINT NOT NULL DEFAULT (extract(epoch from now()) * 1000),
|
||||||
|
updated_at BIGINT NOT NULL DEFAULT (extract(epoch from now()) * 1000),
|
||||||
|
PRIMARY KEY (id),
|
||||||
|
CONSTRAINT fk_api_kgon_members_member_id
|
||||||
|
FOREIGN KEY(member_id)
|
||||||
|
REFERENCES members(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_api_kgon_members_member_id ON api_kgon_members (member_id);
|
||||||
|
|
||||||
|
-- trigger (updated_at)
|
||||||
|
CREATE TRIGGER tg_api_kgon_members_updated_at
|
||||||
|
BEFORE UPDATE
|
||||||
|
ON api_kgon_members
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE PROCEDURE update_updated_at_column();
|
2
migrations/202208051400_api_kgon_balance/down.sql
Normal file
2
migrations/202208051400_api_kgon_balance/down.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
DROP TRIGGER tg_api_kgon_balances_updated_at;
|
||||||
|
DROP TABLE api_kgon_balances;
|
14
migrations/202208051400_api_kgon_balance/up.sql
Normal file
14
migrations/202208051400_api_kgon_balance/up.sql
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
CREATE TABLE IF NOT EXISTS api_kgon_balances (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
balance DOUBLE PRECISION NOT NULL DEFAULT 0.00,
|
||||||
|
balance_bota DOUBLE PRECISION NOT NULL DEFAULT 0.00,
|
||||||
|
created_at BIGINT NOT NULL DEFAULT (extract(epoch from now()) * 1000),
|
||||||
|
updated_at BIGINT NOT NULL DEFAULT (extract(epoch from now()) * 1000)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- trigger (updated_at)
|
||||||
|
CREATE TRIGGER tg_api_kgon_balances_updated_at
|
||||||
|
BEFORE UPDATE
|
||||||
|
ON api_kgon_balances
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE PROCEDURE update_updated_at_column();
|
6
migrations/202208061200_api_kgon_vendor/down.sql
Normal file
6
migrations/202208061200_api_kgon_vendor/down.sql
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
DROP INDEX idx_api_kgon_vendors_company_id;
|
||||||
|
DROP INDEX idx_api_kgon_vendors_vendor_id;
|
||||||
|
DROP INDEX idx_api_kgon_vendors_key;
|
||||||
|
DROP INDEX idx_api_kgon_vendors_category;
|
||||||
|
DROP TRIGGER tg_api_kgon_vendors_updated_at;
|
||||||
|
DROP TABLE api_kgon_vendors;
|
27
migrations/202208061200_api_kgon_vendor/up.sql
Normal file
27
migrations/202208061200_api_kgon_vendor/up.sql
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
CREATE TABLE IF NOT EXISTS api_kgon_vendors (
|
||||||
|
id BIGINT NOT NULL,
|
||||||
|
company_id BIGINT NOT NULL,
|
||||||
|
vendor_id BIGINT NOT NULL,
|
||||||
|
max_bet_casino DOUBLE PRECISION NOT NULL DEFAULT 0.00,
|
||||||
|
max_bet_slot DOUBLE PRECISION NOT NULL DEFAULT 0.00,
|
||||||
|
is_enable CHAR(1) NOT NULL,
|
||||||
|
bet_count BIGINT NOT NULL,
|
||||||
|
key TEXT NOT NULL,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
category TEXT NOT NULL,
|
||||||
|
created_at BIGINT NOT NULL DEFAULT (extract(epoch from now()) * 1000),
|
||||||
|
updated_at BIGINT NOT NULL DEFAULT (extract(epoch from now()) * 1000),
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_api_kgon_vendors_company_id ON api_kgon_vendors (company_id);
|
||||||
|
CREATE INDEX idx_api_kgon_vendors_vendor_id ON api_kgon_vendors (vendor_id);
|
||||||
|
CREATE INDEX idx_api_kgon_vendors_key ON api_kgon_vendors (key);
|
||||||
|
CREATE INDEX idx_api_kgon_vendors_category ON api_kgon_vendors (category);
|
||||||
|
|
||||||
|
-- trigger (updated_at)
|
||||||
|
CREATE TRIGGER tg_api_kgon_vendors_updated_at
|
||||||
|
BEFORE UPDATE
|
||||||
|
ON api_kgon_vendors
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE PROCEDURE update_updated_at_column();
|
6
migrations/202208061300_api_kgon_game/down.sql
Normal file
6
migrations/202208061300_api_kgon_game/down.sql
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
DROP INDEX idx_api_kgon_games_parent_id;
|
||||||
|
DROP INDEX idx_api_kgon_games_key;
|
||||||
|
DROP INDEX idx_api_kgon_games_category;
|
||||||
|
DROP INDEX idx_api_kgon_games_game_type;
|
||||||
|
DROP TRIGGER tg_api_kgon_games_updated_at;
|
||||||
|
DROP TABLE api_kgon_games;
|
28
migrations/202208061300_api_kgon_game/up.sql
Normal file
28
migrations/202208061300_api_kgon_game/up.sql
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
CREATE TABLE IF NOT EXISTS api_kgon_games (
|
||||||
|
id BIGINT NOT NULL,
|
||||||
|
parent_id BIGINT NOT NULL,
|
||||||
|
key TEXT NOT NULL,
|
||||||
|
names TEXT NOT NULL,
|
||||||
|
platform TEXT NOT NULL,
|
||||||
|
category TEXT NOT NULL,
|
||||||
|
game_type TEXT NOT NULL,
|
||||||
|
image TEXT,
|
||||||
|
created_at BIGINT NOT NULL DEFAULT (extract(epoch from now()) * 1000),
|
||||||
|
updated_at BIGINT NOT NULL DEFAULT (extract(epoch from now()) * 1000),
|
||||||
|
PRIMARY KEY (id),
|
||||||
|
CONSTRAINT fk_api_kgon_games_parent_id
|
||||||
|
FOREIGN KEY(parent_id)
|
||||||
|
REFERENCES api_kgon_vendors(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_api_kgon_games_parent_id ON api_kgon_games (parent_id);
|
||||||
|
CREATE INDEX idx_api_kgon_games_key ON api_kgon_games (key);
|
||||||
|
CREATE INDEX idx_api_kgon_games_category ON api_kgon_games (category);
|
||||||
|
CREATE INDEX idx_api_kgon_games_game_type ON api_kgon_games (game_type);
|
||||||
|
|
||||||
|
-- trigger (updated_at)
|
||||||
|
CREATE TRIGGER tg_api_kgon_games_updated_at
|
||||||
|
BEFORE UPDATE
|
||||||
|
ON api_kgon_games
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE PROCEDURE update_updated_at_column();
|
|
@ -0,0 +1,6 @@
|
||||||
|
DROP INDEX idx_api_kgon_betting_history_vendor_id;
|
||||||
|
DROP INDEX idx_api_kgon_betting_history_game_id;
|
||||||
|
DROP INDEX idx_api_kgon_betting_history_created_at;
|
||||||
|
DROP INDEX idx_api_kgon_betting_history_utc_created_at;
|
||||||
|
DROP INDEX idx_api_kgon_betting_history_site_username;
|
||||||
|
DROP TABLE api_kgon_betting_history;
|
33
migrations/202208101000_api_kgon_betting_history/up.sql
Normal file
33
migrations/202208101000_api_kgon_betting_history/up.sql
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
CREATE TABLE IF NOT EXISTS api_kgon_betting_history (
|
||||||
|
id TEXT NOT NULL,
|
||||||
|
vendor_id BIGINT NOT NULL,
|
||||||
|
vendor_name TEXT NOT NULL,
|
||||||
|
game_id BIGINT NOT NULL,
|
||||||
|
game_name TEXT NOT NULL,
|
||||||
|
game_category TEXT NOT NULL,
|
||||||
|
game_type TEXT NOT NULL,
|
||||||
|
currency TEXT NOT NULL,
|
||||||
|
cash DOUBLE PRECISION,
|
||||||
|
before_cash DOUBLE PRECISION,
|
||||||
|
after_cash DOUBLE PRECISION,
|
||||||
|
group_key TEXT,
|
||||||
|
detail TEXT,
|
||||||
|
is_bonus BOOLEAN NOT NULL,
|
||||||
|
is_promo BOOLEAN NOT NULL,
|
||||||
|
is_jackpot BOOLEAN NOT NULL,
|
||||||
|
site_username TEXT NOT NULL,
|
||||||
|
key TEXT NOT NULL,
|
||||||
|
ref_id TEXT NOT NULL,
|
||||||
|
o_ref_id TEXT,
|
||||||
|
betting_type TEXT NOT NULL,
|
||||||
|
category TEXT NOT NULL,
|
||||||
|
created_at BIGINT NOT NULL,
|
||||||
|
utc_created_at BIGINT NOT NULL,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_api_kgon_betting_history_vendor_id ON api_kgon_betting_history (vendor_id);
|
||||||
|
CREATE INDEX idx_api_kgon_betting_history_game_id ON api_kgon_betting_history (game_id);
|
||||||
|
CREATE INDEX idx_api_kgon_betting_history_created_at ON api_kgon_betting_history (created_at);
|
||||||
|
CREATE INDEX idx_api_kgon_betting_history_utc_created_at ON api_kgon_betting_history (utc_created_at);
|
||||||
|
CREATE INDEX idx_api_kgon_betting_history_site_username ON api_kgon_betting_history (site_username);
|
292
src/api/betting/api.rs
Normal file
292
src/api/betting/api.rs
Normal file
|
@ -0,0 +1,292 @@
|
||||||
|
use super::models;
|
||||||
|
use crate::api::core::models::Error;
|
||||||
|
use crate::core;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
///
|
||||||
|
pub struct Api {
|
||||||
|
client: reqwest::Client,
|
||||||
|
api_config: core::config::ApiConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Api {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Api of api.kgon.identity").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Api {
|
||||||
|
///
|
||||||
|
pub fn new(api_config: core::config::ApiConfig) -> Api {
|
||||||
|
Api {
|
||||||
|
client: reqwest::Client::new(),
|
||||||
|
api_config,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub async fn list_bettings(
|
||||||
|
&self,
|
||||||
|
data: models::ListBettingsRequest,
|
||||||
|
) -> Result<models::ListBettingsResponse, Error> {
|
||||||
|
let mut params = HashMap::new();
|
||||||
|
|
||||||
|
if let Some(vendor_key) = data.vendor_key {
|
||||||
|
params.insert("vendorKey", vendor_key);
|
||||||
|
}
|
||||||
|
if let Some(sdate) = data.sdate {
|
||||||
|
params.insert("sdate", sdate);
|
||||||
|
}
|
||||||
|
if let Some(edate) = data.edate {
|
||||||
|
params.insert("edate", edate);
|
||||||
|
}
|
||||||
|
if let Some(group_key) = data.group_key {
|
||||||
|
params.insert("groupKey", group_key);
|
||||||
|
}
|
||||||
|
if let Some(username) = data.username {
|
||||||
|
params.insert("username", username);
|
||||||
|
}
|
||||||
|
|
||||||
|
params.insert("limit", data.limit.to_string());
|
||||||
|
|
||||||
|
let res = match self
|
||||||
|
.client
|
||||||
|
.post(format!("{}/transaction", self.api_config.k_url))
|
||||||
|
.header(reqwest::header::ACCEPT, "application/json")
|
||||||
|
.header(
|
||||||
|
reqwest::header::CONTENT_TYPE,
|
||||||
|
"application/x-www-form-urlencoded",
|
||||||
|
)
|
||||||
|
.header("k-secret", self.api_config.k_secret.as_str())
|
||||||
|
.header("k-username", self.api_config.k_username.as_str())
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(e) => {
|
||||||
|
return Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match res.status() {
|
||||||
|
reqwest::StatusCode::OK => match res.json::<models::_ListBettingsResponse>().await {
|
||||||
|
Ok(r) => {
|
||||||
|
if r.code != 0 {
|
||||||
|
return Err(Error {
|
||||||
|
code: r.code,
|
||||||
|
msg: r.msg,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let transactions = r.transactions.unwrap_or_default();
|
||||||
|
let last_object_id = r.last_object_id;
|
||||||
|
|
||||||
|
Ok(models::ListBettingsResponse {
|
||||||
|
transactions,
|
||||||
|
last_object_id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(e) => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
_ => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: None,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub async fn get_gragmatic_betting(
|
||||||
|
&self,
|
||||||
|
data: models::GetPragmaticBettingRequest,
|
||||||
|
) -> Result<models::GetPragmaticBettingResponse, Error> {
|
||||||
|
let mut params = HashMap::new();
|
||||||
|
|
||||||
|
params.insert("id", data.id);
|
||||||
|
|
||||||
|
let res = match self
|
||||||
|
.client
|
||||||
|
.post(format!("{}/pragmatic/history", self.api_config.k_url))
|
||||||
|
.header(reqwest::header::ACCEPT, "application/json")
|
||||||
|
.header(
|
||||||
|
reqwest::header::CONTENT_TYPE,
|
||||||
|
"application/x-www-form-urlencoded",
|
||||||
|
)
|
||||||
|
.header("k-secret", self.api_config.k_secret.as_str())
|
||||||
|
.header("k-username", self.api_config.k_username.as_str())
|
||||||
|
.form(¶ms)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(e) => {
|
||||||
|
return Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match res.status() {
|
||||||
|
reqwest::StatusCode::OK => match res.json::<models::_GetPragmaticBettingResponse>().await {
|
||||||
|
Ok(r) => {
|
||||||
|
if r.code != 0 {
|
||||||
|
return Err(Error {
|
||||||
|
code: r.code,
|
||||||
|
msg: r.msg,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let url = match r.url {
|
||||||
|
Some(v) => v,
|
||||||
|
None => "".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(models::GetPragmaticBettingResponse { url })
|
||||||
|
}
|
||||||
|
Err(e) => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
_ => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: None,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub async fn get_evolution_betting_detail(
|
||||||
|
&self,
|
||||||
|
data: models::GetEvolutionBettingDetailRequest,
|
||||||
|
) -> Result<models::GetEvolutionBettingDetailResponse, Error> {
|
||||||
|
let mut params = HashMap::new();
|
||||||
|
|
||||||
|
params.insert("ids", data.ids);
|
||||||
|
|
||||||
|
let res = match self
|
||||||
|
.client
|
||||||
|
.post(format!(
|
||||||
|
"{}/evolution/transaction/detail",
|
||||||
|
self.api_config.k_url
|
||||||
|
))
|
||||||
|
.header(reqwest::header::ACCEPT, "application/json")
|
||||||
|
.header(
|
||||||
|
reqwest::header::CONTENT_TYPE,
|
||||||
|
"application/x-www-form-urlencoded",
|
||||||
|
)
|
||||||
|
.header("k-secret", self.api_config.k_secret.as_str())
|
||||||
|
.header("k-username", self.api_config.k_username.as_str())
|
||||||
|
.form(¶ms)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(e) => {
|
||||||
|
return Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match res.status() {
|
||||||
|
reqwest::StatusCode::OK => match res
|
||||||
|
.json::<models::_GetEvolutionBettingDetailResponse>()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(r) => {
|
||||||
|
if r.code != 0 {
|
||||||
|
return Err(Error {
|
||||||
|
code: r.code,
|
||||||
|
msg: r.msg,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let transactions = r.transactions.unwrap_or_default();
|
||||||
|
|
||||||
|
Ok(models::GetEvolutionBettingDetailResponse { transactions })
|
||||||
|
}
|
||||||
|
Err(e) => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
_ => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: None,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub async fn get_statistic(
|
||||||
|
&self,
|
||||||
|
data: models::GetStatisticRequest,
|
||||||
|
) -> Result<models::GetStatisticResponse, Error> {
|
||||||
|
let mut params = HashMap::new();
|
||||||
|
|
||||||
|
if let Some(vendor_key) = data.vendor_key {
|
||||||
|
params.insert("vendorKey", vendor_key);
|
||||||
|
}
|
||||||
|
if let Some(group_key) = data.group_key {
|
||||||
|
params.insert("groupKey", group_key);
|
||||||
|
}
|
||||||
|
if let Some(date) = data.date {
|
||||||
|
params.insert("date", date);
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = match self
|
||||||
|
.client
|
||||||
|
.post(format!("{}/statistic", self.api_config.k_url))
|
||||||
|
.header(reqwest::header::ACCEPT, "application/json")
|
||||||
|
.header(
|
||||||
|
reqwest::header::CONTENT_TYPE,
|
||||||
|
"application/x-www-form-urlencoded",
|
||||||
|
)
|
||||||
|
.header("k-secret", self.api_config.k_secret.as_str())
|
||||||
|
.header("k-username", self.api_config.k_username.as_str())
|
||||||
|
.form(¶ms)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(e) => {
|
||||||
|
return Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match res.status() {
|
||||||
|
reqwest::StatusCode::OK => match res.json::<models::_GetStatisticResponse>().await {
|
||||||
|
Ok(r) => {
|
||||||
|
if r.code != 0 {
|
||||||
|
return Err(Error {
|
||||||
|
code: r.code,
|
||||||
|
msg: r.msg,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(models::GetStatisticResponse { data: r.data })
|
||||||
|
}
|
||||||
|
Err(e) => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
_ => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: None,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
src/api/betting/mod.rs
Normal file
7
src/api/betting/mod.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
|
///
|
||||||
|
pub mod api;
|
||||||
|
///
|
||||||
|
pub mod models;
|
168
src/api/betting/models.rs
Normal file
168
src/api/betting/models.rs
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Betting {
|
||||||
|
/// KGON 거래 고유 코드
|
||||||
|
pub _id: String,
|
||||||
|
/// 게임사 코드
|
||||||
|
#[serde(rename = "vendorId")]
|
||||||
|
pub vendor_id: i64,
|
||||||
|
/// 게임사
|
||||||
|
#[serde(rename = "vendorName")]
|
||||||
|
pub vendor_name: String,
|
||||||
|
/// 게임코드
|
||||||
|
#[serde(rename = "gameId")]
|
||||||
|
pub game_id: i64,
|
||||||
|
/// 게임명
|
||||||
|
#[serde(rename = "gameName")]
|
||||||
|
pub game_name: String,
|
||||||
|
/// 게임종류
|
||||||
|
#[serde(rename = "gameCategory")]
|
||||||
|
pub game_category: String,
|
||||||
|
/// 게임형식
|
||||||
|
#[serde(rename = "gameType")]
|
||||||
|
pub game_type: String,
|
||||||
|
/// 환율
|
||||||
|
pub currency: String,
|
||||||
|
/// 거래금액
|
||||||
|
pub cash: f64,
|
||||||
|
/// 이전보유금액
|
||||||
|
#[serde(rename = "beforeCash")]
|
||||||
|
pub before_cash: f64,
|
||||||
|
/// 이후보유금액
|
||||||
|
#[serde(rename = "afterCash")]
|
||||||
|
pub after_cash: f64,
|
||||||
|
/// 사이트 매장 코드
|
||||||
|
#[serde(rename = "groupKey")]
|
||||||
|
pub group_key: Option<String>,
|
||||||
|
/// 게임 데이터
|
||||||
|
pub detail: Option<Box<serde_json::value::RawValue>>,
|
||||||
|
/// 보너스 여부
|
||||||
|
#[serde(rename = "isBonus")]
|
||||||
|
pub is_bonus: bool,
|
||||||
|
/// 프로모션 여부
|
||||||
|
#[serde(rename = "isPromo")]
|
||||||
|
pub is_promo: bool,
|
||||||
|
/// 잭팟 여부
|
||||||
|
#[serde(rename = "isJackpot")]
|
||||||
|
pub is_jackpot: bool,
|
||||||
|
/// 사이트 회원 아이디
|
||||||
|
#[serde(rename = "siteUsername")]
|
||||||
|
pub site_username: String,
|
||||||
|
/// 게임사 고유코드
|
||||||
|
pub key: String,
|
||||||
|
/// 게임사 상위 배팅 코드
|
||||||
|
#[serde(rename = "refId")]
|
||||||
|
pub ref_id: String,
|
||||||
|
#[serde(rename = "oRefId")]
|
||||||
|
pub o_ref_id: Option<String>,
|
||||||
|
/// 결과로서 turn_bet, turn_win, turn_draw, turn_cancel이 존재
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub betting_type: String,
|
||||||
|
/// 카테고리
|
||||||
|
pub category: String,
|
||||||
|
/// 일자 - 파트너의 timezone 반영
|
||||||
|
#[serde(rename = "createdAt")]
|
||||||
|
pub created_at: String,
|
||||||
|
/// UTC TIME 으로서 한국시간에서 9시간이 빠진 시간입니다. 다음 검색시 sdate에 입력하세요
|
||||||
|
#[serde(rename = "utcCreatedAt")]
|
||||||
|
pub utc_created_at: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct ListBettingsRequest {
|
||||||
|
pub vendor_key: Option<String>,
|
||||||
|
pub sdate: Option<String>,
|
||||||
|
pub edate: Option<String>,
|
||||||
|
pub group_key: Option<String>,
|
||||||
|
pub username: Option<String>,
|
||||||
|
pub limit: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct _ListBettingsResponse {
|
||||||
|
pub code: i64,
|
||||||
|
pub msg: Option<String>,
|
||||||
|
pub transactions: Option<Vec<Betting>>,
|
||||||
|
#[serde(rename = "lastObjectId")]
|
||||||
|
pub last_object_id: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct ListBettingsResponse {
|
||||||
|
pub transactions: Vec<Betting>,
|
||||||
|
pub last_object_id: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct GetPragmaticBettingRequest {
|
||||||
|
pub id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct _GetPragmaticBettingResponse {
|
||||||
|
pub code: i64,
|
||||||
|
pub msg: Option<String>,
|
||||||
|
pub url: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct GetPragmaticBettingResponse {
|
||||||
|
pub url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct EvolutionBettingDetail {
|
||||||
|
pub id: String,
|
||||||
|
pub detail: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct GetEvolutionBettingDetailRequest {
|
||||||
|
pub ids: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct _GetEvolutionBettingDetailResponse {
|
||||||
|
pub code: i64,
|
||||||
|
pub msg: Option<String>,
|
||||||
|
pub transactions: Option<Vec<EvolutionBettingDetail>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct GetEvolutionBettingDetailResponse {
|
||||||
|
pub transactions: Vec<EvolutionBettingDetail>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Statistic {
|
||||||
|
#[serde(rename = "betAmount")]
|
||||||
|
pub bet_amount: f64,
|
||||||
|
#[serde(rename = "drawAmount")]
|
||||||
|
pub draw_amount: f64,
|
||||||
|
#[serde(rename = "cancelAmount")]
|
||||||
|
pub cancel_amount: f64,
|
||||||
|
#[serde(rename = "winAmount")]
|
||||||
|
pub win_amount: f64,
|
||||||
|
#[serde(rename = "revenueAmount")]
|
||||||
|
pub revenue_amount: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct GetStatisticRequest {
|
||||||
|
pub vendor_key: Option<String>,
|
||||||
|
pub group_key: Option<String>,
|
||||||
|
pub date: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct _GetStatisticResponse {
|
||||||
|
pub code: i64,
|
||||||
|
pub msg: Option<String>,
|
||||||
|
pub data: Option<Statistic>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct GetStatisticResponse {
|
||||||
|
pub data: Option<Statistic>,
|
||||||
|
}
|
1
src/api/core/mod.rs
Normal file
1
src/api/core/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod models;
|
5
src/api/core/models.rs
Normal file
5
src/api/core/models.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Error {
|
||||||
|
pub code: i64,
|
||||||
|
pub msg: Option<String>,
|
||||||
|
}
|
166
src/api/game/api.rs
Normal file
166
src/api/game/api.rs
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
use super::models;
|
||||||
|
use crate::api::core::models::Error;
|
||||||
|
use crate::core;
|
||||||
|
use std::{collections::HashMap, time::Duration};
|
||||||
|
|
||||||
|
///
|
||||||
|
pub struct Api {
|
||||||
|
client: reqwest::Client,
|
||||||
|
api_config: core::config::ApiConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Api {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Api of api.kgon.identity").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Api {
|
||||||
|
///
|
||||||
|
pub fn new(api_config: core::config::ApiConfig) -> Api {
|
||||||
|
Api {
|
||||||
|
client: reqwest::Client::new(),
|
||||||
|
api_config,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub async fn list_games(
|
||||||
|
&self,
|
||||||
|
data: models::ListGamesRequest,
|
||||||
|
) -> Result<models::ListGamesResponse, Error> {
|
||||||
|
let mut params = HashMap::new();
|
||||||
|
|
||||||
|
params.insert("vendorKey", data.vendor_key);
|
||||||
|
|
||||||
|
let res = match self
|
||||||
|
.client
|
||||||
|
.post(format!("{}/games", self.api_config.k_url))
|
||||||
|
.header(reqwest::header::ACCEPT, "application/json")
|
||||||
|
.header(
|
||||||
|
reqwest::header::CONTENT_TYPE,
|
||||||
|
"application/x-www-form-urlencoded",
|
||||||
|
)
|
||||||
|
.header("k-secret", self.api_config.k_secret.as_str())
|
||||||
|
.header("k-username", self.api_config.k_username.as_str())
|
||||||
|
.form(¶ms)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(e) => {
|
||||||
|
return Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match res.status() {
|
||||||
|
reqwest::StatusCode::OK => match res.json::<models::_ListGamesResponse>().await {
|
||||||
|
Ok(r) => {
|
||||||
|
if r.code != 0 {
|
||||||
|
return Err(Error {
|
||||||
|
code: r.code,
|
||||||
|
msg: r.msg,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let games = match r.games {
|
||||||
|
Some(v) => v,
|
||||||
|
None => vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(models::ListGamesResponse { games })
|
||||||
|
}
|
||||||
|
Err(e) => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
_ => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: None,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub async fn get_game_url(
|
||||||
|
&self,
|
||||||
|
data: models::GetGameUrlRequest,
|
||||||
|
) -> Result<models::GetGameUrlResponse, Error> {
|
||||||
|
let mut params = HashMap::new();
|
||||||
|
|
||||||
|
params.insert("vendorKey", data.vendor_key);
|
||||||
|
params.insert("gameKey", data.game_key);
|
||||||
|
params.insert("username", data.username);
|
||||||
|
params.insert("nickname", data.nickname);
|
||||||
|
params.insert("siteUsername", data.site_username);
|
||||||
|
|
||||||
|
if let Some(group_key) = data.group_key {
|
||||||
|
params.insert("groupKey", group_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
params.insert("amount", data.amount.to_string());
|
||||||
|
|
||||||
|
if let Some(request_key) = data.request_key {
|
||||||
|
params.insert("requestKey", request_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = match self
|
||||||
|
.client
|
||||||
|
.post(format!("{}/play", self.api_config.k_url))
|
||||||
|
.header(reqwest::header::ACCEPT, "application/json")
|
||||||
|
.header(
|
||||||
|
reqwest::header::CONTENT_TYPE,
|
||||||
|
"application/x-www-form-urlencoded",
|
||||||
|
)
|
||||||
|
.header("k-secret", self.api_config.k_secret.as_str())
|
||||||
|
.header("k-username", self.api_config.k_username.as_str())
|
||||||
|
.form(¶ms)
|
||||||
|
.timeout(Duration::from_secs(10))
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(e) => {
|
||||||
|
return Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match res.status() {
|
||||||
|
reqwest::StatusCode::OK => match res.json::<models::_GetGameUrlResponse>().await {
|
||||||
|
Ok(r) => {
|
||||||
|
if r.code != 0 {
|
||||||
|
return Err(Error {
|
||||||
|
code: r.code,
|
||||||
|
msg: r.msg,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let user_id = r.user_id.unwrap_or(0);
|
||||||
|
let url = r.url.unwrap_or_else(|| "".to_string());
|
||||||
|
let balance = r.balance.unwrap_or(0.00);
|
||||||
|
|
||||||
|
Ok(models::GetGameUrlResponse {
|
||||||
|
user_id,
|
||||||
|
url,
|
||||||
|
balance,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(e) => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
_ => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: None,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
src/api/game/mod.rs
Normal file
7
src/api/game/mod.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
|
///
|
||||||
|
pub mod api;
|
||||||
|
///
|
||||||
|
pub mod models;
|
58
src/api/game/models.rs
Normal file
58
src/api/game/models.rs
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Game {
|
||||||
|
pub id: i64,
|
||||||
|
pub key: String,
|
||||||
|
pub names: HashMap<String, String>,
|
||||||
|
pub platform: String,
|
||||||
|
pub category: String,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub game_type: String,
|
||||||
|
pub image: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ListGamesRequest {
|
||||||
|
pub vendor_key: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct _ListGamesResponse {
|
||||||
|
pub code: i64,
|
||||||
|
pub msg: Option<String>,
|
||||||
|
pub games: Option<Vec<Game>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ListGamesResponse {
|
||||||
|
pub games: Vec<Game>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct GetGameUrlRequest {
|
||||||
|
pub vendor_key: String,
|
||||||
|
pub game_key: String,
|
||||||
|
pub username: String,
|
||||||
|
pub nickname: String,
|
||||||
|
pub site_username: String,
|
||||||
|
pub group_key: Option<String>,
|
||||||
|
pub amount: f64,
|
||||||
|
pub request_key: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct _GetGameUrlResponse {
|
||||||
|
pub code: i64,
|
||||||
|
pub msg: Option<String>,
|
||||||
|
#[serde(rename = "userId")]
|
||||||
|
pub user_id: Option<i64>,
|
||||||
|
pub url: Option<String>,
|
||||||
|
pub balance: Option<f64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct GetGameUrlResponse {
|
||||||
|
pub user_id: i64,
|
||||||
|
pub url: String,
|
||||||
|
pub balance: f64,
|
||||||
|
}
|
153
src/api/member/api.rs
Normal file
153
src/api/member/api.rs
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
use super::models;
|
||||||
|
use crate::api::core::models::Error;
|
||||||
|
use crate::core;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
///
|
||||||
|
pub struct Api {
|
||||||
|
client: reqwest::Client,
|
||||||
|
api_config: core::config::ApiConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Api {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Api of api.kgon.identity").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Api {
|
||||||
|
///
|
||||||
|
pub fn new(api_config: core::config::ApiConfig) -> Api {
|
||||||
|
Api {
|
||||||
|
client: reqwest::Client::new(),
|
||||||
|
api_config,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub async fn list_members(
|
||||||
|
&self,
|
||||||
|
data: models::ListMembersRequest,
|
||||||
|
) -> Result<models::ListMembersResponse, Error> {
|
||||||
|
let mut params = HashMap::new();
|
||||||
|
|
||||||
|
if let Some(group_key) = data.group_key {
|
||||||
|
params.insert("groupKey", group_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = match self
|
||||||
|
.client
|
||||||
|
.post(format!("{}/users", self.api_config.k_url))
|
||||||
|
.header(reqwest::header::ACCEPT, "application/json")
|
||||||
|
.header(
|
||||||
|
reqwest::header::CONTENT_TYPE,
|
||||||
|
"application/x-www-form-urlencoded",
|
||||||
|
)
|
||||||
|
.header("k-secret", self.api_config.k_secret.as_str())
|
||||||
|
.header("k-username", self.api_config.k_username.as_str())
|
||||||
|
.form(¶ms)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(e) => {
|
||||||
|
return Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match res.status() {
|
||||||
|
reqwest::StatusCode::OK => match res.json::<models::_ListMembersResponse>().await {
|
||||||
|
Ok(r) => {
|
||||||
|
if r.code != 0 {
|
||||||
|
return Err(Error {
|
||||||
|
code: r.code,
|
||||||
|
msg: r.msg,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let users = match r.users {
|
||||||
|
Some(v) => v,
|
||||||
|
None => vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(models::ListMembersResponse { users })
|
||||||
|
}
|
||||||
|
Err(e) => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
_ => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: None,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub async fn create_member(
|
||||||
|
&self,
|
||||||
|
data: models::CreateMemberRequest,
|
||||||
|
) -> Result<models::CreateMemberResponse, Error> {
|
||||||
|
let mut params = HashMap::new();
|
||||||
|
|
||||||
|
params.insert("username", data.username);
|
||||||
|
params.insert("nickname", data.nickname);
|
||||||
|
params.insert("siteUsername", data.site_username);
|
||||||
|
|
||||||
|
if let Some(group_key) = data.group_key {
|
||||||
|
params.insert("groupKey", group_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = match self
|
||||||
|
.client
|
||||||
|
.post(format!("{}/register", self.api_config.k_url))
|
||||||
|
.header(reqwest::header::ACCEPT, "application/json")
|
||||||
|
.header(
|
||||||
|
reqwest::header::CONTENT_TYPE,
|
||||||
|
"application/x-www-form-urlencoded",
|
||||||
|
)
|
||||||
|
.header("k-secret", self.api_config.k_secret.as_str())
|
||||||
|
.header("k-username", self.api_config.k_username.as_str())
|
||||||
|
.form(¶ms)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(e) => {
|
||||||
|
return Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match res.status() {
|
||||||
|
reqwest::StatusCode::OK => match res.json::<models::_CreateMemberResponse>().await {
|
||||||
|
Ok(r) => {
|
||||||
|
if r.code != 0 {
|
||||||
|
return Err(Error {
|
||||||
|
code: r.code,
|
||||||
|
msg: r.msg,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let id = r.id.unwrap_or(0);
|
||||||
|
|
||||||
|
Ok(models::CreateMemberResponse { id })
|
||||||
|
}
|
||||||
|
Err(e) => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
_ => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: None,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
src/api/member/mod.rs
Normal file
7
src/api/member/mod.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
|
///
|
||||||
|
pub mod api;
|
||||||
|
///
|
||||||
|
pub mod models;
|
50
src/api/member/models.rs
Normal file
50
src/api/member/models.rs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct ListMembersRequest {
|
||||||
|
pub group_key: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Member {
|
||||||
|
pub id: i64,
|
||||||
|
pub username: String,
|
||||||
|
pub cash: f64,
|
||||||
|
pub cash_bota: f64,
|
||||||
|
pub nickname: String,
|
||||||
|
pub site_username: String,
|
||||||
|
pub group_key: Option<String>,
|
||||||
|
pub oriental_play: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct _ListMembersResponse {
|
||||||
|
pub code: i64,
|
||||||
|
pub msg: Option<String>,
|
||||||
|
pub users: Option<Vec<Member>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ListMembersResponse {
|
||||||
|
pub users: Vec<Member>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct CreateMemberRequest {
|
||||||
|
pub username: String,
|
||||||
|
pub nickname: String,
|
||||||
|
pub site_username: String,
|
||||||
|
pub group_key: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct _CreateMemberResponse {
|
||||||
|
pub code: i64,
|
||||||
|
pub msg: Option<String>,
|
||||||
|
pub id: Option<i64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct CreateMemberResponse {
|
||||||
|
pub id: i64,
|
||||||
|
}
|
283
src/api/member_account/api.rs
Normal file
283
src/api/member_account/api.rs
Normal file
|
@ -0,0 +1,283 @@
|
||||||
|
use super::models;
|
||||||
|
use crate::api::core::models::Error;
|
||||||
|
use crate::core;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
///
|
||||||
|
pub struct Api {
|
||||||
|
client: reqwest::Client,
|
||||||
|
api_config: core::config::ApiConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Api {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Api of api.kgon.member_account").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Api {
|
||||||
|
///
|
||||||
|
pub fn new(api_config: core::config::ApiConfig) -> Api {
|
||||||
|
Api {
|
||||||
|
client: reqwest::Client::new(),
|
||||||
|
api_config,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub async fn get_balance_for_user(
|
||||||
|
&self,
|
||||||
|
data: models::GetBalanceForUserRequest,
|
||||||
|
) -> Result<models::GetBalanceForUserResponse, Error> {
|
||||||
|
let mut params = HashMap::new();
|
||||||
|
|
||||||
|
params.insert("username", data.username);
|
||||||
|
|
||||||
|
let res = match self
|
||||||
|
.client
|
||||||
|
.post(format!("{}/balance", self.api_config.k_url))
|
||||||
|
.header(reqwest::header::ACCEPT, "application/json")
|
||||||
|
.header(
|
||||||
|
reqwest::header::CONTENT_TYPE,
|
||||||
|
"application/x-www-form-urlencoded",
|
||||||
|
)
|
||||||
|
.header("k-secret", self.api_config.k_secret.as_str())
|
||||||
|
.header("k-username", self.api_config.k_username.as_str())
|
||||||
|
.form(¶ms)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(e) => {
|
||||||
|
return Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match res.status() {
|
||||||
|
reqwest::StatusCode::OK => match res.json::<models::_GetBalanceForUserResponse>().await {
|
||||||
|
Ok(r) => {
|
||||||
|
if r.code != 0 {
|
||||||
|
return Err(Error {
|
||||||
|
code: r.code,
|
||||||
|
msg: r.msg,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let balance = r.balance.unwrap_or(0.00);
|
||||||
|
let balance_bota = r.balance_bota.unwrap_or(0.00);
|
||||||
|
let balance_sum = r.balance_sum.unwrap_or(0.00);
|
||||||
|
let companies = r.companies.map(|v| v.get().to_string());
|
||||||
|
|
||||||
|
Ok(models::GetBalanceForUserResponse {
|
||||||
|
balance,
|
||||||
|
balance_bota,
|
||||||
|
balance_sum,
|
||||||
|
companies,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(e) => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
_ => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: None,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub async fn get_balance_for_partner(
|
||||||
|
&self,
|
||||||
|
data: models::GetBalanceForPartnerRequest,
|
||||||
|
) -> Result<models::GetBalanceForPartnerResponse, Error> {
|
||||||
|
let res = match self
|
||||||
|
.client
|
||||||
|
.post(format!("{}/partner/balance", self.api_config.k_url))
|
||||||
|
.header(reqwest::header::ACCEPT, "application/json")
|
||||||
|
.header(
|
||||||
|
reqwest::header::CONTENT_TYPE,
|
||||||
|
"application/x-www-form-urlencoded",
|
||||||
|
)
|
||||||
|
.header("k-secret", self.api_config.k_secret.as_str())
|
||||||
|
.header("k-username", self.api_config.k_username.as_str())
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(e) => {
|
||||||
|
return Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match res.status() {
|
||||||
|
reqwest::StatusCode::OK => match res.json::<models::_GetBalanceForPartnerResponse>().await {
|
||||||
|
Ok(r) => {
|
||||||
|
if r.code != 0 {
|
||||||
|
return Err(Error {
|
||||||
|
code: r.code,
|
||||||
|
msg: r.msg,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let balance = r.balance.unwrap_or(0.00);
|
||||||
|
let balance_bota = r.balance_bota.unwrap_or(0.00);
|
||||||
|
|
||||||
|
Ok(models::GetBalanceForPartnerResponse {
|
||||||
|
balance,
|
||||||
|
balance_bota,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(e) => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
_ => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: None,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub async fn create_deposit(
|
||||||
|
&self,
|
||||||
|
data: models::CreateDepositRequest,
|
||||||
|
) -> Result<models::CreateDepositResponse, Error> {
|
||||||
|
let mut params = HashMap::new();
|
||||||
|
|
||||||
|
params.insert("username", data.username);
|
||||||
|
if let Some(cash_type) = data.cash_type {
|
||||||
|
params.insert("cashType", cash_type);
|
||||||
|
}
|
||||||
|
params.insert("amount", data.amount.to_string());
|
||||||
|
if let Some(request_key) = data.request_key {
|
||||||
|
params.insert("requestKey", request_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = match self
|
||||||
|
.client
|
||||||
|
.post(format!("{}/deposit", self.api_config.k_url))
|
||||||
|
.header(reqwest::header::ACCEPT, "application/json")
|
||||||
|
.header(
|
||||||
|
reqwest::header::CONTENT_TYPE,
|
||||||
|
"application/x-www-form-urlencoded",
|
||||||
|
)
|
||||||
|
.header("k-secret", self.api_config.k_secret.as_str())
|
||||||
|
.header("k-username", self.api_config.k_username.as_str())
|
||||||
|
.form(¶ms)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(e) => {
|
||||||
|
return Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match res.status() {
|
||||||
|
reqwest::StatusCode::OK => match res.json::<models::_CreateDepositResponse>().await {
|
||||||
|
Ok(r) => {
|
||||||
|
if r.code != 0 {
|
||||||
|
return Err(Error {
|
||||||
|
code: r.code,
|
||||||
|
msg: r.msg,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let balance = r.balance.unwrap_or(0.00);
|
||||||
|
|
||||||
|
Ok(models::CreateDepositResponse { balance })
|
||||||
|
}
|
||||||
|
Err(e) => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
_ => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: None,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub async fn create_withdraw(
|
||||||
|
&self,
|
||||||
|
data: models::CreateWithdrawRequest,
|
||||||
|
) -> Result<models::CreateWithdrawResponse, Error> {
|
||||||
|
let mut params = HashMap::new();
|
||||||
|
|
||||||
|
params.insert("username", data.username);
|
||||||
|
if let Some(request_key) = data.request_key {
|
||||||
|
params.insert("requestKey", request_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = match self
|
||||||
|
.client
|
||||||
|
.post(format!("{}/withdraw", self.api_config.k_url))
|
||||||
|
.header(reqwest::header::ACCEPT, "application/json")
|
||||||
|
.header(
|
||||||
|
reqwest::header::CONTENT_TYPE,
|
||||||
|
"application/x-www-form-urlencoded",
|
||||||
|
)
|
||||||
|
.header("k-secret", self.api_config.k_secret.as_str())
|
||||||
|
.header("k-username", self.api_config.k_username.as_str())
|
||||||
|
.form(¶ms)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(e) => {
|
||||||
|
return Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match res.status() {
|
||||||
|
reqwest::StatusCode::OK => match res.json::<models::_CreateWithdrawResponse>().await {
|
||||||
|
Ok(r) => {
|
||||||
|
if r.code != 0 {
|
||||||
|
return Err(Error {
|
||||||
|
code: r.code,
|
||||||
|
msg: r.msg,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let balance = r.balance.unwrap_or(0.00);
|
||||||
|
let balance_cash = r.balance_cash.unwrap_or(0.00);
|
||||||
|
let balance_cash_bota = r.balance_cash_bota.unwrap_or(0.00);
|
||||||
|
let amount = r.amount.unwrap_or(0.00);
|
||||||
|
|
||||||
|
Ok(models::CreateWithdrawResponse {
|
||||||
|
balance,
|
||||||
|
balance_cash,
|
||||||
|
balance_cash_bota,
|
||||||
|
amount,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(e) => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
_ => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: None,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
src/api/member_account/mod.rs
Normal file
7
src/api/member_account/mod.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
|
///
|
||||||
|
pub mod api;
|
||||||
|
///
|
||||||
|
pub mod models;
|
87
src/api/member_account/models.rs
Normal file
87
src/api/member_account/models.rs
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
pub struct GetBalanceForUserRequest {
|
||||||
|
pub username: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct _GetBalanceForUserResponse {
|
||||||
|
pub code: i64,
|
||||||
|
pub msg: Option<String>,
|
||||||
|
pub balance: Option<f64>,
|
||||||
|
#[serde(rename = "balanceBota")]
|
||||||
|
pub balance_bota: Option<f64>,
|
||||||
|
#[serde(rename = "balanceSum")]
|
||||||
|
pub balance_sum: Option<f64>,
|
||||||
|
pub companies: Option<Box<serde_json::value::RawValue>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct GetBalanceForUserResponse {
|
||||||
|
pub balance: f64,
|
||||||
|
#[serde(rename = "balanceBota")]
|
||||||
|
pub balance_bota: f64,
|
||||||
|
#[serde(rename = "balanceSum")]
|
||||||
|
pub balance_sum: f64,
|
||||||
|
pub companies: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct GetBalanceForPartnerRequest {}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct _GetBalanceForPartnerResponse {
|
||||||
|
pub code: i64,
|
||||||
|
pub msg: Option<String>,
|
||||||
|
pub balance: Option<f64>,
|
||||||
|
#[serde(rename = "balanceBota")]
|
||||||
|
pub balance_bota: Option<f64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct GetBalanceForPartnerResponse {
|
||||||
|
pub balance: f64,
|
||||||
|
#[serde(rename = "balanceBota")]
|
||||||
|
pub balance_bota: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CreateDepositRequest {
|
||||||
|
pub username: String,
|
||||||
|
pub cash_type: Option<String>,
|
||||||
|
pub amount: f64,
|
||||||
|
pub request_key: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct _CreateDepositResponse {
|
||||||
|
pub code: i64,
|
||||||
|
pub msg: Option<String>,
|
||||||
|
pub balance: Option<f64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct CreateDepositResponse {
|
||||||
|
pub balance: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CreateWithdrawRequest {
|
||||||
|
pub username: String,
|
||||||
|
pub request_key: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct _CreateWithdrawResponse {
|
||||||
|
pub code: i64,
|
||||||
|
pub msg: Option<String>,
|
||||||
|
pub balance: Option<f64>,
|
||||||
|
pub balance_cash: Option<f64>,
|
||||||
|
pub balance_cash_bota: Option<f64>,
|
||||||
|
pub amount: Option<f64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct CreateWithdrawResponse {
|
||||||
|
pub balance: f64,
|
||||||
|
pub balance_cash: f64,
|
||||||
|
pub balance_cash_bota: f64,
|
||||||
|
pub amount: f64,
|
||||||
|
}
|
6
src/api/mod.rs
Normal file
6
src/api/mod.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
pub mod betting;
|
||||||
|
pub mod core;
|
||||||
|
pub mod game;
|
||||||
|
pub mod member;
|
||||||
|
pub mod member_account;
|
||||||
|
pub mod vendor;
|
81
src/api/vendor/api.rs
vendored
Normal file
81
src/api/vendor/api.rs
vendored
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
use super::models;
|
||||||
|
use crate::api::core::models::Error;
|
||||||
|
use crate::core;
|
||||||
|
|
||||||
|
///
|
||||||
|
pub struct Api {
|
||||||
|
client: reqwest::Client,
|
||||||
|
api_config: core::config::ApiConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Api {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Api of api.kgon.identity").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Api {
|
||||||
|
///
|
||||||
|
pub fn new(api_config: core::config::ApiConfig) -> Api {
|
||||||
|
Api {
|
||||||
|
client: reqwest::Client::new(),
|
||||||
|
api_config,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub async fn list_vendors(
|
||||||
|
&self,
|
||||||
|
data: models::ListVendorsRequest,
|
||||||
|
) -> Result<models::ListVendorsResponse, Error> {
|
||||||
|
let res = match self
|
||||||
|
.client
|
||||||
|
.post(format!("{}/vendors", self.api_config.k_url))
|
||||||
|
.header(reqwest::header::ACCEPT, "application/json")
|
||||||
|
.header(
|
||||||
|
reqwest::header::CONTENT_TYPE,
|
||||||
|
"application/x-www-form-urlencoded",
|
||||||
|
)
|
||||||
|
.header("k-secret", self.api_config.k_secret.as_str())
|
||||||
|
.header("k-username", self.api_config.k_username.as_str())
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(e) => {
|
||||||
|
return Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match res.status() {
|
||||||
|
reqwest::StatusCode::OK => match res.json::<models::_ListVendorsResponse>().await {
|
||||||
|
Ok(r) => {
|
||||||
|
if r.code != 0 {
|
||||||
|
return Err(Error {
|
||||||
|
code: r.code,
|
||||||
|
msg: r.msg,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let vendors = match r.vendors {
|
||||||
|
Some(v) => v,
|
||||||
|
None => vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(models::ListVendorsResponse { vendors })
|
||||||
|
}
|
||||||
|
Err(e) => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: Some(e.to_string()),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
_ => Err(Error {
|
||||||
|
code: -1,
|
||||||
|
msg: None,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
src/api/vendor/mod.rs
vendored
Normal file
7
src/api/vendor/mod.rs
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
|
///
|
||||||
|
pub mod api;
|
||||||
|
///
|
||||||
|
pub mod models;
|
29
src/api/vendor/models.rs
vendored
Normal file
29
src/api/vendor/models.rs
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Vendor {
|
||||||
|
pub id: i64,
|
||||||
|
pub company_id: i64,
|
||||||
|
pub vendor_id: i64,
|
||||||
|
pub max_bet_casino: f64,
|
||||||
|
pub max_bet_slot: f64,
|
||||||
|
pub is_enable: String,
|
||||||
|
pub bet_count: i64,
|
||||||
|
pub key: String,
|
||||||
|
pub name: String,
|
||||||
|
pub category: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ListVendorsRequest {}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct _ListVendorsResponse {
|
||||||
|
pub code: i64,
|
||||||
|
pub msg: Option<String>,
|
||||||
|
pub vendors: Option<Vec<Vendor>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ListVendorsResponse {
|
||||||
|
pub vendors: Vec<Vendor>,
|
||||||
|
}
|
615
src/compositions/betting/composition.rs
Normal file
615
src/compositions/betting/composition.rs
Normal file
|
@ -0,0 +1,615 @@
|
||||||
|
use super::models;
|
||||||
|
use beteran_common_rust as bcr;
|
||||||
|
use diesel::{result::Error, sql_query, RunQueryDsl};
|
||||||
|
use std::fmt::Write;
|
||||||
|
|
||||||
|
static BETTING_HISTORY_COUNT_QUERY: &str = "
|
||||||
|
SELECT
|
||||||
|
COUNT(akbh.id)
|
||||||
|
FROM api_kgon_betting_history as akbh
|
||||||
|
INNER JOIN members m
|
||||||
|
ON m.username = akbh.site_username
|
||||||
|
LEFT OUTER JOIN member_settlement_settings m_mss
|
||||||
|
ON m_mss.member_id = m.id
|
||||||
|
";
|
||||||
|
|
||||||
|
static BETTING_HISTORY_QUERY: &str = "
|
||||||
|
SELECT
|
||||||
|
akbh.id as akbh_id ,
|
||||||
|
akbh.vendor_id as akbh_vendor_id ,
|
||||||
|
akbh.vendor_name as akbh_vendor_name ,
|
||||||
|
akbh.game_id as akbh_game_id ,
|
||||||
|
akbh.game_name as akbh_game_name ,
|
||||||
|
akbh.game_category as akbh_game_category ,
|
||||||
|
akbh.game_type as akbh_game_type ,
|
||||||
|
akbh.currency as akbh_currency ,
|
||||||
|
akbh.cash as akbh_cash ,
|
||||||
|
akbh.before_cash as akbh_before_cash ,
|
||||||
|
akbh.after_cash as akbh_after_cash ,
|
||||||
|
akbh.group_key as akbh_group_key ,
|
||||||
|
akbh.detail as akbh_detail ,
|
||||||
|
akbh.is_bonus as akbh_is_bonus ,
|
||||||
|
akbh.is_promo as akbh_is_promo ,
|
||||||
|
akbh.is_jackpot as akbh_is_jackpot ,
|
||||||
|
akbh.site_username as akbh_site_username ,
|
||||||
|
akbh.key as akbh_key ,
|
||||||
|
akbh.ref_id as akbh_ref_id ,
|
||||||
|
akbh.o_ref_id as akbh_o_ref_id ,
|
||||||
|
akbh.betting_type as akbh_betting_type ,
|
||||||
|
akbh.category as akbh_category ,
|
||||||
|
akbh.created_at as akbh_created_at ,
|
||||||
|
akbh.utc_created_at as akbh_utc_created_at,
|
||||||
|
|
||||||
|
m.id as m_id,
|
||||||
|
m.site_id as m_site_id,
|
||||||
|
m.member_class_id as m_member_class_id,
|
||||||
|
m.member_level_id as m_member_level_id,
|
||||||
|
m.username as m_username,
|
||||||
|
m.password as m_password,
|
||||||
|
m.nickname as m_nickname,
|
||||||
|
m.mobile_phone_number as m_mobile_phone_number,
|
||||||
|
m.state as m_state,
|
||||||
|
m.state_changed_at as m_state_changed_at,
|
||||||
|
m.parent_member_id as m_parent_member_id,
|
||||||
|
m.child_member_count as m_child_member_count,
|
||||||
|
m.last_signined_ip as m_last_signined_ip,
|
||||||
|
m.last_signined_at as m_last_signined_at,
|
||||||
|
m.created_at as m_created_at,
|
||||||
|
m.updated_at as m_updated_at,
|
||||||
|
m.deleted_at as m_deleted_at,
|
||||||
|
|
||||||
|
m_mss.id as m_mss_id,
|
||||||
|
m_mss.member_id as m_mss_member_id,
|
||||||
|
m_mss.can_exchange as m_mss_can_exchange,
|
||||||
|
m_mss.can_first_charge_comp as m_mss_can_first_charge_comp,
|
||||||
|
m_mss.can_per_charge_comp as m_mss_can_per_charge_comp,
|
||||||
|
m_mss.manual_payment_type_for_partner as m_mss_manual_payment_type_for_partner,
|
||||||
|
m_mss.settlement_type as m_mss_settlement_type,
|
||||||
|
m_mss.rate_casino as m_mss_rate_casino,
|
||||||
|
m_mss.rate_casino_loosing as m_mss_rate_casino_loosing,
|
||||||
|
m_mss.rate_casino_bacara as m_mss_rate_casino_bacara,
|
||||||
|
m_mss.rate_casino_roulette as m_mss_rate_casino_roulette,
|
||||||
|
m_mss.rate_casino_dragon_tiger as m_mss_rate_casino_dragon_tiger,
|
||||||
|
m_mss.rate_slot as m_mss_rate_slot,
|
||||||
|
m_mss.rate_slot_loosing as m_mss_rate_slot_loosing,
|
||||||
|
m_mss.rate_powerball_single as m_mss_rate_powerball_single,
|
||||||
|
m_mss.rate_powerball_combo as m_mss_rate_powerball_combo,
|
||||||
|
m_mss.rate_powerladder_single as m_mss_rate_powerladder_single,
|
||||||
|
m_mss.rate_powerladder_combo as m_mss_rate_powerladder_combo,
|
||||||
|
m_mss.rate_eos_single as m_mss_rate_eos_single,
|
||||||
|
m_mss.rate_eos_combo as m_mss_rate_eos_combo,
|
||||||
|
m_mss.rate_bogglepowerball_single as m_mss_rate_bogglepowerball_single,
|
||||||
|
m_mss.rate_bogglepowerball_combo as m_mss_rate_bogglepowerball_combo,
|
||||||
|
m_mss.created_at as m_mss_created_at,
|
||||||
|
m_mss.updated_at as m_mss_updated_at
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FROM api_kgon_betting_history as akbh
|
||||||
|
INNER JOIN members m
|
||||||
|
ON m.username = akbh.site_username
|
||||||
|
LEFT OUTER JOIN member_settlement_settings m_mss
|
||||||
|
ON m_mss.member_id = m.id
|
||||||
|
|
||||||
|
";
|
||||||
|
|
||||||
|
pub struct Composition {}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Composition {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Composition of members").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Composition {
|
||||||
|
///
|
||||||
|
pub fn new() -> Composition {
|
||||||
|
Composition {}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
id: String,
|
||||||
|
) -> Result<Option<models::BettingHistoryModel>, Error> {
|
||||||
|
let query = format!(
|
||||||
|
"
|
||||||
|
{}
|
||||||
|
WHERE
|
||||||
|
akbh.id = $1
|
||||||
|
",
|
||||||
|
BETTING_HISTORY_QUERY
|
||||||
|
);
|
||||||
|
|
||||||
|
match sql_query(query)
|
||||||
|
.bind::<diesel::sql_types::Text, _>(id)
|
||||||
|
.get_result::<models::BettingHistoryModel>(conn)
|
||||||
|
{
|
||||||
|
Ok(m) => Ok(Some(m)),
|
||||||
|
Err(e) => match e {
|
||||||
|
diesel::result::Error::NotFound => Ok(None),
|
||||||
|
_ => Err(e),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select_by_member_id(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
member_id: uuid::Uuid,
|
||||||
|
) -> Result<Option<models::BettingHistoryModel>, Error> {
|
||||||
|
let query = format!(
|
||||||
|
"
|
||||||
|
{}
|
||||||
|
WHERE
|
||||||
|
m.id = $1
|
||||||
|
",
|
||||||
|
BETTING_HISTORY_QUERY
|
||||||
|
);
|
||||||
|
|
||||||
|
match sql_query(query)
|
||||||
|
.bind::<diesel::sql_types::Uuid, _>(member_id)
|
||||||
|
.get_result::<models::BettingHistoryModel>(conn)
|
||||||
|
{
|
||||||
|
Ok(m) => Ok(Some(m)),
|
||||||
|
Err(e) => match e {
|
||||||
|
diesel::result::Error::NotFound => Ok(None),
|
||||||
|
_ => Err(e),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_pagination(&self, find_all: &models::FindAll) -> Result<String, Error> {
|
||||||
|
let mut query_pagination = String::new();
|
||||||
|
|
||||||
|
if let Some(pagination) = &find_all.pagination {
|
||||||
|
let page = match pagination.page {
|
||||||
|
Some(v) => {
|
||||||
|
if v < 1 {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => 1,
|
||||||
|
};
|
||||||
|
if let Some(page_size) = pagination.page_size {
|
||||||
|
write!(
|
||||||
|
&mut query_pagination,
|
||||||
|
" OFFSET {} LIMIT {} ",
|
||||||
|
((page - 1) * page_size) as i64,
|
||||||
|
page_size as i64
|
||||||
|
)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(query_pagination)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_ordery_by(&self, find_all: &models::FindAll) -> Result<String, Error> {
|
||||||
|
let mut query_ordery_by = String::new();
|
||||||
|
|
||||||
|
if let Some(sorts) = &find_all.sorts {
|
||||||
|
for s in sorts {
|
||||||
|
if !query_ordery_by.is_empty() {
|
||||||
|
write!(&mut query_ordery_by, " , ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (property, sort) = match s {
|
||||||
|
bcr::pagination::Sort::ASC(property) => (property.clone(), "ASC".to_string()),
|
||||||
|
bcr::pagination::Sort::DESC(property) => (property.clone(), "DESC".to_string()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let property = match property.as_str() {
|
||||||
|
"member_id" => "m.id".to_string(),
|
||||||
|
"username" => "m.username".to_string(),
|
||||||
|
"nickname" => "m.nickname".to_string(),
|
||||||
|
"vendor_id" => "akbh.vendor_id".to_string(),
|
||||||
|
"vendor_name" => "akbh.vendor_name".to_string(),
|
||||||
|
"game_id" => "akbh.game_id".to_string(),
|
||||||
|
"game_name" => "akbh.game_name".to_string(),
|
||||||
|
"game_category" => "akbh.game_category".to_string(),
|
||||||
|
"game_type" => "akbh.game_type".to_string(),
|
||||||
|
"currency" => "akbh.currency".to_string(),
|
||||||
|
"cash" => "akbh.cash".to_string(),
|
||||||
|
"before_cash" => "akbh.before_cash".to_string(),
|
||||||
|
"after_cash" => "akbh.after_cash".to_string(),
|
||||||
|
"key" => "akbh.key".to_string(),
|
||||||
|
"ref_id" => "akbh.ref_id".to_string(),
|
||||||
|
"o_ref_id" => "akbh.o_ref_id".to_string(),
|
||||||
|
"group_key" => "akbh.group_key".to_string(),
|
||||||
|
"is_bonus" => "akbh.is_bonus".to_string(),
|
||||||
|
"is_promo" => "akbh.is_promo".to_string(),
|
||||||
|
"is_jackpot" => "akbh.is_jackpot".to_string(),
|
||||||
|
"site_username" => "akbh.site_username".to_string(),
|
||||||
|
"betting_type" => "akbh.betting_type".to_string(),
|
||||||
|
"category" => "category.id".to_string(),
|
||||||
|
"created_at" => "akbh.created_at".to_string(),
|
||||||
|
"utc_created_at" => "akbh.utc_created_at".to_string(),
|
||||||
|
_ => "".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if !property.is_empty() {
|
||||||
|
write!(&mut query_ordery_by, "{} {}", property, sort)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(query_ordery_by)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_where(&self, find_all: &models::FindAll) -> Result<String, Error> {
|
||||||
|
let mut query_where = String::new();
|
||||||
|
|
||||||
|
if let Some(s) = &find_all.search {
|
||||||
|
if let Some(sp) = &s.member_id {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "m.id = '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(sp) = s.vendor_id {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.vendor_id = {}", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
if !s.vendor_ids.is_empty() {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(
|
||||||
|
&mut query_where,
|
||||||
|
"akbh.vendor_id IN ({})",
|
||||||
|
s.vendor_ids
|
||||||
|
.iter()
|
||||||
|
.map(|v| v.to_string())
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(",")
|
||||||
|
)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(sp) = &s.vendor_name {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.vendor_name = '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.vendor_name_like {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.vendor_name like '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(sp) = s.game_id {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.game_id = {}", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
if !s.game_ids.is_empty() {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(
|
||||||
|
&mut query_where,
|
||||||
|
"akbh.game_id IN ({})",
|
||||||
|
s.game_ids
|
||||||
|
.iter()
|
||||||
|
.map(|v| v.to_string())
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(",")
|
||||||
|
)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(sp) = &s.game_name {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.game_name = '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.game_name_like {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.game_name like '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(sp) = &s.game_category {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.game_category = '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.game_category_like {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.game_category like '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(sp) = &s.game_type {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.game_type = '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.game_type_like {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.game_type like '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(sp) = &s.currency {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.currency = '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.currency_like {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.currency like '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(sp) = &s.key {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.key = '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.key_like {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.key like '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(sp) = &s.ref_id {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.ref_id = '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.ref_id_like {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.ref_id like '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(sp) = &s.o_ref_id {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.o_ref_id = '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.o_ref_id_like {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.o_ref_id like '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(sp) = &s.group_key {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.group_key = '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.group_key_like {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.group_key like '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(sp) = s.is_bonus {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.is_bonus = '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(sp) = s.is_promo {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.is_promo = '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(sp) = s.is_jackpot {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.is_jackpot = '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(sp) = &s.site_username {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.site_username = '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.site_username_like {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.site_username like '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(sp) = &s.betting_type {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.betting_type = '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.betting_type_like {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.betting_type like '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(sp) = &s.category {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.category = '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.category_like {
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query_where, " AND ")
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
write!(&mut query_where, "akbh.category like '{}'", sp)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(query_where)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select_all_count(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
find_all: &models::FindAll,
|
||||||
|
) -> Result<i64, Error> {
|
||||||
|
use diesel::sql_types::BigInt;
|
||||||
|
|
||||||
|
#[derive(QueryableByName)]
|
||||||
|
struct Count {
|
||||||
|
#[sql_type = "BigInt"]
|
||||||
|
count: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut query = String::new();
|
||||||
|
write!(&mut query, "{}", BETTING_HISTORY_COUNT_QUERY)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
|
||||||
|
let query_where = self.get_where(find_all)?;
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query, " WHERE {}", query_where)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("query: {}", query);
|
||||||
|
|
||||||
|
match sql_query(query).get_result::<Count>(conn) {
|
||||||
|
Ok(m) => Ok(m.count),
|
||||||
|
Err(e) => match e {
|
||||||
|
diesel::result::Error::NotFound => Ok(0),
|
||||||
|
_ => Err(e),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select_all(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
find_all: &models::FindAll,
|
||||||
|
) -> Result<Vec<models::BettingHistoryModel>, Error> {
|
||||||
|
let mut query = String::new();
|
||||||
|
write!(&mut query, "{}", BETTING_HISTORY_QUERY)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
|
||||||
|
let query_where = self.get_where(find_all)?;
|
||||||
|
if !query_where.is_empty() {
|
||||||
|
write!(&mut query, " WHERE {}", query_where)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
let query_ordery_by = self.get_ordery_by(find_all)?;
|
||||||
|
if !query_ordery_by.is_empty() {
|
||||||
|
write!(&mut query, " ORDER BY {}", query_ordery_by)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
let query_pagination = self.get_pagination(find_all)?;
|
||||||
|
if !query_pagination.is_empty() {
|
||||||
|
write!(&mut query, " {} ", query_pagination)
|
||||||
|
.map_err(|e| diesel::result::Error::QueryBuilderError(e.to_string().into()))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("query: {}", query);
|
||||||
|
|
||||||
|
match sql_query(query).get_results::<models::BettingHistoryModel>(conn) {
|
||||||
|
Ok(m) => Ok(m),
|
||||||
|
Err(e) => match e {
|
||||||
|
diesel::result::Error::NotFound => Ok(vec![]),
|
||||||
|
_ => Err(e),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
src/compositions/betting/mod.rs
Normal file
2
src/compositions/betting/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod composition;
|
||||||
|
pub mod models;
|
166
src/compositions/betting/models.rs
Normal file
166
src/compositions/betting/models.rs
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
use beteran_common_rust as bcr;
|
||||||
|
use diesel::deserialize::QueryableByName;
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(PartialEq, Debug, Clone)]
|
||||||
|
pub struct BettingHistoryModel {
|
||||||
|
///
|
||||||
|
pub id: String,
|
||||||
|
///
|
||||||
|
pub vendor_id: i64,
|
||||||
|
///
|
||||||
|
pub vendor_name: String,
|
||||||
|
///
|
||||||
|
pub game_id: i64,
|
||||||
|
///
|
||||||
|
pub game_name: String,
|
||||||
|
///
|
||||||
|
pub game_category: String,
|
||||||
|
///
|
||||||
|
pub game_type: String,
|
||||||
|
///
|
||||||
|
pub currency: String,
|
||||||
|
///
|
||||||
|
pub cash: f64,
|
||||||
|
///
|
||||||
|
pub before_cash: f64,
|
||||||
|
///
|
||||||
|
pub after_cash: f64,
|
||||||
|
///
|
||||||
|
pub group_key: Option<String>,
|
||||||
|
///
|
||||||
|
pub detail: Option<String>,
|
||||||
|
///
|
||||||
|
pub is_bonus: bool,
|
||||||
|
///
|
||||||
|
pub is_promo: bool,
|
||||||
|
///
|
||||||
|
pub is_jackpot: bool,
|
||||||
|
///
|
||||||
|
pub site_username: String,
|
||||||
|
///
|
||||||
|
pub key: String,
|
||||||
|
///
|
||||||
|
pub ref_id: String,
|
||||||
|
///
|
||||||
|
pub o_ref_id: String,
|
||||||
|
///
|
||||||
|
pub betting_type: String,
|
||||||
|
///
|
||||||
|
pub category: String,
|
||||||
|
///
|
||||||
|
pub created_at: i64,
|
||||||
|
///
|
||||||
|
pub utc_created_at: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl QueryableByName<diesel::pg::Pg> for BettingHistoryModel {
|
||||||
|
fn build<R: diesel::row::NamedRow<diesel::pg::Pg>>(row: &R) -> diesel::deserialize::Result<Self> {
|
||||||
|
Ok(BettingHistoryModel {
|
||||||
|
id: row.get("akbh_id")?,
|
||||||
|
vendor_id: row.get("akbh_vendor_id")?,
|
||||||
|
vendor_name: row.get("akbh_vendor_name")?,
|
||||||
|
game_id: row.get("akbh_game_id")?,
|
||||||
|
game_name: row.get("akbh_game_name")?,
|
||||||
|
game_category: row.get("akbh_game_category")?,
|
||||||
|
game_type: row.get("akbh_game_type")?,
|
||||||
|
currency: row.get("akbh_currency")?,
|
||||||
|
cash: row.get("akbh_cash")?,
|
||||||
|
before_cash: row.get("akbh_before_cash")?,
|
||||||
|
after_cash: row.get("akbh_after_cash")?,
|
||||||
|
group_key: row.get("akbh_group_key")?,
|
||||||
|
detail: row.get("akbh_detail")?,
|
||||||
|
is_bonus: row.get("akbh_is_bonus")?,
|
||||||
|
is_promo: row.get("akbh_is_promo")?,
|
||||||
|
is_jackpot: row.get("akbh_is_jackpot")?,
|
||||||
|
site_username: row.get("akbh_site_username")?,
|
||||||
|
key: row.get("akbh_key")?,
|
||||||
|
ref_id: row.get("akbh_ref_id")?,
|
||||||
|
o_ref_id: row.get("akbh_o_ref_id")?,
|
||||||
|
betting_type: row.get("akbh_betting_type")?,
|
||||||
|
category: row.get("akbh_category")?,
|
||||||
|
created_at: row.get("akbh_created_at")?,
|
||||||
|
utc_created_at: row.get("akbh_utc_created_at")?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct FindAllSearch {
|
||||||
|
///
|
||||||
|
pub member_id: Option<String>,
|
||||||
|
///
|
||||||
|
pub vendor_id: Option<i64>,
|
||||||
|
///
|
||||||
|
pub vendor_ids: Vec<i64>,
|
||||||
|
///
|
||||||
|
pub vendor_name: Option<String>,
|
||||||
|
///
|
||||||
|
pub vendor_name_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub game_id: Option<i64>,
|
||||||
|
///
|
||||||
|
pub game_ids: Vec<i64>,
|
||||||
|
///
|
||||||
|
pub game_name: Option<String>,
|
||||||
|
///
|
||||||
|
pub game_name_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub game_category: Option<String>,
|
||||||
|
///
|
||||||
|
pub game_category_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub game_type: Option<String>,
|
||||||
|
///
|
||||||
|
pub game_type_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub currency: Option<String>,
|
||||||
|
///
|
||||||
|
pub currency_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub key: Option<String>,
|
||||||
|
///
|
||||||
|
pub key_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub ref_id: Option<String>,
|
||||||
|
///
|
||||||
|
pub ref_id_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub o_ref_id: Option<String>,
|
||||||
|
///
|
||||||
|
pub o_ref_id_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub group_key: Option<String>,
|
||||||
|
///
|
||||||
|
pub group_key_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub is_bonus: Option<bool>,
|
||||||
|
///
|
||||||
|
pub is_promo: Option<bool>,
|
||||||
|
///
|
||||||
|
pub is_jackpot: Option<bool>,
|
||||||
|
///
|
||||||
|
pub site_username: Option<String>,
|
||||||
|
///
|
||||||
|
pub site_username_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub betting_type: Option<String>,
|
||||||
|
///
|
||||||
|
pub betting_type_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub category: Option<String>,
|
||||||
|
///
|
||||||
|
pub category_like: Option<String>,
|
||||||
|
}
|
||||||
|
///
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct FindAll {
|
||||||
|
pub search: Option<FindAllSearch>,
|
||||||
|
///
|
||||||
|
pub pagination: Option<bcr::pagination::Pagination>,
|
||||||
|
///
|
||||||
|
pub sorts: Option<Vec<bcr::pagination::Sort>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////// temparary definitions ///////////////////////////////////////////
|
0
src/compositions/game/mod.rs
Normal file
0
src/compositions/game/mod.rs
Normal file
211
src/compositions/member/composition.rs
Normal file
211
src/compositions/member/composition.rs
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
use super::models;
|
||||||
|
use crate::repositories;
|
||||||
|
use beteran_common_rust as bcr;
|
||||||
|
use beteran_protobuf_rust as bpr;
|
||||||
|
use prost::Message;
|
||||||
|
use std::net::{IpAddr, Ipv4Addr};
|
||||||
|
|
||||||
|
pub struct Composition {
|
||||||
|
connection_broker: nats::asynk::Connection,
|
||||||
|
member_repository: repositories::member::repository::Repository,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Composition {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Composition of members").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Composition {
|
||||||
|
///
|
||||||
|
pub fn new(connection_broker: nats::asynk::Connection) -> Composition {
|
||||||
|
Composition {
|
||||||
|
connection_broker,
|
||||||
|
member_repository: repositories::member::repository::Repository::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub async fn select_by_member_id(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
member_id: uuid::Uuid,
|
||||||
|
) -> Result<Option<models::Member>, bcr::error::rpc::Error> {
|
||||||
|
let m = match self
|
||||||
|
.member_repository
|
||||||
|
.select_by_member_id(conn, member_id)
|
||||||
|
.map_err(|e| {
|
||||||
|
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||||
|
code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||||
|
message: format!("server {}", e),
|
||||||
|
data: None,
|
||||||
|
})
|
||||||
|
})? {
|
||||||
|
Some(m) => m,
|
||||||
|
None => {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let ss_get_member_req = bpr::ss::member::GetMemberBRequest {
|
||||||
|
client: Some(bpr::models::core::network::Client {
|
||||||
|
client_ip: self
|
||||||
|
.connection_broker
|
||||||
|
.client_ip()
|
||||||
|
.unwrap_or(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)))
|
||||||
|
.to_string(),
|
||||||
|
site_url: None,
|
||||||
|
access_token: None,
|
||||||
|
}),
|
||||||
|
request: Some(bpr::ss::member::get_member_b_request::Request {
|
||||||
|
id: m.member_id.to_string(),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
let ss_get_member_res_msg = self
|
||||||
|
.connection_broker
|
||||||
|
.request(
|
||||||
|
bpr::ss::member::SUBJECT_GET_MEMBER_B,
|
||||||
|
ss_get_member_req.encode_to_vec(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||||
|
code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||||
|
message: format!("server {}", e),
|
||||||
|
data: None,
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let ss_get_member_res = bpr::ss::member::GetMemberBResponse::decode(
|
||||||
|
ss_get_member_res_msg.data.as_slice(),
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
|
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||||
|
code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||||
|
message: format!("server {}", e),
|
||||||
|
data: None,
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if let Some(e) = ss_get_member_res.error {
|
||||||
|
return Err(bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||||
|
code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||||
|
message: format!("server {}", e),
|
||||||
|
data: None,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mm = match ss_get_member_res.result {
|
||||||
|
Some(r) => match r.member {
|
||||||
|
Some(_m) => Some(models::Member {
|
||||||
|
id: m.id,
|
||||||
|
balance: m.balance,
|
||||||
|
balance_bota: m.balance_bota,
|
||||||
|
balance_sum: m.balance_sum,
|
||||||
|
companies: m.companies,
|
||||||
|
oriental_play: m.oriental_play,
|
||||||
|
member: _m,
|
||||||
|
created_at: m.created_at,
|
||||||
|
updated_at: m.updated_at,
|
||||||
|
}),
|
||||||
|
None => None,
|
||||||
|
},
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(mm)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub async fn select_b_by_member_id(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
member_id: uuid::Uuid,
|
||||||
|
) -> Result<Option<models::MemberModel>, bcr::error::rpc::Error> {
|
||||||
|
let m = match self
|
||||||
|
.member_repository
|
||||||
|
.select_by_member_id(conn, member_id)
|
||||||
|
.map_err(|e| {
|
||||||
|
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||||
|
code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||||
|
message: format!("server {}", e),
|
||||||
|
data: None,
|
||||||
|
})
|
||||||
|
})? {
|
||||||
|
Some(m) => m,
|
||||||
|
None => {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let ss_get_member_req = bpr::ss::member::GetMemberRequest {
|
||||||
|
client: Some(bpr::models::core::network::Client {
|
||||||
|
client_ip: self
|
||||||
|
.connection_broker
|
||||||
|
.client_ip()
|
||||||
|
.unwrap_or(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)))
|
||||||
|
.to_string(),
|
||||||
|
site_url: None,
|
||||||
|
access_token: None,
|
||||||
|
}),
|
||||||
|
request: Some(bpr::ss::member::get_member_request::Request {
|
||||||
|
id: m.member_id.to_string(),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
let ss_get_member_res_msg = self
|
||||||
|
.connection_broker
|
||||||
|
.request(
|
||||||
|
bpr::ss::member::SUBJECT_GET_MEMBER,
|
||||||
|
ss_get_member_req.encode_to_vec(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||||
|
code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||||
|
message: format!("server {}", e),
|
||||||
|
data: None,
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let ss_get_member_res = bpr::ss::member::GetMemberResponse::decode(
|
||||||
|
ss_get_member_res_msg.data.as_slice(),
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
|
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||||
|
code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||||
|
message: format!("server {}", e),
|
||||||
|
data: None,
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if let Some(e) = ss_get_member_res.error {
|
||||||
|
return Err(bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||||
|
code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||||
|
message: format!("server {}", e),
|
||||||
|
data: None,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mm = match ss_get_member_res.result {
|
||||||
|
Some(r) => match r.member {
|
||||||
|
Some(_m) => Some(models::MemberModel {
|
||||||
|
id: m.id,
|
||||||
|
balance: m.balance,
|
||||||
|
balance_bota: m.balance_bota,
|
||||||
|
balance_sum: m.balance_sum,
|
||||||
|
companies: m.companies,
|
||||||
|
oriental_play: m.oriental_play,
|
||||||
|
member: _m,
|
||||||
|
created_at: m.created_at,
|
||||||
|
updated_at: m.updated_at,
|
||||||
|
}),
|
||||||
|
None => None,
|
||||||
|
},
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(mm)
|
||||||
|
}
|
||||||
|
}
|
2
src/compositions/member/mod.rs
Normal file
2
src/compositions/member/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod composition;
|
||||||
|
pub mod models;
|
47
src/compositions/member/models.rs
Normal file
47
src/compositions/member/models.rs
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
use beteran_protobuf_rust as bpr;
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(PartialEq, Debug, Clone)]
|
||||||
|
pub struct Member {
|
||||||
|
///
|
||||||
|
pub id: i64,
|
||||||
|
///
|
||||||
|
pub balance: f64,
|
||||||
|
///
|
||||||
|
pub balance_bota: f64,
|
||||||
|
///
|
||||||
|
pub balance_sum: f64,
|
||||||
|
///
|
||||||
|
pub companies: Option<String>,
|
||||||
|
///
|
||||||
|
pub oriental_play: String,
|
||||||
|
///
|
||||||
|
pub member: bpr::models::member::Member,
|
||||||
|
///
|
||||||
|
pub created_at: i64,
|
||||||
|
///
|
||||||
|
pub updated_at: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(PartialEq, Debug, Clone)]
|
||||||
|
pub struct MemberModel {
|
||||||
|
///
|
||||||
|
pub id: i64,
|
||||||
|
///
|
||||||
|
pub balance: f64,
|
||||||
|
///
|
||||||
|
pub balance_bota: f64,
|
||||||
|
///
|
||||||
|
pub balance_sum: f64,
|
||||||
|
///
|
||||||
|
pub companies: Option<String>,
|
||||||
|
///
|
||||||
|
pub oriental_play: String,
|
||||||
|
///
|
||||||
|
pub member: bpr::models::member::MemberModel,
|
||||||
|
///
|
||||||
|
pub created_at: i64,
|
||||||
|
///
|
||||||
|
pub updated_at: i64,
|
||||||
|
}
|
0
src/compositions/member_account/mod.rs
Normal file
0
src/compositions/member_account/mod.rs
Normal file
4
src/compositions/mod.rs
Normal file
4
src/compositions/mod.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
pub mod betting;
|
||||||
|
pub mod game;
|
||||||
|
pub mod member;
|
||||||
|
pub mod member_account;
|
6
src/core/config.rs
Normal file
6
src/core/config.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct ApiConfig {
|
||||||
|
pub k_url: String,
|
||||||
|
pub k_username: String,
|
||||||
|
pub k_secret: String,
|
||||||
|
}
|
1
src/core/mod.rs
Normal file
1
src/core/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod config;
|
197
src/events/member/event.rs
Normal file
197
src/events/member/event.rs
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
use crate::api;
|
||||||
|
use crate::core;
|
||||||
|
use crate::repositories;
|
||||||
|
use beteran_common_rust as bcr;
|
||||||
|
use beteran_protobuf_rust as bpr;
|
||||||
|
use diesel::{
|
||||||
|
r2d2::{ConnectionManager, Pool},
|
||||||
|
PgConnection,
|
||||||
|
};
|
||||||
|
use prost::Message;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
static MEMBER_CLASS_ID_MAIN_OFFICE: &str = "4b014ef5-3bab-4413-aaf9-b0040a70ec77";
|
||||||
|
static MEMBER_CLASS_ID_BRANCH: &str = "ae9b874e-5d0e-4c4d-8432-f45f02691ceb";
|
||||||
|
static MEMBER_CLASS_ID_DIVISION: &str = "f25a17e9-5c5f-4e9c-bf80-92a9cedf829c";
|
||||||
|
static MEMBER_CLASS_ID_OFFICE: &str = "cac7b897-2549-4f04-8415-8868f1dcb1da";
|
||||||
|
static MEMBER_CLASS_ID_STORE: &str = "e11cac11-3825-4f4e-9cd5-39367f23f973";
|
||||||
|
static MEMBER_CLASS_ID_USER: &str = "4598f07a-86d1-42a4-b038-25706683a7cd";
|
||||||
|
|
||||||
|
pub struct EventHandler {
|
||||||
|
connection_broker: nats::asynk::Connection,
|
||||||
|
queue_broker: String,
|
||||||
|
pool: Pool<ConnectionManager<PgConnection>>,
|
||||||
|
api_config: core::config::ApiConfig,
|
||||||
|
member_repository: repositories::member::repository::Repository,
|
||||||
|
member_api: api::member::api::Api,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for EventHandler {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.debug_struct("EventHandler of members").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventHandler {
|
||||||
|
///
|
||||||
|
pub fn new(
|
||||||
|
connection_broker: nats::asynk::Connection,
|
||||||
|
queue_broker: String,
|
||||||
|
pool: Pool<ConnectionManager<PgConnection>>,
|
||||||
|
api_config: core::config::ApiConfig,
|
||||||
|
) -> EventHandler {
|
||||||
|
EventHandler {
|
||||||
|
connection_broker,
|
||||||
|
queue_broker,
|
||||||
|
pool,
|
||||||
|
api_config: api_config.clone(),
|
||||||
|
member_repository: repositories::member::repository::Repository::new(),
|
||||||
|
member_api: api::member::api::Api::new(api_config.clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn subscribe(&self) -> std::result::Result<(), std::boxed::Box<dyn std::error::Error>> {
|
||||||
|
futures::try_join!(self.event_after_create_member()).map(|_| ())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn event_after_create_member(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let s = self
|
||||||
|
.connection_broker
|
||||||
|
.queue_subscribe(
|
||||||
|
bpr::ss::member::EVENT_SUBJECT_AFTER_CREATE_MEMBER,
|
||||||
|
self.queue_broker.as_str(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
while let Some(message) = s.next().await {
|
||||||
|
if let Err(e) = async {
|
||||||
|
let eve = bpr::ss::member::AfterCreateMemberEvent::decode(message.data.as_slice())
|
||||||
|
.map_err(|e| {
|
||||||
|
bcr::error::rpc::Error::InvalidRequest(bcr::error::rpc::InvalidRequest {
|
||||||
|
message: format!("invalid request: {}", e),
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let client = match eve.client {
|
||||||
|
Some(c) => c,
|
||||||
|
None => {
|
||||||
|
return Err(bcr::error::rpc::Error::InvalidParams(
|
||||||
|
bcr::error::rpc::InvalidParams {
|
||||||
|
message: "invalid client information".to_string(),
|
||||||
|
detail: bcr::error::rpc::InvalidParamsDetail {
|
||||||
|
location: "request".to_string(),
|
||||||
|
param: "client".to_string(),
|
||||||
|
value: "".to_string(),
|
||||||
|
error_type: bcr::error::rpc::InvalidParamsType::Required,
|
||||||
|
message: "".to_string(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let event = match eve.event {
|
||||||
|
Some(r) => r,
|
||||||
|
None => {
|
||||||
|
return Err(bcr::error::rpc::Error::InvalidParams(
|
||||||
|
bcr::error::rpc::InvalidParams {
|
||||||
|
message: "invalid event information".to_string(),
|
||||||
|
detail: bcr::error::rpc::InvalidParamsDetail {
|
||||||
|
location: "event".to_string(),
|
||||||
|
param: "event".to_string(),
|
||||||
|
value: "".to_string(),
|
||||||
|
error_type: bcr::error::rpc::InvalidParamsType::Required,
|
||||||
|
message: "".to_string(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let member = match event.member {
|
||||||
|
Some(c) => c,
|
||||||
|
None => {
|
||||||
|
return Err(bcr::error::rpc::Error::InvalidParams(
|
||||||
|
bcr::error::rpc::InvalidParams {
|
||||||
|
message: "invalid client information".to_string(),
|
||||||
|
detail: bcr::error::rpc::InvalidParamsDetail {
|
||||||
|
location: "request".to_string(),
|
||||||
|
param: "client".to_string(),
|
||||||
|
value: "".to_string(),
|
||||||
|
error_type: bcr::error::rpc::InvalidParamsType::Required,
|
||||||
|
message: "".to_string(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let member_id = uuid::Uuid::from_str(member.id.as_str()).map_err(|e| {
|
||||||
|
bcr::error::rpc::Error::InvalidParams(bcr::error::rpc::InvalidParams {
|
||||||
|
message: "invalid member.id param".to_string(),
|
||||||
|
detail: bcr::error::rpc::InvalidParamsDetail {
|
||||||
|
location: "request".to_string(),
|
||||||
|
param: "member.id".to_string(),
|
||||||
|
value: member.id.clone(),
|
||||||
|
error_type: bcr::error::rpc::InvalidParamsType::Required,
|
||||||
|
message: e.to_string(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
let conn = self.pool.get().map_err(|e| {
|
||||||
|
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||||
|
code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||||
|
message: format!("server {}", e),
|
||||||
|
data: None,
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if let Some(mc) = member.member_class {
|
||||||
|
if mc.id.eq(MEMBER_CLASS_ID_USER) {
|
||||||
|
let api_create_res = self
|
||||||
|
.member_api
|
||||||
|
.create_member(api::member::models::CreateMemberRequest {
|
||||||
|
username: member.username.clone(),
|
||||||
|
nickname: member.nickname.clone(),
|
||||||
|
site_username: member.username.clone(),
|
||||||
|
group_key: match member.parent_member {
|
||||||
|
Some(m) => Some(m.username),
|
||||||
|
None => None,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||||
|
code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||||
|
message: format!("server {:?}", e),
|
||||||
|
data: None,
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
self
|
||||||
|
.member_repository
|
||||||
|
.insert(
|
||||||
|
&conn,
|
||||||
|
&repositories::member::models::NewMember {
|
||||||
|
id: api_create_res.id,
|
||||||
|
member_id,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
|
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||||
|
code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||||
|
message: format!("server {}", e),
|
||||||
|
data: None,
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok::<(), bcr::error::rpc::Error>(())
|
||||||
|
}
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
println!("error: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
1
src/events/member/mod.rs
Normal file
1
src/events/member/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod event;
|
208
src/events/member_bank_deposit/event.rs
Normal file
208
src/events/member_bank_deposit/event.rs
Normal file
|
@ -0,0 +1,208 @@
|
||||||
|
use crate::api;
|
||||||
|
use crate::core;
|
||||||
|
use crate::repositories;
|
||||||
|
use crate::synchronizations;
|
||||||
|
use beteran_common_rust as bcr;
|
||||||
|
use beteran_protobuf_rust as bpr;
|
||||||
|
use diesel::{
|
||||||
|
r2d2::{ConnectionManager, Pool},
|
||||||
|
PgConnection,
|
||||||
|
};
|
||||||
|
use prost::Message;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
pub struct EventHandler {
|
||||||
|
connection_broker: nats::asynk::Connection,
|
||||||
|
queue_broker: String,
|
||||||
|
pool: Pool<ConnectionManager<PgConnection>>,
|
||||||
|
api_config: core::config::ApiConfig,
|
||||||
|
member_repository: repositories::member::repository::Repository,
|
||||||
|
member_account_api: api::member_account::api::Api,
|
||||||
|
member_account_synchronizer: synchronizations::member_account::synchronizer::Synchronizer,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for EventHandler {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.debug_struct("EventHandler of members").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventHandler {
|
||||||
|
///
|
||||||
|
pub fn new(
|
||||||
|
connection_broker: nats::asynk::Connection,
|
||||||
|
queue_broker: String,
|
||||||
|
pool: Pool<ConnectionManager<PgConnection>>,
|
||||||
|
member_account_synchronizer: synchronizations::member_account::synchronizer::Synchronizer,
|
||||||
|
api_config: core::config::ApiConfig,
|
||||||
|
) -> EventHandler {
|
||||||
|
EventHandler {
|
||||||
|
connection_broker,
|
||||||
|
queue_broker,
|
||||||
|
pool,
|
||||||
|
member_account_synchronizer,
|
||||||
|
api_config: api_config.clone(),
|
||||||
|
member_repository: repositories::member::repository::Repository::new(),
|
||||||
|
member_account_api: api::member_account::api::Api::new(api_config.clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn subscribe(&self) -> std::result::Result<(), std::boxed::Box<dyn std::error::Error>> {
|
||||||
|
futures::try_join!(self.event_after_update_member_bank_deposit_for_state()).map(|_| ())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn event_after_update_member_bank_deposit_for_state(
|
||||||
|
&self,
|
||||||
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let s = self
|
||||||
|
.connection_broker
|
||||||
|
.queue_subscribe(
|
||||||
|
bpr::ss::member_bank_deposit::EVENT_SUBJECT_AFTER_UPDATE_MEMBER_BANK_DEPOSIT_FOR_STATE,
|
||||||
|
self.queue_broker.as_str(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
while let Some(message) = s.next().await {
|
||||||
|
if let Err(e) = async {
|
||||||
|
let eve = bpr::ss::member_bank_deposit::AfterUpdateMemberBankDepositForState::decode(
|
||||||
|
message.data.as_slice(),
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
|
bcr::error::rpc::Error::InvalidRequest(bcr::error::rpc::InvalidRequest {
|
||||||
|
message: format!("invalid request: {}", e),
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let client = match eve.client {
|
||||||
|
Some(c) => c,
|
||||||
|
None => {
|
||||||
|
return Err(bcr::error::rpc::Error::InvalidParams(
|
||||||
|
bcr::error::rpc::InvalidParams {
|
||||||
|
message: "invalid client information".to_string(),
|
||||||
|
detail: bcr::error::rpc::InvalidParamsDetail {
|
||||||
|
location: "request".to_string(),
|
||||||
|
param: "client".to_string(),
|
||||||
|
value: "".to_string(),
|
||||||
|
error_type: bcr::error::rpc::InvalidParamsType::Required,
|
||||||
|
message: "".to_string(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let event = match eve.event {
|
||||||
|
Some(r) => r,
|
||||||
|
None => {
|
||||||
|
return Err(bcr::error::rpc::Error::InvalidParams(
|
||||||
|
bcr::error::rpc::InvalidParams {
|
||||||
|
message: "invalid event information".to_string(),
|
||||||
|
detail: bcr::error::rpc::InvalidParamsDetail {
|
||||||
|
location: "event".to_string(),
|
||||||
|
param: "event".to_string(),
|
||||||
|
value: "".to_string(),
|
||||||
|
error_type: bcr::error::rpc::InvalidParamsType::Required,
|
||||||
|
message: "".to_string(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let member_bank_deposit = match event.member_bank_deposit {
|
||||||
|
Some(c) => c,
|
||||||
|
None => {
|
||||||
|
return Err(bcr::error::rpc::Error::InvalidParams(
|
||||||
|
bcr::error::rpc::InvalidParams {
|
||||||
|
message: "invalid event information".to_string(),
|
||||||
|
detail: bcr::error::rpc::InvalidParamsDetail {
|
||||||
|
location: "event".to_string(),
|
||||||
|
param: "member_bank_deposit".to_string(),
|
||||||
|
value: "".to_string(),
|
||||||
|
error_type: bcr::error::rpc::InvalidParamsType::Required,
|
||||||
|
message: "".to_string(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let member = match member_bank_deposit.member {
|
||||||
|
Some(c) => c,
|
||||||
|
None => {
|
||||||
|
return Err(bcr::error::rpc::Error::InvalidParams(
|
||||||
|
bcr::error::rpc::InvalidParams {
|
||||||
|
message: "invalid event information".to_string(),
|
||||||
|
detail: bcr::error::rpc::InvalidParamsDetail {
|
||||||
|
location: "event".to_string(),
|
||||||
|
param: "member_bank_deposit.member".to_string(),
|
||||||
|
value: "".to_string(),
|
||||||
|
error_type: bcr::error::rpc::InvalidParamsType::Required,
|
||||||
|
message: "".to_string(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let member_id = uuid::Uuid::from_str(member.id.as_str()).map_err(|e| {
|
||||||
|
bcr::error::rpc::Error::InvalidParams(bcr::error::rpc::InvalidParams {
|
||||||
|
message: "invalid member.id param".to_string(),
|
||||||
|
detail: bcr::error::rpc::InvalidParamsDetail {
|
||||||
|
location: "request".to_string(),
|
||||||
|
param: "member.id".to_string(),
|
||||||
|
value: member.id.clone(),
|
||||||
|
error_type: bcr::error::rpc::InvalidParamsType::Required,
|
||||||
|
message: e.to_string(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let conn = self.pool.get().map_err(|e| {
|
||||||
|
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||||
|
code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||||
|
message: format!("server {}", e),
|
||||||
|
data: None,
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
match beteran_protobuf_rust::models::member_bank_deposit::MemberBankDepositState::from_i32(
|
||||||
|
member_bank_deposit.state,
|
||||||
|
) {
|
||||||
|
Some(s) => {
|
||||||
|
if s == beteran_protobuf_rust::models::member_bank_deposit::MemberBankDepositState::Complete {
|
||||||
|
self.member_account_api.create_deposit(api::member_account::models::CreateDepositRequest{
|
||||||
|
username: member.username.clone(),
|
||||||
|
cash_type: None,
|
||||||
|
amount: member_bank_deposit.amount,
|
||||||
|
request_key: None,
|
||||||
|
}).await
|
||||||
|
.map_err(|e| {
|
||||||
|
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||||
|
code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||||
|
message: format!("server {:?}", e),
|
||||||
|
data: None,
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
self.member_account_synchronizer.balance_for_user(member_id, &member.username).await
|
||||||
|
.map_err(|e| {
|
||||||
|
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||||
|
code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||||
|
message: format!("server {:?}", e),
|
||||||
|
data: None,
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok::<(), bcr::error::rpc::Error>(())
|
||||||
|
}
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
println!("error: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
1
src/events/member_bank_deposit/mod.rs
Normal file
1
src/events/member_bank_deposit/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod event;
|
206
src/events/member_bank_withdraw/event.rs
Normal file
206
src/events/member_bank_withdraw/event.rs
Normal file
|
@ -0,0 +1,206 @@
|
||||||
|
use crate::api;
|
||||||
|
use crate::core;
|
||||||
|
use crate::repositories;
|
||||||
|
use crate::synchronizations;
|
||||||
|
use beteran_common_rust as bcr;
|
||||||
|
use beteran_protobuf_rust as bpr;
|
||||||
|
use diesel::{
|
||||||
|
r2d2::{ConnectionManager, Pool},
|
||||||
|
PgConnection,
|
||||||
|
};
|
||||||
|
use prost::Message;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
pub struct EventHandler {
|
||||||
|
connection_broker: nats::asynk::Connection,
|
||||||
|
queue_broker: String,
|
||||||
|
pool: Pool<ConnectionManager<PgConnection>>,
|
||||||
|
api_config: core::config::ApiConfig,
|
||||||
|
member_repository: repositories::member::repository::Repository,
|
||||||
|
member_account_api: api::member_account::api::Api,
|
||||||
|
member_account_synchronizer: synchronizations::member_account::synchronizer::Synchronizer,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for EventHandler {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.debug_struct("EventHandler of members").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventHandler {
|
||||||
|
///
|
||||||
|
pub fn new(
|
||||||
|
connection_broker: nats::asynk::Connection,
|
||||||
|
queue_broker: String,
|
||||||
|
pool: Pool<ConnectionManager<PgConnection>>,
|
||||||
|
member_account_synchronizer: synchronizations::member_account::synchronizer::Synchronizer,
|
||||||
|
api_config: core::config::ApiConfig,
|
||||||
|
) -> EventHandler {
|
||||||
|
EventHandler {
|
||||||
|
connection_broker,
|
||||||
|
queue_broker,
|
||||||
|
pool,
|
||||||
|
member_account_synchronizer,
|
||||||
|
api_config: api_config.clone(),
|
||||||
|
member_repository: repositories::member::repository::Repository::new(),
|
||||||
|
member_account_api: api::member_account::api::Api::new(api_config.clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn subscribe(&self) -> std::result::Result<(), std::boxed::Box<dyn std::error::Error>> {
|
||||||
|
futures::try_join!(self.event_after_update_member_bank_withdraw_for_state()).map(|_| ())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn event_after_update_member_bank_withdraw_for_state(
|
||||||
|
&self,
|
||||||
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let s = self
|
||||||
|
.connection_broker
|
||||||
|
.queue_subscribe(
|
||||||
|
bpr::ss::member_bank_withdraw::EVENT_SUBJECT_AFTER_UPDATE_MEMBER_BANK_WITHDRAW_FOR_STATE,
|
||||||
|
self.queue_broker.as_str(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
while let Some(message) = s.next().await {
|
||||||
|
if let Err(e) = async {
|
||||||
|
let eve = bpr::ss::member_bank_withdraw::AfterUpdateMemberBankWithdrawForState::decode(
|
||||||
|
message.data.as_slice(),
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
|
bcr::error::rpc::Error::InvalidRequest(bcr::error::rpc::InvalidRequest {
|
||||||
|
message: format!("invalid request: {}", e),
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let client = match eve.client {
|
||||||
|
Some(c) => c,
|
||||||
|
None => {
|
||||||
|
return Err(bcr::error::rpc::Error::InvalidParams(
|
||||||
|
bcr::error::rpc::InvalidParams {
|
||||||
|
message: "invalid client information".to_string(),
|
||||||
|
detail: bcr::error::rpc::InvalidParamsDetail {
|
||||||
|
location: "request".to_string(),
|
||||||
|
param: "client".to_string(),
|
||||||
|
value: "".to_string(),
|
||||||
|
error_type: bcr::error::rpc::InvalidParamsType::Required,
|
||||||
|
message: "".to_string(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let event = match eve.event {
|
||||||
|
Some(r) => r,
|
||||||
|
None => {
|
||||||
|
return Err(bcr::error::rpc::Error::InvalidParams(
|
||||||
|
bcr::error::rpc::InvalidParams {
|
||||||
|
message: "invalid event information".to_string(),
|
||||||
|
detail: bcr::error::rpc::InvalidParamsDetail {
|
||||||
|
location: "event".to_string(),
|
||||||
|
param: "event".to_string(),
|
||||||
|
value: "".to_string(),
|
||||||
|
error_type: bcr::error::rpc::InvalidParamsType::Required,
|
||||||
|
message: "".to_string(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let member_bank_withdraw = match event.member_bank_withdraw {
|
||||||
|
Some(c) => c,
|
||||||
|
None => {
|
||||||
|
return Err(bcr::error::rpc::Error::InvalidParams(
|
||||||
|
bcr::error::rpc::InvalidParams {
|
||||||
|
message: "invalid event information".to_string(),
|
||||||
|
detail: bcr::error::rpc::InvalidParamsDetail {
|
||||||
|
location: "event".to_string(),
|
||||||
|
param: "member_bank_withdraw".to_string(),
|
||||||
|
value: "".to_string(),
|
||||||
|
error_type: bcr::error::rpc::InvalidParamsType::Required,
|
||||||
|
message: "".to_string(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let member = match member_bank_withdraw.member {
|
||||||
|
Some(c) => c,
|
||||||
|
None => {
|
||||||
|
return Err(bcr::error::rpc::Error::InvalidParams(
|
||||||
|
bcr::error::rpc::InvalidParams {
|
||||||
|
message: "invalid event information".to_string(),
|
||||||
|
detail: bcr::error::rpc::InvalidParamsDetail {
|
||||||
|
location: "event".to_string(),
|
||||||
|
param: "member_bank_withdraw.member".to_string(),
|
||||||
|
value: "".to_string(),
|
||||||
|
error_type: bcr::error::rpc::InvalidParamsType::Required,
|
||||||
|
message: "".to_string(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let member_id = uuid::Uuid::from_str(member.id.as_str()).map_err(|e| {
|
||||||
|
bcr::error::rpc::Error::InvalidParams(bcr::error::rpc::InvalidParams {
|
||||||
|
message: "invalid member.id param".to_string(),
|
||||||
|
detail: bcr::error::rpc::InvalidParamsDetail {
|
||||||
|
location: "request".to_string(),
|
||||||
|
param: "member.id".to_string(),
|
||||||
|
value: member.id.clone(),
|
||||||
|
error_type: bcr::error::rpc::InvalidParamsType::Required,
|
||||||
|
message: e.to_string(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let conn = self.pool.get().map_err(|e| {
|
||||||
|
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||||
|
code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||||
|
message: format!("server {}", e),
|
||||||
|
data: None,
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
match beteran_protobuf_rust::models::member_bank_withdraw::MemberBankWithdrawState::from_i32(
|
||||||
|
member_bank_withdraw.state,
|
||||||
|
) {
|
||||||
|
Some(s) => {
|
||||||
|
if s == beteran_protobuf_rust::models::member_bank_withdraw::MemberBankWithdrawState::Complete {
|
||||||
|
self.member_account_api.create_withdraw(api::member_account::models::CreateWithdrawRequest{
|
||||||
|
username: member.username.clone(),
|
||||||
|
request_key: None,
|
||||||
|
}).await
|
||||||
|
.map_err(|e| {
|
||||||
|
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||||
|
code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||||
|
message: format!("server {:?}", e),
|
||||||
|
data: None,
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
self.member_account_synchronizer.balance_for_user(member_id, &member.username).await
|
||||||
|
.map_err(|e| {
|
||||||
|
bcr::error::rpc::Error::Server(bcr::error::rpc::Server {
|
||||||
|
code: bpr::protobuf::rpc::Error::SERVER_00,
|
||||||
|
message: format!("server {:?}", e),
|
||||||
|
data: None,
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok::<(), bcr::error::rpc::Error>(())
|
||||||
|
}
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
println!("error: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
1
src/events/member_bank_withdraw/mod.rs
Normal file
1
src/events/member_bank_withdraw/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod event;
|
3
src/events/mod.rs
Normal file
3
src/events/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
pub mod member;
|
||||||
|
pub mod member_bank_withdraw;
|
||||||
|
pub mod member_bank_deposit;
|
183
src/main.rs
Normal file
183
src/main.rs
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
#[macro_use]
|
||||||
|
extern crate diesel;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate diesel_migrations;
|
||||||
|
|
||||||
|
use diesel::{
|
||||||
|
r2d2::{ConnectionManager, Pool},
|
||||||
|
PgConnection,
|
||||||
|
};
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
mod api;
|
||||||
|
mod compositions;
|
||||||
|
mod core;
|
||||||
|
mod events;
|
||||||
|
mod repositories;
|
||||||
|
mod schedulers;
|
||||||
|
mod services;
|
||||||
|
mod synchronizations;
|
||||||
|
|
||||||
|
diesel_migrations::embed_migrations!();
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let url_db = match env::var_os("URL_DATABASE") {
|
||||||
|
Some(v) => v.into_string().unwrap(),
|
||||||
|
None => "".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let url_broker = match env::var_os("URL_BROKER") {
|
||||||
|
Some(v) => v.into_string().unwrap(),
|
||||||
|
None => "".to_string(),
|
||||||
|
};
|
||||||
|
let queue_broker = match env::var_os("QUEUE_BROKER") {
|
||||||
|
Some(v) => v.into_string().unwrap(),
|
||||||
|
None => "".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let k_url = match env::var_os("K_URL") {
|
||||||
|
Some(v) => v.into_string().unwrap(),
|
||||||
|
None => "".to_string(),
|
||||||
|
};
|
||||||
|
let k_username = match env::var_os("K_USERNAME") {
|
||||||
|
Some(v) => v.into_string().unwrap(),
|
||||||
|
None => "".to_string(),
|
||||||
|
};
|
||||||
|
let k_secret = match env::var_os("K_SECRET") {
|
||||||
|
Some(v) => v.into_string().unwrap(),
|
||||||
|
None => "".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let api_config = core::config::ApiConfig {
|
||||||
|
k_url,
|
||||||
|
k_username,
|
||||||
|
k_secret,
|
||||||
|
};
|
||||||
|
|
||||||
|
let manager = ConnectionManager::<PgConnection>::new(url_db);
|
||||||
|
let pool = Pool::builder()
|
||||||
|
.max_size(10)
|
||||||
|
.test_on_check_out(true)
|
||||||
|
.build(manager)?;
|
||||||
|
let conn = pool.get()?;
|
||||||
|
|
||||||
|
embedded_migrations::run(&conn)?;
|
||||||
|
|
||||||
|
let broker_opts = nats::asynk::Options::new();
|
||||||
|
let connection_broker = broker_opts.connect(url_broker).await?;
|
||||||
|
|
||||||
|
let vendor_synchronizer =
|
||||||
|
synchronizations::vendor::synchronizer::Synchronizer::new(pool.clone(), api_config.clone());
|
||||||
|
let game_synchronizer =
|
||||||
|
synchronizations::game::synchronizer::Synchronizer::new(pool.clone(), api_config.clone());
|
||||||
|
let member_synchronizer = synchronizations::member::synchronizer::Synchronizer::new(
|
||||||
|
connection_broker.clone(),
|
||||||
|
pool.clone(),
|
||||||
|
api_config.clone(),
|
||||||
|
);
|
||||||
|
let member_account_synchronizer =
|
||||||
|
synchronizations::member_account::synchronizer::Synchronizer::new(
|
||||||
|
connection_broker.clone(),
|
||||||
|
pool.clone(),
|
||||||
|
api_config.clone(),
|
||||||
|
);
|
||||||
|
let betting_history_synchronizer =
|
||||||
|
synchronizations::betting_history::synchronizer::Synchronizer::new(
|
||||||
|
pool.clone(),
|
||||||
|
api_config.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let vendor_service = services::vendor::service::Service::new(
|
||||||
|
connection_broker.clone(),
|
||||||
|
queue_broker.clone(),
|
||||||
|
pool.clone(),
|
||||||
|
);
|
||||||
|
let game_service = services::game::service::Service::new(
|
||||||
|
connection_broker.clone(),
|
||||||
|
queue_broker.clone(),
|
||||||
|
pool.clone(),
|
||||||
|
api_config.clone(),
|
||||||
|
);
|
||||||
|
let member_service =
|
||||||
|
services::member::service::Service::new(connection_broker.clone(), queue_broker.clone());
|
||||||
|
let member_account_service = services::member_account::service::Service::new(
|
||||||
|
connection_broker.clone(),
|
||||||
|
queue_broker.clone(),
|
||||||
|
);
|
||||||
|
let betting_service = services::betting::service::Service::new(
|
||||||
|
connection_broker.clone(),
|
||||||
|
queue_broker.clone(),
|
||||||
|
pool.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let member_event_handler = events::member::event::EventHandler::new(
|
||||||
|
connection_broker.clone(),
|
||||||
|
queue_broker.clone(),
|
||||||
|
pool.clone(),
|
||||||
|
api_config.clone(),
|
||||||
|
);
|
||||||
|
let member_bank_deposit_event_handler = events::member_bank_deposit::event::EventHandler::new(
|
||||||
|
connection_broker.clone(),
|
||||||
|
queue_broker.clone(),
|
||||||
|
pool.clone(),
|
||||||
|
member_account_synchronizer.clone(),
|
||||||
|
api_config.clone(),
|
||||||
|
);
|
||||||
|
let member_bank_withdraw_event_handler = events::member_bank_withdraw::event::EventHandler::new(
|
||||||
|
connection_broker.clone(),
|
||||||
|
queue_broker.clone(),
|
||||||
|
pool.clone(),
|
||||||
|
member_account_synchronizer.clone(),
|
||||||
|
api_config.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut sched = tokio_cron_scheduler::JobScheduler::new().await?;
|
||||||
|
|
||||||
|
let game_scheduler = schedulers::game::scheduler::Scheduler::get_instance(
|
||||||
|
sched.clone(),
|
||||||
|
vendor_synchronizer.clone(),
|
||||||
|
game_synchronizer.clone(),
|
||||||
|
)?;
|
||||||
|
game_scheduler.queue().await?;
|
||||||
|
|
||||||
|
let member_scheduler = schedulers::member::scheduler::Scheduler::get_instance(
|
||||||
|
sched.clone(),
|
||||||
|
member_synchronizer.clone(),
|
||||||
|
)?;
|
||||||
|
member_scheduler.queue().await?;
|
||||||
|
|
||||||
|
let balance_scheduler = schedulers::balance::scheduler::Scheduler::get_instance(
|
||||||
|
sched.clone(),
|
||||||
|
member_account_synchronizer.clone(),
|
||||||
|
)?;
|
||||||
|
balance_scheduler.queue().await?;
|
||||||
|
|
||||||
|
let betting_history_scheduler = schedulers::betting_history::scheduler::Scheduler::get_instance(
|
||||||
|
sched.clone(),
|
||||||
|
betting_history_synchronizer.clone(),
|
||||||
|
)?;
|
||||||
|
betting_history_scheduler.queue().await?;
|
||||||
|
|
||||||
|
let _h_scheduler = sched.start().await?;
|
||||||
|
|
||||||
|
println!("Server service [beteran-api-kgon-server-service] is started");
|
||||||
|
|
||||||
|
futures::try_join!(
|
||||||
|
vendor_service.subscribe(),
|
||||||
|
game_service.subscribe(),
|
||||||
|
betting_service.subscribe(),
|
||||||
|
// member_service.subscribe(),
|
||||||
|
// member_account_service.subscribe(),
|
||||||
|
// betting_service.subscribe(),
|
||||||
|
member_event_handler.subscribe(),
|
||||||
|
member_bank_deposit_event_handler.subscribe(),
|
||||||
|
member_bank_withdraw_event_handler.subscribe(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
sched.shutdown().await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
9
src/repositories/balance/mod.rs
Normal file
9
src/repositories/balance/mod.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
|
///
|
||||||
|
pub mod models;
|
||||||
|
///
|
||||||
|
pub mod repository;
|
||||||
|
///
|
||||||
|
pub mod schema;
|
37
src/repositories/balance/models.rs
Normal file
37
src/repositories/balance/models.rs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
use super::schema::api_kgon_balances;
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Identifiable, Queryable, PartialEq, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_balances"]
|
||||||
|
pub struct Balance {
|
||||||
|
///
|
||||||
|
pub id: i32,
|
||||||
|
///
|
||||||
|
pub balance: f64,
|
||||||
|
///
|
||||||
|
pub balance_bota: f64,
|
||||||
|
///
|
||||||
|
pub created_at: i64,
|
||||||
|
///
|
||||||
|
pub updated_at: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Insertable, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_balances"]
|
||||||
|
pub struct NewBalance {
|
||||||
|
///
|
||||||
|
pub balance: f64,
|
||||||
|
///
|
||||||
|
pub balance_bota: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(AsChangeset, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_balances"]
|
||||||
|
pub struct ModifyBalance {
|
||||||
|
///
|
||||||
|
pub balance: f64,
|
||||||
|
///
|
||||||
|
pub balance_bota: f64,
|
||||||
|
}
|
75
src/repositories/balance/repository.rs
Normal file
75
src/repositories/balance/repository.rs
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
use super::{models, schema::api_kgon_balances};
|
||||||
|
use diesel::prelude::*;
|
||||||
|
use diesel::result::Error;
|
||||||
|
|
||||||
|
///
|
||||||
|
pub struct Repository {}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Repository {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Repository of api_kgon_balances").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Repository {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Repository {
|
||||||
|
///
|
||||||
|
pub fn new() -> Repository {
|
||||||
|
Repository {}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn insert(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
new_member: &models::NewBalance,
|
||||||
|
) -> Result<models::Balance, Error> {
|
||||||
|
let inserted = diesel::insert_into(api_kgon_balances::table)
|
||||||
|
.values(new_member)
|
||||||
|
.get_result::<models::Balance>(conn)?;
|
||||||
|
|
||||||
|
Ok(inserted)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select(&self, conn: &diesel::PgConnection) -> Result<Option<models::Balance>, Error> {
|
||||||
|
match api_kgon_balances::table.first::<models::Balance>(conn) {
|
||||||
|
Ok(m) => Ok(Some(m)),
|
||||||
|
Err(e) => match e {
|
||||||
|
diesel::result::Error::NotFound => Ok(None),
|
||||||
|
_ => Err(e),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn update(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
id: i32,
|
||||||
|
modify: &models::ModifyBalance,
|
||||||
|
) -> Result<u64, Error> {
|
||||||
|
use api_kgon_balances::dsl;
|
||||||
|
|
||||||
|
diesel::update(dsl::api_kgon_balances.filter(dsl::id.eq(id)))
|
||||||
|
.set(modify)
|
||||||
|
.execute(conn)
|
||||||
|
.map(|c| c as u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn delete(&self, conn: &diesel::PgConnection, id: i32) -> Result<u64, Error> {
|
||||||
|
use api_kgon_balances::dsl;
|
||||||
|
|
||||||
|
diesel::delete(api_kgon_balances::table.filter(dsl::id.eq(id)))
|
||||||
|
.execute(conn)
|
||||||
|
.map(|c| c as u64)
|
||||||
|
}
|
||||||
|
}
|
18
src/repositories/balance/schema.rs
Normal file
18
src/repositories/balance/schema.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
|
table! {
|
||||||
|
///
|
||||||
|
api_kgon_balances(id) {
|
||||||
|
///
|
||||||
|
id -> Integer,
|
||||||
|
///
|
||||||
|
balance -> Double,
|
||||||
|
///
|
||||||
|
balance_bota -> Double,
|
||||||
|
///
|
||||||
|
created_at -> BigInt,
|
||||||
|
///
|
||||||
|
updated_at -> BigInt,
|
||||||
|
}
|
||||||
|
}
|
9
src/repositories/betting_history/mod.rs
Normal file
9
src/repositories/betting_history/mod.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
|
///
|
||||||
|
pub mod models;
|
||||||
|
///
|
||||||
|
pub mod repository;
|
||||||
|
///
|
||||||
|
pub mod schema;
|
158
src/repositories/betting_history/models.rs
Normal file
158
src/repositories/betting_history/models.rs
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
use super::schema::api_kgon_betting_history;
|
||||||
|
use beteran_common_rust as bcr;
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Identifiable, Queryable, PartialEq, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_betting_history"]
|
||||||
|
pub struct BettingHistory {
|
||||||
|
///
|
||||||
|
pub id: String,
|
||||||
|
///
|
||||||
|
pub vendor_id: i64,
|
||||||
|
///
|
||||||
|
pub vendor_name: String,
|
||||||
|
///
|
||||||
|
pub game_id: i64,
|
||||||
|
///
|
||||||
|
pub game_name: String,
|
||||||
|
///
|
||||||
|
pub game_category: String,
|
||||||
|
///
|
||||||
|
pub game_type: String,
|
||||||
|
///
|
||||||
|
pub currency: String,
|
||||||
|
///
|
||||||
|
pub cash: f64,
|
||||||
|
///
|
||||||
|
pub before_cash: f64,
|
||||||
|
///
|
||||||
|
pub after_cash: f64,
|
||||||
|
///
|
||||||
|
pub group_key: Option<String>,
|
||||||
|
///
|
||||||
|
pub detail: Option<String>,
|
||||||
|
///
|
||||||
|
pub is_bonus: bool,
|
||||||
|
///
|
||||||
|
pub is_promo: bool,
|
||||||
|
///
|
||||||
|
pub is_jackpot: bool,
|
||||||
|
///
|
||||||
|
pub site_username: String,
|
||||||
|
///
|
||||||
|
pub key: String,
|
||||||
|
///
|
||||||
|
pub ref_id: String,
|
||||||
|
///
|
||||||
|
pub o_ref_id: Option<String>,
|
||||||
|
///
|
||||||
|
pub betting_type: String,
|
||||||
|
///
|
||||||
|
pub category: String,
|
||||||
|
///
|
||||||
|
pub created_at: i64,
|
||||||
|
///
|
||||||
|
pub utc_created_at: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Insertable, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_betting_history"]
|
||||||
|
pub struct NewBettingHistory {
|
||||||
|
///
|
||||||
|
pub id: String,
|
||||||
|
///
|
||||||
|
pub vendor_id: i64,
|
||||||
|
///
|
||||||
|
pub vendor_name: String,
|
||||||
|
///
|
||||||
|
pub game_id: i64,
|
||||||
|
///
|
||||||
|
pub game_name: String,
|
||||||
|
///
|
||||||
|
pub game_category: String,
|
||||||
|
///
|
||||||
|
pub game_type: String,
|
||||||
|
///
|
||||||
|
pub currency: String,
|
||||||
|
///
|
||||||
|
pub cash: f64,
|
||||||
|
///
|
||||||
|
pub before_cash: f64,
|
||||||
|
///
|
||||||
|
pub after_cash: f64,
|
||||||
|
///
|
||||||
|
pub group_key: Option<String>,
|
||||||
|
///
|
||||||
|
pub detail: Option<String>,
|
||||||
|
///
|
||||||
|
pub is_bonus: bool,
|
||||||
|
///
|
||||||
|
pub is_promo: bool,
|
||||||
|
///
|
||||||
|
pub is_jackpot: bool,
|
||||||
|
///
|
||||||
|
pub site_username: String,
|
||||||
|
///
|
||||||
|
pub key: String,
|
||||||
|
///
|
||||||
|
pub ref_id: String,
|
||||||
|
///
|
||||||
|
pub o_ref_id: Option<String>,
|
||||||
|
///
|
||||||
|
pub betting_type: String,
|
||||||
|
///
|
||||||
|
pub category: String,
|
||||||
|
///
|
||||||
|
pub created_at: i64,
|
||||||
|
///
|
||||||
|
pub utc_created_at: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct FindAllSearch {
|
||||||
|
///
|
||||||
|
pub vendor_id: Option<i64>,
|
||||||
|
///
|
||||||
|
pub vendor_name_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub game_id: Option<i64>,
|
||||||
|
///
|
||||||
|
pub game_name_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub game_category_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub game_type_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub currency_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub key_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub ref_id_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub o_ref_id_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub group_key_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub is_bonus: Option<bool>,
|
||||||
|
///
|
||||||
|
pub is_promo: Option<bool>,
|
||||||
|
///
|
||||||
|
pub is_jackpot: Option<bool>,
|
||||||
|
///
|
||||||
|
pub site_username_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub betting_type_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub category_like: Option<String>,
|
||||||
|
}
|
||||||
|
///
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct FindAll {
|
||||||
|
pub search: Option<FindAllSearch>,
|
||||||
|
///
|
||||||
|
pub pagination: Option<bcr::pagination::Pagination>,
|
||||||
|
///
|
||||||
|
pub sorts: Option<Vec<bcr::pagination::Sort>>,
|
||||||
|
}
|
366
src/repositories/betting_history/repository.rs
Normal file
366
src/repositories/betting_history/repository.rs
Normal file
|
@ -0,0 +1,366 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
use super::{models, schema::api_kgon_betting_history};
|
||||||
|
use beteran_common_rust as bcr;
|
||||||
|
use diesel::prelude::*;
|
||||||
|
use diesel::result::Error;
|
||||||
|
|
||||||
|
///
|
||||||
|
pub struct Repository {}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Repository {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Repository of api_kgon_betting_history")
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Repository {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Repository {
|
||||||
|
///
|
||||||
|
pub fn new() -> Repository {
|
||||||
|
Repository {}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn insert(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
new_betting_history: &models::NewBettingHistory,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
diesel::insert_into(api_kgon_betting_history::table)
|
||||||
|
.values(new_betting_history)
|
||||||
|
.execute(conn)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn inserts(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
new_betting_history: &Vec<models::NewBettingHistory>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
use api_kgon_betting_history::dsl;
|
||||||
|
|
||||||
|
diesel::insert_into(api_kgon_betting_history::table)
|
||||||
|
.values(new_betting_history)
|
||||||
|
.on_conflict(dsl::id)
|
||||||
|
.do_nothing()
|
||||||
|
.execute(conn)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
id: String,
|
||||||
|
) -> Result<Option<models::BettingHistory>, Error> {
|
||||||
|
match api_kgon_betting_history::table
|
||||||
|
.find(id)
|
||||||
|
.first::<models::BettingHistory>(conn)
|
||||||
|
{
|
||||||
|
Ok(m) => Ok(Some(m)),
|
||||||
|
Err(e) => match e {
|
||||||
|
diesel::result::Error::NotFound => Ok(None),
|
||||||
|
_ => Err(e),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select_all_count(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
find_all: &models::FindAll,
|
||||||
|
) -> Result<i64, Error> {
|
||||||
|
let mut q = api_kgon_betting_history::table.into_boxed();
|
||||||
|
|
||||||
|
if let Some(s) = &find_all.search {
|
||||||
|
if let Some(sp) = s.vendor_id {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::vendor_id.eq(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.vendor_name_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::vendor_name.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = s.game_id {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::game_id.eq(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.game_name_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::game_name.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.game_category_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::game_category.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.game_type_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::game_type.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.currency_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::currency.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.key_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::key.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.ref_id_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::ref_id.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.o_ref_id_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::o_ref_id.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.group_key_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::group_key.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = s.is_bonus {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::is_bonus.eq(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = s.is_promo {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::is_promo.eq(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = s.is_jackpot {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::is_jackpot.eq(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.site_username_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::site_username.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.betting_type_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::betting_type.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.category_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::category.like(sp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
q.count().get_result(conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select_all(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
find_all: &models::FindAll,
|
||||||
|
) -> Result<Vec<models::BettingHistory>, Error> {
|
||||||
|
let mut q = api_kgon_betting_history::table.into_boxed();
|
||||||
|
|
||||||
|
if let Some(s) = &find_all.search {
|
||||||
|
if let Some(sp) = s.vendor_id {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::vendor_id.eq(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.vendor_name_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::vendor_name.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = s.game_id {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::game_id.eq(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.game_name_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::game_name.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.game_category_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::game_category.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.game_type_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::game_type.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.currency_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::currency.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.key_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::key.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.ref_id_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::ref_id.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.o_ref_id_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::o_ref_id.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.group_key_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::group_key.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = s.is_bonus {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::is_bonus.eq(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = s.is_promo {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::is_promo.eq(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = s.is_jackpot {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::is_jackpot.eq(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.site_username_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::site_username.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.betting_type_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::betting_type.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.category_like {
|
||||||
|
q = q.filter(api_kgon_betting_history::dsl::category.like(sp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(p) = &find_all.pagination {
|
||||||
|
let page = p.page.unwrap_or(1);
|
||||||
|
|
||||||
|
if let Some(page_size) = p.page_size {
|
||||||
|
q = q.offset(((page - 1) * page_size) as i64);
|
||||||
|
q = q.limit(page_size as i64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(orderbys) = &find_all.sorts {
|
||||||
|
for s in orderbys {
|
||||||
|
match s {
|
||||||
|
bcr::pagination::Sort::ASC(property) => match property.as_str() {
|
||||||
|
"id" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::id.asc());
|
||||||
|
}
|
||||||
|
"vendor_id" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::vendor_id.asc());
|
||||||
|
}
|
||||||
|
"vendor_name" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::vendor_name.asc());
|
||||||
|
}
|
||||||
|
"game_id" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::game_id.asc());
|
||||||
|
}
|
||||||
|
"game_name" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::game_name.asc());
|
||||||
|
}
|
||||||
|
"game_category" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::game_category.asc());
|
||||||
|
}
|
||||||
|
"game_type" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::game_type.asc());
|
||||||
|
}
|
||||||
|
"currency" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::currency.asc());
|
||||||
|
}
|
||||||
|
"cash" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::cash.asc());
|
||||||
|
}
|
||||||
|
"before_cash" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::before_cash.asc());
|
||||||
|
}
|
||||||
|
"after_cash" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::after_cash.asc());
|
||||||
|
}
|
||||||
|
"key" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::key.asc());
|
||||||
|
}
|
||||||
|
"ref_id" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::ref_id.asc());
|
||||||
|
}
|
||||||
|
"o_ref_id" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::o_ref_id.asc());
|
||||||
|
}
|
||||||
|
"group_key" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::group_key.asc());
|
||||||
|
}
|
||||||
|
"is_bonus" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::is_bonus.asc());
|
||||||
|
}
|
||||||
|
"is_promo" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::is_promo.asc());
|
||||||
|
}
|
||||||
|
"is_jackpot" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::is_jackpot.asc());
|
||||||
|
}
|
||||||
|
"site_username" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::site_username.asc());
|
||||||
|
}
|
||||||
|
"betting_type" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::betting_type.asc());
|
||||||
|
}
|
||||||
|
"category" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::category.asc());
|
||||||
|
}
|
||||||
|
"created_at" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::created_at.asc());
|
||||||
|
}
|
||||||
|
"utc_created_at" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::utc_created_at.asc());
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
bcr::pagination::Sort::DESC(property) => match property.as_str() {
|
||||||
|
"id" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::id.desc());
|
||||||
|
}
|
||||||
|
"vendor_id" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::vendor_id.desc());
|
||||||
|
}
|
||||||
|
"vendor_name" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::vendor_name.desc());
|
||||||
|
}
|
||||||
|
"game_id" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::game_id.desc());
|
||||||
|
}
|
||||||
|
"game_name" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::game_name.desc());
|
||||||
|
}
|
||||||
|
"game_category" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::game_category.desc());
|
||||||
|
}
|
||||||
|
"game_type" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::game_type.desc());
|
||||||
|
}
|
||||||
|
"currency" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::currency.desc());
|
||||||
|
}
|
||||||
|
"cash" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::cash.desc());
|
||||||
|
}
|
||||||
|
"before_cash" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::before_cash.desc());
|
||||||
|
}
|
||||||
|
"after_cash" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::after_cash.desc());
|
||||||
|
}
|
||||||
|
"key" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::key.desc());
|
||||||
|
}
|
||||||
|
"ref_id" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::ref_id.desc());
|
||||||
|
}
|
||||||
|
"o_ref_id" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::o_ref_id.desc());
|
||||||
|
}
|
||||||
|
"group_key" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::group_key.desc());
|
||||||
|
}
|
||||||
|
"is_bonus" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::is_bonus.desc());
|
||||||
|
}
|
||||||
|
"is_promo" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::is_promo.desc());
|
||||||
|
}
|
||||||
|
"is_jackpot" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::is_jackpot.desc());
|
||||||
|
}
|
||||||
|
"site_username" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::site_username.desc());
|
||||||
|
}
|
||||||
|
"betting_type" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::betting_type.desc());
|
||||||
|
}
|
||||||
|
"category" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::category.desc());
|
||||||
|
}
|
||||||
|
"created_at" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::created_at.desc());
|
||||||
|
}
|
||||||
|
"utc_created_at" => {
|
||||||
|
q = q.order_by(api_kgon_betting_history::utc_created_at.desc());
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
q.load::<models::BettingHistory>(conn)
|
||||||
|
}
|
||||||
|
}
|
56
src/repositories/betting_history/schema.rs
Normal file
56
src/repositories/betting_history/schema.rs
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
|
table! {
|
||||||
|
///
|
||||||
|
api_kgon_betting_history(id) {
|
||||||
|
///
|
||||||
|
id -> Text,
|
||||||
|
///
|
||||||
|
vendor_id -> BigInt,
|
||||||
|
///
|
||||||
|
vendor_name -> Text,
|
||||||
|
///
|
||||||
|
game_id -> BigInt,
|
||||||
|
///
|
||||||
|
game_name -> Text,
|
||||||
|
///
|
||||||
|
game_category -> Text,
|
||||||
|
///
|
||||||
|
game_type -> Text,
|
||||||
|
///
|
||||||
|
currency -> Text,
|
||||||
|
///
|
||||||
|
cash -> Double,
|
||||||
|
///
|
||||||
|
before_cash -> Double,
|
||||||
|
///
|
||||||
|
after_cash -> Double,
|
||||||
|
///
|
||||||
|
group_key -> Nullable<Text>,
|
||||||
|
///
|
||||||
|
detail -> Nullable<Text>,
|
||||||
|
///
|
||||||
|
is_bonus -> Bool,
|
||||||
|
///
|
||||||
|
is_promo -> Bool,
|
||||||
|
///
|
||||||
|
is_jackpot -> Bool,
|
||||||
|
///
|
||||||
|
site_username -> Text,
|
||||||
|
///
|
||||||
|
key -> Text,
|
||||||
|
///
|
||||||
|
ref_id -> Text,
|
||||||
|
///
|
||||||
|
o_ref_id -> Nullable<Text>,
|
||||||
|
///
|
||||||
|
betting_type -> Text,
|
||||||
|
///
|
||||||
|
category -> Text,
|
||||||
|
///
|
||||||
|
created_at -> BigInt,
|
||||||
|
///
|
||||||
|
utc_created_at -> BigInt,
|
||||||
|
}
|
||||||
|
}
|
9
src/repositories/game/mod.rs
Normal file
9
src/repositories/game/mod.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
|
///
|
||||||
|
pub mod models;
|
||||||
|
///
|
||||||
|
pub mod repository;
|
||||||
|
///
|
||||||
|
pub mod schema;
|
114
src/repositories/game/models.rs
Normal file
114
src/repositories/game/models.rs
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
use super::schema::api_kgon_games;
|
||||||
|
use beteran_common_rust as bcr;
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Eq, Hash, Identifiable, Queryable, PartialEq, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_games"]
|
||||||
|
pub struct Game {
|
||||||
|
///
|
||||||
|
pub id: i64,
|
||||||
|
///
|
||||||
|
pub parent_id: i64,
|
||||||
|
///
|
||||||
|
pub key: String,
|
||||||
|
///
|
||||||
|
pub names: String,
|
||||||
|
///
|
||||||
|
pub platform: String,
|
||||||
|
///
|
||||||
|
pub category: String,
|
||||||
|
///
|
||||||
|
pub game_type: String,
|
||||||
|
///
|
||||||
|
pub image: Option<String>,
|
||||||
|
///
|
||||||
|
pub created_at: i64,
|
||||||
|
///
|
||||||
|
pub updated_at: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Insertable, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_games"]
|
||||||
|
pub struct NewGame {
|
||||||
|
///
|
||||||
|
pub id: i64,
|
||||||
|
///
|
||||||
|
pub parent_id: i64,
|
||||||
|
///
|
||||||
|
pub key: String,
|
||||||
|
///
|
||||||
|
pub names: String,
|
||||||
|
///
|
||||||
|
pub platform: String,
|
||||||
|
///
|
||||||
|
pub category: String,
|
||||||
|
///
|
||||||
|
pub game_type: String,
|
||||||
|
///
|
||||||
|
pub image: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(AsChangeset, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_games"]
|
||||||
|
pub struct ModifyGame {
|
||||||
|
///
|
||||||
|
pub key: String,
|
||||||
|
///
|
||||||
|
pub names: String,
|
||||||
|
///
|
||||||
|
pub platform: String,
|
||||||
|
///
|
||||||
|
pub category: String,
|
||||||
|
///
|
||||||
|
pub game_type: String,
|
||||||
|
///
|
||||||
|
pub image: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Insertable, AsChangeset, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_games"]
|
||||||
|
pub struct UpsertGame {
|
||||||
|
///
|
||||||
|
pub id: i64,
|
||||||
|
///
|
||||||
|
pub parent_id: i64,
|
||||||
|
///
|
||||||
|
pub key: String,
|
||||||
|
///
|
||||||
|
pub names: String,
|
||||||
|
///
|
||||||
|
pub platform: String,
|
||||||
|
///
|
||||||
|
pub category: String,
|
||||||
|
///
|
||||||
|
pub game_type: String,
|
||||||
|
///
|
||||||
|
pub image: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct FindAllSearch {
|
||||||
|
///
|
||||||
|
pub parent_id: Option<i64>,
|
||||||
|
///
|
||||||
|
pub key_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub platform_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub category_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub game_type_like: Option<String>,
|
||||||
|
}
|
||||||
|
///
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct FindAll {
|
||||||
|
pub search: Option<FindAllSearch>,
|
||||||
|
///
|
||||||
|
pub pagination: Option<bcr::pagination::Pagination>,
|
||||||
|
///
|
||||||
|
pub sorts: Option<Vec<bcr::pagination::Sort>>,
|
||||||
|
}
|
228
src/repositories/game/repository.rs
Normal file
228
src/repositories/game/repository.rs
Normal file
|
@ -0,0 +1,228 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
use super::{models, schema::api_kgon_games};
|
||||||
|
use beteran_common_rust as bcr;
|
||||||
|
use diesel::prelude::*;
|
||||||
|
use diesel::result::Error;
|
||||||
|
|
||||||
|
///
|
||||||
|
pub struct Repository {}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Repository {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Repository of api_kgon_games").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Repository {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Repository {
|
||||||
|
///
|
||||||
|
pub fn new() -> Repository {
|
||||||
|
Repository {}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn insert(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
new_member: &models::NewGame,
|
||||||
|
) -> Result<models::Game, Error> {
|
||||||
|
let inserted = diesel::insert_into(api_kgon_games::table)
|
||||||
|
.values(new_member)
|
||||||
|
.get_result::<models::Game>(conn)?;
|
||||||
|
|
||||||
|
Ok(inserted)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn upserts(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
upsert_games: Vec<models::UpsertGame>,
|
||||||
|
) -> Result<usize, Error> {
|
||||||
|
use api_kgon_games::dsl;
|
||||||
|
use diesel::pg::upsert::excluded;
|
||||||
|
|
||||||
|
let affected = diesel::insert_into(api_kgon_games::table)
|
||||||
|
.values(upsert_games)
|
||||||
|
.on_conflict(dsl::id)
|
||||||
|
.do_update()
|
||||||
|
.set((
|
||||||
|
dsl::parent_id.eq(excluded(dsl::parent_id)),
|
||||||
|
dsl::key.eq(excluded(dsl::key)),
|
||||||
|
dsl::names.eq(excluded(dsl::names)),
|
||||||
|
dsl::platform.eq(excluded(dsl::platform)),
|
||||||
|
dsl::category.eq(excluded(dsl::category)),
|
||||||
|
dsl::game_type.eq(excluded(dsl::game_type)),
|
||||||
|
dsl::image.eq(excluded(dsl::image)),
|
||||||
|
))
|
||||||
|
.execute(conn)?;
|
||||||
|
|
||||||
|
Ok(affected)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
id: i64,
|
||||||
|
) -> Result<Option<models::Game>, Error> {
|
||||||
|
match api_kgon_games::table.find(id).first::<models::Game>(conn) {
|
||||||
|
Ok(m) => Ok(Some(m)),
|
||||||
|
Err(e) => match e {
|
||||||
|
diesel::result::Error::NotFound => Ok(None),
|
||||||
|
_ => Err(e),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select_all_count(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
find_all: &models::FindAll,
|
||||||
|
) -> Result<i64, Error> {
|
||||||
|
let mut q = api_kgon_games::table.into_boxed();
|
||||||
|
|
||||||
|
if let Some(s) = &find_all.search {
|
||||||
|
if let Some(sp) = s.parent_id {
|
||||||
|
q = q.filter(api_kgon_games::dsl::parent_id.eq(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.key_like {
|
||||||
|
q = q.filter(api_kgon_games::dsl::key.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.platform_like {
|
||||||
|
q = q.filter(api_kgon_games::dsl::platform.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.category_like {
|
||||||
|
q = q.filter(api_kgon_games::dsl::category.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.game_type_like {
|
||||||
|
q = q.filter(api_kgon_games::dsl::game_type.like(sp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
q.count().get_result(conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select_all(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
find_all: &models::FindAll,
|
||||||
|
) -> Result<Vec<models::Game>, Error> {
|
||||||
|
let mut q = api_kgon_games::table.into_boxed();
|
||||||
|
|
||||||
|
if let Some(s) = &find_all.search {
|
||||||
|
if let Some(sp) = s.parent_id {
|
||||||
|
q = q.filter(api_kgon_games::dsl::parent_id.eq(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.key_like {
|
||||||
|
q = q.filter(api_kgon_games::dsl::key.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.platform_like {
|
||||||
|
q = q.filter(api_kgon_games::dsl::platform.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.category_like {
|
||||||
|
q = q.filter(api_kgon_games::dsl::category.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.game_type_like {
|
||||||
|
q = q.filter(api_kgon_games::dsl::game_type.like(sp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(p) = &find_all.pagination {
|
||||||
|
let page = p.page.unwrap_or(1);
|
||||||
|
|
||||||
|
if let Some(page_size) = p.page_size {
|
||||||
|
q = q.offset(((page - 1) * page_size) as i64);
|
||||||
|
q = q.limit(page_size as i64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(orderbys) = &find_all.sorts {
|
||||||
|
for s in orderbys {
|
||||||
|
match s {
|
||||||
|
bcr::pagination::Sort::ASC(property) => match property.as_str() {
|
||||||
|
"parent_id" => {
|
||||||
|
q = q.order_by(api_kgon_games::parent_id.asc());
|
||||||
|
}
|
||||||
|
"key" => {
|
||||||
|
q = q.order_by(api_kgon_games::key.asc());
|
||||||
|
}
|
||||||
|
"platform" => {
|
||||||
|
q = q.order_by(api_kgon_games::platform.asc());
|
||||||
|
}
|
||||||
|
"category" => {
|
||||||
|
q = q.order_by(api_kgon_games::category.asc());
|
||||||
|
}
|
||||||
|
"game_type" => {
|
||||||
|
q = q.order_by(api_kgon_games::game_type.asc());
|
||||||
|
}
|
||||||
|
"created_at" => {
|
||||||
|
q = q.order_by(api_kgon_games::created_at.asc());
|
||||||
|
}
|
||||||
|
"updated_at" => {
|
||||||
|
q = q.order_by(api_kgon_games::updated_at.asc());
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
bcr::pagination::Sort::DESC(property) => match property.as_str() {
|
||||||
|
"parent_id" => {
|
||||||
|
q = q.order_by(api_kgon_games::parent_id.desc());
|
||||||
|
}
|
||||||
|
"key" => {
|
||||||
|
q = q.order_by(api_kgon_games::key.desc());
|
||||||
|
}
|
||||||
|
"platform" => {
|
||||||
|
q = q.order_by(api_kgon_games::platform.desc());
|
||||||
|
}
|
||||||
|
"category" => {
|
||||||
|
q = q.order_by(api_kgon_games::category.desc());
|
||||||
|
}
|
||||||
|
"game_type" => {
|
||||||
|
q = q.order_by(api_kgon_games::game_type.desc());
|
||||||
|
}
|
||||||
|
"created_at" => {
|
||||||
|
q = q.order_by(api_kgon_games::created_at.desc());
|
||||||
|
}
|
||||||
|
"updated_at" => {
|
||||||
|
q = q.order_by(api_kgon_games::updated_at.desc());
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
q.load::<models::Game>(conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn update(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
id: i64,
|
||||||
|
modify: &models::ModifyGame,
|
||||||
|
) -> Result<u64, Error> {
|
||||||
|
use api_kgon_games::dsl;
|
||||||
|
|
||||||
|
diesel::update(dsl::api_kgon_games.filter(dsl::id.eq(id)))
|
||||||
|
.set(modify)
|
||||||
|
.execute(conn)
|
||||||
|
.map(|c| c as u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn delete(&self, conn: &diesel::PgConnection, id: i64) -> Result<u64, Error> {
|
||||||
|
use api_kgon_games::dsl;
|
||||||
|
|
||||||
|
diesel::delete(api_kgon_games::table.filter(dsl::id.eq(id)))
|
||||||
|
.execute(conn)
|
||||||
|
.map(|c| c as u64)
|
||||||
|
}
|
||||||
|
}
|
28
src/repositories/game/schema.rs
Normal file
28
src/repositories/game/schema.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
|
table! {
|
||||||
|
///
|
||||||
|
api_kgon_games(id) {
|
||||||
|
///
|
||||||
|
id -> BigInt,
|
||||||
|
///
|
||||||
|
parent_id -> BigInt,
|
||||||
|
///
|
||||||
|
key -> Text,
|
||||||
|
///
|
||||||
|
names -> Text,
|
||||||
|
///
|
||||||
|
platform -> Text,
|
||||||
|
///
|
||||||
|
category -> Text,
|
||||||
|
///
|
||||||
|
game_type -> Text,
|
||||||
|
///
|
||||||
|
image -> Nullable<Text>,
|
||||||
|
///
|
||||||
|
created_at -> BigInt,
|
||||||
|
///
|
||||||
|
updated_at -> BigInt,
|
||||||
|
}
|
||||||
|
}
|
9
src/repositories/member/mod.rs
Normal file
9
src/repositories/member/mod.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
|
///
|
||||||
|
pub mod models;
|
||||||
|
///
|
||||||
|
pub mod repository;
|
||||||
|
///
|
||||||
|
pub mod schema;
|
78
src/repositories/member/models.rs
Normal file
78
src/repositories/member/models.rs
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
use super::schema::api_kgon_members;
|
||||||
|
use beteran_common_rust as bcr;
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Identifiable, Queryable, PartialEq, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_members"]
|
||||||
|
pub struct Member {
|
||||||
|
///
|
||||||
|
pub id: i64,
|
||||||
|
///
|
||||||
|
pub balance: f64,
|
||||||
|
///
|
||||||
|
pub balance_bota: f64,
|
||||||
|
///
|
||||||
|
pub balance_sum: f64,
|
||||||
|
///
|
||||||
|
pub companies: Option<String>,
|
||||||
|
///
|
||||||
|
pub oriental_play: String,
|
||||||
|
///
|
||||||
|
pub member_id: uuid::Uuid,
|
||||||
|
///
|
||||||
|
pub created_at: i64,
|
||||||
|
///
|
||||||
|
pub updated_at: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Insertable, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_members"]
|
||||||
|
pub struct NewMember {
|
||||||
|
///
|
||||||
|
pub id: i64,
|
||||||
|
///
|
||||||
|
pub member_id: uuid::Uuid,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(AsChangeset, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_members"]
|
||||||
|
pub struct ModifyMember {
|
||||||
|
///
|
||||||
|
pub balance: f64,
|
||||||
|
///
|
||||||
|
pub balance_bota: f64,
|
||||||
|
///
|
||||||
|
pub oriental_play: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(AsChangeset, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_members"]
|
||||||
|
pub struct ModifyMemberForBalance {
|
||||||
|
///
|
||||||
|
pub balance: f64,
|
||||||
|
///
|
||||||
|
pub balance_bota: f64,
|
||||||
|
///
|
||||||
|
pub balance_sum: f64,
|
||||||
|
///
|
||||||
|
pub companies: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct FindAllSearch {
|
||||||
|
///
|
||||||
|
pub oriental_play: Option<String>,
|
||||||
|
}
|
||||||
|
///
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct FindAll {
|
||||||
|
pub search: Option<FindAllSearch>,
|
||||||
|
///
|
||||||
|
pub pagination: Option<bcr::pagination::Pagination>,
|
||||||
|
///
|
||||||
|
pub sorts: Option<Vec<bcr::pagination::Sort>>,
|
||||||
|
}
|
215
src/repositories/member/repository.rs
Normal file
215
src/repositories/member/repository.rs
Normal file
|
@ -0,0 +1,215 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
use super::{models, schema::api_kgon_members};
|
||||||
|
use beteran_common_rust as bcr;
|
||||||
|
use diesel::prelude::*;
|
||||||
|
use diesel::result::Error;
|
||||||
|
|
||||||
|
///
|
||||||
|
pub struct Repository {}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Repository {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Repository of api_kgon_members").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Repository {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Repository {
|
||||||
|
///
|
||||||
|
pub fn new() -> Repository {
|
||||||
|
Repository {}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn insert(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
new_member: &models::NewMember,
|
||||||
|
) -> Result<models::Member, Error> {
|
||||||
|
let inserted = diesel::insert_into(api_kgon_members::table)
|
||||||
|
.values(new_member)
|
||||||
|
.get_result::<models::Member>(conn)?;
|
||||||
|
|
||||||
|
Ok(inserted)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
id: i64,
|
||||||
|
) -> Result<Option<models::Member>, Error> {
|
||||||
|
match api_kgon_members::table
|
||||||
|
.find(id)
|
||||||
|
.first::<models::Member>(conn)
|
||||||
|
{
|
||||||
|
Ok(m) => Ok(Some(m)),
|
||||||
|
Err(e) => match e {
|
||||||
|
diesel::result::Error::NotFound => Ok(None),
|
||||||
|
_ => Err(e),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select_by_member_id(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
member_id: uuid::Uuid,
|
||||||
|
) -> Result<Option<models::Member>, Error> {
|
||||||
|
use api_kgon_members::dsl;
|
||||||
|
|
||||||
|
match api_kgon_members::table
|
||||||
|
.filter(dsl::member_id.eq(member_id))
|
||||||
|
.first::<models::Member>(conn)
|
||||||
|
{
|
||||||
|
Ok(m) => Ok(Some(m)),
|
||||||
|
Err(e) => match e {
|
||||||
|
diesel::result::Error::NotFound => Ok(None),
|
||||||
|
_ => Err(e),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select_all_count(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
find_all: &models::FindAll,
|
||||||
|
) -> Result<i64, Error> {
|
||||||
|
let mut q = api_kgon_members::table.into_boxed();
|
||||||
|
|
||||||
|
if let Some(s) = &find_all.search {
|
||||||
|
if let Some(sp) = &s.oriental_play {
|
||||||
|
q = q.filter(api_kgon_members::dsl::oriental_play.eq(sp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
q.count().get_result(conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select_all(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
find_all: &models::FindAll,
|
||||||
|
) -> Result<Vec<models::Member>, Error> {
|
||||||
|
let mut q = api_kgon_members::table.into_boxed();
|
||||||
|
|
||||||
|
if let Some(s) = &find_all.search {
|
||||||
|
if let Some(sp) = &s.oriental_play {
|
||||||
|
q = q.filter(api_kgon_members::dsl::oriental_play.eq(sp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(p) = &find_all.pagination {
|
||||||
|
let page = p.page.unwrap_or(1);
|
||||||
|
|
||||||
|
if let Some(page_size) = p.page_size {
|
||||||
|
q = q.offset(((page - 1) * page_size) as i64);
|
||||||
|
q = q.limit(page_size as i64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(orderbys) = &find_all.sorts {
|
||||||
|
for s in orderbys {
|
||||||
|
match s {
|
||||||
|
bcr::pagination::Sort::ASC(property) => match property.as_str() {
|
||||||
|
"balance" => {
|
||||||
|
q = q.order_by(api_kgon_members::balance.asc());
|
||||||
|
}
|
||||||
|
"balance_bota" => {
|
||||||
|
q = q.order_by(api_kgon_members::balance_bota.asc());
|
||||||
|
}
|
||||||
|
"balance_sum" => {
|
||||||
|
q = q.order_by(api_kgon_members::balance_sum.asc());
|
||||||
|
}
|
||||||
|
"companies" => {
|
||||||
|
q = q.order_by(api_kgon_members::companies.asc());
|
||||||
|
}
|
||||||
|
"oriental_play" => {
|
||||||
|
q = q.order_by(api_kgon_members::oriental_play.asc());
|
||||||
|
}
|
||||||
|
"created_at" => {
|
||||||
|
q = q.order_by(api_kgon_members::created_at.asc());
|
||||||
|
}
|
||||||
|
"updated_at" => {
|
||||||
|
q = q.order_by(api_kgon_members::updated_at.asc());
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
bcr::pagination::Sort::DESC(property) => match property.as_str() {
|
||||||
|
"balance" => {
|
||||||
|
q = q.order_by(api_kgon_members::balance.desc());
|
||||||
|
}
|
||||||
|
"balance_bota" => {
|
||||||
|
q = q.order_by(api_kgon_members::balance_bota.desc());
|
||||||
|
}
|
||||||
|
"balance_sum" => {
|
||||||
|
q = q.order_by(api_kgon_members::balance_sum.desc());
|
||||||
|
}
|
||||||
|
"companies" => {
|
||||||
|
q = q.order_by(api_kgon_members::companies.desc());
|
||||||
|
}
|
||||||
|
"oriental_play" => {
|
||||||
|
q = q.order_by(api_kgon_members::oriental_play.desc());
|
||||||
|
}
|
||||||
|
"created_at" => {
|
||||||
|
q = q.order_by(api_kgon_members::created_at.desc());
|
||||||
|
}
|
||||||
|
"updated_at" => {
|
||||||
|
q = q.order_by(api_kgon_members::updated_at.desc());
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
q.load::<models::Member>(conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn update(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
id: i64,
|
||||||
|
modify: &models::ModifyMember,
|
||||||
|
) -> Result<u64, Error> {
|
||||||
|
use api_kgon_members::dsl;
|
||||||
|
|
||||||
|
diesel::update(dsl::api_kgon_members.filter(dsl::id.eq(id)))
|
||||||
|
.set(modify)
|
||||||
|
.execute(conn)
|
||||||
|
.map(|c| c as u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn update_balance(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
id: i64,
|
||||||
|
modify: &models::ModifyMemberForBalance,
|
||||||
|
) -> Result<u64, Error> {
|
||||||
|
use api_kgon_members::dsl;
|
||||||
|
|
||||||
|
diesel::update(dsl::api_kgon_members.filter(dsl::id.eq(id)))
|
||||||
|
.set(modify)
|
||||||
|
.execute(conn)
|
||||||
|
.map(|c| c as u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn delete(&self, conn: &diesel::PgConnection, id: i64) -> Result<u64, Error> {
|
||||||
|
use api_kgon_members::dsl;
|
||||||
|
|
||||||
|
diesel::delete(api_kgon_members::table.filter(dsl::id.eq(id)))
|
||||||
|
.execute(conn)
|
||||||
|
.map(|c| c as u64)
|
||||||
|
}
|
||||||
|
}
|
26
src/repositories/member/schema.rs
Normal file
26
src/repositories/member/schema.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
|
table! {
|
||||||
|
///
|
||||||
|
api_kgon_members(id) {
|
||||||
|
///
|
||||||
|
id -> BigInt,
|
||||||
|
///
|
||||||
|
balance -> Double,
|
||||||
|
///
|
||||||
|
balance_bota -> Double,
|
||||||
|
///
|
||||||
|
balance_sum -> Double,
|
||||||
|
///
|
||||||
|
companies -> Nullable<Text>,
|
||||||
|
///
|
||||||
|
oriental_play -> Text,
|
||||||
|
///
|
||||||
|
member_id -> Uuid,
|
||||||
|
///
|
||||||
|
created_at -> BigInt,
|
||||||
|
///
|
||||||
|
updated_at -> BigInt,
|
||||||
|
}
|
||||||
|
}
|
7
src/repositories/mod.rs
Normal file
7
src/repositories/mod.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
pub mod balance;
|
||||||
|
pub mod betting_history;
|
||||||
|
pub mod game;
|
||||||
|
pub mod member;
|
||||||
|
pub mod synchronization;
|
||||||
|
pub mod synchronization_history;
|
||||||
|
pub mod vendor;
|
9
src/repositories/synchronization/mod.rs
Normal file
9
src/repositories/synchronization/mod.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
|
///
|
||||||
|
pub mod models;
|
||||||
|
///
|
||||||
|
pub mod repository;
|
||||||
|
///
|
||||||
|
pub mod schema;
|
41
src/repositories/synchronization/models.rs
Normal file
41
src/repositories/synchronization/models.rs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
use super::schema::api_kgon_synchronizations;
|
||||||
|
|
||||||
|
pub static ITEM_MEMBERS: &str = "members";
|
||||||
|
pub static ITEM_BALANCE_PARTNER: &str = "balance_partner";
|
||||||
|
pub static ITEM_BALANCE_USER_ALL: &str = "balance_user_all";
|
||||||
|
pub static ITEM_BALANCE_USER: &str = "balance_user";
|
||||||
|
pub static ITEM_VENDORS: &str = "vendors";
|
||||||
|
pub static ITEM_GAMES: &str = "games";
|
||||||
|
pub static ITEM_BETTING_HISTORY: &str = "betting_history";
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Eq, Hash, Identifiable, Queryable, PartialEq, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_synchronizations"]
|
||||||
|
pub struct Synchronization {
|
||||||
|
///
|
||||||
|
pub id: i32,
|
||||||
|
///
|
||||||
|
pub item: String,
|
||||||
|
///
|
||||||
|
pub last_code: i64,
|
||||||
|
///
|
||||||
|
pub synchronized_at: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Insertable, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_synchronizations"]
|
||||||
|
pub struct NewSynchronization {
|
||||||
|
///
|
||||||
|
pub item: String,
|
||||||
|
///
|
||||||
|
pub last_code: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(AsChangeset, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_synchronizations"]
|
||||||
|
pub struct ModifySynchronization {
|
||||||
|
///
|
||||||
|
pub last_code: i64,
|
||||||
|
}
|
103
src/repositories/synchronization/repository.rs
Normal file
103
src/repositories/synchronization/repository.rs
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
use super::{models, schema::api_kgon_synchronizations};
|
||||||
|
use diesel::prelude::*;
|
||||||
|
use diesel::result::Error;
|
||||||
|
|
||||||
|
///
|
||||||
|
pub struct Repository {}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Repository {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Repository of api_kgon_synchronizations")
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Repository {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Repository {
|
||||||
|
///
|
||||||
|
pub fn new() -> Repository {
|
||||||
|
Repository {}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn insert(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
new_member: &models::NewSynchronization,
|
||||||
|
) -> Result<models::Synchronization, Error> {
|
||||||
|
let inserted = diesel::insert_into(api_kgon_synchronizations::table)
|
||||||
|
.values(new_member)
|
||||||
|
.get_result::<models::Synchronization>(conn)?;
|
||||||
|
|
||||||
|
Ok(inserted)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
id: i32,
|
||||||
|
) -> Result<Option<models::Synchronization>, Error> {
|
||||||
|
match api_kgon_synchronizations::table
|
||||||
|
.find(id)
|
||||||
|
.first::<models::Synchronization>(conn)
|
||||||
|
{
|
||||||
|
Ok(m) => Ok(Some(m)),
|
||||||
|
Err(e) => match e {
|
||||||
|
diesel::result::Error::NotFound => Ok(None),
|
||||||
|
_ => Err(e),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select_by_item(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
item: String,
|
||||||
|
) -> Result<Option<models::Synchronization>, Error> {
|
||||||
|
use api_kgon_synchronizations::dsl;
|
||||||
|
|
||||||
|
match api_kgon_synchronizations::table
|
||||||
|
.filter(dsl::item.eq(item))
|
||||||
|
.first::<models::Synchronization>(conn)
|
||||||
|
{
|
||||||
|
Ok(m) => Ok(Some(m)),
|
||||||
|
Err(e) => match e {
|
||||||
|
diesel::result::Error::NotFound => Ok(None),
|
||||||
|
_ => Err(e),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn update(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
id: i32,
|
||||||
|
modify: &models::ModifySynchronization,
|
||||||
|
) -> Result<u64, Error> {
|
||||||
|
use api_kgon_synchronizations::dsl;
|
||||||
|
|
||||||
|
diesel::update(dsl::api_kgon_synchronizations.filter(dsl::id.eq(id)))
|
||||||
|
.set(modify)
|
||||||
|
.execute(conn)
|
||||||
|
.map(|c| c as u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn delete(&self, conn: &diesel::PgConnection, id: i32) -> Result<u64, Error> {
|
||||||
|
use api_kgon_synchronizations::dsl;
|
||||||
|
|
||||||
|
diesel::delete(api_kgon_synchronizations::table.filter(dsl::id.eq(id)))
|
||||||
|
.execute(conn)
|
||||||
|
.map(|c| c as u64)
|
||||||
|
}
|
||||||
|
}
|
16
src/repositories/synchronization/schema.rs
Normal file
16
src/repositories/synchronization/schema.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
|
table! {
|
||||||
|
///
|
||||||
|
api_kgon_synchronizations(id) {
|
||||||
|
///
|
||||||
|
id -> Integer,
|
||||||
|
///
|
||||||
|
item -> Text,
|
||||||
|
///
|
||||||
|
last_code -> BigInt,
|
||||||
|
///
|
||||||
|
synchronized_at -> BigInt,
|
||||||
|
}
|
||||||
|
}
|
9
src/repositories/synchronization_history/mod.rs
Normal file
9
src/repositories/synchronization_history/mod.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
|
///
|
||||||
|
pub mod models;
|
||||||
|
///
|
||||||
|
pub mod repository;
|
||||||
|
///
|
||||||
|
pub mod schema;
|
76
src/repositories/synchronization_history/models.rs
Normal file
76
src/repositories/synchronization_history/models.rs
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
use super::schema::api_kgon_synchronization_history;
|
||||||
|
use beteran_common_rust as bcr;
|
||||||
|
use diesel::deserialize::QueryableByName;
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Eq, Hash, Identifiable, Queryable, PartialEq, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_synchronization_history"]
|
||||||
|
pub struct SynchronizationHistory {
|
||||||
|
///
|
||||||
|
pub id: i64,
|
||||||
|
///
|
||||||
|
pub item: String,
|
||||||
|
///
|
||||||
|
pub start_at: i64,
|
||||||
|
///
|
||||||
|
pub complete_at: i64,
|
||||||
|
///
|
||||||
|
pub code: i64,
|
||||||
|
///
|
||||||
|
pub message: Option<String>,
|
||||||
|
///
|
||||||
|
pub data: Option<String>,
|
||||||
|
///
|
||||||
|
pub created_at: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Insertable, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_synchronization_history"]
|
||||||
|
pub struct NewSynchronizationHistory {
|
||||||
|
///
|
||||||
|
pub item: String,
|
||||||
|
///
|
||||||
|
pub start_at: i64,
|
||||||
|
///
|
||||||
|
pub complete_at: i64,
|
||||||
|
///
|
||||||
|
pub code: i64,
|
||||||
|
///
|
||||||
|
pub message: Option<String>,
|
||||||
|
///
|
||||||
|
pub data: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct FindAllSearch {
|
||||||
|
///
|
||||||
|
pub item: Option<String>,
|
||||||
|
///
|
||||||
|
pub code: Option<i64>,
|
||||||
|
}
|
||||||
|
///
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct FindAll {
|
||||||
|
pub search: Option<FindAllSearch>,
|
||||||
|
///
|
||||||
|
pub pagination: Option<bcr::pagination::Pagination>,
|
||||||
|
///
|
||||||
|
pub sorts: Option<Vec<bcr::pagination::Sort>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl QueryableByName<diesel::pg::Pg> for SynchronizationHistory {
|
||||||
|
fn build<R: diesel::row::NamedRow<diesel::pg::Pg>>(row: &R) -> diesel::deserialize::Result<Self> {
|
||||||
|
Ok(SynchronizationHistory {
|
||||||
|
id: row.get("id")?,
|
||||||
|
item: row.get("item")?,
|
||||||
|
start_at: row.get("start_at")?,
|
||||||
|
complete_at: row.get("complete_at")?,
|
||||||
|
code: row.get("code")?,
|
||||||
|
message: row.get("message")?,
|
||||||
|
data: row.get("data")?,
|
||||||
|
created_at: row.get("created_at")?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
206
src/repositories/synchronization_history/repository.rs
Normal file
206
src/repositories/synchronization_history/repository.rs
Normal file
|
@ -0,0 +1,206 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
use super::{models, schema::api_kgon_synchronization_history};
|
||||||
|
use beteran_common_rust as bcr;
|
||||||
|
use diesel::result::Error;
|
||||||
|
use diesel::{prelude::*, sql_query};
|
||||||
|
|
||||||
|
///
|
||||||
|
pub struct Repository {}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Repository {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Repository of api_kgon_synchronization_history")
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Repository {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Repository {
|
||||||
|
///
|
||||||
|
pub fn new() -> Repository {
|
||||||
|
Repository {}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn insert(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
new_member: &models::NewSynchronizationHistory,
|
||||||
|
) -> Result<models::SynchronizationHistory, Error> {
|
||||||
|
let inserted = diesel::insert_into(api_kgon_synchronization_history::table)
|
||||||
|
.values(new_member)
|
||||||
|
.get_result::<models::SynchronizationHistory>(conn)?;
|
||||||
|
|
||||||
|
Ok(inserted)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
id: i64,
|
||||||
|
) -> Result<Option<models::SynchronizationHistory>, Error> {
|
||||||
|
match api_kgon_synchronization_history::table
|
||||||
|
.find(id)
|
||||||
|
.first::<models::SynchronizationHistory>(conn)
|
||||||
|
{
|
||||||
|
Ok(m) => Ok(Some(m)),
|
||||||
|
Err(e) => match e {
|
||||||
|
diesel::result::Error::NotFound => Ok(None),
|
||||||
|
_ => Err(e),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select_latest_by_item(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
item: String,
|
||||||
|
) -> Result<Option<models::SynchronizationHistory>, Error> {
|
||||||
|
let query = "
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
item,
|
||||||
|
start_at,
|
||||||
|
complete_at,
|
||||||
|
code,
|
||||||
|
message,
|
||||||
|
data,
|
||||||
|
created_at
|
||||||
|
FROM
|
||||||
|
(
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
item,
|
||||||
|
start_at,
|
||||||
|
complete_at,
|
||||||
|
code,
|
||||||
|
message,
|
||||||
|
data,
|
||||||
|
created_at,
|
||||||
|
row_number() OVER(PARTITION BY item ORDER BY created_at DESC) AS rn
|
||||||
|
FROM
|
||||||
|
api_kgon_synchronization_history
|
||||||
|
) t
|
||||||
|
WHERE t.rn = 1 AND item = $1
|
||||||
|
";
|
||||||
|
|
||||||
|
match sql_query(query)
|
||||||
|
.bind::<diesel::sql_types::Text, _>(item)
|
||||||
|
.get_result::<models::SynchronizationHistory>(conn)
|
||||||
|
{
|
||||||
|
Ok(m) => Ok(Some(m)),
|
||||||
|
Err(e) => match e {
|
||||||
|
diesel::result::Error::NotFound => Ok(None),
|
||||||
|
_ => Err(e),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select_all_count(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
find_all: &models::FindAll,
|
||||||
|
) -> Result<i64, Error> {
|
||||||
|
let mut q = api_kgon_synchronization_history::table.into_boxed();
|
||||||
|
|
||||||
|
if let Some(s) = &find_all.search {
|
||||||
|
if let Some(sp) = &s.item {
|
||||||
|
q = q.filter(api_kgon_synchronization_history::dsl::item.eq(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = s.code {
|
||||||
|
q = q.filter(api_kgon_synchronization_history::dsl::code.eq(sp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
q.count().get_result(conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select_all(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
find_all: &models::FindAll,
|
||||||
|
) -> Result<Vec<models::SynchronizationHistory>, Error> {
|
||||||
|
let mut q = api_kgon_synchronization_history::table.into_boxed();
|
||||||
|
|
||||||
|
if let Some(s) = &find_all.search {
|
||||||
|
if let Some(sp) = &s.item {
|
||||||
|
q = q.filter(api_kgon_synchronization_history::dsl::item.eq(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = s.code {
|
||||||
|
q = q.filter(api_kgon_synchronization_history::dsl::code.eq(sp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(p) = &find_all.pagination {
|
||||||
|
let page = p.page.unwrap_or(1);
|
||||||
|
|
||||||
|
if let Some(page_size) = p.page_size {
|
||||||
|
q = q.offset(((page - 1) * page_size) as i64);
|
||||||
|
q = q.limit(page_size as i64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(orderbys) = &find_all.sorts {
|
||||||
|
for s in orderbys {
|
||||||
|
match s {
|
||||||
|
bcr::pagination::Sort::ASC(property) => match property.as_str() {
|
||||||
|
"item" => {
|
||||||
|
q = q.order_by(api_kgon_synchronization_history::item.asc());
|
||||||
|
}
|
||||||
|
"start_at" => {
|
||||||
|
q = q.order_by(api_kgon_synchronization_history::start_at.asc());
|
||||||
|
}
|
||||||
|
"complete_at" => {
|
||||||
|
q = q.order_by(api_kgon_synchronization_history::complete_at.asc());
|
||||||
|
}
|
||||||
|
"code" => {
|
||||||
|
q = q.order_by(api_kgon_synchronization_history::code.asc());
|
||||||
|
}
|
||||||
|
"created_at" => {
|
||||||
|
q = q.order_by(api_kgon_synchronization_history::created_at.asc());
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
bcr::pagination::Sort::DESC(property) => match property.as_str() {
|
||||||
|
"item" => {
|
||||||
|
q = q.order_by(api_kgon_synchronization_history::item.desc());
|
||||||
|
}
|
||||||
|
"start_at" => {
|
||||||
|
q = q.order_by(api_kgon_synchronization_history::start_at.desc());
|
||||||
|
}
|
||||||
|
"complete_at" => {
|
||||||
|
q = q.order_by(api_kgon_synchronization_history::complete_at.desc());
|
||||||
|
}
|
||||||
|
"code" => {
|
||||||
|
q = q.order_by(api_kgon_synchronization_history::code.desc());
|
||||||
|
}
|
||||||
|
"created_at" => {
|
||||||
|
q = q.order_by(api_kgon_synchronization_history::created_at.desc());
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
q.load::<models::SynchronizationHistory>(conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn delete(&self, conn: &diesel::PgConnection, id: i64) -> Result<u64, Error> {
|
||||||
|
use api_kgon_synchronization_history::dsl;
|
||||||
|
|
||||||
|
diesel::delete(api_kgon_synchronization_history::table.filter(dsl::id.eq(id)))
|
||||||
|
.execute(conn)
|
||||||
|
.map(|c| c as u64)
|
||||||
|
}
|
||||||
|
}
|
24
src/repositories/synchronization_history/schema.rs
Normal file
24
src/repositories/synchronization_history/schema.rs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
|
table! {
|
||||||
|
///
|
||||||
|
api_kgon_synchronization_history(id) {
|
||||||
|
///
|
||||||
|
id -> BigInt,
|
||||||
|
///
|
||||||
|
item -> Text,
|
||||||
|
///
|
||||||
|
start_at -> BigInt,
|
||||||
|
///
|
||||||
|
complete_at -> BigInt,
|
||||||
|
///
|
||||||
|
code -> BigInt,
|
||||||
|
///
|
||||||
|
message -> Nullable<Text>,
|
||||||
|
///
|
||||||
|
data -> Nullable<Text>,
|
||||||
|
///
|
||||||
|
created_at -> BigInt,
|
||||||
|
}
|
||||||
|
}
|
9
src/repositories/vendor/mod.rs
vendored
Normal file
9
src/repositories/vendor/mod.rs
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
|
///
|
||||||
|
pub mod models;
|
||||||
|
///
|
||||||
|
pub mod repository;
|
||||||
|
///
|
||||||
|
pub mod schema;
|
134
src/repositories/vendor/models.rs
vendored
Normal file
134
src/repositories/vendor/models.rs
vendored
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
use super::schema::api_kgon_vendors;
|
||||||
|
use beteran_common_rust as bcr;
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Identifiable, Queryable, PartialEq, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_vendors"]
|
||||||
|
pub struct Vendor {
|
||||||
|
///
|
||||||
|
pub id: i64,
|
||||||
|
///
|
||||||
|
pub company_id: i64,
|
||||||
|
///
|
||||||
|
pub vendor_id: i64,
|
||||||
|
///
|
||||||
|
pub key: String,
|
||||||
|
///
|
||||||
|
pub name: String,
|
||||||
|
///
|
||||||
|
pub category: String,
|
||||||
|
///
|
||||||
|
pub max_bet_casino: f64,
|
||||||
|
///
|
||||||
|
pub max_bet_slot: f64,
|
||||||
|
///
|
||||||
|
pub is_enable: String,
|
||||||
|
///
|
||||||
|
pub bet_count: i64,
|
||||||
|
///
|
||||||
|
pub created_at: i64,
|
||||||
|
///
|
||||||
|
pub updated_at: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Insertable, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_vendors"]
|
||||||
|
pub struct NewVendor {
|
||||||
|
///
|
||||||
|
pub id: i64,
|
||||||
|
///
|
||||||
|
pub company_id: i64,
|
||||||
|
///
|
||||||
|
pub vendor_id: i64,
|
||||||
|
///
|
||||||
|
pub key: String,
|
||||||
|
///
|
||||||
|
pub name: String,
|
||||||
|
///
|
||||||
|
pub category: String,
|
||||||
|
///
|
||||||
|
pub max_bet_casino: f64,
|
||||||
|
///
|
||||||
|
pub max_bet_slot: f64,
|
||||||
|
///
|
||||||
|
pub is_enable: String,
|
||||||
|
///
|
||||||
|
pub bet_count: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(AsChangeset, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_vendors"]
|
||||||
|
pub struct ModifyVendor {
|
||||||
|
///
|
||||||
|
pub company_id: i64,
|
||||||
|
///
|
||||||
|
pub vendor_id: i64,
|
||||||
|
///
|
||||||
|
pub key: String,
|
||||||
|
///
|
||||||
|
pub name: String,
|
||||||
|
///
|
||||||
|
pub category: String,
|
||||||
|
///
|
||||||
|
pub max_bet_casino: f64,
|
||||||
|
///
|
||||||
|
pub max_bet_slot: f64,
|
||||||
|
///
|
||||||
|
pub is_enable: String,
|
||||||
|
///
|
||||||
|
pub bet_count: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Insertable, AsChangeset, Debug, Clone)]
|
||||||
|
#[table_name = "api_kgon_vendors"]
|
||||||
|
pub struct UpsertVendor {
|
||||||
|
///
|
||||||
|
pub id: i64,
|
||||||
|
///
|
||||||
|
pub company_id: i64,
|
||||||
|
///
|
||||||
|
pub vendor_id: i64,
|
||||||
|
///
|
||||||
|
pub key: String,
|
||||||
|
///
|
||||||
|
pub name: String,
|
||||||
|
///
|
||||||
|
pub category: String,
|
||||||
|
///
|
||||||
|
pub max_bet_casino: f64,
|
||||||
|
///
|
||||||
|
pub max_bet_slot: f64,
|
||||||
|
///
|
||||||
|
pub is_enable: String,
|
||||||
|
///
|
||||||
|
pub bet_count: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct FindAllSearch {
|
||||||
|
///
|
||||||
|
pub company_id: Option<i64>,
|
||||||
|
///
|
||||||
|
pub vendor_id: Option<i64>,
|
||||||
|
///
|
||||||
|
pub key_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub name_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub category_like: Option<String>,
|
||||||
|
///
|
||||||
|
pub is_enable: Option<String>,
|
||||||
|
}
|
||||||
|
///
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct FindAll {
|
||||||
|
pub search: Option<FindAllSearch>,
|
||||||
|
///
|
||||||
|
pub pagination: Option<bcr::pagination::Pagination>,
|
||||||
|
///
|
||||||
|
pub sorts: Option<Vec<bcr::pagination::Sort>>,
|
||||||
|
}
|
263
src/repositories/vendor/repository.rs
vendored
Normal file
263
src/repositories/vendor/repository.rs
vendored
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
use super::{models, schema::api_kgon_vendors};
|
||||||
|
use beteran_common_rust as bcr;
|
||||||
|
use diesel::prelude::*;
|
||||||
|
use diesel::result::Error;
|
||||||
|
|
||||||
|
///
|
||||||
|
pub struct Repository {}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Repository {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Repository of api_kgon_vendors").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Repository {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Repository {
|
||||||
|
///
|
||||||
|
pub fn new() -> Repository {
|
||||||
|
Repository {}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn insert(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
new_member: &models::NewVendor,
|
||||||
|
) -> Result<models::Vendor, Error> {
|
||||||
|
let inserted = diesel::insert_into(api_kgon_vendors::table)
|
||||||
|
.values(new_member)
|
||||||
|
.get_result::<models::Vendor>(conn)?;
|
||||||
|
|
||||||
|
Ok(inserted)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn upserts(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
upsert_vendors: Vec<models::UpsertVendor>,
|
||||||
|
) -> Result<usize, Error> {
|
||||||
|
use api_kgon_vendors::dsl;
|
||||||
|
use diesel::pg::upsert::excluded;
|
||||||
|
|
||||||
|
let affected = diesel::insert_into(api_kgon_vendors::table)
|
||||||
|
.values(upsert_vendors)
|
||||||
|
.on_conflict(dsl::id)
|
||||||
|
.do_update()
|
||||||
|
.set((
|
||||||
|
dsl::company_id.eq(excluded(dsl::company_id)),
|
||||||
|
dsl::vendor_id.eq(excluded(dsl::vendor_id)),
|
||||||
|
dsl::key.eq(excluded(dsl::key)),
|
||||||
|
dsl::name.eq(excluded(dsl::name)),
|
||||||
|
dsl::category.eq(excluded(dsl::category)),
|
||||||
|
dsl::max_bet_casino.eq(excluded(dsl::max_bet_casino)),
|
||||||
|
dsl::max_bet_slot.eq(excluded(dsl::max_bet_slot)),
|
||||||
|
dsl::is_enable.eq(excluded(dsl::is_enable)),
|
||||||
|
dsl::bet_count.eq(excluded(dsl::bet_count)),
|
||||||
|
))
|
||||||
|
.execute(conn)?;
|
||||||
|
|
||||||
|
Ok(affected)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
id: i64,
|
||||||
|
) -> Result<Option<models::Vendor>, Error> {
|
||||||
|
match api_kgon_vendors::table
|
||||||
|
.find(id)
|
||||||
|
.first::<models::Vendor>(conn)
|
||||||
|
{
|
||||||
|
Ok(m) => Ok(Some(m)),
|
||||||
|
Err(e) => match e {
|
||||||
|
diesel::result::Error::NotFound => Ok(None),
|
||||||
|
_ => Err(e),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select_all_count(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
find_all: &models::FindAll,
|
||||||
|
) -> Result<i64, Error> {
|
||||||
|
let mut q = api_kgon_vendors::table.into_boxed();
|
||||||
|
|
||||||
|
if let Some(s) = &find_all.search {
|
||||||
|
if let Some(sp) = s.company_id {
|
||||||
|
q = q.filter(api_kgon_vendors::dsl::company_id.eq(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = s.vendor_id {
|
||||||
|
q = q.filter(api_kgon_vendors::dsl::vendor_id.eq(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.key_like {
|
||||||
|
q = q.filter(api_kgon_vendors::dsl::key.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.name_like {
|
||||||
|
q = q.filter(api_kgon_vendors::dsl::name.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.category_like {
|
||||||
|
q = q.filter(api_kgon_vendors::dsl::category.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.is_enable {
|
||||||
|
q = q.filter(api_kgon_vendors::dsl::is_enable.eq(sp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
q.count().get_result(conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn select_all(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
find_all: &models::FindAll,
|
||||||
|
) -> Result<Vec<models::Vendor>, Error> {
|
||||||
|
let mut q = api_kgon_vendors::table.into_boxed();
|
||||||
|
|
||||||
|
if let Some(s) = &find_all.search {
|
||||||
|
if let Some(sp) = s.company_id {
|
||||||
|
q = q.filter(api_kgon_vendors::dsl::company_id.eq(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = s.vendor_id {
|
||||||
|
q = q.filter(api_kgon_vendors::dsl::vendor_id.eq(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.key_like {
|
||||||
|
q = q.filter(api_kgon_vendors::dsl::key.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.name_like {
|
||||||
|
q = q.filter(api_kgon_vendors::dsl::name.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.category_like {
|
||||||
|
q = q.filter(api_kgon_vendors::dsl::category.like(sp));
|
||||||
|
}
|
||||||
|
if let Some(sp) = &s.is_enable {
|
||||||
|
q = q.filter(api_kgon_vendors::dsl::is_enable.eq(sp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(p) = &find_all.pagination {
|
||||||
|
let page = p.page.unwrap_or(1);
|
||||||
|
|
||||||
|
if let Some(page_size) = p.page_size {
|
||||||
|
q = q.offset(((page - 1) * page_size) as i64);
|
||||||
|
q = q.limit(page_size as i64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(orderbys) = &find_all.sorts {
|
||||||
|
for s in orderbys {
|
||||||
|
match s {
|
||||||
|
bcr::pagination::Sort::ASC(property) => match property.as_str() {
|
||||||
|
"company_id" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::company_id.asc());
|
||||||
|
}
|
||||||
|
"vendor_id" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::vendor_id.asc());
|
||||||
|
}
|
||||||
|
"key" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::key.asc());
|
||||||
|
}
|
||||||
|
"name" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::name.asc());
|
||||||
|
}
|
||||||
|
"category" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::category.asc());
|
||||||
|
}
|
||||||
|
"max_bet_casino" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::max_bet_casino.asc());
|
||||||
|
}
|
||||||
|
"max_bet_slot" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::max_bet_slot.asc());
|
||||||
|
}
|
||||||
|
"is_enable" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::is_enable.asc());
|
||||||
|
}
|
||||||
|
"bet_count" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::bet_count.asc());
|
||||||
|
}
|
||||||
|
"created_at" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::created_at.asc());
|
||||||
|
}
|
||||||
|
"updated_at" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::updated_at.asc());
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
bcr::pagination::Sort::DESC(property) => match property.as_str() {
|
||||||
|
"company_id" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::company_id.desc());
|
||||||
|
}
|
||||||
|
"vendor_id" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::vendor_id.desc());
|
||||||
|
}
|
||||||
|
"key" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::key.desc());
|
||||||
|
}
|
||||||
|
"name" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::name.desc());
|
||||||
|
}
|
||||||
|
"category" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::category.desc());
|
||||||
|
}
|
||||||
|
"max_bet_casino" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::max_bet_casino.desc());
|
||||||
|
}
|
||||||
|
"max_bet_slot" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::max_bet_slot.desc());
|
||||||
|
}
|
||||||
|
"is_enable" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::is_enable.desc());
|
||||||
|
}
|
||||||
|
"bet_count" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::bet_count.desc());
|
||||||
|
}
|
||||||
|
"created_at" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::created_at.desc());
|
||||||
|
}
|
||||||
|
"updated_at" => {
|
||||||
|
q = q.order_by(api_kgon_vendors::updated_at.desc());
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
q.load::<models::Vendor>(conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn update(
|
||||||
|
&self,
|
||||||
|
conn: &diesel::PgConnection,
|
||||||
|
id: i64,
|
||||||
|
modify: &models::ModifyVendor,
|
||||||
|
) -> Result<u64, Error> {
|
||||||
|
use api_kgon_vendors::dsl;
|
||||||
|
|
||||||
|
diesel::update(dsl::api_kgon_vendors.filter(dsl::id.eq(id)))
|
||||||
|
.set(modify)
|
||||||
|
.execute(conn)
|
||||||
|
.map(|c| c as u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
pub fn delete(&self, conn: &diesel::PgConnection, id: i64) -> Result<u64, Error> {
|
||||||
|
use api_kgon_vendors::dsl;
|
||||||
|
|
||||||
|
diesel::delete(api_kgon_vendors::table.filter(dsl::id.eq(id)))
|
||||||
|
.execute(conn)
|
||||||
|
.map(|c| c as u64)
|
||||||
|
}
|
||||||
|
}
|
32
src/repositories/vendor/schema.rs
vendored
Normal file
32
src/repositories/vendor/schema.rs
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
|
table! {
|
||||||
|
///
|
||||||
|
api_kgon_vendors(id) {
|
||||||
|
///
|
||||||
|
id -> BigInt,
|
||||||
|
///
|
||||||
|
company_id -> BigInt,
|
||||||
|
///
|
||||||
|
vendor_id -> BigInt,
|
||||||
|
///
|
||||||
|
key -> Text,
|
||||||
|
///
|
||||||
|
name -> Text,
|
||||||
|
///
|
||||||
|
category -> Text,
|
||||||
|
///
|
||||||
|
max_bet_casino -> Double,
|
||||||
|
///
|
||||||
|
max_bet_slot -> Double,
|
||||||
|
///
|
||||||
|
is_enable -> Text,
|
||||||
|
///
|
||||||
|
bet_count -> BigInt,
|
||||||
|
///
|
||||||
|
created_at -> BigInt,
|
||||||
|
///
|
||||||
|
updated_at -> BigInt,
|
||||||
|
}
|
||||||
|
}
|
1
src/schedulers/balance/mod.rs
Normal file
1
src/schedulers/balance/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod scheduler;
|
78
src/schedulers/balance/scheduler.rs
Normal file
78
src/schedulers/balance/scheduler.rs
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
use crate::synchronizations;
|
||||||
|
use once_cell::sync::OnceCell;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tokio_cron_scheduler::{Job, JobScheduler};
|
||||||
|
|
||||||
|
static G_INSTANCE: OnceCell<Arc<Scheduler>> = OnceCell::new();
|
||||||
|
|
||||||
|
///
|
||||||
|
pub struct Scheduler {
|
||||||
|
sched: JobScheduler,
|
||||||
|
member_account_synchronizer: synchronizations::member_account::synchronizer::Synchronizer,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Scheduler {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Scheduler of api.kgon.identity").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Scheduler {
|
||||||
|
///
|
||||||
|
pub fn get_instance(
|
||||||
|
sched: JobScheduler,
|
||||||
|
member_account_synchronizer: synchronizations::member_account::synchronizer::Synchronizer,
|
||||||
|
) -> Result<&'static Arc<Scheduler>, Box<dyn std::error::Error>> {
|
||||||
|
let instance = G_INSTANCE
|
||||||
|
.get_or_try_init(|| -> Result<Arc<Scheduler>, Box<dyn std::error::Error>> {
|
||||||
|
let s = Scheduler {
|
||||||
|
sched,
|
||||||
|
member_account_synchronizer,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Arc::new(s))
|
||||||
|
})
|
||||||
|
.expect("");
|
||||||
|
|
||||||
|
Ok(instance)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn queue(&'static self) -> Result<(), std::boxed::Box<dyn std::error::Error>> {
|
||||||
|
self.balance_for_user().await?;
|
||||||
|
self.balance_for_partner().await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn balance_for_user(&'static self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let j_synchronization = Job::new_async("0 0/3 * * * ?", move |_uuid, _l| {
|
||||||
|
Box::pin(async move {
|
||||||
|
self
|
||||||
|
.member_account_synchronizer
|
||||||
|
.balance_for_user_all()
|
||||||
|
.await
|
||||||
|
.expect("member_account_synchronizer.balance_for_user");
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
self.sched.add(j_synchronization).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn balance_for_partner(&'static self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let j_synchronization = Job::new_async("0 0/3 * * * ?", move |_uuid, _l| {
|
||||||
|
Box::pin(async move {
|
||||||
|
self
|
||||||
|
.member_account_synchronizer
|
||||||
|
.balance_for_partner()
|
||||||
|
.await
|
||||||
|
.expect("member_account_synchronizer.balance_for_partner");
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
self.sched.add(j_synchronization).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
1
src/schedulers/betting_history/mod.rs
Normal file
1
src/schedulers/betting_history/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod scheduler;
|
61
src/schedulers/betting_history/scheduler.rs
Normal file
61
src/schedulers/betting_history/scheduler.rs
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
use crate::synchronizations;
|
||||||
|
use once_cell::sync::OnceCell;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tokio_cron_scheduler::{Job, JobScheduler};
|
||||||
|
|
||||||
|
static G_INSTANCE: OnceCell<Arc<Scheduler>> = OnceCell::new();
|
||||||
|
|
||||||
|
///
|
||||||
|
pub struct Scheduler {
|
||||||
|
sched: JobScheduler,
|
||||||
|
betting_history_synchronizer: synchronizations::betting_history::synchronizer::Synchronizer,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Scheduler {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Scheduler of api.kgon.identity").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Scheduler {
|
||||||
|
///
|
||||||
|
pub fn get_instance(
|
||||||
|
sched: JobScheduler,
|
||||||
|
betting_history_synchronizer: synchronizations::betting_history::synchronizer::Synchronizer,
|
||||||
|
) -> Result<&'static Arc<Scheduler>, Box<dyn std::error::Error>> {
|
||||||
|
let instance = G_INSTANCE
|
||||||
|
.get_or_try_init(|| -> Result<Arc<Scheduler>, Box<dyn std::error::Error>> {
|
||||||
|
let s = Scheduler {
|
||||||
|
sched,
|
||||||
|
betting_history_synchronizer,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Arc::new(s))
|
||||||
|
})
|
||||||
|
.expect("");
|
||||||
|
|
||||||
|
Ok(instance)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn queue(&'static self) -> Result<(), std::boxed::Box<dyn std::error::Error>> {
|
||||||
|
self.betting_history().await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn betting_history(&'static self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let j_synchronization = Job::new_async("0 0/3 * * * ?", move |_uuid, _l| {
|
||||||
|
Box::pin(async move {
|
||||||
|
self
|
||||||
|
.betting_history_synchronizer
|
||||||
|
.betting_history()
|
||||||
|
.await
|
||||||
|
.expect("betting_history_synchronizer.betting_history");
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
self.sched.add(j_synchronization).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
1
src/schedulers/game/mod.rs
Normal file
1
src/schedulers/game/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod scheduler;
|
69
src/schedulers/game/scheduler.rs
Normal file
69
src/schedulers/game/scheduler.rs
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
use crate::synchronizations;
|
||||||
|
use once_cell::sync::OnceCell;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tokio_cron_scheduler::{Job, JobScheduler};
|
||||||
|
|
||||||
|
static G_INSTANCE: OnceCell<Arc<Scheduler>> = OnceCell::new();
|
||||||
|
|
||||||
|
///
|
||||||
|
pub struct Scheduler {
|
||||||
|
sched: JobScheduler,
|
||||||
|
vendor_synchronizer: synchronizations::vendor::synchronizer::Synchronizer,
|
||||||
|
game_synchronizer: synchronizations::game::synchronizer::Synchronizer,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Scheduler {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Scheduler of api.kgon.identity").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Scheduler {
|
||||||
|
pub fn get_instance(
|
||||||
|
sched: JobScheduler,
|
||||||
|
vendor_synchronizer: synchronizations::vendor::synchronizer::Synchronizer,
|
||||||
|
game_synchronizer: synchronizations::game::synchronizer::Synchronizer,
|
||||||
|
) -> Result<&'static Arc<Scheduler>, Box<dyn std::error::Error>> {
|
||||||
|
let instance = G_INSTANCE
|
||||||
|
.get_or_try_init(|| -> Result<Arc<Scheduler>, Box<dyn std::error::Error>> {
|
||||||
|
let s = Scheduler {
|
||||||
|
sched,
|
||||||
|
vendor_synchronizer,
|
||||||
|
game_synchronizer,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Arc::new(s))
|
||||||
|
})
|
||||||
|
.expect("");
|
||||||
|
|
||||||
|
Ok(instance)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn queue(&'static self) -> Result<(), std::boxed::Box<dyn std::error::Error>> {
|
||||||
|
self.vendors_and_games().await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn vendors_and_games(&'static self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let j_synchronization = Job::new_async("0 0/3 * * * ?", move |_uuid, _l| {
|
||||||
|
Box::pin(async move {
|
||||||
|
self
|
||||||
|
.vendor_synchronizer
|
||||||
|
.vendors()
|
||||||
|
.await
|
||||||
|
.expect("vendor_synchronizer.vendors");
|
||||||
|
|
||||||
|
self
|
||||||
|
.game_synchronizer
|
||||||
|
.games()
|
||||||
|
.await
|
||||||
|
.expect("game_synchronizer.games");
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
self.sched.add(j_synchronization).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
1
src/schedulers/member/mod.rs
Normal file
1
src/schedulers/member/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod scheduler;
|
61
src/schedulers/member/scheduler.rs
Normal file
61
src/schedulers/member/scheduler.rs
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
use crate::synchronizations;
|
||||||
|
use once_cell::sync::OnceCell;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tokio_cron_scheduler::{Job, JobScheduler};
|
||||||
|
|
||||||
|
static G_INSTANCE: OnceCell<Arc<Scheduler>> = OnceCell::new();
|
||||||
|
|
||||||
|
///
|
||||||
|
pub struct Scheduler {
|
||||||
|
sched: JobScheduler,
|
||||||
|
member_synchronizer: synchronizations::member::synchronizer::Synchronizer,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Scheduler {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.debug_struct("Scheduler of api.kgon.identity").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Scheduler {
|
||||||
|
///
|
||||||
|
pub fn get_instance(
|
||||||
|
sched: JobScheduler,
|
||||||
|
member_synchronizer: synchronizations::member::synchronizer::Synchronizer,
|
||||||
|
) -> Result<&'static Arc<Scheduler>, Box<dyn std::error::Error>> {
|
||||||
|
let instance = G_INSTANCE
|
||||||
|
.get_or_try_init(|| -> Result<Arc<Scheduler>, Box<dyn std::error::Error>> {
|
||||||
|
let s = Scheduler {
|
||||||
|
sched,
|
||||||
|
member_synchronizer,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Arc::new(s))
|
||||||
|
})
|
||||||
|
.expect("");
|
||||||
|
|
||||||
|
Ok(instance)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn queue(&'static self) -> Result<(), std::boxed::Box<dyn std::error::Error>> {
|
||||||
|
self.members().await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn members(&'static self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let j_synchronization = Job::new_async("0 0/3 * * * ?", move |_uuid, _l| {
|
||||||
|
Box::pin(async move {
|
||||||
|
self
|
||||||
|
.member_synchronizer
|
||||||
|
.members()
|
||||||
|
.await
|
||||||
|
.expect("member_synchronizer.members");
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
self.sched.add(j_synchronization).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
4
src/schedulers/mod.rs
Normal file
4
src/schedulers/mod.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
pub mod balance;
|
||||||
|
pub mod betting_history;
|
||||||
|
pub mod game;
|
||||||
|
pub mod member;
|
2
src/services/betting/mod.rs
Normal file
2
src/services/betting/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod models;
|
||||||
|
pub mod service;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user