This commit is contained in:
Zzc 2025-11-13 18:01:11 +08:00
commit 723e7ddf40
8 changed files with 338 additions and 149 deletions

View File

@ -153,9 +153,10 @@
:key="material.rid"
v-model="material.usageAmount"
type="number"
@input="checkMaterialAmount(material, index)"
:label="material.wzmc"
center
placeholder="请输入数量"
:placeholder="`余额: ${material.ye} `"
>
<template #extra>
<span style="margin-right: 10px">{{ material.dw }}</span>
@ -493,6 +494,7 @@ const addSelectedMaterials = () => {
wzmc: material.wzmc,
usageAmount: null,
dw: material.dw,
ye: material.ye,
});
}
});
@ -500,6 +502,18 @@ const addSelectedMaterials = () => {
checked.value = [];
};
//
const checkMaterialAmount = (material, index) => {
if (material.usageAmount > material.ye) {
showToast({
type: "fail",
message: "输入数量不能超过物资余额",
});
//
form.yhzMaterialList[index].usageAmount = material.ye;
}
};
//
const getMaterialList = async (wzmc) => {
try {

View File

@ -15,8 +15,8 @@
<slot></slot>
<template #footer>
<div class="dialog-footer">
<el-button @click="onCancel">取消</el-button>
<el-button type="primary" @click="onConfirm"> 确认 </el-button>
<el-button @click="onCancel"> {{ onCancelName }} </el-button>
<el-button type="primary" @click="onConfirm"> {{ onConfirmName }} </el-button>
</div>
</template>
</el-dialog>
@ -58,6 +58,14 @@ const props = defineProps({
type: Function,
default: () => {},
},
onConfirmName: {
type: String,
default: "确认",
},
onCancelName: {
type: String,
default: "取消",
}
});
const normalizedComponent = computed(() =>

View File

@ -0,0 +1,3 @@
import MyDrawer from './index.vue'
export default MyDrawer

View File

@ -0,0 +1,100 @@
<template>
<el-drawer
:visible.sync="visible"
:title="title"
:size="size"
:direction="direction"
destroy-on-close
>
<component
v-if="dynamicComponent"
:is="dynamicComponent"
ref="dynamicComponentRef"
v-bind="componentProps"
@vue:mounted="handleComponentMount"
/>
<template #footer>
<div class="drawer-footer">
<el-button @click="onCancel">取消</el-button>
<el-button type="primary" @click="onConfirm">确认</el-button>
</div>
</template>
</el-drawer>
</template>
<script setup>
import { computed, ref, markRaw } from "vue";
const dynamicComponentRef = ref(null);
defineExpose({
dynamicComponentRef,
});
const props = defineProps({
visible: {
type: Boolean,
default: false,
},
size: {
type: String,
default: "50%",
},
direction: {
type: String,
default: "rtl", // rtl/ltr/ttb/btt
validator: (v) => ["rtl", "ltr", "ttb", "btt"].includes(v),
},
title: {
type: String,
default: "",
},
dynamicComponent: {
type: [Object, Function],
default: null,
},
componentProps: {
type: Object,
default: () => ({}),
},
onConfirm: {
type: Function,
default: () => {},
},
onCancel: {
type: Function,
default: () => {},
},
});
const emit = defineEmits(["update:visible"]);
//
const normalizedComponent = computed(() =>
props.dynamicComponent ? markRaw(props.dynamicComponent) : null
);
//
const handleClose = () => {
emit("update:visible", false);
};
// /
const onConfirm = () => {
props.onConfirm();
handleClose();
};
const onCancel = () => {
props.onCancel();
handleClose();
};
</script>
<style scoped>
.drawer-footer {
display: flex;
justify-content: flex-end;
gap: 12px;
}
</style>

View File

@ -6,49 +6,49 @@
label-width="150px"
style="max-height: 60vh; overflow-y: auto; padding-right: 50px"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="物资名称:">
<el-input v-model="form.wzmc" />
</el-form-item>
<el-form-item label="入库日期:">
<el-date-picker
type="date"
placeholder="选择日期"
v-model="form.rkrq"
/>
</el-form-item>
<el-form-item label="入库单位:">
<el-input v-model="form.rkdw" />
</el-form-item>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="数量:">
<el-input-number v-model="form.sl" controls-position="right" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="单位:">
<el-input v-model="form.dw" />
</el-form-item>
</el-col>
</el-row>
</el-col>
<el-col :span="12">
<el-form-item label="存放地点:">
<el-input v-model="form.cfdd" />
</el-form-item>
<el-form-item label="负责人:">
<el-input v-model="form.fzr" />
</el-form-item>
<el-form-item label="联系电话:">
<el-input v-model="form.lxdh" />
</el-form-item>
<el-form-item label="区县名称:">
<el-input v-model="form.qxmc" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="所属服务站:">
<span>{{ yhzData.rawName }}</span>
</el-form-item>
<el-form-item label="物资名称:">
<el-input
maxlength="20"
show-word-limit
v-model="form.material.wzmc"
></el-input>
</el-form-item>
<el-form-item label="数量与单位:">
<el-row :gutter="20">
<el-col :span="16">
<el-input
v-model="form.material.sl"
type="number"
placeholder="请输入数量"
></el-input>
</el-col>
<el-col :span="8">
<el-select
v-model="form.material.dw"
filterable
allow-create
clearable
placeholder="选择单位"
>
<el-option label="个" value="个"></el-option>
<el-option label="包" value="包"></el-option>
<el-option label="盒" value="盒"></el-option>
<el-option label="桶" value="桶"></el-option>
<el-option label="箱" value="箱"></el-option>
<el-option label="袋" value="袋"></el-option>
</el-select>
</el-col>
</el-row>
</el-form-item>
<el-form-item label="设备经度:">
<span>{{ yhzData.jd }}</span>
</el-form-item>
<el-form-item label="设备纬度:">
<span>{{ yhzData.wd }}</span>
</el-form-item>
</el-form>
</div>
</template>
@ -59,7 +59,7 @@ const formRef = ref(null);
defineExpose({ formRef });
const props = defineProps({
detailData: {
yhzData: {
type: Object,
default: () => ({}),
},

View File

@ -1,52 +1,68 @@
<template>
<div class="detail-container">
<el-form
label-position="right"
label-width="150px"
style="max-height: 60vh; overflow-y: auto; padding-right: 50px"
>
<el-card shadow="hover">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="物资名称:">
<el-input disabled v-model="detailData.wzmc" />
</el-form-item>
<el-form-item label="余量:">
<el-input disabled v-model="detailData.ye" />
</el-form-item>
<el-form-item label="入库日期:">
<el-input disabled v-model="detailData.rkrq" />
</el-form-item>
<el-form-item label="入库单位:">
<el-input disabled v-model="detailData.rkdw" />
</el-form-item>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="数量:">
<el-input disabled v-model="detailData.sl"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="单位:">
<el-input disabled v-model="detailData.dw" /> </el-form-item
></el-col>
</el-row>
<el-descriptions title="基础信息" column="1">
<el-descriptions-item label="物资名称: ">{{
detailData.material?.wzmc
}}</el-descriptions-item>
<el-descriptions-item label="余量: ">{{
detailData.material?.ye + ' ' + detailData.material?.dw
}}</el-descriptions-item>
<el-descriptions-item label="所属服务站: ">{{
detailData.material?.yhzMc
}}</el-descriptions-item>
<el-descriptions-item label="备注: ">{{
detailData.material?.remark
}}</el-descriptions-item>
</el-descriptions>
</el-col>
<el-col :span="12">
<el-form-item label="存放地点:">
<el-input disabled v-model="detailData.cfdd" />
</el-form-item>
<el-form-item label="负责人:">
<el-input disabled v-model="detailData.fzr" />
</el-form-item>
<el-form-item label="联系电话:">
<el-input disabled v-model="detailData.lxdh" />
</el-form-item>
<el-form-item label="区县名称:">
<el-input disabled v-model="detailData.qxmc" />
</el-form-item>
<el-col :span="12" style="position: relative">
<el-image
style="
max-width: 180px;
max-height: 180px;
position: absolute;
right: 0;
"
:src="detailData.photos[0]?.photoUrl"
:zoom-rate="1.2"
:max-scale="7"
:min-scale="0.2"
:preview-src-list="detailData.photos?.map((item) => item.photoUrl)"
show-progresss
fit="cover"
/>
</el-col>
</el-row>
</el-form>
</el-card>
<el-card shadow="hover">
<el-descriptions title="物资位置信息" column="3">
<el-descriptions-item label="区县名称: ">{{
detailData.material?.qxmc
}}</el-descriptions-item>
<el-descriptions-item label="物资经度: ">{{
detailData.material?.jd
}}</el-descriptions-item>
<el-descriptions-item label="物资纬度: ">{{
detailData.material?.wd
}}</el-descriptions-item>
</el-descriptions>
</el-card>
<el-card shadow="hover">
<el-descriptions title="物资管理情况" column="3">
<el-descriptions-item label="负责人: ">{{
detailData.material?.fzr
}}</el-descriptions-item>
<el-descriptions-item label="入库人: ">{{
detailData.material?.rkrName
}}</el-descriptions-item>
<el-descriptions-item label="入库日期: ">{{
detailData.material?.rkrq?.slice(0, 10)
}}</el-descriptions-item>
</el-descriptions>
</el-card>
</div>
</template>
@ -60,4 +76,9 @@ const props = defineProps({
</script>
<style>
.detail-container {
display: flex;
flex-direction: column;
gap: 30px;
}
</style>

View File

@ -16,6 +16,7 @@ const filterText = ref(''); // 树节点过滤条件
const tableData = ref([]);
const qxmc = ref(''); // 区县名称
const yhzid = ref(''); // 养护站id
const yhzData = ref(); // 养护站信息
const filterData = reactive({
wzmc: '',
}); // 表格过滤条件
@ -42,22 +43,53 @@ const model = reactive({
const dialogType = ref(''); // 弹窗类型
const dialogRef = ref(null); // 弹窗实例
const drawerVisible = ref(false); // 抽屉显示状态
const drawer = reactive({
title: '',
content: null,
props: {},
onCancel: null,
onConfirm: null,
direction: 'rtl',
size: '50%'
}); // 抽屉内容
const drawerType = ref(''); // 抽屉类型
const drawerRef = ref(null); // 抽屉实例
const INIT_FORM = {
rkrq: "",
rkdw: "",
sl: "",
dw: "",
cfdd: "",
fzr: "",
lxdh: "",
ye: "",
qxmc: "",
wzmc: "",
fzrid: "",
yhzid: "",
material: {
rkrq: "",
rkdw: "",
sl: "",
dw: "",
cfdd: "",
fzr: "",
lxdh: "",
ye: "",
qxmc: "",
wzmc: "",
fzrid: "",
yhzid: "",
jd: "",
wd: "",
},
photos: [],
}; // 表单初始值
const form = reactive({ ...INIT_FORM }); // 表单
// 重置表单方法
const resetForm = () => {
// 深拷贝重置嵌套对象
form.material = { ...INIT_FORM.material };
form.photos = [...INIT_FORM.photos];
form.material.yhzid = yhzid.value;
form.material.jd = yhzData.value?.jd;
form.material.wd = yhzData.value?.wd;
};
// 节点过滤函数
@ -96,7 +128,10 @@ const getTreeData = async () => {
children: qx.yhzList.map(site => ({
id: site.id,
name: `${site.mc}(${site.wzsl})`,
type: 'site'
type: 'site',
rawName: site.mc, // 原始名称
jd: site.jd,
wd: site.wd,
})),
rawName: qx.qxmc, // 原始名称
})
@ -116,18 +151,21 @@ const handleNodeClick = (data, node) => {
if (data.type === 'area' && node.expanded === false) {
console.log('树节点关闭', node.expanded)
yhzid.value = ''; // 重置养护站id
yhzData.value = null; // 重置养护站信息
qxmc.value = ''; // 重置区县名称
return;
}
if (data.type === 'area') {
console.log('你点击的是区县', data.id)
yhzid.value = ''; // 重置养护站id
yhzData.value = null; // 重置养护站信息
qxmc.value = data.id; // 保存区县名称
}
if (data.type === 'site') {
console.log('你点击的是站点', data.name)
yhzid.value = data.id; // 保存养护站id
yhzData.value = data; // 保存养护站信息
qxmc.value = ''; // 重置区县名称
}
};
@ -170,37 +208,25 @@ const columns = [
prop: 'ye',
label: '余量',
},
{
prop: 'rkdw',
label: '入库单位',
},
{
prop: 'rkrq',
label: '入库日期',
},
{
prop: 'sl',
label: '数量',
},
{
prop: 'dw',
label: '单位',
},
{
prop: 'cfdd',
label: '存放地点',
},
{
prop: 'fzr',
label: '负责人',
},
{
prop: 'lxdh',
label: '联系电话',
prop: 'rkrName',
label: '入库人',
},
{
prop: 'qxmc',
label: '所属区县',
prop: 'rkrq',
label: '入库日期',
},
{
prop: 'yhzMc',
label: '所属服务站',
},
{
label: "操作",
@ -220,18 +246,18 @@ const columns = [
},
() => "详情"
),
h(
ElButton,
{
type: "primary",
link: true,
onClick: async () => {
dialogType.value = 'edit'
await getDetailData(row);
},
},
() => "编辑"
),
// h(
// ElButton,
// {
// type: "primary",
// link: true,
// onClick: async () => {
// dialogType.value = 'edit'
// await getDetailData(row);
// },
// },
// () => "编辑"
// ),
h(
ElButton,
{
@ -305,20 +331,20 @@ const getDetailData = async (row) => {
}
if (res.code === '00000') {
if (dialogType.value === 'detail') {
model.title = `物资详情`;
model.content = DetailDialog;
model.props = {
detailData: res.data.material,
drawer.title = `物资详情`;
drawer.content = DetailDialog;
drawer.props = {
detailData: res.data,
};
model.onCancel = () => {
drawer.onCancel = () => {
dialogType.value = '';
modelVisible.value = false;
drawerVisible.value = false;
};
model.onConfirm = () => {
drawer.onConfirm = () => {
dialogType.value = '';
modelVisible.value = false;
drawerVisible.value = false;
};
modelVisible.value = true;
drawerVisible.value = true;
}
if (dialogType.value === 'edit') {
model.title = `编辑物资`;
@ -352,9 +378,9 @@ const getDetailData = async (row) => {
const openAddModel = () => {
model.title = `新增物资`;
model.content = AddDialog;
Object.assign(form, INIT_FORM);
resetForm(); // 重置表单
model.props = {
detailData: {},
yhzData: yhzData.value,
form: form,
};
model.onCancel = () => {
@ -382,6 +408,7 @@ const openAddModel = () => {
console.log('error', error)
}
};
model.width = '40%';
modelVisible.value = true;
}
@ -441,7 +468,7 @@ export default () => {
await getTreeData();
await getyhzwzList();
const rowData = (decodeURIComponent(route.params?.data));
if (rowData !== 'undefined' && rowData!== 'null' && rowData !== '' ) {
if (rowData !== 'undefined' && rowData !== 'null' && rowData !== '') {
const JSONData = JSON.parse(rowData);
filterText.value = JSONData.mc;
};
@ -462,5 +489,9 @@ export default () => {
dialogRef,
model,
openAddModel,
drawerVisible,
drawer,
drawerRef,
yhzid,
}
}

View File

@ -28,7 +28,7 @@
</div>
<div class="form-box">
<div class="event-box">
<el-button type="primary" size="large" @click="script.openAddModel"
<el-button v-if="script.yhzid.value" type="primary" size="large" @click="script.openAddModel"
>新增物资</el-button
>
<el-button type="info" size="large" @click="script.handelExport"
@ -54,9 +54,20 @@
:onConfirm="script.model?.onConfirm"
:onCancel="script.model?.onCancel"
ref="dialogRef"
width="60%"
:width="script.model?.width"
>
</MyDialog>
<MyDrawer
v-model="script.drawerVisible.value"
:title="script.drawer?.title"
:dynamicComponent="script.drawer?.content"
:component-props="script.drawer?.props"
:onConfirm="script.drawer?.onConfirm"
:onCancel="script.drawer?.onCancel"
ref="drawerRef"
:direction="script.drawer?.direction"
:size="script.drawer?.size"
></MyDrawer>
</div>
</div>
</template>
@ -65,9 +76,10 @@
import scriptFn from "./index.js";
import DynamicTable from "../../component/DynamicTable";
import MyDialog from "../../component/MyDialog";
import MyDrawer from "../../component/MyDrawer/index.js";
const script = scriptFn();
const { treeRef, dialogRef } = script;
const { treeRef, dialogRef, drawerRef } = script;
</script>
<style scoped>
.root {