29 changed files with 4722 additions and 92 deletions
-
130414/src/api/goldBeanDetail.ts
-
270414/src/components/DetailTable.vue
-
230414/src/components/Navbar.vue
-
630414/src/components/SearchForm.vue
-
680414/src/views/GoldBeanDetail.vue
-
1120414/src/views/fuzhu.vue
-
30250415/.gitignore
-
3250415/.vscode/extensions.json
-
33250415/README.md
-
10250415/env.d.ts
-
13250415/index.html
-
3667250415/package-lock.json
-
30250415/package.json
-
BIN250415/public/favicon.ico
-
23250415/src/App.vue
-
86250415/src/assets/base.css
-
1250415/src/assets/logo.svg
-
48250415/src/assets/main.css
-
32250415/src/components/Navigation.vue
-
12250415/src/main.ts
-
36250415/src/router/index.js
-
110250415/src/views/Recharge.vue
-
158250415/src/views/RechargeApproval.vue
-
129250415/src/views/Refund.vue
-
9250415/src/views/RefundApproval.vue
-
12250415/tsconfig.app.json
-
11250415/tsconfig.json
-
19250415/tsconfig.node.json
-
18250415/vite.config.ts
@ -1,14 +1,15 @@ |
|||
import axios from 'axios'; |
|||
|
|||
// 后端接口地址
|
|||
const API_BASE_URL = ''; |
|||
const API_BASE_URL = 'http://192.168.8.94:5173'; |
|||
|
|||
// 获取金豆明细数据
|
|||
export const getGoldBeanDetail = async (params: any) => { |
|||
console.log('请求参数:', params); |
|||
try { |
|||
|
|||
const response = await axios.get(``, { params }); |
|||
return response.data; |
|||
const response = await axios.post(`${API_BASE_URL}/recharges/query`, params); |
|||
console.log('完整响应数据:', response.data); |
|||
const list = response.data.items || []; |
|||
const total = response.data.total || 0; |
|||
return { list, total }; |
|||
} catch (error) { |
|||
console.error('获取金豆明细数据失败', error); |
|||
throw error; |
|||
|
@ -0,0 +1,112 @@ |
|||
<template> |
|||
<div class="detail-container"> |
|||
<!-- 使用 el-card 包裹搜索表单 --> |
|||
<el-card class="search-form-container"> |
|||
<SearchForm @search="handleSearch" ref="searchForm" /> |
|||
</el-card> |
|||
<!-- 使用 el-card 包裹表格 --> |
|||
<el-card class="detail-table-container"> |
|||
<DetailTable :tableData="tableData" /> |
|||
</el-card> |
|||
<!-- 美化分页器样式 --> |
|||
<div class="pagination-container"> |
|||
<el-pagination |
|||
@size-change="handleSizeChange" |
|||
@current-change="handleCurrentChange" |
|||
:current-page="currentPage" |
|||
:page-sizes="[8, 10, 20]" |
|||
:page-size="pageSize" |
|||
layout="total, sizes, prev, pager, next, jumper" |
|||
:total="total" |
|||
/> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import SearchForm from '../components/SearchForm.vue'; |
|||
import DetailTable from '../components/DetailTable.vue'; |
|||
import { getGoldBeanDetail } from '../api/goldBeanDetail'; |
|||
|
|||
export default { |
|||
components: { |
|||
SearchForm, |
|||
DetailTable |
|||
}, |
|||
data() { |
|||
return { |
|||
tableData: [], |
|||
currentPage: 2, |
|||
pageSize: 8, |
|||
total: 0 |
|||
}; |
|||
}, |
|||
async created() { |
|||
await this.handleSearch({ |
|||
jwcode: '', |
|||
region: '', |
|||
orderId: '', |
|||
paymentMethod: '', |
|||
page: this.currentPage, |
|||
size: this.pageSize |
|||
}); |
|||
}, |
|||
methods: { |
|||
async handleSearch(params) { |
|||
try { |
|||
const data = await getGoldBeanDetail(params); |
|||
this.tableData = data.list || []; |
|||
this.total = data.total || 0; |
|||
this.currentPage = params.page; |
|||
this.pageSize = params.size; |
|||
} catch (error) { |
|||
console.error('查询失败', error); |
|||
} |
|||
}, |
|||
handleSizeChange(newSize) { |
|||
this.pageSize = newSize; |
|||
this.handleSearch({ |
|||
jwcode: this.$refs.searchForm?.form?.jwcode || '', |
|||
region: this.$refs.searchForm?.form?.region || '', |
|||
orderId: this.$refs.searchForm?.form?.orderId || '', |
|||
paymentMethod: this.$refs.searchForm?.form?.paymentMethod || '', |
|||
page: this.currentPage, |
|||
size: newSize |
|||
}); |
|||
}, |
|||
handleCurrentChange(newPage) { |
|||
this.currentPage = newPage; |
|||
this.handleSearch({ |
|||
jwcode: this.$refs.searchForm?.form?.jwcode || '', |
|||
region: this.$refs.searchForm?.form?.region || '', |
|||
orderId: this.$refs.searchForm?.form?.orderId || '', |
|||
paymentMethod: this.$refs.searchForm?.form?.paymentMethod || '', |
|||
page: newPage, |
|||
size: this.pageSize |
|||
}); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.detail-container { |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 20px; /* 添加间距 */ |
|||
padding: 20px; |
|||
} |
|||
|
|||
.search-form-container { |
|||
width: 100%; |
|||
} |
|||
|
|||
.detail-table-container { |
|||
width: 100%; |
|||
} |
|||
|
|||
.pagination-container { |
|||
display: flex; |
|||
justify-content: center; /* 分页器居中 */ |
|||
} |
|||
</style> |
@ -0,0 +1,30 @@ |
|||
# Logs |
|||
logs |
|||
*.log |
|||
npm-debug.log* |
|||
yarn-debug.log* |
|||
yarn-error.log* |
|||
pnpm-debug.log* |
|||
lerna-debug.log* |
|||
|
|||
node_modules |
|||
.DS_Store |
|||
dist |
|||
dist-ssr |
|||
coverage |
|||
*.local |
|||
|
|||
/cypress/videos/ |
|||
/cypress/screenshots/ |
|||
|
|||
# Editor directories and files |
|||
.vscode/* |
|||
!.vscode/extensions.json |
|||
.idea |
|||
*.suo |
|||
*.ntvs* |
|||
*.njsproj |
|||
*.sln |
|||
*.sw? |
|||
|
|||
*.tsbuildinfo |
@ -0,0 +1,3 @@ |
|||
{ |
|||
"recommendations": ["Vue.volar"] |
|||
} |
@ -0,0 +1,33 @@ |
|||
# 250414 |
|||
|
|||
This template should help get you started developing with Vue 3 in Vite. |
|||
|
|||
## Recommended IDE Setup |
|||
|
|||
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur). |
|||
|
|||
## Type Support for `.vue` Imports in TS |
|||
|
|||
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types. |
|||
|
|||
## Customize configuration |
|||
|
|||
See [Vite Configuration Reference](https://vite.dev/config/). |
|||
|
|||
## Project Setup |
|||
|
|||
```sh |
|||
npm install |
|||
``` |
|||
|
|||
### Compile and Hot-Reload for Development |
|||
|
|||
```sh |
|||
npm run dev |
|||
``` |
|||
|
|||
### Type-Check, Compile and Minify for Production |
|||
|
|||
```sh |
|||
npm run build |
|||
``` |
@ -0,0 +1,10 @@ |
|||
/// <reference types="vite/client" />
|
|||
declare module "*.vue" { |
|||
|
|||
import Vue from 'vue'; |
|||
|
|||
export default Vue; |
|||
|
|||
} |
|||
|
|||
declare module '*.js'; |
@ -0,0 +1,13 @@ |
|||
<!DOCTYPE html> |
|||
<html lang=""> |
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<link rel="icon" href="/favicon.ico"> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|||
<title>Vite App</title> |
|||
</head> |
|||
<body> |
|||
<div id="app"></div> |
|||
<script type="module" src="/src/main.ts"></script> |
|||
</body> |
|||
</html> |
3667
250415/package-lock.json
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,30 @@ |
|||
{ |
|||
"name": "250414", |
|||
"version": "0.0.0", |
|||
"private": true, |
|||
"type": "module", |
|||
"scripts": { |
|||
"dev": "vite", |
|||
"build": "run-p type-check \"build-only {@}\" --", |
|||
"preview": "vite preview", |
|||
"build-only": "vite build", |
|||
"type-check": "vue-tsc --build" |
|||
}, |
|||
"dependencies": { |
|||
"axios": "^1.8.4", |
|||
"element-plus": "^2.9.7", |
|||
"vue": "^3.5.13", |
|||
"vue-router": "^4.5.0" |
|||
}, |
|||
"devDependencies": { |
|||
"@tsconfig/node22": "^22.0.1", |
|||
"@types/node": "^22.14.0", |
|||
"@vitejs/plugin-vue": "^5.2.3", |
|||
"@vue/tsconfig": "^0.7.0", |
|||
"npm-run-all2": "^7.0.2", |
|||
"typescript": "~5.8.0", |
|||
"vite": "^6.2.4", |
|||
"vite-plugin-vue-devtools": "^7.7.2", |
|||
"vue-tsc": "^2.2.8" |
|||
} |
|||
} |
@ -0,0 +1,23 @@ |
|||
<template> |
|||
<div class="layout"> |
|||
<Navigation /> |
|||
<div class="main-content"> |
|||
<router-view /> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import Navigation from './components/Navigation.vue' |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.layout { |
|||
display: flex; |
|||
} |
|||
|
|||
.main-content { |
|||
flex: 1; |
|||
padding: 20px; |
|||
} |
|||
</style> |
@ -0,0 +1,86 @@ |
|||
/* color palette from <https://github.com/vuejs/theme> */ |
|||
:root { |
|||
--vt-c-white: #ffffff; |
|||
--vt-c-white-soft: #f8f8f8; |
|||
--vt-c-white-mute: #f2f2f2; |
|||
|
|||
--vt-c-black: #181818; |
|||
--vt-c-black-soft: #222222; |
|||
--vt-c-black-mute: #282828; |
|||
|
|||
--vt-c-indigo: #2c3e50; |
|||
|
|||
--vt-c-divider-light-1: rgba(60, 60, 60, 0.29); |
|||
--vt-c-divider-light-2: rgba(60, 60, 60, 0.12); |
|||
--vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); |
|||
--vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); |
|||
|
|||
--vt-c-text-light-1: var(--vt-c-indigo); |
|||
--vt-c-text-light-2: rgba(60, 60, 60, 0.66); |
|||
--vt-c-text-dark-1: var(--vt-c-white); |
|||
--vt-c-text-dark-2: rgba(235, 235, 235, 0.64); |
|||
} |
|||
|
|||
/* semantic color variables for this project */ |
|||
:root { |
|||
--color-background: var(--vt-c-white); |
|||
--color-background-soft: var(--vt-c-white-soft); |
|||
--color-background-mute: var(--vt-c-white-mute); |
|||
|
|||
--color-border: var(--vt-c-divider-light-2); |
|||
--color-border-hover: var(--vt-c-divider-light-1); |
|||
|
|||
--color-heading: var(--vt-c-text-light-1); |
|||
--color-text: var(--vt-c-text-light-1); |
|||
|
|||
--section-gap: 160px; |
|||
} |
|||
|
|||
@media (prefers-color-scheme: dark) { |
|||
:root { |
|||
--color-background: var(--vt-c-black); |
|||
--color-background-soft: var(--vt-c-black-soft); |
|||
--color-background-mute: var(--vt-c-black-mute); |
|||
|
|||
--color-border: var(--vt-c-divider-dark-2); |
|||
--color-border-hover: var(--vt-c-divider-dark-1); |
|||
|
|||
--color-heading: var(--vt-c-text-dark-1); |
|||
--color-text: var(--vt-c-text-dark-2); |
|||
} |
|||
} |
|||
|
|||
*, |
|||
*::before, |
|||
*::after { |
|||
box-sizing: border-box; |
|||
margin: 0; |
|||
font-weight: normal; |
|||
} |
|||
|
|||
body { |
|||
min-height: 100vh; |
|||
color: var(--color-text); |
|||
background: var(--color-background); |
|||
transition: |
|||
color 0.5s, |
|||
background-color 0.5s; |
|||
line-height: 1.6; |
|||
font-family: |
|||
Inter, |
|||
-apple-system, |
|||
BlinkMacSystemFont, |
|||
'Segoe UI', |
|||
Roboto, |
|||
Oxygen, |
|||
Ubuntu, |
|||
Cantarell, |
|||
'Fira Sans', |
|||
'Droid Sans', |
|||
'Helvetica Neue', |
|||
sans-serif; |
|||
font-size: 15px; |
|||
text-rendering: optimizeLegibility; |
|||
-webkit-font-smoothing: antialiased; |
|||
-moz-osx-font-smoothing: grayscale; |
|||
} |
@ -0,0 +1 @@ |
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg> |
@ -0,0 +1,48 @@ |
|||
@import './base.css'; |
|||
|
|||
#app { |
|||
max-width: 1280px; |
|||
margin: 0 auto; |
|||
padding: 2rem; |
|||
font-weight: normal; |
|||
} |
|||
|
|||
a, |
|||
.green { |
|||
text-decoration: none; |
|||
color: hsla(160, 100%, 37%, 1); |
|||
transition: 0.4s; |
|||
padding: 3px; |
|||
} |
|||
|
|||
@media (hover: hover) { |
|||
a:hover { |
|||
background-color: hsla(160, 100%, 37%, 0.2); |
|||
} |
|||
} |
|||
|
|||
@media (min-width: 1024px) { |
|||
body { |
|||
display: flex; |
|||
place-items: center; |
|||
} |
|||
|
|||
#app { |
|||
display: grid; |
|||
grid-template-columns: 1fr 1fr; |
|||
padding: 0 2rem; |
|||
} |
|||
} |
|||
|
|||
.layout { |
|||
display: flex; |
|||
} |
|||
|
|||
.sidebar { |
|||
min-width: 200px; |
|||
} |
|||
|
|||
.main-content { |
|||
flex: 1; |
|||
padding: 20px; |
|||
} |
@ -0,0 +1,32 @@ |
|||
<template> |
|||
<el-menu |
|||
default-active="recharge-approval" |
|||
class="el-menu-vertical-demo" |
|||
@select="handleSelect" |
|||
background-color="#545c64" |
|||
text-color="#fff" |
|||
> |
|||
<el-menu-item index="recharge">充值</el-menu-item> |
|||
<el-menu-item index="refund">退款</el-menu-item> |
|||
<el-menu-item index="recharge-approval">充值审批</el-menu-item> |
|||
<el-menu-item index="refund-approval">退款审批</el-menu-item> |
|||
</el-menu> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { useRouter } from 'vue-router' |
|||
|
|||
const router = useRouter() |
|||
|
|||
const handleSelect = (key) => { |
|||
// 将连字符去掉并将每个单词的首字母大写 |
|||
const routeName = key.split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join('') |
|||
router.push({ name: routeName }) |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.el-menu-vertical-demo { |
|||
width: 200px; |
|||
} |
|||
</style> |
@ -0,0 +1,12 @@ |
|||
import { createApp } from 'vue'; |
|||
import App from './App.vue'; |
|||
import router from './router/index.js'; |
|||
import ElementPlus from 'element-plus'; |
|||
import 'element-plus/dist/index.css'; |
|||
|
|||
|
|||
const app = createApp(App); |
|||
app.use(router); |
|||
app.use(ElementPlus); |
|||
app.mount('#app'); |
|||
|
@ -0,0 +1,36 @@ |
|||
// src/router/index.js
|
|||
import { createRouter, createWebHistory } from 'vue-router' |
|||
import RechargeApproval from '../views/RechargeApproval.vue' |
|||
import Recharge from '../views/Recharge.vue' |
|||
import Refund from '../views/Refund.vue' |
|||
import RefundApproval from '../views/RefundApproval.vue' |
|||
|
|||
const routes = [ |
|||
{ |
|||
path: '/recharge-approval', |
|||
name: 'RechargeApproval', |
|||
component: RechargeApproval |
|||
}, |
|||
{ |
|||
path: '/recharge', |
|||
name: 'Recharge', |
|||
component: Recharge |
|||
}, |
|||
{ |
|||
path: '/refund', |
|||
name: 'Refund', |
|||
component: Refund |
|||
}, |
|||
{ |
|||
path: '/refund-approval', |
|||
name: 'RefundApproval', |
|||
component: RefundApproval |
|||
} |
|||
] |
|||
|
|||
const router = createRouter({ |
|||
history: createWebHistory(), |
|||
routes |
|||
}) |
|||
|
|||
export default router |
@ -0,0 +1,110 @@ |
|||
<template> |
|||
<div> |
|||
<h1>充值申请</h1> |
|||
<el-form :model="rechargeForm" @submit.prevent="submitRecharge" label-width="120px"> |
|||
<el-form-item label="精网号"> |
|||
<!-- 将 @input 替换为 @blur 事件 --> |
|||
<el-input v-model="rechargeForm.netId" @blur="checkJwcode" required style="width: 150px;"></el-input> |
|||
<!-- 根据检查结果显示提示信息 --> |
|||
<span v-if="jwcodeCheckResult !== null"> |
|||
{{ jwcodeCheckResult ? '精网号存在' : '该精网号不存在' }} |
|||
</span> |
|||
</el-form-item> |
|||
<!-- 其他表单项保持不变 --> |
|||
<el-form-item label="充值金额"> |
|||
<el-input-number v-model="rechargeForm.amount" :min="0" required></el-input-number> |
|||
</el-form-item> |
|||
<el-form-item label="支付方式"> |
|||
<el-select v-model="rechargeForm.paymentMethod" placeholder="请选择支付方式" required style="width: 150px;"> |
|||
<el-option label="微信" value="wechat"></el-option> |
|||
<el-option label="支付宝" value="alipay"></el-option> |
|||
<el-option label="银行卡" value="bankCard"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="备注"> |
|||
<el-input v-model="rechargeForm.remark" type="textarea" style="width: 150px;"></el-input> |
|||
</el-form-item> |
|||
<el-form-item> |
|||
<el-button type="primary" native-type="submit">提交申请</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { ref } from 'vue'; |
|||
import axios from 'axios'; |
|||
import { ElMessage } from 'element-plus'; |
|||
|
|||
// 定义充值表单数据 |
|||
const rechargeForm = ref({ |
|||
netId: '', |
|||
amount: 0, |
|||
paymentMethod: '', |
|||
remark: '' |
|||
}); |
|||
|
|||
// 存储精网号检查结果 |
|||
const jwcodeCheckResult = ref(null); |
|||
|
|||
// 检查精网号是否存在的方法 |
|||
const checkJwcode = async () => { |
|||
const jwcode = rechargeForm.value.netId; |
|||
if (jwcode) { |
|||
try { |
|||
// 发送 GET 请求检查精网号 |
|||
const response = await axios.get(`http://192.168.8.108:5173/recharges/checkJwcode/${jwcode}`); |
|||
// 假设后端返回布尔值表示是否存在 |
|||
jwcodeCheckResult.value = response.data; |
|||
} catch (error) { |
|||
console.error('检查精网号时出错:', error); |
|||
jwcodeCheckResult.value = null; |
|||
} |
|||
} else { |
|||
jwcodeCheckResult.value = null; |
|||
} |
|||
}; |
|||
|
|||
// 处理充值申请提交 |
|||
const submitRecharge = async () => { |
|||
if (jwcodeCheckResult.value === false) { |
|||
ElMessage.error('精网号不存在,无法提交申请'); |
|||
return; |
|||
} |
|||
|
|||
try { |
|||
// 构造要提交的数据 |
|||
const postData = { |
|||
jwcode: rechargeForm.value.netId, |
|||
amount: rechargeForm.value.amount, |
|||
paymentMethod: rechargeForm.value.paymentMethod, |
|||
notes: rechargeForm.value.remark |
|||
}; |
|||
|
|||
// 发送 POST 请求 |
|||
const response = await axios.post('http://192.168.8.108:5173/recharges/add/addRecharges', postData); |
|||
|
|||
// 处理响应 |
|||
if (response.status === 200) { |
|||
ElMessage.success('充值申请提交成功'); |
|||
// 清空表单 |
|||
rechargeForm.value = { |
|||
netId: '', |
|||
amount: 0, |
|||
paymentMethod: '', |
|||
remark: '' |
|||
}; |
|||
jwcodeCheckResult.value = null; |
|||
} else { |
|||
ElMessage.error('充值申请提交失败,请重试'); |
|||
} |
|||
} catch (error) { |
|||
console.error('提交充值申请时出错:', error); |
|||
ElMessage.error('提交充值申请时出错,请检查网络或联系管理员'); |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped> |
|||
/* 若充值审核页面有特殊样式,可在这里添加相同样式 */ |
|||
</style> |
@ -0,0 +1,158 @@ |
|||
<template> |
|||
<div> |
|||
<el-form :inline="true" :model="queryParams" class="demo-form-inline"> |
|||
<el-form-item label="精网号"> |
|||
<el-input v-model="queryParams.jwcode" placeholder="请输入精网号"></el-input> |
|||
</el-form-item> |
|||
<el-form-item label="状态"> |
|||
<el-select v-model="queryParams.status" placeholder="请选择状态"> |
|||
<el-option label="待审批" value="0"></el-option> |
|||
<el-option label="审批通过" value="1"></el-option> |
|||
<el-option label="审批驳回" value="2"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item> |
|||
<el-button type="primary" @click="fetchOrders">查询</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
<el-table :data="orders" stripe> |
|||
<el-table-column prop="id" label="序号"></el-table-column> |
|||
<el-table-column prop="姓名" label="姓名"></el-table-column> |
|||
<el-table-column prop="jwcode" label="精网号"></el-table-column> |
|||
<el-table-column prop="order_id" label="订单号"></el-table-column> |
|||
<el-table-column prop="amount" label="金额"></el-table-column> |
|||
<el-table-column prop="payment_method" label="支付方式"></el-table-column> |
|||
<el-table-column prop="notes" label="备注"></el-table-column> |
|||
<el-table-column prop="status" label="状态"> |
|||
<template #default="{ row }"> |
|||
<span v-if="row.status === 0">待审批</span> |
|||
<span v-if="row.status === 1">审批通过</span> |
|||
<span v-if="row.status === 2">审批驳回</span> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="所属地区" label="所属地区"></el-table-column> |
|||
<el-table-column label="操作"> |
|||
<template #default="{ row }"> |
|||
<el-button |
|||
v-if="row.status === 0" |
|||
type="success" |
|||
@click="approveOrder(row.id)" |
|||
:disabled="row.disabled" |
|||
> |
|||
审批通过 |
|||
</el-button> |
|||
<el-button |
|||
v-if="row.status === 0" |
|||
type="danger" |
|||
@click="rejectOrder(row.id)" |
|||
:disabled="row.disabled" |
|||
> |
|||
驳回 |
|||
</el-button> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
<el-pagination |
|||
@size-change="handleSizeChange" |
|||
@current-change="handleCurrentChange" |
|||
:current-page="queryParams.offset / queryParams.size + 1" |
|||
:page-sizes="[10, 20, 100]" |
|||
:page-size="queryParams.size" |
|||
layout="total, sizes, prev, pager, next, jumper" |
|||
:total="total" |
|||
> |
|||
</el-pagination> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { ref, onMounted } from 'vue' |
|||
import axios from 'axios' |
|||
import { ElMessage } from 'element-plus'; |
|||
|
|||
const queryParams = ref({ |
|||
jwcode: '', |
|||
status: null, |
|||
size: 10, |
|||
offset: 0 |
|||
}) |
|||
|
|||
const orders = ref([]) |
|||
const total = ref(0) |
|||
|
|||
const fetchOrders = async () => { |
|||
try { |
|||
const response = await axios.post('http://192.168.8.94:5173/recharges/getall', queryParams.value) |
|||
console.log('接口返回的数据:', response.data.items) |
|||
if (Array.isArray(response.data.items)) { |
|||
orders.value = response.data.items.map(order => ({ |
|||
...order, |
|||
disabled: order.status !== 0 |
|||
})) |
|||
} else { |
|||
const dataArray = response.data.data || [] |
|||
orders.value = dataArray.map(order => ({ |
|||
...order, |
|||
disabled: order.status !== 0 |
|||
})) |
|||
} |
|||
// 从服务器端获取总数据量 |
|||
total.value = response.data.total || 0 |
|||
console.log('更新后的 orders 数据:', orders.value) |
|||
} catch (error) { |
|||
console.error('获取订单失败:', error) |
|||
} |
|||
} |
|||
|
|||
const approveOrder = async (id) => { |
|||
try { |
|||
await axios.post(`http://192.168.8.94:5173/recharges/approve/${id}`) |
|||
const index = orders.value.findIndex(order => order.id === id) |
|||
if (index !== -1) { |
|||
orders.value[index].status = 1 |
|||
orders.value[index].disabled = true |
|||
} |
|||
ElMessage.success('订单审批通过'); |
|||
} catch (error) { |
|||
console.error('审批通过失败:', error) |
|||
ElMessage.error('审批通过失败,请重试'); |
|||
} |
|||
} |
|||
|
|||
const rejectOrder = async (id) => { |
|||
try { |
|||
await axios.post(`http://192.168.8.94:5173/recharges/reject/${id}`) |
|||
const index = orders.value.findIndex(order => order.id === id) |
|||
if (index !== -1) { |
|||
orders.value[index].status = 2 |
|||
orders.value[index].disabled = true |
|||
} |
|||
ElMessage.success('订单已驳回'); |
|||
} catch (error) { |
|||
console.error('审批驳回失败:', error) |
|||
ElMessage.error('审批驳回失败,请重试'); |
|||
} |
|||
} |
|||
|
|||
const handleSizeChange = (newSize) => { |
|||
queryParams.value.size = newSize |
|||
queryParams.value.offset = 0 |
|||
fetchOrders() |
|||
} |
|||
|
|||
const handleCurrentChange = (newPage) => { |
|||
queryParams.value.offset = (newPage - 1) * queryParams.value.size |
|||
fetchOrders() |
|||
} |
|||
|
|||
onMounted(() => { |
|||
// 点击左侧导航栏的充值审批时,查询所有充值订单 |
|||
queryParams.value.jwcode = '' |
|||
queryParams.value.status = null |
|||
fetchOrders() |
|||
}) |
|||
</script> |
|||
|
|||
<style scoped> |
|||
/* 可以根据需要保留或添加其他样式 */ |
|||
</style> |
@ -0,0 +1,129 @@ |
|||
<template> |
|||
<div> |
|||
<h1>退款审核申请</h1> |
|||
<el-form :model="refundForm" @submit.prevent="submitRefund" label-width="120px"> |
|||
<el-form-item label="精网号"> |
|||
<el-input v-model="refundForm.jwcode" @blur="checkJwcode" required style="width: 150px;"></el-input> |
|||
<span v-if="jwcodeCheckResult !== null"> |
|||
{{ jwcodeCheckResult ? '精网号存在' : '该精网号不存在' }} |
|||
</span> |
|||
</el-form-item> |
|||
<el-form-item label="订单号"> |
|||
<el-select v-model="refundForm.orderId" placeholder="请选择订单号" style="width: 150px;"> |
|||
<el-option |
|||
v-for="order in orderList" |
|||
:key="order.orderId" |
|||
:label="order.orderId" |
|||
:value="order.orderId"> |
|||
</el-option> |
|||
</el-select> |
|||
<el-button @click="fetchOrderList">查询订单号</el-button> |
|||
</el-form-item> |
|||
<el-form-item label="备注"> |
|||
<el-input v-model="refundForm.remark" type="textarea" style="width: 150px;"></el-input> |
|||
</el-form-item> |
|||
<el-form-item> |
|||
<el-button type="primary" native-type="submit">提交申请</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { ref } from 'vue'; |
|||
import axios from 'axios'; |
|||
import { ElMessage } from 'element-plus'; |
|||
|
|||
// 定义退款表单数据 |
|||
const refundForm = ref({ |
|||
jwcode: '', |
|||
orderId: '', |
|||
remark: '' |
|||
}); |
|||
|
|||
// 存储精网号检查结果 |
|||
const jwcodeCheckResult = ref(null); |
|||
// 存储订单列表 |
|||
const orderList = ref([]); |
|||
|
|||
// 检查精网号是否存在的方法 |
|||
const checkJwcode = async () => { |
|||
const jwcode = refundForm.value.jwcode; |
|||
if (jwcode) { |
|||
try { |
|||
const response = await axios.get(`http://192.168.8.94:5173/recharges/checkJwcode/${jwcode}`); |
|||
jwcodeCheckResult.value = response.data; |
|||
} catch (error) { |
|||
console.error('检查精网号时出错:', error); |
|||
jwcodeCheckResult.value = null; |
|||
} |
|||
} else { |
|||
jwcodeCheckResult.value = null; |
|||
} |
|||
}; |
|||
|
|||
// 根据精网号查询订单列表的方法 |
|||
const fetchOrderList = async () => { |
|||
const jwcode = refundForm.value.jwcode; |
|||
if (!jwcode) { |
|||
ElMessage.warning('请先输入精网号'); |
|||
return; |
|||
} |
|||
try { |
|||
const response = await axios.get(`http://192.168.8.94:5173/refunds/add/getOrderIds?jwcode=${jwcode}`); |
|||
orderList.value = response.data.map(orderId => ({ orderId })); |
|||
if (orderList.value.length === 0) { |
|||
ElMessage.info('未查询到符合条件的订单号'); |
|||
} |
|||
} catch (error) { |
|||
console.error('查询订单号时出错:', error); |
|||
ElMessage.error('查询订单号时出错,请检查网络或联系管理员'); |
|||
} |
|||
}; |
|||
|
|||
// 处理退款申请提交 |
|||
const submitRefund = async () => { |
|||
if (jwcodeCheckResult.value === false) { |
|||
ElMessage.error('精网号不存在,无法提交申请'); |
|||
return; |
|||
} |
|||
if (!refundForm.value.orderId) { |
|||
ElMessage.warning('请选择订单号'); |
|||
return; |
|||
} |
|||
|
|||
try { |
|||
// 构造要提交的数据 |
|||
const postData = { |
|||
jwcode: refundForm.value.jwcode, |
|||
orderId: refundForm.value.orderId, |
|||
notes: refundForm.value.remark |
|||
}; |
|||
|
|||
// 发送 POST 请求 |
|||
const response = await axios.post('http://192.168.8.94:5173/refunds/add/addRefunds', postData); |
|||
|
|||
// 处理响应 |
|||
if (response.status === 200) { |
|||
ElMessage.success('退款申请提交成功'); |
|||
// 清空表单 |
|||
refundForm.value = { |
|||
jwcode: '', |
|||
orderId: '', |
|||
remark: '' |
|||
}; |
|||
jwcodeCheckResult.value = null; |
|||
orderList.value = []; |
|||
} else { |
|||
ElMessage.error('退款申请提交失败,请重试'); |
|||
} |
|||
} catch (error) { |
|||
console.error('提交退款申请时出错:', error); |
|||
ElMessage.error('提交退款申请时出错,请检查网络或联系管理员'); |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped> |
|||
/* 若充值审核页面有特殊样式,可在这里添加相同样式 */ |
|||
</style> |
@ -0,0 +1,9 @@ |
|||
<template> |
|||
<div>这是退款审批页面</div> |
|||
</template> |
|||
|
|||
<script setup> |
|||
</script> |
|||
|
|||
<style scoped> |
|||
</style> |
@ -0,0 +1,12 @@ |
|||
{ |
|||
"extends": "@vue/tsconfig/tsconfig.dom.json", |
|||
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"], |
|||
"exclude": ["src/**/__tests__/*"], |
|||
"compilerOptions": { |
|||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", |
|||
|
|||
"paths": { |
|||
"@/*": ["./src/*"] |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,11 @@ |
|||
{ |
|||
"files": [], |
|||
"references": [ |
|||
{ |
|||
"path": "./tsconfig.node.json" |
|||
}, |
|||
{ |
|||
"path": "./tsconfig.app.json" |
|||
} |
|||
] |
|||
} |
@ -0,0 +1,19 @@ |
|||
{ |
|||
"extends": "@tsconfig/node22/tsconfig.json", |
|||
"include": [ |
|||
"vite.config.*", |
|||
"vitest.config.*", |
|||
"cypress.config.*", |
|||
"nightwatch.conf.*", |
|||
"playwright.config.*", |
|||
"eslint.config.*" |
|||
], |
|||
"compilerOptions": { |
|||
"noEmit": true, |
|||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", |
|||
|
|||
"module": "ESNext", |
|||
"moduleResolution": "Bundler", |
|||
"types": ["node"] |
|||
} |
|||
} |
@ -0,0 +1,18 @@ |
|||
import { fileURLToPath, URL } from 'node:url' |
|||
|
|||
import { defineConfig } from 'vite' |
|||
import vue from '@vitejs/plugin-vue' |
|||
import vueDevTools from 'vite-plugin-vue-devtools' |
|||
|
|||
// https://vite.dev/config/
|
|||
export default defineConfig({ |
|||
plugins: [ |
|||
vue(), |
|||
vueDevTools(), |
|||
], |
|||
resolve: { |
|||
alias: { |
|||
'@': fileURLToPath(new URL('./src', import.meta.url)) |
|||
}, |
|||
}, |
|||
}) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue