表单详情页封装

master
toesbieya 6 years ago
parent d491804416
commit 20a8aa9ed1
  1. 1
      vue/src/asset/style/index.scss
  2. 220
      vue/src/component/AbstractForm/DetailForm.vue
  3. 16
      vue/src/component/biz/doc/DocDetailFooter.vue
  4. 34
      vue/src/component/biz/doc/DocDetailHeader.vue
  5. 22
      vue/src/mixin/docDetailMixin.js
  6. 26
      vue/src/view/purchase/inbound/detailPage.vue
  7. 26
      vue/src/view/purchase/order/detailPage.vue
  8. 26
      vue/src/view/sell/order/detailPage.vue
  9. 26
      vue/src/view/sell/outbound/detailPage.vue

@ -5,7 +5,6 @@
@import "element-ui";
@import "~@ele/style/index.scss";
@import "nprogress";
@import "detail-page";
body {
height: 100%;

@ -0,0 +1,220 @@
<script type="text/jsx">
import FormAnchor from "@/component/AbstractForm/FormAnchor"
import FormValidateInfo from "@/component/AbstractForm/FormValidateInfo"
const renderHeader = (h, title, description, extra, close) => (
<div class="detail-page-header">
<el-page-header on-back={close} content={title}/>
<el-row>
<el-row class="detail-page-header-left">
{description.map(({label, content}) => (
<el-col key={label} xs={24} sm={12}>
<span class="detail-page-header-description-label">{label}</span>
<span class="detail-page-header-description-content">{content}</span>
</el-col>
))}
</el-row>
<div class="detail-page-header-extra">
<div>
{extra.map(({title, content}) => (
<div key={title}>
<div class="detail-page-header-extra-title">{title}</div>
<div class="detail-page-header-extra-content">{content}</div>
</div>
))}
</div>
</div>
</el-row>
</div>
)
const renderFooter = (h, form, buttons, close) => (
<div class="detail-page-footer">
<div class="detail-page-footer-left">
<slot name="left"/>
</div>
<div class="detail-page-footer-right">
<FormValidateInfo form={form}/>
{renderButtons(h, buttons, close)}
</div>
</div>
)
const renderButtons = (h, buttons, close) => {
const list = buttons.map(({type, content, e}) =>
<el-button size="small" type={type} on-click={e}>{content}</el-button>
)
list.unshift(<el-button plain size="small" on-click={close}> </el-button>)
return list
}
export default {
name: "DetailForm",
functional: true,
props: {
loading: Boolean,
reference: Function,
anchors: {type: Array, default: () => []},
title: String,
description: {type: Array, default: () => []},
extra: {type: Array, default: () => []},
buttons: {type: Array, default: () => []},
},
render(h, context) {
const {
props: {loading, reference, anchors, title, description, extra, buttons},
listeners: {close},
children
} = context
const getFormRef = () => {
if (!reference) return null
const ref = reference()
if (!ref) return null
return ref.form
}
return (
<div v-loading={loading} class="detail-page">
{renderHeader(h, title, description, extra, close)}
<FormAnchor reference={reference} data={anchors}/>
{children}
{renderFooter(h, getFormRef, buttons, close)}
</div>
)
}
}
</script>
<style lang="scss">
@import "~@/asset/style/variables.scss";
.detail-page {
&.el-loading-parent--relative {
position: static !important;
}
&-header {
margin: -#{$page-view-margin} -#{$page-view-margin} 0 -#{$page-view-margin};
padding: 16px 32px 0 32px;
background: #fff;
border-bottom: 1px solid #e8eaec;
> .el-page-header {
padding: 0 0 24px 0;
.el-page-header__left:hover {
color: $--color-primary;
}
}
> .el-row {
display: flex;
width: 100%;
margin-bottom: 12px;
@media (max-width: 768px) {
display: block;
}
}
&-left {
width: 100%;
overflow: hidden;
.el-col {
margin-bottom: 16px;
}
}
&-extra {
min-width: 242px;
margin-left: 88px;
@media (max-width: 1200px) {
margin-left: 44px;
}
@media (max-width: 992px) {
margin-left: 20px;
}
@media (max-width: 768px) {
margin-left: 0;
}
> div {
display: flex;
justify-content: space-between;
width: 200px;
}
&-title {
margin-bottom: 4px;
color: rgba(0, 0, 0, .45);
font-size: 14px;
}
&-content {
margin-top: 12px;
color: rgba(0, 0, 0, .85);
font-size: 24px;
}
}
&-description {
span {
display: inline-flex;
align-items: baseline;
}
&-label {
color: rgba(0, 0, 0, .85);
font-weight: 400;
font-size: 14px;
line-height: 1.5715;
text-align: start;
}
&-content {
color: rgba(0, 0, 0, .65);
font-size: 14px;
line-height: 1.5715;
}
}
}
> .el-form > .el-row > .el-card {
margin-top: 16px;
}
&-footer {
@include clearfix;
position: absolute;
width: 100%;
right: 0;
bottom: 0;
z-index: 99;
transition: all 0.3s ease 0s;
height: 56px;
padding: 0 24px;
line-height: 56px;
border-top: 1px solid #f0f0f0;
box-shadow: 0 3px 6px -4px rgba(0, 0, 0, .12), 0 6px 16px 0 rgba(0, 0, 0, .08), 0 9px 28px 8px rgba(0, 0, 0, .05);
backdrop-filter: blur(3px);
&-left {
float: left;
}
&-right {
float: right;
}
}
}
</style>

@ -1,16 +0,0 @@
<template functional>
<div class="detail-page-footer">
<div class="detail-page-footer-left">
<slot name="left"/>
</div>
<div class="detail-page-footer-right">
<slot/>
</div>
</div>
</template>
<script>
export default {
name: "DocDetailFooter"
}
</script>

@ -1,34 +0,0 @@
<template functional>
<div class="detail-page-header">
<el-page-header @back="listeners.close" :content="props.title"/>
<el-row>
<el-row class="detail-page-header-left">
<el-col v-for="i in props.description" :key="i.label" :xs="24" :sm="12">
<span class="detail-page-header-description-label">{{ i.label }}</span>
<span class="detail-page-header-description-content">{{ i.content }}</span>
</el-col>
</el-row>
<div class="detail-page-header-extra">
<div>
<div v-for="i in props.extra" :key="i.title">
<div class="detail-page-header-extra-title">{{ i.title }}</div>
<div class="detail-page-header-extra-content">{{ i.content }}</div>
</div>
</div>
</div>
</el-row>
</div>
</template>
<script>
export default {
name: "DocDetailHeader",
props: {
title: String,
description: {type: Array, default: () => []},
extra: {type: Array, default: () => []}
}
}
</script>

@ -2,13 +2,10 @@ import {commonMethods} from "@/mixin/docTableMixin"
import AbstractForm from '@/component/AbstractForm'
import AbstractFormItem from "@/component/AbstractForm/item"
import AbstractTable from "@/component/AbstractTable"
import DocDetailHeader from "@/component/biz/doc/DocDetailHeader"
import DocDetailFooter from "@/component/biz/doc/DocDetailFooter"
import DetailForm from "@/component/AbstractForm/DetailForm"
import DocHistory from '@/component/biz/doc/DocHistory'
import DocSteps from '@/component/biz/doc/DocSteps'
import FormAnchor from "@/component/AbstractForm/FormAnchor"
import FormCard from '@/component/AbstractForm/FormCard'
import FormValidateInfo from "@/component/AbstractForm/FormValidateInfo"
import UploadFile from '@/component/UploadFile'
import {isEmpty, mergeObj} from '@/util'
import {auth} from "@/util/auth"
@ -21,13 +18,10 @@ export default {
AbstractForm,
AbstractFormItem,
AbstractTable,
DocDetailHeader,
DocDetailFooter,
DetailForm,
DocHistory,
DocSteps,
FormAnchor,
FormCard,
FormValidateInfo,
UploadFile
},
@ -104,6 +98,18 @@ export default {
canReject() {
//有驳回权限、edit模式且status=1
return auth(this.api.reject.url) && this.type === 'edit' && this.form.status === 1
},
//底部按钮
buttons() {
return [
{_if: 'canSave', type: 'primary', content: '保 存', e: this.save},
{_if: 'canCommit', type: 'primary', content: '提 交', e: this.commit},
{_if: 'canWithdraw', type: 'danger', content: '撤 回', e: this.withdraw},
{_if: 'canPass', type: 'success', content: '通 过', e: this.pass},
{_if: 'canReject', type: 'danger', content: '驳 回', e: this.reject},
]
.filter(i => this[i._if])
}
},

@ -1,14 +1,14 @@
<template>
<div v-loading="loading" class="detail-page">
<form-anchor :reference="() => $refs" :data="anchors"/>
<doc-detail-header
:title="this.title"
<detail-form
:loading="loading"
:reference="() => $refs"
:anchors="anchors"
:title="title"
:description="headerDescription"
:extra="headerExtra"
:buttons="buttons"
@close="close"
/>
>
<abstract-form :model="form" :rules="rules">
<form-card ref="progress" header="流程进度">
<doc-steps :status="form.status" :type="type"/>
@ -68,18 +68,8 @@
</form-card>
</abstract-form>
<doc-detail-footer>
<form-validate-info :form="() => $refs.form"/>
<el-button plain size="small" @click="close"> </el-button>
<el-button v-if="canSave" size="small" type="primary" @click="save"> </el-button>
<el-button v-if="canCommit" size="small" type="primary" @click="commit"> </el-button>
<el-button v-if="canWithdraw" size="small" type="danger" @click="withdraw"> </el-button>
<el-button v-if="canPass" size="small" type="success" @click="pass"> </el-button>
<el-button v-if="canReject" size="small" type="danger" @click="reject"> </el-button>
</doc-detail-footer>
<order-selector v-model="parentDialog" @select="selectParent"/>
</div>
</detail-form>
</template>
<script>

@ -1,14 +1,14 @@
<template>
<div v-loading="loading" class="detail-page">
<form-anchor :reference="() => $refs" :data="anchors"/>
<doc-detail-header
:title="this.title"
<detail-form
:loading="loading"
:reference="() => $refs"
:anchors="anchors"
:title="title"
:description="headerDescription"
:extra="headerExtra"
:buttons="buttons"
@close="close"
/>
>
<abstract-form :model="form" :rules="rules">
<form-card ref="progress" header="流程进度">
<doc-steps :status="form.status" :finish="form.finish" :type="type"/>
@ -114,18 +114,8 @@
</form-card>
</abstract-form>
<doc-detail-footer>
<form-validate-info :form="() => $refs.form"/>
<el-button plain size="small" @click="close"> </el-button>
<el-button v-if="canSave" size="small" type="primary" @click="save"> </el-button>
<el-button v-if="canCommit" size="small" type="primary" @click="commit"> </el-button>
<el-button v-if="canWithdraw" size="small" type="danger" @click="withdraw"> </el-button>
<el-button v-if="canPass" size="small" type="success" @click="pass"> </el-button>
<el-button v-if="canReject" size="small" type="danger" @click="reject"> </el-button>
</doc-detail-footer>
<supplier-selector v-model="supplierDialog" @select="selectSupplier"/>
</div>
</detail-form>
</template>
<script>

@ -1,14 +1,14 @@
<template>
<div v-loading="loading" class="detail-page">
<form-anchor :reference="() => $refs" :data="anchors"/>
<doc-detail-header
:title="this.title"
<detail-form
:loading="loading"
:reference="() => $refs"
:anchors="anchors"
:title="title"
:description="headerDescription"
:extra="headerExtra"
:buttons="buttons"
@close="close"
/>
>
<abstract-form :model="form" :rules="rules">
<form-card ref="progress" header="流程进度">
<doc-steps :status="form.status" :finish="form.finish" :type="type"/>
@ -97,20 +97,10 @@
</form-card>
</abstract-form>
<doc-detail-footer>
<form-validate-info :form="() => $refs.form"/>
<el-button plain size="small" @click="close"> </el-button>
<el-button v-if="canSave" size="small" type="primary" @click="save"> </el-button>
<el-button v-if="canCommit" size="small" type="primary" @click="commit"> </el-button>
<el-button v-if="canWithdraw" size="small" type="danger" @click="withdraw"> </el-button>
<el-button v-if="canPass" size="small" type="success" @click="pass"> </el-button>
<el-button v-if="canReject" size="small" type="danger" @click="reject"> </el-button>
</doc-detail-footer>
<stock-selector v-model="stockDialog" @select="selectStock"/>
<customer-selector v-model="customerDialog" @select="selectCustomer"/>
</div>
</detail-form>
</template>
<script>

@ -1,14 +1,14 @@
<template>
<div v-loading="loading" class="detail-page">
<form-anchor :reference="() => $refs" :data="anchors"/>
<doc-detail-header
:title="this.title"
<detail-form
:loading="loading"
:reference="() => $refs"
:anchors="anchors"
:title="title"
:description="headerDescription"
:extra="headerExtra"
:buttons="buttons"
@close="close"
/>
>
<abstract-form :model="form" :rules="rules">
<form-card ref="progress" header="流程进度">
<doc-steps :status="form.status" :type="type"/>
@ -83,20 +83,10 @@
</form-card>
</abstract-form>
<doc-detail-footer>
<form-validate-info :form="() => $refs.form"/>
<el-button plain size="small" @click="close"> </el-button>
<el-button v-if="canSave" size="small" type="primary" @click="save"> </el-button>
<el-button v-if="canCommit" size="small" type="primary" @click="commit"> </el-button>
<el-button v-if="canWithdraw" size="small" type="danger" @click="withdraw"> </el-button>
<el-button v-if="canPass" size="small" type="success" @click="pass"> </el-button>
<el-button v-if="canReject" size="small" type="danger" @click="reject"> </el-button>
</doc-detail-footer>
<order-selector v-model="parentDialog" @select="selectParent"/>
<stock-selector v-model="stockDialog" :cid="row ? row.cid : null" @select="selectStock"/>
</div>
</detail-form>
</template>
<script>

Loading…
Cancel
Save