feat: 多个模块新增功能与优化交互

1.  DictSelect组件新增单选按钮组渲染模式
2.  公告管理页面新增查看公告功能
3.  合同产品内容组件优化产品选择器与表格布局
This commit is contained in:
2026-05-12 10:47:21 +08:00
parent 1e62425fb8
commit 9b2e62916f
4 changed files with 260 additions and 207 deletions

View File

@@ -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
}
})
}

View File

@@ -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: {

View File

@@ -5,7 +5,11 @@
<!-- 第一行合并所有八个单元格内容为嘉祥科伦普重工有限公司 -->
<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>
@@ -18,116 +22,56 @@
<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>
@@ -154,13 +98,8 @@
<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,6 +134,12 @@ export default {
products: [],
remark: '',
productName: '',
productOptions: [
{ label: '冷硬钢卷', value: '冷硬钢卷' },
{ label: '镀锌钢卷', value: '镀锌钢卷' },
{ label: '冷轧钢卷', value: '冷轧钢卷' },
{ label: '镀铬钢卷', value: '镀铬钢卷' },
]
}
},
computed: {
@@ -291,85 +236,86 @@ export default {
</script>
<style scoped>
.product-content {
.product-content {
border: 1px solid #e4e7ed;
border-radius: 4px;
overflow: hidden;
}
}
.table-header {
.table-header {
background-color: #f5f7fa;
text-align: center;
border-bottom: 1px solid #e4e7ed;
}
}
.company-name {
.company-name {
font-size: 16px;
font-weight: bold;
}
}
.table-row {
.table-row {
display: grid;
grid-template-columns: 80px 150px 120px 100px 160px 120px 140px 1fr;
border-bottom: 1px solid #e4e7ed;
}
}
.table-row-hover:hover {
.table-row-hover:hover {
background-color: #f5f7fa;
}
}
.table-header-row {
.table-header-row {
background-color: #f5f7fa;
font-weight: bold;
}
}
.table-total-row {
.table-total-row {
background-color: #f5f7fa;
font-weight: bold;
}
}
.table-cell {
.table-cell {
padding: 8px;
border-right: 1px solid #e4e7ed;
display: flex;
align-items: center;
}
}
.table-cell:last-child {
.table-cell:last-child {
border-right: none;
}
}
.table-cell[colspan="3"] {
.table-cell[colspan="3"] {
grid-column: span 3;
}
}
.table-cell[colspan="5"] {
.table-cell[colspan="5"] {
grid-column: span 5;
}
}
.table-cell[colspan="8"] {
.table-cell[colspan="8"] {
grid-column: span 8;
}
.table-cell[colspan="9"] {
grid-column: span 9;
}
}
.serial-number {
.table-cell[colspan="9"] {
grid-column: span 9;
}
.serial-number {
position: relative;
display: inline-flex;
align-items: center;
}
}
.delete-btn {
.delete-btn {
opacity: 0;
margin-left: 10px;
}
}
.serial-number:hover .delete-btn {
.serial-number:hover .delete-btn {
opacity: 1;
}
}
.el-input {
.el-input {
width: 100%;
}
}
</style>

View File

@@ -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();
@@ -310,3 +366,12 @@ export default {
}
};
</script>
<style scoped>
.notice-content img {
max-width: 100%;
height: auto;
display: block;
margin: 10px auto;
}
</style>