Files
console-dev/app/components/WithdrawDialog.vue
T

971 lines
41 KiB
Vue

<script>
// 提现表单共用余额与推荐奖励两个场景,规则、手续费和可提现余额均按场景校验。
import "~/assets/styles/WithdrawDialog.ks0wdKEK.css";
import { toDisplayString } from "vue";
import { useId } from "vue";
import { onBeforeUnmount } from "vue";
import { mergeModels } from "vue";
import { useModel } from "vue";
import { watch } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
import { withCtx } from "vue";
import { createCommentVNode } from "vue";
import { computed } from "vue";
import { reactive } from "vue";
import { createElementBlock } from "vue";
import { Fragment } from "vue";
import { createElementVNode } from "vue";
import { createTextVNode } from "vue";
import { unref } from "vue";
import { defineComponent } from "vue";
import { createVNode } from "vue";
import { openBlock } from "vue";
import { useApi } from "~/lib/auth.js";
import { useAuth } from "~/lib/auth.js";
import dialog from "primevue/dialog";
import button from "primevue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import message from "primevue/message";
import inputtext from "primevue/inputtext";
import select from "primevue/select";
import inputnumber from "primevue/inputnumber";
import textarea from "primevue/textarea";
import skeleton from "primevue/skeleton";
function C(e) {
return (
Array.isArray(e?.method) &&
e.method.some(
(e) =>
!!e &&
typeof e == `object` &&
Number.isInteger(e.id) &&
Number(e.id) >= 0 &&
typeof e.name == `string`,
)
);
}
function w(e, t = ``) {
return t === `recommend`
? C(e)
: e?.status === 1 || e?.status === `1` || e?.status === !0;
}
// 金额最多两位小数,先转为安全整数“分”,避免用浮点金额直接比较限额。
function T(e) {
if (typeof e != `string` && typeof e != `number`) return null;
let t = String(e).trim();
if (!/^\d+(?:\.\d{1,2})?$/.test(t)) return null;
let [n = `0`, r = ``] = t.split(`.`),
i = Number(n) * 100 + Number(r.padEnd(2, `0`));
return Number.isSafeInteger(i) ? i : null;
}
// 百分比允许六位小数,用 BigInt 计算手续费并向下取整到分。
function E(e, t) {
let n = String(t ?? ``).trim();
if (!/^\d+(?:\.\d{1,6})?$/.test(n) || Number(n) > 100) return null;
let [r = `0`, i = ``] = n.split(`.`),
a = 10n ** BigInt(i.length),
o = BigInt(r) * a + BigInt(i || `0`);
return Number((BigInt(e) * o) / (100n * a));
}
var ce = {
key: 0,
class: `sk`,
},
le = {
key: 1,
class: `form`,
},
ue = {
key: 2,
class: `form`,
},
de = {
class: `notice`,
},
fe = {
key: 0,
},
pe = {
key: 1,
},
me = {
key: 2,
},
he = {
key: 3,
},
ge = {
class: `field`,
},
_e = [`id`],
ve = {
class: `field`,
},
D = [`for`],
O = {
key: 0,
class: `hint`,
},
k = {
key: 1,
class: `hint`,
},
A = {
class: `field`,
},
j = [`for`],
M = {
class: `field`,
},
N = [`for`],
P = [`for`],
F = {
class: `field`,
},
ye = [`for`],
be = {
class: `calc`,
},
xe = {
class: `calc-row`,
},
Se = {
class: `calc-row`,
},
Ce = {
class: `calc-row total`,
},
I = Object.assign(
_plugin_vue_export_helper_t(
defineComponent({
__name: `WithdrawDialog`,
props: mergeModels(
{
source: {
default: ``,
},
available: {
default: null,
},
title: {
default: ``,
},
},
{
modelValue: {
type: Boolean,
default: !1,
},
modelModifiers: {},
},
),
emits: mergeModels([`success`], [`update:modelValue`]),
setup(r, { emit: _ }) {
let x = useModel(r, `modelValue`),
C = _,
I = r,
L = useApi(),
R = useAuth(),
z = useId(),
we = {
day: `天`,
week: `周`,
month: `月`,
},
B = ref(null),
V = ref(!1),
H = ref(!1),
U = ref(``),
W = 0,
G = !0,
K = reactive({
method_id: null,
amount: null,
name: ``,
account: ``,
card_number: ``,
notes: ``,
}),
q = computed(() => {
let e = B.value,
t = T(K.amount);
return !e || t === null || t <= 0
? 0
: e.withdraw_fee_type === `fixed`
? (T(e.withdraw_fee || 0) ?? 0)
: Math.max(
E(t, e.percent || 0) ?? 0,
T(e.percent_min || 0) ?? 0,
);
}),
Te = computed(() => q.value / 100),
Ee = computed(
() => Math.max(0, (T(K.amount) ?? 0) - q.value) / 100,
),
J = computed(() =>
B.value?.method.find((e) => e.id === K.method_id),
),
Y = computed(
() => !!J.value && J.value.id !== 0 && !J.value.no_account,
),
X = computed(() => !!J.value && /银行卡/.test(J.value.name)),
Z = computed(() =>
Number(B.value?.max) > 0 ? Number(B.value?.max) : void 0,
),
Q = (e) => w(e, I.source ? `recommend` : ``);
function De() {
Object.assign(K, {
method_id: null,
amount: null,
name: ``,
account: ``,
card_number: ``,
notes: ``,
});
}
// 加载可用渠道及规则;奖励场景额外读取奖励专属限额和手续费,代次隔离旧响应。
async function $() {
if (!G || !x.value || V.value) return;
let e = ++W,
t = I.source;
((V.value = !0), (B.value = null), (U.value = ``));
try {
let n = await L.get(
`/withdraw/rule/credit`,
t
? {
scene: `recommend`,
}
: void 0,
);
if (!G || e !== W) return;
if (!n || !Array.isArray(n.method))
throw Error(`提现设置不完整,请重新加载`);
let r = {
...n,
method: n.method.filter(
(e) =>
!!e &&
Number.isInteger(e.id) &&
e.id >= 0 &&
typeof e.name == `string`,
),
};
if (t && r.method.length) {
let t = await L.get(`/recommend/config`);
if (!G || e !== W) return;
if (
T(t?.config?.withdraw_min) === null ||
E(100, t?.config?.withdraw_handling_fee) === null
)
throw Error(`奖励提现规则不完整,请重新加载`);
r = {
...r,
min: String(t.config.withdraw_min),
max: ``,
cycle: ``,
cycle_limit: 0,
withdraw_fee_type: `percent`,
withdraw_fee: ``,
percent: String(t.config.withdraw_handling_fee),
percent_min: `0`,
};
}
if (Q(r)) {
let e = T(r.min || 0) !== null && T(r.max || 0) !== null,
t =
r.withdraw_fee_type === `fixed`
? T(r.withdraw_fee || 0) !== null
: r.withdraw_fee_type === `percent` &&
E(100, r.percent || 0) !== null &&
T(r.percent_min || 0) !== null;
if (!e || !t) throw Error(`提现设置不完整,请重新加载`);
}
((B.value = r),
(K.method_id = r.method[0]?.id ?? null),
(K.amount = Number(r.min || 0) || null),
!r.method.length &&
Q(r) &&
(U.value = `暂无可用的提现方式,请联系客服`));
} catch (t) {
G &&
e === W &&
(U.value = t instanceof Error ? t.message : `加载提现设置失败`);
} finally {
G && e === W && (V.value = !1);
}
}
// 提交前重新校验渠道、金额区间、可用余额和收款账号,只发送当前渠道需要的字段。
async function Oe() {
if (!G || !x.value || H.value || V.value || !Q(B.value)) return;
let e = B.value;
if (!e) return;
if (((U.value = ``), !J.value)) {
U.value = `请选择有效的提现方式`;
return;
}
let t = T(K.amount);
if (t === null || t <= 0) {
U.value = `请输入大于 0 且最多两位小数的提现金额`;
return;
}
let n = T(e.min || 0),
r = T(e.max || 0);
if (n === null || r === null) {
U.value = `提现金额限制异常,请重新加载提现设置`;
return;
}
if (t < n) {
U.value = `提现金额不能低于 ¥${e.min}`;
return;
}
if (r > 0 && t > r) {
U.value = `提现金额不能高于 ¥${e.max}`;
return;
}
let i = T(I.source ? I.available : R.overview?.credit);
if (i === null) {
U.value = `可提现金额暂不可用,请刷新页面后重试`;
return;
}
if (t > i) {
U.value = I.source
? `提现金额不能超过可提现奖励`
: `提现金额不能超过可用余额`;
return;
}
if (
Y.value &&
!(X.value ? K.card_number.trim() : K.account.trim())
) {
U.value = X.value ? `请填写银行卡号` : `请填写收款账号`;
return;
}
if (q.value > t) {
U.value = `提现金额不能低于手续费`;
return;
}
let a = W,
o = I.source;
H.value = !0;
try {
let n = {
method_id: K.method_id,
amount: t / 100,
name: Y.value ? K.name.trim() : ``,
account: Y.value && !X.value ? K.account.trim() : ``,
card_number: Y.value && X.value ? K.card_number.trim() : ``,
notes: K.notes.trim(),
};
(o && ((n.source = o), (n.fee = Number(e.percent))),
await L.post(o ? `/recommend/withdraw` : `/withdraw`, n),
G &&
o === I.source &&
(a === W && (x.value = !1), C(`success`)));
} catch (e) {
G &&
a === W &&
(U.value = e instanceof Error ? e.message : `提交失败`);
} finally {
G && (H.value = !1);
}
}
return (
watch(
[x, () => I.source],
([e]) => {
(W++,
(B.value = null),
(V.value = !1),
(U.value = ``),
De(),
e && $());
},
{
immediate: !0,
flush: `sync`,
},
),
onBeforeUnmount(() => {
((G = !1), W++);
}),
(t, n) => {
let r = skeleton,
i = message,
a = button,
s = select,
u = inputnumber,
d = inputtext,
_ = textarea,
b = dialog;
return (
openBlock(),
createBlock(
b,
{
visible: x.value,
"onUpdate:visible": (n[7] ||= (e) => (x.value = e)),
header: I.title || `提现`,
modal: ``,
draggable: !1,
closable: !unref(H),
"close-on-escape": !unref(H),
style: {
width: `min(720px, calc(100vw - 28px))`,
},
},
{
footer: withCtx(() => [
createVNode(
a,
{
label: `取消`,
icon: `pi pi-times`,
severity: `secondary`,
outlined: ``,
disabled: unref(H),
onClick: (n[6] ||= (e) => (x.value = !1)),
},
null,
8,
[`disabled`],
),
createVNode(
a,
{
label: `确认`,
icon: `pi pi-check`,
loading: unref(H),
disabled:
unref(V) ||
unref(H) ||
!Q(unref(B)) ||
!unref(B)?.method.length,
onClick: Oe,
},
null,
8,
[`loading`, `disabled`],
),
]),
default: withCtx(() => [
unref(V)
? (openBlock(),
createElementBlock(`div`, ce, [
createVNode(r, {
height: `180px`,
}),
]))
: !unref(B) && unref(U)
? (openBlock(),
createElementBlock(`div`, le, [
createVNode(
i,
{
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(unref(U)),
1,
),
]),
_: 1,
},
),
createVNode(a, {
label: `重新加载提现设置`,
icon: `pi pi-refresh`,
severity: `secondary`,
outlined: ``,
onClick: $,
}),
]))
: unref(B)
? (openBlock(),
createElementBlock(`div`, ue, [
Q(unref(B))
? createCommentVNode(``, !0)
: (openBlock(),
createBlock(
i,
{
key: 0,
severity: `warn`,
closable: !1,
},
{
default: withCtx(() => [
...(n[8] ||= [
createTextVNode(
` 提现功能当前已关闭,如有需要请联系客服。 `,
-1,
),
]),
]),
_: 1,
},
)),
createElementVNode(`section`, de, [
(n[10] ||= createElementVNode(
`div`,
{
class: `notice-title`,
},
[
createElementVNode(`i`, {
class: `pi pi-info-circle`,
}),
createTextVNode(` 提现说明`),
],
-1,
)),
createElementVNode(`ul`, null, [
I.source
? (openBlock(),
createElementBlock(
`li`,
fe,
`提现申请需审核;审核通过后,提现到余额将计入账户余额,其他方式由管理员安排汇款。`,
))
: unref(B).process === `artificial`
? (openBlock(),
createElementBlock(
`li`,
pe,
` 提现申请经人工审核通过后按所选方式处理,处理进度可在提现记录查看。 `,
))
: (openBlock(),
createElementBlock(
`li`,
me,
`提现申请按所选方式处理,处理进度可在提现记录查看。`,
)),
createElementVNode(
`li`,
null,
` 手续费:` +
toDisplayString(
unref(B).withdraw_fee_type === `fixed`
? `每笔 ¥${unref(B).withdraw_fee}`
: `按 ${unref(B).percent}% 收取,最低 ¥${unref(B).percent_min}`,
) +
`。 `,
1,
),
createElementVNode(`li`, null, [
createTextVNode(
` 起提 ¥` +
toDisplayString(unref(B).min),
1,
),
unref(Z)
? (openBlock(),
createElementBlock(
Fragment,
{
key: 0,
},
[
createTextVNode(
`,单笔上限 ¥` +
toDisplayString(unref(B).max),
1,
),
],
64,
))
: createCommentVNode(``, !0),
Number(unref(B).cycle_limit) > 0
? (openBlock(),
createElementBlock(
Fragment,
{
key: 1,
},
[
createTextVNode(
` ,每` +
toDisplayString(
we[unref(B).cycle] ||
unref(B).cycle,
) +
`最多 ` +
toDisplayString(
unref(B).cycle_limit,
) +
` 次`,
1,
),
],
64,
))
: createCommentVNode(``, !0),
(n[9] ||= createTextVNode(`。 `, -1)),
]),
I.source
? createCommentVNode(``, !0)
: (openBlock(),
createElementBlock(
`li`,
he,
`已开票的充值需先申请发票作废或冲红,方可提现。`,
)),
]),
]),
createElementVNode(`div`, ge, [
createElementVNode(
`span`,
{
id: `${unref(z)}-method-label`,
class: `field-label`,
},
`提现方式`,
8,
_e,
),
createVNode(
s,
{
"input-id": `${unref(z)}-method`,
"aria-labelledby": `${unref(z)}-method-label`,
modelValue: unref(K).method_id,
"onUpdate:modelValue": (n[0] ||= (e) =>
(unref(K).method_id = e)),
options: unref(B).method,
optionLabel: `name`,
optionValue: `id`,
placeholder: `请选择提现方式`,
disabled: unref(H) || !Q(unref(B)),
fluid: ``,
},
null,
8,
[
`input-id`,
`aria-labelledby`,
`modelValue`,
`options`,
`disabled`,
],
),
]),
createElementVNode(`div`, ve, [
createElementVNode(
`label`,
{
for: `${unref(z)}-amount`,
},
`提现金额`,
8,
D,
),
createVNode(
u,
{
"input-id": `${unref(z)}-amount`,
modelValue: unref(K).amount,
"onUpdate:modelValue": (n[1] ||= (e) =>
(unref(K).amount = e)),
mode: `currency`,
currency: `CNY`,
locale: `zh-CN`,
min: Number(unref(B).min),
max: unref(Z),
disabled: unref(H) || !Q(unref(B)),
minFractionDigits: 2,
maxFractionDigits: 2,
fluid: ``,
},
null,
8,
[
`input-id`,
`modelValue`,
`min`,
`max`,
`disabled`,
],
),
I.source
? (openBlock(),
createElementBlock(
`span`,
O,
`可提现奖励 ¥` +
toDisplayString(
Number(I.available ?? 0).toFixed(2),
),
1,
))
: (openBlock(),
createElementBlock(
`span`,
k,
`可用余额 ¥` +
toDisplayString(
unref(R).overview?.credit ?? `0.00`,
),
1,
)),
]),
unref(Y)
? (openBlock(),
createElementBlock(
Fragment,
{
key: 1,
},
[
createElementVNode(`div`, A, [
createElementVNode(
`label`,
{
for: `${unref(z)}-name`,
},
`收款人姓名`,
8,
j,
),
createVNode(
d,
{
id: `${unref(z)}-name`,
modelValue: unref(K).name,
"onUpdate:modelValue": (n[2] ||= (
e,
) => (unref(K).name = e)),
placeholder: `与账号实名一致`,
autocomplete: `name`,
disabled:
unref(H) || !Q(unref(B)),
maxlength: 20,
fluid: ``,
},
null,
8,
[`id`, `modelValue`, `disabled`],
),
]),
createElementVNode(`div`, M, [
unref(X)
? (openBlock(),
createElementBlock(
Fragment,
{
key: 0,
},
[
createElementVNode(
`label`,
{
for: `${unref(z)}-card-number`,
},
`银行卡号`,
8,
N,
),
createVNode(
d,
{
id: `${unref(z)}-card-number`,
modelValue:
unref(K).card_number,
"onUpdate:modelValue":
(n[3] ||= (e) =>
(unref(
K,
).card_number = e)),
placeholder: `请输入银行卡号`,
disabled:
unref(H) ||
!Q(unref(B)),
maxlength: 100,
fluid: ``,
},
null,
8,
[
`id`,
`modelValue`,
`disabled`,
],
),
],
64,
))
: (openBlock(),
createElementBlock(
Fragment,
{
key: 1,
},
[
createElementVNode(
`label`,
{
for: `${unref(z)}-account`,
},
`收款账号`,
8,
P,
),
createVNode(
d,
{
id: `${unref(z)}-account`,
modelValue:
unref(K).account,
"onUpdate:modelValue":
(n[4] ||= (e) =>
(unref(K).account =
e)),
placeholder: `请输入收款账号`,
disabled:
unref(H) ||
!Q(unref(B)),
maxlength: 100,
fluid: ``,
},
null,
8,
[
`id`,
`modelValue`,
`disabled`,
],
),
],
64,
)),
]),
],
64,
))
: createCommentVNode(``, !0),
createElementVNode(`div`, F, [
createElementVNode(
`label`,
{
for: `${unref(z)}-notes`,
},
`备注`,
8,
ye,
),
createVNode(
_,
{
id: `${unref(z)}-notes`,
modelValue: unref(K).notes,
"onUpdate:modelValue": (n[5] ||= (e) =>
(unref(K).notes = e)),
rows: `2`,
placeholder: `选填`,
disabled: unref(H) || !Q(unref(B)),
maxlength: 1e3,
autoResize: ``,
fluid: ``,
},
null,
8,
[`id`, `modelValue`, `disabled`],
),
]),
createElementVNode(`div`, be, [
createElementVNode(`div`, xe, [
(n[11] ||= createElementVNode(
`span`,
null,
`提现金额`,
-1,
)),
createElementVNode(
`b`,
null,
`¥` +
toDisplayString(
Number(unref(K).amount ?? 0).toFixed(
2,
),
),
1,
),
]),
createElementVNode(`div`, Se, [
(n[12] ||= createElementVNode(
`span`,
null,
`手续费`,
-1,
)),
createElementVNode(
`b`,
null,
`-¥` +
toDisplayString(unref(Te).toFixed(2)),
1,
),
]),
createElementVNode(`div`, Ce, [
(n[13] ||= createElementVNode(
`span`,
null,
`预计到账`,
-1,
)),
createElementVNode(
`b`,
null,
`¥` +
toDisplayString(unref(Ee).toFixed(2)),
1,
),
]),
]),
unref(U)
? (openBlock(),
createBlock(
i,
{
key: 2,
severity: `error`,
closable: !1,
},
{
default: withCtx(() => [
createTextVNode(
toDisplayString(unref(U)),
1,
),
]),
_: 1,
},
))
: createCommentVNode(``, !0),
]))
: createCommentVNode(``, !0),
]),
_: 1,
},
8,
[`visible`, `header`, `closable`, `close-on-escape`],
)
);
}
);
},
}),
[[`__scopeId`, `data-v-e4be3b52`]],
),
{
__name: `WithdrawDialog`,
},
);
export { w as n };
export default I;
</script>