feat: 上线银行模块

This commit is contained in:
陈淳
2024-03-14 18:32:58 +08:00
parent 069e411dc4
commit e4f89e5a05
11 changed files with 230 additions and 47 deletions

View File

@@ -10,7 +10,10 @@ namespace Yi.Framework.Bbs.Application.Contracts.Dtos.Bank
{ {
public class BankCardDto:EntityDto<Guid> public class BankCardDto:EntityDto<Guid>
{ {
/// <summary>
/// 满期限时间,可空
/// </summary>
public DateTime? FulltermTime { get; set; }
public DateTime? LastDepositTime { get; set; } public DateTime? LastDepositTime { get; set; }
public DateTime CreationTime { get; set; } public DateTime CreationTime { get; set; }
@@ -31,10 +34,6 @@ namespace Yi.Framework.Bbs.Application.Contracts.Dtos.Bank
public decimal MaxStorageMoney { get; set; } public decimal MaxStorageMoney { get; set; }
/// <summary>
/// 满期限时间,可空
/// </summary>
public DateTime? Fullterm { get; set; }
/// <summary> /// <summary>
/// 银行卡状态 /// 银行卡状态

View File

@@ -29,13 +29,12 @@ export function applyingBankCard() {
export function drawMoney(cardId) { export function drawMoney(cardId) {
return request({ return request({
url: `/bank/draw/${cardId}`, url: `/bank/draw/${cardId}`,
method: "put", method: "put"
data: data,
}); });
} }
// 存款 // 存款
export function delUser(cardId,moneyNum) { export function depositMoney(cardId,moneyNum) {
return request({ return request({
url: `/bank/deposit/${cardId}/${moneyNum}`, url: `/bank/deposit/${cardId}/${moneyNum}`,
method: "put" method: "put"

View File

@@ -92,7 +92,6 @@ const props = defineProps(['code'])
let codeCopyDic=[]; let codeCopyDic=[];
const addCopyEvent=()=>{ const addCopyEvent=()=>{
const copySpans = document.querySelectorAll('.copy'); const copySpans = document.querySelectorAll('.copy');
console.log(copySpans,"copySpans");
// 为每个 copy span 元素添加点击事件 // 为每个 copy span 元素添加点击事件
copySpans.forEach(span => { copySpans.forEach(span => {

View File

@@ -147,6 +147,7 @@ const currentUserInfo=computed(()=>{
useUserStore().updateToken(token); useUserStore().updateToken(token);
try { try {
// 存储用户信息 // 存储用户信息
await useUserStore().getInfo(); // 用户信息 await useUserStore().getInfo(); // 用户信息
// 登录成功后 路由跳转 // 登录成功后 路由跳转
// 如果有记录当前跳转页面 // 如果有记录当前跳转页面

View File

@@ -48,10 +48,17 @@
</el-input> </el-input>
</div> </div>
<div class="user"> <div class="user">
<div class="money" v-if="isLogin">钱钱<span>{{money}}</span></div>
<el-dropdown trigger="click"> <el-dropdown trigger="click">
<AvatarInfo :size="30" :isSelf="true" /> <AvatarInfo :size="30" :isSelf="true" />
<template #dropdown> <template #dropdown>
<el-dropdown-menu v-if="isLogin"> <el-dropdown-menu v-if="isLogin">
<el-dropdown-item>你的钱钱{{money}}</el-dropdown-item>
<el-dropdown-item @click="enterProfile" <el-dropdown-item @click="enterProfile"
>进入个人中心</el-dropdown-item >进入个人中心</el-dropdown-item
> >
@@ -60,11 +67,14 @@
> >
<el-dropdown-item @click="logout">登出</el-dropdown-item> <el-dropdown-item @click="logout">登出</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
<el-dropdown-menu v-else="isLogin"> <el-dropdown-menu v-else>
<el-dropdown-item @click="toLogin">去登录</el-dropdown-item> <el-dropdown-item @click="toLogin">去登录</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
</el-dropdown> </el-dropdown>
<div class="gitee" @click="handleGitClick"> <div class="gitee" @click="handleGitClick">
<el-tooltip effect="dark" content="在gitee找到我们" placement="bottom"> <el-tooltip effect="dark" content="在gitee找到我们" placement="bottom">
<img src="@/assets/common/icons/gitee.png" alt="" /> <img src="@/assets/common/icons/gitee.png" alt="" />
@@ -86,12 +96,13 @@ import useUserStore from "@/stores/user.js";
import useConfigStore from "@/stores/config"; import useConfigStore from "@/stores/config";
import useAuths from "@/hooks/useAuths"; import useAuths from "@/hooks/useAuths";
import { Session } from "@/utils/storage"; import { Session } from "@/utils/storage";
import { storeToRefs } from 'pinia'
const { isLogin, clearStorage } = useAuths(); const { isLogin, clearStorage } = useAuths();
const configStore = useConfigStore(); const configStore = useConfigStore();
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const userStore = useUserStore(); const userStore = useUserStore();
const { money } = storeToRefs(userStore)
const activeIndex = ref("1"); const activeIndex = ref("1");
const searchText = ref(""); const searchText = ref("");
const handleSelect = (key, keyPath) => { const handleSelect = (key, keyPath) => {
@@ -142,6 +153,16 @@ const handleGithubClick = () => {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.money
{
font-size: small;
color: #FED055;
margin: 0 5px;
span{
font-weight: 600;
}
}
.header { .header {
width: 1300px; width: 1300px;
display: flex; display: flex;

View File

@@ -27,7 +27,7 @@
<el-menu-item index="5" :route="{ path: '/activity/bank' }"> <el-menu-item index="5" :route="{ path: '/activity/bank' }">
<el-icon> <el-icon>
<Money /> <Money />
</el-icon> <span>银行(即将开放)</span> </el-icon> <span>银行</span>
</el-menu-item> </el-menu-item>
<el-menu-item index="6" :route="{ path: '/activity/x' }"> <el-menu-item index="6" :route="{ path: '/activity/x' }">
<el-icon> <el-icon>
@@ -40,10 +40,10 @@
</template> </template>
<script setup> <script setup>
const handleOpen = (key, keyPath) => { const handleOpen = (key, keyPath) => {
console.log(key, keyPath) //console.log(key, keyPath)
} }
const handleClose = (key, keyPath) => { const handleClose = (key, keyPath) => {
console.log(key, keyPath) // console.log(key, keyPath)
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@@ -2,7 +2,7 @@ import { login, logout, register } from "@/apis/accountApi";
import { getUserDetailInfo, getLoginCode } from "@/apis/auth"; import { getUserDetailInfo, getLoginCode } from "@/apis/auth";
import useAuths from "@/hooks/useAuths"; import useAuths from "@/hooks/useAuths";
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { getBbsUserProfile } from '@/apis/userApi.js'
const { getToken, setToken, clearStorage } = useAuths(); const { getToken, setToken, clearStorage } = useAuths();
const useUserStore = defineStore("user", { const useUserStore = defineStore("user", {
@@ -16,6 +16,7 @@ const useUserStore = defineStore("user", {
permissions: [], permissions: [],
codeImageURL: "", codeImageURL: "",
codeUUid: "", codeUUid: "",
money:0
}), }),
getters: {}, getters: {},
actions: { actions: {
@@ -42,8 +43,10 @@ const useUserStore = defineStore("user", {
// 获取用户信息 // 获取用户信息
getInfo() { getInfo() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
getUserDetailInfo() getUserDetailInfo()
.then((response) => { .then(async (response) => {
const res = response.data; const res = response.data;
const user = res.user; const user = res.user;
const avatar = const avatar =
@@ -59,6 +62,7 @@ const useUserStore = defineStore("user", {
} else { } else {
this.roles = ["ROLE_DEFAULT"]; this.roles = ["ROLE_DEFAULT"];
} }
// this.roles = ["admin"]; // this.roles = ["admin"];
// this.permissions=["*:*:*"] // this.permissions=["*:*:*"]
this.name = user.nick; this.name = user.nick;
@@ -66,11 +70,23 @@ const useUserStore = defineStore("user", {
this.userName = user.userName; this.userName = user.userName;
this.id = user.id; this.id = user.id;
//获取bbs信息
const {data:bbsData}= await getBbsUserProfile(this.id)
this.money= bbsData.money;
resolve(res); resolve(res);
}) })
.catch((error) => { .catch((error) => {
reject(error); reject(error);
}); });
}); });
}, },
// 退出系统 // 退出系统

View File

@@ -4,7 +4,7 @@
<div> <div>
<ExchangeRate :option="statisOptions" /> <ExchangeRate :option="statisOptions" />
<div class="div-show"> <div class="div-show">
<p class="p-rate">当前实时利息<span>110%</span>可获取投入的百分之110%的本金</p> <p class="p-rate">当前实时利息<span>130%</span>可获取投入的百分之130%的本金</p>
<el-button type="primary" @click="applying()"><el-icon> <el-button type="primary" @click="applying()"><el-icon>
<AddLocation /> <AddLocation />
</el-icon>申领银行卡</el-button> </el-icon>申领银行卡</el-button>
@@ -12,48 +12,132 @@
</div> </div>
<el-divider /> <el-divider />
<div> <div>
<el-row :gutter="20"> <el-row :gutter="20" v-if="bankCardList.length > 0">
<el-col :span=8 v-for="item in bankCardList">
<BankCard></BankCard> <el-col :span=8 v-for="item in bankCardList" :key="item.id">
<BankCard :card="item" @handlerDeposit="handlerDeposit(item.id)" @handlerDraw="sendDraw(item.id)"></BankCard>
</el-col> </el-col>
</el-row> </el-row>
<div v-else> <el-alert title="当前暂未拥有银行卡,请申请!" type="info" center :closable="false" /></div>
</div> </div>
<el-dialog v-model="depositDialogVisible" title="输入您的存款金额最低不能少于50该卡最大上限100" width="600">
<el-form :model="depositForm" ref="depositFormRef" >
<el-form-item label="存入金额" prop="number">
<el-input-number v-model="depositForm.number" :min="50" :max="100" autocomplete="off"/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="depositDialogVisible = false">取消</el-button>
<el-button type="primary" @click="sendDeposit">
确认存入该卡中
</el-button>
</div>
</template>
</el-dialog>
</div> </div>
</template> </template>
<script setup> <script setup>
import BankCard from "./components/BankCard.vue" import BankCard from "./components/BankCard.vue"
import ExchangeRate from "./components/ExchangeRateChart.vue" import ExchangeRate from "./components/ExchangeRateChart.vue"
import { getBankCardList, applyingBankCard, getInterestList } from '@/apis/bankApi' import { getBankCardList, applyingBankCard, getInterestList, depositMoney,drawMoney } from '@/apis/bankApi'
import useAuths from '@/hooks/useAuths.js'; import useAuths from '@/hooks/useAuths.js';
import { computed, ref,onMounted } from "vue"; import { computed, ref, onMounted,reactive } from "vue";
import useUserStore from "@/stores/user";
const { isLogin } = useAuths(); const { isLogin } = useAuths();
const bankCardList = ref([]); const bankCardList = ref([]);
const interestList = ref([]);
const depositForm = ref({
cardId: null,
number: 50
});
const userStore=useUserStore();
const depositFormRef = ref(null)
const depositDialogVisible = ref(false);
const interestList=ref([]);
const refreshData = async () => { const refreshData = async () => {
if (isLogin) { if (isLogin) {
const {data} = await getBankCardList(); const { data } = await getBankCardList();
bankCardList.value=data; bankCardList.value = data;
} }
const {data2:data} = await getInterestList(); const { data2: data } = await getInterestList();
interestList.value =data; interestList.value = data;
} }
onMounted(async () => { onMounted(async () => {
await refreshData(); await refreshData();
}) })
//申请银行卡
const applying = async () => { const applying = async () => {
// await applyingBankCard();
ElMessageBox.confirm(
'现在要向行长申领银行卡吗?行长会根据你的【等级】信誉可为你开通不同数量的银行卡',
'提交申请',
{
confirmButtonText: '申请',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(async () => {
await applyingBankCard();
ElMessage({
type: 'success',
message: '领取成功',
})
await refreshData();
});
//刷新一下 //刷新一下
await refreshData();
} }
//打开存款面板
const handlerDeposit = (cardId) => {
depositForm.value.cardId = cardId;
depositDialogVisible.value = true;
}
//进行提款操作
const sendDraw=async (cardId)=>{
ElMessageBox.confirm(
'确定现在进行提款吗?如果提前提款,将只能获取存入的本金',
'提款',
{
confirmButtonText: '确认提款',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(async () => {
await drawMoney(cardId)
await refreshData();
await userStore.getInfo();
ElMessage({
type: 'success',
message: '钱钱提款成功',
})
});
const statisOptions = computed( () => {
}
//进行存款操作
const sendDeposit = async () => {
await depositMoney(depositForm.value.cardId, depositForm.value.number);
depositDialogVisible.value=false;
await refreshData();
await userStore.getInfo();
ElMessage({
type: 'success',
message: '钱钱提款成功',
})
}
const statisOptions = computed(() => {
return { return {
xAxis: { xAxis: {

View File

@@ -1,34 +1,99 @@
<template> <template>
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body"
银行卡-32659854213658541 :class="{ 'card-wait': cardData.bankCardState=='Wait',
<p>当前余额100钱钱</p> 'card-unused': cardData.bankCardState=='Unused'}">
<p>状态存款中</p> 银行卡-{{ cardData.id.substring(0,8) }}
<p>剩余定期提款时间还剩: 2天12小时</p> <p>当前余额{{ cardData.storageMoney }}钱钱</p>
</div> <p>状态{{ state }}</p>
<p v-if="cardData.bankCardState=='Wait'">剩余提款时间: {{ time }}</p>
</div>
<div class="div-oper"> <div class="div-oper">
<el-button>存款</el-button><el-button type="danger"></el-button> <el-button v-if="cardData.bankCardState=='Unused'" @click="handlerDeposit"></el-button>
<el-button v-if="cardData.bankCardState=='Wait'" type="danger" @click="handlerDraw(cardData.id)">提款</el-button>
</div> </div>
</div> </div>
</template> </template>
<script setup>
import {computed,watch,ref} from 'vue'
const props = defineProps(['card'])
const emit =defineEmits(['handlerDeposit'])
const cardData=ref(props.card);
const bankCardStateEnum=[
{key:'Unused',value:"闲置中"},
{key:'Wait',value:"存款中"}
]
const state=computed(()=>{
return bankCardStateEnum.filter(x=>x.key==cardData.value.bankCardState)[0].value
})
const time=computed(()=> {
// 将传入的字符串转换为时间对象
const inputDate = new Date(props.card.fulltermTime);
// 获取当前时间
const currentDate = new Date();
// 计算时间差(以毫秒为单位)
const timeDiff = inputDate.getTime() - currentDate.getTime();
// 如果传入时间早于当前时间,则返回"已满"提示
if (timeDiff <= 0) {
return "0";
}
// 将时间差转换为天、小时、分钟和秒
const days = Math.floor(timeDiff / (1000 * 60 * 60 * 24));
const hours = Math.floor((timeDiff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))+1;
// 返回剩余时间字符串
return `${days}${hours}`;
}
)
const handlerDraw=(cardId)=>{
emit('handlerDraw',cardId)
}
//存款
const handlerDeposit=()=>{
emit('handlerDeposit')
};
watch(
() => props.card,
(val, oldValue) => {
cardData.value=props.card;
},
{ immediate: true, deep: true }
);
</script>
<style scoped lang="scss"> <style scoped lang="scss">
.card-wait
{
background-color:brown;
}
.card-unused
{ background-color: #FDC830;
}
.card { .card {
height: 140px; height: 140px;
margin: 10px 0; margin: 10px 0;
border-radius: 15px; border-radius: 15px;
box-shadow: rgba(0, 0, 0, 0.2) 0px 4px 8px 0px; box-shadow: rgba(0, 0, 0, 0.2) 0px 4px 8px 0px;
.card-body
{ .card-body {
padding: 5px; padding: 5px;
height: 100px; height: 100px;
background-color: #FDC830; // background-color: #FDC830;
color: #FFFFFF; color: #FFFFFF;
border-radius: 15px 15px 0 0; border-radius: 15px 15px 0 0;
} }
.div-oper { .div-oper {
padding: 5px; padding: 5px;
padding-right: 10px; padding-right: 10px;
border-radius:0 0 15px 15px ; border-radius: 0 0 15px 15px;
background-color: #FFFFFF; background-color: #FFFFFF;
text-align: end; text-align: end;
height: 40px; height: 40px;

View File

@@ -1,7 +1,6 @@
<template> <template>
<div> <div>
<div class="rate v-chart" ref="statis"> <div class="rate v-chart" ref="statis">
银行利息利息趋势图
</div> </div>

View File

@@ -1,6 +1,6 @@
export const exchangeRateConfig ={ export const exchangeRateConfig ={
title: { title: {
text: '银行利息趋势图' text: '银行利息趋势图-(暂未开放)'
}, },
tooltip: { tooltip: {
trigger: 'axis' trigger: 'axis'