出差报销 资金明细

master
lion 1 year ago
parent f6280c8a9d
commit 4c032c1f2f

@ -3,7 +3,7 @@ import request from "@/utils/request";
export function getActual(params){ export function getActual(params){
return request({ return request({
method:'get', method:'get',
url:'/api/ht/contract-plan-act-links/index', url:'/api/ht/contract-plan-act-temp/index',
params params
}) })
} }
@ -11,7 +11,7 @@ export function getActual(params){
export function delActual(params){ export function delActual(params){
return request({ return request({
method:'get', method:'get',
url:'/api/ht/contract-plan-act-links/destroy', url:'/api/ht/contract-plan-act-temp/destroy',
params params
}) })
} }
@ -19,7 +19,7 @@ export function delActual(params){
export function editorActual(data){ export function editorActual(data){
return request({ return request({
method:'post', method:'post',
url:'/api/ht/contract-plan-act-links/save', url:'/api/ht/contract-plan-act-temp/save',
data data
}) })
} }
@ -27,7 +27,15 @@ export function editorActual(data){
export function detailActual(params){ export function detailActual(params){
return request({ return request({
method:'get', method:'get',
url:"/api/ht/contract-plan-act-links/show", url:"/api/ht/contract-plan-act-temp/show",
params params
}) })
} }
export function carryActual(data){
return request({
method:'post',
url:"/api/ht/contract-plan-act-temp/carry",
data
})
}

@ -57,7 +57,12 @@
width: 120, width: 120,
align: 'left' align: 'left'
}, },
{
prop: 'zijinlaiyuan',
label: '资金来源',
minWidth: 240,
align: 'left'
},
{ {
prop: 'flow.title', prop: 'flow.title',
label: '流程名称', label: '流程名称',
@ -133,24 +138,24 @@
parent: null, // 添加父级字段 parent: null, // 添加父级字段
isSelect: false // 添加选中状态字段 isSelect: false // 添加选中状态字段
}; };
const innerData = originalData[xingming_details]; const innerData = originalData[xingming_details];
innerData.map(item=>{ innerData.map(item => {
item.isSelect = false item.isSelect = false
}) })
person.children.push(...innerData) person.children.push(...innerData)
// const source = { // const source = {
// id: Math.random(), // id: Math.random(),
// name: '', // name: '',
// children: innerData.map((item) => ({ // children: innerData.map((item) => ({
// ...item, // ...item,
// name: item.xingming_detail, // name: item.xingming_detail,
// parent: source, // 指向当前父级 // parent: source, // 指向当前父级
// isSelect: false // 添加选中状态字段 // isSelect: false // 添加选中状态字段
// })), // })),
// parent: person, // 指向当前父级 // parent: person, // 指向当前父级
// isSelect: false // 添加选中状态字段 // isSelect: false // 添加选中状态字段
// }; // };
// person.children.push(source); // person.children.push(source);
result.push(person); result.push(person);
} }

@ -1,163 +1,166 @@
<template> <template>
<div style="padding: 0 20px"> <div style="padding: 0 20px">
<lx-header <lx-header icon="md-apps" style="margin-bottom: 10px; border: 0px; margin-top: 15px" text="实际使用金额">
icon="md-apps" <div slot="content"></div>
style="margin-bottom: 10px; border: 0px; margin-top: 15px" <slot>
text="实际使用金额" <div class="selects">
> <!-- <div>
<div slot="content"></div> <span style="padding: 0 6px; word-break: keep-all"> 关键字 </span>
<slot> <Input
<div class="selects"> v-model="select.keyword"
<!-- <div> placeholder="请输入关键字"
<span style="padding: 0 6px; word-break: keep-all"> 关键字 </span> style="width: 180px"
<Input ></Input>
v-model="select.keyword" </div>
placeholder="请输入关键字"
style="width: 180px" <Button style="margin-left: 10px" type="primary" @click=""
></Input> >重置
</div> </Button>
<Button style="margin-left: 10px" type="primary" @click="getList"
<Button style="margin-left: 10px" type="primary" @click="" >查询</Button
>重置 > -->
</Button> <Button style="margin-left: 10px" type="primary" @click="
<Button style="margin-left: 10px" type="primary" @click="getList" ($refs['addActual'].type = 'add'), $refs['addActual'].show()
>查询</Button ">新增</Button>
> --> </div>
<Button </slot>
style="margin-left: 10px" </lx-header>
type="primary"
@click=" <xy-table :list="list" :table-item="table">
($refs['addActual'].type = 'add'), $refs['addActual'].show() <template #btns>
" <el-table-column :fixed="$store.getters.device === 'mobile'?false:'right'" label="操作" align="left" width="200">
>新增</Button <template #default="{ row }">
> <div style="display: flex;align-items: flex-start;">
</div> <Button style="margin-right: 4px;" v-if="calculateTotalUseMoney(row.plan_act_links)<parseFloat(row.money)" ghost size="small" type="primary" @click="execute(row)">确认执行</Button>
</slot> <Button style="margin-right: 4px;" ghost size="small" type="primary" @click="
</lx-header> ($refs['addActual'].id = row.id),
($refs['addActual'].type = 'editor'),
<xy-table $refs['addActual'].show()
:list="list" ">编辑</Button>
:table-item="table" <Poptip :transfer="true" confirm placement="bottom"
> :title="row.plan_act_links.length>0?'已有执行记录,确认要连同执行记录一同删除?':'确认要删除吗?'" @on-ok="destroy(row)">
<template #btns> <Button size="small" type="error" ghost>删除</Button>
<el-table-column :fixed="$store.getters.device === 'mobile'?false:'right'" label="操作" align="left" width="200"> </Poptip>
<template #default="{ row }"> </div>
<div style="display: flex;align-items: flex-start;"> </template>
<Button </el-table-column>
ghost </template>
size="small" </xy-table>
type="primary"
@click=" <div style="display: flex; justify-content: flex-end">
($refs['addActual'].id = row.id), <Page :total="total" @on-change="e => {
($refs['addActual'].type = 'editor'), select.page = e;
$refs['addActual'].show() getList()
" }" show-elevator show-sizer @on-page-size-change="e => {
>编辑</Button select.page = 1;
> select.page_size = e;
<Poptip getList();
:transfer="true" }" />
confirm </div>
placement="bottom"
title="确认要删除吗" <addActual :plan_department_ids="depts" ref="addActual" @refresh="getList"></addActual>
@on-ok="destroy(row)" <exeActual ref="exeActual" @refresh="getList"></exeActual>
> </div>
<Button style="margin-left: 4px;" size="small" type="error" ghost>删除</Button> </template>
</Poptip>
</div> <script>
</template> import {
</el-table-column> getActual,
</template> delActual,
</xy-table> } from "@/api/budget/actual";
import addActual from "./components/addActual.vue";
<div style="display: flex; justify-content: flex-end"> import exeActual from "./components/exeActual.vue";
<Page export default {
:total="total" components: {
@on-change="e => { addActual,
select.page = e; exeActual
getList() },
}" data() {
show-elevator return {
show-sizer depts: [],
@on-page-size-change="e => { select: {
select.page = 1; page: 1,
select.page_size = e; page_size: 10,
getList(); },
}" visible: false,
/> total: 0,
</div> table: [{
label: "资金来源所属年份",
<addActual prop: "plan.year",
:plan_department_ids="depts" width: 120,
ref="addActual" },
@refresh="getList" {
></addActual> label: "事由",
</div> prop: "reason",
</template> width: 180,
align: 'left'
<script> },
import { getActual, delActual } from "@/api/budget/actual"; {
import addActual from "./components/addActual.vue"; label: "资金来源",
export default { prop: "plan.name",
components: { align: 'left'
addActual, // width: 180,
}, },
data() { {
return { label: "金额",
depts: [], prop: "money",
select: { width: 180,
page: 1, },
page_size: 10, {
}, label: "已使用金额",
total: 0, prop: "use_money",
table: [ width: 180,
{ formatter: (row, v2, value) => {
label: "资金来源所属年份", return this.calculateTotalUseMoney(row.plan_act_links)
prop: "plan.year", }
width: 180, }
}, ],
{ list: [],
label: "资金来源", };
prop: "plan.name", },
// width: 180, methods: {
}, async getList() {
{ const res = await getActual(this.select);
label: "使用金额", this.list = res.data;
prop: "use_money", this.total = res.total || 0;
width: 200, },
} calculateTotalUseMoney(plan_act_links) {
], let total = 0;
list: [], for (let i = 0; i < plan_act_links.length; i++) {
}; const useMoney = parseFloat(plan_act_links[i].use_money);
}, if (!isNaN(useMoney)) {
methods: { total += useMoney;
async getList() { }
const res = await getActual(this.select); }
this.list = res.data; return parseFloat(total).toFixed(2);
this.total = res.total || 0; },
}, destroy(row) {
destroy (row) { delActual({
delActual({ id: row.id
id: row.id }).then(res => {
}).then(res => { this.$message({
this.$message({ type: 'success',
type: 'success', message: '删除成功'
message: '删除成功' })
}) this.getList()
this.getList() })
}) },
} execute(row) {
}, this.$refs.exeActual.setForm(row.id,row.plan_act_links)
computed: {}, this.$refs.exeActual.isShow = true
created() { }
this.getList(); },
}, computed: {},
}; created() {
</script> this.getList();
},
<style scoped lang="scss"> };
.selects { </script>
display: flex;
align-items: center; <style scoped lang="scss">
flex-wrap: wrap; .selects {
} display: flex;
align-items: center;
flex-wrap: wrap;
}
</style> </style>

