完成运维记录

master
lynn 1 year ago
parent c9eedafa54
commit f3e70818b4

@ -63,19 +63,19 @@
size="medium" size="medium"
> >
<el-table-column <el-table-column
prop="id" prop="no"
label="记录编号" label="记录编号"
min-width="120" min-width="120"
align="center" align="center"
/> />
<el-table-column <el-table-column
prop="material" prop="stocks_item.zichanmingcheng"
label="维护物资" label="维护物资"
min-width="120" min-width="120"
align="center" align="center"
/> />
<el-table-column <el-table-column
prop="plan_date" prop="planned_maintenance_date"
label="计划维护日期" label="计划维护日期"
min-width="120" min-width="120"
align="center" align="center"
@ -86,18 +86,18 @@
align="center" align="center"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<template v-if="scope.row.status === 'completed'"> <template v-if="scope.row.status === 1">
{{ scope.row.actual_date }} {{ scope.row.maintenance_date }}
</template> </template>
<template v-else> <template v-else>
<div :class="['status-badge', getBadgeClass(scope.row.plan_date)]" style="display: inline-block;"> <div :class="['status-badge', getBadgeClass(scope.row.planned_maintenance_date)]" style="display: inline-block;">
{{ getBadgeText(scope.row.plan_date) }} {{ getBadgeText(scope.row.planned_maintenance_date) }}
</div> </div>
</template> </template>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="operator" prop="responsible_admin.name"
label="负责人" label="负责人"
min-width="100" min-width="100"
align="center" align="center"
@ -120,8 +120,8 @@
> >
<template slot-scope="scope"> <template slot-scope="scope">
<div style="display: flex; gap: 8px; justify-content: center;"> <div style="display: flex; gap: 8px; justify-content: center;">
<Button type="primary" size="small" style="border-radius: 6px;" @click="viewDetail(scope.row)"></Button> <Button v-if="scope.row.status === 1" type="primary" size="small" style="border-radius: 6px;" @click="viewDetail(scope.row)"></Button>
<Button v-if="scope.row.status !== 'completed'" type="primary" size="small" style="border-radius: 6px;" ghost @click="completeMaintenance(scope.row)"></Button> <Button v-if="scope.row.status === 0" type="primary" size="small" style="border-radius: 6px;" ghost @click="completeMaintenance(scope.row)"></Button>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
@ -149,28 +149,38 @@
<button class="close-button" @click="closeModal">&times;</button> <button class="close-button" @click="closeModal">&times;</button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<form @submit.prevent="submitMaintenance"> <Form ref="maintenanceForm" :model="form" :rules="formRules" :label-width="120">
<div class="form-group"> <FormItem label="实际维护日期" prop="actual_date">
<label for="actual-date">实际维护日期:</label> <DatePicker v-model="form.actual_date" type="date" placeholder="请选择实际维护日期" style="width: 100%"></DatePicker>
<input type="date" id="actual-date" v-model="form.actual_date" required> </FormItem>
</div> <FormItem label="维护备注" prop="notes">
<div class="form-group"> <Input v-model="form.notes" type="textarea" :rows="4" placeholder="请输入维护备注"></Input>
<label for="maintenance-notes">备注:</label> </FormItem>
<textarea id="maintenance-notes" v-model="form.notes" rows="4" required></textarea> <FormItem label="上传图片" prop="photos">
</div> <Upload
<div class="form-group"> ref="upload"
<label for="maintenance-photos">上传图片:</label> :before-upload="handleBeforeUpload"
<input type="file" id="maintenance-photos" multiple accept="image/*" @change="handleFileUpload"> :on-success="handleUploadSuccess"
<small class="form-text">可选</small> :on-error="handleUploadError"
</div> :on-remove="handleRemove"
<div class="form-group signature-area"> :max-size="2048"
<label>签名:</label> multiple
type="drag"
:action="baseUrl + 'api/admin/upload-file'"
>
<div style="padding: 20px 0">
<Icon type="ios-cloud-upload" size="52" style="color: #3399ff"></Icon>
<p>点击或拖拽文件到此处上传</p>
</div>
</Upload>
</FormItem>
<FormItem label="签名" prop="signature">
<div class="signature-pad-wrapper"> <div class="signature-pad-wrapper">
<canvas ref="signaturePad" class="signature-canvas"></canvas> <canvas ref="signaturePad" class="signature-canvas"></canvas>
<Button size="small" style="margin-top: 8px;" @click="clearSignature"></Button> <Button size="small" style="margin-top: 8px;" @click="clearSignature"></Button>
</div> </div>
</div> </FormItem>
</form> </Form>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<Button @click="closeModal"></Button> <Button @click="closeModal"></Button>
@ -191,23 +201,23 @@
<div class="modal-body"> <div class="modal-body">
<div class="form-group"> <div class="form-group">
<label>记录编号:</label> <label>记录编号:</label>
<div class="form-value">{{ currentRecord.id }}</div> <div class="form-value">{{ currentRecord.no }}</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>维护物资:</label> <label>维护物资:</label>
<div class="form-value">{{ currentRecord.material }}</div> <div class="form-value">{{ currentRecord.stocks_item_name }}</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>计划维护日期:</label> <label>计划维护日期:</label>
<div class="form-value">{{ currentRecord.plan_date }}</div> <div class="form-value">{{ currentRecord.planned_maintenance_date }}</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>实际维护日期:</label> <label>实际维护日期:</label>
<div class="form-value">{{ currentRecord.actual_date || '-' }}</div> <div class="form-value">{{ currentRecord.maintenance_date || '-' }}</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>负责人:</label> <label>负责人:</label>
<div class="form-value">{{ currentRecord.operator }}</div> <div class="form-value">{{ currentRecord.responsible_admin_name }}</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>状态:</label> <label>状态:</label>
@ -218,30 +228,51 @@
<div class="form-value">{{ currentRecord.maintenance_notes || '-' }}</div> <div class="form-value">{{ currentRecord.maintenance_notes || '-' }}</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>维护图片:</label> <label>维护照片:</label>
<div class="photo-gallery" v-if="currentRecord.maintenance_photos && currentRecord.maintenance_photos.length"> <div class="photo-gallery" v-if="currentRecord.files && currentRecord.files.length">
<div v-for="(photo, index) in currentRecord.maintenance_photos" :key="index" class="photo-item"> <img
<img :src="photo" alt="维护图片" class="photo-preview"> v-for="(file, idx) in currentRecord.files"
</div> :key="'file-' + idx"
:src="file.url"
class="photo-preview"
@click="previewImage(file.url)"
style="cursor:pointer;"
alt="维护图片"
/>
</div> </div>
<div class="form-value" v-else>-</div> <div class="form-value" v-else>-</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>维护人签名:</label> <label>签名照片:</label>
<div class="form-value">{{ currentRecord.maintenance_signature || '-' }}</div> <div class="photo-gallery" v-if="currentRecord.sign && currentRecord.sign.url">
<img
:src="currentRecord.sign.url"
class="sign-preview"
@click="previewImage(currentRecord.sign.url)"
style="cursor:pointer;"
alt="签名图片"
/>
</div>
<div class="form-value" v-else>-</div>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer" style="justify-content: center;">
<Button @click="closeViewModal"></Button> <Button @click="closeViewModal"></Button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- 预览弹窗 -->
<div v-if="previewUrl" class="image-preview-modal" @click="closePreview">
<img :src="previewUrl" class="image-preview-large" />
</div>
</div> </div>
</template> </template>
<script> <script>
import { Button, Select, Option, DatePicker, Input } from 'view-design'; import { Button, Select, Option, DatePicker, Input, Form, FormItem, Upload, Icon } from 'view-design';
import { getOperationList, saveOperation, getOperationDetail } from '@/api/maintenance/maintenance';
export default { export default {
components: { components: {
@ -249,10 +280,15 @@ export default {
Select, Select,
Option, Option,
DatePicker, DatePicker,
Input Input,
Form,
FormItem,
Upload,
Icon
}, },
data() { data() {
return { return {
baseUrl: process.env.VUE_APP_BASE_API || window.location.origin + '/',
select: { select: {
page: 1, page: 1,
page_size: 10, page_size: 10,
@ -267,62 +303,7 @@ export default {
pending: 0, pending: 0,
completed: 0 completed: 0
}, },
list: [ list: [],
{
id: 'WX20230815001',
material: '3号水泵',
plan_date: '2023-08-14',
actual_date: '2023-08-15',
operator: '张三',
status: 'completed',
maintenance_notes: '水泵运行正常,已更换密封圈',
maintenance_photos: ['/path/to/photo1.jpg', '/path/to/photo2.jpg'],
maintenance_signature: '张三'
},
{
id: 'WX20230816002',
material: '柴油发电机',
plan_date: '2025-05-15', //
actual_date: '',
operator: '李四',
status: 'pending'
},
{
id: 'WX20230818003',
material: '防汛挡板',
plan_date: '2023-08-17',
actual_date: '2023-08-18',
operator: '王五',
status: 'completed',
maintenance_notes: '挡板完好,已进行防腐处理',
maintenance_photos: ['/path/to/photo3.jpg'],
maintenance_signature: '王五'
},
{
id: 'WX20241225004',
material: '冲锋舟',
plan_date: '2024-12-25', //
actual_date: '',
operator: '赵六',
status: 'pending'
},
{
id: 'WX20230701005',
material: '救生衣检查',
plan_date: '2023-07-01', //
actual_date: '',
operator: '孙七',
status: 'pending'
},
{
id: 'WX20240810006',
material: '应急照明灯',
plan_date: '2024-08-10', //
actual_date: '',
operator: '周八',
status: 'pending'
}
],
showModal: false, showModal: false,
showViewModal: false, showViewModal: false,
currentRecord: {}, currentRecord: {},
@ -331,9 +312,57 @@ export default {
notes: '', notes: '',
photos: [] photos: []
}, },
formRules: {
actual_date: [
{
required: true,
message: '请选择实际维护日期',
trigger: 'blur',
validator: (rule, value, callback) => {
if (!value) {
callback(new Error('请选择实际维护日期'));
} else {
callback();
}
}
}
],
notes: [],
photos: [
{
required: true,
type: 'array',
min: 1,
message: '请上传维护图片',
trigger: 'change',
validator: (rule, value, callback) => {
if (!value || value.length === 0) {
callback(new Error('请上传维护图片'));
} else {
callback();
}
}
}
],
signature: [
{
required: true,
message: '请签名',
trigger: 'change',
validator: (rule, value, callback) => {
if (!this.getSignatureDataUrl()) {
callback(new Error('请签名'));
} else {
callback();
}
}
}
]
},
currentUser: '张三', currentUser: '张三',
total: 0, total: 0,
tableHeight: 550 tableHeight: 550,
previewUrl: ''
} }
}, },
created() { created() {
@ -350,66 +379,25 @@ export default {
methods: { methods: {
async getList() { async getList() {
try { try {
// TODO: API const params = {
this.list = [ page: this.select.page,
{ page_size: this.select.page_size,
id: 'WX20230815001', warehouse: this.select.warehouse,
material: '3号水泵', status: this.select.status,
plan_date: '2023-08-14', date_start: this.select.date_start,
actual_date: '2023-08-15', date_end: this.select.date_end,
operator: '张三', keyword: this.select.keyword
status: 'completed',
maintenance_notes: '水泵运行正常,已更换密封圈',
maintenance_photos: ['/path/to/photo1.jpg', '/path/to/photo2.jpg'],
maintenance_signature: '张三'
},
{
id: 'WX20230816002',
material: '柴油发电机',
plan_date: '2025-08-15', //
actual_date: '',
operator: '李四',
status: 'pending'
},
{
id: 'WX20230818003',
material: '防汛挡板',
plan_date: '2023-08-17',
actual_date: '2023-08-18',
operator: '王五',
status: 'completed'
},
{
id: 'WX20241225004',
material: '冲锋舟',
plan_date: '2024-12-25', //
actual_date: '',
operator: '赵六',
status: 'pending'
},
{
id: 'WX20230701005',
material: '救生衣检查',
plan_date: '2023-07-01', //
actual_date: '',
operator: '孙七',
status: 'pending'
},
{
id: 'WX20240810006',
material: '应急照明灯',
plan_date: '2024-08-10', //
actual_date: '',
operator: '周八',
status: 'pending'
}
];
this.total = this.list.length;
this.stats = {
total: this.list.length,
pending: this.list.filter(item => item.status === 'pending').length,
completed: this.list.filter(item => item.status === 'completed').length
}; };
const res = await getOperationList(params);
if (res && res.list) {
this.list = res.list.data;
this.total = res.list.total;
this.stats = {
total: res.chart.total,
pending: res.chart.wait,
completed: res.chart.done
};
}
} catch (e) { } catch (e) {
this.$message.error('获取维护记录失败'); this.$message.error('获取维护记录失败');
} }
@ -456,17 +444,35 @@ export default {
return diffDays; return diffDays;
}, },
viewDetail(item) { async viewDetail(item) {
this.currentRecord = { ...item }; try {
this.showViewModal = true; // 1.
const detail = await getOperationDetail({ id: item.id });
// 2.
this.currentRecord = {
...detail,
stocks_item_name: detail.stocks_item?.zichanmingcheng || '-',
responsible_admin_name: detail.responsible_admin?.name || '-'
};
// 3.
this.showViewModal = true;
} catch (e) {
this.$message.error('获取维护详情失败');
}
}, },
completeMaintenance(item) { completeMaintenance(item) {
this.showModal = true this.showModal = true;
this.currentRecord = { ...item };
this.form = { this.form = {
actual_date: new Date().toISOString().split('T')[0], actual_date: new Date().toISOString().split('T')[0],
notes: '', notes: '',
photos: [] photos: []
} };
this.$nextTick(() => {
if (this.$refs.maintenanceForm) {
this.$refs.maintenanceForm.resetFields();
}
});
}, },
closeModal() { closeModal() {
this.showModal = false this.showModal = false
@ -476,18 +482,78 @@ export default {
photos: [] photos: []
} }
}, },
handleFileUpload(event) { handleBeforeUpload(file) {
this.form.photos = Array.from(event.target.files) //
return true; // true
},
handleUploadSuccess(response, file) {
// response.id idresponse.url
this.form.photos.push({ id: response.id, url: response.url });
},
handleUploadError(error, file) {
//
this.$message.error('上传图片失败');
},
handleRemove(file) {
// file.url
const index = this.form.photos.findIndex(photo => photo.url === file.url);
if (index !== -1) {
this.form.photos.splice(index, 1);
}
}, },
async submitMaintenance() { async submitMaintenance() {
try { try {
// TODO: this.$refs.maintenanceForm.validate(async (valid) => {
this.closeModal() if (valid) {
this.getList() // 1. canvassign_id
const signatureDataUrl = this.getSignatureDataUrl();
let sign_id = '';
if (signatureDataUrl) {
// base64Blob
const blob = this.dataURLtoBlob(signatureDataUrl);
const formData = new FormData();
formData.append('file', blob, 'signature.png');
//
const res = await this.$axios.post(this.baseUrl + 'api/admin/upload-file', formData, {
headers: { 'Content-Type': 'multipart/form-data' }
});
sign_id = res.data?.id || res.id;
}
// 2.
const params = {
id: this.currentRecord.id,
maintenance_date: this.formatDate(this.form.actual_date),
maintenance_content: this.form.notes,
file_ids: this.form.photos.map(photo => photo.id),
sign_id: sign_id,
status: 1
};
await saveOperation(params);
this.closeModal();
this.getList();
}
});
} catch (e) { } catch (e) {
this.$message.error('提交维护记录失败') this.$message.error('提交维护记录失败');
} }
}, },
formatDate(date) {
if (!date) return '';
const d = new Date(date);
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
},
dataURLtoBlob(dataurl) {
// base64Blob
const arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]);
let n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {type:mime});
},
getBadgeClass(planDate) { getBadgeClass(planDate) {
const diffDays = this.getDateDifferenceInDays(planDate); const diffDays = this.getDateDifferenceInDays(planDate);
return diffDays >= 0 ? 'badge-blue' : 'badge-red'; return diffDays >= 0 ? 'badge-blue' : 'badge-red';
@ -498,11 +564,10 @@ export default {
}, },
getStatusText(status) { getStatusText(status) {
const statusMap = { const statusMap = {
'pending': '待处理', '0': '待处理',
'completed': '已完成', '1': '已完成'
'ongoing': '进行中'
}; };
return statusMap[status] || status; return statusMap[status] || '未知状态';
}, },
closeViewModal() { closeViewModal() {
this.showViewModal = false; this.showViewModal = false;
@ -577,6 +642,12 @@ export default {
return this.signaturePadCanvas.toDataURL('image/png'); return this.signaturePadCanvas.toDataURL('image/png');
} }
return ''; return '';
},
previewImage(url) {
this.previewUrl = url;
},
closePreview() {
this.previewUrl = '';
} }
}, },
watch: { watch: {
@ -611,10 +682,11 @@ export default {
} }
.content-wrapper { .content-wrapper {
background-color: #fff; background: #f4f6fa !important;
border-radius: 10px;
border: 1.5px solid #e0e3e8 !important;
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
padding: 20px; padding: 20px;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
margin-top: 10px; margin-top: 10px;
} }
@ -672,25 +744,36 @@ export default {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
min-height: 0; min-height: 0;
height: calc(100vh - 200px);
} }
.el-table th { .el-table {
background: #f5f7fa !important; border-radius: 10px;
color: #333; overflow: hidden;
font-weight: bold; width: 100%;
font-size: 15px; height: 100%;
}
.el-table__body-wrapper {
height: calc(100% - 40px);
overflow-y: auto;
}
.el-table__header-wrapper {
height: 40px;
} }
.el-table td { .el-table td {
font-size: 14px; font-size: 14px;
height: 48px; padding: 8px 0;
} }
.el-table { .el-table th {
border-radius: 10px; background: #f5f7fa !important;
overflow: hidden; color: #333;
width: 100%; font-weight: bold;
height: 100%; font-size: 15px;
padding: 8px 0;
} }
.status-badge { .status-badge {
@ -731,7 +814,7 @@ export default {
position: relative; position: relative;
margin: auto; margin: auto;
pointer-events: none; pointer-events: none;
max-width: 600px; max-width: 900px;
width: 90%; width: 90%;
} }
@ -741,28 +824,30 @@ export default {
flex-direction: column; flex-direction: column;
width: 100%; width: 100%;
pointer-events: auto; pointer-events: auto;
background-color: #fff; background: #f7f9fa !important;
background-clip: padding-box; background-clip: padding-box;
border: 1px solid rgba(0,0,0,.2); border-radius: 12px;
border-radius: 0.3rem; box-shadow: 0 8px 32px rgba(0,0,0,0.15);
border: 2px solid #e0e3e8 !important;
outline: 0; outline: 0;
box-shadow: 0 0.5rem 1rem rgba(0,0,0,.5);
} }
.modal-header { .modal-header {
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
justify-content: space-between; justify-content: space-between;
padding: 1rem 1rem; padding: 1.2rem 1.5rem;
border-bottom: 1px solid #dee2e6; background: #f5f7fa;
border-top-left-radius: calc(0.3rem - 1px); border-bottom: 1px solid #eaeaea;
border-top-right-radius: calc(0.3rem - 1px); border-radius: 12px 12px 0 0;
} }
.modal-title { .modal-title {
margin-bottom: 0; margin-bottom: 0;
line-height: 1.5; line-height: 1.5;
font-size: 1.25rem; font-size: 1.35rem;
font-weight: 700;
color: #222;
} }
.close-button { .close-button {
@ -770,48 +855,47 @@ export default {
margin: -1rem -1rem -1rem auto; margin: -1rem -1rem -1rem auto;
background-color: transparent; background-color: transparent;
border: 0; border: 0;
font-size: 1.5rem; font-size: 2rem;
font-weight: 700; font-weight: 700;
line-height: 1; line-height: 1;
color: #000; color: #888;
text-shadow: 0 1px 0 #fff; text-shadow: 0 1px 0 #fff;
opacity: .5; opacity: 0.7;
cursor: pointer; cursor: pointer;
transition: color 0.2s, opacity 0.2s;
} }
.close-button:hover { .close-button:hover {
opacity: .75; color: #ed4014;
opacity: 1;
} }
.modal-body { .modal-body {
position: relative; background: #fcfcfd;
flex: 1 1 auto; padding: 2rem 1.5rem 1.5rem 1.5rem;
padding: 1rem; border-radius: 0 0 12px 12px;
} display: grid;
grid-template-columns: 1fr 1fr;
.modal-footer { gap: 16px 32px;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: flex-end;
padding: 0.75rem;
border-top: 1px solid #dee2e6;
border-bottom-right-radius: calc(0.3rem - 1px);
border-bottom-left-radius: calc(0.3rem - 1px);
gap: 0.5rem;
} }
.form-group { .form-group {
width: 100%; background: #fff !important;
border: 1.5px solid #e0e3e8 !important;
box-shadow: 0 1px 2px rgba(0,0,0,0.03);
border-radius: 6px;
padding: 12px 16px;
margin-bottom: 0;
display: flex;
flex-direction: column;
min-width: 0; min-width: 0;
margin-bottom: 1rem;
} }
.form-group label { .form-group label {
display: block; color: #888;
margin-bottom: 0.5rem; font-size: 0.98rem;
margin-bottom: 4px;
font-weight: 500; font-weight: 500;
font-size: 0.9rem;
} }
.form-group input[type="date"], .form-group input[type="date"],
@ -824,7 +908,7 @@ export default {
font-weight: 400; font-weight: 400;
line-height: 1.5; line-height: 1.5;
color: #495057; color: #495057;
background-color: #fff; background-color: #fff !important;
background-clip: padding-box; background-clip: padding-box;
border: 1px solid #ced4da; border: 1px solid #ced4da;
border-radius: 0.25rem; border-radius: 0.25rem;
@ -870,34 +954,132 @@ export default {
} }
.form-value { .form-value {
padding: 8px 12px; color: #222;
background-color: #f8f9fa; font-size: 1.08rem;
border: 1px solid #e9ecef; font-weight: 500;
border-radius: 4px; background: transparent;
min-height: 38px; border: none;
min-height: 32px;
padding: 0;
} }
.photo-gallery { .photo-gallery {
display: grid; display: flex;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); flex-wrap: wrap;
gap: 10px; gap: 10px;
margin-top: 10px; background: #f8f9fa;
border-radius: 6px;
padding: 8px;
margin-top: 4px;
} }
.photo-item { .photo-preview {
position: relative; width: 64px;
padding-bottom: 100%; height: 64px;
overflow: hidden; object-fit: cover;
border-radius: 4px; border-radius: 4px;
border: 1px solid #e9ecef; border: 1.5px solid #eaeaea;
box-shadow: 0 1px 4px rgba(0,0,0,0.06);
cursor: pointer;
transition: transform 0.15s;
} }
.photo-preview { .photo-preview:hover {
position: absolute; transform: scale(1.08);
top: 0; box-shadow: 0 4px 16px rgba(0,0,0,0.13);
left: 0; }
.pagination-container {
display: flex;
justify-content: flex-end;
margin-top: 20px;
}
@media (max-width: 900px) {
.modal-dialog {
max-width: 98vw;
}
.modal-body {
padding: 1rem 0.5rem 1rem 0.5rem;
grid-template-columns: 1fr;
}
}
.modal-footer {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
padding: 0.75rem;
border-top: 1px solid #dee2e6;
border-bottom-right-radius: 12px;
border-bottom-left-radius: 12px;
gap: 0.5rem;
}
.image-preview-modal {
position: fixed;
z-index: 2000;
left: 0; top: 0; right: 0; bottom: 0;
background: rgba(0,0,0,0.7);
display: flex;
align-items: center;
justify-content: center;
}
.image-preview-large {
max-width: 90vw;
max-height: 90vh;
border-radius: 8px;
box-shadow: 0 4px 24px rgba(0,0,0,0.3);
background: #fff;
}
.sign-preview {
width: 100%; width: 100%;
height: 100%; max-width: 100%;
object-fit: cover; height: auto;
object-fit: contain;
border-radius: 4px;
border: 1.5px solid #eaeaea;
box-shadow: 0 1px 4px rgba(0,0,0,0.06);
margin-top: 4px;
cursor: pointer;
background: #fff;
}
/* 分割线 */
hr {
border: none;
border-top: 1.5px solid #e0e3e8;
margin: 16px 0;
}
.ivu-input, .ivu-select, .ivu-date-picker, .ivu-btn, .el-table {
border-color: #bfc8d6 !important;
background: #fff !important;
}
.ivu-btn-primary, .el-button--primary {
background: #2d8cf0 !important;
border-color: #2d8cf0 !important;
color: #fff !important;
}
/* 主色条 */
.modal-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
padding: 1.2rem 1.5rem;
background: #f5f7fa;
border-bottom: 1px solid #eaeaea;
border-radius: 12px 12px 0 0;
}
/* 分割线 */
hr {
border: none;
border-top: 1.5px solid #e0e3e8;
margin: 16px 0;
} }
</style> </style>

@ -483,7 +483,7 @@ export default {
'filter[1][key]': 'wuzileixing', 'filter[1][key]': 'wuzileixing',
'filter[1][op]': 'eq', 'filter[1][op]': 'eq',
'filter[1][value]': '一一码' 'filter[1][value]': '一一码'
}; };
const res = await request({ const res = await request({
url: '/api/admin/stocks-item/index', url: '/api/admin/stocks-item/index',

Loading…
Cancel
Save