采购审批
This commit is contained in:
parent
41e848d46d
commit
036d902c41
19
src/App.vue
19
src/App.vue
@ -71,4 +71,23 @@ body .el-page-header__back{
|
||||
left: 60px;
|
||||
transform: none;
|
||||
}
|
||||
.h5Tit{
|
||||
background-color: #cad1e5;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
margin-bottom: 15px;
|
||||
padding-left: 20px;
|
||||
position: relative;
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
&::before{
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 9px;
|
||||
height: 14px;
|
||||
background-color: var(--el-color-primary);
|
||||
content: '';
|
||||
width: 3px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
292
src/components/approval/balancepayment.vue
Normal file
292
src/components/approval/balancepayment.vue
Normal file
@ -0,0 +1,292 @@
|
||||
<template>
|
||||
<el-dialog v-model="showDialog" title="尾款打款审批" width="1200px" @close="closeDialog">
|
||||
<div v-loading="loading">
|
||||
<div class="h5Tit">商品信息</div>
|
||||
<el-table :data="goodsList" style="width: 100%;margin-top: 15px;" border>
|
||||
<el-table-column prop="goods.title" label="商品名称" />
|
||||
<el-table-column label="规格名称">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.sku && scope.row.sku.title || scope.row.title }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="unit" label="单位" align="center" />
|
||||
<el-table-column prop="expect_unit_price" label="预计产品单价(含税)" align="center" />
|
||||
<el-table-column label="实际产品单价(含税)" align="center">
|
||||
<template #default="scope">
|
||||
<el-input class="inpt" type="text" v-model="scope.row.real_unit_price" @input="changeInput" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="expect_quantity" label="预计采购数量" align="center" />
|
||||
<el-table-column label="实际采购数量" align="center">
|
||||
<template #default="scope">
|
||||
<el-input class="inpt" type="text" v-model="scope.row.real_quantity" @input="changeInput" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="expect_amount" label="预计订单金额" align="center" />
|
||||
<el-table-column prop="real_amount" label="实际订单金额" align="center" />
|
||||
<el-table-column prop="has_paid_amount" label="已打款" align="center" />
|
||||
<el-table-column label="申请打款金额" align="center">
|
||||
<template #default="scope">
|
||||
<el-input type="text" class="inpt" v-model="scope.row.apply_amount" @input="changeApply" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="h5Tit">其他费用</div>
|
||||
<el-button type="primary" @click="addFee">添加其他费用</el-button>
|
||||
<el-table :data="feesList" style="width: 100%;margin-top: 15px;" border>
|
||||
<el-table-column label="费用名称" align="center">
|
||||
<template #default="scope">
|
||||
<el-input type="text" v-model="scope.row.fee_name" :disabled="scope.row.id" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="订单金额">
|
||||
<template #default="scope">
|
||||
<el-input type="text" v-model="scope.row.amount" :disabled="scope.row.id" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="打款信息">
|
||||
<template #default="scope">
|
||||
<el-select v-model="scope.row.other_expense_account_id" placeholder="请选择" clearable filterable :disabled="scope.row.id">
|
||||
<el-option v-for="it in accountList" :key="it.id" :label="it.name" :value="it.id" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-button type="danger" :disabled="scope.row.id" size="mini" @click="removeFee(scope.$index)"><el-icon><DeleteFilled /></el-icon></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div style="padding: 20px 0;color: #f00;">合计申请打款金额:{{total_amount}}元</div>
|
||||
|
||||
<div class="huibox">
|
||||
<div>
|
||||
打款前:总实际订单金额(元):{{itemInfo.total_amount}},
|
||||
总实际已支付金额(元):{{itemInfo.has_paid_amount}},
|
||||
总实际未支付金额(元):{{ ((itemInfo.total_amount * 100 - itemInfo.has_paid_amount * 100) / 100).toFixed(2) }}
|
||||
</div>
|
||||
<div>
|
||||
打款后:总实际订单金额(元):{{real_total_amount}},
|
||||
总实际已支付金额(元):{{ ((itemInfo.has_paid_amount * 100 + total_amount * 100) / 100).toFixed(2) }},
|
||||
总实际未支付金额(元):{{ ((real_total_amount * 100 - itemInfo.has_paid_amount * 100 - total_amount * 100) / 100).toFixed(2) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="closeDialog()">取消</el-button>
|
||||
<el-button type="primary" @click="commitApproval()" :loading="btnloading">提交审批</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { DeleteFilled, Search } from "@element-plus/icons"
|
||||
import { reactive, toRefs, watch } from 'vue'
|
||||
import { get, post } from '@/api/request'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
export default {
|
||||
components: { DeleteFilled, Search },
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
id: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
const data = reactive({
|
||||
launchId: 0,
|
||||
showDialog: false,
|
||||
accountList: [],
|
||||
goodsList: [],
|
||||
loading: false,
|
||||
feesList: [],
|
||||
btnloading: false,
|
||||
total_amount: 0,
|
||||
real_total_amount: 0,
|
||||
itemInfo: {}
|
||||
})
|
||||
|
||||
function getDetail() {
|
||||
data.loading = true
|
||||
get(`/api/purchaseOrder/${data.launchId}`).then((res) => {
|
||||
data.itemInfo = res.data
|
||||
data.feesList = res.data.other_expenses
|
||||
data.goodsList = res.data.products
|
||||
data.loading = false
|
||||
}).catch(() => {
|
||||
data.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
function getAccount() {
|
||||
get(`/api/otherExpenseAccount`, {page: 1, pageSize: 1000}).then((res) => {
|
||||
data.accountList = res.data
|
||||
})
|
||||
}
|
||||
|
||||
const commitApproval = () => {
|
||||
data.btnloading = true
|
||||
let products = []
|
||||
for (let index = 0; index < data.goodsList.length; index++) {
|
||||
let obj = data.goodsList[index]
|
||||
products.push({
|
||||
id: obj.id,
|
||||
product_id: obj.product_id,
|
||||
sku_id: obj.id,
|
||||
real_unit_price: obj.real_unit_price,
|
||||
real_quantity: obj.real_quantity,
|
||||
apply_amount: obj.apply_amount
|
||||
})
|
||||
}
|
||||
let params = {
|
||||
purchase_order_id: data.launchId,
|
||||
products: products,
|
||||
otherExpenses: data.feesList
|
||||
}
|
||||
post(`/api/purchaseOrder/finalPaymentSubmit`, params).then((res) => {
|
||||
ElMessage({ type: 'success', message: '提交成功' })
|
||||
closeDialog()
|
||||
context.emit('refresh')
|
||||
data.btnloading = false
|
||||
}).catch(() => {
|
||||
data.btnloading = false
|
||||
})
|
||||
}
|
||||
|
||||
function clearForm() {
|
||||
data.feesList = []
|
||||
data.goodsList = []
|
||||
}
|
||||
|
||||
const closeDialog = () => {
|
||||
clearForm()
|
||||
context.emit('close')
|
||||
data.showDialog = false
|
||||
}
|
||||
|
||||
function addFee() {
|
||||
data.feesList.push({
|
||||
fee_name: '',
|
||||
amount: '',
|
||||
other_expense_account_id: ''
|
||||
})
|
||||
}
|
||||
|
||||
function removeFee(i) {
|
||||
data.feesList.splice(i, 1)
|
||||
}
|
||||
|
||||
function getTotalAmount() {
|
||||
let num = 0, total = 0
|
||||
for (let index = 0; index < data.goodsList.length; index++) {
|
||||
let item = data.goodsList[index]
|
||||
if(item.apply_amount) {
|
||||
num += item.apply_amount * 100
|
||||
total += item.apply_amount * 100
|
||||
} else if(item.real_unit_price && item.real_quantity) {
|
||||
let real_amount = item.real_unit_price * item.real_quantity
|
||||
num += real_amount * 100 - item.has_paid_amount * 100
|
||||
total += real_amount * 100
|
||||
}
|
||||
}
|
||||
for (let index = 0; index < data.feesList.length; index++) {
|
||||
let item = data.feesList[index]
|
||||
if(item.amount && item.has_paid_amount * 1 > 0) {
|
||||
total += item.amount * 100
|
||||
if(!item.id && item.amount) {
|
||||
num += item.amount * 100
|
||||
}
|
||||
}
|
||||
}
|
||||
data.total_amount = (num / 100).toFixed(2)
|
||||
data.real_total_amount = (total / 100).toFixed(2)
|
||||
}
|
||||
|
||||
function changeInput(){
|
||||
for (let index = 0; index < data.goodsList.length; index++) {
|
||||
let item = data.goodsList[index]
|
||||
if(item.real_unit_price && item.real_quantity) {
|
||||
item.real_amount = item.real_unit_price * item.real_quantity
|
||||
item.apply_amount = ((item.real_amount * 100 - item.has_paid_amount * 100) / 100).toFixed(2)
|
||||
}
|
||||
}
|
||||
getTotalAmount()
|
||||
}
|
||||
|
||||
function changeApply() {
|
||||
let num = 0, total = 0
|
||||
for (let index = 0; index < data.goodsList.length; index++) {
|
||||
let item = data.goodsList[index]
|
||||
num += item.apply_amount * 100
|
||||
total += item.apply_amount * 100
|
||||
}
|
||||
for (let index = 0; index < data.feesList.length; index++) {
|
||||
let item = data.feesList[index]
|
||||
if(item.amount && item.has_paid_amount * 1 > 0) {
|
||||
total += item.amount * 100
|
||||
if(!item.id && item.amount) {
|
||||
num += item.amount * 100
|
||||
}
|
||||
}
|
||||
}
|
||||
data.total_amount = (num / 100).toFixed(2)
|
||||
data.real_total_amount = (total / 100).toFixed(2)
|
||||
}
|
||||
|
||||
watch(() => data.feesList, (newProps) => {
|
||||
getTotalAmount()
|
||||
}, { deep: true })
|
||||
|
||||
watch(() => props, (newProps) => {
|
||||
if (newProps.show) {
|
||||
data.showDialog = true
|
||||
data.launchId = newProps.id
|
||||
if(data.launchId) {
|
||||
getDetail()
|
||||
}
|
||||
getAccount()
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
changeInput,
|
||||
getDetail,
|
||||
getAccount,
|
||||
closeDialog,
|
||||
clearForm,
|
||||
commitApproval,
|
||||
addFee,
|
||||
removeFee,
|
||||
getTotalAmount,
|
||||
changeApply
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
::v-deep .inpt .el-input__inner{
|
||||
text-align: center;
|
||||
}
|
||||
.h5Tit{
|
||||
margin-top: 20px;
|
||||
}
|
||||
.huibox{
|
||||
background-color: #f5f5f5;
|
||||
padding: 15px;
|
||||
line-height: 30px;
|
||||
border-left: 3px solid #3c8dbc;
|
||||
}
|
||||
</style>
|
||||
96
src/components/approval/logs.vue
Normal file
96
src/components/approval/logs.vue
Normal file
@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<el-dialog v-model="showDialog" title="审批记录" width="700px" @close="closeDialog">
|
||||
<div style="padding-top: 30px;">
|
||||
<el-timeline style="max-width: 600px">
|
||||
<el-timeline-item v-for="(item, index) in logsList" :key="index">
|
||||
<div><span style="color: #f00;">{{Status[item.status]}}</span>#{{Type[item.type]}}</div>
|
||||
<div style="color: #888;padding-top:5px;">{{item.created_at}}</div>
|
||||
<div style="padding-top: 30px;" v-if="item.records.length">
|
||||
<el-timeline style="max-width: 600px">
|
||||
<el-timeline-item v-for="it in item.records" :key="it.id" :timestamp="it.created_at">
|
||||
<div>
|
||||
<span style="color: #00C297;">@{{it.admin_user && it.admin_user.username}}</span>
|
||||
<span style="color: #f00;">{{Status[it.node_status]}}</span>
|
||||
</div>
|
||||
<span style="color: #666;" v-if="it.comments">原因:{{it.comments}}</span>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</div>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Plus, Search } from "@element-plus/icons"
|
||||
import { reactive, toRefs, watch } from 'vue'
|
||||
import { get } from '@/api/request'
|
||||
|
||||
export default {
|
||||
components: { Plus, Search },
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
id: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
const data = reactive({
|
||||
launchId: 0,
|
||||
showDialog: false,
|
||||
loading: false,
|
||||
Type: {
|
||||
'1': '采购订单审批',
|
||||
'2': '预付款打款审批',
|
||||
'3': '尾款打款审批',
|
||||
'4': '已结束'
|
||||
},
|
||||
Status: {
|
||||
'1': '提交了审批',
|
||||
'2': '同意了审批',
|
||||
'3': '驳回了审批',
|
||||
'4': '上传凭证'
|
||||
},
|
||||
logsList: []
|
||||
})
|
||||
|
||||
function getDetail() {
|
||||
data.loading = true
|
||||
get(`/api/purchaseOrder/orderInstanceList`, {purchase_order_id: data.launchId}).then((res) => {
|
||||
data.logsList = res.data
|
||||
data.loading = false
|
||||
}).catch(() => {
|
||||
data.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
const closeDialog = () => {
|
||||
context.emit('close')
|
||||
data.showDialog = false
|
||||
}
|
||||
|
||||
watch(() => props, (newProps) => {
|
||||
if (newProps.show) {
|
||||
data.showDialog = true
|
||||
data.launchId = newProps.id
|
||||
getDetail()
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
closeDialog,
|
||||
getDetail,
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
522
src/components/approval/order.vue
Normal file
522
src/components/approval/order.vue
Normal file
@ -0,0 +1,522 @@
|
||||
<template>
|
||||
<el-dialog v-model="showDialog" title="采购订单审批" width="1200px" @close="closeDialog">
|
||||
<el-form label-position="right" label-width="110px" v-loading="loading" :disabled="elType == 'view'">
|
||||
<el-form-item label="公司名称:">
|
||||
<el-select v-model="itemInfo.company_id" placeholder="请选择" clearable filterable style="width: 320px;">
|
||||
<el-option v-for="it in companyList" :key="it.id" :label="it.name" :value="it.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="选品:">
|
||||
<el-select v-model="itemInfo.manager_id" placeholder="请选择" clearable filterable style="width: 320px;">
|
||||
<el-option v-for="it in managerList" :key="it.id" :label="it.username" :value="it.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="供应商名称:">
|
||||
<el-select v-model="itemInfo.purchase_supplier_id" placeholder="请选择" clearable filterable style="width: 320px;">
|
||||
<el-option v-for="it in supplierList" :key="it.id" :label="it.supplier_name" :value="it.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品信息:">
|
||||
<el-button type="primary" @click="openGoods()">添加商品</el-button>
|
||||
|
||||
<el-table :data="goodsList" style="width: 100%;margin-top: 15px;" border>
|
||||
<el-table-column prop="goods.title" label="商品名称" />
|
||||
<el-table-column label="规格名称">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.sku && scope.row.sku.title || scope.row.title }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="预计产品单价(含税)" align="center">
|
||||
<template #default="scope">
|
||||
<el-input class="inpt" type="text" v-model="scope.row.expect_unit_price" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单位" align="center">
|
||||
<template #default="scope">
|
||||
<el-input class="inpt" type="text" v-model="scope.row.unit" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="预计采购数量" align="center">
|
||||
<template #default="scope">
|
||||
<el-input class="inpt" type="text" v-model="scope.row.expect_quantity" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="预付款比例(%)" align="center">
|
||||
<template #default="scope">
|
||||
<div style="display: flex;align-items: center;"><el-input type="text" class="inpt" v-model="scope.row.prepayment_ratio" /> %</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="交货时间" width="160" align="center">
|
||||
<template #default="scope">
|
||||
<el-date-picker
|
||||
v-model="scope.row.delivery_date"
|
||||
type="date"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="选择日期"
|
||||
style="width: 130px;"
|
||||
clearable>
|
||||
</el-date-picker>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-button type="danger" size="mini" @click="removeGoods(scope.$index, scope.row.product_id)"><el-icon><DeleteFilled /></el-icon></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="其他费用:">
|
||||
<el-button type="primary" @click="addFee">添加其他费用</el-button>
|
||||
|
||||
<el-table :data="feesList" style="width: 100%;margin-top: 15px;" border>
|
||||
<el-table-column label="费用名称" align="center">
|
||||
<template #default="scope">
|
||||
<el-input type="text" v-model="scope.row.fee_name" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="订单金额">
|
||||
<template #default="scope">
|
||||
<el-input type="text" v-model="scope.row.amount" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="打款信息">
|
||||
<template #default="scope">
|
||||
<el-select v-model="scope.row.other_expense_account_id" placeholder="请选择" clearable filterable>
|
||||
<el-option v-for="it in accountList" :key="it.id" :label="it.name" :value="it.id" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-button type="danger" size="mini" @click="removeFee(scope.$index)"><el-icon><DeleteFilled /></el-icon></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注:">
|
||||
<el-input v-model="itemInfo.remark" placeholder="请填写备注内容" type="textarea" :rows="4"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="逾期交货说明:">
|
||||
<el-input v-model="itemInfo.late_delivery_explanation" placeholder="请填写逾期交货说明" type="textarea" :rows="4"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="总计:">
|
||||
<div class="sumbox">
|
||||
总预计订单金额(元):<span>{{ sumData.total_amount || '0.00' }}</span>,
|
||||
总预付款(元):<span>{{ sumData.pre_pay_amount || '0.00' }}</span>,
|
||||
总尾款(元):<span>{{ sumData.balance_amount || '0.00' }}</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<div class="space"></div>
|
||||
<div class="h5Tit">其余信息</div>
|
||||
<el-form-item label="开团时间:">
|
||||
<el-date-picker
|
||||
v-model="itemInfo.sold_start_time"
|
||||
type="datetime"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择开团时间"
|
||||
clearable>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="预计到仓时间:">
|
||||
<el-date-picker
|
||||
v-model="itemInfo.arrived_time"
|
||||
type="datetime"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="预计到仓时间"
|
||||
clearable>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="仓库:">
|
||||
<el-input type="text" v-model="itemInfo.warehouse_name" placeholder="请输入仓库名称" clearable style="width: 320px;" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer" v-if="elType != 'view'">
|
||||
<el-button @click="closeDialog()">取消</el-button>
|
||||
<el-button type="primary" @click="commitApproval()" :loading="btnloading">提交审批</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="showGoods" width="900px" title="添加商品">
|
||||
<div class="searchBox">
|
||||
<div class="row">
|
||||
<span class="span">商品名称:</span>
|
||||
<div class="right">
|
||||
<el-select v-model="filter.goodsIds" placeholder="请选择" clearable filterable class="wid100">
|
||||
<el-option v-for="it in goodskuList" :key="it.id" :label="it.title" :value="it.id" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="span">规格名称:</span>
|
||||
<div class="right"><el-input v-model="filter.title" class="wid100" clearable></el-input></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="span">规格编码:</span>
|
||||
<div class="right"><el-input v-model="filter.sku_code" class="wid100" clearable></el-input></div>
|
||||
</div>
|
||||
<el-button type="primary" @click="handleSearch"><el-icon><Search /></el-icon> 筛选</el-button>
|
||||
</div>
|
||||
<el-table :data="tableList" style="width: 100%" border v-loading="loading1" @select="select"
|
||||
ref="multipleTable" @select-all="selectAll">
|
||||
<el-table-column type="selection" width="55" :selectable="checkSelect" />
|
||||
<el-table-column prop="id" label="ID" width="80" align="center" />
|
||||
<el-table-column prop="goods.title" label="商品名称" align="center" />
|
||||
<el-table-column prop="goods.goods_code" label="商品货号" align="center" />
|
||||
<el-table-column prop="title" label="规格名称" align="center" />
|
||||
<el-table-column prop="sku_code" label="规格编码" align="center" />
|
||||
</el-table>
|
||||
<div class="page-pagination">
|
||||
<el-pagination
|
||||
:current-page="page"
|
||||
background
|
||||
layout="prev, pager, next, sizes, total"
|
||||
:total="total"
|
||||
:page-sizes="[10, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"></el-pagination>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="showGoods = false">取消</el-button>
|
||||
<el-button type="primary" @click="addGoods">确定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { DeleteFilled, Search } from "@element-plus/icons"
|
||||
import { reactive, toRefs, watch } from 'vue'
|
||||
import { get, post } from '@/api/request'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
|
||||
export default {
|
||||
components: { DeleteFilled, Search },
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
id: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: '',
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
const data = reactive({
|
||||
launchId: 0,
|
||||
elType: '',
|
||||
showDialog: false,
|
||||
companyList: [],
|
||||
managerList: [],
|
||||
supplierList: [],
|
||||
accountList: [],
|
||||
goodsList: [],
|
||||
itemInfo: {},
|
||||
loading: false,
|
||||
showGoods: false,
|
||||
feesList: [],
|
||||
goodskuList: [],
|
||||
filter: {},
|
||||
tableList: [],
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
loading1: false,
|
||||
chooseList: [],
|
||||
btnloading: false,
|
||||
goodsIds: [],
|
||||
sumData: {}
|
||||
})
|
||||
|
||||
function getDetail() {
|
||||
data.loading = true
|
||||
get(`/api/purchaseOrder/${data.launchId}`).then((res) => {
|
||||
data.itemInfo = res.data
|
||||
data.feesList = res.data.other_expenses
|
||||
data.goodsList = res.data.products
|
||||
res.data.products.forEach((item) => {
|
||||
data.goodsIds.push(item.product_id)
|
||||
})
|
||||
data.loading = false
|
||||
}).catch(() => {
|
||||
data.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
function getCompany() {
|
||||
get(`/api/company/all`, {page: 1, pageSize: 1000}).then((res) => {
|
||||
data.companyList = res.data
|
||||
})
|
||||
}
|
||||
|
||||
function getManagerList() {
|
||||
get('/api/staff', {role_id: 1}).then((res) => {
|
||||
data.managerList = res.data
|
||||
})
|
||||
}
|
||||
|
||||
function getSupplier() {
|
||||
get(`/api/purchaseSupplier`, {page: 1, pageSize: 1000}).then((res) => {
|
||||
data.supplierList = res.data
|
||||
})
|
||||
}
|
||||
|
||||
function getAccount() {
|
||||
get(`/api/otherExpenseAccount`, {page: 1, pageSize: 1000}).then((res) => {
|
||||
data.accountList = res.data
|
||||
})
|
||||
}
|
||||
|
||||
const commitApproval = () => {
|
||||
data.btnloading = true
|
||||
let products = []
|
||||
for (let index = 0; index < data.goodsList.length; index++) {
|
||||
let obj = data.goodsList[index]
|
||||
products.push({
|
||||
product_id: obj.goods_id,
|
||||
sku_id: obj.sku_id,
|
||||
expect_unit_price: obj.expect_unit_price,
|
||||
expect_quantity: obj.expect_quantity,
|
||||
unit: obj.unit,
|
||||
prepayment_ratio: obj.prepayment_ratio,
|
||||
delivery_date: obj.delivery_date
|
||||
})
|
||||
}
|
||||
let params = {
|
||||
company_id: data.itemInfo.company_id,
|
||||
manager_id: data.itemInfo.manager_id,
|
||||
purchase_supplier_id: data.itemInfo.purchase_supplier_id,
|
||||
products: products,
|
||||
otherExpenses: data.feesList,
|
||||
remark: data.itemInfo.remark,
|
||||
late_delivery_explanation: data.itemInfo.late_delivery_explanation,
|
||||
sold_start_time: data.itemInfo.sold_start_time,
|
||||
arrived_time: data.itemInfo.arrived_time,
|
||||
warehouse_name: data.itemInfo.warehouse_name
|
||||
}
|
||||
post(`/api/purchaseOrder`, params).then((res) => {
|
||||
ElMessage({ type: 'success', message: '操作成功' })
|
||||
closeDialog()
|
||||
context.emit('refresh')
|
||||
data.btnloading = false
|
||||
}).catch(() => {
|
||||
data.btnloading = false
|
||||
})
|
||||
}
|
||||
|
||||
function clearForm() {
|
||||
data.itemInfo = {}
|
||||
data.feesList = []
|
||||
data.goodsList = []
|
||||
data.goodsIds = []
|
||||
}
|
||||
|
||||
function getGoodskuList() {
|
||||
get(`/api/all/goods`).then((res) => {
|
||||
data.goodskuList = res.data
|
||||
})
|
||||
}
|
||||
|
||||
function handleSearch() {
|
||||
data.page = 1
|
||||
fetchData()
|
||||
}
|
||||
|
||||
const fetchData = () => {
|
||||
data.loading1 = true
|
||||
let params = {
|
||||
page: data.page,
|
||||
pageSize: data.pageSize,
|
||||
...data.filter,
|
||||
}
|
||||
get(`/api/goods-skus`, params).then((res) => {
|
||||
data.tableList = res.data
|
||||
data.total = res.meta.total
|
||||
data.loading1 = false
|
||||
data.chooseList = []
|
||||
}).catch(() => {
|
||||
data.loading1 = false
|
||||
})
|
||||
}
|
||||
|
||||
function handleCurrentChange(e) {
|
||||
data.page = e
|
||||
fetchData()
|
||||
}
|
||||
|
||||
function handleSizeChange(e) {
|
||||
data.page = 1
|
||||
data.pageSize = e
|
||||
fetchData()
|
||||
}
|
||||
|
||||
const closeDialog = () => {
|
||||
clearForm()
|
||||
context.emit('close')
|
||||
data.showDialog = false
|
||||
}
|
||||
|
||||
function select(e) {
|
||||
data.chooseList = e
|
||||
}
|
||||
|
||||
function selectAll(e) {
|
||||
data.chooseList = e
|
||||
}
|
||||
|
||||
function checkSelect(row) {
|
||||
if (data.goodsIds.indexOf(row.id) >= 0) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
function addGoods() {
|
||||
if(!data.chooseList.length) {
|
||||
return ElMessage.info('请选择商品')
|
||||
}
|
||||
data.chooseList.forEach((item) => {
|
||||
item.product_id = item.goods_id
|
||||
item.sku_id = item.id
|
||||
data.goodsList.push(item)
|
||||
data.goodsIds.push(item.goods_id)
|
||||
})
|
||||
data.showGoods = false
|
||||
}
|
||||
|
||||
function removeGoods(i, id) {
|
||||
data.goodsList.splice(i, 1)
|
||||
let index = data.goodsIds.indexOf(id)
|
||||
data.goodsIds.splice(index, 1)
|
||||
}
|
||||
|
||||
function addFee() {
|
||||
data.feesList.push({
|
||||
fee_name: '',
|
||||
amount: '',
|
||||
other_expense_account_id: ''
|
||||
})
|
||||
}
|
||||
|
||||
function removeFee(i) {
|
||||
data.feesList.splice(i, 1)
|
||||
}
|
||||
|
||||
function openGoods() {
|
||||
data.showGoods = true
|
||||
handleSearch()
|
||||
}
|
||||
|
||||
watch(() => data.goodsList, (newProps) => {
|
||||
let num1 = 0, num2 = 0, num3 = 0
|
||||
for (let index = 0; index < newProps.length; index++) {
|
||||
let item = newProps[index]
|
||||
if(item.expect_unit_price && item.expect_quantity) {
|
||||
num1 += item.expect_unit_price * item.expect_quantity
|
||||
if(item.prepayment_ratio) {
|
||||
num2 += num1 * item.prepayment_ratio
|
||||
num3 += num1 * 100 - num2
|
||||
}
|
||||
}
|
||||
}
|
||||
data.sumData.total_amount = num1.toFixed(2)
|
||||
data.sumData.pre_pay_amount = (num2 / 100).toFixed(2)
|
||||
data.sumData.balance_amount = (num3 / 100).toFixed(2)
|
||||
}, { deep: true })
|
||||
|
||||
watch(() => props, (newProps) => {
|
||||
if (newProps.show) {
|
||||
data.showDialog = true
|
||||
data.launchId = newProps.id
|
||||
data.elType = newProps.type || ''
|
||||
if(data.launchId) {
|
||||
getDetail()
|
||||
}
|
||||
getCompany()
|
||||
getManagerList()
|
||||
getSupplier()
|
||||
getGoodskuList()
|
||||
getAccount()
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
getDetail,
|
||||
getAccount,
|
||||
closeDialog,
|
||||
getCompany,
|
||||
getManagerList,
|
||||
getSupplier,
|
||||
clearForm,
|
||||
commitApproval,
|
||||
getGoodskuList,
|
||||
handleSearch,
|
||||
handleCurrentChange,
|
||||
handleSizeChange,
|
||||
select,
|
||||
selectAll,
|
||||
checkSelect,
|
||||
addGoods,
|
||||
removeGoods,
|
||||
addFee,
|
||||
removeFee,
|
||||
openGoods
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.searchBox{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
background-color: #fff;
|
||||
padding: 15px 0 0 0;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 15px;
|
||||
.row{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 250px;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 15px;
|
||||
.span{
|
||||
display: block;
|
||||
width: 80px;
|
||||
font-size: 14px;
|
||||
text-align: right;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.right{
|
||||
width: calc(100% - 100px);
|
||||
}
|
||||
.wid100{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.space{
|
||||
background: repeating-linear-gradient(-45deg, #F56C6C 0, #F56C6C 20%, transparent 0, transparent 25%, #1989fa 0, #1989fa 45%, transparent 0, transparent 50%);
|
||||
height: 2px;
|
||||
background-size: 80px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
::v-deep .inpt .el-input__inner{
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
146
src/components/approval/prepayment.vue
Normal file
146
src/components/approval/prepayment.vue
Normal file
@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<el-dialog v-model="showDialog" title="预付款打款审批" width="700px" @close="closeDialog">
|
||||
<el-form label-position="right" label-width="90px" v-loading="loading">
|
||||
<el-form-item label="订单合同:">
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
action="/api/upload/img"
|
||||
:headers="headers"
|
||||
:on-remove="handleRemoveImg"
|
||||
:on-error="handleUploadError"
|
||||
:on-preview="handlePreview"
|
||||
:on-success="handleSuccess"
|
||||
:file-list="imgsList"
|
||||
:show-file-list="true"
|
||||
list-type="picture-card"
|
||||
accept=".png,.jpg,.gif">
|
||||
<el-icon><Plus /></el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="closeDialog()">取消</el-button>
|
||||
<el-button type="primary" @click="commitApproval()" :loading="loading">提交审批</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 预览图片 -->
|
||||
<el-dialog v-model="picVisible" center width="800px">
|
||||
<img :src="dialogImageUrl" style="max-width: 700px; margin: 0 auto;display: block;" />
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Plus, Search } from "@element-plus/icons"
|
||||
import { reactive, toRefs, watch, ref, nextTick } from 'vue'
|
||||
import { get, post } from '@/api/request'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
export default {
|
||||
components: { Plus, Search },
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
id: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
const data = reactive({
|
||||
headers: {
|
||||
Authorization: localStorage.getItem('token'),
|
||||
'Shop-Id': localStorage.getItem('shopId') || ''
|
||||
},
|
||||
picVisible: false,
|
||||
dialogImageUrl: '',
|
||||
launchId: 0,
|
||||
showDialog: false,
|
||||
imgsList: [],
|
||||
loading: false,
|
||||
})
|
||||
|
||||
const commitApproval = () => {
|
||||
data.loading = true
|
||||
let imgs = []
|
||||
for (let index = 0; index < data.imgsList.length; index++) {
|
||||
let obj = data.imgsList[index]
|
||||
imgs.push(obj.url)
|
||||
}
|
||||
let params = {
|
||||
purchase_order_id: data.launchId,
|
||||
related_images: imgs
|
||||
}
|
||||
post(`/api/purchaseOrder/prepaymentSubmit`, params).then((res) => {
|
||||
ElMessage({ type: 'success', message: '提交成功' })
|
||||
closeDialog()
|
||||
context.emit('refresh')
|
||||
data.loading = false
|
||||
}).catch(() => {
|
||||
data.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
function handleUploadError(err) {
|
||||
if(JSON.parse(err.message) && JSON.parse(err.message).message) {
|
||||
ElMessage({ type: 'error', message: JSON.parse(err.message).message })
|
||||
}
|
||||
}
|
||||
|
||||
function handleRemoveImg(res, ress) {
|
||||
data.imgsList = ress
|
||||
}
|
||||
|
||||
function handleSuccess(res) {
|
||||
data.imgsList.push({url: res.data.link})
|
||||
}
|
||||
|
||||
const uploadRef = ref(null)
|
||||
|
||||
function clearForm() {
|
||||
data.imgsList = []
|
||||
nextTick(() => {
|
||||
uploadRef.value.clearFiles()
|
||||
})
|
||||
}
|
||||
|
||||
const closeDialog = () => {
|
||||
clearForm()
|
||||
context.emit('close')
|
||||
data.showDialog = false
|
||||
}
|
||||
|
||||
function handlePreview(File) {
|
||||
data.dialogImageUrl = File.url
|
||||
data.picVisible = true
|
||||
}
|
||||
|
||||
watch(() => props, (newProps) => {
|
||||
if (newProps.show) {
|
||||
data.showDialog = true
|
||||
data.launchId = newProps.id
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
return {
|
||||
uploadRef,
|
||||
...toRefs(data),
|
||||
closeDialog,
|
||||
clearForm,
|
||||
commitApproval,
|
||||
handlePreview,
|
||||
handleSuccess,
|
||||
handleRemoveImg,
|
||||
handleUploadError
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
122
src/components/approval/update.vue
Normal file
122
src/components/approval/update.vue
Normal file
@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<el-dialog v-model="showDialog" title="更新信息" width="700px" @close="closeDialog">
|
||||
<el-form label-position="right" label-width="120px" v-loading="loading">
|
||||
<el-form-item label="开团时间:">
|
||||
<el-date-picker
|
||||
v-model="itemInfo.sold_start_time"
|
||||
type="datetime"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择开团时间"
|
||||
clearable>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="预计到仓时间:">
|
||||
<el-date-picker
|
||||
v-model="itemInfo.arrived_time"
|
||||
type="datetime"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="预计到仓时间"
|
||||
clearable>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="仓库:">
|
||||
<el-input type="text" v-model="itemInfo.warehouse_name" placeholder="请输入仓库名称" clearable style="width: 320px;" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="closeDialog()">取消</el-button>
|
||||
<el-button type="primary" @click="commitApproval()" :loading="loading">提交审批</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Plus, Search } from "@element-plus/icons"
|
||||
import { reactive, toRefs, watch, ref, nextTick } from 'vue'
|
||||
import { get, post } from '@/api/request'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
export default {
|
||||
components: { Plus, Search },
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
id: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
const data = reactive({
|
||||
launchId: 0,
|
||||
showDialog: false,
|
||||
loading: false,
|
||||
itemInfo: {}
|
||||
})
|
||||
|
||||
function getDetail() {
|
||||
data.loading = true
|
||||
get(`/api/purchaseOrder/${data.launchId}`).then((res) => {
|
||||
data.itemInfo = res.data
|
||||
data.loading = false
|
||||
}).catch(() => {
|
||||
data.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
const commitApproval = () => {
|
||||
data.loading = true
|
||||
let params = {
|
||||
purchase_order_id: data.launchId,
|
||||
sold_start_time: data.itemInfo.sold_start_time,
|
||||
arrived_time: data.itemInfo.arrived_time,
|
||||
warehouse_name: data.itemInfo.warehouse_name
|
||||
}
|
||||
post(`/api/purchaseOrder/updateOrderInfo`, params).then((res) => {
|
||||
ElMessage({ type: 'success', message: '修改成功' })
|
||||
closeDialog()
|
||||
context.emit('refresh')
|
||||
data.loading = false
|
||||
}).catch(() => {
|
||||
data.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
function clearForm() {
|
||||
data.itemInfo = {}
|
||||
}
|
||||
|
||||
const closeDialog = () => {
|
||||
clearForm()
|
||||
context.emit('close')
|
||||
data.showDialog = false
|
||||
}
|
||||
|
||||
watch(() => props, (newProps) => {
|
||||
if (newProps.show) {
|
||||
data.showDialog = true
|
||||
data.launchId = newProps.id
|
||||
getDetail()
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
closeDialog,
|
||||
clearForm,
|
||||
commitApproval,
|
||||
getDetail,
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
162
src/components/approval/uploadinvoice.vue
Normal file
162
src/components/approval/uploadinvoice.vue
Normal file
@ -0,0 +1,162 @@
|
||||
<template>
|
||||
<el-dialog v-model="showDialog" title="上传发票" width="700px" @close="closeDialog">
|
||||
<el-form label-position="right" label-width="90px" v-loading="loading">
|
||||
<el-form-item label="发票:">
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
action="/api/upload/img"
|
||||
:headers="headers"
|
||||
:on-remove="handleRemoveImg"
|
||||
:on-error="handleUploadError"
|
||||
:on-preview="handlePreview"
|
||||
:on-success="handleSuccess"
|
||||
:file-list="imgsList"
|
||||
:show-file-list="true"
|
||||
list-type="picture-card"
|
||||
accept=".png,.jpg,.gif">
|
||||
<el-icon><Plus /></el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="closeDialog()">取消</el-button>
|
||||
<el-button type="primary" @click="commitApproval()" :loading="loading">提交审批</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 预览图片 -->
|
||||
<el-dialog v-model="picVisible" center width="800px">
|
||||
<img :src="dialogImageUrl" style="max-width: 700px; margin: 0 auto;display: block;" />
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Plus, Search } from "@element-plus/icons"
|
||||
import { reactive, toRefs, watch, ref, nextTick } from 'vue'
|
||||
import { get, post } from '@/api/request'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
export default {
|
||||
components: { Plus, Search },
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
id: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
const data = reactive({
|
||||
headers: {
|
||||
Authorization: localStorage.getItem('token'),
|
||||
'Shop-Id': localStorage.getItem('shopId') || ''
|
||||
},
|
||||
picVisible: false,
|
||||
dialogImageUrl: '',
|
||||
launchId: 0,
|
||||
showDialog: false,
|
||||
imgsList: [],
|
||||
loading: false,
|
||||
})
|
||||
|
||||
function getDetail() {
|
||||
data.loading = true
|
||||
get(`/api/purchaseOrder/${data.launchId}`).then((res) => {
|
||||
let list = res.data.invoice_images || []
|
||||
list.forEach((item) => {
|
||||
data.imgsList.push({url: item})
|
||||
})
|
||||
data.loading = false
|
||||
}).catch(() => {
|
||||
data.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
const commitApproval = () => {
|
||||
data.loading = true
|
||||
let imgs = []
|
||||
for (let index = 0; index < data.imgsList.length; index++) {
|
||||
let obj = data.imgsList[index]
|
||||
imgs.push(obj.url)
|
||||
}
|
||||
let params = {
|
||||
purchase_order_id: data.launchId,
|
||||
invoice_images: imgs
|
||||
}
|
||||
post(`/api/purchaseOrder/invoiceSubmit`, params).then((res) => {
|
||||
ElMessage({ type: 'success', message: '提交成功' })
|
||||
closeDialog()
|
||||
context.emit('refresh')
|
||||
data.loading = false
|
||||
}).catch(() => {
|
||||
data.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
function handleUploadError(err) {
|
||||
if(JSON.parse(err.message) && JSON.parse(err.message).message) {
|
||||
ElMessage({ type: 'error', message: JSON.parse(err.message).message })
|
||||
}
|
||||
}
|
||||
|
||||
function handleRemoveImg(res, ress) {
|
||||
data.imgsList = ress
|
||||
}
|
||||
|
||||
function handleSuccess(res) {
|
||||
data.imgsList.push({url: res.data.link})
|
||||
}
|
||||
|
||||
const uploadRef = ref(null)
|
||||
|
||||
function clearForm() {
|
||||
data.imgsList = []
|
||||
data.imgsList = []
|
||||
nextTick(() => {
|
||||
uploadRef.value.clearFiles()
|
||||
})
|
||||
}
|
||||
|
||||
const closeDialog = () => {
|
||||
clearForm()
|
||||
context.emit('close')
|
||||
data.showDialog = false
|
||||
}
|
||||
|
||||
function handlePreview(File) {
|
||||
data.dialogImageUrl = File.url
|
||||
data.picVisible = true
|
||||
}
|
||||
|
||||
watch(() => props, (newProps) => {
|
||||
if (newProps.show) {
|
||||
data.showDialog = true
|
||||
data.launchId = newProps.id
|
||||
getDetail()
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
return {
|
||||
uploadRef,
|
||||
...toRefs(data),
|
||||
closeDialog,
|
||||
clearForm,
|
||||
commitApproval,
|
||||
handlePreview,
|
||||
handleSuccess,
|
||||
handleRemoveImg,
|
||||
handleUploadError,
|
||||
getDetail
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
146
src/components/approval/uploadpayment.vue
Normal file
146
src/components/approval/uploadpayment.vue
Normal file
@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<el-dialog v-model="showDialog" title="上传支付凭证" width="700px" @close="closeDialog">
|
||||
<el-form label-position="right" label-width="90px" v-loading="loading">
|
||||
<el-form-item label="支付凭证:">
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
action="/api/upload/img"
|
||||
:headers="headers"
|
||||
:on-remove="handleRemoveImg"
|
||||
:on-error="handleUploadError"
|
||||
:on-preview="handlePreview"
|
||||
:on-success="handleSuccess"
|
||||
:file-list="imgsList"
|
||||
:show-file-list="true"
|
||||
list-type="picture-card"
|
||||
accept=".png,.jpg,.gif">
|
||||
<el-icon><Plus /></el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="closeDialog()">取消</el-button>
|
||||
<el-button type="primary" @click="commitApproval()" :loading="loading">提交</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 预览图片 -->
|
||||
<el-dialog v-model="picVisible" center width="800px">
|
||||
<img :src="dialogImageUrl" style="max-width: 700px; margin: 0 auto;display: block;" />
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Plus, Search } from "@element-plus/icons"
|
||||
import { reactive, toRefs, watch, ref, nextTick } from 'vue'
|
||||
import { get, post } from '@/api/request'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
export default {
|
||||
components: { Plus, Search },
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
id: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
}
|
||||
},
|
||||
setup(props, context) {
|
||||
const data = reactive({
|
||||
headers: {
|
||||
Authorization: localStorage.getItem('token'),
|
||||
'Shop-Id': localStorage.getItem('shopId') || ''
|
||||
},
|
||||
picVisible: false,
|
||||
dialogImageUrl: '',
|
||||
launchId: 0,
|
||||
showDialog: false,
|
||||
imgsList: [],
|
||||
loading: false,
|
||||
})
|
||||
|
||||
const commitApproval = () => {
|
||||
data.loading = true
|
||||
let imgs = []
|
||||
for (let index = 0; index < data.imgsList.length; index++) {
|
||||
let obj = data.imgsList[index]
|
||||
imgs.push(obj.url)
|
||||
}
|
||||
let params = {
|
||||
instance_id: data.launchId,
|
||||
payment_voucher: imgs
|
||||
}
|
||||
post(`/api/purchaseOrder/uploadPayment`, params).then((res) => {
|
||||
ElMessage({ type: 'success', message: '提交成功' })
|
||||
closeDialog()
|
||||
context.emit('refresh')
|
||||
data.loading = false
|
||||
}).catch(() => {
|
||||
data.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
function handleUploadError(err) {
|
||||
if(JSON.parse(err.message) && JSON.parse(err.message).message) {
|
||||
ElMessage({ type: 'error', message: JSON.parse(err.message).message })
|
||||
}
|
||||
}
|
||||
|
||||
function handleRemoveImg(res, ress) {
|
||||
data.imgsList = ress
|
||||
}
|
||||
|
||||
function handleSuccess(res) {
|
||||
data.imgsList.push({url: res.data.link})
|
||||
}
|
||||
|
||||
const uploadRef = ref(null)
|
||||
|
||||
function clearForm() {
|
||||
data.imgsList = []
|
||||
nextTick(() => {
|
||||
uploadRef.value.clearFiles()
|
||||
})
|
||||
}
|
||||
|
||||
const closeDialog = () => {
|
||||
clearForm()
|
||||
context.emit('close')
|
||||
data.showDialog = false
|
||||
}
|
||||
|
||||
function handlePreview(File) {
|
||||
data.dialogImageUrl = File.url
|
||||
data.picVisible = true
|
||||
}
|
||||
|
||||
watch(() => props, (newProps) => {
|
||||
if (newProps.show) {
|
||||
data.showDialog = true
|
||||
data.launchId = newProps.id
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
return {
|
||||
uploadRef,
|
||||
...toRefs(data),
|
||||
closeDialog,
|
||||
clearForm,
|
||||
commitApproval,
|
||||
handlePreview,
|
||||
handleSuccess,
|
||||
handleRemoveImg,
|
||||
handleUploadError
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
@ -31,10 +31,34 @@ export const whiteList = [
|
||||
},
|
||||
{
|
||||
path: '/purchase/index',
|
||||
name: 'purchase',
|
||||
name: 'purchaselist',
|
||||
full_path: 'views/purchase/index.vue',
|
||||
component: () => import('views/purchase/index')
|
||||
},
|
||||
{
|
||||
path: '/purchase/supplier',
|
||||
name: 'purchaseSupplier',
|
||||
full_path: 'views/purchase/supplier.vue',
|
||||
component: () => import('views/purchase/supplier')
|
||||
},
|
||||
{
|
||||
path: '/purchase/waitapproval',
|
||||
name: 'waitapproval',
|
||||
full_path: 'views/purchase/waitapproval.vue',
|
||||
component: () => import('views/purchase/waitapproval')
|
||||
},
|
||||
{
|
||||
path: '/purchase/approval',
|
||||
name: 'purchaseapproval',
|
||||
full_path: 'views/purchase/approval.vue',
|
||||
component: () => import('views/purchase/approval')
|
||||
},
|
||||
{
|
||||
path: '/purchase/otherfees',
|
||||
name: 'otherfees',
|
||||
full_path: 'views/purchase/otherfees.vue',
|
||||
component: () => import('views/purchase/otherfees')
|
||||
},
|
||||
{
|
||||
path: '/warehouse/index',
|
||||
name: 'warehouse',
|
||||
@ -85,10 +109,14 @@ export const constantRouterComponents = {
|
||||
'commoditySku': () => import('views/commodity/sku'),
|
||||
'combination': () => import('views/commodity/combination'),
|
||||
'commodityBrand': () => import('views/commodity/brand'),
|
||||
'purchase': () => import('views/purchase/index'),
|
||||
'purchaselist': () => import('views/purchase/index'),
|
||||
'warehouse': () => import('views/warehouse/index'),
|
||||
'warehouseIO': () => import('views/warehouse/io'),
|
||||
'supplier': () => import('views/supplier/index'),
|
||||
'purchaseSupplier': () => import('views/purchase/supplier'),
|
||||
'waitapproval': () => import('views/purchase/waitapproval'),
|
||||
'purchaseapproval': () => import('views/purchase/approval'),
|
||||
'otherfees': () => import('views/purchase/otherfees'),
|
||||
'statistics': () => import('views/statistics/index'),
|
||||
'role': () => import('views/permission/role'),
|
||||
'menus': () => import('views/permission/menus'),
|
||||
|
||||
@ -158,6 +158,12 @@
|
||||
<el-radio :label="0">不启用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品成本:">
|
||||
<el-input placeholder="商品成本" v-model="item.goods_cost" clearable style="width: 250px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="运费成本:">
|
||||
<el-input placeholder="运费成本" v-model="item.freight_cost" clearable style="width: 250px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="赠品:">
|
||||
<el-radio-group v-model="item.gift" style="width: 250px;">
|
||||
<el-radio :label="0">不是</el-radio>
|
||||
@ -373,7 +379,9 @@ export default {
|
||||
warehouse_id: data.itemInfo.warehouse_id || '',
|
||||
status: 1,
|
||||
sort: 0,
|
||||
gift: 0
|
||||
gift: 0,
|
||||
goods_cost: '',
|
||||
freight_cost: ''
|
||||
}
|
||||
data.skusList.push(sku)
|
||||
}
|
||||
|
||||
@ -58,9 +58,11 @@
|
||||
<el-card shadow="never">
|
||||
<div class="opaBox">
|
||||
<el-button type="primary" @click="handleAdd"><el-icon><Plus /></el-icon> 新增</el-button>
|
||||
<!-- <el-button type="warning" @click="handleExport"><span class="iconfont icon-daochu"></span> 导出</el-button> -->
|
||||
<el-button type="primary" v-if="role" :disabled="!chooseList.length" @click="lte_stock = 0, showStock = true">设置预警库存</el-button>
|
||||
</div>
|
||||
<el-table :data="tableList" style="width: 100%" border v-loading="loading">
|
||||
<el-table :data="tableList" style="width: 100%" border v-loading="loading" @select="select"
|
||||
ref="multipleTable" @select-all="selectAll">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="id" label="ID" width="80" align="center" />
|
||||
<el-table-column prop="goods.title" label="商品名称" align="center" />
|
||||
<el-table-column prop="goods.goods_code" label="商品货号" align="center" />
|
||||
@ -82,6 +84,9 @@
|
||||
<el-table-column prop="lock_in_stock" label="运营锁定库存" align="center" />
|
||||
<el-table-column prop="after_sale_stock" label="售后锁定库存" align="center" />
|
||||
<el-table-column prop="available_inventory" label="可售库存" align="center" />
|
||||
<el-table-column prop="lte_stock" label="预警库存" align="center" />
|
||||
<el-table-column prop="goods_cost" label="商品成本" align="center" />
|
||||
<el-table-column prop="freight_cost" label="运费成本" align="center" />
|
||||
<el-table-column prop="warehouse.name" label="仓库" align="center" />
|
||||
<el-table-column label="状态" align="center">
|
||||
<template #default="scope">
|
||||
@ -112,27 +117,31 @@
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="showDialog" width="600px" :title="opaType == 'add' ? '新增' : '编辑' ">
|
||||
<el-dialog v-model="showUpdate" width="600px" title="新增">
|
||||
<el-form label-position="right" label-width="110px">
|
||||
<el-form-item label="所属商品:">
|
||||
<el-select v-model="itemInfo.goods_id" placeholder="请选择" clearable filterable :disabled="role && opaType == 'edit'">
|
||||
<el-select v-model="itemInfo.goods_id" placeholder="请选择" clearable filterable disabled>
|
||||
<el-option v-for="it in goodsList" :key="it.id" :label="it.title" :value="it.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="规格名称:">
|
||||
<el-input v-model="itemInfo.title" clearable :disabled="role && opaType == 'edit'"></el-input>
|
||||
<el-input v-model="itemInfo.title" clearable disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="规格编码:">
|
||||
<el-input v-model="itemInfo.sku_code" clearable :disabled="role && opaType == 'edit'"></el-input>
|
||||
<el-input v-model="itemInfo.sku_code" clearable disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="仓库:">
|
||||
<el-select v-model="itemInfo.warehouse_id" placeholder="请选择" clearable filterable :disabled="role && opaType == 'edit'">
|
||||
<el-option v-for="it in warehouseList" :key="it.id" :label="it.name" :value="it.id" />
|
||||
</el-select>
|
||||
<el-form-item label="赠品:">
|
||||
<el-radio-group v-model="itemInfo.gift" disabled>
|
||||
<el-radio :label="0">不是</el-radio>
|
||||
<el-radio :label="1">是</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="总锁定库存:">
|
||||
<el-input v-model="itemInfo.total_lock_num" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="预警库存:">
|
||||
<el-input v-model="itemInfo.lte_stock" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="一阶段库存:">
|
||||
<el-input v-model="itemInfo.first_stage_stock" clearable></el-input>
|
||||
</el-form-item>
|
||||
@ -146,27 +155,64 @@
|
||||
<el-input v-model="itemInfo.lock_in_stock" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="售后锁定库存:">
|
||||
<el-input v-model="itemInfo.after_sale_stock" clearable :disabled="role && opaType == 'edit'"></el-input>
|
||||
<el-input v-model="itemInfo.after_sale_stock" clearable disabled></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="showUpdate = false">取消</el-button>
|
||||
<el-button type="primary" @click="commitUpdate()" :loading="opa_loading">确定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="showDialog" width="600px" :title="opaType == 'add' ? '新增' : '编辑' ">
|
||||
<el-form label-position="right" label-width="110px">
|
||||
<el-form-item label="所属商品:">
|
||||
<el-select v-model="itemInfo.goods_id" placeholder="请选择" clearable filterable>
|
||||
<el-option v-for="it in goodsList" :key="it.id" :label="it.title" :value="it.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="规格名称:">
|
||||
<el-input v-model="itemInfo.title" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="规格编码:">
|
||||
<el-input v-model="itemInfo.sku_code" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="仓库:">
|
||||
<el-select v-model="itemInfo.warehouse_id" placeholder="请选择" clearable filterable>
|
||||
<el-option v-for="it in warehouseList" :key="it.id" :label="it.name" :value="it.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="售后锁定库存:">
|
||||
<el-input v-model="itemInfo.after_sale_stock" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品成本:">
|
||||
<el-input v-model="itemInfo.goods_cost" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="运费成本:">
|
||||
<el-input v-model="itemInfo.freight_cost" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态:">
|
||||
<el-radio-group v-model="itemInfo.status" :disabled="role && opaType == 'edit'">
|
||||
<el-radio-group v-model="itemInfo.status">
|
||||
<el-radio :label="1">启用</el-radio>
|
||||
<el-radio :label="0">不启用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="赠品:">
|
||||
<el-radio-group v-model="itemInfo.gift" :disabled="role && opaType == 'edit'">
|
||||
<el-radio-group v-model="itemInfo.gift">
|
||||
<el-radio :label="0">不是</el-radio>
|
||||
<el-radio :label="1">是</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序:">
|
||||
<el-input-number v-model="itemInfo.sort" :min="0" :disabled="role && opaType == 'edit'" />
|
||||
<el-input-number v-model="itemInfo.sort" :min="0" />
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer" v-if="opaType != 'view'">
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="showDialog = false">取消</el-button>
|
||||
<el-button type="primary" @click="commitOpa()" :loading="opa_loading">确定</el-button>
|
||||
</span>
|
||||
@ -178,6 +224,19 @@
|
||||
<img :src="dialogImageUrl" style="max-width: 700px; margin: 0 auto;display: block;" />
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="showStock" width="600px" title="设置预警库存">
|
||||
<el-form label-position="right" label-width="110px">
|
||||
<el-form-item label="预警库存:">
|
||||
<el-input-number v-model="lte_stock" clearable></el-input-number>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="showStock = false">取消</el-button>
|
||||
<el-button type="primary" @click="commitStock()">确定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -209,7 +268,11 @@ export default {
|
||||
role: localStorage.getItem('roleName') == '爆品运营',
|
||||
goodsIds: [],
|
||||
brandIds: [],
|
||||
brandList: []
|
||||
brandList: [],
|
||||
chooseList: [],
|
||||
lte_stock: 0,
|
||||
showStock: false,
|
||||
showUpdate: false
|
||||
})
|
||||
|
||||
function handleSearch() {
|
||||
@ -260,7 +323,11 @@ export default {
|
||||
function handleEdit(item) {
|
||||
data.opaType = 'edit'
|
||||
data.itemInfo = JSON.parse(JSON.stringify(item))
|
||||
data.showDialog = true
|
||||
if(data.role) {
|
||||
data.showUpdate = true
|
||||
} else {
|
||||
data.showDialog = true
|
||||
}
|
||||
}
|
||||
|
||||
function handleUpload(row) {
|
||||
@ -292,36 +359,40 @@ export default {
|
||||
parseErrors(err.response.data.errors)
|
||||
})
|
||||
} else {
|
||||
if(data.role) {
|
||||
params = {
|
||||
lock_in_stock: data.itemInfo.lock_in_stock,
|
||||
first_stage_stock: data.itemInfo.first_stage_stock,
|
||||
second_stage_stock: data.itemInfo.second_stage_stock,
|
||||
third_stage_stock: data.itemInfo.third_stage_stock
|
||||
}
|
||||
post(`/api/goods/sku/lockInStock/${data.itemInfo.id}`, params, 'PUT').then(() => {
|
||||
fetchData()
|
||||
ElMessage({ type: 'success', message: '编辑成功' })
|
||||
data.showDialog = false
|
||||
data.opa_loading = false
|
||||
}).catch((err) => {
|
||||
data.opa_loading = false
|
||||
parseErrors(err.response.data.errors)
|
||||
})
|
||||
} else {
|
||||
post(`/api/goods-skus/${data.itemInfo.id}`, params, 'PUT').then(() => {
|
||||
fetchData()
|
||||
ElMessage({ type: 'success', message: '编辑成功' })
|
||||
data.showDialog = false
|
||||
data.opa_loading = false
|
||||
}).catch((err) => {
|
||||
data.opa_loading = false
|
||||
parseErrors(err.response.data.errors)
|
||||
})
|
||||
}
|
||||
post(`/api/goods-skus/${data.itemInfo.id}`, params, 'PUT').then(() => {
|
||||
fetchData()
|
||||
ElMessage({ type: 'success', message: '编辑成功' })
|
||||
data.showDialog = false
|
||||
data.opa_loading = false
|
||||
}).catch((err) => {
|
||||
data.opa_loading = false
|
||||
parseErrors(err.response.data.errors)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function commitUpdate() {
|
||||
data.opa_loading = true
|
||||
let params = {
|
||||
lock_in_stock: data.itemInfo.lock_in_stock,
|
||||
first_stage_stock: data.itemInfo.first_stage_stock,
|
||||
second_stage_stock: data.itemInfo.second_stage_stock,
|
||||
third_stage_stock: data.itemInfo.third_stage_stock,
|
||||
lte_stock: data.itemInfo.lte_stock,
|
||||
goods_cost: data.itemInfo.goods_cost,
|
||||
freight_cost: data.itemInfo.freight_cost
|
||||
}
|
||||
post(`/api/goods/sku/lockInStock/${data.itemInfo.id}`, params, 'PUT').then(() => {
|
||||
fetchData()
|
||||
ElMessage({ type: 'success', message: '编辑成功' })
|
||||
data.showUpdate = false
|
||||
data.opa_loading = false
|
||||
}).catch((err) => {
|
||||
data.opa_loading = false
|
||||
parseErrors(err.response.data.errors)
|
||||
})
|
||||
}
|
||||
|
||||
function getWarehouseList() {
|
||||
get(`/api/all/warehouses`).then((res) => {
|
||||
data.warehouseList = res.data
|
||||
@ -340,6 +411,31 @@ export default {
|
||||
})
|
||||
}
|
||||
|
||||
function select(e) {
|
||||
data.chooseList = e
|
||||
}
|
||||
|
||||
function selectAll(e) {
|
||||
data.chooseList = e
|
||||
}
|
||||
|
||||
function commitStock() {
|
||||
let ids = []
|
||||
data.chooseList.forEach((it) => {
|
||||
ids.push(it.id)
|
||||
})
|
||||
let params = {
|
||||
ids: ids,
|
||||
lte_stock: data.lte_stock
|
||||
}
|
||||
post('/api/goods/sku/batchUpdateLetStock', params, 'PUT').then((res) => {
|
||||
ElMessage({ type: 'success', message: '操作成功' })
|
||||
data.chooseList = []
|
||||
data.showStock = false
|
||||
fetchData()
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchData()
|
||||
getWarehouseList()
|
||||
@ -357,9 +453,13 @@ export default {
|
||||
handleEdit,
|
||||
handleUpload,
|
||||
commitOpa,
|
||||
commitUpdate,
|
||||
getWarehouseList,
|
||||
getGoodsList,
|
||||
getBrandList
|
||||
getBrandList,
|
||||
select,
|
||||
selectAll,
|
||||
commitStock
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
444
src/views/purchase/approval.vue
Normal file
444
src/views/purchase/approval.vue
Normal file
@ -0,0 +1,444 @@
|
||||
<template>
|
||||
<div class="pageBox">
|
||||
<div class="searchBox">
|
||||
<div class="row">
|
||||
<span class="span">ID:</span>
|
||||
<div class="right"><el-input v-model="filter.id" class="wid100" clearable></el-input></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="span">供应商名称:</span>
|
||||
<div class="right">
|
||||
<el-select v-model="filter.purchase_supplier_id" placeholder="请选择" clearable filterable>
|
||||
<el-option v-for="it in suppliersList" :key="it.id" :label="it.supplier_name" :value="it.id" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="span">提交时间:</span>
|
||||
<div class="right">
|
||||
<el-date-picker
|
||||
v-model="submitTime"
|
||||
type="datetimerange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 100%;box-sizing: border-box;">
|
||||
</el-date-picker>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="span">审批类型:</span>
|
||||
<div class="right">
|
||||
<el-select v-model="filter.approval_type" placeholder="请选择" clearable class="wid100">
|
||||
<el-option label="采购订单审批" :value="1" />
|
||||
<el-option label="预付款打款审批" :value="2" />
|
||||
<el-option label="尾款打款审批" :value="3" />
|
||||
<el-option label="已结束" :value="4" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row row1">
|
||||
<el-button type="primary" @click="handleSearch"><el-icon><Search /></el-icon> 筛选</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-card shadow="never">
|
||||
<div class="opaBox">
|
||||
<el-button type="primary" @click="handleAdd"><el-icon><Plus /></el-icon> 新增</el-button>
|
||||
</div>
|
||||
<el-table :data="goodsList" style="width: 100%" border v-loading="loading">
|
||||
<el-table-column prop="id" label="ID" width="80" align="center" />
|
||||
<el-table-column prop="type" label="采购类型" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ approvalType[scope.row.approval_type] }}</span>
|
||||
|
||||
<div v-if="scope.row.approval_type == 1" :class="'status' + scope.row.order_approval_status">{{ approvalStatus[scope.row.order_approval_status] }}</div>
|
||||
<div v-else-if="scope.row.approval_type == 2" :class="'status' + scope.row.prepayment_approval_status">{{ approvalStatus[scope.row.prepayment_approval_status] }}</div>
|
||||
<div v-else-if="scope.row.approval_type == 3" :class="'status' + scope.row.final_payment_approval_status">{{ approvalStatus[scope.row.final_payment_approval_status] }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="purchase_supplier.supplier_name" label="采购供应商" />
|
||||
<el-table-column label="申请采购商品信息">
|
||||
<template #default="scope">
|
||||
<div v-if="scope.row.products">
|
||||
<div v-for="it in scope.row.products" :key="it.id">{{it.goods && it.goods.title}}({{ it.unit }})</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="总预计订单金额/总预防款/总尾款" align="center">
|
||||
<template #default="scope">
|
||||
<div>{{ scope.row.total_amount }}</div>
|
||||
<div>{{ scope.row.prepayment_amount }}</div>
|
||||
<div>{{ scope.row.final_payment_amount }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="总实际订单金额/总实际已支付金额/总实际未支付金额" align="center">
|
||||
<template #default="scope">
|
||||
<div>{{ scope.row.has_paid_amount }}</div>
|
||||
<div>{{ scope.row.has_paid_prepayment_amount }}</div>
|
||||
<div>{{ scope.row.has_paid_final_payment_amount }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="提交人/提交时间" align="center">
|
||||
<template #default="scope">
|
||||
<div>{{ scope.row.admin_user && scope.row.admin_user.username || '-' }}</div>
|
||||
<span>{{ scope.row.created_at }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="260">
|
||||
<template #default="scope">
|
||||
<div class="elbtn">
|
||||
<el-button type="primary" v-if="scope.row.approval_type != 4" text @click="resubmit(scope.row.id)"><el-icon><RefreshLeft /></el-icon>重新提审</el-button>
|
||||
|
||||
<el-button type="primary" text @click="toPrepayment(scope.row.id)" v-if="(scope.row.approval_type == 1 && scope.row.order_approval_status == 2) || (scope.row.approval_type == 2 && scope.row.prepayment_approval_status == 3)"><el-icon><Position /></el-icon>发起预付款审批</el-button>
|
||||
|
||||
<el-button type="primary" text @click="toPayment(scope.row.current_instance_id)"
|
||||
v-if="(scope.row.approval_type == 2 && scope.row.prepayment_approval_status == 2) || (scope.row.approval_type == 3 && scope.row.final_payment_approval_status == 2)">
|
||||
<el-icon><Upload /></el-icon>上传支付凭证
|
||||
</el-button>
|
||||
|
||||
<el-button type="primary" text @click="toBalancePayment(scope.row.id)"
|
||||
v-if="(scope.row.approval_type == 2 && scope.row.prepayment_approval_status == 4) || (scope.row.approval_type == 3 && scope.row.final_payment_approval_status == 3) || (scope.row.approval_type == 3 && scope.row.final_payment_approval_status == 4 && scope.row.total_amount * 1 > scope.row.has_paid_amount * 1)">
|
||||
<el-icon><Position /></el-icon>尾款打款审批
|
||||
</el-button>
|
||||
|
||||
<el-button type="primary" text @click="toInvoice(scope.row.id)" v-if="scope.row.approval_type != 4"><el-icon><Upload /></el-icon>上传发票</el-button>
|
||||
<el-button type="danger" text @click="endApproval(scope.row.id)" v-if="scope.row.final_payment_approval_status == 4 && scope.row.approval_type != 4"><el-icon><SwitchButton /></el-icon>结束审批</el-button>
|
||||
<el-button type="primary" text @click="handleView(scope.row.id)"><el-icon><ZoomIn /></el-icon>查看详情</el-button>
|
||||
<el-button type="info" text @click="openLogs(scope.row.id)"><el-icon><Clock /></el-icon>审批记录</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="page-pagination">
|
||||
<el-pagination
|
||||
:current-page="page"
|
||||
background
|
||||
layout="prev, pager, next, sizes, total"
|
||||
:total="total"
|
||||
:page-sizes="[10, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"></el-pagination>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 预览图片 -->
|
||||
<el-dialog v-model="picVisible" center width="800px">
|
||||
<img :src="dialogImageUrl" style="max-width: 700px; margin: 0 auto;display: block;" />
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog v-model="showAdd" width="500px" title="新增审批">
|
||||
<el-form label-position="right" label-width="10px">
|
||||
<el-form-item label="">
|
||||
<el-radio-group v-model="add_type">
|
||||
<el-radio :label="1">采购订单审批</el-radio>
|
||||
<el-radio :label="2">预付款打款审批</el-radio>
|
||||
<el-radio :label="3">尾款打款审批</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="showAdd = false">取消</el-button>
|
||||
<el-button type="primary" @click="curId = 0, showOrderApproval = true, showAdd = false">确定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 订单审批 -->
|
||||
<order-approval :show="showOrderApproval" :type="elType" :id="curId" @refresh="handleSearch" @close="showOrderApproval = false"></order-approval>
|
||||
|
||||
<!-- 预付款审批 -->
|
||||
<order-prepayment :show="showPrepayment" :id="curId" @refresh="fetchData" @close="showPrepayment = false"></order-prepayment>
|
||||
|
||||
<!-- 上传支付凭证 -->
|
||||
<upload-payment :show="showPayment" :id="curId" @refresh="fetchData" @close="showPayment = false"></upload-payment>
|
||||
|
||||
<!-- 尾款审批 -->
|
||||
<balance-payment :show="showBalance" :id="curId" @refresh="fetchData" @close="showBalance = false"></balance-payment>
|
||||
|
||||
<!-- 修改信息 -->
|
||||
<update-approval :show="showEditApproval" :id="curId" @refresh="fetchData" @close="showEditApproval = false"></update-approval>
|
||||
|
||||
<!-- 修改信息 -->
|
||||
<approval-logs :show="showApprovalLogs" :id="curId" @close="showApprovalLogs = false"></approval-logs>
|
||||
|
||||
<!-- 上传发票 -->
|
||||
<upload-invoice :show="showInvoice" :id="curId" @close="showInvoice = false"></upload-invoice>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { onMounted, reactive, toRefs, ref, nextTick } from "vue"
|
||||
import { get, post } from "@/api/request"
|
||||
import { Search, Plus, Edit, ZoomIn, Delete, RefreshLeft, SwitchButton, Position, Upload, Clock } from '@element-plus/icons'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import orderApproval from '@/components/approval/order.vue'
|
||||
import orderPrepayment from '@/components/approval/prepayment.vue'
|
||||
import uploadPayment from '@/components/approval/uploadpayment.vue'
|
||||
import balancePayment from '@/components/approval/balancepayment.vue'
|
||||
import updateApproval from '@/components/approval/update.vue'
|
||||
import approvalLogs from '@/components/approval/logs.vue'
|
||||
import uploadInvoice from '@/components/approval/uploadinvoice.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Search, Plus, Edit, ZoomIn, Delete, RefreshLeft, SwitchButton, Position, Upload, Clock,
|
||||
uploadPayment, balancePayment, updateApproval, orderApproval, orderPrepayment, approvalLogs, uploadInvoice
|
||||
},
|
||||
setup() {
|
||||
const data = reactive({
|
||||
add_type: 1,
|
||||
showAdd: false,
|
||||
showEditApproval: false,
|
||||
showOrderApproval: false,
|
||||
showApprovalLogs: false,
|
||||
showInvoice: false,
|
||||
showPayment: false,
|
||||
showBalance: false,
|
||||
showPrepayment: false,
|
||||
filter: {},
|
||||
submitTime: [],
|
||||
goodsList: [],
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
loading: false,
|
||||
picVisible: false,
|
||||
dialogImageUrl: '',
|
||||
approvalType: {
|
||||
'1': '采购订单审批',
|
||||
'2': '预付款打款审批',
|
||||
'3': '尾款打款审批',
|
||||
'4': '已结束'
|
||||
},
|
||||
approvalStatus: {
|
||||
'0': '草稿',
|
||||
'1': '进行中',
|
||||
'2': '已完成',
|
||||
'3': '已驳回',
|
||||
'4': '上传凭证'
|
||||
},
|
||||
warehouseList: [],
|
||||
suppliersList: [],
|
||||
allGoodsList: [],
|
||||
curId: 0,
|
||||
elType: ''
|
||||
})
|
||||
|
||||
function handleSearch() {
|
||||
data.page = 1
|
||||
fetchData()
|
||||
}
|
||||
|
||||
const fetchData = () => {
|
||||
data.loading = true
|
||||
let params = {
|
||||
page: data.page,
|
||||
pageSize: data.pageSize,
|
||||
...data.filter,
|
||||
start_date: data.submitTime ? data.submitTime[0] : '',
|
||||
end_date: data.submitTime ? data.submitTime[1] : ''
|
||||
}
|
||||
get(`/api/purchaseOrder`, params).then((res) => {
|
||||
data.goodsList = res.data
|
||||
data.total = res.meta.total
|
||||
data.loading = false
|
||||
}).catch(() => {
|
||||
data.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
function handleCurrentChange(e) {
|
||||
data.page = e
|
||||
fetchData()
|
||||
}
|
||||
|
||||
function handleSizeChange(e) {
|
||||
data.page = 1
|
||||
data.pageSize = e
|
||||
fetchData()
|
||||
}
|
||||
|
||||
function getWarehouseList() {
|
||||
get(`/api/all/warehouses`).then((res) => {
|
||||
data.warehouseList = res.data
|
||||
})
|
||||
}
|
||||
|
||||
function getSuppliersList() {
|
||||
get(`/api/purchaseSupplier`, {pageSize: 1000}).then((res) => {
|
||||
data.suppliersList = res.data
|
||||
})
|
||||
}
|
||||
|
||||
function getAllGoodsList() {
|
||||
get(`/api/all/goods`).then((res) => {
|
||||
data.allGoodsList = res.data
|
||||
})
|
||||
}
|
||||
|
||||
function resubmit(id) {
|
||||
data.curId = id
|
||||
data.showEditApproval = true
|
||||
}
|
||||
|
||||
function toPrepayment(id) {
|
||||
data.curId = id
|
||||
data.showPrepayment = true
|
||||
}
|
||||
|
||||
function toPayment(id) {
|
||||
data.curId = id
|
||||
data.showPayment = true
|
||||
}
|
||||
|
||||
function toBalancePayment(id) {
|
||||
data.curId = id
|
||||
data.showBalance = true
|
||||
}
|
||||
|
||||
function openLogs(id) {
|
||||
data.curId = id
|
||||
data.showApprovalLogs = true
|
||||
}
|
||||
|
||||
function toInvoice(id) {
|
||||
data.curId = id
|
||||
data.showInvoice = true
|
||||
}
|
||||
|
||||
function endApproval(id) {
|
||||
ElMessageBox.confirm('确定要结束当前审批流程吗?', '警告', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
post(`/api/purchaseOrder/endProcess`, {purchase_order_id: id}).then(() => {
|
||||
fetchData()
|
||||
ElMessage({ type: 'success', message: '操作成功' })
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function handleAdd() {
|
||||
data.elType = ''
|
||||
data.curId = 0
|
||||
data.showOrderApproval = true
|
||||
}
|
||||
|
||||
function handleView(id) {
|
||||
data.elType = 'view'
|
||||
data.curId = id
|
||||
data.showOrderApproval = true
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchData()
|
||||
getWarehouseList()
|
||||
getSuppliersList()
|
||||
getAllGoodsList()
|
||||
})
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
handleAdd,
|
||||
handleSearch,
|
||||
handleCurrentChange,
|
||||
handleSizeChange,
|
||||
fetchData,
|
||||
getWarehouseList,
|
||||
getSuppliersList,
|
||||
getAllGoodsList,
|
||||
resubmit,
|
||||
endApproval,
|
||||
toPrepayment,
|
||||
toPayment,
|
||||
toBalancePayment,
|
||||
openLogs,
|
||||
toInvoice,
|
||||
handleView
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.searchBox{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
background-color: #fff;
|
||||
padding: 15px 15px 0 0;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 15px;
|
||||
.row{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 20%;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 15px;
|
||||
.span{
|
||||
display: block;
|
||||
width: 100px;
|
||||
font-size: 14px;
|
||||
text-align: right;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.right{
|
||||
width: calc(100% - 100px);
|
||||
}
|
||||
.wid100{
|
||||
width: 100%;
|
||||
}
|
||||
&.row1{
|
||||
margin-left: 15px;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
.opaBox{
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.imgBox{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
.el-image{
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 4px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.skuBox{
|
||||
border: 1px solid #e5e5e5;
|
||||
border-radius: 5px;
|
||||
padding: 15px 0;
|
||||
margin-bottom: 15px;
|
||||
background-color: #f3f3f3;
|
||||
.tit{
|
||||
padding-left: 40px;
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
::v-deep .elbtn .el-button.is-text{
|
||||
padding: 8px 0px;
|
||||
}
|
||||
.status1{
|
||||
color: #f90;
|
||||
}
|
||||
.status2{
|
||||
color: #67C23A;
|
||||
}
|
||||
.status3{
|
||||
color: #909399;
|
||||
}
|
||||
.status4{
|
||||
color: #F56C6C;
|
||||
}
|
||||
</style>
|
||||
@ -343,31 +343,31 @@ export default {
|
||||
}
|
||||
|
||||
function handleFileSuccess(res, ress) {
|
||||
if (res.code === 0) {
|
||||
data.qaFileList = [{ name: ress.name, url: res.data.link }]
|
||||
}
|
||||
}
|
||||
function handleFileRemove(res, ress) {
|
||||
data.qaFileList = ress
|
||||
if (res.code === 0) {
|
||||
data.qaFileList = [{ name: ress.name, url: res.data.link }]
|
||||
}
|
||||
}
|
||||
function handleFileRemove(res, ress) {
|
||||
data.qaFileList = ress
|
||||
}
|
||||
|
||||
function previewFile(File) {
|
||||
window.open(File.response.data.link)
|
||||
}
|
||||
|
||||
const handleBeforeUpload = (file) => {
|
||||
let type = file.name.indexOf('.pdf') !== -1 || file.name.indexOf('.doc') !== -1 || file.name.indexOf('.docx') !== -1 || file.name.indexOf('.zip') !== -1 || file.name.indexOf('.xlsx') !== -1
|
||||
if (type) {
|
||||
const isLt4M = file.size / 1024 / 1024 < 4
|
||||
if (!isLt4M) {
|
||||
ElMessage.error('附件上传大小不能超过 4MB!')
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
ElMessage.error('上传文件格式不正确')
|
||||
function previewFile(File) {
|
||||
window.open(File.response.data.link)
|
||||
}
|
||||
|
||||
const handleBeforeUpload = (file) => {
|
||||
let type = file.name.indexOf('.pdf') !== -1 || file.name.indexOf('.doc') !== -1 || file.name.indexOf('.docx') !== -1 || file.name.indexOf('.zip') !== -1 || file.name.indexOf('.xlsx') !== -1
|
||||
if (type) {
|
||||
const isLt4M = file.size / 1024 / 1024 < 4
|
||||
if (!isLt4M) {
|
||||
ElMessage.error('附件上传大小不能超过 4MB!')
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
ElMessage.error('上传文件格式不正确')
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function handleSkuDelete(index) {
|
||||
data.skusList.splice(index, 1)
|
||||
|
||||
265
src/views/purchase/otherfees.vue
Normal file
265
src/views/purchase/otherfees.vue
Normal file
@ -0,0 +1,265 @@
|
||||
<template>
|
||||
<div class="pageBox">
|
||||
<div class="searchBox">
|
||||
<div class="row">
|
||||
<span class="span">开户信息名称:</span>
|
||||
<div class="right"><el-input v-model="filter.name" class="wid100" clearable></el-input></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="span">银行开户名:</span>
|
||||
<div class="right"><el-input v-model="filter.bank_account_holder" class="wid100" clearable></el-input></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<el-button type="primary" @click="handleSearch"><el-icon><Search /></el-icon> 筛选</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-card shadow="never">
|
||||
<div class="opaBox">
|
||||
<el-button type="primary" @click="handleAdd"><el-icon><Plus /></el-icon> 新增</el-button>
|
||||
</div>
|
||||
<el-table :data="goodsList" style="width: 100%" border v-loading="loading">
|
||||
<el-table-column prop="id" label="ID" width="80" align="center" />
|
||||
<el-table-column prop="name" label="开户信息名称" />
|
||||
<el-table-column prop="bank_account_name" label="银行开户名" />
|
||||
<el-table-column prop="bank_account_number" label="银行帐户" />
|
||||
<el-table-column prop="bank_name" label="开户银行支行名称" />
|
||||
<el-table-column label="操作" align="center" width="150">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" circle @click="handleEdit(scope.row)"><el-icon><Edit /></el-icon></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="page-pagination">
|
||||
<el-pagination
|
||||
:current-page="page"
|
||||
background
|
||||
layout="prev, pager, next, sizes, total"
|
||||
:total="total"
|
||||
:page-sizes="[10, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"></el-pagination>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="showDialog" width="900px" :title="opaType == 'add' ? '新增' : '编辑' ">
|
||||
<el-form label-position="right" label-width="170px">
|
||||
<el-form-item label="开户信息名称:">
|
||||
<el-input v-model="itemInfo.name" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="银行开户名:">
|
||||
<el-input v-model="itemInfo.bank_account_name" clearable placeholder="请输入银行开户名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="银行账户:">
|
||||
<el-input v-model="itemInfo.bank_account_number" clearable placeholder="请输入银行账户"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="开户银行支行名称:">
|
||||
<el-input v-model="itemInfo.bank_name" clearable placeholder="请输入银行开户名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="开户银行所在地地址:">
|
||||
<el-input v-model="itemInfo.bank_address" clearable placeholder="请输入开户银行所在地地址"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="showDialog = false">取消</el-button>
|
||||
<el-button type="primary" @click="commitSupplier()" :loading="opa_loading">确定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 预览图片 -->
|
||||
<el-dialog v-model="picVisible" center width="800px">
|
||||
<img :src="dialogImageUrl" style="max-width: 700px; margin: 0 auto;display: block;" />
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { onMounted, reactive, toRefs } from "vue"
|
||||
import { get, post } from "@/api/request"
|
||||
import { Search, Plus, Edit } from '@element-plus/icons'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { parseErrors } from 'components/common'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Search, Plus, Edit
|
||||
},
|
||||
setup() {
|
||||
const data = reactive({
|
||||
filter: {},
|
||||
goodsList: [],
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
loading: false,
|
||||
opaType: '',
|
||||
showDialog: false,
|
||||
opa_loading: false,
|
||||
itemInfo: {},
|
||||
supplier_name: '',
|
||||
bank_account_holder: ''
|
||||
})
|
||||
|
||||
function handleSearch() {
|
||||
data.page = 1
|
||||
fetchData()
|
||||
}
|
||||
|
||||
const fetchData = () => {
|
||||
data.loading = true
|
||||
let params = {
|
||||
page: data.page,
|
||||
pageSize: data.pageSize,
|
||||
...data.filter
|
||||
}
|
||||
get(`/api/otherExpenseAccount`, params).then((res) => {
|
||||
data.goodsList = res.data
|
||||
data.total = res.meta.total
|
||||
data.loading = false
|
||||
}).catch(() => {
|
||||
data.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
function handleCurrentChange(e) {
|
||||
data.page = e
|
||||
fetchData()
|
||||
}
|
||||
|
||||
function handleSizeChange(e) {
|
||||
data.page = 1
|
||||
data.pageSize = e
|
||||
fetchData()
|
||||
}
|
||||
|
||||
function handleAdd() {
|
||||
data.opaType = 'add'
|
||||
data.itemInfo = {}
|
||||
data.showDialog = true
|
||||
}
|
||||
|
||||
function handleEdit(item) {
|
||||
data.opaType = 'edit'
|
||||
data.itemInfo = JSON.parse(JSON.stringify(item))
|
||||
data.showDialog = true
|
||||
}
|
||||
|
||||
function commitSupplier() {
|
||||
if(!data.itemInfo.name) {
|
||||
return ElMessage.info('请输入开户信息名称')
|
||||
} else if(!data.itemInfo.bank_account_name) {
|
||||
return ElMessage.info('银行开户名必填')
|
||||
} else if(!data.itemInfo.bank_account_number) {
|
||||
return ElMessage.info('银行账户必填')
|
||||
}
|
||||
data.opa_loading = true
|
||||
let params = {
|
||||
...data.itemInfo
|
||||
}
|
||||
|
||||
if(data.opaType == 'add') {
|
||||
post(`/api/otherExpenseAccount`, params).then(() => {
|
||||
data.page = 1
|
||||
fetchData()
|
||||
ElMessage({ type: 'success', message: '新增成功' })
|
||||
data.showDialog = false
|
||||
data.opa_loading = false
|
||||
}).catch((err) => {
|
||||
data.opa_loading = false
|
||||
parseErrors(err.response.data.errors)
|
||||
})
|
||||
} else {
|
||||
post(`/api/purchaseSupplier/${data.itemInfo.id}`, params, 'PUT').then(() => {
|
||||
fetchData()
|
||||
ElMessage({ type: 'success', message: '编辑成功' })
|
||||
data.showDialog = false
|
||||
data.opa_loading = false
|
||||
}).catch((err) => {
|
||||
data.opa_loading = false
|
||||
parseErrors(err.response.data.errors)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchData()
|
||||
})
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
handleSearch,
|
||||
handleCurrentChange,
|
||||
handleSizeChange,
|
||||
fetchData,
|
||||
handleAdd,
|
||||
handleEdit,
|
||||
commitSupplier
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.searchBox{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
background-color: #fff;
|
||||
padding: 15px 0 0 0;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 15px;
|
||||
.row{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 20%;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 15px;
|
||||
&.row1{
|
||||
width: 25%;
|
||||
}
|
||||
.span{
|
||||
display: block;
|
||||
width: 100px;
|
||||
font-size: 14px;
|
||||
text-align: right;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.right{
|
||||
width: calc(100% - 120px);
|
||||
}
|
||||
.wid100{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.opaBox{
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.imgBox{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
.el-image{
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 4px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.skuBox{
|
||||
border: 1px solid #e5e5e5;
|
||||
border-radius: 5px;
|
||||
padding: 15px 0;
|
||||
margin-bottom: 15px;
|
||||
background-color: #f3f3f3;
|
||||
.tit{
|
||||
padding-left: 40px;
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
447
src/views/purchase/supplier.vue
Normal file
447
src/views/purchase/supplier.vue
Normal file
@ -0,0 +1,447 @@
|
||||
<template>
|
||||
<div class="pageBox">
|
||||
<div class="searchBox">
|
||||
<div class="row">
|
||||
<span class="span">供应商名称:</span>
|
||||
<div class="right"><el-input v-model="supplier_name" class="wid100" clearable></el-input></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<el-button type="primary" @click="handleSearch"><el-icon><Search /></el-icon> 筛选</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-card shadow="never">
|
||||
<div class="opaBox">
|
||||
<el-button type="primary" @click="handleAdd"><el-icon><Plus /></el-icon> 新增</el-button>
|
||||
<!-- <el-button type="warning" @click="handleExport"><span class="iconfont icon-daochu"></span> 导出</el-button> -->
|
||||
</div>
|
||||
<el-table :data="goodsList" style="width: 100%" border v-loading="loading">
|
||||
<el-table-column prop="id" label="ID" width="80" align="center" />
|
||||
<el-table-column prop="supplier_name" label="供应商名称" />
|
||||
<el-table-column label="营业执照" align="center">
|
||||
<template #default="scope">
|
||||
<div class="imgBox" v-if="scope.row.business_license_path">
|
||||
<el-image :z-index="9999" :src="scope.row.business_license_path" :hide-on-click-modal="true" :preview-src-list="[scope.row.business_license_path]" fit="cover" :preview-teleported="true" />
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="生产许可证" align="center">
|
||||
<template #default="scope">
|
||||
<div class="imgBox" v-if="scope.row.production_license_path">
|
||||
<el-image :z-index="9999" :src="scope.row.production_license_path" :hide-on-click-modal="true" :preview-src-list="[scope.row.production_license_path]" fit="cover" :preview-teleported="true" />
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="合同">
|
||||
<template #default="scope">
|
||||
<div class="imgBox" v-if="scope.row.contract_path">
|
||||
<a :href="scope.row.contract_path" target="_blank">合同附件</a>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="bank_account" label="银行帐户" />
|
||||
<el-table-column prop="bank_account_holder" label="银行开户名" />
|
||||
<el-table-column prop="bank_branch_name" label="开户银行支行名称" />
|
||||
<el-table-column label="操作" align="center" width="150">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" circle @click="handleEdit(scope.row)"><el-icon><Edit /></el-icon></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="page-pagination">
|
||||
<el-pagination
|
||||
:current-page="page"
|
||||
background
|
||||
layout="prev, pager, next, sizes, total"
|
||||
:total="total"
|
||||
:page-sizes="[10, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"></el-pagination>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="showDialog" width="900px" :title="opaType == 'add' ? '新增' : '编辑' ">
|
||||
<el-form label-position="right" label-width="150px">
|
||||
<el-form-item label="供应商名称:">
|
||||
<el-input v-model="itemInfo.supplier_name" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="营业执照:">
|
||||
<el-upload
|
||||
ref="yyzzRef"
|
||||
action="/api/upload/img"
|
||||
:headers="headers"
|
||||
:on-remove="handleRemoveYyzzImg"
|
||||
:on-error="handleUploadError"
|
||||
:on-preview="handlePreview"
|
||||
:on-success="handleYyzzSuccess"
|
||||
:file-list="yyzzList"
|
||||
:show-file-list="true"
|
||||
list-type="picture-card"
|
||||
accept=".png,.jpg,.gif">
|
||||
<el-icon><Plus /></el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item label="生产许可证:">
|
||||
<el-upload
|
||||
ref="xkzRef"
|
||||
action="/api/upload/img"
|
||||
:headers="headers"
|
||||
:on-remove="handleRemoveXkzImg"
|
||||
:on-error="handleUploadError"
|
||||
:on-preview="handlePreview"
|
||||
:on-success="handleXkzSuccess"
|
||||
:file-list="xkzList"
|
||||
:show-file-list="true"
|
||||
list-type="picture-card"
|
||||
accept=".png,.jpg,.gif">
|
||||
<el-icon><Plus /></el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item label="合同:">
|
||||
<el-upload
|
||||
ref="fileRef"
|
||||
action="/api/upload/file"
|
||||
:on-success="handleFileSuccess"
|
||||
:on-remove="handleFileRemove"
|
||||
:before-upload="handleBeforeUpload"
|
||||
:on-error="handleUploadError"
|
||||
:on-preview="previewFile"
|
||||
:headers="headers"
|
||||
:file-list="fileList"
|
||||
:show-file-list="true">
|
||||
<el-button type="primary">上传附件</el-button>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">请上传zip、pdf、excel、doc(docx)格式附件,最大限制为 4 M</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item label="银行帐户:">
|
||||
<el-input v-model="itemInfo.bank_account" clearable placeholder="请输入银行账户"></el-input>
|
||||
<div style="color: #f00;font-size: 12px;">请仔细核对银行账户</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="银行开户名:">
|
||||
<el-input v-model="itemInfo.bank_account_holder" clearable placeholder="请输入银行开户名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="开户银行支行名称:">
|
||||
<el-input v-model="itemInfo.bank_branch_name" clearable placeholder="请输入银行开户名"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="showDialog = false">取消</el-button>
|
||||
<el-button type="primary" @click="commitSupplier()" :loading="opa_loading">确定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 预览图片 -->
|
||||
<el-dialog v-model="picVisible" center width="800px">
|
||||
<img :src="dialogImageUrl" style="max-width: 700px; margin: 0 auto;display: block;" />
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { onMounted, reactive, toRefs, ref, nextTick } from "vue"
|
||||
import { get, post } from "@/api/request"
|
||||
import { Search, Plus, Edit, ZoomIn, Delete } from '@element-plus/icons'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { parseErrors } from 'components/common'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Search, Plus, Edit, ZoomIn, Delete
|
||||
},
|
||||
setup() {
|
||||
const data = reactive({
|
||||
headers: {
|
||||
Authorization: localStorage.getItem('token'),
|
||||
'Shop-Id': localStorage.getItem('shopId') || ''
|
||||
},
|
||||
supplier_name: '',
|
||||
goodsList: [],
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
loading: false,
|
||||
opaType: '',
|
||||
showDialog: false,
|
||||
opa_loading: false,
|
||||
Type: {
|
||||
'default': '默认'
|
||||
},
|
||||
itemInfo: {},
|
||||
picVisible: false,
|
||||
dialogImageUrl: '',
|
||||
fileList: [],
|
||||
yyzzList: [],
|
||||
xkzList: [],
|
||||
|
||||
})
|
||||
|
||||
function handleSearch() {
|
||||
data.page = 1
|
||||
fetchData()
|
||||
}
|
||||
|
||||
const fetchData = () => {
|
||||
data.loading = true
|
||||
let params = {
|
||||
page: data.page,
|
||||
pageSize: data.pageSize,
|
||||
supplier_name: data.supplier_name
|
||||
}
|
||||
get(`/api/purchaseSupplier`, params).then((res) => {
|
||||
data.goodsList = res.data
|
||||
data.total = res.meta.total
|
||||
data.loading = false
|
||||
}).catch(() => {
|
||||
data.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
function handleCurrentChange(e) {
|
||||
data.page = e
|
||||
fetchData()
|
||||
}
|
||||
|
||||
function handleSizeChange(e) {
|
||||
data.page = 1
|
||||
data.pageSize = e
|
||||
fetchData()
|
||||
}
|
||||
|
||||
function handleAdd() {
|
||||
data.opaType = 'add'
|
||||
data.itemInfo = {
|
||||
type: 'default',
|
||||
sort: 0,
|
||||
status: 1
|
||||
}
|
||||
data.showDialog = true
|
||||
}
|
||||
|
||||
function handleEdit(item) {
|
||||
data.opaType = 'edit'
|
||||
data.itemInfo = JSON.parse(JSON.stringify(item))
|
||||
data.yyzzList = item.business_license_path ? [{url: item.business_license_path}] : []
|
||||
data.xkzList = item.production_license_path ? [{url: item.production_license_path}] : []
|
||||
data.fileList = item.contract_path ? [{name: '合同附件', url: item.contract_path}] : []
|
||||
data.showDialog = true
|
||||
}
|
||||
|
||||
function commitSupplier() {
|
||||
if(!data.itemInfo.supplier_name) {
|
||||
return ElMessage.info('请输入供应商名称')
|
||||
} else if(!data.yyzzList.length) {
|
||||
return ElMessage.info('请上传营业执照')
|
||||
} else if(!data.fileList.length) {
|
||||
return ElMessage.info('请上传合同附件')
|
||||
} else if(!data.itemInfo.bank_account) {
|
||||
return ElMessage.info('请输入银行账户')
|
||||
} else if(!data.itemInfo.bank_account_holder) {
|
||||
return ElMessage.info('请输入银行开户名')
|
||||
} else if(!data.itemInfo.bank_branch_name) {
|
||||
return ElMessage.info('请输入银行开户名')
|
||||
}
|
||||
data.opa_loading = true
|
||||
let params = {
|
||||
supplier_name: data.itemInfo.supplier_name,
|
||||
business_license_path: data.yyzzList[0].url,
|
||||
production_license_path: data.xkzList[0] && data.xkzList[0].url || '',
|
||||
contract_path: data.fileList[0].url,
|
||||
bank_account: data.itemInfo.bank_account,
|
||||
bank_account_holder: data.itemInfo.bank_account_holder,
|
||||
bank_branch_name: data.itemInfo.bank_branch_name
|
||||
}
|
||||
|
||||
if(data.opaType == 'add') {
|
||||
post(`/api/purchaseSupplier`, params).then(() => {
|
||||
clearForm()
|
||||
data.page = 1
|
||||
fetchData()
|
||||
ElMessage({ type: 'success', message: '新增成功' })
|
||||
data.showDialog = false
|
||||
data.opa_loading = false
|
||||
}).catch((err) => {
|
||||
data.opa_loading = false
|
||||
parseErrors(err.response.data.errors)
|
||||
})
|
||||
} else {
|
||||
post(`/api/purchaseSupplier/${data.itemInfo.id}`, params, 'PUT').then(() => {
|
||||
clearForm()
|
||||
fetchData()
|
||||
ElMessage({ type: 'success', message: '编辑成功' })
|
||||
data.showDialog = false
|
||||
data.opa_loading = false
|
||||
}).catch((err) => {
|
||||
data.opa_loading = false
|
||||
parseErrors(err.response.data.errors)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function handleRemoveYyzzImg(res, ress) {
|
||||
data.yyzzList = []
|
||||
}
|
||||
|
||||
function handleRemoveXkzImg(res, ress) {
|
||||
data.xkzList = []
|
||||
}
|
||||
|
||||
function handleUploadError(err) {
|
||||
if(JSON.parse(err.message) && JSON.parse(err.message).message) {
|
||||
ElMessage({ type: 'error', message: JSON.parse(err.message).message })
|
||||
}
|
||||
}
|
||||
|
||||
function handleYyzzSuccess(res) {
|
||||
data.yyzzList = [{url: res.data.link}]
|
||||
}
|
||||
|
||||
function handleXkzSuccess(res) {
|
||||
data.xkzList = [{url: res.data.link}]
|
||||
}
|
||||
|
||||
function handlePreview(File) {
|
||||
data.dialogImageUrl = File.url
|
||||
data.picVisible = true
|
||||
}
|
||||
|
||||
function handleFileSuccess(res, ress) {
|
||||
if (res.code === 0) {
|
||||
data.fileList = [{ name: ress.name, url: res.data.link }]
|
||||
}
|
||||
}
|
||||
function handleFileRemove(res, ress) {
|
||||
data.fileList = ress
|
||||
}
|
||||
|
||||
function previewFile(File) {
|
||||
window.open(File.url || File.response.data.link)
|
||||
}
|
||||
|
||||
const handleBeforeUpload = (file) => {
|
||||
let type = file.name.indexOf('.pdf') !== -1 || file.name.indexOf('.doc') !== -1 || file.name.indexOf('.docx') !== -1 || file.name.indexOf('.zip') !== -1 || file.name.indexOf('.xlsx') !== -1
|
||||
if (type) {
|
||||
const isLt4M = file.size / 1024 / 1024 < 4
|
||||
if (!isLt4M) {
|
||||
ElMessage.error('附件上传大小不能超过 4MB!')
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
ElMessage.error('上传文件格式不正确')
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const yyzzRef = ref(null)
|
||||
const xkzRef = ref(null)
|
||||
const fileRef = ref(null)
|
||||
|
||||
function clearForm() {
|
||||
data.yyzzList = []
|
||||
data.xkzList = []
|
||||
data.fileList = []
|
||||
nextTick(() => {
|
||||
yyzzRef.value.clearFiles()
|
||||
xkzRef.value.clearFiles()
|
||||
fileRef.value.clearFiles()
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchData()
|
||||
})
|
||||
|
||||
return {
|
||||
yyzzRef,
|
||||
xkzRef,
|
||||
fileRef,
|
||||
parseErrors,
|
||||
...toRefs(data),
|
||||
handleSearch,
|
||||
handleCurrentChange,
|
||||
handleSizeChange,
|
||||
fetchData,
|
||||
handleAdd,
|
||||
handleEdit,
|
||||
commitSupplier,
|
||||
handleRemoveYyzzImg,
|
||||
handleRemoveXkzImg,
|
||||
handleUploadError,
|
||||
handlePreview,
|
||||
handleYyzzSuccess,
|
||||
handleXkzSuccess,
|
||||
handleFileSuccess,
|
||||
handleFileRemove,
|
||||
previewFile,
|
||||
handleBeforeUpload,
|
||||
clearForm
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.searchBox{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
background-color: #fff;
|
||||
padding: 15px 0 0 0;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 15px;
|
||||
.row{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 20%;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 15px;
|
||||
&.row1{
|
||||
width: 25%;
|
||||
}
|
||||
.span{
|
||||
display: block;
|
||||
width: 100px;
|
||||
font-size: 14px;
|
||||
text-align: right;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.right{
|
||||
width: calc(100% - 120px);
|
||||
}
|
||||
.wid100{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.opaBox{
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.imgBox{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
.el-image{
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 4px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.skuBox{
|
||||
border: 1px solid #e5e5e5;
|
||||
border-radius: 5px;
|
||||
padding: 15px 0;
|
||||
margin-bottom: 15px;
|
||||
background-color: #f3f3f3;
|
||||
.tit{
|
||||
padding-left: 40px;
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
319
src/views/purchase/waitapproval.vue
Normal file
319
src/views/purchase/waitapproval.vue
Normal file
@ -0,0 +1,319 @@
|
||||
<template>
|
||||
<div class="pageBox">
|
||||
<div class="searchBox">
|
||||
<div class="row">
|
||||
<span class="span">ID:</span>
|
||||
<div class="right"><el-input v-model="filter.id" class="wid100" clearable></el-input></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="span">提交时间:</span>
|
||||
<div class="right">
|
||||
<el-date-picker
|
||||
v-model="submitTime"
|
||||
type="datetimerange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 100%;box-sizing: border-box;">
|
||||
</el-date-picker>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="span">审批类型:</span>
|
||||
<div class="right">
|
||||
<el-select v-model="filter.type" placeholder="请选择" clearable class="wid100">
|
||||
<el-option label="采购订单审批" :value="1" />
|
||||
<el-option label="预付款打款审批" :value="2" />
|
||||
<el-option label="尾款打款审批" :value="3" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row row1">
|
||||
<el-button type="primary" @click="handleSearch"><el-icon><Search /></el-icon> 筛选</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-card shadow="never">
|
||||
<div class="opaBox">
|
||||
<el-button type="primary" @click="showAdd = true"><el-icon><Plus /></el-icon> 新增</el-button>
|
||||
</div>
|
||||
<el-table :data="goodsList" style="width: 100%" border v-loading="loading">
|
||||
<el-table-column prop="id" label="ID" width="80" align="center" />
|
||||
<el-table-column prop="type" label="采购类型" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ approvalType[scope.row.order.approval_type] }}</span>
|
||||
|
||||
<div v-if="scope.row.order.approval_type == 1">{{ approvalStatus[scope.row.order.order_approval_status] }}</div>
|
||||
<div v-else-if="scope.row.order.approval_type == 2">{{ approvalStatus[scope.row.order.prepayment_approval_status] }}</div>
|
||||
<div v-else-if="scope.row.order.approval_type == 3">{{ approvalStatus[scope.row.order.final_payment_approval_status] }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="总预计订单金额/总预防款/总尾款" align="center">
|
||||
<template #default="scope">
|
||||
<div>{{ scope.row.order.total_amount }}</div>
|
||||
<div>{{ scope.row.order.prepayment_amount }}</div>
|
||||
<div>{{ scope.row.order.final_payment_amount }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="总实际订单金额/总实际已支付金额/总实际未支付金额" align="center">
|
||||
<template #default="scope">
|
||||
<div v-if="scope.row.order">
|
||||
<div>{{ scope.row.order.has_paid_amount }}</div>
|
||||
<div>{{ scope.row.order.has_paid_prepayment_amount }}</div>
|
||||
<div>{{ scope.row.order.has_paid_final_payment_amount }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="提交人/提交时间" align="center">
|
||||
<template #default="scope">
|
||||
<div>{{ scope.row.admin_user && scope.row.admin_user.username || '-' }}</div>
|
||||
<span>{{ scope.row.created_at }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="200">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" text @click="toApproval(scope.row.id)"><el-icon><Stamp /></el-icon>审批</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="page-pagination">
|
||||
<el-pagination
|
||||
:current-page="page"
|
||||
background
|
||||
layout="prev, pager, next, sizes, total"
|
||||
:total="total"
|
||||
:page-sizes="[10, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"></el-pagination>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="showDialog" width="500px" title="审批">
|
||||
<el-form label-position="right" label-width="100px">
|
||||
<el-form-item label="审批状态:">
|
||||
<el-radio-group v-model="spInfo.status">
|
||||
<el-radio :label="2">通过</el-radio>
|
||||
<el-radio :label="3">驳回</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注:">
|
||||
<el-input v-model="spInfo.comment" type="textarea" :rows="4"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="showDialog = false">取消</el-button>
|
||||
<el-button type="primary" @click="commitApproval()">确定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<order-approval :show="showOrderApproval" :id="curId" @refresh="handleSearch" @close="showOrderApproval = false"></order-approval>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { onMounted, reactive, toRefs, ref, nextTick } from "vue"
|
||||
import { get, post } from "@/api/request"
|
||||
import { Search, Plus, Edit, ZoomIn, Delete, Stamp } from '@element-plus/icons'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import orderApproval from '@/components/approval/order.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Search, Plus, Edit, ZoomIn, Delete, orderApproval, Stamp
|
||||
},
|
||||
setup() {
|
||||
const data = reactive({
|
||||
add_type: 1,
|
||||
showDialog: false,
|
||||
showOrderApproval: false,
|
||||
filter: {},
|
||||
submitTime: [],
|
||||
goodsList: [],
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
loading: false,
|
||||
picVisible: false,
|
||||
dialogImageUrl: '',
|
||||
approvalType: {
|
||||
'1': '采购订单审批',
|
||||
'2': '预付款打款审批',
|
||||
'3': '尾款打款审批',
|
||||
'4': '已结束'
|
||||
},
|
||||
approvalStatus: {
|
||||
'0': '草稿',
|
||||
'1': '进行中',
|
||||
'2': '已完成',
|
||||
'3': '已取消'
|
||||
},
|
||||
warehouseList: [],
|
||||
suppliersList: [],
|
||||
allGoodsList: [],
|
||||
curId: 0,
|
||||
spInfo: {}
|
||||
})
|
||||
|
||||
function handleSearch() {
|
||||
data.page = 1
|
||||
fetchData()
|
||||
}
|
||||
|
||||
const fetchData = () => {
|
||||
data.loading = true
|
||||
let params = {
|
||||
page: data.page,
|
||||
pageSize: data.pageSize,
|
||||
...data.filter,
|
||||
wait_type: 1,
|
||||
start_time: data.submitTime ? data.submitTime[0] : '',
|
||||
end_time: data.submitTime ? data.submitTime[1] : ''
|
||||
}
|
||||
get(`/api/purchaseOrder/instanceList`, params).then((res) => {
|
||||
data.goodsList = res.data
|
||||
data.total = res.meta.total
|
||||
data.loading = false
|
||||
}).catch(() => {
|
||||
data.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
function handleCurrentChange(e) {
|
||||
data.page = e
|
||||
fetchData()
|
||||
}
|
||||
|
||||
function handleSizeChange(e) {
|
||||
data.page = 1
|
||||
data.pageSize = e
|
||||
fetchData()
|
||||
}
|
||||
|
||||
function getWarehouseList() {
|
||||
get(`/api/all/warehouses`).then((res) => {
|
||||
data.warehouseList = res.data
|
||||
})
|
||||
}
|
||||
|
||||
function getSuppliersList() {
|
||||
get(`/api/suppliers`, {pageSize: 1000}).then((res) => {
|
||||
data.suppliersList = res.data
|
||||
})
|
||||
}
|
||||
|
||||
function getAllGoodsList() {
|
||||
get(`/api/all/goods`).then((res) => {
|
||||
data.allGoodsList = res.data
|
||||
})
|
||||
}
|
||||
|
||||
function toApproval(id) {
|
||||
data.curId = id
|
||||
data.spInfo = {
|
||||
status: 2,
|
||||
comment: ''
|
||||
}
|
||||
data.showDialog = true
|
||||
}
|
||||
|
||||
function commitApproval() {
|
||||
let params = {
|
||||
instance_id: data.curId,
|
||||
status: data.spInfo.status,
|
||||
comment: data.spInfo.comment
|
||||
}
|
||||
post(`/api/purchaseOrder/processApproval`, params).then((res) => {
|
||||
ElMessage.success('审批成功')
|
||||
data.showDialog = false
|
||||
fetchData()
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchData()
|
||||
getWarehouseList()
|
||||
getSuppliersList()
|
||||
getAllGoodsList()
|
||||
})
|
||||
|
||||
return {
|
||||
...toRefs(data),
|
||||
handleSearch,
|
||||
handleCurrentChange,
|
||||
handleSizeChange,
|
||||
fetchData,
|
||||
getWarehouseList,
|
||||
getSuppliersList,
|
||||
getAllGoodsList,
|
||||
toApproval,
|
||||
commitApproval
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.searchBox{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
background-color: #fff;
|
||||
padding: 15px 15px 0 0;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 15px;
|
||||
.row{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 20%;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 15px;
|
||||
.span{
|
||||
display: block;
|
||||
width: 100px;
|
||||
font-size: 14px;
|
||||
text-align: right;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.right{
|
||||
width: calc(100% - 100px);
|
||||
}
|
||||
.wid100{
|
||||
width: 100%;
|
||||
}
|
||||
&.row1{
|
||||
margin-left: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.opaBox{
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.imgBox{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
.el-image{
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 4px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.skuBox{
|
||||
border: 1px solid #e5e5e5;
|
||||
border-radius: 5px;
|
||||
padding: 15px 0;
|
||||
margin-bottom: 15px;
|
||||
background-color: #f3f3f3;
|
||||
.tit{
|
||||
padding-left: 40px;
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -48,6 +48,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<el-card shadow="never">
|
||||
<div class="opaBox">
|
||||
<el-button type="warning" @click="handleExport" :loading="exportLoading"><span class="iconfont icon-daochu"></span> 导出</el-button>
|
||||
</div>
|
||||
<el-table :data="statisticsList" style="width: 100%" border v-loading="loading" @sort-change="sortChange"
|
||||
:default-sort="{
|
||||
prop: 'number,order_num,seven_day_avg_number,stock_wait,three_day_avg_number,three_day_stock_wait,thirty_day_number,actual_inventory,total_profit',
|
||||
@ -86,6 +89,8 @@
|
||||
<div v-if="scope.row.goods_sku">{{ scope.row.goods_sku.actual_inventory }}({{ scope.row.goods_sku.lock_in_stock }})</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="goods_cost" label="商品成本" align="center" />
|
||||
<el-table-column prop="freight_cost" label="运费成本" align="center" />
|
||||
<el-table-column prop="refund_amount" label="退款金额" align="center" />
|
||||
<el-table-column prop="red_refund_amount" label="红包退款有责金额" align="center" />
|
||||
<el-table-column prop="total_profit" label="总利润" align="center" />
|
||||
@ -241,6 +246,7 @@ import { onMounted, reactive, toRefs } from "vue"
|
||||
import { get } from "@/api/request"
|
||||
import { Search, Shop, TrendCharts, QuestionFilled, List } from '@element-plus/icons'
|
||||
import * as echarts from 'echarts'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
export default {
|
||||
@ -283,7 +289,8 @@ export default {
|
||||
from_shop_ids: [],
|
||||
shopsList: [],
|
||||
grain_size: 60,
|
||||
dataLineY2: []
|
||||
dataLineY2: [],
|
||||
exportLoading: false
|
||||
})
|
||||
|
||||
function handleSearch() {
|
||||
@ -559,6 +566,48 @@ export default {
|
||||
})
|
||||
}
|
||||
|
||||
const handleExport = () => {
|
||||
data.exportLoading = true
|
||||
let params = {
|
||||
...data.filter,
|
||||
page: data.page,
|
||||
pageSize: data.pageSize,
|
||||
start_date: data.rangeTime ? data.rangeTime[0] : '',
|
||||
end_date: data.rangeTime ? data.rangeTime[1] : '',
|
||||
direction: data.ascOrDesc,
|
||||
order_by_column: data.sort,
|
||||
export: 1
|
||||
}
|
||||
params.brand_id = data.filter.brand_id || 0
|
||||
get(`/api/orderItemDailyReport`, params, 'blob').then((res) => {
|
||||
downLoadXls(res)
|
||||
ElMessage({ type: "success", message: "导出成功!" })
|
||||
data.exportLoading = false
|
||||
}).catch(() => {
|
||||
data.exportLoading = false
|
||||
})
|
||||
}
|
||||
|
||||
function downLoadXls(response) {
|
||||
const content = response
|
||||
const blob = new Blob([content])
|
||||
const fileName = `数据统计.xlsx`
|
||||
if ('download' in document.createElement('a')) {
|
||||
// 非IE下载
|
||||
const elink = document.createElement('a')
|
||||
elink.download = fileName
|
||||
elink.style.display = 'none'
|
||||
elink.href = URL.createObjectURL(blob)
|
||||
document.body.appendChild(elink)
|
||||
elink.click()
|
||||
URL.revokeObjectURL(elink.href) // 释放URL 对象
|
||||
document.body.removeChild(elink)
|
||||
} else {
|
||||
// IE10+下载
|
||||
navigator.msSaveBlob(blob, fileName)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchData()
|
||||
getBrandList()
|
||||
@ -582,7 +631,8 @@ export default {
|
||||
orderCharts,
|
||||
getOrderCharts,
|
||||
changeOrderTime,
|
||||
getShopsList
|
||||
getShopsList,
|
||||
handleExport
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -618,6 +668,9 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
.opaBox{
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.imgBox{
|
||||
.el-image{
|
||||
width: 60px;
|
||||
|
||||
@ -21,8 +21,9 @@ module.exports = {
|
||||
// target: "http://192.168.0.52:86", // 本地
|
||||
// target: "http://192.168.99.5:8093", // 本地
|
||||
// target: "http://43.138.23.240:82", // 本地//
|
||||
// target: "http://192.168.99.72:81", // 本地//
|
||||
// target: "http://192.168.202.67:86", // 本地//
|
||||
target: 'http://warehouse.chutang66.com/',
|
||||
// target: 'http://world.dev.chutang66.com/',
|
||||
changeOrigin: true, //开启代理
|
||||
pathRewrite: { // 重命名
|
||||
"^/api": "api"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user