dev
xy 4 years ago
parent 03c01da9d6
commit 56da388794

@ -0,0 +1,34 @@
import request from '@/utils/request'
import * as url from 'url'
export function index(params) {
return request({
method: "get",
url: "/api/admin/target_type/index",
params
})
}
export function show(params) {
return request({
method: "get",
url: "/api/admin/target_type/show",
params
})
}
export function save(data) {
return request({
method: "post",
url: "/api/admin/target_type/save",
data
})
}
export function destroy(params) {
return request({
method: "get",
url: "/api/admin/target_type/destroy",
params
})
}

@ -0,0 +1,13 @@
import request from "@/utils/request"
export function getOutDetail({ tbname,out_contract_id }) {
return request({
method: 'get',
url: '/index.php',
requestBase: '/old',
params: {
s: "/Api/flowDetail",
tbname,
out_contract_id
}
})
}

@ -41,20 +41,45 @@ export default {
}, },
methods: { methods: {
footerRender(){ footerRender(){
if(this.type === 'form'){
return ( return (
<div> <div>
<Button ghost type="primary" on-click={this.reset}>重置</Button> <Button ghost type="primary" on-click={this.reset}>重置</Button>
<Button type="primary" on-click={this.submit}>确定</Button> <Button type="primary" on-click={this.submit}>{this.okText || '确定'}</Button>
</div> </div>
) )
}
if(this.type === 'normal'){
return (
<div>
<Button ghost type="primary" on-click={()=>{this.$emit('update:isShow',false)}}>取消</Button>
<Button type="primary" on-click={()=>{this.$emit('on-ok')}}>{this.okText || '确定'}</Button>
</div>
)
}
}, },
showChange(e){ showChange(e){
this.$emit('update:isShow',e) this.$emit('update:isShow',e)
}, },
cancelClick(){ validate(){
this.$emit('update:isShow',false) return new Promise((resolve,reject)=>{
this.$refs['elForm'].validate().then(res=>{
if(res){
resolve(res)
}else{
reject(res)
}
}).catch(err=>{
reject(err)
this.$Message.warning({
content:'请填写完整信息',
duration:1
})
})
})
}, },
reset(){ reset(){
this.$emit('reset')
if(this.type === 'normal'){ if(this.type === 'normal'){
return return
} }
@ -75,6 +100,16 @@ export default {
}, },
okClick(){ okClick(){
this.$emit('on-ok') this.$emit('on-ok')
},
clearValidate(){
this.$refs['elForm'].clearValidate()
}
},
watch:{
isShow(val){
if(!val && this.type === 'form'){
this.reset()
}
} }
}, },
render(h) { render(h) {
@ -88,7 +123,7 @@ export default {
footer slot: footer slot:
footerContent footerContent
*/ */
const {cancelClick,okText,okClick,footerRender,width,type,$scopedSlots,rules,form,showChange,isShow,title} = this const {okText,okClick,footerRender,width,type,$scopedSlots,rules,form,showChange,isShow,title} = this
return ( return (
<Modal <Modal
ok-text={okText} ok-text={okText}
@ -101,14 +136,16 @@ export default {
default(){ default(){
if(type === "form"){ if(type === "form"){
let formItems = [] let formItems = []
Object.keys(form).map((key)=>{ for(let key in form){
if(form.hasOwnProperty(key) && $scopedSlots[key]){
formItems.push( formItems.push(
<el-form-item <el-form-item
prop={key}> prop={key}>
{eval(`{$scopedSlots.${key} ? $scopedSlots.${key}() : ''}`)} {eval(`{$scopedSlots.${key} ? $scopedSlots.${key}() : ''}`)}
</el-form-item> </el-form-item>
) )
}) }
}
return ( return (
<el-form <el-form
style={title.length === 0 ? {'margin-top':'32px'} : {}} style={title.length === 0 ? {'margin-top':'32px'} : {}}
@ -143,20 +180,19 @@ export default {
return ( return (
<div <div
style={title.length === 0 ? {'margin-top':'32px'} : {}}> style={title.length === 0 ? {'margin-top':'32px'} : {}}>
{$scopedSlots.normalContent ? $scopedSlots.normalContent() : ''} {$scopedSlots.default ? $scopedSlots.default() : ''}
</div> </div>
) )
} }
}, },
header(){
if($scopedSlots.headerContent){
return $scopedSlots.headerContent()
}
},
footer(){ footer(){
{ {
if(type === 'form') return ($scopedSlots.footerContent ? $scopedSlots.footerContent() : footerRender()) if(type === 'form' || type === 'normal') return ($scopedSlots.footerContent ? $scopedSlots.footerContent() : footerRender())
if(type === 'normal') return (
<div>
<Button ghost type="primary" on-click={cancelClick}>取消</Button>
<Button type="primary" on-click={okClick}>确定</Button>
</div>
)
} }
} }
}}> }}>
@ -167,6 +203,72 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
.xy-table-item-label{
width: 140px;
text-align: right;
}
.xy-table-item-min{
position: relative;
&::after{
z-index: 1;
position: absolute;
right: 0;
top: 0;
content:'(分钟)'
}
::v-deep .el-input__clear{
position: relative;
right: 46px;
z-index: 2;
}
}
.xy-table-item-price{
position: relative;
&::after{
z-index: 1;
position: absolute;
right: 0;
top: 0;
content:'(元)'
}
::v-deep .el-input__clear{
padding: 0 6px;
position: relative;
right: 30px;
z-index: 2;
}
}
.xy-table-item-price-wan{
position: relative;
&::after{
padding: 0 6px;
position: absolute;
right: 0;
top: 0;
content:'(万元)'
}
::v-deep .el-input__clear{
position: relative;
right: 46px;
z-index: 2;
}
}
.xy-table-item-price-percent{
position: relative;
&::after{
padding: 0 6px;
position: absolute;
right: 0;
top: 0;
content:'%'
}
::v-deep .el-input__clear{
position: relative;
right: 46px;
z-index: 2;
}
}
.vertical-center-modal{ .vertical-center-modal{
display: flex; display: flex;
align-items: center; align-items: center;
@ -179,13 +281,14 @@ export default {
.ivu-modal-body{ .ivu-modal-body{
max-height: 65vh !important; max-height: 65vh !important;
min-height: 300px; min-height: 300px;
overflow-y: scroll; overflow: scroll;
} }
.xy-table-item{ .xy-table-item{
display: flex; display: flex;
align-items: center; align-items: center;
margin-right: 80px;
padding-right: 80px;
&-label{ &-label{
padding: 0 20px; padding: 0 20px;
@ -194,7 +297,12 @@ export default {
} }
} }
.el-form-item{
flex-shrink: 0;
flex-basis: 50%;
}
.el-form-item__error{ .el-form-item__error{
white-space: nowrap;
word-break: keep-all !important; word-break: keep-all !important;
top: 100% !important; top: 100% !important;
left: calc(100% - 80px) !important; left: calc(100% - 80px) !important;

@ -212,7 +212,7 @@ export default {
grid-template-rows: 50px; grid-template-rows: 50px;
grid-template-areas: "logo . menu . user"; grid-template-areas: "logo . menu . user";
z-index: 9999; z-index: 1000;
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;

@ -47,6 +47,14 @@ import moment from 'moment'
Vue.prototype.$moment = moment; Vue.prototype.$moment = moment;
Vue.prototype.$integrateData = (target,value) => {
for(let i in target){
if(target.hasOwnProperty(i) && value.hasOwnProperty(i)){
target[i] = value[i]
}
}
}
new Vue({ new Vue({
el: '#app', el: '#app',
router, router,

@ -20,7 +20,7 @@ const service = axios.create({
// request interceptor // request interceptor
service.interceptors.request.use( service.interceptors.request.use(
config => { config => {
config.baseURL = config.requestBase || process.env.VUE_APP_DOMIAN
if (!config.noloading) { if (!config.noloading) {
// do something before request is sent // do something before request is sent
loading = Loading.service({ loading = Loading.service({

@ -0,0 +1,199 @@
<template>
<div>
<xy-dialog
ref="dialog"
:is-show.sync="isShow"
type="form"
:title="type === 'add' ? '新增绩效指标类型' : '编辑绩效指标类型'"
:form="form"
:rules="rules"
@submit="submit"
>
<template v-slot:pid>
<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-cascader
:key="cascaderId_pid"
clearable
style="width: 300px"
:show-all-levels="false"
v-model="form.pid"
:options="pids"
:props="{ value: 'id', label: 'name', checkStrictly: true }"
@change="pidCascaderHandler"
></el-cascader>
</div>
</div>
</template>
<template v-slot:name>
<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.name"
clearable
placeholder="请输入名称"
style="width: 300px"
></el-input>
</div>
</div>
</template>
<template v-slot:remark>
<div class="xy-table-item">
<div class="xy-table-item-label">备注 :</div>
<div class="xy-table-item-content">
<el-input
type="textarea"
:autosize="{ minRows: 2 }"
v-model="form.remark"
clearable
placeholder="请输入备注"
style="width: 300px"
></el-input>
</div>
</div>
</template>
<template v-slot:sort>
<div class="xy-table-item">
<div class="xy-table-item-label">排序 :</div>
<div class="xy-table-item-content">
<el-input-number
v-model="form.sort"
clearable
placeholder="请输入排序"
style="width: 300px"
:controls="false"
:precision="0"
></el-input-number>
</div>
</div>
</template>
</xy-dialog>
</div>
</template>
<script>
import { show, save } from "@/api/achievements/types";
export default {
props: {
pids:Array
},
data() {
return {
isShow: false,
id: "",
type: "",
cascaderId_pid: "",
form: {
pid: "",
name: "",
remark: "",
sort: "",
},
rules: {
pid: [
{
required: true,
message: "请填写上级",
},
],
name: [
{
required: true,
message: "请填写名称",
},
],
},
};
},
methods: {
show() {
this.isShow = true;
},
hidden() {
this.isShow = false;
},
init() {
this.form = {
pid: "",
name: "",
remark: "",
sort: "",
};
},
pidCascaderHandler(e) {
if (e.length > 0) {
this.form.pid = e.at(-1);
} else {
this.form.pid = "";
}
},
async getDetail() {
const res = await show({ id: this.id });
this.$integrateData(this.form, res);
},
submit() {
if (this.type === "add") {
if (this.form.hasOwnProperty("id")) {
delete this.form.id;
}
}
if (this.type === "editor") {
Object.defineProperty(this.form, "id", {
value: this.id,
enumerable: true,
configurable: true,
writable: true,
});
}
save(this.form).then((res) => {
this.$message({
type: 'success',
message: this.type === 'add' ? '新增绩效类型' : '编辑绩效类型' + '成功'
});
this.isShow = false;
this.$emit("refresh");
});
},
},
watch: {
isShow(val) {
if (val) {
if (this.type === "editor") {
this.getDetail();
}
} else {
this.id = "";
this.type = "";
this.init();
this.$refs["dialog"].clearValidate();
delete this.form.id;
}
},
pids() {
++this.cascaderId_pid;
},
},
};
</script>
<style scoped lang="scss">
::v-deep .el-input__inner {
text-align: left;
}
</style>

@ -0,0 +1,84 @@
<template>
<div style="padding: 0 20px;">
<lx-header icon="md-apps" style="margin-bottom: 10px; border: 0px; margin-top: 15px" text="绩效指标类型">
<div slot="content"></div>
<slot>
<div class="selects">
<div>
<span style="padding: 0 6px;word-break: keep-all;">
关键字
</span>
<Input v-model="select.keyword" placeholder="请输入关键字" style="width: 180px"></Input>
</div>
<Button style="margin-left: 10px" type="primary"
@click="">重置
</Button>
<Button style="margin-left: 10px" type="primary" @click="select.page = 1,getList()">查询</Button>
<Button style="margin-left: 10px" type="primary" @click="$refs['addTypes'].show()">新增</Button>
</div>
</slot>
</lx-header>
<xy-table :list="list" :table-item="table" >
</xy-table>
<div style="display: flex;justify-content: flex-end;">
<Page :total="total" @on-change="" show-elevator show-sizer @on-page-size-change="" />
</div>
<addTypes ref="addTypes" @refresh="getList"></addTypes>
</div>
</template>
<script>
import { index } from "@/api/achievements/types"
import addTypes from '@/views/achievements/components/addTypes.vue'
export default {
components:{
addTypes
},
data() {
return {
select:{
keyword: "",
page: 1,
page_size: 10
},
total: 0,
table: [
{
label: "一级指标名称"
},
{
label: "二级指标名称"
},
{
label: "三级指标名称"
}
],
list: []
}
},
methods: {
async getList() {
const res = await index(this.select)
this.list = res.data
}
},
computed: {},
created() {
this.getList()
}
}
</script>
<style scoped lang="scss">
.selects{
display: flex;
align-items: center;
flex-wrap: wrap;
}
</style>

@ -28,7 +28,7 @@
</el-option> </el-option>
</el-select> </el-select>
</span> </span>
<el-switch v-model="isTree" @change="changeTree" active-text="树形结构"> <el-switch v-model="isTree" @change="changeTree" active-text="树形结构" style="margin-left: 4px;">
</el-switch> </el-switch>
<Button style="margin-left: 10px" type="primary" @click="showAdd('')">新增</Button> <Button style="margin-left: 10px" type="primary" @click="showAdd('')">新增</Button>
<Button style="margin-left: 10px" type="primary" @click="getBudgets">查询</Button> <Button style="margin-left: 10px" type="primary" @click="getBudgets">查询</Button>

@ -0,0 +1,77 @@
<template>
<div style="padding: 0 20px;">
<lx-header icon="md-apps" style="margin-bottom: 10px; border: 0px; margin-top: 15px" text="绩效指标">
<div slot="content"></div>
<slot>
<div class="selects">
<div>
<span style="padding: 0 6px;word-break: keep-all;">
关键字
</span>
<Input v-model="select.keyword" placeholder="请输入关键字" style="width: 180px"></Input>
</div>
<Button style="margin-left: 10px" type="primary"
@click="">重置
</Button>
<Button style="margin-left: 10px" type="primary" @click="">查询</Button>
</div>
</slot>
</lx-header>
<xy-table :list="list" :table-item="table" >
</xy-table>
<div style="display: flex;justify-content: flex-end;">
<Page :total="total" @on-change="" show-elevator show-sizer @on-page-size-change="" />
</div>
</div>
</template>
<script>
export default {
data() {
return {
select:{
keyword: ""
},
total: 0,
table: [
{
label: "一级指标名称"
},
{
label: "二级指标名称"
},
{
label: "三级指标名称"
},
{
label: "计算符号"
},
{
label: "半年(程)指标值"
},
{
label: "全年(程)指标值"
},
{
label: "单位"
}
],
list: []
}
},
methods: {},
computed: {}
}
</script>
<style scoped lang="scss">
.selects{
display: flex;
align-items: center;
flex-wrap: wrap;
}
</style>

@ -1,7 +1,12 @@
<template> <template>
<div v-if="detail"> <div v-if="detail">
<!-- 合同详情--> <!-- 合同详情-->
<xy-dialog :is-show.sync="isShowDetail" type="normal" title="详情" class="contract-detail"> <xy-dialog
:is-show.sync="isShowDetail"
type="normal"
title="详情"
class="contract-detail"
>
<template v-slot:normalContent> <template v-slot:normalContent>
<div class="base-info"> <div class="base-info">
<div class="base-info-title">项目基本信息</div> <div class="base-info-title">项目基本信息</div>
@ -11,41 +16,58 @@
</div> </div>
<div class="base-info-item"> <div class="base-info-item">
<div class="base-info-item-title">项目类型</div> <div class="base-info-item-title">项目类型</div>
<div class="base-info-item-content">{{typeFormatter(detail.type)}}</div> <div class="base-info-item-content">
{{ typeFormatter(detail.type) }}
</div> </div>
<div style="display: flex;justify-content: space-between;"> </div>
<div style="display: flex; justify-content: space-between">
<div class="base-info-item" style="flex-basis: 50%"> <div class="base-info-item" style="flex-basis: 50%">
<div class="base-info-item-title">采购形式</div> <div class="base-info-item-title">采购形式</div>
<div class="base-info-item-content">{{detail.purchase_way.value}}</div> <div class="base-info-item-content" v-if="detail.purchase_way">
{{ detail.purchase_way.value }}
</div>
</div> </div>
<div class="base-info-item" style="flex-basis: 50%"> <div class="base-info-item" style="flex-basis: 50%">
<div class="base-info-item-title">采购方式</div> <div class="base-info-item-title">采购方式</div>
<div class="base-info-item-content">{{detail.purchase_type.value}}</div> <div class="base-info-item-content" v-if="detail.purchase_type">
{{ detail.purchase_type.value }}
</div>
</div> </div>
</div> </div>
<div style="display: flex;justify-content: space-between;"> <div style="display: flex; justify-content: space-between">
<div class="base-info-item" style="flex-basis: 50%"> <div class="base-info-item" style="flex-basis: 50%">
<div class="base-info-item-title">签订时间</div> <div class="base-info-item-title">签订时间</div>
<div class="base-info-item-content">{{ detail.date }}</div> <div class="base-info-item-content">{{ detail.date }}</div>
</div> </div>
<div class="base-info-item" style="flex-basis: 50%"> <div class="base-info-item" style="flex-basis: 50%">
<div class="base-info-item-title">服务时间</div> <div class="base-info-item-title">服务时间</div>
<div class="base-info-item-content">{{detail.start_date}}至{{detail.end_date}}</div> <div class="base-info-item-content">
{{ detail.start_date }}至{{ detail.end_date }}
</div>
</div> </div>
</div> </div>
<div class="base-info-item"> <div class="base-info-item">
<div class="base-info-item-title">项目预算</div> <div class="base-info-item-title">项目预算</div>
<div class="base-info-item-content">{{moneyFormat(detail.plan_price)}}</div> <div class="base-info-item-content">
{{ moneyFormat(detail.plan_price) }}
</div>
<div class="base-info-item-unit">(元)</div> <div class="base-info-item-unit">(元)</div>
</div> </div>
<div class="base-info-item"> <div class="base-info-item">
<div class="base-info-item-title">资金渠道</div> <div class="base-info-item-title">资金渠道</div>
<div class="base-info-item-content">{{moneyWayFormatter(detail.money_way_detail)}}</div> <div class="base-info-item-content">
{{ moneyWayFormatter(detail.money_way_detail) }}
</div>
</div> </div>
</div> </div>
<div class="link-budget-plan"> <div class="link-budget-plan">
<div class="link-budget-plan-title">关联预算计划</div> <div class="link-budget-plan-title">关联预算计划</div>
<xy-table :height="260" :table-item="linkBudgetPlanTable" :show-index="false" :list="detail.plans"> <xy-table
:height="260"
:table-item="linkBudgetPlanTable"
:show-index="false"
:list="detail.plans"
>
<template v-slot:btns> <template v-slot:btns>
<div></div> <div></div>
</template> </template>
@ -55,7 +77,9 @@
<div class="sign-info-title">签订信息</div> <div class="sign-info-title">签订信息</div>
<div class="sign-info-item"> <div class="sign-info-item">
<div class="sign-info-item-title">合同金额</div> <div class="sign-info-item-title">合同金额</div>
<div class="sign-info-item-content">{{moneyFormat(detail.money)}}</div> <div class="sign-info-item-content">
{{ moneyFormat(detail.money) }}
</div>
<div class="sign-info-item-unit">(元)</div> <div class="sign-info-item-unit">(元)</div>
</div> </div>
<div style="display: flex; justify-content: space-between"> <div style="display: flex; justify-content: space-between">
@ -65,33 +89,126 @@
</div> </div>
<div class="sign-info-item" style="flex-basis: 50%"> <div class="sign-info-item" style="flex-basis: 50%">
<div class="sign-info-item-title">执行部门</div> <div class="sign-info-item-title">执行部门</div>
<div class="sign-info-item-content">{{detail.carry_department}}</div> <div class="sign-info-item-content">
{{ detail.carry_department }}
</div>
</div>
</div>
</div>
<div class="out-sign-info" v-if="outContractDetail.flow_detail">
<div class="sign-info-title">合同会签信息</div>
<div class="sign-info-item">
<div class="sign-info-item-title">合同金额</div>
<div class="sign-info-item-content">
{{ moneyFormat(outContractDetail.flow_detail.total) }}
</div>
<div class="sign-info-item-unit">(元)</div>
</div>
<div style="display: flex; justify-content: space-between">
<div class="sign-info-item" style="flex-basis: 50%">
<div class="sign-info-item-title">甲方</div>
<div class="sign-info-item-content">
{{ outContractDetail.flow_detail.jiafang }}
</div>
</div>
<div class="sign-info-item" style="flex-basis: 50%">
<div class="sign-info-item-title">乙方</div>
<div class="sign-info-item-content">
{{ outContractDetail.flow_detail.yifang }}
</div>
</div>
</div>
</div>
<div class="out-sign-info" v-if="outCaigouDetail.flow_detail">
<div class="sign-info-title">采购信息</div>
<div class="sign-info-item">
<div class="sign-info-item-title">名称</div>
<div class="sign-info-item-content">
{{ outCaigouDetail.flow_detail.content_name }}
</div>
</div>
<div class="sign-info-item" style="flex-basis: 50%">
<div class="sign-info-item-title">规格</div>
<div class="sign-info-item-content">
{{ outCaigouDetail.flow_detail.content_guige }}
</div>
</div>
<div class="sign-info-item" style="flex-basis: 50%">
<div class="sign-info-item-title">类型</div>
<div class="sign-info-item-content">
{{ outCaigouDetail.flow_detail.type }}
</div>
</div>
<div class="sign-info-item" style="flex-basis: 50%">
<div class="sign-info-item-title">预算</div>
<div class="sign-info-item-content">
{{ moneyFormat(outCaigouDetail.flow_detail.yusuan) }}
</div> </div>
</div> </div>
</div> </div>
<div class="pay-plan"> <div class="pay-plan">
<div class="pay-plan-title">付款计划</div> <div class="pay-plan-title">付款计划</div>
<xy-table :height="240" :list="signPlan" :table-item="planTable" :show-index="false" :btn-width="130" <xy-table
:height="240"
:list="signPlan"
:table-item="planTable"
:show-index="false"
:btn-width="130"
@delete="deletePayPlan" @delete="deletePayPlan"
@editor="(row)=>{$refs['detailContractSign'].planId = row.id;$refs['detailContractSign'].isShow = true}"> @editor="
(row) => {
$refs['detailContractSign'].planId = row.id;
$refs['detailContractSign'].isShow = true;
}
"
>
</xy-table> </xy-table>
</div> </div>
<div class="related-processes"> <div class="related-processes">
<div class="related-processes-title">相关流程进展查看</div> <div class="related-processes-title">相关流程进展查看</div>
<div class="related-processes-item"> <div class="related-processes-item">
<div @click="seeBuyProcess" :style="{'color':detail.purchase_last_flow_id ? 'green' : 'red'}">采购流程查看</div> <div
<div @click="seeSignProcess" :style="{'color':detail.join_last_flow_id ? 'green' : 'red'}">合同会签流程查看</div> @click="toOutDetail('caigou')"
<template v-if="detail.purchase_way.remark === 'true'"> :style="{ color: detail.purchase_last_flow_id ? 'green' : 'red' }"
<div @click="seeBidding" :style="{'color':detail.invite_last_flow_id ? 'green' : 'red'}">招标审批流程查看</div> >
采购流程查看
</div>
<div
@click="toOutDetail('hetong')"
:style="{ color: detail.join_last_flow_id ? 'green' : 'red' }"
>
合同会签流程查看
</div>
<template
v-if="
detail.purchase_way && detail.purchase_way.remark === 'true'
"
>
<div
@click="seeBidding"
:style="{ color: detail.invite_last_flow_id ? 'green' : 'red' }"
>
招标审批流程查看
</div>
</template> </template>
<template v-if="detail.is_plan != 1"> <template v-if="detail.is_plan != 1">
<div @click="seeAskProcess" :style="{'color':detail.req_last_flow_id ? 'green' : 'red'}">请示流程查看</div> <div
@click="seeAskProcess"
:style="{ color: detail.req_last_flow_id ? 'green' : 'red' }"
>
请示流程查看
</div>
</template> </template>
</div> </div>
</div> </div>
<div class="journal"> <div class="journal">
<div class="journal-title">日志</div> <div class="journal-title">日志</div>
<xy-table :height="240" :table-item="journalTable" :list="detail.log" :show-index="false"> <xy-table
:height="240"
:table-item="journalTable"
:list="detail.log"
:show-index="false"
>
<template v-slot:btns> <template v-slot:btns>
<div></div> <div></div>
</template> </template>
@ -104,38 +221,30 @@
</template> </template>
</xy-dialog> </xy-dialog>
<detailContractSign ref="detailContractSign" @editorSuccess="getDetail(id)"></detailContractSign> <detailContractSign
ref="detailContractSign"
@editorSuccess="getDetail(id)"
></detailContractSign>
</div> </div>
</template> </template>
<script> <script>
import { import { detailContract } from "@/api/contract/contract";
detailContract
} from "@/api/contract/contract";
import { import {
delContractSign, delContractSign,
getContractSign getContractSign,
} from "@/api/contractSign/contractSign" } from "@/api/contractSign/contractSign";
import { import { parseTime } from "@/utils";
parseTime import { getOatoken } from "@/api/oatoken";
} from "@/utils" import { Message } from "element-ui";
import { import { moneyFormatter } from "@/utils";
getOatoken import { getparameter } from "@/api/system/dictionary";
} from "@/api/oatoken"; import { getOutDetail } from "@/api/out";
import {
Message import detailContractSign from "./detailContractSign";
} from "element-ui";
import {
moneyFormatter
} from "@/utils"
import {
getparameter
} from "@/api/system/dictionary";
import detailContractSign from "./detailContractSign"
export default { export default {
components: { components: {
detailContractSign detailContractSign,
}, },
data() { data() {
return { return {
@ -143,18 +252,19 @@
width: 0, width: 0,
height: 0, height: 0,
top: 0, top: 0,
left: 0 left: 0,
}, },
//合同详情 //合同详情
id: '', id: "",
detail: null, detail: null,
isShowDetail: false, isShowDetail: false,
linkBudgetPlanTable: [{ linkBudgetPlanTable: [
{
label: "ID", label: "ID",
sortable: false, sortable: false,
prop: 'id', prop: "id",
width: 130 width: 130,
}, },
{ {
label: "类型", label: "类型",
@ -163,121 +273,129 @@
customFn: (row) => { customFn: (row) => {
const typeSwitch = (type) => { const typeSwitch = (type) => {
{ {
let res = this.planTypes.filter(item => { let res = this.planTypes.filter((item) => {
return item.id === type return item.id === type;
}) });
return res[0]?.value || '未知' return res[0]?.value || "未知";
} }
} };
return ( < return (
div > <div>
< <Tag color="primary"> {typeSwitch(row.type)} </Tag>{" "}
Tag color = "primary" > { </div>
typeSwitch(row.type) );
} < },
/Tag> <
/div>
)
}
}, },
{ {
label: "项目", label: "项目",
width: 140, width: 140,
sortable: false, sortable: false,
prop: 'name' prop: "name",
}, },
{ {
label: "金额", label: "金额",
sortable: false, sortable: false,
prop: 'money', prop: "money",
align: 'right', align: "right",
minWidth: 200, minWidth: 200,
formatter: (v1, v2, value) => { formatter: (v1, v2, value) => {
return Number(value).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,') return Number(value)
} .toFixed(2)
.replace(/(\d)(?=(\d{3})+\.)/g, "$1,");
},
}, },
{ {
label: '使用金额', label: "使用金额",
sortable: false, sortable: false,
prop: 'useMoney', prop: "useMoney",
align: 'right', align: "right",
minWidth: 200, minWidth: 200,
formatter: (v1, v2, value) => { formatter: (v1, v2, value) => {
return Number(value).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,') return Number(value)
} .toFixed(2)
} .replace(/(\d)(?=(\d{3})+\.)/g, "$1,");
},
},
], ],
journalTable: [{ journalTable: [
label: 'ID', {
label: "ID",
sortable: false, sortable: false,
prop: 'id' prop: "id",
}, },
{ {
label: "日志类型", label: "日志类型",
sortable: false, sortable: false,
prop: 'type' prop: "type",
}, },
{ {
label: "日志内容", label: "日志内容",
sortable: false, sortable: false,
prop: 'remark' prop: "remark",
}, },
{ {
label: "操作人", label: "操作人",
sortable: false, sortable: false,
prop: 'admin.name' prop: "admin.name",
}, },
{ {
label: "时间", label: "时间",
sortable: false, sortable: false,
prop: 'created_at', prop: "created_at",
width: 160, width: 160,
formatter: (cell, data, value) => { formatter: (cell, data, value) => {
return parseTime(new Date(value), '{y}-{m}-{d} {h}:{i}') return parseTime(new Date(value), "{y}-{m}-{d} {h}:{i}");
} },
} },
], ],
signPlan: [], signPlan: [],
planTypes: [], planTypes: [],
planTable: [{ planTable: [
prop: 'date', {
label: '日期', prop: "date",
label: "日期",
sortable: false, sortable: false,
formatter: (cell, data, value) => { formatter: (cell, data, value) => {
return parseTime(new Date(value), '{y}-{m}-{d}') return parseTime(new Date(value), "{y}-{m}-{d}");
} },
}, },
{ {
prop: 'money', prop: "money",
label: '金额(元)', label: "金额(元)",
align: 'right', align: "right",
minWidth: 180, minWidth: 180,
sortable: false, sortable: false,
formatter: (v1, v2, value) => { formatter: (v1, v2, value) => {
return Number(value).toFixed(2).replace(/(\d)(?=(\d{3})+\.)/g, '$1,') return Number(value)
} .toFixed(2)
.replace(/(\d)(?=(\d{3})+\.)/g, "$1,");
},
}, },
{ {
prop: 'content', prop: "content",
label: '内容', label: "内容",
align: 'left', align: "left",
sortable: false, sortable: false,
}, },
{ {
prop: 'remark', prop: "remark",
label: '备注', label: "备注",
align: 'left', align: "left",
sortable: false, sortable: false,
} },
] ],
}
//out获取到信息
outContractDetail: {},
outCaigouDetail: {},
};
}, },
methods: { methods: {
async getPlanTypes() { async getPlanTypes() {
const res = await getparameter({ const res = await getparameter({
number: 'money_way' number: "money_way",
}) });
this.planTypes = res.detail this.planTypes = res.detail;
}, },
async seeBuyProcess() { async seeBuyProcess() {
@ -285,107 +403,110 @@
Message({ Message({
type: "warning", type: "warning",
message: "还未进行采购申请", message: "还未进行采购申请",
duration: 2000 duration: 2000,
}) });
return return;
} }
let res = await getOatoken() let res = await getOatoken();
let url = let url = `${process.env.VUE_APP_OUT_URL}/admin/flow/view/${this.detail.purchase_last_flow_id}?oatoken=${res.oatoken}`;
`${process.env.VUE_APP_OUT_URL}/admin/flow/view/${this.detail.purchase_last_flow_id}?oatoken=${res.oatoken}` let seeBuy = window.open(
let seeBuy = window.open(url, 'seeBuy', url,
"seeBuy",
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0` `top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
) );
}, },
async seeBidding() { async seeBidding() {
if (!this.detail?.invite_last_flow_id) { if (!this.detail?.invite_last_flow_id) {
Message({ Message({
type: "warning", type: "warning",
message: "还未进行招标申请", message: "还未进行招标申请",
duration: 2000 duration: 2000,
}) });
return return;
} }
let res = await getOatoken() let res = await getOatoken();
let url = let url = `${process.env.VUE_APP_OUT_URL}/admin/flow/view/${this.detail.invite_last_flow_id}?oatoken=${res.oatoken}`;
`${process.env.VUE_APP_OUT_URL}/admin/flow/view/${this.detail.invite_last_flow_id}?oatoken=${res.oatoken}` let seeBidding = window.open(
let seeBidding = window.open(url, 'seeBidding', url,
"seeBidding",
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0` `top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
) );
}, },
async seeSignProcess() { async seeSignProcess() {
if (!this.detail?.join_last_flow_id) { if (!this.detail?.join_last_flow_id) {
Message({ Message({
type: "warning", type: "warning",
message: "还未进行会签申请", message: "还未进行会签申请",
duration: 2000 duration: 2000,
}) });
return return;
} }
let res = await getOatoken() let res = await getOatoken();
let url = let url = `${process.env.VUE_APP_OUT_URL}/admin/flow/view/${this.detail.join_last_flow_id}?oatoken=${res.oatoken}`;
`${process.env.VUE_APP_OUT_URL}/admin/flow/view/${this.detail.join_last_flow_id}?oatoken=${res.oatoken}` let seeSign = window.open(
let seeSign = window.open(url, 'seeSign', url,
"seeSign",
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0` `top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
) );
}, },
async seeAskProcess() { async seeAskProcess() {
if (!this.detail?.req_last_flow_id) { if (!this.detail?.req_last_flow_id) {
Message({ Message({
type: "warning", type: "warning",
message: "还未进行请示申请", message: "还未进行请示申请",
duration: 2000 duration: 2000,
}) });
return return;
} }
let res = await getOatoken() let res = await getOatoken();
let url = let url = `${process.env.VUE_APP_OUT_URL}/admin/flow/view/${this.detail.req_last_flow_id}?oatoken=${res.oatoken}`;
`${process.env.VUE_APP_OUT_URL}/admin/flow/view/${this.detail.req_last_flow_id}?oatoken=${res.oatoken}` let seeAsk = window.open(
let seeAsk = window.open(url, 'seeAsk', url,
"seeAsk",
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0` `top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
) );
}, },
async getDetail(id) { async getDetail(id) {
this.id = id this.id = id;
let res = await detailContract({ let res = await detailContract({
id: id id: id,
}) });
this.detail = res this.detail = res;
let plans = res.plans let plans = res.plans;
let linkPlan = res.plan_link let linkPlan = res.plan_link;
let linkPlanTable = plans.map(item => { let linkPlanTable = plans.map((item) => {
let res = linkPlan.filter(item1 => { let res = linkPlan.filter((item1) => {
return item1.plan_id === item.id return item1.plan_id === item.id;
})[0] })[0];
return { return {
id: item.id, id: item.id,
type: item.type, type: item.type,
name: item.name, name: item.name,
money: item.money, money: item.money,
useMoney: res.use_money useMoney: res.use_money,
} };
}) });
this.detail.plans = linkPlanTable this.detail.plans = linkPlanTable;
console.log(this.detail) console.log(this.detail);
let plan = await getContractSign({ let plan = await getContractSign({
contract_id: id contract_id: id,
}) });
this.signPlan = plan.data this.signPlan = plan.data;
}, },
//删除付款计划 //删除付款计划
deletePayPlan(row) { deletePayPlan(row) {
delContractSign({ delContractSign({
id: row.id id: row.id,
}).then(res => { }).then((res) => {
this.getSignPlan() this.getSignPlan();
Message({ Message({
type: 'success', type: "success",
message: "操作成功" message: "操作成功",
}) });
}) });
}, },
}, },
computed: { computed: {
@ -393,50 +514,65 @@
return function (type) { return function (type) {
switch (type) { switch (type) {
case 1: case 1:
return "服务" return "服务";
break; break;
case 2: case 2:
return "货物" return "货物";
break; break;
case 3: case 3:
return "工程" return "工程";
break; break;
case 4: case 4:
return '其他' return "其他";
break; break;
default: default:
return "未知" return "未知";
}
} }
};
}, },
moneyWayFormatter() { moneyWayFormatter() {
return function (arr) { return function (arr) {
let res = arr.map(item => { let res = arr.map((item) => {
return item.value return item.value;
}) });
return res.toString() return res.toString();
} };
}, },
moneyFormat() { moneyFormat() {
return function (money) { return function (money) {
return moneyFormatter(money) return moneyFormatter(money);
};
},
},
watch: {
isShowDetail(val) {
if (val) {
getOutDetail({ tbname: "hetong", out_contract_id: this.id }).then(
(res) => {
this.outContractDetail = res;
} }
);
getOutDetail({ tbname: "caigou", out_contract_id: this.id }).then(
(res) => {
console.log(11111, res);
this.outCaigouDetail = res;
} }
);
}
},
}, },
mounted() { mounted() {
this.window.width = screen.availWidth * 0.95 this.window.width = screen.availWidth * 0.95;
this.window.height = screen.availHeight * 0.95 this.window.height = screen.availHeight * 0.95;
this.window.top = (window.screen.height - 30 - this.window.height) / 2 this.window.top = (window.screen.height - 30 - this.window.height) / 2;
this.window.left = (window.screen.width - 10 - this.window.width) / 2 this.window.left = (window.screen.width - 10 - this.window.width) / 2;
} },
} };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.contract-detail { .contract-detail {
.base-info { .base-info {
&-title { &-title {
font-weight: 600; font-weight: 600;
@ -449,21 +585,19 @@
margin-top: 8px; margin-top: 8px;
&-title { &-title {
padding: 0 20px; padding: 0 20px;
} }
&-content {} &-content {
}
&-unit { &-unit {
margin-left: 20px; margin-left: 20px;
} }
} }
} }
.link-budget-plan { .link-budget-plan {
margin-top: 20px; margin-top: 20px;
&-title { &-title {
@ -474,7 +608,6 @@
} }
.sign-info { .sign-info {
&-title { &-title {
@extend .link-budget-plan-title; @extend .link-budget-plan-title;
} }
@ -495,7 +628,10 @@
} }
} }
} }
.out-sign-info {
margin-top: 20px;
@extend .sign-info;
}
.pay-plan { .pay-plan {
margin-top: 20px; margin-top: 20px;
@ -505,7 +641,6 @@
} }
.related-processes { .related-processes {
margin-top: 20px; margin-top: 20px;
&-title { &-title {
@ -526,7 +661,6 @@
} }
.journal { .journal {
margin-top: 20px; margin-top: 20px;
&-title { &-title {

@ -264,8 +264,9 @@
</div> </div>
<div class="xy-table-item-content"> <div class="xy-table-item-content">
<el-switch v-model="form.is_simple" active-text="是" inactive-text="否" :active-value="1" :inactive-value="0"/> <el-switch v-model="form.is_simple" active-text="是" inactive-text="否" :active-value="1" :inactive-value="0"/>
<span>(水电煤、报刊订阅、网络通讯、车辆使用等费用付款)</span>
</div> </div>
<div>(水电煤、报刊订阅、网络通讯、车辆使用等费用付款)</div>
</div> </div>
</template> </template>
<template v-slot:supply v-if="form.is_simple"> <template v-slot:supply v-if="form.is_simple">
@ -1385,7 +1386,7 @@ export default {
} }
let res = await getOatoken() let res = await getOatoken()
let url = let url =
`${process.env.VUE_APP_OUT_URL}?s=/flow/add/modid/8&oatoken=${res.oatoken}&out_contract_id=${row.id}&contract_json=${JSON.stringify(baseInfo)}` `${process.env.VUE_APP_OUT_OLD}?s=/flow/add/modid/8&oatoken=${res.oatoken}&out_contract_id=${row.id}&contract_json=${JSON.stringify(baseInfo)}`
let bidding = window.open(url, 'bidding', let bidding = window.open(url, 'bidding',
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0` `top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
) )
@ -1400,11 +1401,18 @@ export default {
"type": this.type.filter(item => { "type": this.type.filter(item => {
return item.value === row.type return item.value === row.type
})[0]?.label, })[0]?.label,
"yusuan": row?.plan_price "yusuan": row?.plan_price.toString(),
"zijinlaiyuan":row.money_way_detail.reduce((prev,cur,index) => {
if(index === 0) {
return cur.value
}else{
return prev + "," + cur.value
}
},"")
} }
let res = await getOatoken() let res = await getOatoken()
let url = let url =
`${process.env.VUE_APP_OUT_URL}?s=/flow/add/modid/8&oatoken=${res.oatoken}&out_contract_id=${row.id}&contract_json=${JSON.stringify(baseInfo)}` `${process.env.VUE_APP_OUT_OLD}?s=/flow/add/modid/8&username=${this.$store.state.user.username}&out_contract_id=${row.id}&contract_json=${JSON.stringify(baseInfo)}`
let buyProcess = window.open(url, 'buyProcess', let buyProcess = window.open(url, 'buyProcess',
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0` `top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
) )
@ -1419,7 +1427,7 @@ export default {
} }
let res = await getOatoken() let res = await getOatoken()
let url = let url =
`${process.env.VUE_APP_OUT_URL}?s=/flow/add/modid/9&oatoken=${res.oatoken}&out_contract_id=${row.id}&contract_json=${JSON.stringify(baseInfo)}` `${process.env.VUE_APP_OUT_OLD}?s=/flow/add/modid/9&username=${this.$store.state.user.username}&out_contract_id=${row.id}&contract_json=${JSON.stringify(baseInfo)}`
let signProcess = window.open(url, 'signProcess', let signProcess = window.open(url, 'signProcess',
`top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0` `top=${this.window.top},left=${this.window.left},width=${this.window.width},height=${this.window.height},location=0`
) )
@ -1797,4 +1805,7 @@ export default {
content: '(元)' content: '(元)'
} }
} }
.xy-table-item-label{
width: 200px;
}
</style> </style>

@ -12,20 +12,20 @@
<router-link :to="`/statisticalReport/budgetProgress`"> <router-link :to="`/statisticalReport/budgetProgress`">
<div class="progress-card"> <div class="progress-card">
<div class="progress-card-item"> <div class="progress-card-item">
<div class="progress-card-item__num">{{moneyFormat(statistic.progress.money_total_1)}}</div> <div class="progress-card-item__num">{{moneyFormat(statistic.progress ? statistic.progress.money_total_1 : 0)}}</div>
<div class="progress-card-item__label">年初预算合计金额</div> <div class="progress-card-item__label">年初预算合计金额</div>
</div> </div>
<div class="progress-card-item"> <div class="progress-card-item">
<div class="progress-card-item__num">{{moneyFormat(statistic.progress.money_total_2)}}</div> <div class="progress-card-item__num">{{moneyFormat(statistic.progress ? statistic.progress.money_total_2 : 0)}}</div>
<div class="progress-card-item__label">调整后预算合计金额</div> <div class="progress-card-item__label">调整后预算合计金额</div>
</div> </div>
<div class="progress-card-item"> <div class="progress-card-item">
<div class="progress-card-item__num">{{moneyFormat(statistic.progress.use_money_total)}}</div> <div class="progress-card-item__num">{{moneyFormat(statistic.progress? statistic.progress.use_money_total : 0)}}</div>
<div class="progress-card-item__label">已支付金额</div> <div class="progress-card-item__label">已支付金额</div>
</div> </div>
<div class="progress-card-item"> <div class="progress-card-item">
<div class="progress-card-item__num"> <div class="progress-card-item__num">
{{toper(statistic.progress.money_total_1,statistic.progress.money_total_2,statistic.progress.use_money_total)}}% {{toper(statistic.progress ? statistic.progress.money_total_1 : 0,statistic.progress ? statistic.progress.money_total_2 : 0,statistic.progress? statistic.progress.use_money_total : 0)}}%
</div> </div>
<div class="progress-card-item__label">进展率</div> <div class="progress-card-item__label">进展率</div>
</div> </div>

@ -64,7 +64,7 @@ module.exports = {
target: process.env.VUE_APP_OUT_OLD, target: process.env.VUE_APP_OUT_OLD,
changeOrigin: true, //配置跨域 changeOrigin: true, //配置跨域
pathRewrite: { pathRewrite: {
['^' + process.env.VUE_APP_OUT_OLD]: process.env.VUE_APP_OUT_OLD ['^/old']: process.env.VUE_APP_OUT_OLD
} }
} }
} }

Loading…
Cancel
Save