This commit is contained in:
2025-06-04 08:55:14 +08:00
parent 4a945c763f
commit d6306fd462
14 changed files with 300 additions and 58 deletions

View File

@@ -407,6 +407,20 @@ const merchant = {
data: data
});
},
editPassword: async (data) => {
return request({
url: '/index/index/editPassword',
method: Method.POST,
data: data
});
},
postWithdrawal: async (data) => {
return request({
url: '/index/business/postWithdrawal',
method: Method.POST,
data: data
});
},
}
export default merchant;

View File

@@ -2,6 +2,7 @@
import {reactive, ref} from "vue";
import {Message} from "@arco-design/web-vue";
import Api from "../../api/index.ts";
import {QrcodeCanvas} from "qrcode.vue";
const {money} = defineProps({
money: {
@@ -21,7 +22,7 @@ const open = () => {
}
const initQR = async () => {
const {data} = await Api.merchant.rechargeOrderQR({
const {data: {data}} = await Api.merchant.rechargeOrderQR({
money: money,
});
Object.assign(qrInfo, data);
@@ -46,10 +47,10 @@ const initQR = async () => {
</div>
<div class="text-center mt-[20px]">打开支付宝扫描下方二维码支付</div>
<div class="w-[200px] aspect-square mx-auto mt-[5px]">
<img class="w-full h-full object-cover" src="" alt=""/>
<qrcode-canvas size="200" :value="qrInfo.qr_code"></qrcode-canvas>
</div>
<div class="flex justify-center mt-[5px] flex-col items-center">
<a-link :hoverable="false" style="color: var(--color-neutral-6)">
<a-link :hoverable="false" style="color: var(--color-neutral-6)" @click="initQR">
<icon-sync class="mr-[5px]"/>
点击刷新
</a-link>

View File

@@ -0,0 +1,41 @@
<script setup lang="ts">
import {nextTick, ref, useTemplateRef} from "vue";
const inputTagRef = useTemplateRef('inputTagRef');
const modelValue = defineModel();
const input = ref('');
const changeInput = (e) => {
if (e.match(/#(\S+?)(?=\s)/g)) {
modelValue.value.push(...e.match(/#(\S+?)(?=\s)/g).map(tag => tag.slice(1)));
input.value = null;
nextTick(() => {
inputTagRef.value.blur();
nextTick(() => {
inputTagRef.value.focus();
})
})
}
}
const pressEnter = () => {
modelValue.value = modelValue.value.filter(v => v.match(/#(\S+?)(?=\s)/g));
}
</script>
<template>
<a-input-tag
ref="inputTagRef"
:retain-input-value="false"
@press-enter="pressEnter"
@input-value-change="changeInput"
v-model:model-value="modelValue"
v-model:input-value="input"
placeholder="请输入话题"
unique-value>
</a-input-tag>
</template>
<style scoped lang="scss">
</style>

View File

@@ -27,7 +27,7 @@ const verifyPhone = async () => {
if (timer === null) {
const {msg, code} = await api(mobile, type);
if (code === 1) Message.success(msg);
time.value = 10;
time.value = 60;
timer = setInterval(() => {
if (time.value <= 0) {
time.value = null;

View File

@@ -1,42 +1,88 @@
<script setup>
import {reactive} from 'vue';
import {reactive, useTemplateRef} from 'vue';
import VerificationCode from "../../components/VerificationCode/index.vue";
import Api from "../../api/index.js";
import {Message} from "@arco-design/web-vue";
import {toPath} from "../../utils/index.js";
const from = reactive({
phone: null,
verificationCode: null,
const formRef = useTemplateRef('formRef');
const form = reactive({
mobile: null,
captcha: null,
password: null,
});
const rules = {
mobile: [{
required: true,
message: '手机号不能为空',
}],
captcha: [{
required: true,
message: '验证码不能为空',
}],
password: [{
required: true,
message: '请输入新密码',
}],
}
const success = () => {
formRef.value.validate().then(async (res) => {
if (res) {
const firstKey = Object.keys(res)[0];
Message.warning(res[firstKey].message);
} else {
const {msg} = await Api.merchant.editPassword(form);
Message.success(msg);
}
});
}
</script>
<template>
<div class="p-[50px] rounded-[12px] bg-white w-[460px] min-h-[540px] box-border card">
<div class="text-[24px] text-center text2">忘记密码</div>
<div class="mt-[48px] flex flex-col gap-[20px]">
<a-form layout="vertical">
<a-form-item>
<a-input v-model:model-value="from.phone" placeholder="手机号"></a-input>
<a-form
ref="formRef"
:model="form"
:rules="rules"
layout="vertical">
<a-form-item field="mobile">
<a-input v-model:model-value="form.mobile" placeholder="手机号"></a-input>
</a-form-item>
<a-form-item>
<a-form-item field="captcha">
<VerificationCode
:type="3"
:api="Api.merchant.sendSms"
:phone="from.phone"
v-model:verification-code="from.verificationCode">
:mobile="form.mobile"
v-model:verification-code="form.captcha">
</VerificationCode>
</a-form-item>
<a-form-item>
<a-input v-model:model-value="from.password" placeholder="新密码"></a-input>
<a-form-item field="password">
<a-input v-model:model-value="form.password" placeholder="新密码"></a-input>
</a-form-item>
</a-form>
</div>
<div class="flex flex-col mt-[30px] gap-[32px]">
<a-button type="primary">确认修改</a-button>
<a-button type="primary" @click="success">确认修改</a-button>
<a-button
@click="toPath('/loginSYS/login')"
type="text">
返回
<icon-arrow-right class="ml-[5px]"/>
</a-button>
</div>
</div>
</template>
<style>
.arco-form-item-label-col {
display: none;
}
</style>
<style scoped>
.card {
box-shadow: 0 8px 20px 0 rgba(0, 0, 0, 0.1);

View File

@@ -3,6 +3,7 @@ import {reactive, ref} from 'vue';
import {toPath} from "../../utils/index.js";
import VerificationCode from '../../components/VerificationCode/index.vue';
import {useUserStore} from "../../pinia/UserStore/index.js";
import {Message} from "@arco-design/web-vue";
const {login} = useUserStore();
@@ -18,6 +19,25 @@ const from = reactive({
});
const mode = ref(MODE.PHONE);
const loginSYS = (isRoot, form) => {
if (!from.mobile || from.mobile === '') {
Message.warning('手机号不能为空');
return;
}
if (mode.value === MODE.PHONE) {
if (!from.code || from.code === '') {
Message.warning('验证码不能为空');
return;
}
} else {
if (!from.password || from.password === '') {
Message.warning('密码不能为空');
return;
}
}
login(isRoot, form);
}
</script>
<template>
@@ -43,8 +63,8 @@ const mode = ref(MODE.PHONE);
</a-input>
</div>
<div class="flex flex-col mt-[50px] gap-[32px]">
<a-button @click="login(false, from)" type="primary">登陆商户端</a-button>
<a-button @click="login(true, from)" type="primary">登陆管理端</a-button>
<a-button @click="loginSYS(false, from)" type="primary">登陆商户端</a-button>
<a-button @click="loginSYS(true, from)" type="primary">登陆管理端</a-button>
<a-button
@click="toPath('/loginSYS/register')"
type="text">

View File

@@ -1,11 +1,12 @@
<script setup>
import {reactive} from 'vue';
import {reactive, useTemplateRef} from 'vue';
import VerificationCode from "../../components/VerificationCode/index.vue";
import Api from "../../api/index.js";
import {Message} from "@arco-design/web-vue";
import {toPath} from "../../utils/index.js";
const from = reactive({
const formRef = useTemplateRef('formRef');
const form = reactive({
wechat: null,
mobile: null,
password: null,
@@ -13,9 +14,35 @@ const from = reactive({
invite: null,
});
const rules = {
wechat: [{
required: true,
message: '微信号不能为空',
}],
mobile: [{
required: true,
message: '手机号不能为空',
}],
password: [{
required: true,
message: '密码不能为空',
}],
captcha: [{
required: true,
message: '验证码不能为空',
}],
}
const register = async () => {
const {msg} = await Api.merchant.register(from);
Message.success(msg);
formRef.value.validate().then(async (res) => {
if (res) {
const firstKey = Object.keys(res)[0];
Message.warning(res[firstKey].message);
} else {
const {msg} = await Api.merchant.register(form);
Message.success(msg);
}
});
}
</script>
@@ -23,26 +50,30 @@ const register = async () => {
<div class="p-[50px] rounded-[12px] bg-white w-[460px] box-border card">
<div class="text-[24px] text-center text2">账号注册</div>
<div class="mt-[30px] flex flex-col gap-[20px]">
<a-form layout="vertical">
<a-form-item label="微信号">
<a-input v-model:model-value="from.wechat" placeholder="请输入微信号"></a-input>
<a-form
ref="formRef"
:model="form"
:rules="rules"
layout="vertical">
<a-form-item label="微信号" field="wechat">
<a-input v-model:model-value="form.wechat" placeholder="请输入微信号"></a-input>
</a-form-item>
<a-form-item label="手机号">
<a-input v-model:model-value="from.mobile" placeholder="请输入手机号"></a-input>
<a-form-item label="手机号" field="mobile">
<a-input v-model:model-value="form.mobile" placeholder="请输入手机号"></a-input>
</a-form-item>
<a-form-item label="验证码">
<a-form-item label="验证码" field="captcha">
<VerificationCode
:type="1"
:api="Api.merchant.sendSms"
:mobile="from.mobile"
v-model:verification-code="from.captcha">
:mobile="form.mobile"
v-model:verification-code="form.captcha">
</VerificationCode>
</a-form-item>
<a-form-item label="登陆密码">
<a-input v-model:model-value="from.password" placeholder="请输入登陆密码"></a-input>
<a-form-item label="登陆密码" field="password">
<a-input v-model:model-value="form.password" placeholder="请输入登陆密码"></a-input>
</a-form-item>
<a-form-item label="邀请码(选填)">
<a-input v-model:model-value="from.invite" placeholder="请输入邀请码"></a-input>
<a-input v-model:model-value="form.invite" placeholder="请输入邀请码"></a-input>
</a-form-item>
</a-form>
</div>

View File

@@ -1,7 +1,43 @@
<script setup>
import {ref} from "vue";
import {reactive, ref, watch} from "vue";
import Api from "../../../api/index.js";
import {Message} from "@arco-design/web-vue";
const visible = ref(false);
const detail = reactive({});
const {id, money} = defineProps({
id: {
type: Number,
default: null,
},
money: {
type: Number,
default: null
}
});
watch(
() => visible.value,
(val) => {
if (val) Api.merchant.postWithdrawal({
id: id,
type: 0,
money: money,
}).then(({data}) => {
Object.assign(detail, data);
});
},
{deep: true}
)
const success = async () => {
const {msg} = await Api.merchant.postWithdrawal({
id: id,
type: 1,
money: money,
});
Message.success(msg);
}
</script>
<template>
@@ -11,19 +47,26 @@ const visible = ref(false);
</div>
<a-modal
@ok="success"
ok-text="确认提现"
title-align="start"
title="核对提现信息"
v-model:visible="visible">
<a-form label-align="left">
<a-form-item label="姓名">
彭于晏
{{ detail.name }}
</a-form-item>
<a-form-item label="支付宝账号">
13505948653
{{ detail.account }}
</a-form-item>
<a-form-item label="提现金额">
335.14
{{ detail.money }}
</a-form-item>
<a-form-item label="提现手续费">
{{ detail.process }}
</a-form-item>
<a-form-item label="到账金额">
{{ detail.real_money }}
</a-form-item>
</a-form>
<div class="info">手续费率为1%由三方代账公司收取</div>

View File

@@ -16,7 +16,8 @@ const form = reactive({
<a-form>
<a-form-item label="立即充值">
<a-input-number v-model:model-value="form.money" class="w-1/2" placeholder="输入金额"></a-input-number>
<a-input-number v-model:model-value="form.money" class="w-1/2" placeholder="输入金额"
:precision="2" :min="1"></a-input-number>
</a-form-item>
<a-form-item class="mt-[40px]">

View File

@@ -1,9 +1,8 @@
<script setup>
import ZFBICON from "../../../../../assets/images/zfb.png";
import YHKICON from "../../../../../assets/images/yhk.png";
import {onMounted, reactive} from "vue";
import {onMounted, reactive, ref} from "vue";
import AddWithdrawalInformationModal from "../../../components/AddWithdrawalInformationModal.vue";
import openWithdrawalStatus from "./openWithdrawalStatus.js";
import LookWithdrawalInformationModal from "../../../components/LookWithdrawalInformationModal.vue";
import Api from "../../../../../api/index.js";
@@ -13,7 +12,8 @@ const {businessInfo} = defineProps({
default: {}
}
});
const money = ref(null);
const radioValue = ref(null);
const withdrawalList = reactive([]);
const getData = async () => {
const {data} = await Api.merchant.getWithdrawalList();
@@ -39,9 +39,9 @@ onMounted(() => {
class="ml-[100px]"
:auto-label-width="true">
<a-form-item label="提现账户">
<a-radio-group>
<a-radio-group v-model:model-value="radioValue">
<div class="grid grid-cols-2 gap-[18px]">
<a-radio value="1" v-for="v in withdrawalList">
<a-radio :value="index" v-for="(v, index) in withdrawalList">
<div class="flex items-center">
<div class="input-card flex w-[306px] items-center">
<img class="w-[15px] h-[15px] object-cover" :src="v.type === 1 ? ZFBICON : YHKICON"
@@ -67,14 +67,15 @@ onMounted(() => {
<a-form-item label="提现金额">
<div class="max-w-[768px] flex gap-[20px] items-center">
<a-input-number :placeholder="`最多可提现${businessInfo.money}元`"></a-input-number>
<a-input-number v-model:model-value="money" :precision="2"
:placeholder="`最多可提现${businessInfo.money}元`"></a-input-number>
<a-link :hoverable="false" class="whitespace-nowrap">全部提现</a-link>
</div>
</a-form-item>
<a-form-item class="mt-[40px]">
<a-button type="primary" @click="openWithdrawalStatus">立即提现</a-button>
<LookWithdrawalInformationModal>
<!-- <a-button type="primary" @click="openWithdrawalStatus">立即提现</a-button>-->
<LookWithdrawalInformationModal :id="withdrawalList[radioValue]?.id" :money="money">
<a-button type="primary">立即提现</a-button>
</LookWithdrawalInformationModal>
</a-form-item>

View File

@@ -39,10 +39,19 @@ const getData = async () => {
Object.assign(vo, data);
Object.assign(UserStore.userInfo, vo);
form.old_mobile = vo.mobile;
form.mobile = vo.mobile;
vo.password = '********';
}
const saveNickname = async () => {
if (!form.nickname || form.nickname === '') {
Message.warning('昵称不能为空');
return;
}
if (form.nickname.length > 20) {
Message.warning('昵称非法,请重新输入');
return;
}
const {msg} = await Api.merchant.saveNickname({
nickname: form.nickname,
});
@@ -52,6 +61,18 @@ const saveNickname = async () => {
}
const saveMobile = async () => {
if (!form.new_mobile || form.new_mobile === '') {
Message.warning('新手机号不能为空');
return;
}
if (!form.old_captcha || form.old_captcha === '') {
Message.warning('原手机验证码不能为空');
return;
}
if (!form.new_captcha || form.new_captcha === '') {
Message.warning('新手机验证码不能为空');
return;
}
const {msg} = await Api.merchant.saveMobile({
old_mobile: form.old_mobile,
new_mobile: form.new_mobile,
@@ -67,6 +88,14 @@ const saveMobile = async () => {
}
const savePassword = async () => {
if (!form.captcha || form.captcha === '') {
Message.warning('验证码不能为空');
return;
}
if (!form.password || form.password === '') {
Message.warning('请输入新密码');
return;
}
const {msg} = await Api.merchant.savePassword({
mobile: form.mobile,
captcha: form.captcha,
@@ -80,6 +109,14 @@ const savePassword = async () => {
}
const saveWechat = async () => {
if (!form.wechat || form.wechat === '') {
Message.warning('微信号不能为空');
return;
}
if (/[^a-zA-Z0-9_-]/.test(form.wechat)) {
Message.warning('微信号非法,请重新输入');
return;
}
const {msg} = await Api.merchant.saveWechat({
wechat: form.wechat
});
@@ -193,7 +230,7 @@ onMounted(() => {
<a-tab-pane title="账号密码" key="3">
<a-form-item label="手机号">
<a-input v-model:model-value="form.mobile" placeholder="请输入手机号"></a-input>
<a-input v-model:model-value="form.mobile" disabled placeholder="请输入手机号"></a-input>
</a-form-item>
<a-form-item label="验证码">
<VerificationCode

View File

@@ -51,7 +51,7 @@ const refuseTaskChildren = async () => {
const update = async () => {
const {msg} = await Api.merchant.editChildrenMaterimal({
id: task.task_id,
data: detail.map(v => ({...v, tags: v.tags_arr})),
data: detail.map(v => ({...v, tags: v.tags_arr.split(",")})),
});
Message.success(msg);
emits('success');
@@ -93,17 +93,14 @@ const update = async () => {
</a-textarea>
</a-form-item>
<a-form-item label="话题">
<div v-if="item.tags_arr.length > 0" id="tag-list"
<div id="tag-list"
class="w-full bg-[var(--color-neutral-2)] p-[4px]">
<a-tag v-for="v in item.tags_arr">{{ v }}</a-tag>
</div>
<div v-else>
暂无话题
<a-input v-model:model-value="task.tags"></a-input>
</div>
</a-form-item>
<a-form-item label="素材">
<div v-if="item.material_arr.length > 0" class="flex flex-wrap gap-[16px]">
<div class="flex flex-wrap gap-[16px]">
<x-image
v-for="(v, index) in item.material_arr"
:hide-delete="true"
@@ -124,9 +121,6 @@ const update = async () => {
</div>
</add-material>
</div>
<div v-else>
暂无话题
</div>
</a-form-item>
<a-form-item label="评论区内容" v-if="task.is_comment === 1">