Jelajahi Sumber

feat: 协同办公特瑞增加自定义需求

liujt 16 jam lalu
induk
melakukan
99fdea8cd3

+ 342 - 0
src/BIZComponents/processSubmitDialog/components/applicationComponent.vue

@@ -0,0 +1,342 @@
+<template>
+    <div>
+        <el-table
+            :data="tableData"
+            style="width: 100%"
+            size="mini"
+            border>
+            <el-table-column
+                prop="productName"
+                align="center"
+                label="产品名称">
+                <template slot="header" slot-scope="scope">
+                    <div><span class="required">*</span>产品名称</div>
+                </template>
+            </el-table-column>
+            <el-table-column
+                prop="quantity"
+                align="center"
+                label="数量">
+                <template slot="header" slot-scope="scope">
+                    <div><span class="required">*</span>数量</div>
+                </template>
+            </el-table-column>
+            <el-table-column
+                prop="specification"
+                align="center"
+                label="规格型号">
+                <template slot="header" slot-scope="scope">
+                    <div><span class="required">*</span>规格型号</div>
+                </template>
+            </el-table-column>
+            <el-table-column
+                label="操作"
+                align="center"
+                width="90"
+                 v-if="!view">
+                <template slot-scope="scope">
+                    <el-button @click="editRow(scope.row, scope.$index)" type="text" size="mini">编辑</el-button>
+                    <el-button @click="deleteRow(scope.$index)" type="text" size="mini">删除</el-button>
+                </template>
+                </el-table-column>
+        </el-table>
+        <div v-if="!view" @click="addRow" style="text-align: center;">
+            <el-button type="text" icon="el-icon-plus">添加</el-button>
+        </div>
+        <ele-modal
+            title="明细"
+            custom-class="ele-dialog-form long-dialog-form"
+            :visible.sync="visible"
+            :before-close="handleClose"
+            :close-on-click-modal="false"
+            top="5vh"
+            :close-on-press-escape="false"
+            append-to-body
+            width="70%"
+            :maxable="true"
+            destroy-on-close
+        >
+            <el-card shadow="never">
+                <el-form ref="form" :model="form">
+                    <el-form-item
+                        label="产品名称"
+                        label-width="110px"
+                        prop="productName"
+                        :rules="{
+                            required: true,
+                            message: '请选择产品名称',
+                            trigger: 'change'
+                        }"
+                    >
+                        <el-select
+                            v-model="form.productName"
+                            placeholder="请选择"
+                            style="width: 100%"
+                        >
+                            <el-option
+                                v-for="item in productNameList"
+                                :key="item.value"
+                                :label="item.label"
+                                :value="item.value"
+                            >
+                            </el-option>
+                        </el-select>
+                    </el-form-item>
+        
+                    <el-form-item
+                        label="数量"
+                        label-width="110px"
+                        prop="quantity"
+                        :rules="{
+                            required: true,
+                            message: '请输入数量',
+                            trigger: 'change'
+                        }"
+                    >
+                        <el-input
+                            v-model="form.quantity"
+                            type="number"
+                            placeholder="请输入"
+                        ></el-input>
+                    </el-form-item>
+                    <el-form-item 
+                        label="规格型号" 
+                        label-width="110px" 
+                        prop="specification"
+                        :rules="{
+                                required: true,
+                                message: '请输入规格型号',
+                                trigger: 'change'
+                            }"
+                    >
+                        <el-input
+                            v-model="form.specification"
+                            placeholder="请输入"
+                        ></el-input>
+                    </el-form-item>
+                </el-form>
+            </el-card>
+
+            <div slot="footer">
+                <el-button type="primary" size="small" @click="save">保存</el-button>
+                <el-button size="small" @click="handleClose">关闭</el-button>
+            </div>
+        </ele-modal>
+    </div>
+</template>
+<script>
+export default {
+    props: {
+        info: {
+            type: Object,
+            default: () => {}
+        },
+        generateForm: {
+            type: Object,
+            default: () => {}
+        },
+        id: {
+            type: String,
+            default: ''
+        },
+        view: {
+            type: Boolean,
+            default: false
+        },
+    },
+    watch: {
+        info: {
+            handler(newVal, oldVal) {
+                console.log('info', newVal);
+                this.tableData = newVal[this.id] || [];
+            },
+            deep: true,
+            immediate: true
+        },
+    },
+    data() {
+        const formItem = {
+            productName: '',
+            quantity: '',
+            specification: ''
+        }
+        return {
+            form: {},
+            formItem,
+            tableData: [],
+            visible: false,
+            currentItem: {},
+            currentIndex: null,
+            type: 'add',
+            productNameList: [
+                {
+                    value: '一次性使用刀头',
+                    label: '一次性使用刀头'
+                },
+                {
+                    value: '一次性使用多功能引流管',
+                    label: '一次性使用多功能引流管'
+                },
+                {
+                    value: '强光手电筒+变径接头',
+                    label: '强光手电筒+变径接头'
+                },
+                {
+                    value: '手电筒充电器',
+                    label: '手电筒充电器'
+                },
+                {
+                    value: '医用冷敷贴疼痛型',
+                    label: '医用冷敷贴疼痛型'
+                },
+                {
+                    value: '医用冷敷凝胶防脱育发型',
+                    label: '医用冷敷凝胶防脱育发型'
+                },
+                {
+                    value: '医用冷敷凝胶痔疮型',
+                    label: '医用冷敷凝胶痔疮型'
+                },
+                {
+                    value: '医用冷敷凝胶皮肤瘙痒型',
+                    label: '医用冷敷凝胶皮肤瘙痒型'
+                },
+                {
+                    value: '医用透明质酸钠修复贴',
+                    label: '医用透明质酸钠修复贴'
+                },
+                {
+                    value: '医用透明质酸钠修复贴(灰色修复线下款)',
+                    label: '医用透明质酸钠修复贴(灰色修复线下款)'
+                },
+                {
+                    value: '医用透明质酸钠修复贴(黄色祛痘线下款)',
+                    label: '医用透明质酸钠修复贴(黄色祛痘线下款)'
+                },
+                {
+                    value: '医用透明质酸钠修复贴(绿色修复线上款)',
+                    label: '医用透明质酸钠修复贴(绿色修复线上款)'
+                },
+                {
+                    value: '医用透明质酸钠修复贴(绿色祛痘线上款)',
+                    label: '医用透明质酸钠修复贴(绿色祛痘线上款)'
+                },
+                {
+                    value: '一次性射频等离子手术电极',
+                    label: '一次性射频等离子手术电极'
+                },
+                {
+                    value: '一次性冲冼吸引器',
+                    label: '一次性冲冼吸引器'
+                },
+                {
+                    value: '三位放疗定位器',
+                    label: '三位放疗定位器'
+                },
+                {
+                    value: '一次性使用胃管',
+                    label: '一次性使用胃管'
+                },
+                {
+                    value: '笔记本套装',
+                    label: '笔记本套装'
+                }
+            ],
+        }
+    },
+    mounted() {
+        // console.log('info~~~', this.info);
+        // this.initForm();
+    },
+    methods: {
+        async updateRowInfo() {
+            let data = await this.generateForm.getData(false);
+            this.generateForm.setData({
+                [this.id]: this.tableData
+            });
+            console.log('updateRowInfo', this.tableData, data);
+        },
+        validateForm() {
+            //开始表单校验
+            return new Promise((resolve, reject) => {
+                this.$refs.form.validate((valid) => {
+                    if (!valid) {
+                        reject(false);
+                    } else {
+                        resolve(true);
+                    }
+                });
+            });
+        },
+        addRow() {
+            this.type = 'add';
+            this.form = JSON.parse(JSON.stringify(this.formItem));
+            this.visible = true;
+
+        },
+        handleClose() {
+            this.visible = false;
+        },
+        editRow(row, index) {
+            this.type = 'edit';
+            console.log('编辑行', row, index);
+            this.currentItem = row;
+            this.currentIndex = index;
+            this.visible = true;
+            this.form = JSON.parse(JSON.stringify(row));
+        },
+        deleteRow(index) {
+            this.tableData.splice(index, 1);
+            this.updateRowInfo();
+        },
+        async save() {
+            try {
+                await this.validateForm();
+                console.log('表单验证通过');
+                // 深拷贝form对象,避免引用问题
+                const newForm = JSON.parse(JSON.stringify(this.form));
+                console.log('newForm', newForm);
+                if(this.type === 'add') {
+                    this.tableData.push(newForm);
+                } else {
+                    this.tableData[this.currentIndex] = newForm;
+                }
+                console.log('this.tableData', this.tableData);
+                this.updateRowInfo()
+                this.handleClose(); // 保存后关闭弹窗
+                // 重置form
+                // this.form = {};
+            } catch (error) {
+                console.log('表单验证失败', error);
+            }
+        }
+    }
+}
+</script>
+<style scoped>
+.header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    width: 100%;
+}
+.blank_business_component {
+    display: flex;
+    align-items: center;
+    margin-bottom: 10px;
+}
+.label {
+    width: 80px;
+}
+.value {
+    flex: 1;
+    width: calc(100% - 80px);
+}
+:deep(.el-form-box .el-table .el-table__row .el-table__cell .cell) {
+    padding-left: 10px;
+    padding-right: 10px;
+}
+.required {
+    color: red;
+}
+</style>

