修改采购件页面金额显示,修改权限管理页面非字段级内容可见与可编辑联动
This commit is contained in:
@ -471,7 +471,7 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="总价">
|
||||
<el-form-item label="不含税总价">
|
||||
<el-input-number
|
||||
v-model="form.total_price"
|
||||
:precision="2"
|
||||
@ -778,7 +778,7 @@ const stockColumns = [
|
||||
{prop: 'tax_rate', label: '税率', minWidth: '80'},
|
||||
{prop: 'unit_price', label: '不含税单价', minWidth: '120'},
|
||||
|
||||
{prop: 'total_price', label: '总价', minWidth: '120'},
|
||||
{prop: 'total_price', label: '不含税总价', minWidth: '120'},
|
||||
{prop: 'currency', label: '币种', minWidth: '80'},
|
||||
{prop: 'exchange_rate', label: '汇率', minWidth: '80'},
|
||||
{prop: 'supplier_name', label: '供应商', minWidth: '150'},
|
||||
|
||||
@ -380,7 +380,13 @@
|
||||
<el-autocomplete v-model="form.production_manager" :fetch-suggestions="querySearchManager" placeholder="输入或选择负责人" style="width: 100%" clearable :trigger-on-focus="true" @select="handleManagerSelect"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8"><el-form-item label="产品定价"><el-input-number v-model="form.sale_price" :precision="2" style="width:100%"><template #prefix>¥</template></el-input-number></el-form-item></el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="产品定价">
|
||||
<el-input-number v-model="form.sale_price" :precision="2" :controls="false" style="width:100%" placeholder="请输入">
|
||||
<template #prefix>¥</template>
|
||||
</el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="24">
|
||||
@ -389,8 +395,16 @@
|
||||
<el-date-picker v-model="form.production_time_range" type="datetimerange" value-format="YYYY-MM-DD HH:mm:ss" style="width:100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6"><el-form-item label="原料成本"><el-input-number v-model="form.raw_material_cost" :precision="2" style="width:100%" /></el-form-item></el-col>
|
||||
<el-col :span="6"><el-form-item label="人工成本"><el-input-number v-model="form.manual_cost" :precision="2" style="width:100%" /></el-form-item></el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="原料成本">
|
||||
<el-input-number v-model="form.raw_material_cost" :precision="2" :controls="false" style="width:100%" placeholder="请输入"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="人工成本">
|
||||
<el-input-number v-model="form.manual_cost" :precision="2" :controls="false" style="width:100%" placeholder="请输入"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24" style="margin-top:10px">
|
||||
<el-col :span="24"><el-form-item label="详情链接"><el-input v-model="form.detail_link" /></el-form-item></el-col>
|
||||
@ -628,7 +642,9 @@ const form = reactive({
|
||||
warehouse_location: '', status: '在库', quality_status: '合格',
|
||||
bom_code: '', bom_version: '', work_order_code: '', order_id: '',
|
||||
production_manager: '', production_time_range: [] as string[],
|
||||
raw_material_cost: 0, manual_cost: 0, sale_price: 0,
|
||||
raw_material_cost: undefined as number | undefined,
|
||||
manual_cost: undefined as number | undefined,
|
||||
sale_price: undefined as number | undefined,
|
||||
quality_report_link: [] as string[], inspection_report_link: [] as string[], product_photo: [] as string[], detail_link: ''
|
||||
})
|
||||
|
||||
@ -837,9 +853,9 @@ const handleUpdate = (row: any) => {
|
||||
quality_report_link: row.quality_report_link || [],
|
||||
inspection_report_link: row.inspection_report_link || [],
|
||||
in_quantity: Number(row.qty_inbound),
|
||||
raw_material_cost: Number(row.raw_material_cost),
|
||||
manual_cost: Number(row.manual_cost),
|
||||
sale_price: Number(row.sale_price)
|
||||
raw_material_cost: (row.raw_material_cost !== null && row.raw_material_cost !== undefined) ? Number(row.raw_material_cost) : undefined,
|
||||
manual_cost: (row.manual_cost !== null && row.manual_cost !== undefined) ? Number(row.manual_cost) : undefined,
|
||||
sale_price: (row.sale_price !== null && row.sale_price !== undefined) ? Number(row.sale_price) : undefined
|
||||
})
|
||||
if(row.production_start_time && row.production_end_time) { form.production_time_range = [row.production_start_time, row.production_end_time] } else { form.production_time_range = [] }
|
||||
productPhotoList.value = form.product_photo.map(url => ({ name: url.split('/').pop(), url: getImageUrl(url) }))
|
||||
@ -943,7 +959,16 @@ const submitForm = async () => {
|
||||
const iImages = iList.filter(item => !isExternalLink(item))
|
||||
if (inspection_url.value && !iList.includes(inspection_url.value)) iImages.push(inspection_url.value)
|
||||
else if (inspection_url.value) iImages.push(inspection_url.value)
|
||||
const payload = { ...form, quality_report_link: qImages, inspection_report_link: iImages, production_start_time: form.production_time_range?.[0], production_end_time: form.production_time_range?.[1] }
|
||||
const payload = {
|
||||
...form,
|
||||
quality_report_link: qImages,
|
||||
inspection_report_link: iImages,
|
||||
raw_material_cost: Number(form.raw_material_cost || 0),
|
||||
manual_cost: Number(form.manual_cost || 0),
|
||||
sale_price: Number(form.sale_price || 0),
|
||||
production_start_time: form.production_time_range?.[0],
|
||||
production_end_time: form.production_time_range?.[1]
|
||||
}
|
||||
delete payload.production_time_range
|
||||
try {
|
||||
if(dialogStatus.value === 'create') {
|
||||
@ -969,7 +994,7 @@ const handlePrint = async (row: any) => {
|
||||
const confirmPrint = async () => { printing.value = true; try { await executePrint(currentPrintData.value); ElMessage.success('已发送'); printVisible.value = false } catch (e: any) { ElMessage.error('打印失败') } finally { printing.value = false } }
|
||||
const resetForm = () => {
|
||||
materialOptions.value = []; bomOptions.value = []; productPhotoList.value = []; qualityFileList.value = []; inspectionFileList.value = []; quality_url.value = ''; inspection_url.value = ''
|
||||
Object.assign(form, { id: undefined, base_id: undefined, material_name: '', spec_model: '', material_type: '', category: '', unit: '', sku: '', barcode: '', serial_number: '', in_date: '', in_quantity: 1, stock_quantity: 1, available_quantity: 1, warehouse_location: '', status: '在库', quality_status: '合格', bom_code: '', bom_version: '', work_order_code: '', order_id: '', production_manager: '', production_time_range: [], raw_material_cost: 0, manual_cost: 0, sale_price: 0, quality_report_link: [], inspection_report_link: [], product_photo: [], detail_link: '' })
|
||||
Object.assign(form, { id: undefined, base_id: undefined, material_name: '', spec_model: '', material_type: '', category: '', unit: '', sku: '', barcode: '', serial_number: '', in_date: '', in_quantity: 1, stock_quantity: 1, available_quantity: 1, warehouse_location: '', status: '在库', quality_status: '合格', bom_code: '', bom_version: '', work_order_code: '', order_id: '', production_manager: '', production_time_range: [], raw_material_cost: undefined, manual_cost: undefined, sale_price: undefined, quality_report_link: [], inspection_report_link: [], product_photo: [], detail_link: '' })
|
||||
}
|
||||
const getStatusType = (s:string) => ({'在库':'success','出库':'info','借库':'warning','损耗':'danger'}[s]||'warning')
|
||||
const getQualityType = (s:string) => ({'合格':'success','不合格':'danger','待检':'info'}[s]||'info')
|
||||
@ -1047,10 +1072,13 @@ onMounted(() => {
|
||||
/* [新增] 纯文本样式 */
|
||||
.is-text-view :deep(.el-input__wrapper) { box-shadow: none !important; background-color: transparent !important; border-bottom: 1px dashed #dcdfe6; border-radius: 0; padding-left: 0; }
|
||||
.is-text-view :deep(.el-input__inner) { color: #303133; font-weight: 600; font-size: 14px; cursor: text; }
|
||||
|
||||
/* 左对齐数字框 */
|
||||
:deep(.el-input-number .el-input__inner) { text-align: left; }
|
||||
</style>
|
||||
|
||||
<style>
|
||||
.long-dropdown { width: 580px !important; }
|
||||
.long-dropdown .el-select-dropdown__wrap { max-height: 320px !important; }
|
||||
.long-dropdown .el-input__suffix { z-index: 10; }
|
||||
</style>
|
||||
</style>
|
||||
@ -468,9 +468,21 @@
|
||||
|
||||
<div class="divider-text">成本核算 (单件)</div>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="8"><el-form-item label="原材料成本"><el-input-number v-model="form.raw_material_cost" :precision="2" controls-position="right" style="width:100%"/></el-form-item></el-col>
|
||||
<el-col :span="8"><el-form-item label="手动/工时"><el-input-number v-model="form.manual_cost" :precision="2" controls-position="right" style="width:100%"/></el-form-item></el-col>
|
||||
<el-col :span="8"><el-form-item label="单件总成本"><el-input-number v-model="form.unit_total_cost" :precision="2" disabled :controls="false" style="width:100%" class="total-price-input"/></el-form-item></el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="原材料成本">
|
||||
<el-input-number v-model="form.raw_material_cost" :precision="2" :controls="false" style="width:100%" placeholder="请输入"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="手动/工时">
|
||||
<el-input-number v-model="form.manual_cost" :precision="2" :controls="false" style="width:100%" placeholder="请输入"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="单件总成本">
|
||||
<el-input-number v-model="form.unit_total_cost" :precision="2" :controls="false" style="width:100%" placeholder="请输入"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="24" style="margin-top:10px">
|
||||
@ -516,7 +528,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {ref, reactive, onMounted, watch} from 'vue'
|
||||
import {ref, reactive, onMounted} from 'vue'
|
||||
import {Plus, Setting, Refresh, Search, Lock, Box, House, InfoFilled, Link, Printer, Camera, Picture} from '@element-plus/icons-vue'
|
||||
import {ElMessage, ElLoading} from 'element-plus'
|
||||
import dayjs from 'dayjs'
|
||||
@ -677,26 +689,19 @@ const permissionMap: Record<string, string> = {
|
||||
|
||||
// 根据用户权限初始化列显示状态
|
||||
const initColumnPermissions = () => {
|
||||
// 超级管理员跳过权限检查,显示所有列
|
||||
if (userStore.role === 'SUPER_ADMIN' || userStore.username === 'IRIS') {
|
||||
return
|
||||
}
|
||||
|
||||
// 普通用户:严格执行列级权限控制,没有权限的列必须隐藏
|
||||
// 遍历 allColumns,将没有权限的列从 visibleColumnProps 中移除
|
||||
const allowedColumns = allColumns.filter(col => {
|
||||
const code = permissionMap[col.prop]
|
||||
if (code) {
|
||||
return userStore.hasPermission(code)
|
||||
}
|
||||
// 如果没有映射,默认隐藏
|
||||
return false
|
||||
}).map(col => col.prop)
|
||||
|
||||
// 更新 visibleColumnProps,只保留有权限的列
|
||||
// 同时保持用户之前已经选择的有权限的列
|
||||
const currentVisible = visibleColumnProps.value.filter(prop => allowedColumns.includes(prop))
|
||||
// 如果当前没有可见列,则使用 allowedColumns 作为默认
|
||||
if (currentVisible.length === 0) {
|
||||
visibleColumnProps.value = allowedColumns
|
||||
} else {
|
||||
@ -718,8 +723,12 @@ const visibleColumnProps = ref(defaultColumns)
|
||||
|
||||
const form = reactive({
|
||||
id: undefined, base_id: undefined as number | undefined,
|
||||
company_name: '', // [新增]
|
||||
material_name: '', spec_model: '', category: '', unit: '', material_type: '', sku: '', barcode: '', in_date: '', serial_number: '', batch_number: '', status: '在库', quality_status: '合格', in_quantity: 1, stock_quantity: 1, available_quantity: 1, warehouse_location: '', bom_code: '', bom_version: '', work_order_code: '', raw_material_cost: 0, manual_cost: 0, unit_total_cost: 0, production_manager: '', production_time_range: [] as string[], arrival_photo: [] as string[], quality_report_link: [] as string[], detail_link: ''
|
||||
company_name: '',
|
||||
material_name: '', spec_model: '', category: '', unit: '', material_type: '', sku: '', barcode: '', in_date: '', serial_number: '', batch_number: '', status: '在库', quality_status: '合格', in_quantity: 1, stock_quantity: 1, available_quantity: 1, warehouse_location: '', bom_code: '', bom_version: '', work_order_code: '',
|
||||
raw_material_cost: undefined as number | undefined,
|
||||
manual_cost: undefined as number | undefined,
|
||||
unit_total_cost: undefined as number | undefined,
|
||||
production_manager: '', production_time_range: [] as string[], arrival_photo: [] as string[], quality_report_link: [] as string[], detail_link: ''
|
||||
})
|
||||
|
||||
// ------------------------------------
|
||||
@ -842,11 +851,9 @@ const rules = {
|
||||
// 表单字段权限检查
|
||||
// ------------------------------------
|
||||
const hasFormFieldPermission = (fieldName: string) => {
|
||||
// 超级管理员直接返回true
|
||||
if (userStore.role === 'SUPER_ADMIN' || userStore.username === 'IRIS') {
|
||||
return true
|
||||
}
|
||||
// 根据字段名映射到权限码
|
||||
const map: Record<string, string> = {
|
||||
company_name: 'inbound_semi:company_name',
|
||||
material_name: 'inbound_semi:material_name',
|
||||
@ -872,14 +879,13 @@ const hasFormFieldPermission = (fieldName: string) => {
|
||||
manual_cost: 'inbound_semi:manual_cost',
|
||||
unit_total_cost: 'inbound_semi:unit_total_cost',
|
||||
production_manager: 'inbound_semi:production_manager',
|
||||
production_time_range: 'inbound_semi:production_start_time', // 使用开始时间权限
|
||||
production_time_range: 'inbound_semi:production_start_time',
|
||||
arrival_photo: 'inbound_semi:arrival_photo',
|
||||
quality_report_link: 'inbound_semi:quality_report_link',
|
||||
detail_link: 'inbound_semi:detail_link',
|
||||
}
|
||||
const code = map[fieldName]
|
||||
if (!code) {
|
||||
// 没有映射的字段默认显示
|
||||
return true
|
||||
}
|
||||
return userStore.hasPermission(code)
|
||||
@ -910,7 +916,6 @@ const handleEntryModeChange = (val: string) => {
|
||||
if (val === 'batch') { form.serial_number = ''; form.batch_number = '000001'; if(formRef.value) formRef.value.clearValidate('serial_number') }
|
||||
else { form.batch_number = ''; if(formRef.value) formRef.value.clearValidate('batch_number') }
|
||||
}
|
||||
watch(() => [form.raw_material_cost, form.manual_cost], () => { form.unit_total_cost = Number((form.raw_material_cost + form.manual_cost).toFixed(2)) })
|
||||
|
||||
const fetchData = async () => {
|
||||
loading.value = true
|
||||
@ -967,7 +972,9 @@ const handleUpdate = (row: any) => {
|
||||
warehouse_location: row.warehouse_loc, status: row.status, quality_status: row.quality_status,
|
||||
in_quantity: Number(row.qty_inbound), stock_quantity: Number(row.qty_stock), available_quantity: Number(row.qty_available),
|
||||
bom_code: row.bom_code, bom_version: row.bom_version, work_order_code: row.work_order_code,
|
||||
raw_material_cost: Number(row.raw_material_cost) || 0, manual_cost: Number(row.manual_cost) || 0,
|
||||
raw_material_cost: (row.raw_material_cost !== null && row.raw_material_cost !== undefined) ? Number(row.raw_material_cost) : undefined,
|
||||
manual_cost: (row.manual_cost !== null && row.manual_cost !== undefined) ? Number(row.manual_cost) : undefined,
|
||||
unit_total_cost: (row.unit_total_cost !== null && row.unit_total_cost !== undefined) ? Number(row.unit_total_cost) : undefined,
|
||||
production_manager: row.production_manager,
|
||||
production_time_range: (row.production_start_time && row.production_end_time) ? [row.production_start_time, row.production_end_time] : [],
|
||||
detail_link: row.detail_link,
|
||||
@ -1065,7 +1072,16 @@ const submitForm = async () => {
|
||||
if (quality_report_url.value && !finalReportList.includes(quality_report_url.value)) finalReportList.push(quality_report_url.value)
|
||||
const onlyImages = finalReportList.filter(item => !isExternalLink(item))
|
||||
if (quality_report_url.value) onlyImages.push(quality_report_url.value)
|
||||
const payload: any = { ...form, quality_report_link: onlyImages, in_quantity: Number(form.in_quantity), raw_material_cost: Number(form.raw_material_cost), manual_cost: Number(form.manual_cost), production_start_time: form.production_time_range?.[0] || null, production_end_time: form.production_time_range?.[1] || null }
|
||||
const payload: any = {
|
||||
...form,
|
||||
quality_report_link: onlyImages,
|
||||
in_quantity: Number(form.in_quantity),
|
||||
raw_material_cost: Number(form.raw_material_cost || 0),
|
||||
manual_cost: Number(form.manual_cost || 0),
|
||||
unit_total_cost: Number(form.unit_total_cost || 0),
|
||||
production_start_time: form.production_time_range?.[0] || null,
|
||||
production_end_time: form.production_time_range?.[1] || null
|
||||
}
|
||||
delete payload.production_time_range
|
||||
try {
|
||||
if (dialogStatus.value === 'create') {
|
||||
@ -1098,11 +1114,13 @@ const resetForm = () => {
|
||||
Object.assign(form, {
|
||||
id: undefined, base_id: undefined,
|
||||
company_name: '', // [新增]
|
||||
material_name: '', spec_model: '', category: '', unit: '', material_type: '', sku: '', barcode: '', in_date: '', serial_number: '', batch_number: '', status: '在库', quality_status: '合格', in_quantity: 1, stock_quantity: 1, available_quantity: 1, warehouse_location: '', bom_code: '', bom_version: '', work_order_code: '', raw_material_cost: 0, manual_cost: 0, unit_total_cost: 0, production_manager: '', production_time_range: [], arrival_photo: [], quality_report_link: [], detail_link: '' })
|
||||
material_name: '', spec_model: '', category: '', unit: '', material_type: '', sku: '', barcode: '', in_date: '', serial_number: '', batch_number: '', status: '在库', quality_status: '合格', in_quantity: 1, stock_quantity: 1, available_quantity: 1, warehouse_location: '', bom_code: '', bom_version: '', work_order_code: '',
|
||||
raw_material_cost: undefined, manual_cost: undefined, unit_total_cost: undefined,
|
||||
production_manager: '', production_time_range: [], arrival_photo: [], quality_report_link: [], detail_link: '' })
|
||||
}
|
||||
const getStatusType = (status: string) => { const map: any = { '在库': 'success', '出库': 'info', '借库': 'warning', '损耗': 'danger' }; return map[status] || 'warning' }
|
||||
const getQualityType = (status: string) => { const map: any = { '合格': 'success', '不合格': 'danger', '待检': 'info', '返修中': 'warning' }; return map[status] || 'info' }
|
||||
const formatMoney = (val: any) => { const num = Number(val); return isNaN(num) ? '-' : `¥ ${num.toFixed(2)}` }
|
||||
const formatMoney = (val: any) => isNaN(Number(val)) ? '-' : `¥ ${Number(val).toFixed(2)}`
|
||||
|
||||
onMounted(() => {
|
||||
// 先根据权限初始化列显示状态
|
||||
@ -1178,10 +1196,13 @@ onMounted(() => {
|
||||
.opt-spec { color: #999; font-size: 12px; }
|
||||
.opt-tags { display: flex; gap: 5px; flex-shrink: 0; }
|
||||
.company-tag { font-weight: bold; }
|
||||
|
||||
/* 左对齐数字框 */
|
||||
:deep(.el-input-number .el-input__inner) { text-align: left; }
|
||||
</style>
|
||||
|
||||
<style>
|
||||
.long-dropdown { width: 580px !important; }
|
||||
.long-dropdown .el-select-dropdown__wrap { max-height: 320px !important; }
|
||||
.long-dropdown .el-input__suffix { z-index: 10; }
|
||||
</style>
|
||||
</style>
|
||||
Reference in New Issue
Block a user