@ -1,240 +1,252 @@
<template> <template>
<div> <div>
<xy-dialog <xy-dialog ref="dialog" :is-show.sync="isShow" type="form" :title="type === 'add' ? '新增实际使用金额' : '编辑实际使用金额'"
ref="dialog" :form="form" :rules="rules" @submit="submit">
:is-show.sync="isShow" <template v-slot:reason>
type="form" <div class="xy-table-item">
:title="type === 'add' ? '新增实际使用金额' : '编辑实际使用金额'" <div class="xy-table-item-label"><span style="color: red; font-weight: 600; padding-right: 4px">*</span>事由:
:form="form" </div>
:rules="rules" <div class="xy-table-item-content">
@submit="submit" <el-input v-model="form.reason" clearable placeholder="请输入事由" style="width: 300px"></el-input>
> </div>
<template v-slot:plan_id> </div>
<div class="xy-table-item"> </template>
<div class="xy-table-item-label"> <template v-slot:plan_id>
<span style="color: red; font-weight: 600; padding-right: 4px" <div class="xy-table-item">
>*</span <div class="xy-table-item-label">
> <span style="color: red; font-weight: 600; padding-right: 4px">*</span>
资金来源: 资金来源:
</div> </div>
<div class="xy-table-item-content"> <div class="xy-table-item-content">
<div class="planTitle" @click="$refs.actualPicker.isShow=true">{{form.plan_title}}</div> <div class="planTitle" @click="$refs.actualPicker.isShow=true">{{form.plan_title}}</div>
<!-- <el-input </div>
v-model="form.plan_title" </div>
disabled </template>
clearable
placeholder="请输入备注"
style="width: 300px" <template v-slot:money>
@click="$refs.actualPicker.isShow=true" <div class="xy-table-item">
></el-input> --> <div class="xy-table-item-label"><span style="color: red; font-weight: 600; padding-right: 4px">*</span>金额:
</div> </div>
</div> <div class="xy-table-item-content">
</template> <el-input v-model="form.money" clearable placeholder="请输入金额" style="width: 300px"></el-input>
</div>
<template v-slot:use_money> </div>
<div class="xy-table-item"> </template>
<div class="xy-table-item-label"><span style="color: red; font-weight: 600; padding-right: 4px"
>*</span <!-- <template v-slot:use_money>
>使用金额 :</div> <div class="xy-table-item">
<div class="xy-table-item-content"> <div class="xy-table-item-label"><span style="color: red; font-weight: 600; padding-right: 4px">*</span>已使用金额:
<el-input </div>
v-model="form.use_money" <div class="xy-table-item-content">
<el-input v-model="form.use_money" clearable placeholder="请输入已使用金额" style="width: 300px"></el-input>
clearable </div>
placeholder="请输入备注" </div>
style="width: 300px" </template> -->
></el-input> </xy-dialog>
</div> <actualPicker ref="actualPicker" @refresh="getPlanId"></actualPicker>
</div> </div>
</template> </template>
</xy-dialog>
<actualPicker ref="actualPicker" @refresh="getPlanId"></actualPicker> <script>
</div> import {
</template> editorActual,
detailActual
<script> } from "@/api/budget/actual";
import { editorActual, detailActual } from "@/api/budget/actual"; import actualPicker from "@/components/PlanPicker/actualPicker.vue"
import actualPicker from "@/components/PlanPicker/actualPicker.vue" export default {
export default { components: {
components:{ actualPicker
actualPicker },
}, data() {
data() { return {
return { isShow: false,
isShow: false, id: "",
id: "", type: "",
type: "", form: {
form: { reason: '',
plan_id:'', plan_id: '',
use_money:'', money: '',
plan_title:'' // use_money: '',
}, plan_title: ''
rules: { },
plan_id: [ rules: {
{ reason: [{
required: true, required: true,
message: "请选择资金来源", message: "请填写事由",
}, }],
], plan_id: [{
use_money: [ required: true,
{ message: "请选择资金来源",
required: true, }],
message: "请填写使用金额", money:[{
}, required: true,
], message: "请填写金额",
}, }],
}; // use_money: [{
}, // required: true,
methods: { // message: "请填写已使用金额",
show() { // }],
this.isShow = true; },
}, }
hidden() { },
this.isShow = false; methods: {
}, show() {
init() { this.isShow = true;
this.form = { },
plan_id:'', hidden() {
use_money:'' this.isShow = false;
}; },
}, init() {
setForm(key = [], value = []) { this.form = {
if (key instanceof Array) { reason: '',
key.forEach((key, index) => { plan_id: '',
this.form[key] = value[index] ?? ""; money:'',
}); // use_money: '',
} plan_title: ''
if (typeof key === "string") { };
this.form[key] = value; },
} setForm(key = [], value = []) {
if (!key) { if (key instanceof Array) {
this.init(); key.forEach((key, index) => {
} this.form[key] = value[index] ?? "";
}, });
async getDetail() { }
const res = await detailActual({ id: this.id }); if (typeof key === "string") {
this.$integrateData(this.form, res); this.form[key] = value;
this.form.plan_title = res.plan?res.plan.name:'' }
}, if (!key) {
getPlanId(e){ this.init();
console.log("e",e) }
this.form.plan_id = e.plan_id?e.plan_id:'' },
this.form.plan_title = e.plan_title?e.plan_title:'' async getDetail() {
}, const res = await detailActual({
submit() { id: this.id
if (this.type === "add") { });
if (this.form.hasOwnProperty("id")) { this.$integrateData(this.form, res);
delete this.form.id; this.form.plan_title = res.plan ? res.plan.name : ''
} },
} getPlanId(e) {
if (this.type === "editor") { console.log("e", e)
Object.defineProperty(this.form, "id", { this.form.plan_id = e.plan_id ? e.plan_id : ''
value: this.id, this.form.plan_title = e.plan_title ? e.plan_title : ''
enumerable: true, },
configurable: true, submit() {
writable: true, if (this.type === "add") {
}); if (this.form.hasOwnProperty("id")) {
} delete this.form.id;
editorActual(this.form).then((res) => { }
this.$message({ }
type: "success", if (this.type === "editor") {
message: Object.defineProperty(this.form, "id", {
this.type === "add" value: this.id,
? "新增实际使用金额" enumerable: true,
: "编辑实际使用金额" + "成功", configurable: true,
}); writable: true,
this.isShow = false; });
this.$emit("refresh"); }
}); editorActual(this.form).then((res) => {
}, this.$message({
}, type: "success",
watch: { message: this.type === "add" ?
isShow(val) { "新增资金调节记录" :
if (val) { "编辑资金调节记录" + "成功",
if (this.type === "editor") { });
this.getDetail(); this.isShow = false;
} this.$emit("refresh");
} else { });
this.id = ""; },
this.type = ""; },
this.init(); watch: {
this.$refs["dialog"].clearValidate(); isShow(val) {
delete this.form.id; if (val) {
} if (this.type === "editor") {
}, this.getDetail();
}, }
}; } else {
</script> this.id = "";
this.type = "";
<style scoped lang="scss"> this.init();
.xy-table-item-label{ this.$refs["dialog"].clearValidate();
width: 180px; delete this.form.id;
} }
::v-deep .el-input__inner { },
text-align: left; },
} };
::v-deep .planTitle{ </script>
width:300px;
display: flex; <style scoped lang="scss">
background-color: #FFF; .xy-table-item-label {
background-image: none; width: 180px;
border-radius: 4px; }
border: 1px solid #DCDFE6;
-webkit-box-sizing: border-box; ::v-deep .el-input__inner {
box-sizing: border-box; text-align: left;
color: #606266; }
display: inline-block;
font-size: inherit; ::v-deep .planTitle {
height: 40px; width: 300px;
line-height: 40px; display: flex;
outline: 0; background-color: #FFF;
padding: 0 15px; background-image: none;
} border-radius: 4px;
.img__delete { border: 1px solid #DCDFE6;
transform: scale(0.8, 0.8); -webkit-box-sizing: border-box;
box-sizing: border-box;
position: absolute; color: #606266;
top: 4px; display: inline-block;
right: 4px; font-size: inherit;
} height: 40px;
line-height: 40px;
::v-deep .avatar-uploader .el-upload { outline: 0;
border: 1px dashed #d9d9d9; padding: 0 15px;
border-radius: 6px; }
cursor: pointer;
position: relative; .img__delete {
overflow: hidden; transform: scale(0.8, 0.8);
}
position: absolute;
::v-deep .avatar-uploader .el-upload:hover { top: 4px;
border-color: #338de3; right: 4px;
} }
::v-deep .el-upload--picture-card { ::v-deep .avatar-uploader .el-upload {
font-size: 28px; border: 1px dashed #d9d9d9;
color: #8c939d; border-radius: 6px;
width: 80px !important; cursor: pointer;
height: 80px !important; position: relative;
line-height: 80px !important; overflow: hidden;
text-align: center; }
}
::v-deep .avatar-uploader .el-upload:hover {
::v-deep .avatar-uploader-icon { border-color: #338de3;
font-size: 28px; }
color: #8c939d;
width: 80px !important; ::v-deep .el-upload--picture-card {
height: 80px !important; font-size: 28px;
line-height: 80px !important; color: #8c939d;
text-align: center; width: 80px !important;
} height: 80px !important;
line-height: 80px !important;
::v-deep .avatar { text-align: center;
width: 80px !important; }
display: block;
border-radius: 6px; ::v-deep .avatar-uploader-icon {
} font-size: 28px;
color: #8c939d;
::v-deep .el-input__inner { width: 80px !important;
text-align: left; height: 80px !important;
} line-height: 80px !important;
text-align: center;
}
::v-deep .avatar {
width: 80px !important;
display: block;
border-radius: 6px;
}
::v-deep .el-input__inner {
text-align: left;
}
</style> </style>