+ 433 - 0
src/BIZComponents/processSubmitDialog/components/businessTripComponent.vue

@@ -0,0 +1,433 @@
+<template>
+    <div>
+        <el-table
+            :data="tableData"
+            style="width: 100%"
+            size="mini"
+            border>
+            <el-table-column
+                prop="transportation"
+                align="center"
+                label="交通工具">
+                <template slot="header" slot-scope="scope">
+                    <div><span class="required">*</span>交通工具</div>
+                </template>
+            </el-table-column>
+            <el-table-column
+                prop="isRoundTrip"
+                align="center"
+                label="单程往返">
+                <template slot="header" slot-scope="scope">
+                    <div><span class="required">*</span>单程往返</div>
+                </template>
+            </el-table-column>
+            <el-table-column
+                prop="departureCity"
+                align="center"
+                label="出发城市">
+                <template slot="header" slot-scope="scope">
+                    <div><span class="required">*</span>出发城市</div>
+                </template>
+            </el-table-column>
+            <el-table-column
+                prop="destinationCity"
+                align="center"
+                label="目的城市">
+                <template slot="header" slot-scope="scope">
+                    <div><span class="required">*</span>目的城市</div>
+                </template>
+            </el-table-column>
+            <el-table-column
+                prop="startTime"
+                align="center"
+                label="开始时间">
+                <template slot="header" slot-scope="scope">
+                    <div><span class="required">*</span>开始时间</div>
+                </template>
+            </el-table-column>
+            <el-table-column
+                prop="endTime"
+                align="center"
+                label="结束时间">
+                <template slot="header" slot-scope="scope">
+                    <div><span class="required">*</span>结束时间</div>
+                </template>
+            </el-table-column>
+            <el-table-column
+                prop="duration"
+                align="center"
+                label="时长">
+                <template slot="header" slot-scope="scope">
+                    <div><span class="required">*</span>时长</div>
+                </template>
+            </el-table-column>
+            <el-table-column
+                label="操作"
+                align="center"
+                width="90"
+                 v-if="!view">
+                <template slot-scope="scope">
+                    <el-button @click="editRow(scope.row, scope.$index)" type="text" size="mini">编辑</el-button>
+                    <el-button @click="deleteRow(scope.$index)" type="text" size="mini">删除</el-button>
+                </template>
+                </el-table-column>
+        </el-table>
+        <div v-if="!view" style="text-align: center;">
+            <el-button type="text" icon="el-icon-plus" @click="addRow">添加</el-button>
+        </div>
+        <ele-modal
+            title="明细"
+            custom-class="ele-dialog-form long-dialog-form"
+            :visible.sync="visible"
+            :before-close="handleClose"
+            :close-on-click-modal="false"
+            top="5vh"
+            :close-on-press-escape="false"
+            append-to-body
+            width="70%"
+            :maxable="true"
+            destroy-on-close
+        >
+            <el-card shadow="never">
+                <el-form ref="form" :model="form">
+                    <el-form-item
+                        label="交通工具"
+                        label-width="110px"
+                        prop="transportation"
+                        :rules="{
+                            required: true,
+                            message: '请输入交通工具',
+                            trigger: 'change'
+                        }"
+                    >
+                        <el-input
+                            v-model="form.transportation"
+                            placeholder="请输入"
+                        ></el-input>
+                    </el-form-item>
+        
+                    <el-form-item
+                        label="单程往返"
+                        label-width="110px"
+                        prop="isRoundTrip"
+                        :rules="{
+                            required: true,
+                            message: '请输入单程往返',
+                            trigger: 'change'
+                        }"
+                    >
+                        <el-input
+                            v-model="form.isRoundTrip"
+                            placeholder="请输入"
+                        ></el-input>
+                    </el-form-item>
+                    <el-form-item 
+                        label="出发城市" 
+                        label-width="110px" 
+                        prop="departureCity"
+                        :rules="{
+                                required: true,
+                                message: '请输入出发城市',
+                                trigger: 'change'
+                            }"
+                    >
+                        <el-input
+                            v-model="form.departureCity"
+                            placeholder="请输入"
+                        ></el-input>
+                    </el-form-item>
+                    <el-form-item 
+                        label="目的城市" 
+                        label-width="110px" 
+                        prop="destinationCity"
+                        :rules="{
+                                required: true,
+                                message: '请输入目的城市',
+                                trigger: 'change'
+                            }"
+                    >
+                        <el-input
+                            v-model="form.destinationCity"
+                            placeholder="请输入"
+                        ></el-input>
+                    </el-form-item>
+                    <el-form-item 
+                        label="开始时间" 
+                        label-width="110px" 
+                        prop="startTime"
+                        :rules="{
+                                required: true,
+                                message: '请输入开始时间',
+                                trigger: 'change'
+                            }"
+                    >
+                        <el-date-picker
+                            style="width: 100%"
+                            v-model="form.startTime"
+                            value-format="yyyy-MM-dd HH:mm:ss"
+                            type="datetime"
+                            placeholder="选择日期"
+                        >
+                        </el-date-picker>
+                    </el-form-item>
+                    <el-form-item 
+                        label="结束时间" 
+                        label-width="110px" 
+                        prop="endTime"
+                        :rules="{
+                                required: true,
+                                message: '请输入结束时间',
+                                trigger: 'change'
+                            }"
+                    >
+                        <el-date-picker
+                            style="width: 100%"
+                            v-model="form.endTime"
+                            value-format="yyyy-MM-dd HH:mm:ss"
+                            type="datetime"
+                            placeholder="选择日期"
+                        >
+                        </el-date-picker>
+                    </el-form-item>
+                    <el-form-item 
+                        label="时长" 
+                        label-width="110px" 
+                        prop="duration"
+                        :rules="{
+                                required: true,
+                                message: '请选择开始/结束时间',
+                                trigger: 'change'
+                            }"
+                    >
+                        <el-input
+                            v-model="form.duration"
+                            placeholder="自动计算"
+                            disabled
+                        ></el-input>
+                    </el-form-item>
+                </el-form>
+            </el-card>
+
+            <div slot="footer">
+                <el-button type="primary" size="small" @click="save">保存</el-button>
+                <el-button size="small" @click="handleClose">关闭</el-button>
+            </div>
+        </ele-modal>
+    </div>
+</template>
+<script>
+export default {
+    props: {
+        info: {
+            type: Object,
+            default: () => {}
+        },
+        generateForm: {
+            type: Object,
+            default: () => {}
+        },
+        id: {
+            type: String,
+            default: ''
+        },
+        view: {
+            type: Boolean,
+            default: false
+        },
+    },
+    watch: {
+        info: {
+            handler(newVal, oldVal) {
+                console.log('info', newVal);
+                this.tableData = newVal[this.id] || [];
+            },
+            deep: true,
+            immediate: true
+        },
+        // 监听开始/结束时间自动计算时长
+        'form.startTime': {
+            handler() {
+                this.calcDuration();
+            }
+        },
+        'form.endTime': {
+            handler() {
+                this.calcDuration();
+            }
+        }
+    },
+    data() {
+        const formItem = {
+            productName: '',
+            quantity: '',
+            specification: ''
+        }
+        return {
+            form: {},
+            formItem,
+            tableData: [],
+            visible: false,
+            currentItem: {},
+            currentIndex: null,
+            type: 'add'
+        }
+    },
+    mounted() {
+        // console.log('info~~~', this.info);
+        // this.initForm();
+    },
+    methods: {
+        async updateRowInfo() {
+            let data = await this.generateForm.getData(false);
+            this.generateForm.setData({
+                [this.id]: this.tableData
+            });
+            console.log('updateRowInfo', this.tableData, data);
+        },
+        validateForm() {
+            //开始表单校验
+            return new Promise((resolve, reject) => {
+                this.$refs.form.validate((valid) => {
+                    if (!valid) {
+                        reject(false);
+                    } else {
+                        resolve(true);
+                    }
+                });
+            });
+        },
+        // 根据开始/结束时间自动计算时长
+        calcDuration() {
+            if (this.form.startTime && this.form.endTime) {
+                const start = new Date(this.form.startTime).getTime();
+                const end = new Date(this.form.endTime).getTime();
+                if (isNaN(start) || isNaN(end) || end <= start) {
+                    this.form.duration = '';
+                    return;
+                }
+                const diff = Math.floor((end - start) / 1000); // 秒差
+                const days = Math.floor(diff / 86400);
+                const hours = Math.floor((diff % 86400) / 3600);
+                const minutes = Math.floor((diff % 3600) / 60);
+                const seconds = diff % 60;
+
+                const parts = [];
+                if (days > 0) parts.push(`${days}天`);
+                if (hours > 0) parts.push(`${hours}时`);
+                if (minutes > 0) parts.push(`${minutes}分`);
+                if (seconds > 0) parts.push(`${seconds}秒`);
+                this.form.duration = parts.join('');
+            }
+        },
+        // 将 "X天X时X分X秒" 解析为总秒数
+        parseDurationToSeconds(duration) {
+            if (!duration) return 0;
+            const match = {
+                days: duration.match(/(\d+)天/),
+                hours: duration.match(/(\d+)时/),
+                minutes: duration.match(/(\d+)分/),
+                seconds: duration.match(/(\d+)秒/)
+            };
+            return (
+                (parseInt(match.days?.[1]) || 0) * 86400 +
+                (parseInt(match.hours?.[1]) || 0) * 3600 +
+                (parseInt(match.minutes?.[1]) || 0) * 60 +
+                (parseInt(match.seconds?.[1]) || 0)
+            );
+        },
+        // 计算多行时长累加,赋值给 input_if1cav3p
+        async calculateTotalDays() {
+            let totalSeconds = 0;
+            this.tableData.forEach((item) => {
+                totalSeconds += this.parseDurationToSeconds(item.duration);
+            });
+            // 转换回 "X天X时X分X秒" 格式
+            const days = Math.floor(totalSeconds / 86400);
+            const hours = Math.floor((totalSeconds % 86400) / 3600);
+            const minutes = Math.floor((totalSeconds % 3600) / 60);
+            const seconds = totalSeconds % 60;
+            const parts = [];
+            if (days > 0) parts.push(`${days}天`);
+            if (hours > 0) parts.push(`${hours}时`);
+            if (minutes > 0) parts.push(`${minutes}分`);
+            if (seconds > 0 || parts.length === 0) parts.push(`${seconds}秒`);
+            const totalDuration = parts.join('');
+
+            this.generateForm.setData({
+                input_if1cav3p: totalDuration
+            });
+        },
+        addRow() {
+            this.type = 'add';
+            this.form = JSON.parse(JSON.stringify(this.formItem));
+            this.visible = true;
+
+        },
+        handleClose() {
+            this.visible = false;
+        },
+        editRow(row, index) {
+            this.type = 'edit';
+            console.log('编辑行', row, index);
+            this.currentItem = row;
+            this.currentIndex = index;
+            this.visible = true;
+            this.form = JSON.parse(JSON.stringify(row));
+        },
+        deleteRow(index) {
+            this.tableData.splice(index, 1);
+            this.updateRowInfo();
+            this.calculateTotalDays();
+        },
+        async save() {
+            try {
+                await this.validateForm();
+                console.log('表单验证通过');
+                // 深拷贝form对象,避免引用问题
+                const newForm = JSON.parse(JSON.stringify(this.form));
+                console.log('newForm', newForm);
+                if(this.type === 'add') {
+                    this.tableData.push(newForm);
+                } else {
+                    this.tableData[this.currentIndex] = newForm;
+                }
+                console.log('this.tableData', this.tableData);
+                this.updateRowInfo()
+                this.calculateTotalDays();
+                this.handleClose(); // 保存后关闭弹窗
+                // 重置form
+                // this.form = {};
+            } catch (error) {
+                console.log('表单验证失败', error);
+            }
+        }
+    }
+}
+</script>
+<style scoped>
+.header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    width: 100%;
+}
+.blank_business_component {
+    display: flex;
+    align-items: center;
+    margin-bottom: 10px;
+}
+.label {
+    width: 80px;
+}
+.value {
+    flex: 1;
+    width: calc(100% - 80px);
+}
+:deep(.el-form-box .el-table .el-table__row .el-table__cell .cell) {
+    padding-left: 10px;
+    padding-right: 10px;
+}
+.required {
+    color: red;
+}
+</style>

