<template>
|
<div class="page-view">
|
<el-form ref="form" :model="tableList" :show-message="false" label-position="right">
|
{{ tableList.tableData }}
|
<el-table
|
ref="fromTable"
|
:data="tableList.tableData"
|
:show-summary="showSummary.show"
|
:summary-method="getSummaries"
|
:span-method="arraySpanMethod"
|
style="width: 100%"
|
@selection-change="handleSelectionChange"
|
:row-key="(row) => row.productId"
|
>
|
<el-table-column v-if="selectBox" type="selection" :reserve-selection="true" width="40" align="center">
|
</el-table-column>
|
<el-table-column v-if="tableList.isReturn" type="index" label="#" width="50" align="center"></el-table-column>
|
<el-table-column
|
v-for="(item, i) in tableList.tableColumn"
|
:key="i"
|
:prop="item.prop"
|
:label="item.label"
|
:width="item.width"
|
:min-width="item.min"
|
align="center"
|
>
|
<!-- 表头样式 -->
|
<template slot="header">
|
<span v-if="item.isRequird" style="color: #f56c6c">*</span>
|
<span>{{ item.label }}</span>
|
</template>
|
<!-- column样式 -->
|
<template slot-scope="scope">
|
<template v-if="!detailEnter">
|
<el-form-item
|
v-if="item.input"
|
label=" "
|
:prop="'tableData.' + scope.$index + '.' + item.prop"
|
:rules="[{ required: item.isRequird ? true : false, message: '输入不能为空' }]"
|
>
|
<el-input
|
v-model.trim="scope.row[item.prop]"
|
maxlength="50"
|
size="mini"
|
:disabled="!isOperate"
|
@change="
|
(val) => {
|
commonInputChange(val, item.prop, scope.row,scope)
|
}
|
"
|
></el-input>
|
</el-form-item>
|
<el-form-item
|
v-else-if="item.productName"
|
label=" "
|
:prop="'tableData.' + scope.$index + '.' + item.prop"
|
>
|
<div class="custom-name">
|
<el-autocomplete
|
v-model="scope.row[item.prop]"
|
:fetch-suggestions="querySearchAsync"
|
value-key="name"
|
:disabled="!isOperate"
|
size="mini"
|
@select="
|
(val) => {
|
handleSelectClient(val, item.prop, scope.row)
|
}
|
"
|
></el-autocomplete>
|
<div class="common-select-btn" v-if="isOperate" @click="selClientClick(scope.row, item.prop)">
|
<i class="el-icon-circle-plus-outline" title="选择"></i>
|
</div>
|
<div
|
v-if="scope.row[item.prop] && scope.row[item.prop].length > 0&&isOperate"
|
class="common-select-btn"
|
@click="clearupClient(scope.row)"
|
>
|
<i class="el-icon-remove-outline" title="清除"></i>
|
</div>
|
</div>
|
</el-form-item>
|
<el-form-item
|
v-else-if="item.date"
|
label=" "
|
:prop="'tableData.' + scope.$index + '.' + item.prop"
|
:rules="[{ required: item.isRequird ? true : false, message: '输入不能为空' }]"
|
>
|
<!-- <el-input v-model.trim="scope.row[item.prop]" maxlength="50" size="mini"></el-input> -->
|
<el-date-picker :disabled="!isOperate" v-model="scope.row[item.prop]" type="date" size="mini" style="width: 110px">
|
</el-date-picker>
|
</el-form-item>
|
<el-form-item
|
v-else-if="item.inputNumber"
|
label=" "
|
:prop="'tableData.' + scope.$index + '.' + item.prop"
|
:rules="[{ required: item.isRequird ? true : false, message: '输入不能为空' }]"
|
>
|
<el-input-number
|
v-model="scope.row[item.prop]"
|
placeholder=""
|
:min="0"
|
:controls="false"
|
:disabled="!isOperate"
|
size="mini"
|
style="width: 100%; margin-right: 5px"
|
@change="
|
(val) => {
|
commonInputChange(val, item.prop, scope.row,scope)
|
}
|
"
|
></el-input-number>
|
</el-form-item>
|
<el-form-item
|
v-else-if="item.inputFloat"
|
label=" "
|
:prop="'tableData.' + scope.$index + '.' + item.prop"
|
:rules="[{ required: item.isRequird ? true : false, message: '输入不能为空' }]"
|
>
|
<el-input-number
|
v-model="scope.row[item.prop]"
|
placeholder=""
|
:min="0"
|
:precision="2"
|
:disabled="!isOperate"
|
:controls="false"
|
size="mini"
|
style="width: 100%; margin-right: 5px"
|
@change="
|
(val) => {
|
commonInputChange(val, item.prop, scope.row,scope)
|
}
|
"
|
></el-input-number>
|
</el-form-item>
|
<span v-else>
|
<template v-if="pageName=='quotation'&&item.prop=='profit'">
|
{{ (scope.row.price&&scope.row.cost)?Number(scope.row.price)-Number(scope.row.cost):'' }}
|
</template>
|
<template v-if="pageName=='quotation'&&item.prop=='margin'">
|
{{ (scope.row.price&&scope.row.cost)?((Number(scope.row.price)-Number(scope.row.cost))*100/Number(scope.row.cost)).toFixed(2):'' }}
|
</template>
|
<template v-else>
|
{{ scope.row[item.prop] }}
|
</template>
|
</span>
|
</template>
|
<el-form-item
|
v-else-if="item.inputNumber && selectBox"
|
label=" "
|
:prop="'tableData.' + scope.$index + '.' + item.prop"
|
:rules="[{ required: item.isRequird ? true : false, message: '输入不能为空' }]"
|
>
|
<el-input-number
|
v-model="scope.row[item.prop]"
|
placeholder=""
|
:min="0"
|
:controls="false"
|
:disabled="!isOperate"
|
size="mini"
|
style="width: 100%; margin-right: 5px"
|
@change="
|
(val) => {
|
commonInputChange(val, item.prop, scope.row,scope)
|
}
|
"
|
></el-input-number>
|
</el-form-item>
|
<span v-else style="text-align: right">{{ scope.row[item.prop] }}</span>
|
</template>
|
</el-table-column>
|
<el-table-column label="操作" width="40" align="center">
|
<template slot-scope="scope">
|
<el-button
|
type="text"
|
size="small"
|
:disabled="!isOperate"
|
@click="deleteClick(scope)"
|
>删除</el-button>
|
</template>
|
</el-table-column>
|
<slot name="tableButton" />
|
</el-table>
|
</el-form>
|
<div v-if="!detailEnter" style="margin: 10px">
|
<el-button size="small" type="primary" :disabled="!isOperate" @click="add">新增</el-button>
|
<!-- <el-button size="small" type="primary" disabled>导入明细</el-button> -->
|
<el-button size="small" type="primary" :disabled="!isOperate" @click="empty">清空</el-button>
|
<el-button size="small" type="primary" @click="recalculate" :disabled="(isRecalculate&&!isOperate) ? false : true"
|
>重算</el-button
|
>
|
</div>
|
<div v-if="false && (showSummary.total || showSummary.refundable)" style="height: 42px; line-height: 42px">
|
<el-row :gutter="10">
|
<el-col v-if="showSummary.total" :span="3" :offset="21">
|
<span style="font-weight: bold">合计</span>
|
<span style="margin-left: 10px">{{ total }}</span>
|
</el-col>
|
<el-col v-if="showSummary.refundable" :span="3" :offset="21">
|
<span style="font-weight: bold">应退款</span>
|
<span style="margin-left: 10px">0.00</span>
|
</el-col>
|
</el-row>
|
</div>
|
<!-- 合同订单 -->
|
<SelectCommonDialog
|
v-if="editSelCommonConfig.editVisible"
|
:edit-common-config="editSelCommonConfig"
|
:quotationNumber="quotationNumber"
|
@selClient="selClient"
|
/>
|
</div>
|
</template>
|
|
<script>
|
import { getProductList } from "@/api/common/other"
|
import SelectCommonDialog from "@/views/other/commonDialog/SelectCommonDialog"
|
export default {
|
name: "CommmonFormTableView",
|
components: { SelectCommonDialog },
|
props: {
|
detailEnter: {
|
type: Boolean,
|
default: false
|
},
|
selectBox: {
|
type: Boolean,
|
default: false
|
},
|
// 那个页面 用来判断计算方式
|
pageName:{
|
type:String,
|
default:''
|
},
|
// 根据报价单查询产品
|
quotationNumber:{
|
type:[String,Number],
|
default:''
|
},
|
// 是否可以操作 添加等
|
isOperate:{
|
type:Boolean,
|
default:true,
|
},
|
productTableList: {
|
type: Object,
|
default: () => {
|
return {
|
tableData: [], // 接口返回数据
|
isReturn: false,
|
tableColumn: [
|
// table表单
|
{ label: "", prop: "", min: 200, tooltip: true }
|
]
|
}
|
}
|
},
|
showSummary: {
|
type: Object,
|
default: () => {
|
return {
|
show: false,
|
total: false,
|
refundable: false,
|
sumProp: [],
|
mergeNumber: 1
|
}
|
}
|
}
|
},
|
data() {
|
return {
|
total: 0,
|
productList: [],
|
tableList: [],
|
editSelCommonConfig: {
|
editVisible: false,
|
title: "",
|
infomation: {}
|
},
|
productIndex: 0,
|
isRecalculate: true
|
}
|
},
|
created() {
|
if (!this.selectBox) {
|
this.getProductList()
|
}
|
this.tableList = this.productTableList
|
if (this.tableList.tableData.length === 1 && this.tableList.tableData[0].name === "") {
|
this.isRecalculate = false
|
} else {
|
this.isRecalculate = true
|
}
|
},
|
computed: {},
|
methods: {
|
// 产品名称
|
async getProductList() {
|
await getProductList({
|
productName: "",
|
productNumber: "",
|
page: 1,
|
pageSize: 100
|
}).then((res) => {
|
console.log(res, "产品名称")
|
if (res.code === 200) {
|
if (res.data.data && res.data.data.length > 0) {
|
this.productList = res.data.data
|
}
|
}
|
})
|
},
|
handleReserve(row) {
|
return row._id ? row._id : row.id
|
},
|
// 多选
|
handleSelectionChange(val) {
|
this.$emit("getSelectArray", val)
|
},
|
// 行合并
|
arraySpanMethod() {
|
if (this.showSummary.show) {
|
this.$nextTick(() => {
|
if (this.$refs.table) {
|
var current = this.$refs.table.querySelector(".el-table__footer-wrapper").querySelector(".el-table__footer")
|
var cell = current.rows[0].cells
|
for (let i = 0; i < this.showSummary.mergeNumber; i++) {
|
cell[i].style.display = "none"
|
}
|
cell[this.showSummary.mergeNumber].classList.remove("is-left")
|
cell[this.showSummary.mergeNumber].colSpan = this.showSummary.mergeNumber.toString()
|
}
|
})
|
}
|
},
|
// 合计
|
getSummaries(param) {
|
const { columns, data } = param
|
const sums = []
|
columns.forEach((column, index) => {
|
// // 更改行名称
|
if (index === this.showSummary.mergeNumber) {
|
sums[index] = "小计:"
|
return
|
}
|
const title = ["#", "产品名称",'产品编号','单位','销售单价','成本单价']
|
// 去除某些不需要计算的数据
|
if (title.includes(column.label)) {
|
sums[index] = ""
|
return
|
}
|
if(this.pageName=='quotation'&&column.label=='毛利'){
|
sums[index] = ""
|
return
|
}
|
// 把当前表格数据中同个分类的数据收集起来
|
const values = data.map((item) => Number(item[column.property]))
|
// 过滤掉
|
if (!values.every((value) => Number.isNaN(value))) {
|
sums[index] = ` ${values.reduce((prev, curr) => {
|
const value = Number(curr)
|
if (!Number.isNaN(value)) {
|
const num = prev + curr
|
return Number(num.toFixed(2))
|
} else {
|
return Number(prev.toFixed(2))
|
}
|
}, 0)}`
|
} else {
|
sums[index] = ""
|
}
|
if (column.property === "total") {
|
this.total = sums[index]
|
}
|
})
|
return sums
|
},
|
// 数字换行为金额显示格式
|
number_format(number, decimals, dec_point, thousands_sep) {
|
decimals = 2 //这里默认设置保留两位小数,也可以注释这句采用传入的参数
|
/*
|
* 参数说明:
|
* number:要格式化的数字
|
* decimals:保留几位小数
|
* dec_point:小数点符号
|
* thousands_sep:千分位符号
|
* */
|
number = (number + "").replace(/[^0-9+-Ee.]/g, "")
|
var n = !isFinite(+number) ? 0 : +number,
|
prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
|
sep = typeof thousands_sep === "undefined" ? "," : thousands_sep,
|
dec = typeof dec_point === "undefined" ? "." : dec_point
|
var s = n.toString().split(".")
|
var re = /(-?\d+)(\d{3})/
|
while (re.test(s[0])) {
|
s[0] = s[0].replace(re, "$1" + sep + "$2")
|
}
|
if ((s[1] || "").length < prec) {
|
s[1] = s[1] || ""
|
s[1] += new Array(prec - s[1].length + 1).join("0")
|
} else {
|
s[1] = s[1].substring(0, prec) //小数点位数超出长度时截取前面的位数
|
}
|
return s.join(dec)
|
},
|
// 新增
|
add() {
|
this.$emit("addProductClick")
|
},
|
commonInputChange(val, prop, row,scope) {
|
if (prop === "amount") {
|
this.tableList.tableData.map((ite) => {
|
if (ite.name === row.name) {
|
ite.total = row.amount * row.price
|
}
|
})
|
}
|
if(this.pageName=='quotation'&&prop=='cost'&&scope.row.cost){
|
let value=scope.row.cost
|
let reg2 =
|
/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/;
|
if (!reg2.test(value)||value==0) {
|
this.$message.error("成本单价需要填写大于0的2位小数!")
|
}
|
this.$forceUpdate()
|
}
|
this.$emit("inputContent", val, prop, row)
|
},
|
// 清空
|
empty() {
|
this.isRecalculate = false
|
this.$emit("emptyProductClick")
|
},
|
// 删除
|
deleteClick(scope){
|
this.tableList.tableData.splice(scope.$index,1)
|
this.$forceUpdate();
|
this.$message.success('删除除成功!')
|
this.$emit("deleteClick",scope)
|
},
|
// 重算
|
recalculate() {
|
this.$confirm("确定要重算明细所有行?", "提示", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning"
|
})
|
.then(() => {
|
this.$emit("recalculateProductClick")
|
this.tableList.tableData.map((ite) => {
|
ite.total = ite.amount ? ite.amount * ite.price : 1 * ite.price
|
})
|
})
|
.catch(() => {})
|
},
|
// 选择产品名称相关方法
|
querySearchAsync(queryString, cb) {
|
var restaurants = this.productList
|
var results = queryString ? restaurants.filter(this.createStateFilter(queryString)) : restaurants
|
cb(results)
|
},
|
createStateFilter(queryString) {
|
return (state) => {
|
return state.name.toLowerCase().indexOf(queryString.toLowerCase()) === 0
|
}
|
},
|
handleSelectClient(item, prop, row) {
|
// this.clientId = item.id
|
this.isRecalculate = true
|
console.log(item, prop, row)
|
this.tableList.tableData.map((ite) => {
|
if (ite.name === item.name) {
|
ite.amount = item.amount || 1
|
ite.number = item.number
|
ite.price = item.price
|
ite.total = item.amount ? item.amount * item.price : 1 * item.price
|
ite.unit = item.unit
|
}
|
})
|
},
|
selClientClick(row, prop) {
|
console.log(row, prop)
|
this.productIndex = row.productId - 1
|
this.editSelCommonConfig.title = "产品名称"
|
this.editSelCommonConfig.editVisible = true
|
},
|
selClient(item) {
|
console.log(item)
|
console.log(this.tableList.tableData)
|
this.isRecalculate = true
|
// this.editConfig.infomation.client_name = row.name
|
this.tableList.tableData.map((ite, index) => {
|
if (index === this.productIndex) {
|
ite.name = item.name
|
ite.amount = item.amount || 1
|
ite.number = item.number
|
ite.price = item.price
|
ite.total = item.amount ? item.amount * item.price : 1 * item.price
|
ite.unit = item.unit
|
}
|
})
|
},
|
// 清除已选择用户
|
clearupClient(row) {
|
this.productIndex = row.productId - 1
|
this.tableList.tableData.map((ite, index) => {
|
if (index === this.productIndex) {
|
ite.name = ""
|
ite.amount = 1
|
ite.number = ""
|
ite.price = 0
|
ite.total = 0
|
ite.unit = ""
|
}
|
})
|
this.$emit("clearupProduct", this.tableList.tableData)
|
}
|
// 多选设置已选中
|
// toggleSelection(rows) {
|
// console.log("88888888888888888888888888888888888888888")
|
// console.log(rows)
|
// if (rows) {
|
// rows.forEach((row) => {
|
// this.$refs.fromTable.toggleRowSelection(row, true)
|
// console.log(row)
|
// })
|
// }
|
// }
|
}
|
}
|
</script>
|
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
<style lang="scss" scoped>
|
.page-view {
|
|
.el-form-item {
|
margin-bottom: 0;
|
.custom-name {
|
display: flex;
|
.common-select-btn {
|
margin-left: 5px;
|
font-size: 18px;
|
cursor: pointer;
|
}
|
}
|
}
|
}
|
::v-deep {
|
.el-form-item__label {
|
display: none;
|
}
|
.el-table__footer-wrapper tbody td.el-table__cell {
|
background-color: #fff;
|
// text-align: right;
|
font-weight: bold;
|
}
|
.el-input--suffix .el-input__inner {
|
padding-right: 0px;
|
}
|
.el-table .cell,
|
.el-table th.el-table__cell > .cell {
|
padding: 0 5px;
|
}
|
.el-input__inner {
|
// text-align: left;
|
text-align: center !important;
|
}
|
}
|
</style>
|