feat: 多个模块新增功能与优化交互
1. DictSelect组件新增单选按钮组渲染模式 2. 公告管理页面新增查看公告功能 3. 合同产品内容组件优化产品选择器与表格布局
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import request from '@/utils/request'
|
||||
import veilReq from '@/utils/veilReq'
|
||||
import { tansParams } from "@/utils/klp";
|
||||
|
||||
// 查询钢卷物料表列表
|
||||
@@ -436,3 +437,17 @@ export function listWithAdjustRecordCoil(params) {
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据入场钢卷号查询最早的热轧卷板材质
|
||||
*/
|
||||
export function getFirstHeatCoilMaterial(enterCoilNo) {
|
||||
return veilReq({
|
||||
url: '/wms/materialCoil/material/queryEarliestHotRolledMaterial',
|
||||
method: 'get',
|
||||
timeout: 600000,
|
||||
params: {
|
||||
enterCoilNo
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div style="display: flex; align-items: center;" v-loading="loading">
|
||||
<!-- 下拉选择器:绑定计算属性做双向绑定,保留原有样式+清空功能 -->
|
||||
<!-- 下拉选择器 -->
|
||||
<el-select
|
||||
v-if="!toolbarOnly"
|
||||
v-if="!toolbarOnly && renderType === 'select'"
|
||||
v-model="innerValue"
|
||||
:placeholder="placeholder"
|
||||
clearable filterable
|
||||
@@ -17,6 +17,22 @@
|
||||
/>
|
||||
</el-select>
|
||||
|
||||
<!-- 单选按钮组 -->
|
||||
<el-radio-group
|
||||
v-if="!toolbarOnly && renderType === 'radio'"
|
||||
v-model="innerValue"
|
||||
:style="radioStyle"
|
||||
>
|
||||
<el-radio-button
|
||||
v-for="item in radioOptions"
|
||||
:key="item.dictValue"
|
||||
:label="item.dictValue"
|
||||
:disabled="item.disabled"
|
||||
>
|
||||
{{ item.dictLabel }}
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
|
||||
<!-- 编辑按钮:点击打开弹窗 -->
|
||||
<div
|
||||
v-if="editable"
|
||||
@@ -163,6 +179,7 @@ export default {
|
||||
refresh: { type: Boolean, default: true },
|
||||
multiple: { type: Boolean, default: false },
|
||||
disables: { type: String, default: '' },
|
||||
renderType: { type: String, default: 'select' },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -213,6 +230,16 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
radioOptions() {
|
||||
const options = [{ dictLabel: '全部', dictValue: '', disabled: false }, ...this.dictOptions]
|
||||
return options.map(item => ({
|
||||
...item,
|
||||
disabled: this.disabledFormat(item.dictValue)
|
||||
}))
|
||||
},
|
||||
radioStyle() {
|
||||
return 'display: flex; align-items: center; flex-wrap: wrap; gap: 8px;'
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
dictType: {
|
||||
|
||||
@@ -5,132 +5,76 @@
|
||||
<!-- 第一行合并所有八个单元格,内容为:嘉祥科伦普重工有限公司 -->
|
||||
<div class="table-row table-header">
|
||||
<div class="table-cell" colspan="3">
|
||||
<div class="company-name">产品名称:<el-input style="width: 50%" v-model="productName" placeholder="请输入产品名称" size="small" :readonly="readonly"/></div>
|
||||
<div class="company-name">产品名称:
|
||||
<el-select v-model="productName" placeholder="请选择产品名称" size="small" :readonly="readonly" filterable allow-create clearable>
|
||||
<el-option v-for="item in productOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-cell" colspan="5">
|
||||
<div class="company-name">生产厂家:嘉祥科伦普重工有限公司</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 第二行为表头 -->
|
||||
<div class="table-row">
|
||||
<div class="table-cell">序号</div>
|
||||
<div class="table-cell">规格(mm)</div>
|
||||
<div class="table-cell">材质</div>
|
||||
<div class="table-cell">数量(吨)</div>
|
||||
<div class="table-cell" v-if="false">含税单价(元/吨)</div>
|
||||
<div class="table-cell">不含税单价(元/吨)</div>
|
||||
<div class="table-cell">含税单价(元/吨)</div>
|
||||
<div class="table-cell" v-if="false">不含税单价(元/吨)</div>
|
||||
<div class="table-cell">含税总额(元)</div>
|
||||
<div class="table-cell">不含税总额(元)</div>
|
||||
<div class="table-cell">
|
||||
备注
|
||||
<el-button
|
||||
v-if="!readonly"
|
||||
type="primary"
|
||||
size="mini"
|
||||
icon="el-icon-plus"
|
||||
@click="addProduct"
|
||||
style="margin-left: 10px;"
|
||||
>
|
||||
<el-button v-if="!readonly" type="primary" size="mini" icon="el-icon-plus" @click="addProduct"
|
||||
style="margin-left: 10px;">
|
||||
添加行
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 产品行 -->
|
||||
<div
|
||||
v-for="(item, index) in products"
|
||||
:key="index"
|
||||
class="table-row"
|
||||
:class="{ 'table-row-hover': !readonly }"
|
||||
>
|
||||
<div v-for="(item, index) in products" :key="index" class="table-row" :class="{ 'table-row-hover': !readonly }">
|
||||
<div class="table-cell">
|
||||
<div class="serial-number">
|
||||
<span>{{ index + 1 }}</span>
|
||||
<el-button
|
||||
v-if="!readonly && products.length > 1"
|
||||
type="text"
|
||||
size="mini"
|
||||
icon="el-icon-delete"
|
||||
class="delete-btn"
|
||||
@click="removeProduct(index)"
|
||||
/>
|
||||
<el-button v-if="!readonly && products.length > 1" type="text" size="mini" icon="el-icon-delete"
|
||||
class="delete-btn" @click="removeProduct(index)" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-cell">
|
||||
<el-input
|
||||
v-model="item.spec"
|
||||
placeholder="请输入规格"
|
||||
:readonly="readonly"
|
||||
size="small"
|
||||
/>
|
||||
<el-input v-model="item.spec" placeholder="请输入规格" :readonly="readonly" size="small" />
|
||||
</div>
|
||||
<div class="table-cell">
|
||||
<el-input
|
||||
v-model="item.material"
|
||||
placeholder="请输入材质"
|
||||
:readonly="readonly"
|
||||
size="small"
|
||||
/>
|
||||
<el-input v-model="item.material" placeholder="请输入材质" :readonly="readonly" size="small" />
|
||||
</div>
|
||||
<div class="table-cell">
|
||||
<el-input
|
||||
v-model.number="item.quantity"
|
||||
placeholder="请输入数量"
|
||||
type="number"
|
||||
:readonly="readonly"
|
||||
size="small"
|
||||
@change="calculateTotals"
|
||||
/>
|
||||
<el-input v-model.number="item.quantity" placeholder="请输入数量" type="number" :readonly="readonly" size="small"
|
||||
@change="calculateTotals" />
|
||||
</div>
|
||||
|
||||
<div class="table-cell">
|
||||
<el-input v-model.number="item.taxPrice" placeholder="请输入含税单价" type="number" :readonly="readonly" size="small"
|
||||
@change="calculateTotals" />
|
||||
</div>
|
||||
<div class="table-cell" v-if="false">
|
||||
<el-input
|
||||
v-model.number="item.taxPrice"
|
||||
placeholder="请输入含税单价"
|
||||
type="number"
|
||||
:readonly="readonly"
|
||||
size="small"
|
||||
@change="calculateTotals"
|
||||
/>
|
||||
<el-input v-model.number="item.noTaxPrice" placeholder="请输入不含税单价" type="number" :readonly="readonly"
|
||||
size="small" @change="calculateTotals" />
|
||||
</div>
|
||||
<div class="table-cell">
|
||||
<el-input
|
||||
v-model.number="item.noTaxPrice"
|
||||
placeholder="请输入不含税单价"
|
||||
type="number"
|
||||
:readonly="readonly"
|
||||
size="small"
|
||||
@change="calculateTotals"
|
||||
/>
|
||||
<el-input v-model.number="item.taxTotal" placeholder="含税总额" type="number" :readonly="true" size="small" />
|
||||
</div>
|
||||
<div class="table-cell">
|
||||
<el-input
|
||||
v-model.number="item.taxTotal"
|
||||
placeholder="含税总额"
|
||||
type="number"
|
||||
:readonly="true"
|
||||
size="small"
|
||||
/>
|
||||
<el-input :value="((item.taxTotal || 0) / 1.13).toFixed(2)" placeholder="不含税总额" type="number" :readonly="true"
|
||||
size="small" />
|
||||
</div>
|
||||
<div class="table-cell">
|
||||
<el-input
|
||||
:value="((item.taxTotal || 0) / 1.13).toFixed(2)"
|
||||
placeholder="不含税总额"
|
||||
type="number"
|
||||
:readonly="true"
|
||||
size="small"
|
||||
/>
|
||||
</div>
|
||||
<div class="table-cell">
|
||||
<el-input
|
||||
v-model="item.remark"
|
||||
placeholder="请输入备注"
|
||||
:readonly="readonly"
|
||||
size="small"
|
||||
/>
|
||||
<el-input v-model="item.remark" placeholder="请输入备注" :readonly="readonly" size="small" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 合计行 -->
|
||||
<div class="table-row table-total-row">
|
||||
<div class="table-cell" colspan="3">合计</div>
|
||||
@@ -141,7 +85,7 @@
|
||||
<div class="table-cell">{{ ((totalTaxTotal || 0) / 1.13).toFixed(2) }}</div>
|
||||
<div class="table-cell"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 合计人民币(大写) -->
|
||||
<div class="table-row">
|
||||
<div class="table-cell" colspan="8">
|
||||
@@ -149,18 +93,13 @@
|
||||
<span>{{ totalAmountInWords }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 备注 -->
|
||||
<div class="table-row">
|
||||
<div class="table-cell" colspan="8">
|
||||
<span>备注:</span>
|
||||
<el-input
|
||||
v-model="remark"
|
||||
type="textarea"
|
||||
placeholder="请输入备注"
|
||||
:readonly="readonly"
|
||||
:autosize="{ minRows: 2 }"
|
||||
/>
|
||||
<el-input v-model="remark" type="textarea" placeholder="请输入备注" :readonly="readonly"
|
||||
:autosize="{ minRows: 2 }" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -195,21 +134,27 @@ export default {
|
||||
products: [],
|
||||
remark: '',
|
||||
productName: '',
|
||||
productOptions: [
|
||||
{ label: '冷硬钢卷', value: '冷硬钢卷' },
|
||||
{ label: '镀锌钢卷', value: '镀锌钢卷' },
|
||||
{ label: '冷轧钢卷', value: '冷轧钢卷' },
|
||||
{ label: '镀铬钢卷', value: '镀铬钢卷' },
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 计算总数量
|
||||
totalQuantity() {
|
||||
return calculateTotalQuantity(this.products);
|
||||
},
|
||||
// 计算总含税总额
|
||||
totalTaxTotal() {
|
||||
return calculateTotalTaxTotal(this.products);
|
||||
},
|
||||
// 计算大写金额
|
||||
totalAmountInWords() {
|
||||
return convertToChinese(this.totalTaxTotal);
|
||||
},
|
||||
totalQuantity() {
|
||||
return calculateTotalQuantity(this.products);
|
||||
},
|
||||
// 计算总含税总额
|
||||
totalTaxTotal() {
|
||||
return calculateTotalTaxTotal(this.products);
|
||||
},
|
||||
// 计算大写金额
|
||||
totalAmountInWords() {
|
||||
return convertToChinese(this.totalTaxTotal);
|
||||
},
|
||||
// 生成JSON字符串
|
||||
jsonContent() {
|
||||
// 只存储非空行
|
||||
@@ -251,24 +196,24 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
// 解析content字符串
|
||||
parseContent(content) {
|
||||
try {
|
||||
const data = parseProductContent(content);
|
||||
this.products = data.products.length > 0 ? data.products : [{}];
|
||||
this.remark = data.remark || '';
|
||||
this.productName = data.productName || '';
|
||||
} catch (error) {
|
||||
console.error('解析content失败:', error);
|
||||
this.products = [{}];
|
||||
this.remark = '';
|
||||
}
|
||||
},
|
||||
// 计算金额
|
||||
calculateTotals() {
|
||||
this.products.forEach(item => {
|
||||
item.taxTotal = calculateProductTaxTotal(item);
|
||||
});
|
||||
},
|
||||
parseContent(content) {
|
||||
try {
|
||||
const data = parseProductContent(content);
|
||||
this.products = data.products.length > 0 ? data.products : [{}];
|
||||
this.remark = data.remark || '';
|
||||
this.productName = data.productName || '';
|
||||
} catch (error) {
|
||||
console.error('解析content失败:', error);
|
||||
this.products = [{}];
|
||||
this.remark = '';
|
||||
}
|
||||
},
|
||||
// 计算金额
|
||||
calculateTotals() {
|
||||
this.products.forEach(item => {
|
||||
item.taxTotal = calculateProductTaxTotal(item);
|
||||
});
|
||||
},
|
||||
// 添加产品行
|
||||
addProduct() {
|
||||
this.products.push({});
|
||||
@@ -291,85 +236,86 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.product-content {
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.table-header {
|
||||
background-color: #f5f7fa;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.company-name {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
display: grid;
|
||||
grid-template-columns: 80px 150px 120px 100px 160px 120px 140px 1fr;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.table-row-hover:hover {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.table-header-row {
|
||||
background-color: #f5f7fa;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.table-total-row {
|
||||
background-color: #f5f7fa;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.table-cell {
|
||||
padding: 8px;
|
||||
border-right: 1px solid #e4e7ed;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.table-cell:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.table-cell[colspan="3"] {
|
||||
grid-column: span 3;
|
||||
}
|
||||
.product-content {
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.table-cell[colspan="5"] {
|
||||
grid-column: span 5;
|
||||
}
|
||||
|
||||
.table-cell[colspan="8"] {
|
||||
grid-column: span 8;
|
||||
}
|
||||
.table-cell[colspan="9"] {
|
||||
grid-column: span 9;
|
||||
}
|
||||
|
||||
.serial-number {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
opacity: 0;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.serial-number:hover .delete-btn {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.el-input {
|
||||
width: 100%;
|
||||
}
|
||||
.table-header {
|
||||
background-color: #f5f7fa;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.company-name {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
display: grid;
|
||||
grid-template-columns: 80px 150px 120px 100px 160px 120px 140px 1fr;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.table-row-hover:hover {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.table-header-row {
|
||||
background-color: #f5f7fa;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.table-total-row {
|
||||
background-color: #f5f7fa;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.table-cell {
|
||||
padding: 8px;
|
||||
border-right: 1px solid #e4e7ed;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.table-cell:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.table-cell[colspan="3"] {
|
||||
grid-column: span 3;
|
||||
}
|
||||
|
||||
.table-cell[colspan="5"] {
|
||||
grid-column: span 5;
|
||||
}
|
||||
|
||||
.table-cell[colspan="8"] {
|
||||
grid-column: span 8;
|
||||
}
|
||||
|
||||
.table-cell[colspan="9"] {
|
||||
grid-column: span 9;
|
||||
}
|
||||
|
||||
.serial-number {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
opacity: 0;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.serial-number:hover .delete-btn {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.el-input {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -96,6 +96,12 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-view"
|
||||
@click="handleView(scope.row)"
|
||||
>查看</el-button>
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
@@ -166,6 +172,45 @@
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 查看公告对话框 -->
|
||||
<el-dialog title="查看公告" :visible.sync="viewOpen" width="780px" append-to-body>
|
||||
<el-form ref="viewForm" :model="viewForm" label-width="80px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="公告标题">
|
||||
<span>{{ viewForm.noticeTitle }}</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="公告类型">
|
||||
<dict-tag :options="dict.type.sys_notice_type" :value="viewForm.noticeType"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="状态">
|
||||
<dict-tag :options="dict.type.sys_notice_status" :value="viewForm.status"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="创建者">
|
||||
<span>{{ viewForm.createBy }}</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="创建时间">
|
||||
<span>{{ parseTime(viewForm.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<div v-html="viewForm.noticeContent" class="notice-content" style="min-height: 192px; border: 1px solid #dcdfe6; padding: 10px; border-radius: 4px;"></div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="viewOpen = false">关 闭</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -195,6 +240,10 @@ export default {
|
||||
title: "",
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 是否显示查看弹出层
|
||||
viewOpen: false,
|
||||
// 查看表单
|
||||
viewForm: {},
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
@@ -261,6 +310,13 @@ export default {
|
||||
this.single = selection.length!=1
|
||||
this.multiple = !selection.length
|
||||
},
|
||||
/** 查看按钮操作 */
|
||||
handleView(row) {
|
||||
getNotice(row.noticeId).then(response => {
|
||||
this.viewForm = response.data;
|
||||
this.viewOpen = true;
|
||||
});
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
@@ -309,4 +365,13 @@ export default {
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.notice-content img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 10px auto;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user