+ 357 - 0
src/BIZComponents/processSubmitDialog/components/purchaseRequisitionComponent.vue

@@ -0,0 +1,357 @@
+<template>
+    <div>
+        <el-table
+            :data="tableData"
+            style="width: 100%"
+            size="mini"
+            border>
+            <el-table-column
+                prop="materialName"
+                align="center"
+                label="物料名称">
+                <template slot="header" slot-scope="scope">
+                    <div><span class="required">*</span>物料名称</div>
+                </template>
+            </el-table-column>
+            <el-table-column
+                prop="specification"
+                align="center"
+                label="规格型号">
+                <template slot="header" slot-scope="scope">
+                    <div><span class="required">*</span>规格型号</div>
+                </template>
+            </el-table-column>
+            <el-table-column
+                prop="unit"
+                align="center"
+                label="单位">
+                <template slot="header" slot-scope="scope">
+                    <div><span class="required">*</span>单位</div>
+                </template>
+            </el-table-column>
+            <el-table-column
+                prop="quantity"
+                align="center"
+                label="数量">
+                <template slot="header" slot-scope="scope">
+                    <div><span class="required">*</span>数量</div>
+                </template>
+            </el-table-column>
+            <el-table-column
+                prop="purpose"
+                align="center"
+                label="用途">
+                <template slot="header" slot-scope="scope">
+                    <div><span class="required">*</span>用途</div>
+                </template>
+            </el-table-column>
+            <el-table-column
+                prop="expectedDeliveryDate"
+                align="center"
+                label="期望交付日期">
+                <!-- <template slot="header" slot-scope="scope">
+                    <div><span class="required">*</span>期望交付日期</div>
+                </template> -->
+            </el-table-column>
+            <el-table-column
+                prop="remark"
+                align="center"
+                label="备注">
+                <!-- <template slot="header" slot-scope="scope">
+                    <div><span class="required">*</span>备注</div>
+                </template> -->
+            </el-table-column>
+            <el-table-column
+                label="操作"
+                align="center"
+                width="90"
+                 v-if="!view">
+                <template slot-scope="scope">
+                    <el-button @click="editRow(scope.row, scope.$index)" type="text" size="mini">编辑</el-button>
+                    <el-button @click="deleteRow(scope.$index)" type="text" size="mini">删除</el-button>
+                </template>
+                </el-table-column>
+        </el-table>
+        <div v-if="!view" @click="addRow" style="text-align: center;">
+            <el-button type="text" icon="el-icon-plus">添加</el-button>
+        </div>
+        <ele-modal
+            title="明细"
+            custom-class="ele-dialog-form long-dialog-form"
+            :visible.sync="visible"
+            :before-close="handleClose"
+            :close-on-click-modal="false"
+            top="5vh"
+            :close-on-press-escape="false"
+            append-to-body
+            width="70%"
+            :maxable="true"
+            destroy-on-close
+        >
+            <el-card shadow="never">
+                <el-form ref="form" :model="form">
+                    <el-form-item
+                        label="物料名称"
+                        label-width="110px"
+                        prop="materialName"
+                        :rules="{
+                            required: true,
+                            message: '请输入物料名称',
+                            trigger: 'change'
+                        }"
+                    >
+                        <el-input
+                            v-model="form.materialName"
+                            placeholder="请输入"
+                        ></el-input>
+                    </el-form-item>
+        
+                    <el-form-item
+                        label="规格型号"
+                        label-width="110px"
+                        prop="specification"
+                        :rules="{
+                            required: true,
+                            message: '请输入规格型号',
+                            trigger: 'change'
+                        }"
+                    >
+                        <el-input
+                            v-model="form.specification"
+                            placeholder="请输入"
+                        ></el-input>
+                    </el-form-item>
+                    <el-form-item 
+                        label="单位" 
+                        label-width="110px" 
+                        prop="unit"
+                        :rules="{
+                                required: true,
+                                message: '请输入单位',
+                                trigger: 'change'
+                            }"
+                    >
+                        <el-input
+                            v-model="form.unit"
+                            placeholder="请输入"
+                        ></el-input>
+                    </el-form-item>
+                    <el-form-item 
+                        label="数量" 
+                        label-width="110px" 
+                        prop="quantity"
+                        :rules="{
+                                required: true,
+                                message: '请输入数量',
+                                trigger: 'change'
+                            }"
+                    >
+                        <el-input
+                            v-model="form.quantity"
+                            type="number"
+                            placeholder="请输入"
+                        ></el-input>
+                    </el-form-item>
+                    <el-form-item 
+                        label="用途" 
+                        label-width="110px" 
+                        prop="purpose"
+                        :rules="{
+                                required: true,
+                                message: '请输入用途',
+                                trigger: 'change'
+                            }"
+                    >
+                        <el-input
+                            v-model="form.purpose"
+                            type="textarea"
+                            placeholder="请输入"
+                        ></el-input>
+                    </el-form-item>
+                    <el-form-item 
+                        label="期望交付日期" 
+                        label-width="110px" 
+                        prop="expectedDeliveryDate"
+                        :rules="{
+                                required: false,
+                                message: '请输入期望交付日期',
+                                trigger: 'change'
+                            }"
+                    >
+                        <el-date-picker
+                            style="width: 100%"
+                            v-model="form.expectedDeliveryDate"
+                            value-format="yyyy-MM-dd HH:mm:ss"
+                            type="datetime"
+                            placeholder="选择日期"
+                        >
+                        </el-date-picker>
+                    </el-form-item>
+                    <el-form-item 
+                        label="备注" 
+                        label-width="110px" 
+                        prop="remark"
+                        :rules="{
+                                required: false,
+                                message: '请输入备注',
+                                trigger: 'change'
+                            }"
+                    >
+                        <el-input
+                            v-model="form.remark"
+                            type="textarea"
+                            placeholder="请输入"
+                        ></el-input>
+                    </el-form-item>
+                </el-form>
+            </el-card>
+
+            <div slot="footer">
+                <el-button type="primary" size="small" @click="save">保存</el-button>
+                <el-button size="small" @click="handleClose">关闭</el-button>
+            </div>
+        </ele-modal>
+    </div>
+</template>
+<script>
+export default {
+    props: {
+        info: {
+            type: Object,
+            default: () => {}
+        },
+        generateForm: {
+            type: Object,
+            default: () => {}
+        },
+        id: {
+            type: String,
+            default: ''
+        },
+        view: {
+            type: Boolean,
+            default: false
+        },
+    },
+    watch: {
+        info: {
+            handler(newVal, oldVal) {
+                console.log('info', newVal);
+                this.tableData = newVal[this.id] || [];
+            },
+            deep: true,
+            immediate: true
+        },
+    },
+    data() {
+        const formItem = {
+            productName: '',
+            quantity: '',
+            specification: ''
+        }
+        return {
+            form: {},
+            formItem,
+            tableData: [],
+            visible: false,
+            currentItem: {},
+            currentIndex: null,
+            type: 'add'
+        }
+    },
+    mounted() {
+        // console.log('info~~~', this.info);
+        // this.initForm();
+    },
+    methods: {
+        async updateRowInfo() {
+            let data = await this.generateForm.getData(false);
+            this.generateForm.setData({
+                [this.id]: this.tableData
+            });
+            console.log('updateRowInfo', this.tableData, data);
+        },
+        validateForm() {
+            //开始表单校验
+            return new Promise((resolve, reject) => {
+                this.$refs.form.validate((valid) => {
+                    if (!valid) {
+                        reject(false);
+                    } else {
+                        resolve(true);
+                    }
+                });
+            });
+        },
+        addRow() {
+            this.type = 'add';
+            this.form = JSON.parse(JSON.stringify(this.formItem));
+            this.visible = true;
+
+        },
+        handleClose() {
+            this.visible = false;
+        },
+        editRow(row, index) {
+            this.type = 'edit';
+            console.log('编辑行', row, index);
+            this.currentItem = row;
+            this.currentIndex = index;
+            this.visible = true;
+            this.form = JSON.parse(JSON.stringify(row));
+        },
+        deleteRow(index) {
+            this.tableData.splice(index, 1);
+            this.updateRowInfo();
+        },
+        async save() {
+            try {
+                await this.validateForm();
+                console.log('表单验证通过');
+                // 深拷贝form对象,避免引用问题
+                const newForm = JSON.parse(JSON.stringify(this.form));
+                console.log('newForm', newForm);
+                if(this.type === 'add') {
+                    this.tableData.push(newForm);
+                } else {
+                    this.tableData[this.currentIndex] = newForm;
+                }
+                console.log('this.tableData', this.tableData);
+                this.updateRowInfo()
+                this.handleClose(); // 保存后关闭弹窗
+                // 重置form
+                // this.form = {};
+            } catch (error) {
+                console.log('表单验证失败', error);
+            }
+        }
+    }
+}
+</script>
+<style scoped>
+.header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    width: 100%;
+}
+.blank_business_component {
+    display: flex;
+    align-items: center;
+    margin-bottom: 10px;
+}
+.label {
+    width: 80px;
+}
+.value {
+    flex: 1;
+    width: calc(100% - 80px);
+}
+:deep(.el-form-box .el-table .el-table__row .el-table__cell .cell) {
+    padding-left: 10px;
+    padding-right: 10px;
+}
+.required {
+    color: red;
+}
+</style>

