parent
ff8fab0853
commit
ac7257be8b
@ -0,0 +1,125 @@ |
|||||||
|
.detail-page { |
||||||
|
&-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-row { |
||||||
|
display: flex; |
||||||
|
width: 100%; |
||||||
|
margin-bottom: 12px; |
||||||
|
|
||||||
|
@media (max-width: 768px) { |
||||||
|
display: block; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
&-close-btn { |
||||||
|
font-size: 18px; |
||||||
|
} |
||||||
|
|
||||||
|
&-title { |
||||||
|
margin-left: 5px; |
||||||
|
font-weight: 500; |
||||||
|
font-size: 20px; |
||||||
|
line-height: 42px; |
||||||
|
overflow: hidden; |
||||||
|
white-space: nowrap; |
||||||
|
text-overflow: ellipsis; |
||||||
|
} |
||||||
|
|
||||||
|
&-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; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -1,46 +0,0 @@ |
|||||||
<script type="text/jsx"> |
|
||||||
export default { |
|
||||||
name: "DocumentHistory", |
|
||||||
|
|
||||||
functional: true, |
|
||||||
|
|
||||||
props: { |
|
||||||
type: String, |
|
||||||
data: {type: Array, default: () => []} |
|
||||||
}, |
|
||||||
|
|
||||||
render(h, context) { |
|
||||||
const {type, data = []} = context.props |
|
||||||
if (type === 'add') return '' |
|
||||||
return ( |
|
||||||
<el-popover |
|
||||||
v-on:show={context.listeners.show} |
|
||||||
placement="bottom" |
|
||||||
width="250" |
|
||||||
trigger="click" |
|
||||||
> |
|
||||||
<el-timeline> |
|
||||||
<el-scrollbar wrap-class="el-select-dropdown__wrap"> |
|
||||||
{ |
|
||||||
data.map(activity => ( |
|
||||||
<el-timeline-item |
|
||||||
key={activity.id} |
|
||||||
timestamp={activity.time} |
|
||||||
placement="top" |
|
||||||
> |
|
||||||
<p>{activity.uname} {activity.type}</p> |
|
||||||
<p>{activity.info}</p> |
|
||||||
</el-timeline-item> |
|
||||||
)) |
|
||||||
} |
|
||||||
</el-scrollbar> |
|
||||||
{data.length <= 0 ? <div className="el-timeline__empty">暂无记录</div> : ''} |
|
||||||
</el-timeline> |
|
||||||
<button slot="reference" class="el-dialog__headerbtn" style="right: 60px" title="历史状态记录"> |
|
||||||
<i class="el-icon-document el-dialog__close"/> |
|
||||||
</button> |
|
||||||
</el-popover> |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
||||||
</script> |
|
||||||
@ -1,27 +0,0 @@ |
|||||||
<script type="text/jsx"> |
|
||||||
export default { |
|
||||||
name: "DocumentSteps", |
|
||||||
|
|
||||||
functional: true, |
|
||||||
|
|
||||||
props: { |
|
||||||
status: Number, |
|
||||||
type: String |
|
||||||
}, |
|
||||||
|
|
||||||
render(h, context) { |
|
||||||
let {status, type} = context.props |
|
||||||
let firstStatus = type === 'add' ? 'finish' : 'success' |
|
||||||
let secondStatus = status === 1 ? 'success' : type === 'add' ? 'wait' : 'finish' |
|
||||||
if (status !== 2) { |
|
||||||
return ( |
|
||||||
<el-steps align-center style="margin-top: 20px"> |
|
||||||
<el-step title="填写单据" status={firstStatus}/> |
|
||||||
<el-step title="提交单据,等待审核" status={secondStatus}/> |
|
||||||
<el-step title="审核通过" status="wait"/> |
|
||||||
</el-steps> |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
</script> |
|
||||||
@ -0,0 +1,16 @@ |
|||||||
|
<template functional> |
||||||
|
<div class="detail-page-footer"> |
||||||
|
<div class="detail-page-footer-left"> |
||||||
|
<slot name="left"/> |
||||||
|
</div> |
||||||
|
<div class="detail-page-footer-right"> |
||||||
|
<slot name="right"/> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
export default { |
||||||
|
name: "DocDetailFooter" |
||||||
|
} |
||||||
|
</script> |
||||||
@ -0,0 +1,47 @@ |
|||||||
|
<template functional> |
||||||
|
<div class="detail-page-header"> |
||||||
|
<el-row> |
||||||
|
<el-button |
||||||
|
class="detail-page-header-close-btn" |
||||||
|
type="text" |
||||||
|
icon="el-icon-arrow-left" |
||||||
|
@click="listeners.close" |
||||||
|
/> |
||||||
|
<span class="detail-page-header-title">{{props.title}}</span> |
||||||
|
</el-row> |
||||||
|
<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> |
||||||
@ -0,0 +1,64 @@ |
|||||||
|
<template> |
||||||
|
<el-card header="单据历史" style="margin-top: 16px"> |
||||||
|
<abstract-table v-loading="loading" :data="data" :highlight-current-row="false"> |
||||||
|
<el-table-column align="center" label="#" type="index" width="80"/> |
||||||
|
<el-table-column align="center" label="操作人" prop="uname"/> |
||||||
|
<el-table-column align="center" label="操作类型" prop="type"/> |
||||||
|
<el-table-column align="center" label="时 间" prop="time"/> |
||||||
|
<el-table-column align="center" label="备注" prop="info"/> |
||||||
|
</abstract-table> |
||||||
|
</el-card> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import AbstractTable from "@/components/AbstractTable" |
||||||
|
import {getDocumentHistoryByPid} from "@/api/documentHistory" |
||||||
|
import {isEmpty, timeFormat} from "@/utils" |
||||||
|
|
||||||
|
export default { |
||||||
|
name: "DocHistory", |
||||||
|
|
||||||
|
components: {AbstractTable}, |
||||||
|
|
||||||
|
props: {id: String}, |
||||||
|
|
||||||
|
data() { |
||||||
|
return { |
||||||
|
loading: false, |
||||||
|
data: [] |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
watch: { |
||||||
|
id: { |
||||||
|
immediate: true, |
||||||
|
handler(v) { |
||||||
|
if (isEmpty(v)) return |
||||||
|
getDocumentHistoryByPid(v) |
||||||
|
.then(history => { |
||||||
|
history.forEach(i => { |
||||||
|
i.time = timeFormat(null, new Date(i.time)) |
||||||
|
let type = null |
||||||
|
switch (i.type) { |
||||||
|
case 0: |
||||||
|
type = '撤回' |
||||||
|
break |
||||||
|
case 1: |
||||||
|
type = '提交' |
||||||
|
break |
||||||
|
case 2: |
||||||
|
type = '通过' |
||||||
|
break |
||||||
|
case 3: |
||||||
|
type = '驳回' |
||||||
|
break |
||||||
|
} |
||||||
|
i.type = type |
||||||
|
}) |
||||||
|
this.data = history |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
@ -0,0 +1,25 @@ |
|||||||
|
<script type="text/jsx"> |
||||||
|
export default { |
||||||
|
name: "DocSteps", |
||||||
|
|
||||||
|
functional: true, |
||||||
|
|
||||||
|
props: { |
||||||
|
status: Number, |
||||||
|
finish: Number |
||||||
|
}, |
||||||
|
|
||||||
|
render(h, context) { |
||||||
|
const {status, finish} = context.props |
||||||
|
const active = status === 2 && (finish === undefined || finish === 1) ? 3 : status |
||||||
|
return ( |
||||||
|
<el-steps align-center active={active + 1}> |
||||||
|
<el-step title="填写单据"/> |
||||||
|
<el-step title="提交单据,等待审核"/> |
||||||
|
<el-step title="审核通过"/> |
||||||
|
<el-step title="单据完成"/> |
||||||
|
</el-steps> |
||||||
|
) |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
@ -1,6 +1,6 @@ |
|||||||
<script type="text/jsx"> |
<script type="text/jsx"> |
||||||
export default { |
export default { |
||||||
name: "DialogFormItem", |
name: "AbstractFormItem", |
||||||
|
|
||||||
functional: true, |
functional: true, |
||||||
|
|
||||||
@ -0,0 +1,23 @@ |
|||||||
|
<script type="text/jsx"> |
||||||
|
export default { |
||||||
|
name: "AbstractForm", |
||||||
|
|
||||||
|
functional: true, |
||||||
|
|
||||||
|
render(h, context) { |
||||||
|
const {data, children} = context |
||||||
|
return ( |
||||||
|
<el-form |
||||||
|
ref="form" |
||||||
|
label-position="right" |
||||||
|
label-width="100px" |
||||||
|
size="small" |
||||||
|
status-icon |
||||||
|
{...data} |
||||||
|
> |
||||||
|
<el-row>{children}</el-row> |
||||||
|
</el-form> |
||||||
|
) |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
@ -0,0 +1,28 @@ |
|||||||
|
import Vue from "vue" |
||||||
|
|
||||||
|
const state = { |
||||||
|
map: {} |
||||||
|
} |
||||||
|
|
||||||
|
const mutations = { |
||||||
|
init(state, key) { |
||||||
|
if (state.map.hasOwnProperty(key)) { |
||||||
|
state.map[key] = false |
||||||
|
} |
||||||
|
else Vue.set(state.map, key, false) |
||||||
|
}, |
||||||
|
|
||||||
|
emit(state, key) { |
||||||
|
state.map[key] = true |
||||||
|
}, |
||||||
|
|
||||||
|
renew(state, key) { |
||||||
|
state.map[key] = false |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export default { |
||||||
|
namespaced: true, |
||||||
|
state, |
||||||
|
mutations |
||||||
|
} |
||||||
@ -0,0 +1,9 @@ |
|||||||
|
import {isEmpty} from "@/utils" |
||||||
|
import router from '@/router' |
||||||
|
import store from '@/store' |
||||||
|
|
||||||
|
export function closeCurrentPage(next) { |
||||||
|
return store |
||||||
|
.dispatch('tagsView/delView', router.currentRoute) |
||||||
|
.then(() => !isEmpty(next) && router.replace(next)) |
||||||
|
} |
||||||
@ -1,168 +0,0 @@ |
|||||||
<template> |
|
||||||
<dialog-form :loading="loading" :value="value" width="70%" @close="cancel" @open="open"> |
|
||||||
<template slot="title"> |
|
||||||
{{title}} |
|
||||||
<document-history :data="history" :type="type" @show="getHistory"/> |
|
||||||
</template> |
|
||||||
|
|
||||||
<el-form |
|
||||||
ref="form" |
|
||||||
:model="form" |
|
||||||
:rules="rules" |
|
||||||
label-position="right" |
|
||||||
label-width="100px" |
|
||||||
size="small" |
|
||||||
status-icon |
|
||||||
> |
|
||||||
<el-row :gutter="20"> |
|
||||||
<dialog-form-item v-if="form.id" label="单 号:" prop="id"> |
|
||||||
<el-input :value="form.id" readonly/> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item label="采购订单:" prop="pid"> |
|
||||||
<el-input :value="form.pid" readonly> |
|
||||||
<el-button slot="append" :disabled="!canSave" @click="parentDialog=true">选择</el-button> |
|
||||||
</el-input> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item v-if="form.id" label="创建人:" prop="cname"> |
|
||||||
<el-input :value="form.cname" readonly/> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item v-if="form.id" label="创建时间:" prop="ctime"> |
|
||||||
<el-date-picker :value="form.ctime" format="yyyy-MM-dd HH:mm:ss" readonly type="date"/> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item v-if="form.status===2" label="审核人:" prop="vname"> |
|
||||||
<el-input :value="form.vname" readonly/> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item v-if="form.status===2" label="审核时间:" prop="vtime"> |
|
||||||
<el-date-picker :value="form.vtime" format="yyyy-MM-dd HH:mm:ss" readonly type="date"/> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item label="附 件:" full> |
|
||||||
<upload-file |
|
||||||
:file-list="form.imageList" |
|
||||||
:disabled="!canSave" |
|
||||||
@remove="removeUpload" |
|
||||||
@success="uploadSuccess" |
|
||||||
/> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item label="备 注:" prop="remark" full> |
|
||||||
<el-input |
|
||||||
v-model="form.remark" |
|
||||||
:rows="4" |
|
||||||
:readonly="!canSave" |
|
||||||
maxlength="200" |
|
||||||
show-word-limit |
|
||||||
type="textarea" |
|
||||||
/> |
|
||||||
</dialog-form-item> |
|
||||||
</el-row> |
|
||||||
</el-form> |
|
||||||
|
|
||||||
<el-table :data="form.data"> |
|
||||||
<el-table-column align="center" label="#" type="index" width="80"/> |
|
||||||
<el-table-column align="center" label="商 品" prop="cname"/> |
|
||||||
<el-table-column align="center" label="入库数量" width="150"> |
|
||||||
<template v-slot="{row}"> |
|
||||||
<el-input-number |
|
||||||
v-if="canSave" |
|
||||||
v-model="row.num" |
|
||||||
controls-position="right" |
|
||||||
:min="0" |
|
||||||
size="small" |
|
||||||
@change="(nv,ov)=>changeInboundNum(nv,ov,row)" |
|
||||||
/> |
|
||||||
<span v-else>{{row.num}}</span> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
</el-table> |
|
||||||
|
|
||||||
<document-steps :status="form.status" :type="type"/> |
|
||||||
|
|
||||||
<template v-slot:footer> |
|
||||||
<span v-if="form.status===2" class="seal">已审核</span> |
|
||||||
<el-button plain size="small" @click="closeDialog">取 消</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> |
|
||||||
</template> |
|
||||||
|
|
||||||
<order-selector v-model="parentDialog" @select="selectParent"/> |
|
||||||
</dialog-form> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script> |
|
||||||
import OrderSelector from "./OrderSelector" |
|
||||||
import bizDocumentDialogMixin from "@/mixins/bizDocumentDialogMixin" |
|
||||||
import {add, commit, getById, pass, reject, update, withdraw} from "@/api/document/purchase/inbound" |
|
||||||
import {getSubById as getParentSubById} from "@/api/document/purchase/order" |
|
||||||
import {isEmpty} from "@/utils" |
|
||||||
import {isInteger} from "@/utils/validate" |
|
||||||
import {elAlert} from "@/utils/message" |
|
||||||
|
|
||||||
export default { |
|
||||||
name: "EditDialog", |
|
||||||
|
|
||||||
mixins: [bizDocumentDialogMixin], |
|
||||||
|
|
||||||
components: {OrderSelector}, |
|
||||||
|
|
||||||
data() { |
|
||||||
return { |
|
||||||
documentName: '采购入库单', |
|
||||||
api: { |
|
||||||
getById, add, update, commit, withdraw, pass, reject |
|
||||||
}, |
|
||||||
form: { |
|
||||||
pid: null |
|
||||||
}, |
|
||||||
rules: { |
|
||||||
pid: [{required: true, message: '请选择采购订单', trigger: 'change'}] |
|
||||||
}, |
|
||||||
parentDialog: false, |
|
||||||
parentSubList: [] |
|
||||||
} |
|
||||||
}, |
|
||||||
|
|
||||||
methods: { |
|
||||||
afterInit() { |
|
||||||
if (this.type !== 'edit') return |
|
||||||
return getParentSubById(this.form.pid).then(data => this.parentSubList = data) |
|
||||||
}, |
|
||||||
|
|
||||||
selectParent(id, sub) { |
|
||||||
this.parentSubList = sub |
|
||||||
this.form.pid = id |
|
||||||
this.form.data = sub.map(i => ({ |
|
||||||
pid: this.form.id, |
|
||||||
cid: i.cid, |
|
||||||
cname: i.cname, |
|
||||||
num: i.remain_num |
|
||||||
})) |
|
||||||
}, |
|
||||||
|
|
||||||
changeInboundNum(nv, ov, row) { |
|
||||||
let parentSub = this.parentSubList.find(i => i.cid === row.cid) |
|
||||||
if (!parentSub || nv > parentSub.remain_num) { |
|
||||||
return elAlert(`${row.cname}的入库数量超出采购数量`, () => row.num = ov) |
|
||||||
} |
|
||||||
}, |
|
||||||
|
|
||||||
validate() { |
|
||||||
if (this.type === 'edit' && isEmpty(this.form.id)) { |
|
||||||
return '属性缺失,请关闭弹窗刷新重试' |
|
||||||
} |
|
||||||
if (this.form.data.length <= 0) return '入库商品不能为空' |
|
||||||
let index = 1 |
|
||||||
for (let sub of this.form.data) { |
|
||||||
if (isEmpty(sub.num)) return `第${index}个商品数量不能为空` |
|
||||||
if (sub.num < 0 || !isInteger(sub.num)) return `第${index}个商品数量有误` |
|
||||||
let parentSub = this.parentSubList.find(i => i.cid === sub.cid) |
|
||||||
if (!parentSub) return `第${index}个商品不在采购订单中` |
|
||||||
if (parentSub.remain_num < sub.num) return `第${index}个商品的入库数量超出采购数量` |
|
||||||
index++ |
|
||||||
} |
|
||||||
return null |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
</script> |
|
||||||
@ -0,0 +1,185 @@ |
|||||||
|
<template> |
||||||
|
<div v-loading="loading" class="detail-page"> |
||||||
|
<doc-detail-header |
||||||
|
:title="this.title" |
||||||
|
:description="headerDescription" |
||||||
|
:extra="headerExtra" |
||||||
|
@close="close" |
||||||
|
/> |
||||||
|
|
||||||
|
<abstract-form :model="form" :rules="rules"> |
||||||
|
<el-card header="流程进度"> |
||||||
|
<doc-steps :status="form.status" :type="type"/> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card header="基础信息"> |
||||||
|
<abstract-form-item label="采购订单:" prop="pid"> |
||||||
|
<el-input v-if="canSave" :value="form.pid" readonly> |
||||||
|
<el-button slot="append" @click="parentDialog=true">选择</el-button> |
||||||
|
</el-input> |
||||||
|
<template v-else>{{form.pid}}</template> |
||||||
|
</abstract-form-item> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card header="入库商品"> |
||||||
|
<abstract-table :data="form.data" :highlight-current-row="false"> |
||||||
|
<el-table-column align="center" label="#" type="index" width="80"/> |
||||||
|
<el-table-column align="center" label="商 品" prop="cname"/> |
||||||
|
<el-table-column align="center" label="入库数量" width="150"> |
||||||
|
<template v-slot="{row}"> |
||||||
|
<el-input-number |
||||||
|
v-if="canSave" |
||||||
|
v-model="row.num" |
||||||
|
controls-position="right" |
||||||
|
:min="0" |
||||||
|
size="small" |
||||||
|
@change="(nv,ov)=>changeInboundNum(nv,ov,row)" |
||||||
|
/> |
||||||
|
<span v-else>{{row.num}}</span> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</abstract-table> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card header="附件"> |
||||||
|
<upload-file |
||||||
|
:file-list="form.imageList" |
||||||
|
:disabled="!canSave" |
||||||
|
@remove="removeUpload" |
||||||
|
@success="uploadSuccess" |
||||||
|
/> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card header="备注"> |
||||||
|
<el-input |
||||||
|
v-model="form.remark" |
||||||
|
:rows="4" |
||||||
|
:readonly="!canSave" |
||||||
|
maxlength="200" |
||||||
|
show-word-limit |
||||||
|
type="textarea" |
||||||
|
/> |
||||||
|
</el-card> |
||||||
|
</abstract-form> |
||||||
|
|
||||||
|
<doc-history :id="form.id"/> |
||||||
|
|
||||||
|
<doc-detail-footer> |
||||||
|
<template v-slot:right> |
||||||
|
<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> |
||||||
|
</template> |
||||||
|
</doc-detail-footer> |
||||||
|
|
||||||
|
<order-selector v-model="parentDialog" @select="selectParent"/> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import OrderSelector from './components/OrderSelector' |
||||||
|
import bizDocDetailMixin from "@/mixins/bizDocDetailMixin" |
||||||
|
import {baseUrl, add, commit, getById, pass, reject, update, withdraw} from "@/api/document/purchase/inbound" |
||||||
|
import {getSubById as getParentSubById} from "@/api/document/purchase/order" |
||||||
|
import {isEmpty} from "@/utils" |
||||||
|
import {isInteger} from "@/utils/validate" |
||||||
|
import {elAlert} from "@/utils/message" |
||||||
|
import {timestamp2Date} from "@/filter" |
||||||
|
|
||||||
|
export default { |
||||||
|
name: "purchaseInboundDetail", |
||||||
|
|
||||||
|
mixins: [bizDocDetailMixin], |
||||||
|
|
||||||
|
components: {OrderSelector}, |
||||||
|
|
||||||
|
data() { |
||||||
|
return { |
||||||
|
baseUrl, |
||||||
|
docName: '采购入库单', |
||||||
|
api: { |
||||||
|
getById, add, update, commit, withdraw, pass, reject |
||||||
|
}, |
||||||
|
form: { |
||||||
|
pid: null |
||||||
|
}, |
||||||
|
rules: { |
||||||
|
pid: [{required: true, message: '请选择采购订单', trigger: 'change'}] |
||||||
|
}, |
||||||
|
parentDialog: false, |
||||||
|
parentSubList: [] |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
computed: { |
||||||
|
headerDescription() { |
||||||
|
return [ |
||||||
|
{label: '创建人:', content: this.form.cname}, |
||||||
|
{label: '创建时间:', content: timestamp2Date(this.form.ctime)}, |
||||||
|
{label: '审核人:', content: this.form.vname}, |
||||||
|
{label: '审核时间:', content: timestamp2Date(this.form.vtime)} |
||||||
|
] |
||||||
|
}, |
||||||
|
headerExtra() { |
||||||
|
return [ |
||||||
|
{title: '单据状态', content: this.getStatus(this.form.status)} |
||||||
|
] |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
methods: { |
||||||
|
afterInit() { |
||||||
|
if (this.type !== 'edit') return |
||||||
|
return getParentSubById(this.form.pid).then(data => this.parentSubList = data) |
||||||
|
}, |
||||||
|
selectParent(id, sub) { |
||||||
|
this.parentSubList = sub |
||||||
|
this.form.pid = id |
||||||
|
this.form.data = sub.map(i => ({ |
||||||
|
pid: this.form.id, |
||||||
|
cid: i.cid, |
||||||
|
cname: i.cname, |
||||||
|
num: i.remain_num |
||||||
|
})) |
||||||
|
}, |
||||||
|
changeInboundNum(nv, ov, row) { |
||||||
|
let parentSub = this.parentSubList.find(i => i.cid === row.cid) |
||||||
|
if (!parentSub || nv > parentSub.remain_num) { |
||||||
|
return elAlert(`${row.cname}的入库数量超出采购数量`, () => row.num = ov) |
||||||
|
} |
||||||
|
}, |
||||||
|
validate() { |
||||||
|
if (this.type === 'edit' && isEmpty(this.form.id)) { |
||||||
|
return '属性缺失,请关闭弹窗刷新重试' |
||||||
|
} |
||||||
|
if (this.form.data.length <= 0) { |
||||||
|
return '入库商品不能为空' |
||||||
|
} |
||||||
|
|
||||||
|
let index = 1 |
||||||
|
for (let sub of this.form.data) { |
||||||
|
if (isEmpty(sub.num)) { |
||||||
|
return `第${index}个商品数量不能为空` |
||||||
|
} |
||||||
|
if (sub.num < 0 || !isInteger(sub.num)) { |
||||||
|
return `第${index}个商品数量有误` |
||||||
|
} |
||||||
|
|
||||||
|
let parentSub = this.parentSubList.find(i => i.cid === sub.cid) |
||||||
|
|
||||||
|
if (!parentSub) { |
||||||
|
return `第${index}个商品不在采购订单中` |
||||||
|
} |
||||||
|
if (parentSub.remain_num < sub.num) { |
||||||
|
return `第${index}个商品的入库数量超出采购数量` |
||||||
|
} |
||||||
|
index++ |
||||||
|
} |
||||||
|
return null |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
@ -1,211 +0,0 @@ |
|||||||
<template> |
|
||||||
<dialog-form :loading="loading" :value="value" width="70%" @close="cancel" @open="open"> |
|
||||||
<template v-slot:title> |
|
||||||
{{title}} |
|
||||||
<document-history :data="history" :type="type" @show="getHistory"/> |
|
||||||
</template> |
|
||||||
|
|
||||||
<el-form |
|
||||||
ref="form" |
|
||||||
:model="form" |
|
||||||
:rules="rules" |
|
||||||
label-position="right" |
|
||||||
label-width="100px" |
|
||||||
size="small" |
|
||||||
status-icon |
|
||||||
> |
|
||||||
<el-row :gutter="20"> |
|
||||||
<dialog-form-item v-if="form.id" label="单 号:" prop="id"> |
|
||||||
<el-input :value="form.id" readonly/> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item label="供应商:" prop="sname"> |
|
||||||
<el-input :value="form.sname" readonly> |
|
||||||
<el-button slot="append" :disabled="!canSave" @click="supplierDialog=true">选择</el-button> |
|
||||||
</el-input> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item v-if="form.id" label="创建人:" prop="cname"> |
|
||||||
<el-input :value="form.cname" readonly/> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item v-if="form.id" label="创建时间:" prop="ctime"> |
|
||||||
<el-date-picker :value="form.ctime" format="yyyy-MM-dd HH:mm:ss" readonly type="date"/> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item v-if="form.status===2" label="审核人:" prop="vname"> |
|
||||||
<el-input :value="form.vname" readonly/> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item v-if="form.status===2" label="审核时间:" prop="vtime"> |
|
||||||
<el-date-picker :value="form.vtime" format="yyyy-MM-dd HH:mm:ss" readonly type="date"/> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item v-if="form.finish===2" label="完成时间:" prop="ftime"> |
|
||||||
<el-date-picker :value="form.ftime" format="yyyy-MM-dd HH:mm:ss" readonly type="date"/> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item label="附 件:" full> |
|
||||||
<upload-file |
|
||||||
:file-list="form.imageList" |
|
||||||
:disabled="!canSave" |
|
||||||
@remove="removeUpload" |
|
||||||
@success="uploadSuccess" |
|
||||||
/> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item label="备 注:" prop="remark" full> |
|
||||||
<el-input |
|
||||||
v-model="form.remark" |
|
||||||
:rows="4" |
|
||||||
:readonly="!canSave" |
|
||||||
maxlength="200" |
|
||||||
show-word-limit |
|
||||||
type="textarea" |
|
||||||
/> |
|
||||||
</dialog-form-item> |
|
||||||
</el-row> |
|
||||||
</el-form> |
|
||||||
|
|
||||||
<el-table ref="table" :data="form.data"> |
|
||||||
<el-table-column align="center" label="#" type="index" width="80"/> |
|
||||||
<el-table-column align="center" label="商 品"> |
|
||||||
<template v-slot="{row}"> |
|
||||||
<category-selector |
|
||||||
v-if="row._editable" |
|
||||||
v-model="row.cid" |
|
||||||
:selected="selectedCategories" |
|
||||||
@get-name="row.cname=$event" |
|
||||||
/> |
|
||||||
<span v-else>{{row.cname}}</span> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column align="center" label="采购数量"> |
|
||||||
<template v-slot="{row}"> |
|
||||||
<el-input-number |
|
||||||
v-if="row._editable" |
|
||||||
v-model="row.num" |
|
||||||
controls-position="right" |
|
||||||
:min="0" |
|
||||||
size="small" |
|
||||||
/> |
|
||||||
<span v-else>{{row.num}}</span> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column align="center" label="采购单价"> |
|
||||||
<template v-slot="{row}"> |
|
||||||
<el-input-number |
|
||||||
v-if="row._editable" |
|
||||||
v-model="row.price" |
|
||||||
controls-position="right" |
|
||||||
:min="0" |
|
||||||
size="small" |
|
||||||
/> |
|
||||||
<span v-else>{{row.price}}</span> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column v-if="form.id" align="center" label="剩余未入库" prop="remain_num"/> |
|
||||||
<el-table-column v-if="form.id" align="center" label="入库情况" width="120"> |
|
||||||
<template v-slot="{row}"> |
|
||||||
<span :class="{success:row.remain_num===0}" class="dot"/> |
|
||||||
{{row.remain_num===0?'已全部入库':'未全部入库'}} |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column v-if="canSave" align="center" label="操作" width="140"> |
|
||||||
<template v-if="canSave" v-slot="{row,$index}"> |
|
||||||
<el-button v-if="!row._editable" type="text" @click="()=>row._editable=true">编辑</el-button> |
|
||||||
<el-button v-else type="text" @click="()=>row._editable=false">保存</el-button> |
|
||||||
<el-button type="text" @click="()=>delSub(row,$index)">删除</el-button> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<div v-if="canSave" slot="append" class="table-add-btn"> |
|
||||||
<el-button plain type="dashed" size="small" icon="el-icon-plus" @click="addSub">添加采购商品</el-button> |
|
||||||
</div> |
|
||||||
</el-table> |
|
||||||
|
|
||||||
<document-steps :status="form.status" :type="type"/> |
|
||||||
|
|
||||||
<template v-slot:footer> |
|
||||||
<span v-if="form.status===2" class="seal">已审核</span> |
|
||||||
<span v-if="form.finish===2" class="seal">已完成</span> |
|
||||||
<el-button plain size="small" @click="closeDialog">取 消</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> |
|
||||||
</template> |
|
||||||
|
|
||||||
<supplier-selector v-model="supplierDialog" @select="selectSupplier" @jump="closeDialog"/> |
|
||||||
</dialog-form> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script> |
|
||||||
import SupplierSelector from './SupplierSelector' |
|
||||||
import CategorySelector from './CategorySelector' |
|
||||||
import bizDocumentDialogMixin from "@/mixins/bizDocumentDialogMixin" |
|
||||||
import {add, commit, getById, pass, reject, update, withdraw} from "@/api/document/purchase/order" |
|
||||||
import {isEmpty} from "@/utils" |
|
||||||
import {plus, mul} from "@/utils/math" |
|
||||||
import {isInteger} from "@/utils/validate" |
|
||||||
|
|
||||||
export default { |
|
||||||
name: "EditDialog", |
|
||||||
mixins: [bizDocumentDialogMixin], |
|
||||||
components: {CategorySelector, SupplierSelector}, |
|
||||||
data() { |
|
||||||
return { |
|
||||||
documentName: '采购订单', |
|
||||||
api: { |
|
||||||
getById, add, update, commit, withdraw, pass, reject |
|
||||||
}, |
|
||||||
form: { |
|
||||||
sid: null, |
|
||||||
sname: null, |
|
||||||
finish: 0, |
|
||||||
ftime: null, |
|
||||||
total: 0 |
|
||||||
}, |
|
||||||
rules: { |
|
||||||
sname: [{required: true, message: '供应商不能为空', trigger: 'change'}] |
|
||||||
}, |
|
||||||
supplierDialog: false |
|
||||||
} |
|
||||||
}, |
|
||||||
computed: { |
|
||||||
selectedCategories() { |
|
||||||
return this.form.data.map(i => i.cid) |
|
||||||
} |
|
||||||
}, |
|
||||||
methods: { |
|
||||||
selectSupplier(row) { |
|
||||||
this.form.sid = row.id |
|
||||||
this.form.sname = row.name |
|
||||||
}, |
|
||||||
addSub() { |
|
||||||
this.form.data.push({ |
|
||||||
cid: null, |
|
||||||
cname: null, |
|
||||||
num: 0, |
|
||||||
price: 0, |
|
||||||
_editable: true |
|
||||||
}) |
|
||||||
}, |
|
||||||
delSub(row, index) { |
|
||||||
this.form.data.splice(index, 1) |
|
||||||
}, |
|
||||||
validate() { |
|
||||||
if (this.form.data.length <= 0) return '采购商品不能为空' |
|
||||||
if (this.type === 'edit' && isEmpty(this.form.id)) { |
|
||||||
return '属性缺失,请关闭弹窗刷新重试' |
|
||||||
} |
|
||||||
let index = 1 |
|
||||||
for (let sub of this.form.data) { |
|
||||||
if (isEmpty(sub.cid, sub.cname)) return `第${index}个商品分类不能为空` |
|
||||||
if (isEmpty(sub.num)) return `第${index}个商品数量不能为空` |
|
||||||
if (isEmpty(sub.price)) return `第${index + 1}个商品单价不能为空` |
|
||||||
if (sub.num < 0 || !isInteger(sub.num)) return `第${index}个商品数量有误` |
|
||||||
if (sub.price <= 0 || !isInteger(sub.price)) return `第${index}个商品单价有误` |
|
||||||
this.form.total = plus(this.form.total, mul(sub.num, sub.price)) |
|
||||||
index++ |
|
||||||
} |
|
||||||
return null |
|
||||||
}, |
|
||||||
afterInit() { |
|
||||||
this.form.data.forEach(item => item.__editable = false) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
</script> |
|
||||||
@ -0,0 +1,241 @@ |
|||||||
|
<template> |
||||||
|
<div v-loading="loading" class="detail-page"> |
||||||
|
<doc-detail-header |
||||||
|
:title="this.title" |
||||||
|
:description="headerDescription" |
||||||
|
:extra="headerExtra" |
||||||
|
@close="close" |
||||||
|
/> |
||||||
|
|
||||||
|
<abstract-form :model="form" :rules="rules"> |
||||||
|
<el-card header="流程进度"> |
||||||
|
<doc-steps :status="form.status" :finish="form.finish" :type="type"/> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card header="基础信息"> |
||||||
|
<abstract-form-item label="供应商:" prop="sname"> |
||||||
|
<el-input v-if="canSave" :value="form.sname" readonly> |
||||||
|
<el-button slot="append" @click="supplierDialog=true">选择</el-button> |
||||||
|
</el-input> |
||||||
|
<template v-else>{{form.sname}}</template> |
||||||
|
</abstract-form-item> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card header="采购商品"> |
||||||
|
<abstract-table :data="form.data" :highlight-current-row="false"> |
||||||
|
<el-table-column align="center" label="#" type="index" width="80"/> |
||||||
|
<el-table-column align="center" label="商 品"> |
||||||
|
<template v-slot="{row}"> |
||||||
|
<category-selector |
||||||
|
v-if="row._editable" |
||||||
|
v-model="row.cid" |
||||||
|
:selected="selectedCategories" |
||||||
|
@get-name="row.cname=$event" |
||||||
|
/> |
||||||
|
<span v-else>{{row.cname}}</span> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column align="center" label="采购数量"> |
||||||
|
<template v-slot="{row}"> |
||||||
|
<el-input-number |
||||||
|
v-if="row._editable" |
||||||
|
v-model="row.num" |
||||||
|
controls-position="right" |
||||||
|
:min="0" |
||||||
|
size="small" |
||||||
|
/> |
||||||
|
<span v-else>{{row.num}}</span> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column align="center" label="采购单价"> |
||||||
|
<template v-slot="{row}"> |
||||||
|
<el-input-number |
||||||
|
v-if="row._editable" |
||||||
|
v-model="row.price" |
||||||
|
controls-position="right" |
||||||
|
:min="0" |
||||||
|
size="small" |
||||||
|
/> |
||||||
|
<span v-else>{{row.price}}</span> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column v-if="form.id" align="center" label="剩余未入库" prop="remain_num"/> |
||||||
|
<el-table-column v-if="form.id" align="center" label="入库情况" width="120"> |
||||||
|
<template v-slot="{row}"> |
||||||
|
<span :class="{success:row.remain_num===0}" class="dot"/> |
||||||
|
{{row.remain_num===0?'已全部入库':'未全部入库'}} |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column v-if="canSave" align="center" label="操作" width="140"> |
||||||
|
<template v-if="canSave" v-slot="{row,$index}"> |
||||||
|
<el-button v-if="!row._editable" type="text" @click="()=>row._editable=true">编辑</el-button> |
||||||
|
<el-button v-else type="text" @click="()=>row._editable=false">保存</el-button> |
||||||
|
<el-button type="text" @click="()=>delSub(row,$index)">删除</el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<div v-if="canSave" slot="append" class="table-add-btn"> |
||||||
|
<el-button |
||||||
|
plain |
||||||
|
type="dashed" |
||||||
|
icon="el-icon-plus" |
||||||
|
:disabled="!canAddSub" |
||||||
|
@click="addSub" |
||||||
|
> |
||||||
|
添加采购商品 |
||||||
|
</el-button> |
||||||
|
</div> |
||||||
|
</abstract-table> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card header="附件"> |
||||||
|
<upload-file |
||||||
|
:file-list="form.imageList" |
||||||
|
:disabled="!canSave" |
||||||
|
@remove="removeUpload" |
||||||
|
@success="uploadSuccess" |
||||||
|
/> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card header="备注"> |
||||||
|
<el-input |
||||||
|
v-model="form.remark" |
||||||
|
:rows="4" |
||||||
|
:readonly="!canSave" |
||||||
|
maxlength="200" |
||||||
|
show-word-limit |
||||||
|
type="textarea" |
||||||
|
/> |
||||||
|
</el-card> |
||||||
|
</abstract-form> |
||||||
|
|
||||||
|
<doc-history :id="form.id"/> |
||||||
|
|
||||||
|
<doc-detail-footer> |
||||||
|
<template v-slot:right> |
||||||
|
<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> |
||||||
|
</template> |
||||||
|
</doc-detail-footer> |
||||||
|
|
||||||
|
<supplier-selector v-model="supplierDialog" @select="selectSupplier"/> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import CategorySelector from './components/CategorySelector' |
||||||
|
import SupplierSelector from './components/SupplierSelector' |
||||||
|
import bizDocDetailMixin from "@/mixins/bizDocDetailMixin" |
||||||
|
import {baseUrl, add, commit, getById, pass, reject, update, withdraw} from "@/api/document/purchase/order" |
||||||
|
import {isEmpty} from "@/utils" |
||||||
|
import {isInteger} from "@/utils/validate" |
||||||
|
import {mul, plus} from "@/utils/math" |
||||||
|
import {timestamp2Date} from "@/filter" |
||||||
|
|
||||||
|
export default { |
||||||
|
name: "purchaseOrderDetail", |
||||||
|
|
||||||
|
mixins: [bizDocDetailMixin], |
||||||
|
|
||||||
|
components: {CategorySelector, SupplierSelector}, |
||||||
|
|
||||||
|
data() { |
||||||
|
return { |
||||||
|
baseUrl, |
||||||
|
docName: '采购订单', |
||||||
|
api: { |
||||||
|
getById, add, update, commit, withdraw, pass, reject |
||||||
|
}, |
||||||
|
form: { |
||||||
|
sid: null, |
||||||
|
sname: null, |
||||||
|
finish: 0, |
||||||
|
ftime: null, |
||||||
|
total: 0 |
||||||
|
}, |
||||||
|
rules: { |
||||||
|
sname: [{required: true, message: '供应商不能为空', trigger: 'change'}] |
||||||
|
}, |
||||||
|
supplierDialog: false |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
computed: { |
||||||
|
headerDescription() { |
||||||
|
return [ |
||||||
|
{label: '创建人:', content: this.form.cname}, |
||||||
|
{label: '创建时间:', content: timestamp2Date(this.form.ctime)}, |
||||||
|
{label: '审核人:', content: this.form.vname}, |
||||||
|
{label: '审核时间:', content: timestamp2Date(this.form.vtime)}, |
||||||
|
{label: '完成时间:', content: timestamp2Date(this.form.ftime)} |
||||||
|
] |
||||||
|
}, |
||||||
|
headerExtra() { |
||||||
|
return [ |
||||||
|
{title: '单据状态', content: this.getStatus(this.form.status)}, |
||||||
|
{title: '完成情况', content: this.getFinish(this.form.finish)} |
||||||
|
] |
||||||
|
}, |
||||||
|
selectedCategories() { |
||||||
|
return this.form.data.map(i => i.cid) |
||||||
|
}, |
||||||
|
canAddSub() { |
||||||
|
return this.form.data.every(i => !i._editable) |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
methods: { |
||||||
|
selectSupplier(row) { |
||||||
|
this.form.sid = row.id |
||||||
|
this.form.sname = row.name |
||||||
|
}, |
||||||
|
addSub() { |
||||||
|
this.form.data.push({ |
||||||
|
cid: null, |
||||||
|
cname: null, |
||||||
|
num: 0, |
||||||
|
price: 0, |
||||||
|
_editable: true |
||||||
|
}) |
||||||
|
}, |
||||||
|
delSub(row, index) { |
||||||
|
this.form.data.splice(index, 1) |
||||||
|
}, |
||||||
|
validate() { |
||||||
|
if (this.form.data.length <= 0) { |
||||||
|
return '采购商品不能为空' |
||||||
|
} |
||||||
|
if (this.type === 'edit' && isEmpty(this.form.id)) { |
||||||
|
return '属性缺失,请关闭弹窗刷新重试' |
||||||
|
} |
||||||
|
let index = 1 |
||||||
|
for (let sub of this.form.data) { |
||||||
|
if (isEmpty(sub.cid, sub.cname)) { |
||||||
|
return `第${index}个商品分类不能为空` |
||||||
|
} |
||||||
|
if (isEmpty(sub.num)) { |
||||||
|
return `第${index}个商品数量不能为空` |
||||||
|
} |
||||||
|
if (isEmpty(sub.price)) { |
||||||
|
return `第${index + 1}个商品单价不能为空` |
||||||
|
} |
||||||
|
if (sub.num < 0 || !isInteger(sub.num)) { |
||||||
|
return `第${index}个商品数量有误` |
||||||
|
} |
||||||
|
if (sub.price <= 0 || !isInteger(sub.price)) { |
||||||
|
return `第${index}个商品单价有误` |
||||||
|
} |
||||||
|
this.form.total = plus(this.form.total, mul(sub.num, sub.price)) |
||||||
|
index++ |
||||||
|
} |
||||||
|
return null |
||||||
|
}, |
||||||
|
afterInit() { |
||||||
|
this.form.data.forEach(item => item.__editable = false) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
@ -1,216 +0,0 @@ |
|||||||
<template> |
|
||||||
<dialog-form :loading="loading" :value="value" width="70%" @close="cancel" @open="open"> |
|
||||||
<template v-slot:title> |
|
||||||
{{title}} |
|
||||||
<document-history :data="history" :type="type" @show="getHistory"/> |
|
||||||
</template> |
|
||||||
|
|
||||||
<el-form |
|
||||||
ref="form" |
|
||||||
:model="form" |
|
||||||
:rules="rules" |
|
||||||
label-position="right" |
|
||||||
label-width="100px" |
|
||||||
size="small" |
|
||||||
status-icon |
|
||||||
> |
|
||||||
<el-row :gutter="20"> |
|
||||||
<dialog-form-item v-if="form.id" label="单 号:" prop="id"> |
|
||||||
<el-input :value="form.id" readonly/> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item label="客 户:" prop="customer_name"> |
|
||||||
<el-input :value="form.customer_name" readonly> |
|
||||||
<el-button slot="append" :disabled="!canSave" @click="customerDialog=true">选择</el-button> |
|
||||||
</el-input> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item v-if="form.id" label="创建人:" prop="cname"> |
|
||||||
<el-input :value="form.cname" readonly/> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item v-if="form.id" label="创建时间:" prop="ctime"> |
|
||||||
<el-date-picker :value="form.ctime" format="yyyy-MM-dd HH:mm:ss" readonly type="date"/> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item v-if="form.status===2" label="审核人:" prop="vname"> |
|
||||||
<el-input :value="form.vname" readonly/> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item v-if="form.status===2" label="审核时间:" prop="vtime"> |
|
||||||
<el-date-picker :value="form.vtime" format="yyyy-MM-dd HH:mm:ss" readonly type="date"/> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item v-if="form.finish===2" label="完成时间:" prop="ftime"> |
|
||||||
<el-date-picker :value="form.ftime" format="yyyy-MM-dd HH:mm:ss" readonly type="date"/> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item label="附 件:" full> |
|
||||||
<upload-file |
|
||||||
:file-list="form.imageList" |
|
||||||
:disabled="!canSave" |
|
||||||
@remove="removeUpload" |
|
||||||
@success="uploadSuccess" |
|
||||||
/> |
|
||||||
</dialog-form-item> |
|
||||||
<dialog-form-item label="备 注:" prop="remark" full> |
|
||||||
<el-input |
|
||||||
v-model="form.remark" |
|
||||||
:rows="4" |
|
||||||
:readonly="!canSave" |
|
||||||
maxlength="200" |
|
||||||
show-word-limit |
|
||||||
type="textarea" |
|
||||||
/> |
|
||||||
</dialog-form-item> |
|
||||||
</el-row> |
|
||||||
</el-form> |
|
||||||
|
|
||||||
<el-table ref="table" :data="form.data"> |
|
||||||
<el-table-column align="center" label="#" type="index" width="80"/> |
|
||||||
<el-table-column align="center" label="商品" prop="cname"/> |
|
||||||
<el-table-column align="center" label="销售数量"> |
|
||||||
<template v-slot="{row}"> |
|
||||||
<el-input-number |
|
||||||
v-if="canSave" |
|
||||||
v-model="row.num" |
|
||||||
controls-position="right" |
|
||||||
:min="0" |
|
||||||
size="small" |
|
||||||
/> |
|
||||||
<span v-else>{{row.num}}</span> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column align="center" label="销售单价"> |
|
||||||
<template v-slot="{row}"> |
|
||||||
<el-input-number |
|
||||||
v-if="canSave" |
|
||||||
v-model="row.price" |
|
||||||
controls-position="right" |
|
||||||
:min="0" |
|
||||||
size="small" |
|
||||||
/> |
|
||||||
<span v-else>{{row.price}}</span> |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<el-table-column align="center" label="剩余未出库" prop="remain_num"/> |
|
||||||
<el-table-column v-if="form.id" align="center" label="出库情况" width="120"> |
|
||||||
<template v-slot="{row}"> |
|
||||||
<span :class="{success:row.remain_num===0}" class="dot"/> |
|
||||||
{{row.remain_num===0?'已全部出库':'未全部出库'}} |
|
||||||
</template> |
|
||||||
</el-table-column> |
|
||||||
<div v-if="canSave" slot="append" class="table-add-btn"> |
|
||||||
<el-button |
|
||||||
plain |
|
||||||
type="dashed" |
|
||||||
size="small" |
|
||||||
icon="el-icon-plus" |
|
||||||
@click="stockDialog=true" |
|
||||||
> |
|
||||||
添加销售商品 |
|
||||||
</el-button> |
|
||||||
</div> |
|
||||||
</el-table> |
|
||||||
|
|
||||||
<document-steps :status="form.status" :type="type"/> |
|
||||||
|
|
||||||
<template v-slot:footer> |
|
||||||
<span v-if="form.status===2" class="seal">已审核</span> |
|
||||||
<span v-if="form.finish===2" class="seal">已完成</span> |
|
||||||
<el-button plain size="small" @click="closeDialog">取 消</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> |
|
||||||
</template> |
|
||||||
|
|
||||||
<stock-selector v-model="stockDialog" @select="selectStock"/> |
|
||||||
|
|
||||||
<customer-selector v-model="customerDialog" @select="selectCustomer" @jump="closeDialog"/> |
|
||||||
</dialog-form> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script> |
|
||||||
import StockSelector from './StockSelector' |
|
||||||
import CustomerSelector from './CustomerSelector' |
|
||||||
import bizDocumentDialogMixin from "@/mixins/bizDocumentDialogMixin" |
|
||||||
import {add, commit, getById, pass, reject, update, withdraw} from "@/api/document/sell/order" |
|
||||||
import {isEmpty} from "@/utils" |
|
||||||
import {mul, plus} from "@/utils/math" |
|
||||||
import {isInteger} from "@/utils/validate" |
|
||||||
|
|
||||||
export default { |
|
||||||
name: "EditDialog", |
|
||||||
|
|
||||||
mixins: [bizDocumentDialogMixin], |
|
||||||
|
|
||||||
components: {StockSelector, CustomerSelector}, |
|
||||||
|
|
||||||
data() { |
|
||||||
return { |
|
||||||
documentName: '销售订单', |
|
||||||
api: { |
|
||||||
getById, add, update, commit, withdraw, pass, reject |
|
||||||
}, |
|
||||||
form: { |
|
||||||
customer_id: null, |
|
||||||
customer_name: null, |
|
||||||
finish: 0, |
|
||||||
ftime: null, |
|
||||||
total: 0 |
|
||||||
}, |
|
||||||
rules: { |
|
||||||
customer_name: [{required: true, message: '客户不能为空', trigger: 'change'}] |
|
||||||
}, |
|
||||||
customerDialog: false, |
|
||||||
stockDialog: false |
|
||||||
} |
|
||||||
}, |
|
||||||
|
|
||||||
computed: { |
|
||||||
selectedCategories() { |
|
||||||
return this.form.data.map(i => i.cid) |
|
||||||
} |
|
||||||
}, |
|
||||||
|
|
||||||
methods: { |
|
||||||
selectCustomer(row) { |
|
||||||
this.form.customer_id = row.id |
|
||||||
this.form.customer_name = row.name |
|
||||||
this.customerDialog = false |
|
||||||
}, |
|
||||||
|
|
||||||
selectStock(stocks) { |
|
||||||
this.form.data = stocks.map(i => ({cid: i.cid, cname: i.cname, num: i.total_num, price: 0})) |
|
||||||
this.stockDialog = false |
|
||||||
}, |
|
||||||
|
|
||||||
addSub() { |
|
||||||
this.form.data.push({ |
|
||||||
cid: null, |
|
||||||
cname: null, |
|
||||||
num: 0, |
|
||||||
price: 0, |
|
||||||
remain_num: 0 |
|
||||||
}) |
|
||||||
}, |
|
||||||
|
|
||||||
delSub(row, index) { |
|
||||||
this.form.data.splice(index, 1) |
|
||||||
}, |
|
||||||
|
|
||||||
validate() { |
|
||||||
if (this.form.data.length <= 0) return '销售商品不能为空' |
|
||||||
if (this.type === 'edit' && isEmpty(this.form.id)) { |
|
||||||
return '属性缺失,请关闭弹窗刷新重试' |
|
||||||
} |
|
||||||
let index = 1 |
|
||||||
for (let sub of this.form.data) { |
|
||||||
if (isEmpty(sub.cid, sub.cname)) return `第${index}个商品分类不能为空` |
|
||||||
if (isEmpty(sub.num)) return `第${index}个商品数量不能为空` |
|
||||||
if (isEmpty(sub.price)) return `第${index + 1}个商品单价不能为空` |
|
||||||
if (sub.num < 0 || !isInteger(sub.num)) return `第${index}个商品数量有误` |
|
||||||
if (sub.price <= 0 || !isInteger(sub.price)) return `第${index}个商品单价有误` |
|
||||||
this.form.total = plus(this.form.total, mul(sub.num, sub.price)) |
|
||||||
index++ |
|
||||||
} |
|
||||||
return null |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
</script> |
|
||||||
@ -0,0 +1,217 @@ |
|||||||
|
<template> |
||||||
|
<div v-loading="loading" class="detail-page"> |
||||||
|
<doc-detail-header |
||||||
|
:title="this.title" |
||||||
|
:description="headerDescription" |
||||||
|
:extra="headerExtra" |
||||||
|
@close="close" |
||||||
|
/> |
||||||
|
|
||||||
|
<abstract-form :model="form" :rules="rules"> |
||||||
|
<el-card header="流程进度"> |
||||||
|
<doc-steps :status="form.status" :type="type"/> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card header="基础信息"> |
||||||
|
<abstract-form-item label="客 户:" prop="customer_name"> |
||||||
|
<el-input v-if="canSave" :value="form.customer_name" readonly> |
||||||
|
<el-button slot="append" @click="customerDialog=true">选择</el-button> |
||||||
|
</el-input> |
||||||
|
<template v-else>{{form.customer_name}}</template> |
||||||
|
</abstract-form-item> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card header="销售商品"> |
||||||
|
<abstract-table :data="form.data" :highlight-current-row="false"> |
||||||
|
<el-table-column align="center" label="#" type="index" width="80"/> |
||||||
|
<el-table-column align="center" label="商品" prop="cname"/> |
||||||
|
<el-table-column align="center" label="销售数量"> |
||||||
|
<template v-slot="{row}"> |
||||||
|
<el-input-number |
||||||
|
v-if="canSave" |
||||||
|
v-model="row.num" |
||||||
|
controls-position="right" |
||||||
|
:min="0" |
||||||
|
size="small" |
||||||
|
/> |
||||||
|
<span v-else>{{row.num}}</span> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column align="center" label="销售单价"> |
||||||
|
<template v-slot="{row}"> |
||||||
|
<el-input-number |
||||||
|
v-if="canSave" |
||||||
|
v-model="row.price" |
||||||
|
controls-position="right" |
||||||
|
:min="0" |
||||||
|
size="small" |
||||||
|
/> |
||||||
|
<span v-else>{{row.price}}</span> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column align="center" label="剩余未出库" prop="remain_num"/> |
||||||
|
<el-table-column v-if="form.id" align="center" label="出库情况" width="120"> |
||||||
|
<template v-slot="{row}"> |
||||||
|
<span :class="{success:row.remain_num===0}" class="dot"/> |
||||||
|
{{row.remain_num===0?'已全部出库':'未全部出库'}} |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<div v-if="canSave" slot="append" class="table-add-btn"> |
||||||
|
<el-button |
||||||
|
plain |
||||||
|
type="dashed" |
||||||
|
icon="el-icon-plus" |
||||||
|
:disabled="!canAddSub" |
||||||
|
@click="stockDialog=true" |
||||||
|
> |
||||||
|
添加销售商品 |
||||||
|
</el-button> |
||||||
|
</div> |
||||||
|
</abstract-table> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card header="附件"> |
||||||
|
<upload-file |
||||||
|
:file-list="form.imageList" |
||||||
|
:disabled="!canSave" |
||||||
|
@remove="removeUpload" |
||||||
|
@success="uploadSuccess" |
||||||
|
/> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card header="备注"> |
||||||
|
<el-input |
||||||
|
v-model="form.remark" |
||||||
|
:rows="4" |
||||||
|
:readonly="!canSave" |
||||||
|
maxlength="200" |
||||||
|
show-word-limit |
||||||
|
type="textarea" |
||||||
|
/> |
||||||
|
</el-card> |
||||||
|
</abstract-form> |
||||||
|
|
||||||
|
<doc-history :id="form.id"/> |
||||||
|
|
||||||
|
<doc-detail-footer> |
||||||
|
<template v-slot:right> |
||||||
|
<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> |
||||||
|
</template> |
||||||
|
</doc-detail-footer> |
||||||
|
|
||||||
|
<stock-selector v-model="stockDialog" @select="selectStock"/> |
||||||
|
|
||||||
|
<customer-selector v-model="customerDialog" @select="selectCustomer"/> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import CustomerSelector from './components/CustomerSelector' |
||||||
|
import StockSelector from './components/StockSelector' |
||||||
|
import bizDocDetailMixin from "@/mixins/bizDocDetailMixin" |
||||||
|
import {baseUrl, add, commit, getById, pass, reject, update, withdraw} from "@/api/document/sell/order" |
||||||
|
import {isEmpty} from "@/utils" |
||||||
|
import {mul, plus} from "@/utils/math" |
||||||
|
import {isInteger} from "@/utils/validate" |
||||||
|
import {timestamp2Date} from "@/filter" |
||||||
|
|
||||||
|
export default { |
||||||
|
name: "sellOrderDetail", |
||||||
|
|
||||||
|
mixins: [bizDocDetailMixin], |
||||||
|
|
||||||
|
components: {CustomerSelector, StockSelector}, |
||||||
|
|
||||||
|
data() { |
||||||
|
return { |
||||||
|
baseUrl, |
||||||
|
docName: '销售订单', |
||||||
|
api: { |
||||||
|
getById, add, update, commit, withdraw, pass, reject |
||||||
|
}, |
||||||
|
form: { |
||||||
|
customer_id: null, |
||||||
|
customer_name: null, |
||||||
|
finish: 0, |
||||||
|
ftime: null, |
||||||
|
total: 0 |
||||||
|
}, |
||||||
|
rules: { |
||||||
|
customer_name: [{required: true, message: '客户不能为空', trigger: 'change'}] |
||||||
|
}, |
||||||
|
customerDialog: false, |
||||||
|
stockDialog: false |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
computed: { |
||||||
|
headerDescription() { |
||||||
|
return [ |
||||||
|
{label: '创建人:', content: this.form.cname}, |
||||||
|
{label: '创建时间:', content: timestamp2Date(this.form.ctime)}, |
||||||
|
{label: '审核人:', content: this.form.vname}, |
||||||
|
{label: '审核时间:', content: timestamp2Date(this.form.vtime)}, |
||||||
|
{label: '完成时间:', content: timestamp2Date(this.form.ftime)} |
||||||
|
] |
||||||
|
}, |
||||||
|
headerExtra() { |
||||||
|
return [ |
||||||
|
{title: '单据状态', content: this.getStatus(this.form.status)}, |
||||||
|
{title: '完成情况', content: this.getFinish(this.form.finish)} |
||||||
|
] |
||||||
|
}, |
||||||
|
selectedCategories() { |
||||||
|
return this.form.data.map(i => i.cid) |
||||||
|
}, |
||||||
|
canAddSub() { |
||||||
|
return this.form.data.every(i => !i._editable) |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
methods: { |
||||||
|
selectCustomer(row) { |
||||||
|
this.form.customer_id = row.id |
||||||
|
this.form.customer_name = row.name |
||||||
|
this.customerDialog = false |
||||||
|
}, |
||||||
|
selectStock(stocks) { |
||||||
|
this.form.data = stocks.map(i => ({cid: i.cid, cname: i.cname, num: i.total_num, price: 0})) |
||||||
|
this.stockDialog = false |
||||||
|
}, |
||||||
|
addSub() { |
||||||
|
this.form.data.push({ |
||||||
|
cid: null, |
||||||
|
cname: null, |
||||||
|
num: 0, |
||||||
|
price: 0, |
||||||
|
remain_num: 0 |
||||||
|
}) |
||||||
|
}, |
||||||
|
delSub(row, index) { |
||||||
|
this.form.data.splice(index, 1) |
||||||
|
}, |
||||||
|
validate() { |
||||||
|
if (this.form.data.length <= 0) return '销售商品不能为空' |
||||||
|
if (this.type === 'edit' && isEmpty(this.form.id)) { |
||||||
|
return '属性缺失,请关闭弹窗刷新重试' |
||||||
|
} |
||||||
|
let index = 1 |
||||||
|
for (let sub of this.form.data) { |
||||||
|
if (isEmpty(sub.cid, sub.cname)) return `第${index}个商品分类不能为空` |
||||||
|
if (isEmpty(sub.num)) return `第${index}个商品数量不能为空` |
||||||
|
if (isEmpty(sub.price)) return `第${index + 1}个商品单价不能为空` |
||||||
|
if (sub.num < 0 || !isInteger(sub.num)) return `第${index}个商品数量有误` |
||||||
|
if (sub.price <= 0 || !isInteger(sub.price)) return `第${index}个商品单价有误` |
||||||
|
this.form.total = plus(this.form.total, mul(sub.num, sub.price)) |
||||||
|
index++ |
||||||
|
} |
||||||
|
return null |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
Loading…
Reference in new issue