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"> |
||||
export default { |
||||
name: "DialogFormItem", |
||||
name: "AbstractFormItem", |
||||
|
||||
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