+ 46 - 3
src/BIZComponents/processSubmitDialog/processSubmitDialog.vue

@@ -102,6 +102,10 @@
                   @change="changePrice(scope.model.blank_adopzrdd)"
                 ></el-input>
               </div>
+              <div class="blank_adopzrdd">
+                <span>附件:</span>
+                <fileMain v-model="scope.model.blank_adopzrdd[index].file" ></fileMain>
+              </div>
             </div>
           </template>
 
@@ -185,6 +189,33 @@
               :info="scope.model"
             ></reissueComponent>
           </template>
+          <!-- 申领单(临床/非临床) -->
+          <template v-slot:blank_application_component="scope">
+            <applicationComponent
+              ref="blank_application_component"
+              id="blank_application_component"
+              :generateForm="$refs.generateForm"
+              :info="scope.model"
+            ></applicationComponent>
+          </template>  
+          <!-- 采购申请单(行政采购) -->
+          <template v-slot:blank_purchase_requisition="scope">
+            <purchaseRequisitionComponent
+              ref="blank_purchase_requisition"
+              id="blank_purchase_requisition"
+              :generateForm="$refs.generateForm"
+              :info="scope.model"
+            ></purchaseRequisitionComponent>
+          </template>
+          <!-- 出差申请单 -->
+          <template v-slot:blank_business_trip="scope">
+            <businessTripComponent
+              ref="blank_business_trip"
+              id="blank_business_trip"
+              :generateForm="$refs.generateForm"
+              :info="scope.model"
+            ></businessTripComponent>
+          </template>
         </fm-generate-form>
       </div>
       <div
