263 lines
7.2 KiB
Vue
263 lines
7.2 KiB
Vue
<script setup lang="ts">
|
||
import { useRequest } from "vue-request";
|
||
import { myRequest } from "@/requests/request.ts";
|
||
import { ref } from "vue";
|
||
import _ from "lodash";
|
||
import { account, userinfo } from "@/store/store.ts";
|
||
import { ElMessage } from "element-plus";
|
||
import { formatError } from "@/utils/utils.ts";
|
||
import { Check, Close } from "@element-plus/icons-vue";
|
||
import { sum } from "lodash-es";
|
||
import YlActionDiv from "@/components/yl-action-div.vue";
|
||
|
||
const editData = ref({ card: "", type: false, balance: 0 });
|
||
const dialog = ref(false);
|
||
const page = ref(1);
|
||
const pageSize = ref(10);
|
||
const editYe = ref(false);
|
||
// const show = ref(false);
|
||
|
||
const { data, loading, run } = useRequest<{
|
||
data: { balance: number; type: boolean; card: string }[];
|
||
}>(() => myRequest(`/api/yeb`, userinfo.token));
|
||
const { runAsync: updateCard } = useRequest(
|
||
() =>
|
||
myRequest(
|
||
`/api/yeb`,
|
||
userinfo.token,
|
||
{ ...editData.value, balance: Number(editData.value.balance) },
|
||
"put",
|
||
),
|
||
{ manual: true },
|
||
);
|
||
const { runAsync: deleteCard } = useRequest(
|
||
(card: string) =>
|
||
myRequest(`/api/yeb`, userinfo.token, { card: card }, "delete"),
|
||
{ manual: true },
|
||
);
|
||
const { runAsync: addCard, loading: adding } = useRequest(
|
||
() =>
|
||
myRequest(
|
||
`/api/yeb`,
|
||
userinfo.token,
|
||
{ ...editData.value, balance: Number(editData.value.balance) },
|
||
"post",
|
||
),
|
||
{ manual: true },
|
||
);
|
||
|
||
const addCardBtn = () => {
|
||
editData.value = { card: "", type: false, balance: 0 };
|
||
dialog.value = true;
|
||
};
|
||
const addCardFunc = () => {
|
||
if (
|
||
!editData.value.card ||
|
||
(!editData.value.balance && editData.value.balance !== 0)
|
||
) {
|
||
ElMessage.error("参数格式错误");
|
||
return;
|
||
}
|
||
addCard()
|
||
.then((res) => {
|
||
editData.value = { card: "", type: false, balance: 0 };
|
||
ElMessage.success(res.data);
|
||
run();
|
||
dialog.value = false;
|
||
})
|
||
.catch((err) => ElMessage.error(formatError(err)));
|
||
};
|
||
const updateCardFunc = () => {
|
||
updateCard()
|
||
.then((res) => {
|
||
ElMessage.success(res.data);
|
||
run();
|
||
editData.value = { card: "", type: false, balance: 0 };
|
||
})
|
||
.catch((err) => ElMessage.error(formatError(err)));
|
||
};
|
||
const deleteCardFunc = (e: string) => {
|
||
deleteCard(e)
|
||
.then((res) => {
|
||
ElMessage.success(res.data);
|
||
run();
|
||
})
|
||
.catch((err) => ElMessage.error(formatError(err)));
|
||
};
|
||
const updateType = (
|
||
t: boolean,
|
||
d: { card: string; type: boolean; balance: number },
|
||
) => {
|
||
editData.value = { ...d, type: t };
|
||
updateCard()
|
||
.then((res) => {
|
||
ElMessage.success(res.data);
|
||
run();
|
||
editData.value = { card: "", type: false, balance: 0 };
|
||
})
|
||
.catch((err) => ElMessage.error(formatError(err)));
|
||
};
|
||
</script>
|
||
|
||
<template>
|
||
<yl-action-div>
|
||
<el-button link @click="addCardBtn">新增项目</el-button>
|
||
</yl-action-div>
|
||
<el-table
|
||
stripe
|
||
v-loading="loading"
|
||
:data="
|
||
_.get(data, 'data', []).filter(
|
||
(_: {}, index: number) =>
|
||
index >= (page - 1) * pageSize && index < page * pageSize,
|
||
)
|
||
"
|
||
>
|
||
<el-table-column prop="card" label="项目" align="center" />
|
||
<el-table-column prop="balance" label="余额(双击修改)" align="center">
|
||
<template #default="scope"
|
||
><div
|
||
v-if="scope.row.card !== editData.card"
|
||
class="balance-div"
|
||
:style="`color:${scope.row.type ? 'red' : ''}`"
|
||
@dblclick="
|
||
() => {
|
||
editYe = true;
|
||
editData = {
|
||
card: scope.row.card,
|
||
type: scope.row.type,
|
||
balance: scope.row.balance,
|
||
};
|
||
}
|
||
"
|
||
>
|
||
{{ account.show ? scope.row.balance : "******" }}
|
||
</div>
|
||
<div v-else-if="editYe" class="flex between">
|
||
<el-input
|
||
v-model="editData.balance"
|
||
type="number"
|
||
placeholder="输入当前余额"
|
||
:min="0"
|
||
:max="99999999"
|
||
style="width: calc(100% - 50px)"
|
||
>
|
||
<template #prefix>¥</template>
|
||
</el-input>
|
||
<div v-if="editYe">
|
||
<el-icon color="green" size="20"
|
||
><i class="bi-check2" @click="updateCardFunc"
|
||
/></el-icon>
|
||
<el-icon
|
||
color="red"
|
||
size="20"
|
||
@click="editData = { card: '', type: false, balance: 0 }"
|
||
><i class="bi-x"
|
||
/></el-icon>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="支出型" align="center">
|
||
<template #default="scope">
|
||
<el-switch
|
||
v-model="scope.row.type"
|
||
inline-prompt
|
||
:loading="loading"
|
||
active-text="是"
|
||
inactive-text="否"
|
||
@change="
|
||
(t: boolean) => {
|
||
editYe = false;
|
||
updateType(t, scope.row);
|
||
}
|
||
"
|
||
/>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" align="center">
|
||
<template #default="scope">
|
||
<el-popconfirm
|
||
:title="`确认删除 ${scope.row.card} ?`"
|
||
cancel-button-text="取消"
|
||
confirm-button-text="确认"
|
||
@confirm="() => deleteCardFunc(scope.row.card)"
|
||
><template #reference
|
||
><el-icon color="red"><Close /></el-icon></template
|
||
></el-popconfirm>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
<div class="flex between pagination-div">
|
||
<div>
|
||
<label>显示余额:</label
|
||
><el-switch v-model="account.show">
|
||
<template #active-action><Check /></template>
|
||
<template #inactive-action><Close /></template> </el-switch
|
||
><label v-if="account.show">
|
||
合计:{{
|
||
sum(data?.data.map((e) => (e.type ? -e.balance : e.balance))).toFixed(
|
||
2,
|
||
)
|
||
}}</label
|
||
>
|
||
</div>
|
||
<div>
|
||
<el-pagination
|
||
layout="sizes, prev, pager, next"
|
||
:total="_.get(data, 'data', []).length"
|
||
v-model:current-page="page"
|
||
v-model:page-size="pageSize"
|
||
:hide-on-single-page="pageSize === 10"
|
||
/>
|
||
</div>
|
||
</div>
|
||
<el-dialog title="新增项目" v-model="dialog">
|
||
<div class="input-div flex between">
|
||
<el-input v-model="editData.card" placeholder="输入项目名称" clearable>
|
||
<template #prefix>
|
||
<el-switch
|
||
v-model="editData.type"
|
||
active-text="借贷"
|
||
inactive-text="存款"
|
||
style="--el-switch-off-color: #606266; --el-switch-on-color: red"
|
||
inline-prompt
|
||
/>
|
||
</template>
|
||
</el-input>
|
||
</div>
|
||
<div class="input-div">
|
||
<el-input
|
||
v-model="editData.balance"
|
||
type="number"
|
||
placeholder="输入当前余额"
|
||
:min="0"
|
||
:max="99999999"
|
||
><template #prefix>¥</template></el-input
|
||
>
|
||
</div>
|
||
<template #footer>
|
||
<div class="dialog-footer">
|
||
<el-button type="primary" @click="addCardFunc" :disabled="adding"
|
||
>保存</el-button
|
||
>
|
||
</div>
|
||
</template>
|
||
</el-dialog>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.input-div {
|
||
margin: 1rem 2rem;
|
||
}
|
||
.dialog-footer {
|
||
padding-right: 2rem;
|
||
}
|
||
.balance-div:hover {
|
||
cursor: pointer;
|
||
}
|
||
.pagination-div {
|
||
padding: 1rem;
|
||
}
|
||
</style>
|