@ -0,0 +1,177 @@
<template>
<div>
<xy-dialog ref="dialog" :is-show.sync="isShow" type="form" title="确认执行" :form="form" :rules="rules"
@submit="submit">
<template v-slot:use_money>
<div class="xy-table-item">
<div class="xy-table-item-label"><span style="color: red; font-weight: 600; padding-right: 4px">*</span>使用金额:
</div>
<div class="xy-table-item-content">
<el-input v-model="form.use_money" clearable placeholder="请输入本次使用金额" style="width: 300px"></el-input>
</div>
</div>
</template>
<template v-slot:plan_act_links>
<div class="xy-table-item">
<div class="xy-table-item-label"><span style="color: red; font-weight: 600; padding-right: 4px"></span>执行记录:
</div>
<div class="xy-table-item-content">
<xy-table style="width:500px" :list="form.plan_act_links" :table-item="table">
<template #btns>
<div></div>
</template>
</xy-table>
</div>
</div>
</template>
</xy-dialog>
</div>
</template>
<script>
import {
carryActual
} from "@/api/budget/actual";
export default {
components: {},
data() {
return {
isShow: false,
form: {
use_money: '',
plan_act_links: '',
contract_plan_act_temp_id: ''
},
table: [{
label: "使用金额",
prop: "use_money",
}, {
label: "执行时间",
prop: "created_at",
width: 180,
}],
rules: {
use_money: [{
required: true,
message: "请填写使用金额",
}],
},
}
},
methods: {
show() {
this.isShow = true;
},
hidden() {
this.isShow = false;
},
init() {
this.form = {
use_money: '',
plan_act_links: [],
contract_plan_act_temp_id: ''
};
},
setForm(contract_plan_act_temp_id, plan_act_links) {
this.form.contract_plan_act_temp_id = contract_plan_act_temp_id
this.form.plan_act_links = plan_act_links
},
submit() {
carryActual(this.form).then((res) => {
this.$message({
type: "success",
message: "执行成功",
});
this.isShow = false;
this.$emit("refresh");
});
},
},
watch: {
isShow(val) {
if (val) {
} else {
this.init();
this.$refs["dialog"].clearValidate();
}
},
},
};
</script>
<style scoped lang="scss">
.xy-table-item-label {
width: 180px;
}
::v-deep .el-input__inner {
text-align: left;
}
::v-deep .planTitle {
width: 300px;
display: flex;
background-color: #FFF;
background-image: none;
border-radius: 4px;
border: 1px solid #DCDFE6;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: #606266;
display: inline-block;
font-size: inherit;
height: 40px;
line-height: 40px;
outline: 0;
padding: 0 15px;
}
.img__delete {
transform: scale(0.8, 0.8);
position: absolute;
top: 4px;
right: 4px;
}
::v-deep .avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
::v-deep .avatar-uploader .el-upload:hover {
border-color: #338de3;
}
::v-deep .el-upload--picture-card {
font-size: 28px;
color: #8c939d;
width: 80px !important;
height: 80px !important;
line-height: 80px !important;
text-align: center;
}
::v-deep .avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 80px !important;
height: 80px !important;
line-height: 80px !important;
text-align: center;
}
::v-deep .avatar {
width: 80px !important;
display: block;
border-radius: 6px;
}
::v-deep .el-input__inner {
text-align: left;
}
</style>
Loading…
Cancel
Save