@@ -443,6 +474,9 @@
   import eventComponent from './components/eventComponent.vue';
   import reissueComponent from './components/reissueComponent.vue';
   import SHGDListDialog from './components/SHGDListDialog.vue';
+  import applicationComponent from './components/applicationComponent.vue';
+  import purchaseRequisitionComponent from './components/purchaseRequisitionComponent.vue';
+  import businessTripComponent from './components/businessTripComponent.vue';
   import { parameterGetByCode } from '@/api/main/index.js';
 
   export default {
@@ -457,7 +491,10 @@
       productSpecificationComponent,
       eventComponent,
       reissueComponent,
-      SHGDListDialog
+      SHGDListDialog,
+      applicationComponent,
+      purchaseRequisitionComponent,
+      businessTripComponent
     },
     mixins: [dictMixins],
     props: {
@@ -519,7 +556,10 @@
           'blank_use_qualification',
           'blank_product_specification',
           'blank_event_component',
-          'blank_reissue_component'
+          'blank_reissue_component',
+          'blank_application_component',
+          'blank_purchase_requisition',
+          'blank_business_trip'
         ]
       };
     },
@@ -622,7 +662,10 @@ this.postOptions.push(...response.data);
           blank_use_qualification: '资质使用',
           blank_product_specification: '产品规格',
           blank_event_component: '事件',
