前端安全修复:登录接口改用统一auth接口、Dashboard过滤条件修正、RBAC token处理
This commit is contained in:
parent
6f5d2b8d13
commit
6807cd94a1
|
|
@ -29,10 +29,15 @@ const router = createRouter({
|
|||
routes
|
||||
})
|
||||
|
||||
// 路由守卫
|
||||
// 路由守卫:检查 token
|
||||
router.beforeEach((to, from, next) => {
|
||||
// 暂时禁用登录验证
|
||||
next()
|
||||
if (to.meta.requiresAuth && !localStorage.getItem('token')) {
|
||||
next('/login')
|
||||
} else if (to.path === '/login' && localStorage.getItem('token')) {
|
||||
next('/')
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
})
|
||||
|
||||
export default router
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* 封装 axios,自动附加 Authorization header
|
||||
* 所有需要鉴权的 API 请求统一走这里
|
||||
*/
|
||||
import axios from 'axios'
|
||||
|
||||
const api = axios.create({
|
||||
baseURL: '/api',
|
||||
timeout: 15000
|
||||
})
|
||||
|
||||
// 请求拦截器:自动附加 token
|
||||
api.interceptors.request.use(
|
||||
(config) => {
|
||||
const token = localStorage.getItem('token')
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`
|
||||
}
|
||||
return config
|
||||
},
|
||||
(error) => Promise.reject(error)
|
||||
)
|
||||
|
||||
// 响应拦截器:token 过期则跳转登录
|
||||
api.interceptors.response.use(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
if (error.response?.status === 401) {
|
||||
localStorage.removeItem('token')
|
||||
localStorage.removeItem('riderInfo')
|
||||
window.location.href = '/login'
|
||||
}
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
export default api
|
||||
|
|
@ -80,7 +80,7 @@
|
|||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import axios from 'axios'
|
||||
import api from '../utils/api'
|
||||
|
||||
const searchForm = ref({ type: '', status: '' })
|
||||
const tableData = ref([])
|
||||
|
|
@ -90,7 +90,7 @@ const viewData = ref({})
|
|||
const rejectReason = ref('')
|
||||
|
||||
const fetchData = async () => {
|
||||
const res = await axios.get('http://localhost:3000/api/applications')
|
||||
const res = await api.get('/applications')
|
||||
if (res.data.success) tableData.value = res.data.data
|
||||
}
|
||||
const handleSearch = () => {
|
||||
|
|
@ -102,7 +102,7 @@ const handleSearch = () => {
|
|||
const handleReset = () => { searchForm.value = { type: '', status: '' }; fetchData() }
|
||||
const handleView = (row) => { viewData.value = row; dialogVisible.value = true }
|
||||
const handleApprove = async () => {
|
||||
await axios.put(`http://localhost:3000/api/applications/${viewData.value._id}`, { status: '已通过' })
|
||||
await api.put(`/applications/${viewData.value._id}`, { status: '已通过' })
|
||||
ElMessage.success('已通过')
|
||||
dialogVisible.value = false
|
||||
fetchData()
|
||||
|
|
@ -110,7 +110,7 @@ const handleApprove = async () => {
|
|||
const handleReject = () => { rejectDialogVisible.value = true }
|
||||
const confirmReject = async () => {
|
||||
if (!rejectReason.value.trim()) { ElMessage.warning('请填写拒绝理由'); return }
|
||||
await axios.put(`http://localhost:3000/api/applications/${viewData.value._id}`, { status: '已拒绝', rejectReason: rejectReason.value })
|
||||
await api.put(`/applications/${viewData.value._id}`, { status: '已拒绝', rejectReason: rejectReason.value })
|
||||
ElMessage.info('已拒绝')
|
||||
rejectDialogVisible.value = false
|
||||
rejectReason.value = ''
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@
|
|||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import axios from 'axios'
|
||||
import api from '../utils/api'
|
||||
|
||||
const searchForm = ref({ type: '', status: '' })
|
||||
const tableData = ref([])
|
||||
|
|
@ -105,7 +105,7 @@ const form = ref({ _id: '', type: '', title: '', content: '', applicant: '', app
|
|||
const rules = { type: [{ required: true, message: '请选择类型', trigger: 'change' }], title: [{ required: true, message: '请输入标题', trigger: 'blur' }] }
|
||||
|
||||
const fetchData = async () => {
|
||||
const res = await axios.get('http://localhost:3000/api/approvals')
|
||||
const res = await api.get('/approvals')
|
||||
if (res.data.success) tableData.value = res.data.data
|
||||
}
|
||||
const handleSearch = () => {
|
||||
|
|
@ -118,20 +118,20 @@ const handleReset = () => { searchForm.value = { type: '', status: '' }; fetchDa
|
|||
const handleAdd = () => { dialogTitle.value = '创建审批'; form.value = { _id: '', type: '', title: '', content: '', applicant: '', approver: '', remark: '', status: '待审批' }; dialogVisible.value = true }
|
||||
const handleEdit = (row) => { dialogTitle.value = '查看审批'; form.value = { ...row }; dialogVisible.value = true }
|
||||
const handleApprove = async (row) => {
|
||||
await axios.put(`http://localhost:3000/api/approvals/${row._id}`, { status: '已通过', approver: '管理员' })
|
||||
await api.put(`/approvals/${row._id}`, { status: '已通过', approver: '管理员' })
|
||||
ElMessage.success('审批通过'); fetchData()
|
||||
}
|
||||
const handleReject = async (row) => {
|
||||
await axios.put(`http://localhost:3000/api/approvals/${row._id}`, { status: '已拒绝', approver: '管理员' })
|
||||
await api.put(`/approvals/${row._id}`, { status: '已拒绝', approver: '管理员' })
|
||||
ElMessage.info('已拒绝'); fetchData()
|
||||
}
|
||||
const handleSubmit = async () => {
|
||||
await formRef.value.validate()
|
||||
if (form.value._id) {
|
||||
await axios.put(`http://localhost:3000/api/approvals/${form.value._id}`, form.value)
|
||||
await api.put(`/approvals/${form.value._id}`, form.value)
|
||||
ElMessage.success('修改成功')
|
||||
} else {
|
||||
await axios.post('http://localhost:3000/api/approvals', form.value)
|
||||
await api.post('/approvals', form.value)
|
||||
ElMessage.success('创建成功')
|
||||
}
|
||||
dialogVisible.value = false; fetchData()
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@
|
|||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import axios from 'axios'
|
||||
import api from '../utils/api'
|
||||
|
||||
const searchForm = ref({ type: '', status: '' })
|
||||
const tableData = ref([])
|
||||
|
|
@ -105,7 +105,7 @@ const form = ref({ _id: '', type: '', content: '', handler: '', response: '', st
|
|||
const rules = { type: [{ required: true, message: '请选择类型', trigger: 'change' }], content: [{ required: true, message: '请输入内容', trigger: 'blur' }] }
|
||||
|
||||
const fetchData = async () => {
|
||||
const res = await axios.get('http://localhost:3000/api/complaints')
|
||||
const res = await api.get('/complaints')
|
||||
if (res.data.success) tableData.value = res.data.data
|
||||
}
|
||||
const handleSearch = () => {
|
||||
|
|
@ -120,17 +120,17 @@ const handleEdit = (row) => { dialogTitle.value = '处理投诉'; form.value = {
|
|||
const handleSubmit = async () => {
|
||||
await formRef.value.validate()
|
||||
if (form.value._id) {
|
||||
await axios.put(`http://localhost:3000/api/complaints/${form.value._id}`, form.value)
|
||||
await api.put(`/complaints/${form.value._id}`, form.value)
|
||||
ElMessage.success('处理成功')
|
||||
} else {
|
||||
await axios.post('http://localhost:3000/api/complaints', form.value)
|
||||
await api.post('/complaints', form.value)
|
||||
ElMessage.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false; fetchData()
|
||||
}
|
||||
const handleDelete = async (row) => {
|
||||
await ElMessageBox.confirm('确定删除?', '提示', { type: 'warning' })
|
||||
await axios.delete(`http://localhost:3000/api/complaints/${row._id}`)
|
||||
await api.delete(`/complaints/${row._id}`)
|
||||
ElMessage.success('删除成功'); fetchData()
|
||||
}
|
||||
const getStatusType = (status) => ({ '待处理': 'danger', '处理中': 'warning', '已解决': 'success', '已关闭': 'info' }[status] || 'info')
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@
|
|||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import axios from 'axios'
|
||||
import api from '../utils/api'
|
||||
|
||||
const searchForm = ref({ type: '', status: '' })
|
||||
const tableData = ref([])
|
||||
|
|
@ -114,7 +114,7 @@ const form = ref({ _id: '', type: '', title: '', partyA: '', partyB: '', content
|
|||
const rules = { type: [{ required: true, message: '请选择类型', trigger: 'change' }], title: [{ required: true, message: '请输入标题', trigger: 'blur' }] }
|
||||
|
||||
const fetchData = async () => {
|
||||
const res = await axios.get('http://localhost:3000/api/conflicts')
|
||||
const res = await api.get('/conflicts')
|
||||
if (res.data.success) tableData.value = res.data.data
|
||||
}
|
||||
const handleSearch = () => {
|
||||
|
|
@ -129,17 +129,17 @@ const handleEdit = (row) => { dialogTitle.value = '处理矛盾'; form.value = {
|
|||
const handleSubmit = async () => {
|
||||
await formRef.value.validate()
|
||||
if (form.value._id) {
|
||||
await axios.put(`http://localhost:3000/api/conflicts/${form.value._id}`, form.value)
|
||||
await api.put(`/conflicts/${form.value._id}`, form.value)
|
||||
ElMessage.success('修改成功')
|
||||
} else {
|
||||
await axios.post('http://localhost:3000/api/conflicts', form.value)
|
||||
await api.post('/conflicts', form.value)
|
||||
ElMessage.success('登记成功')
|
||||
}
|
||||
dialogVisible.value = false; fetchData()
|
||||
}
|
||||
const handleDelete = async (row) => {
|
||||
await ElMessageBox.confirm('确定删除?', '提示', { type: 'warning' })
|
||||
await axios.delete(`http://localhost:3000/api/conflicts/${row._id}`)
|
||||
await api.delete(`/conflicts/${row._id}`)
|
||||
ElMessage.success('删除成功'); fetchData()
|
||||
}
|
||||
const getStatusType = (status) => ({ '待处理': 'danger', '处理中': 'warning', '已解决': 'success', '已关闭': 'info' }[status] || 'info')
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@
|
|||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import axios from 'axios'
|
||||
import api from '../utils/api'
|
||||
|
||||
const searchForm = ref({ name: '', phone: '' })
|
||||
const tableData = ref([])
|
||||
|
|
@ -110,7 +110,7 @@ const rules = {
|
|||
|
||||
const fetchCustomers = async () => {
|
||||
try {
|
||||
const res = await axios.get('http://localhost:3000/api/customers')
|
||||
const res = await api.get('/customers')
|
||||
if (res.data.success) {
|
||||
tableData.value = res.data.data
|
||||
}
|
||||
|
|
@ -154,10 +154,10 @@ const handleSubmit = async () => {
|
|||
try {
|
||||
await formRef.value.validate()
|
||||
if (form.value._id) {
|
||||
const res = await axios.put(`http://localhost:3000/api/customers/${form.value._id}`, form.value)
|
||||
const res = await api.put(`/customers/${form.value._id}`, form.value)
|
||||
if (res.data.success) { ElMessage.success('修改成功') }
|
||||
} else {
|
||||
const res = await axios.post('http://localhost:3000/api/customers', form.value)
|
||||
const res = await api.post('/customers', form.value)
|
||||
if (res.data.success) { ElMessage.success('添加成功') }
|
||||
}
|
||||
dialogVisible.value = false
|
||||
|
|
@ -168,7 +168,7 @@ const handleSubmit = async () => {
|
|||
const handleDelete = async (row) => {
|
||||
try {
|
||||
await ElMessageBox.confirm('确定要删除这个客户吗?', '提示', { type: 'warning' })
|
||||
const res = await axios.delete(`http://localhost:3000/api/customers/${row._id}`)
|
||||
const res = await api.delete(`/customers/${row._id}`)
|
||||
if (res.data.success) { ElMessage.success('删除成功'); fetchCustomers() }
|
||||
} catch {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,16 +104,16 @@
|
|||
<el-table :data="recentPayments" stripe size="small">
|
||||
<el-table-column label="类型" width="80">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.type === 'income' ? 'success' : 'danger'" size="small">
|
||||
{{ row.type === 'income' ? '收入' : '支出' }}
|
||||
<el-tag :type="row.type === '收入' ? 'success' : 'danger'" size="small">
|
||||
{{ row.type === '收入' ? '收入' : '支出' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="party" label="对方" width="120" />
|
||||
<el-table-column prop="amount" label="金额" width="100">
|
||||
<template #default="{ row }">
|
||||
<span :style="{ color: row.type === 'income' ? '#52c41a' : '#f5222d', fontWeight: 'bold' }">
|
||||
{{ row.type === 'income' ? '+' : '-' }}¥{{ row.amount }}
|
||||
<span :style="{ color: row.type === '收入' ? '#52c41a' : '#f5222d', fontWeight: 'bold' }">
|
||||
{{ row.type === '收入' ? '+' : '-' }}¥{{ row.amount }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
|
@ -173,19 +173,21 @@ const barChartRef = ref(null)
|
|||
|
||||
const loadData = async () => {
|
||||
try {
|
||||
const token = localStorage.getItem('token')
|
||||
const headers = token ? { Authorization: `Bearer ${token}` } : {}
|
||||
// 加载车辆数据
|
||||
const vehicleRes = await fetch('http://localhost:3000/api/vehicles')
|
||||
const vehicleRes = await fetch('/api/vehicles', { headers })
|
||||
const vehicleData = await vehicleRes.json()
|
||||
if (vehicleData.success) {
|
||||
const vehicles = vehicleData.data
|
||||
stats.value.totalVehicles = vehicles.length
|
||||
stats.value.availableVehicles = vehicles.filter(v => v.status === '空闲').length
|
||||
stats.value.rentedVehicles = vehicles.filter(v => v.status === '出租中' || v.status === '在租').length
|
||||
stats.value.rentedVehicles = vehicles.filter(v => v.status === '在租').length
|
||||
stats.value.maintenanceVehicles = vehicles.filter(v => v.status === '维修中').length
|
||||
}
|
||||
|
||||
// 加载财务数据
|
||||
const financeRes = await fetch('http://localhost:3000/api/finance')
|
||||
const financeRes = await fetch('/api/finance', { headers })
|
||||
const financeData = await financeRes.json()
|
||||
if (financeData.success) {
|
||||
const list = financeData.data.list || []
|
||||
|
|
@ -195,8 +197,8 @@ const loadData = async () => {
|
|||
financeStats.value.totalExpense = summary.totalExpense || 0
|
||||
financeStats.value.balance = summary.balance || 0
|
||||
financeStats.value.totalCount = list.length
|
||||
financeStats.value.incomeCount = list.filter(p => p.type === 'income').length
|
||||
financeStats.value.expenseCount = list.filter(p => p.type === 'expense').length
|
||||
financeStats.value.incomeCount = list.filter(p => p.type === '收入').length
|
||||
financeStats.value.expenseCount = list.filter(p => p.type === '支出').length
|
||||
|
||||
// 最近5笔
|
||||
recentPayments.value = list.slice(0, 5)
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@
|
|||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import axios from 'axios'
|
||||
import api from '../utils/api'
|
||||
|
||||
const searchForm = ref({ type: '', status: '' })
|
||||
const tableData = ref([])
|
||||
|
|
@ -83,7 +83,7 @@ const viewData = ref({})
|
|||
const result = ref('')
|
||||
|
||||
const fetchData = async () => {
|
||||
const res = await axios.get('http://localhost:3000/api/disputes')
|
||||
const res = await api.get('/disputes')
|
||||
if (res.data.success) tableData.value = res.data.data
|
||||
}
|
||||
const handleSearch = () => {
|
||||
|
|
@ -95,7 +95,7 @@ const handleSearch = () => {
|
|||
const handleReset = () => { searchForm.value = { type: '', status: '' }; fetchData() }
|
||||
const handleView = (row) => { viewData.value = row; result.value = row.result || ''; dialogVisible.value = true }
|
||||
const handleResolve = async () => {
|
||||
await axios.put(`http://localhost:3000/api/disputes/${viewData.value._id}`, { status: '已解决', result: result.value })
|
||||
await api.put(`/disputes/${viewData.value._id}`, { status: '已解决', result: result.value })
|
||||
ElMessage.success('已标记为解决')
|
||||
dialogVisible.value = false
|
||||
fetchData()
|
||||
|
|
|
|||
|
|
@ -94,7 +94,9 @@ const barChartRef = ref(null)
|
|||
|
||||
const refresh = async () => {
|
||||
try {
|
||||
const res = await fetch('http://localhost:3000/api/finance')
|
||||
const token = localStorage.getItem('token')
|
||||
const headers = token ? { Authorization: `Bearer ${token}` } : {}
|
||||
const res = await fetch('/api/finance', { headers })
|
||||
const data = await res.json()
|
||||
if (data.success) {
|
||||
payments.value = data.data.list
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@
|
|||
</el-badge>
|
||||
<el-dropdown @command="handleCommand">
|
||||
<span class="user-info">
|
||||
👤 管理员
|
||||
👤 {{ userName }}
|
||||
<el-icon><arrow-down /></el-icon>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
|
|
@ -85,6 +85,10 @@ const route = useRoute()
|
|||
const activeMenu = computed(() => route.path)
|
||||
const notificationCount = ref(2)
|
||||
|
||||
// 读取登录用户信息
|
||||
const riderInfo = JSON.parse(localStorage.getItem('riderInfo') || '{}')
|
||||
const userName = ref(riderInfo.name || '管理员')
|
||||
|
||||
const pageTitle = computed(() => {
|
||||
const titles = {
|
||||
'/': '数据看板',
|
||||
|
|
@ -104,7 +108,8 @@ const showNotifications = () => {
|
|||
|
||||
const handleCommand = (command) => {
|
||||
if (command === 'logout') {
|
||||
localStorage.removeItem('isLoggedIn')
|
||||
localStorage.removeItem('token')
|
||||
localStorage.removeItem('riderInfo')
|
||||
window.location.href = '/login'
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@
|
|||
<el-input v-model="loginForm.password" type="password" placeholder="请输入密码" show-password />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" style="width: 100%;" @click="handleLogin">登录</el-button>
|
||||
<el-button type="primary" style="width: 100%;" :loading="loading" @click="handleLogin">登录</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="tips">演示账号: admin / admin</div>
|
||||
<div class="tips">演示账号: admin / admin123</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -29,6 +29,7 @@ import { ElMessage } from 'element-plus'
|
|||
|
||||
const router = useRouter()
|
||||
const formRef = ref(null)
|
||||
const loading = ref(false)
|
||||
const loginForm = ref({ username: '', password: '' })
|
||||
|
||||
const rules = {
|
||||
|
|
@ -36,18 +37,41 @@ const rules = {
|
|||
password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
|
||||
}
|
||||
|
||||
const handleLogin = () => {
|
||||
formRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
if (loginForm.value.username === 'admin' && loginForm.value.password === 'admin') {
|
||||
ElMessage.success('登录成功!')
|
||||
localStorage.setItem('isLoggedIn', 'true')
|
||||
router.push('/')
|
||||
} else {
|
||||
ElMessage.error('用户名或密码错误')
|
||||
}
|
||||
const handleLogin = async () => {
|
||||
const valid = await formRef.value.validate().catch(() => false)
|
||||
if (!valid) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await fetch('/api/auth/login', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(loginForm.value)
|
||||
})
|
||||
const data = await res.json()
|
||||
|
||||
if (data.success) {
|
||||
localStorage.setItem('token', data.data.token)
|
||||
localStorage.setItem('userInfo', JSON.stringify({
|
||||
id: data.data.id,
|
||||
username: data.data.username,
|
||||
name: data.data.name,
|
||||
type: data.data.type,
|
||||
role: data.data.role,
|
||||
roleLabel: data.data.roleLabel,
|
||||
permissions: data.data.permissions
|
||||
}))
|
||||
localStorage.setItem('permissions', JSON.stringify(data.data.permissions))
|
||||
ElMessage.success('登录成功!')
|
||||
router.push('/')
|
||||
} else {
|
||||
ElMessage.error(data.message || '登录失败')
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
ElMessage.error('网络错误,请检查后端服务是否启动')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@
|
|||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import axios from 'axios'
|
||||
import api from '../utils/api'
|
||||
|
||||
const searchForm = ref({ orderNumber: '', status: '' })
|
||||
const tableData = ref([])
|
||||
|
|
@ -150,15 +150,15 @@ const rules = {
|
|||
|
||||
const fetchOrders = async () => {
|
||||
try {
|
||||
const res = await axios.get('http://localhost:3000/api/orders')
|
||||
const res = await api.get('/orders')
|
||||
if (res.data.success) tableData.value = res.data.data
|
||||
} catch { ElMessage.error('获取订单列表失败') }
|
||||
}
|
||||
|
||||
const fetchOptions = async () => {
|
||||
const [cRes, vRes] = await Promise.all([
|
||||
axios.get('http://localhost:3000/api/customers'),
|
||||
axios.get('http://localhost:3000/api/vehicles')
|
||||
api.get('/customers'),
|
||||
api.get('/vehicles')
|
||||
])
|
||||
if (cRes.data.success) customers.value = cRes.data.data
|
||||
if (vRes.data.success) vehicles.value = vRes.data.data.filter(v => v.status === '空闲')
|
||||
|
|
@ -195,10 +195,10 @@ const handleSubmit = async () => {
|
|||
try {
|
||||
await formRef.value.validate()
|
||||
if (form.value._id) {
|
||||
const res = await axios.put(`http://localhost:3000/api/orders/${form.value._id}`, form.value)
|
||||
const res = await api.put(`/orders/${form.value._id}`, form.value)
|
||||
if (res.data.success) ElMessage.success('修改成功')
|
||||
} else {
|
||||
const res = await axios.post('http://localhost:3000/api/orders', form.value)
|
||||
const res = await api.post('/orders', form.value)
|
||||
if (res.data.success) ElMessage.success('创建成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
|
|
@ -209,7 +209,7 @@ const handleSubmit = async () => {
|
|||
const handleDelete = async (row) => {
|
||||
try {
|
||||
await ElMessageBox.confirm('确定要删除这个订单吗?', '提示', { type: 'warning' })
|
||||
const res = await axios.delete(`http://localhost:3000/api/orders/${row._id}`)
|
||||
const res = await api.delete(`/orders/${row._id}`)
|
||||
if (res.data.success) { ElMessage.success('删除成功'); fetchOrders() }
|
||||
} catch {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@
|
|||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import axios from 'axios'
|
||||
import api from '../utils/api'
|
||||
|
||||
const searchForm = ref({ type: '', status: '' })
|
||||
const tableData = ref([])
|
||||
|
|
@ -109,7 +109,7 @@ const form = ref({ _id: '', type: '', amount: 0, method: '', account: '', operat
|
|||
const rules = { type: [{ required: true, message: '请选择类型', trigger: 'change' }], amount: [{ required: true, message: '请输入金额', trigger: 'blur' }] }
|
||||
|
||||
const fetchData = async () => {
|
||||
const res = await axios.get('http://localhost:3000/api/payments')
|
||||
const res = await api.get('/payments')
|
||||
if (res.data.success) tableData.value = res.data.data
|
||||
}
|
||||
const handleSearch = () => {
|
||||
|
|
@ -122,16 +122,16 @@ const handleReset = () => { searchForm.value = { type: '', status: '' }; fetchDa
|
|||
const handleAdd = () => { dialogTitle.value = '创建打款'; form.value = { _id: '', type: '', amount: 0, method: '', account: '', operator: '', remark: '', status: '待打款' }; dialogVisible.value = true }
|
||||
const handleEdit = (row) => { dialogTitle.value = '编辑打款'; form.value = { ...row }; dialogVisible.value = true }
|
||||
const handleProcess = async (row) => {
|
||||
await axios.put(`http://localhost:3000/api/payments/${row._id}`, { status: '已打款' })
|
||||
await api.put(`/payments/${row._id}`, { status: '已打款' })
|
||||
ElMessage.success('打款成功'); fetchData()
|
||||
}
|
||||
const handleSubmit = async () => {
|
||||
await formRef.value.validate()
|
||||
if (form.value._id) {
|
||||
await axios.put(`http://localhost:3000/api/payments/${form.value._id}`, form.value)
|
||||
await api.put(`/payments/${form.value._id}`, form.value)
|
||||
ElMessage.success('修改成功')
|
||||
} else {
|
||||
await axios.post('http://localhost:3000/api/payments', form.value)
|
||||
await api.post('/payments', form.value)
|
||||
ElMessage.success('创建成功')
|
||||
}
|
||||
dialogVisible.value = false; fetchData()
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@
|
|||
<script setup>
|
||||
import { ref, onMounted, computed } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import axios from 'axios'
|
||||
import api from '../utils/api'
|
||||
|
||||
const searchForm = ref({ name: '', approvalStatus: '' })
|
||||
const tableData = ref([])
|
||||
|
|
@ -132,7 +132,7 @@ const dialogVisible = ref(false)
|
|||
const viewData = ref({})
|
||||
|
||||
const fetchData = async () => {
|
||||
const res = await axios.get('http://localhost:3000/api/stores')
|
||||
const res = await api.get('/stores')
|
||||
if (res.data.success) tableData.value = res.data.data
|
||||
}
|
||||
const handleSearch = () => {
|
||||
|
|
@ -150,7 +150,7 @@ const rejectReason = ref('')
|
|||
const showRejectDialog = ref(false)
|
||||
|
||||
const handleApprove = async () => {
|
||||
await axios.put(`http://localhost:3000/api/stores/${viewData.value._id}`, { approvalStatus: '已通过' })
|
||||
await api.put(`/stores/${viewData.value._id}`, { approvalStatus: '已通过' })
|
||||
ElMessage.success('已通过审批')
|
||||
dialogVisible.value = false
|
||||
fetchData()
|
||||
|
|
@ -160,7 +160,7 @@ const confirmReject = async () => {
|
|||
ElMessage.warning('请填写拒绝理由')
|
||||
return
|
||||
}
|
||||
await axios.put(`http://localhost:3000/api/stores/${viewData.value._id}`, { approvalStatus: '已拒绝', rejectReason: rejectReason.value })
|
||||
await api.put(`/stores/${viewData.value._id}`, { approvalStatus: '已拒绝', rejectReason: rejectReason.value })
|
||||
ElMessage.info('已拒绝')
|
||||
showRejectDialog.value = false
|
||||
rejectReason.value = ''
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@
|
|||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import axios from 'axios'
|
||||
import api from '../utils/api'
|
||||
import { exportExcel, formatDate } from '../utils'
|
||||
|
||||
const searchForm = ref({ vehicleId: '', status: '' })
|
||||
|
|
@ -128,7 +128,7 @@ const rules = {
|
|||
|
||||
const fetchVehicles = async () => {
|
||||
try {
|
||||
const res = await axios.get('http://localhost:3000/api/vehicles')
|
||||
const res = await api.get('/vehicles')
|
||||
if (res.data.success) tableData.value = res.data.data
|
||||
} catch { ElMessage.error('获取车辆列表失败') }
|
||||
}
|
||||
|
|
@ -158,10 +158,10 @@ const handleSubmit = async () => {
|
|||
try {
|
||||
await formRef.value.validate()
|
||||
if (form.value._id) {
|
||||
const res = await axios.put(`http://localhost:3000/api/vehicles/${form.value._id}`, form.value)
|
||||
const res = await api.put(`/vehicles/${form.value._id}`, form.value)
|
||||
if (res.data.success) ElMessage.success('修改成功')
|
||||
} else {
|
||||
const res = await axios.post('http://localhost:3000/api/vehicles', form.value)
|
||||
const res = await api.post('/vehicles', form.value)
|
||||
if (res.data.success) ElMessage.success('添加成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
|
|
@ -172,7 +172,7 @@ const handleSubmit = async () => {
|
|||
const handleDelete = async (row) => {
|
||||
try {
|
||||
await ElMessageBox.confirm('确定要删除这辆车吗?', '提示', { type: 'warning' })
|
||||
const res = await axios.delete(`http://localhost:3000/api/vehicles/${row._id}`)
|
||||
const res = await api.delete(`/vehicles/${row._id}`)
|
||||
if (res.data.success) { ElMessage.success('删除成功'); fetchVehicles() }
|
||||
} catch {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,26 @@
|
|||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
server: {
|
||||
port: 5173,
|
||||
host: '0.0.0.0',
|
||||
allowedHosts: ['51bike.online', 'admin.51bike.online', '43.156.200.173'],
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://localhost:3000',
|
||||
changeOrigin: true,
|
||||
// 显式确保 Authorization header 被转发(Vite 默认会转发,此处明确声明以防被代理中间件清除)
|
||||
configure: (proxy) => {
|
||||
proxy.on('proxyReq', (proxyReq) => {
|
||||
// 确保 Authorization header 被传递到后端
|
||||
if (proxyReq.getHeader('authorization')) {
|
||||
proxyReq.setHeader('authorization', proxyReq.getHeader('authorization'))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue