174
社区成员
发帖
与我相关
我的任务
分享
Course for This Assignment | MIEC EE304FZ |
---|---|
Team Name | Wizards of codes |
Assignment Requirements | Extreme Programming |
Objectives of This Assignment | Back-end separation calculator programming with login module |
Other References | NA |
Log in to show history
Scientific Calculator
Interest Rate Calculator_Deposit
Interest Rate Calculator_Loan
Register and Login
// 配置为静态路由
{
path: '',
component: Layout,
redirect: 'calculator',
children: [
{
path: 'calculator',
component: () => import('@/views/calculator/index.vue'),
name: 'Index',
meta: { title: '科学计算器', icon: 'dashboard' }
}
]
},
{
path: '/interestrate',
component: Layout,
meta: { title: '利率计算器', icon: 'dashboard' },
children: [
{
path: 'deposit',
component: () => import('@/views/InterestRate/deposit/index.vue'),
name: 'Deposit',
meta: { title: '存款', icon: 'dashboard' }
},
{
path: 'loans',
component: () => import('@/views/InterestRate/loans/index.vue'),
name: 'Loans',
meta: { title: '贷款', icon: 'dashboard' }
}
]
},
src\views\login.vue
<template>
<div class="login">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
<h3 class="title">小组作业</h3>
<el-form-item prop="username">
<el-input
v-model="loginForm.username"
type="text"
auto-complete="off"
placeholder="账号"
>
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
type="password"
auto-complete="off"
placeholder="密码"
@keyup.enter.native="handleLogin"
>
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="captchaEnabled">
<el-input
v-model="loginForm.code"
auto-complete="off"
placeholder="验证码"
style="width: 63%"
@keyup.enter.native="handleLogin"
>
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
</el-input>
<div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img"/>
</div>
</el-form-item>
<el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
<el-form-item style="width:100%;">
<el-button
:loading="loading"
size="medium"
type="primary"
style="width:100%;"
@click.native.prevent="handleLogin"
>
<span v-if="!loading">登 录</span>
<span v-else>登 录 中...</span>
</el-button>
<div style="float: right;" v-if="register">
<router-link class="link-type" :to="'/register'">立即注册</router-link>
</div>
</el-form-item>
</el-form>
<!-- 底部 -->
<div class="el-login-footer">
<span>Copyright © 2018-2023 ruoyi.vip All Rights Reserved.</span>
</div>
</div>
</template>
<script>
import { getCodeImg } from "@/api/login";
import Cookies from "js-cookie";
import { encrypt, decrypt } from '@/utils/jsencrypt'
export default {
name: "Login",
data() {
return {
codeUrl: "",
loginForm: {
// username: "admin",
username: "",
// password: "admin123",
password: "",
rememberMe: false,
code: "",
uuid: ""
},
loginRules: {
username: [
{ required: true, trigger: "blur", message: "请输入您的账号" }
],
password: [
{ required: true, trigger: "blur", message: "请输入您的密码" }
],
code: [{ required: true, trigger: "change", message: "请输入验证码" }]
},
loading: false,
// 验证码开关
captchaEnabled: true,
// 注册开关
register: true,
redirect: undefined
};
},
watch: {
$route: {
handler: function(route) {
this.redirect = route.query && route.query.redirect;
},
immediate: true
}
},
created() {
this.getCode();
this.getCookie();
},
methods: {
getCode() {
getCodeImg().then(res => {
this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled;
if (this.captchaEnabled) {
this.codeUrl = "data:image/gif;base64," + res.img;
this.loginForm.uuid = res.uuid;
}
});
},
getCookie() {
const username = Cookies.get("username");
const password = Cookies.get("password");
const rememberMe = Cookies.get('rememberMe')
this.loginForm = {
username: username === undefined ? this.loginForm.username : username,
password: password === undefined ? this.loginForm.password : decrypt(password),
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
};
},
handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true;
if (this.loginForm.rememberMe) {
Cookies.set("username", this.loginForm.username, { expires: 30 });
Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 });
Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 });
} else {
Cookies.remove("username");
Cookies.remove("password");
Cookies.remove('rememberMe');
}
this.$store.dispatch("Login", this.loginForm).then(() => {
this.$router.push({ path: this.redirect || "/" }).catch(()=>{});
}).catch(() => {
this.loading = false;
if (this.captchaEnabled) {
this.getCode();
}
});
}
});
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss">
.login {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
background-image: url("../assets/images/login-background.jpg");
background-size: cover;
}
.title {
margin: 0px auto 30px auto;
text-align: center;
color: #707070;
}
.login-form {
border-radius: 6px;
background: #ffffff;
width: 400px;
padding: 25px 25px 5px 25px;
.el-input {
height: 38px;
input {
height: 38px;
}
}
.input-icon {
height: 39px;
width: 14px;
margin-left: 2px;
}
}
.login-tip {
font-size: 13px;
text-align: center;
color: #bfbfbf;
}
.login-code {
width: 33%;
height: 38px;
float: right;
img {
cursor: pointer;
vertical-align: middle;
}
}
.el-login-footer {
height: 40px;
line-height: 40px;
position: fixed;
bottom: 0;
width: 100%;
text-align: center;
color: #fff;
font-family: Arial;
font-size: 12px;
letter-spacing: 1px;
}
.login-code-img {
height: 38px;
}
</style>
src\views\register.vue
<template>
<div class="register">
<el-form ref="registerForm" :model="registerForm" :rules="registerRules" class="register-form">
<h3 class="title">小组作业</h3>
<el-form-item prop="username">
<el-input v-model="registerForm.username" type="text" auto-complete="off" placeholder="账号">
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="registerForm.password"
type="password"
auto-complete="off"
placeholder="密码"
@keyup.enter.native="handleRegister"
>
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<el-form-item prop="confirmPassword">
<el-input
v-model="registerForm.confirmPassword"
type="password"
auto-complete="off"
placeholder="确认密码"
@keyup.enter.native="handleRegister"
>
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="captchaEnabled">
<el-input
v-model="registerForm.code"
auto-complete="off"
placeholder="验证码"
style="width: 63%"
@keyup.enter.native="handleRegister"
>
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
</el-input>
<div class="register-code">
<img :src="codeUrl" @click="getCode" class="register-code-img"/>
</div>
</el-form-item>
<el-form-item style="width:100%;">
<el-button
:loading="loading"
size="medium"
type="primary"
style="width:100%;"
@click.native.prevent="handleRegister"
>
<span v-if="!loading">注 册</span>
<span v-else>注 册 中...</span>
</el-button>
<div style="float: right;">
<router-link class="link-type" :to="'/login'">使用已有账户登录</router-link>
</div>
</el-form-item>
</el-form>
<!-- 底部 -->
<div class="el-register-footer">
<span>Copyright © 2018-2023 ruoyi.vip All Rights Reserved.</span>
</div>
</div>
</template>
<script>
import { getCodeImg, register } from "@/api/login";
export default {
name: "Register",
data() {
const equalToPassword = (rule, value, callback) => {
if (this.registerForm.password !== value) {
callback(new Error("两次输入的密码不一致"));
} else {
callback();
}
};
return {
codeUrl: "",
registerForm: {
username: "",
password: "",
confirmPassword: "",
code: "",
uuid: ""
},
registerRules: {
username: [
{ required: true, trigger: "blur", message: "请输入您的账号" },
{ min: 2, max: 20, message: '用户账号长度必须介于 2 和 20 之间', trigger: 'blur' }
],
password: [
{ required: true, trigger: "blur", message: "请输入您的密码" },
{ min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur' }
],
confirmPassword: [
{ required: true, trigger: "blur", message: "请再次输入您的密码" },
{ required: true, validator: equalToPassword, trigger: "blur" }
],
code: [{ required: true, trigger: "change", message: "请输入验证码" }]
},
loading: false,
captchaEnabled: true
};
},
created() {
this.getCode();
},
methods: {
getCode() {
getCodeImg().then(res => {
this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled;
if (this.captchaEnabled) {
this.codeUrl = "data:image/gif;base64," + res.img;
this.registerForm.uuid = res.uuid;
}
});
},
handleRegister() {
this.$refs.registerForm.validate(valid => {
if (valid) {
this.loading = true;
register(this.registerForm).then(res => {
const username = this.registerForm.username;
this.$alert("<font color='red'>恭喜你,您的账号 " + username + " 注册成功!</font>", '系统提示', {
dangerouslyUseHTMLString: true,
type: 'success'
}).then(() => {
this.$router.push("/login");
}).catch(() => {});
}).catch(() => {
this.loading = false;
if (this.captchaEnabled) {
this.getCode();
}
})
}
});
}
}
};
</script>
<style rel="stylesheet/scss" lang="scss">
.register {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
background-image: url("../assets/images/login-background.jpg");
background-size: cover;
}
.title {
margin: 0px auto 30px auto;
text-align: center;
color: #707070;
}
.register-form {
border-radius: 6px;
background: #ffffff;
width: 400px;
padding: 25px 25px 5px 25px;
.el-input {
height: 38px;
input {
height: 38px;
}
}
.input-icon {
height: 39px;
width: 14px;
margin-left: 2px;
}
}
.register-tip {
font-size: 13px;
text-align: center;
color: #bfbfbf;
}
.register-code {
width: 33%;
height: 38px;
float: right;
img {
cursor: pointer;
vertical-align: middle;
}
}
.el-register-footer {
height: 40px;
line-height: 40px;
position: fixed;
bottom: 0;
width: 100%;
text-align: center;
color: #fff;
font-family: Arial;
font-size: 12px;
letter-spacing: 1px;
}
.register-code-img {
height: 38px;
}
</style>
src\views\InterestRate\deposit\index.vue
<template>
<div class="container">
<el-form ref="form" :model="form" label-width="80px" :rules="rules">
<el-form-item label="存款金额" prop="value">
<el-input v-model="form.value"></el-input>
</el-form-item>
<el-form-item label="存款方式">
<el-select v-model="form.mode" placeholder="请选择存款方式" @change="modeChange">
<el-option label="活期" value="1"></el-option>
<el-option label="定期" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item label="存款利率">
<el-input v-model="form.interestRate" disabled>
<template slot="prepend">
<el-button @click="updateList">修改利率</el-button>
</template>
<template slot="append">%</template>
</el-input>
</el-form-item>
<el-form-item label="存款期限">
<el-select v-model="form.date" placeholder="请选择存款期限" :disabled="form.mode === '1' ? true : false"
@change="dateChange">
<el-option label="三个月" value="3m"></el-option>
<el-option label="半年" value="6m"></el-option>
<el-option label="一年" value="1y"></el-option>
<el-option label="二年" value="2y"></el-option>
<el-option label="三年" value="3y"></el-option>
<el-option label="五年" value="5y"></el-option>
</el-select>
</el-form-item>
<el-form-item label="利息">
<el-input v-model="form.result" disabled></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">立即计算</el-button>
</el-form-item>
</el-form>
<!-- 利率 -->
<el-dialog title="存款利率" :visible.sync="dialogVisible" width="40%">
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="name" label="类型" width="180">
</el-table-column>
<el-table-column prop="value" label="利率" width="180">
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button type="text" @click="update(scope.row)">修改</el-button>
</template>
</el-table-column>
</el-table>
</el-dialog>
<!-- 修改利率 -->
<el-dialog title="修改利率" :visible.sync="updateDialogVisible" width="40%">
<el-form ref="form" :model="updateForm" label-width="80px">
<el-form-item label="利率类型">
<el-input v-model="updateForm.name"></el-input>
</el-form-item>
<el-form-item label="利率">
<el-input v-model="updateForm.value"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="updateEnter">确认</el-button>
</el-form-item>
</el-form>
</el-dialog>
</div>
</template>
<script>
import { update, list, get } from '@/api/InterestRate/deposit.js'
export default {
data() {
return {
form: {
value: '',
mode: '1',
interestRate: '',
date: '',
result: ''
},
rules: {
value: [
{ required: true, message: '请输入金额', trigger: 'blur' },
],
date: [
{ required: true, message: '请选择贷款期限', trigger: 'blur' },
]
},
dialogVisible: false,
updateDialogVisible: false,
tableData: [],
updateForm: {
id: '',
value: '',
name: ''
}
}
},
mounted() {
this.get('hq')
},
methods: {
async list() {
const { data } = await list()
this.tableData = data;
},
onSubmit() {
this.$refs.form.validate((valid) => {
if (valid) {
if (this.form.mode === '2' && this.form.date === '') {
this.$message({
type: 'warning',
message: '请选择存款期限'
})
return false
}
this.form.result = this.form.value * this.form.interestRate * 0.01
}
});
},
updateList() {
this.list()
this.dialogVisible = true
},
async update(data) {
const { msg } = await update(data);
this.updateDialogVisible = false
this.$message({
type: 'success',
message: msg
})
},
update(row) {
const { name, value, id } = row
this.updateForm.name = name
this.updateForm.value = value
this.updateForm.id = id
this.updateDialogVisible = true
},
async updateEnter() {
const result = await update(this.updateForm)
this.list()
this.updateDialogVisible = false
this.$message({
type: 'success',
message: result.msg
})
},
modeChange(mode) {
if (mode === '1') {
this.get('hq')
return
}
this.form.interestRate = ''
},
async get(date) {
const { data } = await get(date)
this.form.interestRate = data.value
},
dateChange(date) {
this.get(date)
}
}
}
</script>
<style scoped>
.container {
width: 500px;
padding: 20px;
background-color: rgba(242, 231, 231, 0.627);
border-radius: 20px;
margin: 20px auto;
}
</style>
src\api\InterestRate\deposit.js
import request from '@/utils/request'
export function update(data) {
return request({
url: '/interestrate/deposit',
method: 'put',
data
})
}
export function list() {
return request({
url: '/interestrate/deposit',
})
}
export function get(date) {
return request({
url: `/interestrate/deposit/${date}`
})
}
src\views\InterestRate\loans\index.vue
<template>
<div class="container">
<el-form ref="form" :model="form" label-width="80px" :rules="rules">
<el-form-item label="贷款金额" prop="value">
<el-input v-model="form.value"></el-input>
</el-form-item>
<el-form-item label="贷款利率">
<el-input v-model="form.interestRate" disabled>
<template slot="prepend">
<el-button @click="updateList">修改利率</el-button>
</template>
<template slot="append">%</template>
</el-input>
</el-form-item>
<el-form-item label="贷款期限" prop="date">
<el-select v-model="form.date" placeholder="请选择贷款期限" @change="dateChange">
<el-option label="六个月" value="6m"></el-option>
<el-option label="一年" value="1y"></el-option>
<el-option label="一至三年" value="1y-3y"></el-option>
<el-option label="三至五年" value="3y-5y"></el-option>
<el-option label="五年" value="5y"></el-option>
</el-select>
</el-form-item>
<el-form-item label="利息">
<el-input v-model="form.result" disabled></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">立即计算</el-button>
</el-form-item>
</el-form>
<!-- 利率 -->
<el-dialog title="贷款利率" :visible.sync="dialogVisible" width="40%">
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="name" label="类型" width="180">
</el-table-column>
<el-table-column prop="value" label="利率" width="180">
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button type="text" @click="update(scope.row)">修改</el-button>
</template>
</el-table-column>
</el-table>
</el-dialog>
<!-- 修改利率 -->
<el-dialog title="修改利率" :visible.sync="updateDialogVisible" width="30%">
<el-form ref="form" :model="updateForm" label-width="80px">
<el-form-item label="利率类型">
<el-input v-model="updateForm.name"></el-input>
</el-form-item>
<el-form-item label="利率">
<el-input v-model="updateForm.value"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="updateEnter">确认</el-button>
</el-form-item>
</el-form>
</el-dialog>
</div>
</template>
<script>
import { update, list, get } from '@/api/InterestRate/loans.js'
export default {
data() {
return {
form: {
value: '',
interestRate: '',
date: '',
result: ''
},
rules: {
value: [
{ required: true, message: '请输入金额', trigger: 'blur' },
],
date: [
{ required: true, message: '请选择贷款期限', trigger: 'blur' },
]
},
dialogVisible: false,
updateDialogVisible: false,
tableData: [],
updateForm: {
id: '',
value: '',
name: ''
}
}
},
methods: {
async list() {
const { data } = await list()
this.tableData = data;
},
updateList() {
this.list();
this.dialogVisible = true;
},
onSubmit() {
this.$refs.form.validate((valid) => {
if (valid) {
this.form.result = this.form.value * this.form.interestRate * 0.01
}
});
},
update(row) {
const { name, value, id } = row
this.updateForm.name = name
this.updateForm.value = value
this.updateForm.id = id
this.updateDialogVisible = true
},
async updateEnter() {
const result = await update(this.updateForm)
this.list()
this.updateDialogVisible = false
this.$message({
type: 'success',
message: result.msg
})
},
async get(date) {
const { data } = await get(date)
this.form.interestRate = data.value
},
dateChange(date) {
this.get(date)
}
}
}
</script>
<style scoped>
.container {
width: 500px;
padding: 20px;
background-color: rgba(242, 231, 231, 0.627);
border-radius: 20px;
margin: 20px auto;
}
</style>
import request from '@/utils/request'
export function update(data) {
return request({
url: '/interestrate/loans',
method: 'put',
data
})
}
export function list() {
return request({
url: '/interestrate/loans',
})
}
export function get(date) {
return request({
url: `/interestrate/loans/${date}`
})
}
<template>
<div class="container">
<div class="main">
<div class="top">
<span class="expression">
{{ expression }}
</span>
</div>
<div class="body">
<div class="row">
<div class="item item-type2" @click="clickItem('(')">(</div>
<div class="item item-type2" @click="clickItem(')')">)</div>
<div class="item item-type2" @click="clickItem('%')">%</div>
<div class="item item-type3" @click="clickItem('del')">DEL</div>
<div class="item item-type3" @click="clickItem('ac')">AC</div>
<div class="item-count item-type5">已计算:{{ count }}次</div>
</div>
<div class="row">
<div class="item item-type1" @click="clickItem('7')">7</div>
<div class="item item-type1" @click="clickItem('8')">8</div>
<div class="item item-type1" @click="clickItem('9')">9</div>
<div class="item item-type2" @click="clickItem('÷')">÷</div>
<div class="item item-type2" @click="clickItem('sin()')">sin</div>
<div class="item item-type2" @click="clickItem('pow()')">pow</div>
</div>
<div class="row">
<div class="item item-type1" @click="clickItem('4')">4</div>
<div class="item item-type1" @click="clickItem('5')">5</div>
<div class="item item-type1" @click="clickItem('6')">6</div>
<div class="item item-type2" @click="clickItem('x')">x</div>
<div class="item item-type2" @click="clickItem('cos()')">cos</div>
<div class="item item-type2" @click="clickItem('ln()')">ln</div>
</div>
<div class="row">
<div class="item item-type1" @click="clickItem('1')">1</div>
<div class="item item-type1" @click="clickItem('2')">2</div>
<div class="item item-type1" @click="clickItem('3')">3</div>
<div class="item item-type2" @click="clickItem('-')">-</div>
<div class="item item-type2" @click="clickItem('tan()')">tan</div>
<div class="item item-type2" @click="clickItem('√()')">√</div>
</div>
<div class="row">
<div class="item item-type1" @click="clickItem('0')">0</div>
<div class="item item-type1" @click="clickItem('.')">.</div>
<div class="item item-type4" @click="clickItem('=')">=</div>
<div class="item item-type2" @click="clickItem('+')">+</div>
<div class="item item-type1" @click="clickItem('π')">π</div>
<div class="item item-type1" @click="clickItem('e')">e</div>
</div>
</div>
</div>
<div class="list">
<el-table :data="tableData" style="width: 100%" @row-dblclick="clickRow">
<el-table-column label="历史记录" width="180">
<template slot-scope="scope">
<el-tooltip effect="dark" content="双击列表项可替换输入框内容" placement="top">
<span>{{ scope.row.expression }}</span>
</el-tooltip>
</template>
</el-table-column>
</el-table>
</div>
</div>
</template>
<script>
import { calculate, getCount, getHistory } from '@/api/calculator.js';
export default {
data() {
return {
expression: '',
tableData: [],
count: 0
}
},
mounted() {
this.getCount()
this.getHistory()
},
methods: {
clickItem(value) {
if (value === '=') {
this.calculate()
return
}
if (value === 'del') {
this.expression = this.expression.substring(0, this.expression.length - 1)
return
}
if (value === 'ac') {
this.expression = ''
return
}
this.expression = this.expression + value
},
async calculate() {
const { data } = await calculate(this.expression)
this.expression = data
this.getCount()
this.getHistory()
},
async getCount() {
const { data } = await getCount()
this.count = data
},
async getHistory() {
const { data } = await getHistory()
this.tableData = data
},
clickRow(row) {
this.expression = row.expression
}
}
}
</script>
<style scoped>
.container {
width: 800px;
height: 440px;
padding: 20px;
border-radius: 20px;
display: flex;
justify-content: space-between;
background-color: rgba(242, 231, 231, 0.627);
margin: 20px auto;
}
.main {
width: 600px;
margin-right: 20px;
}
.top {
widows: 550px;
height: 100px;
border: 2px solid rgba(174, 169, 169, 0.627);
border-radius: 10px;
background-color: #fff;
line-height: 100px;
}
.expression {
font-size: 24px;
}
.row {
width: 550px;
display: flex;
justify-content: space-between;
margin: 10px 0;
}
.item {
width: 70px;
height: 50px;
border-radius: 10px;
border: 2px solid rgba(174, 169, 169, 0.627);
text-align: center;
line-height: 50px;
font-size: 20px;
font-weight: 700;
}
.item-count {
width: 70px;
height: 50px;
border-radius: 10px;
line-height: 50px;
border: 2px solid rgba(174, 169, 169, 0.627);
text-align: center;
font-size: 10px;
font-weight: 700;
}
.item-type1 {
background-color: #fff;
}
.item-type2 {
background-color: rgba(174, 169, 169, 0.627);
}
.item-type3 {
background-color: #ffb52f;
}
.item-type4 {
background-color: #4f6ef2;
}
.item-type5 {
background-color: rgb(79, 242, 171);
}
.list {
width: 200px;
border: 2px solid rgba(174, 169, 169, 0.627);
border-radius: 10px;
overflow: auto;
}
</style>
import request from '@/utils/request'
export function calculate(data) {
return request({
url: `/calculator`,
method: 'post',
data
})
}
export function getCount() {
return request({
url: '/calculator/count'
})
}
export function getHistory(){
return request({
url: '/calculator/history'
})
}
package com.ruoyi.web.controller.calculator;
import com.ruoyi.calculator.domain.InterestRate;
import com.ruoyi.calculator.service.InterestRateService;
import com.ruoyi.common.core.domain.AjaxResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/interestrate")
public class InterestRateController {
@Autowired
private InterestRateService interestRateService;
@GetMapping("/deposit")
public AjaxResult listDeposit(){
List<InterestRate> list = interestRateService.listDeposit();
return AjaxResult.success(list);
}
@GetMapping("/deposit/{date}")
public AjaxResult getDeposit(@PathVariable String date) {
InterestRate interestRate = interestRateService.getDeposit(date);
return AjaxResult.success(interestRate);
}
@PutMapping("/deposit")
public AjaxResult updateDeposit(@RequestBody InterestRate interestRate){
interestRateService.updateDeposit(interestRate);
return AjaxResult.success("修改成功");
}
@GetMapping("/loans")
public AjaxResult listLoans(){
List<InterestRate> list = interestRateService.listLoans();
return AjaxResult.success(list);
}
@GetMapping("/loans/{date}")
public AjaxResult getLoans(@PathVariable String date) {
InterestRate interestRate = interestRateService.getLoans(date);
return AjaxResult.success(interestRate);
}
@PutMapping("/loans")
public AjaxResult updateLoans(@RequestBody InterestRate interestRate){
interestRateService.updateLoans(interestRate);
return AjaxResult.success("修改成功");
}
}
package com.ruoyi.calculator.service;
import com.ruoyi.calculator.domain.InterestRate;
import java.util.List;
public interface InterestRateService {
List<InterestRate> listDeposit();
void updateDeposit(InterestRate interestRate);
List<InterestRate> listLoans();
void updateLoans(InterestRate interestRate);
InterestRate getDeposit(String date);
InterestRate getLoans(String date);
}
package com.ruoyi.calculator.service.impl;
import com.ruoyi.calculator.domain.InterestRate;
import com.ruoyi.calculator.mapper.InterestRateMapper;
import com.ruoyi.calculator.service.InterestRateService;
import com.ruoyi.common.constant.CalculateConstants;
import com.ruoyi.common.context.BaseContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class InterestRateServiceImpl implements InterestRateService {
@Autowired
private InterestRateMapper interestRateMapper;
@Override
public List<InterestRate> listDeposit() {
return interestRateMapper.list(CalculateConstants.DEPOSIT, BaseContext.getCurrentId());
}
@Override
public void updateDeposit(InterestRate interestRate) {
interestRateMapper.update(interestRate);
}
@Override
public List<InterestRate> listLoans() {
return interestRateMapper.list(CalculateConstants.LOANS, BaseContext.getCurrentId());
}
@Override
public void updateLoans(InterestRate interestRate) {
interestRateMapper.update(interestRate);
}
@Override
public InterestRate getDeposit(String date) {
InterestRate interestRate = interestRateMapper.get(CalculateConstants.DEPOSIT, date, BaseContext.getCurrentId());
return interestRate;
}
@Override
public InterestRate getLoans(String date) {
InterestRate interestRate = interestRateMapper.get(CalculateConstants.LOANS, date, BaseContext.getCurrentId());
return interestRate;
}
}
package com.ruoyi.calculator.mapper;
import com.ruoyi.calculator.domain.InterestRate;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface InterestRateMapper {
List<InterestRate> list(@Param("type") int type, @Param("userId") long userId);
void update(@Param("interestRate") InterestRate interestRate);
void init(long userId);
InterestRate get(@Param("type") Integer type, @Param("date") String date, @Param("userId") Long currentId);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.calculator.mapper.InterestRateMapper">
<insert id="init">
insert into interest_rate (user_id, name, tag, type, value)
values (#{userId}, '活期', 'hq', 1, 0.50),
(#{userId}, '三个月', '3M', 1, 2.85),
(#{userId}, '六个月', '6M', 1, 3.05),
(#{userId}, '一年', '1y', 1, 3.25),
(#{userId}, '二年', '2y', 1, 4.15),
(#{userId}, '三年', '3y', 1, 4.75),
(#{userId}, '五年', '5y', 1, 5.25),
(#{userId}, '六个月', '6M', 2, 5.85),
(#{userId}, '一年', '1y', 2, 6.31),
(#{userId}, '一至三年', '1y-3y', 2, 6.40),
(#{userId}, '三至五年', '3y-5y', 2, 6.65),
(#{userId}, '五年', '5y', 2, 6.80);
</insert>
<update id="update">
update interest_rate
set name = #{interestRate.name},
value = #{interestRate.value}
where id = #{interestRate.id}
</update>
<select id="list" resultType="com.ruoyi.calculator.domain.InterestRate">
select * from interest_rate
where type = #{type} and user_id = #{userId}
</select>
<select id="get" resultType="com.ruoyi.calculator.domain.InterestRate">
select *
from interest_rate
where
type = #{type}
and user_id = #{userId}
and tag = #{date}
</select>
</mapper>
package com.ruoyi.web.controller.calculator;
import com.ruoyi.calculator.domain.CalculatorHistory;
import com.ruoyi.calculator.service.CalculatorService;
import com.ruoyi.common.core.domain.AjaxResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/calculator")
public class CalculatorController {
@Autowired
private CalculatorService calculatorService;
@PostMapping
public AjaxResult calculate(@RequestBody String expression) {
String result = calculatorService.calculate(expression);
return AjaxResult.success((Object) result);
}
@GetMapping("/count")
public AjaxResult getCount() {
long count = calculatorService.getCuont();
return AjaxResult.success(count);
}
@GetMapping("/history")
public AjaxResult getHistory() {
List<CalculatorHistory> list = calculatorService.getHistory();
return AjaxResult.success(list);
}
}
package com.ruoyi.calculator.service;
import com.ruoyi.calculator.domain.CalculatorHistory;
import java.util.List;
public interface CalculatorService {
String calculate(String expression);
long getCuont();
List<CalculatorHistory> getHistory();
}
package com.ruoyi.calculator.service.impl;
import com.ruoyi.calculator.domain.CalculatorHistory;
import com.ruoyi.calculator.mapper.CalculatorMapper;
import com.ruoyi.calculator.service.CalculatorService;
import com.ruoyi.common.context.BaseContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.util.List;
@Service
public class CalculatorServiceImpl implements CalculatorService {
@Autowired
private CalculatorMapper calculatorMapper;
@Override
public String calculate(String expression) {
calculatorMapper.add(BaseContext.getCurrentId(), expression);
expression = expression
.replaceAll("x", "*")
.replaceAll("÷", "/")
.replaceAll("π", "Math.PI")
.replaceAll("sin", "Math.sin")
.replaceAll("cos", "Math.cos")
.replaceAll("tan", "Math.tan")
.replaceAll("√", "Math.sqrt")
.replaceAll("e", "Math.E")
.replaceAll("ln", "Math.log")
.replaceAll("pow", "Math.pow");
String result;
try {
result = execute(expression);
} catch (ScriptException e) {
result = "ERROR";
}
return result;
}
@Override
public long getCuont() {
return calculatorMapper.count(BaseContext.getCurrentId());
}
@Override
public List<CalculatorHistory> getHistory() {
return calculatorMapper.listHistory(BaseContext.getCurrentId());
}
private String execute(String str) throws ScriptException {
ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");
return jse.eval(str).toString();
}
}
package com.ruoyi.calculator.mapper;
import com.ruoyi.calculator.domain.CalculatorHistory;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface CalculatorMapper {
long count(long userId);
void add(@Param("userId") long userId, @Param("expression") String expression);
List<CalculatorHistory> listHistory(Long userId);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.calculator.mapper.CalculatorMapper">
<insert id="add">
insert into calculator_history (user_id, expression)
value (#{userId}, #{expression})
</insert>
<select id="count" resultType="java.lang.Long">
select count(id)
from calculator_history
where user_id = #{userId}
</select>
<select id="listHistory" resultType="com.ruoyi.calculator.domain.CalculatorHistory">
select * from calculator_history
where user_id = #{userId}
order by id desc
</select>
</mapper>
字段名 | 数据类型 | 约束 | 备注 |
---|---|---|---|
id | bigint | primary key | |
user_id | bigint | not null | 用户id |
name | varchar(20) | not null | 利率名称 |
tag | varchar(20) | not null | 利率标识 |
value | decimal(5,2) | not null | 利率 |
type | int | not null | 利率类型。 1:存款利率 2:贷款利率 |
字段名 | 数据类型 | 约束 | 备注 |
---|---|---|---|
id | bigint | primary key | |
user_id | bigint | not null | 用户id |
expression | varchar(255) | not null | 表达式 |
s-3-mapper.dtd">
insert into calculator_history (user_id, expression)
value (#{userId}, #{expression})
<select id="count" resultType="java.lang.Long">
select count(id)
from calculator_history
where user_id = #{userId}
</select>
<select id="listHistory" resultType="com.ruoyi.calculator.domain.CalculatorHistory">
select * from calculator_history
where user_id = #{userId}
order by id desc
</select>
```
Student ID | Work Description | Contribution |
---|---|---|
832101227 | Front-end: routing, login, registration | 15% |
832101224 | Frontend: Interest Rate Calculator - Loan - Page Structure | 5% |
832101212 | Frontend: Interest Rate Calculator - Loan - Interface | 9% |
832101213 | Frontend: Scientific Calculator - page structure | 5% |
832101208 | Backend: Database Front-end: interest rate calculator - deposits - page structure Frontend: Interest Rate Calculator - Deposit - Interface | 15% |
832101226 | Frontend: Scientific Calculator - Interface | 5% |
832101228 | Backend: Login Registration Backend: Scientific Calculator - mapper | 7% |
832101218 | Backend : Interest Rate Calculator - controller Backend: Scientific Calculator - service | 7% |
832101216 | Backend : Interest Rate Calculator - service Backend : Interest Rate Calculator - servicelmpl | 7% |
832101222 | Backend: Scientific Calculator -- mapper.xml | 9% |
832101205 | Backend : Interest Rate Calculator - mapper Backend : Interest Rate Calculator -- mapper.xml | 9% |
832101206 | Backend: Interest Rate Calculator - service Backend : Scientific Calculator -- servicelmpl | 9% |
82101218写错了,应为832101215