-          blank_reissue_component: '补发信息'
+          blank_reissue_component: '补发信息',
+          blank_application_component: '申领单',
+          blank_purchase_requisition: '采购申请单',
+          blank_business_trip: '出差申请单'
         };
         return nameMap[componentKey] || componentKey;
       },

+ 38 - 1
src/views/bpm/collaborative/detail.vue

@@ -55,6 +55,10 @@
                   style="width: calc(100% - 80px)"
                 ></el-input>
               </div>
+              <div class="blank_adopzrdd">
+                <span>附件:</span>
+                <fileMain v-model="scope.model.blank_adopzrdd[index].file" type="view" ></fileMain>
+              </div>
             </div>
           </template>
           <!-- 客户名称 -->
@@ -141,6 +145,33 @@
               :view="view"
             ></reissueComponent>
           </template>
+          <!-- 申领单(临床/非临床) -->
+          <template v-slot:blank_application_component="scope">
+            <applicationComponent
+              ref="blank_application_component"
+              id="blank_application_component"
+              :generateForm="$refs.generateForm"
+              :info="scope.model"
+            ></applicationComponent>
+          </template>
+          <!-- 采购申请单(行政采购) -->
+          <template v-slot:blank_purchase_requisition="scope">
+            <purchaseRequisitionComponent
+              ref="blank_purchase_requisition"
+              id="blank_purchase_requisition"
+              :generateForm="$refs.generateForm"
+              :info="scope.model"
+            ></purchaseRequisitionComponent>
+          </template>
+          <!-- 出差申请单 -->
+          <template v-slot:blank_business_trip="scope">
+            <businessTripComponent
+              ref="blank_business_trip"
+              id="blank_business_trip"
+              :generateForm="$refs.generateForm"
+              :info="scope.model"
+            ></businessTripComponent>
+          </template>
         </fm-generate-form>
       </div>
       <div
@@ -193,6 +224,9 @@ import productSpecificationComponent from '@/BIZComponents/processSubmitDialog/c
 import eventComponent from '@/BIZComponents/processSubmitDialog/components/eventComponent.vue';
 import reissueComponent from '@/BIZComponents/processSubmitDialog/components/reissueComponent.vue';
 import Detail from '@/views/bpm/processInstance/detailNew.vue';
+import applicationComponent from '@/BIZComponents/processSubmitDialog/components/applicationComponent.vue';
+import purchaseRequisitionComponent from '@/BIZComponents/processSubmitDialog/components/purchaseRequisitionComponent.vue';
+import businessTripComponent from '@/BIZComponents/processSubmitDialog/components/businessTripComponent.vue';
 
 export default {
   name: 'formDetailDialog',
@@ -204,7 +238,10 @@ export default {
     productSpecificationComponent,
     eventComponent,
     reissueComponent,
-    Detail
+    Detail,
+    applicationComponent,
+    purchaseRequisitionComponent,
+    businessTripComponent
   },
   props: {
     formDetailDialogFlag: {

+ 34 - 1
src/views/bpm/done/detailDialog.vue

@@ -140,6 +140,33 @@
           :view="view"
         ></reissueComponent>
       </template>
+      <!-- 申领单(临床/非临床) -->
+          <template v-slot:blank_application_component="scope">
+            <applicationComponent
+              ref="blank_application_component"
+              id="blank_application_component"
+              :generateForm="$refs.generateForm"
+              :info="scope.model"
+            ></applicationComponent>
+          </template>
+          <!-- 采购申请单(行政采购) -->
+          <template v-slot:blank_purchase_requisition="scope">
+            <purchaseRequisitionComponent
+              ref="blank_purchase_requisition"
+              id="blank_purchase_requisition"
+              :generateForm="$refs.generateForm"
+              :info="scope.model"
+            ></purchaseRequisitionComponent>
+          </template>
+          <!-- 出差申请单 -->
+          <template v-slot:blank_business_trip="scope">
+            <businessTripComponent
+              ref="blank_business_trip"
+              id="blank_business_trip"
+              :generateForm="$refs.generateForm"
+              :info="scope.model"
+            ></businessTripComponent>
+          </template>
       </fm-generate-form>
       <async-biz-form-component
         v-else
@@ -171,6 +198,9 @@
   import productSpecificationComponent from '@/BIZComponents/processSubmitDialog/components/productSpecificationComponent.vue';
   import eventComponent from '@/BIZComponents/processSubmitDialog/components/eventComponent.vue';
   import reissueComponent from '@/BIZComponents/processSubmitDialog/components/reissueComponent.vue';
+  import applicationComponent from '@/BIZComponents/processSubmitDialog/components/applicationComponent.vue';
+import purchaseRequisitionComponent from '@/BIZComponents/processSubmitDialog/components/purchaseRequisitionComponent.vue';
+import businessTripComponent from '@/BIZComponents/processSubmitDialog/components/businessTripComponent.vue';
 
   export default {
     components: {
@@ -180,7 +210,10 @@
       useQualificationComponent,
       productSpecificationComponent,
       eventComponent,
-      reissueComponent
+      reissueComponent,
+      applicationComponent,
+    purchaseRequisitionComponent,
+    businessTripComponent
     },
     data() {
       return {

+ 40 - 1
src/views/bpm/handleTask/formParser/formParserDialog.vue

@@ -16,6 +16,7 @@
     <fm-generate-form
       v-if="Object.keys(form?.formJson || {}).length !== 0"
       :data="jsonData"
+      :edit="false"
       :value="form.valueJson"
       ref="generateForm"
     >
@@ -37,6 +38,10 @@
               style="width: calc(100% - 80px)"
             ></el-input>
           </div>
+          <div class="blank_adopzrdd">
+            <span>附件:</span>
+            <fileMain v-model="scope.model.blank_adopzrdd[index].file" ></fileMain>
+          </div>
         </div>
       </template>
       <!-- 客户名称 -->
@@ -124,6 +129,33 @@
           :view="view"
         ></reissueComponent>
       </template>
+      <!-- 申领单(临床/非临床) -->
+      <template v-slot:blank_application_component="scope">
+        <applicationComponent
+          ref="blank_application_component"
+          id="blank_application_component"
+          :generateForm="$refs.generateForm"
+          :info="scope.model"
+        ></applicationComponent>
+      </template>
+      <!-- 采购申请单(行政采购) -->
+      <template v-slot:blank_purchase_requisition="scope">
+        <purchaseRequisitionComponent
+          ref="blank_purchase_requisition"
+          id="blank_purchase_requisition"
+          :generateForm="$refs.generateForm"
+          :info="scope.model"
+        ></purchaseRequisitionComponent>
+      </template>
+      <!-- 出差申请单 -->
+      <template v-slot:blank_business_trip="scope">
+        <businessTripComponent
+          ref="blank_business_trip"
+          id="blank_business_trip"
+          :generateForm="$refs.generateForm"
+          :info="scope.model"
+        ></businessTripComponent>
+      </template>
     </fm-generate-form>
 
     <outboundXTBG
@@ -211,6 +243,10 @@ import productSpecificationComponent from '@/BIZComponents/processSubmitDialog/c
 import eventComponent from '@/BIZComponents/processSubmitDialog/components/eventComponent.vue';
 import reissueComponent from '@/BIZComponents/processSubmitDialog/components/reissueComponent.vue';
 import { processInstanceValueJsonChange } from '@/api/bpm/processInstance';
+import applicationComponent from '@/BIZComponents/processSubmitDialog/components/applicationComponent.vue';
+import purchaseRequisitionComponent from '@/BIZComponents/processSubmitDialog/components/purchaseRequisitionComponent.vue';
+import businessTripComponent from '@/BIZComponents/processSubmitDialog/components/businessTripComponent.vue';
+
 
 export default {
   name: 'formParserDialog',
@@ -222,7 +258,10 @@ export default {
     useQualificationComponent,
     productSpecificationComponent,
     eventComponent,
-    reissueComponent
+    reissueComponent,
+    applicationComponent,
+    purchaseRequisitionComponent,
+    businessTripComponent
   },
   props: {
     businessId: {