ZaiZai vor 1 Jahr
Ursprung
Commit
30882704a9

+ 2 - 1
package.json

@@ -48,6 +48,7 @@
         "unocss": "0.58.2",
         "unocss-preset-extra": "^0.5.3",
         "unocss-preset-scrollbar": "^0.3.1",
-        "vite": "^4.5.0"
+        "vite": "^4.5.0",
+        "z-element-plus": "^1.1.4"
     }
 }

+ 2 - 0
src/components/index.js

@@ -10,6 +10,7 @@ import HcViewReport from './view-report/view-report.vue'
 import HcGradientCard from './gradient-card/index.vue'
 import HcSmsAuth from './hc-sms-auth/index.vue'
 import HcPdfs from './hc-pdfs/pdfs.vue'
+import HcTableForm from './table-form/index.vue'
 
 //注册全局组件
 export const setupComponents = (App) => {
@@ -25,4 +26,5 @@ export const setupComponents = (App) => {
     App.component('HcViewReport', HcViewReport)
     App.component('HcSmsAuth', HcSmsAuth)
     App.component('HcPdfs', HcPdfs)
+    App.component('HcTableForm', HcTableForm)
 }

+ 123 - 0
src/components/plugins/table-form/hc-date-picker-1.vue

@@ -0,0 +1,123 @@
+<template>
+    <ElDatePicker
+        :id="keyname"
+        v-model="modelValues"
+        :clearable="clearable"
+        :disabled="disabled"
+        :end-placeholder="endPlaceholder"
+        :format="format"
+        :keyname="keyname"
+        :placeholder="placeholder"
+        :range-separator="rangeSeparator"
+        :readonly="readonly"
+        :start-placeholder="startPlaceholder"
+        :type="type"
+        :value-format="valueFormat"
+        style="width: 100%;height: 100%;"
+        @change="timePickerChange"
+        @keydown.shift.up="keyupShiftUp"
+        @keydown.shift.down="keyupShiftDown"
+        @keydown.shift.left="keyupShiftLeft"
+        @keydown.shift.right="keyupShiftRight"
+    />
+</template>
+
+<script>
+export default {
+    inheritAttrs: false,
+}
+</script>
+
+<script setup>
+import { ref, watch } from 'vue'
+import { ElDatePicker } from 'z-element-plus'
+import 'dayjs/locale/zh-cn'
+
+const props = defineProps({
+    modelValue: {
+        type: [Date, String, Number, Array],
+    },
+    type: {
+        type: String,
+        default: 'date',
+    },
+    rangeSeparator: {
+        type: String,
+        default: '-',
+    },
+    startPlaceholder: {
+        type: String,
+        default: '',
+    },
+    endPlaceholder: {
+        type: String,
+        default: '',
+    },
+    format: {
+        type: String,
+        default: 'YYYY:MM:DD',
+    },
+    valueFormat: {
+        type: String,
+        default: 'YYYY年MM月DD日',
+    },
+    keyname: {
+        type: String,
+        default: '',
+    },
+    readonly: {
+        type: Boolean,
+        default: false,
+    },
+    disabled: {
+        type: Boolean,
+        default: false,
+    },
+    clearable: {
+        type: Boolean,
+        default: true,
+    },
+    placeholder: {
+        type: String,
+        default: '',
+    },
+})
+
+//事件
+const emit = defineEmits(['update:modelValue', 'change', 'keydowns'])
+
+//变量
+const modelValues = ref(props.modelValue)
+
+//监听
+watch(() => [
+    props.modelValue,
+], ([val]) => {
+    modelValues.value = val
+})
+
+const timePickerChange = (val) => {
+    emit('update:modelValue', val)
+    emit('change', val)
+}
+
+//向上
+const keyupShiftUp = (e) => {
+    emit('keydowns', { type: 'up', name: { target: { id: props.keyname } }, key: props.keyname, e })
+}
+
+//向下
+const keyupShiftDown = (e) => {
+    emit('keydowns', { type: 'down', name: { target: { id: props.keyname } }, key: props.keyname, e })
+}
+
+//向左
+const keyupShiftLeft = (e) => {
+    emit('keydowns', { type: 'left', name: { target: { id: props.keyname } }, key: props.keyname, e })
+}
+
+//向右
+const keyupShiftRight = (e) => {
+    emit('keydowns', { type: 'right', name: { target: { id: props.keyname } }, key: props.keyname, e })
+}
+</script>

+ 168 - 0
src/components/plugins/table-form/hc-form-checkbox-group.vue

@@ -0,0 +1,168 @@
+<template>
+    <div
+        :class="isFocus ? 'is-focus' : ''" class="hc-form-checkbox-group-box"
+        @keydown.shift.up="keyupShiftUp"
+        @keydown.shift.down="keyupShiftDown"
+        @keydown.shift.left="keyupShiftLeft"
+        @keydown.shift.right="keyupShiftRight"
+    >
+        <ElCheckbox
+            v-for="item in checkboxDatas" :key="item.key" :checked="item.checked"
+            @change="onCheckboxChange($event, item)"
+        >
+            {{ item.name }}
+        </ElCheckbox>
+        <input :id="keyname" class="hc-checkbox-group-input" @blur="handleBlur" @focus="handleFocus">
+    </div>
+</template>
+
+<script>
+export default {
+    inheritAttrs: false,
+}
+</script>
+
+<script setup>
+import { nextTick, ref, watch } from 'vue'
+import { ElCheckbox } from 'element-plus'
+import { arrIndex, deepClone, isNullES } from 'js-fast-way'
+
+const props = defineProps({
+    ui: {
+        type: String,
+        default: '',
+    },
+    datas: {
+        type: Array,
+        default: () => ([]),
+    },
+    objs: {
+        type: Array,
+        default: () => ([]),
+    },
+    val: {
+        type: [String, Number],
+        default: '',
+    },
+    keyname: {
+        type: [String, Number],
+        default: '',
+    },
+})
+
+//事件
+const emit = defineEmits(['change', 'keydowns'])
+
+//变量
+const checkboxDatas = ref([])
+
+//渲染完成
+nextTick(() => {
+    setInitDatas(deepClone(props.datas), deepClone(props.objs))
+})
+
+//监听表头
+watch(() => [
+    props.val,
+], ([val]) => {
+    setModelVal(val)
+})
+
+//处理初始数据
+const setInitDatas = (datas, objs) => {
+    for (let i = 0; i < datas.length; i++) {
+        objs.push({ key: String(datas[i]), name: datas[i] })
+    }
+    checkboxDatas.value = objs
+    setModelVal(props.val)
+}
+
+//处理数据
+const setModelVal = (val) => {
+    const datas = deepClone(checkboxDatas.value)
+    if (!isNullES(val)) {
+        const arr = String(val).split(',')
+        for (let i = 0; i < arr.length; i++) {
+            const item = String(arr[i])
+            const index = arrIndex(datas, 'key', item)
+            datas[index].checked = true
+        }
+    }
+    checkboxDatas.value = datas
+}
+
+//当绑定值变化时触发的事件
+const onCheckboxChange = (val, item) => {
+    item.checked = val
+    getCheckedValue()
+}
+
+//取选中的值
+const getCheckedValue = () => {
+    let valString = ''
+    const datas = checkboxDatas.value
+    for (let i = 0; i < datas.length; i++) {
+        if (datas[i].checked) {
+            const key = String(datas[i].key)
+            valString = valString ? `${valString},${key}` : key
+        }
+    }
+    //事件返回
+    emit('change', {
+        key: props.keyname,
+        val: valString,
+    })
+}
+
+//向上
+const keyupShiftUp = (e) => {
+    emit('keydowns', { type: 'up', name: { target: { id: props.keyname } }, key: props.keyname, e })
+}
+
+//向下
+const keyupShiftDown = (e) => {
+    emit('keydowns', { type: 'down', name: { target: { id: props.keyname } }, key: props.keyname, e })
+}
+
+//向左
+const keyupShiftLeft = (e) => {
+    emit('keydowns', { type: 'left', name: { target: { id: props.keyname } }, key: props.keyname, e })
+}
+
+//向右
+const keyupShiftRight = (e) => {
+    emit('keydowns', { type: 'right', name: { target: { id: props.keyname } }, key: props.keyname, e })
+}
+
+
+//获得焦点
+const isFocus = ref(false)
+const handleFocus = () => {
+    isFocus.value = true
+}
+
+//失去焦点
+const handleBlur = () => {
+    isFocus.value = false
+}
+</script>
+
+<style lang="scss" scoped>
+.hc-form-checkbox-group-box {
+    position: relative;
+    width: 100%;
+    height: initial;
+    border-radius: 4px;
+    transition: box-shadow 0.3s, background-color 0.3s;
+    &.is-focus, &:hover {
+        background-color: #eddac4;
+        box-shadow: 0 0 0 1.5px var(--el-color-primary) inset;
+    }
+    .hc-checkbox-group-input {
+        position: absolute;
+        z-index: -1;
+        right: 10px;
+        width: 10px;
+    }
+}
+</style>

+ 119 - 0
src/components/plugins/table-form/hc-form-radio-group.vue

@@ -0,0 +1,119 @@
+<template>
+    <div
+        :class="isFocus ? 'is-focus' : ''" class="hc-form-radio-group-box"
+        @keydown.shift.up="keyupShiftUp"
+        @keydown.shift.down="keyupShiftDown"
+        @keydown.shift.left="keyupShiftLeft"
+        @keydown.shift.right="keyupShiftRight"
+    >
+        <ElRadioGroup
+            v-model="modelValues"
+            :disabled="disabled"
+            :keyname="keyname"
+            :placeholder="placeholder"
+            @change="radioGroupChange"
+        >
+            <slot />
+        </ElRadioGroup>
+        <input :id="keyname" class="hc-radio-group-input" @blur="handleBlur" @focus="handleFocus">
+    </div>
+</template>
+
+<script>
+export default {
+    inheritAttrs: false,
+}
+</script>
+
+<script setup>
+import { ref, watch } from 'vue'
+import { ElRadio, ElRadioGroup } from 'element-plus'
+
+const props = defineProps({
+    modelValue: {
+        type: [String, Number, Boolean],
+    },
+    keyname: {
+        type: String,
+        default: '',
+    },
+    placeholder: {
+        type: String,
+        default: '',
+    },
+    disabled: {
+        type: Boolean,
+        default: false,
+    },
+})
+
+//事件
+const emit = defineEmits(['update:modelValue', 'change', 'keydowns'])
+
+//变量
+const modelValues = ref(props.modelValue)
+
+//监听
+watch(() => [
+    props.modelValue,
+], ([val]) => {
+    modelValues.value = val
+})
+
+const radioGroupChange = (val) => {
+    emit('update:modelValue', val)
+    emit('change', val)
+}
+
+//向上
+const keyupShiftUp = (e) => {
+    emit('keydowns', { type: 'up', name: { target: { id: props.keyname } }, key: props.keyname, e })
+}
+
+//向下
+const keyupShiftDown = (e) => {
+    emit('keydowns', { type: 'down', name: { target: { id: props.keyname } }, key: props.keyname, e })
+}
+
+//向左
+const keyupShiftLeft = (e) => {
+    emit('keydowns', { type: 'left', name: { target: { id: props.keyname } }, key: props.keyname, e })
+}
+
+//向右
+const keyupShiftRight = (e) => {
+    emit('keydowns', { type: 'right', name: { target: { id: props.keyname } }, key: props.keyname, e })
+}
+
+
+//获得焦点
+const isFocus = ref(false)
+const handleFocus = () => {
+    isFocus.value = true
+}
+
+//失去焦点
+const handleBlur = () => {
+    isFocus.value = false
+}
+</script>
+
+<style lang="scss" scoped>
+.hc-form-radio-group-box {
+    position: relative;
+    width: 100%;
+    height: initial;
+    border-radius: 4px;
+    transition: box-shadow 0.3s, background-color 0.3s;
+    &.is-focus, &:hover {
+        background-color: #eddac4;
+        box-shadow: 0 0 0 1.5px var(--el-color-primary) inset;
+    }
+    .hc-radio-group-input {
+        position: absolute;
+        z-index: -1;
+        right: 10px;
+        width: 10px;
+    }
+}
+</style>

+ 122 - 0
src/components/plugins/table-form/hc-form-upload.vue

@@ -0,0 +1,122 @@
+<template>
+    <el-upload
+        v-loading="isLoading" :accept="accept" :action="action" :class="isFocus ? 'is-focus' : ''"
+        :disabled="isLoading" :headers="getHeader()" :keyname="isKeyName"
+        :on-error="formUploadError"
+        :on-progress="uploadprogress" :placeholder="placeholder" :show-file-list="false"
+        class="hc-upload-table-form"
+        element-loading-text="上传中..." @exceed="formUploadExceed" @success="formUploadSuccess"
+    >
+        <img v-if="isSrc" :src="isSrc" alt="" class="hc-table-form-img">
+        <div v-else class="hc-table-form-icon">
+            点此选择文件并上传
+        </div>
+        <div v-if="isSrc" class="hc-table-form-del">
+            <el-button plain type="danger" @click.stop="delTableFormFile">
+                删除当前文件
+            </el-button>
+        </div>
+        <input :id="isKeyName" v-model="isSrc" class="hc-upload-input-src" @blur="handleBlur" @focus="handleFocus">
+    </el-upload>
+</template>
+
+<script setup>
+import { ref, watch } from 'vue'
+import { getHeader } from 'hc-vue3-ui'
+
+const props = defineProps({
+    src: {
+        type: [Number, String],
+        default: '',
+    },
+    keyname: {
+        type: [Number, String],
+        default: '',
+    },
+    placeholder: {
+        type: [Number, String],
+        default: '相片',
+    },
+})
+
+//事件
+const emit = defineEmits(['success', 'del'])
+//变量
+const isLoading = ref(false)
+const isSrc = ref(props.src)
+const isKeyName = ref(props.keyname)
+
+const action = '/api/blade-manager/exceltab/add-buss-imginfo'
+const accept = 'image/png,image/jpg,image/jpeg'
+
+//监听
+watch(() => [
+    props.src,
+    props.keyname,
+], ([src, keyname]) => {
+    isSrc.value = src
+    isKeyName.value = keyname
+})
+
+//上传进度
+const uploadprogress = () => {
+    isLoading.value = true
+}
+
+//上传完成
+const formUploadSuccess = (res) => {
+    isLoading.value = false
+    if (res.code === 200) {
+        const link = res.data?.link || ''
+        emit('success', {
+            res,
+            src: link,
+            key: isKeyName.value,
+        })
+    }
+}
+
+//上传失败
+const formUploadError = () => {
+    isLoading.value = false
+}
+
+//格式错误
+const formUploadExceed = () => {
+    isLoading.value = false
+}
+
+//删除上传的文件
+const delTableFormFile = () => {
+    emit('del', isKeyName.value)
+}
+
+const isFocus = ref(false)
+
+//获得焦点
+const handleFocus = () => {
+    isFocus.value = true
+}
+
+//失去焦点
+const handleBlur = () => {
+    isFocus.value = false
+}
+</script>
+
+<style lang="scss" scoped>
+.hc-upload-table-form {
+    border-radius: 3px;
+    transition: box-shadow 0.3s, background-color 0.3s;
+    &.is-focus, &:hover {
+        background-color: #eddac4;
+        box-shadow: 0 0 0 1.5px var(--el-color-primary) inset;
+    }
+    .hc-upload-input-src {
+        position: absolute;
+        z-index: -1;
+        right: 10px;
+        width: 10px;
+    }
+}
+</style>

+ 103 - 0
src/components/plugins/table-form/hc-time-picker.vue

@@ -0,0 +1,103 @@
+<template>
+    <ElTimePicker
+        :id="keyname"
+        v-model="modelValues"
+        :clearable="clearable"
+        :disabled="disabled"
+        :format="format"
+        :keyname="keyname"
+        :placeholder="placeholder"
+        :readonly="readonly"
+        :value-format="valueFormat"
+        style="width: 100%;height: 100%;"
+        @change="timePickerChange"
+        @keydown.shift.up="keyupShiftUp"
+        @keydown.shift.down="keyupShiftDown"
+        @keydown.shift.left="keyupShiftLeft"
+        @keydown.shift.right="keyupShiftRight"
+    />
+</template>
+
+<script>
+export default {
+    inheritAttrs: false,
+}
+</script>
+
+<script setup>
+import { ref, watch } from 'vue'
+import { ElTimePicker } from 'z-element-plus'
+import 'dayjs/locale/zh-cn'
+
+const props = defineProps({
+    modelValue: {
+        type: [Date, String, Number, Array],
+    },
+    format: {
+        type: String,
+        default: 'HH:mm:ss',
+    },
+    valueFormat: {
+        type: String,
+        default: 'HH:mm:ss',
+    },
+    keyname: {
+        type: String,
+        default: '',
+    },
+    readonly: {
+        type: Boolean,
+        default: false,
+    },
+    disabled: {
+        type: Boolean,
+        default: false,
+    },
+    clearable: {
+        type: Boolean,
+        default: true,
+    },
+    placeholder: {
+        type: String,
+        default: '',
+    },
+})
+
+//事件
+const emit = defineEmits(['update:modelValue', 'change', 'keydowns'])
+
+//变量
+const modelValues = ref(props.modelValue)
+
+//监听
+watch(() => [
+    props.modelValue,
+], ([val]) => {
+    modelValues.value = val
+})
+
+const timePickerChange = (val) => {
+    emit('update:modelValue', val)
+    emit('change', val)
+}
+
+//向上
+const keyupShiftUp = (e) => {
+    emit('keydowns', { type: 'up', name: { target: { id: props.keyname } }, key: props.keyname, e })
+}
+
+//向下
+const keyupShiftDown = (e) => {
+    emit('keydowns', { type: 'down', name: { target: { id: props.keyname } }, key: props.keyname, e })
+}
+
+//向左
+const keyupShiftLeft = (e) => {
+    emit('keydowns', { type: 'left', name: { target: { id: props.keyname } }, key: props.keyname, e })
+}
+
+//向右
+const keyupShiftRight = (e) => {
+    emit('keydowns', { type: 'right', name: { target: { id: props.keyname } }, key: props.keyname, e })
+}
+</script>

+ 299 - 0
src/components/table-form/index.vue

@@ -0,0 +1,299 @@
+<template>
+    <div :id="`table-form-item-${keyId}`" v-loading="isLoading" :class="!isTableForm ? 'no-scroll-bar' : ''" style="width: auto; height: 100%;" class="hc-table-form-data-item">
+        <el-scrollbar class="table-form-item-scrollbar">
+            <div :id="`table-form-${keyId}`" class="hc-excel-table-form" />
+        </el-scrollbar>
+    </div>
+</template>
+
+<script setup>
+import { nextTick, onMounted, ref, watch } from 'vue'
+import HTableForm from '~src/plugins/HTableForm'
+import { getRandom, isString } from 'js-fast-way'
+
+//初始
+const props = defineProps({
+    html: String,
+    form: {
+        type: Object,
+        default: () => ({}),
+    },
+    loading: Boolean,
+})
+
+//事件
+const emit = defineEmits(['render'])
+
+const keyId = getRandom(6)
+
+//初始变量
+const isLoading = ref(props.loading)
+
+//表单数据
+const excelHtml = ref(props.html)
+const excelForm = ref(props.form)
+
+//样式
+const tableFormApp = ref(null)
+const tableFormVM = ref(null)
+const isTableForm = ref(false)
+
+//监听
+watch(() => props.loading, (loading) => {
+    isLoading.value = loading
+})
+
+//html变动
+watch(() => props.html, (html) => {
+    excelHtml.value = html
+    setExcelHtml()
+})
+
+//深度监听变动的对象数据
+watch(() => props.form, (val) => {
+    excelForm.value = val
+    setPickerKey()
+    setFormData(val)
+}, {
+    deep: true,
+})
+
+//渲染完成
+onMounted(() => {
+    setPickerKey()
+    getExcelHtml()
+})
+
+//获取已填写的数据
+const setPickerKey = () => {
+    HTableForm.setPickerKey(excelForm.value)
+}
+
+const setExcelHtml = () => {
+    setPickerKey()
+    //先卸载
+    if (tableFormApp.value) {
+        tableFormApp.value?.unmount()
+        tableFormApp.value = null
+        nextTick(() => {
+            getExcelHtml()
+        })
+    } else {
+        getExcelHtml()
+    }
+}
+
+//获取模板标签数据
+const getExcelHtml = () => {
+    const temp = isString(excelHtml.value) ? excelHtml.value : ''
+    if (temp && keyId) {
+        //渲染表单
+        isTableForm.value = true
+        const { app, vm } = HTableForm.createForm({
+            pid: keyId,
+            template: temp,
+            tableForm: excelForm.value,
+            appId: `#table-form-${keyId}`,
+            onFormDataChange: (form) => {
+                excelForm.value = form
+                emit('render', form)
+            },
+        })
+        tableFormApp.value = app
+        tableFormVM.value = vm
+        excelForm.value.isRenderForm = true
+        emit('render', excelForm.value)
+    } else {
+        isTableForm.value = false
+        excelForm.value.isRenderForm = false
+        emit('render', excelForm.value)
+    }
+}
+
+//获取表单数据
+const getFormData = () => {
+    return excelForm.value
+}
+
+//设置表单数据
+const setFormData = (data) => {
+    excelForm.value = data
+    tableFormVM.value?.setFormData(excelForm.value)
+}
+
+//卸载渲染
+const unmountHtml = () => {
+    if (tableFormApp.value) {
+        tableFormApp.value?.unmount()
+    }
+}
+
+// 暴露出去
+defineExpose({
+    getFormData,
+    setFormData,
+    setExcelHtml,
+    unmountHtml,
+})
+</script>
+
+<style lang="scss">
+.hc-excel-table-form {
+    transform: scale(0.9);
+    transform-origin: top;
+}
+//插入特殊字符弹窗的输入框
+.hc-table-form-data-item .hc-excel-table-form td,
+.hc-table-form-data-item .hc-excel-table-form td .el-input .el-input__wrapper .el-input__inner,
+.el-form-item.special-form-item .el-form-item__content .el-input .el-input__wrapper .el-input__inner {
+    font-family: "hc-eudc", hc-sans, 宋体, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !important;
+}
+
+.hc-table-form-data-item {
+    position: relative;
+    padding: 12px;
+    height: 100%;
+    overflow: hidden;
+    background-color: white;
+    &.no-scroll-bar .el-scrollbar {
+        display: none;
+    }
+    .hc-excel-table-form {
+        position: relative;
+        display: flex;
+        padding: 10px;
+        justify-content: center;
+        td {
+            position: relative;
+            padding: 6px;
+            background-clip: padding-box;
+            .el-input {
+                clear: both;
+                color: #606266;
+                border-radius: 3px;
+                height: initial;
+                background-color: #ffffff !important;
+                .el-input__wrapper {
+                    background-color: inherit;
+                    caret-color: var(--el-color-primary);
+                }
+                .el-input__suffix-inner {
+                    width: 18px;
+                }
+            }
+            .el-textarea {
+                width: 100%;
+                height: 100%;
+                .el-textarea__inner {
+                    min-height: initial;
+                    background-color: #ffffff;
+                    border-radius: 3px;
+                    color: #606266;
+                    height: 100%;
+                    caret-color: var(--el-color-primary);
+                }
+            }
+            //日期选择框
+            .el-date-editor.el-input .el-input__wrapper,
+            .el-date-editor.el-date-editor--datetimerange.el-input__wrapper {
+                width: 100%;
+                height: initial;
+                clear: both;
+            }
+            //焦点
+            .el-input .el-input__wrapper.is-focus, .el-input .el-input__wrapper:hover,
+            .el-textarea .el-textarea__inner:hover {
+                box-shadow: 0 0 0 1.5px var(--el-input-focus-border-color) inset;
+                background-color: #eddac4;
+            }
+            //公式
+            &[gscolor] {
+                .el-input, .el-textarea .el-textarea__inner {
+                    background-color: #dcdcdc !important;
+                }
+                .el-date-editor.el-input__wrapper{
+                    background-color: #dcdcdc !important;
+                }
+                .el-select .el-select__wrapper {
+                    background: #dcdcdc !important;
+                }
+            }
+            //文本选中颜色
+            .el-input .el-input__wrapper input,
+            .el-textarea textarea {
+                &::selection {
+                    background: var(--el-color-primary-light-9);
+                    color: var(--el-color-primary);
+                }
+                &::-moz-selection {
+                    background: var(--el-color-primary-light-9);
+                    color: var(--el-color-primary);
+                }
+            }
+            //下拉框
+            .el-select {
+                width: 100%;
+                height: initial;
+                clear: both;
+            }
+            .el-select .el-select__wrapper.is-focused {
+                background: var(--el-color-primary-light-9);
+                color: var(--el-color-primary);
+            }
+            //表单上传
+            .hc-upload-table-form {
+                position: absolute;
+                top: 6px;
+                bottom: 6px;
+                left: 6px;
+                right: 6px;
+                .el-upload {
+                    height: 100%;
+                }
+            }
+        }
+        //列合并的单元格
+        td[rowspan] {
+            height: initial;
+        }
+        //非输入框颜色
+        td:not([titlexx]), td[titlexx*=''],
+        td:not([title]), td[title*=''] {
+            background-color: white !important;
+            user-select: none;
+        }
+    }
+    .hc-no-table-form {
+        position: relative;
+        height: 100%;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        .table-form-no {
+            position: relative;
+            img {
+                width: 350px;
+            }
+            .desc {
+                text-align: center;
+                font-size: 20px;
+                color: #aaa;
+            }
+        }
+    }
+}
+
+.hc-red-border {
+    &.el-textarea__inner, &.el-input .el-input__wrapper {
+        --el-input-border-color: #fe0000 !important;
+        box-shadow: 0 0 0 2px #fe0000 inset !important;
+    }
+}
+
+.hc-green-border {
+    &.el-textarea__inner, &.el-input .el-input__wrapper {
+        --el-input-border-color: #1ECC95 !important;
+        box-shadow: 0 0 0 2px #1ECC95 inset !important;
+    }
+}
+</style>

+ 165 - 0
src/plugins/HTableForm.js

@@ -0,0 +1,165 @@
+import { createApp } from 'vue/dist/vue.esm-bundler.js'
+import { getHeader } from 'hc-vue3-ui'
+import { toParse } from 'js-fast-way'
+
+//自定义组件或二次封装的组件
+import HcTableFormUpload from '~com/plugins/table-form/hc-form-upload.vue'
+import HcFormCheckboxGroup from '~com/plugins/table-form/hc-form-checkbox-group.vue'
+import ElTimePicker from '~com/plugins/table-form/hc-time-picker.vue'
+import ElDatePicker from '~com/plugins/table-form/hc-date-picker-1.vue'
+import ElRadioGroup from '~com/plugins/table-form/hc-form-radio-group.vue'
+
+//修改过的组件
+//import { ElOption, ElSelect } from 'z-element-plus' ElSelect, ElOption,
+
+import ElementPlus from 'element-plus'
+import zhCn from 'element-plus/es/locale/lang/zh-cn'
+
+const components = { ElDatePicker, ElTimePicker, HcTableFormUpload, ElRadioGroup, HcFormCheckboxGroup }
+
+//表单渲染
+export default class HTableForm {
+
+    static tableFormApp = null
+    static tableFormVM = null
+
+    static createForm({ template, tableForm, appId, onRight, onBlur, onLeftClick, onFormDataChange, onChartRefs }) {
+        const app = createApp({
+            //自定义组件,需要把饿了么的组件,或者自定义组件手动传递进来绑定,否则渲染时,自定义组件不会生效
+            components,
+            data() {
+                return {
+                    getTokenHeader: getHeader(),
+                    formData: tableForm,
+                }
+            },
+            //监听数据,伪双向绑定(v-model)
+            watch: {
+                formData: {
+                    handler(obj) {
+                        tableForm = obj
+                        this.formDataChange(obj)
+                    },
+                    deep: true,
+                },
+            },
+            methods: {
+                //表单数据改变
+                formDataChange(obj) {
+                    if (onFormDataChange) {
+                        onFormDataChange(obj)
+                    }
+                },
+                //改变表单数据
+                setFormData(obj) {
+                    this.formData = obj
+                },
+                //鼠标右键菜单
+                contextmenuClick(a, b, c, d, e, f, event) {
+                    event.preventDefault()
+                },
+                //鼠标右键事件
+                RightClick(a, b, c, d, e, f, event) {
+                    setTimeout(() => {
+                        const KeyName = event?.target?.getAttribute('keyname') || ''
+                        if (onRight) {
+                            event.preventDefault()
+                            onRight(event, KeyName)
+                        }
+                    }, 100)
+                },
+                //焦点事件
+                getInformation() {
+                },
+                //日期选择事件
+                datePickerChange(val, key) {
+                    this.formData[key] = val
+                },
+                //上传完成
+                formUploadSuccess({ src, key }) {
+                    this.formData[key] = src
+                },
+                //删除上传的文件
+                delTableFormFile(key) {
+                    this.formData[key] = ''
+                },
+                //失去焦点事件
+                getRegularExpression(event, reg, msg, a, b, leng, type, c, d) {
+                    const KeyName = event?.target?.getAttribute('keyname') || ''
+                    if (onBlur) {
+                        onBlur(event, KeyName, reg, this.formData[KeyName], msg, leng, type, c, d)
+                    }
+                },
+                //远程搜索处理
+                formRemoteChange(data) {
+                    Object.keys(data).forEach(key => {
+                        this.formData[key] = data[key]
+                    })
+                },
+                //多选框处理
+                checkboxGroupChange({ key, val }) {
+                    this.formData[key] = val
+                },
+                //键盘事件 上键
+                keyupShiftUp() {},
+                //键盘事件 下键
+                keyupShiftDown() {},
+                //键盘事件 左键
+                keyupShiftLeft() {},
+                //键盘事件 右键
+                keyupShiftRight() {},
+                //日期时间框键盘事件
+                dateKeydown() {},
+                //输入左键点击事件
+                inputLeftClick(event, key) {
+                    setTimeout(() => {
+                        if (onLeftClick) {
+                            onLeftClick(key)
+                        }
+                    }, 100)
+                },
+                setChartRefs(el, pKeyId, key) {
+                    if (onChartRefs) onChartRefs(el, pKeyId, key)
+                },
+            },
+            //html标签数据
+            template,
+        })
+        // 饿了么UI框架
+        app.use(ElementPlus, {
+            locale: zhCn,
+        })
+        const vm = app.mount(appId)
+        this.tableFormApp = app
+        this.tableFormVM = vm
+        return { app, vm }
+    }
+
+    //处理日期范围数据
+    static setPickerKey(data) {
+        const pickerKey = data['pickerKey'] || ''
+        if (pickerKey) {
+            const pickerKeys = pickerKey.split(',')
+            for (let i = 0; i < pickerKeys.length; i++) {
+                const val = data[pickerKeys[i]] || ''
+                if (val) {
+                    const dataVal = val.replace(/'/g, '"')
+                    data[pickerKeys[i]] = toParse(dataVal) || []
+                } else {
+                    data[pickerKeys[i]] = []
+                }
+            }
+        }
+        return data
+    }
+
+
+    //卸载实例
+    static unmountFormApp() {
+        if (this.tableFormApp) {
+            this.tableFormApp?.unmount()
+            this.tableFormApp = null
+        }
+    }
+
+}

+ 11 - 1
src/views/tasks/components/hc-data/html-form.vue

@@ -1,11 +1,13 @@
 <template>
     <div class="hc-task-html-form-body">
-        html表单
+        <hc-table-form ref="htmlRef" :form="htmlForm" :html="tableHtml" :loading="htmlLoading" @render="htmlRender" />
     </div>
 </template>
 
 <script setup>
 import { onMounted, ref, watch } from 'vue'
+import tableHtml from '../html-form/html'
+
 const props = defineProps({
     isEdit: {
         type: Boolean,
@@ -42,6 +44,14 @@ const setTaskInfo = (table, row) => {
     console.log('table', table)
     console.log('row', row)
 }
+
+//填写的表单
+const htmlRef = ref(null)
+const htmlForm = ref({})
+const htmlLoading = ref(false)
+const htmlRender = (form) => {
+    htmlForm.value = form
+}
 </script>
 
 <style lang="scss" scoped>

+ 6 - 0
src/views/tasks/components/hc-data/task-review.vue

@@ -495,5 +495,11 @@ const taskTabsClick = (key) => {
             }
         }
     }
+    .hc-task-html-form-body {
+        height: 100%;
+        .hc-table-form-data-item .el-scrollbar__view {
+            height: auto;
+        }
+    }
 }
 </style>

+ 135 - 0
src/views/tasks/components/html-form/html.js

@@ -0,0 +1,135 @@
+export default `
+<table cellspacing="0" style="border-collapse: collapse;">
+    <colgroup>
+        <col width="22px">
+        <col width="117px">
+        <col width="176px">
+        <col width="145px">
+        <col width="245px">
+    </colgroup>
+    <tbody>
+    <tr xy_type="1,false,5,false">
+        <td colspan="5" exceval="1" style="color:rgb(0,0,0);font-family:宋体;font-size:14.0pt;background-color:rgb(255,255,255);border-bottom-color:000000;border-bottom-style:double;border-bottom-width:3;font-weight:bold;vertical-align:center;text-align:center;word-wrap:inherit;height:49px;"
+        title="单位名称:">
+            <el-input type="text" style="width:100%;height:100%;" v-model="formData.key1"></el-input>
+        </td>
+    </tr>
+    <tr xy_type="1,false,5,false">
+        <td colspan="5" exceval="2" style="color:rgb(0,0,0);font-family:宋体;font-size:14.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:double;border-top-width:3;font-weight:bold;vertical-align:center;text-align:center;word-wrap:inherit;height:46px;">咨询意见单</td>
+    </tr>
+    <tr xy_type="1,false,5,false">
+        <td colspan="3" exceval="3" style="color:rgb(0,0,0);font-family:宋体;font-size:12.0pt;background-color:rgb(255,255,255);border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:30px;" title=""></td>
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:12.0pt;background-color:rgb(255,255,255);border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;font-weight:bold;vertical-align:center;text-align:right;word-wrap:inherit;height:30px;">咨询编号:</td>
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:12.0pt;background-color:rgb(255,255,255);border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;font-weight:bold;text-decoration:underline;vertical-align:center;text-align:left;word-wrap:inherit;height:30px;"
+        title="咨询编号:">
+            <el-input v-model="formData.key2" style="width:100%;height:100%;"></el-input>
+        </td>
+    </tr>
+    <tr xy_type="2,true,5,true">
+        <td colspan="2" exceval="4" style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:57px;">项目名称:</td>
+        <td colspan="3" exceval="5" style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:57px;"
+        title="项目名称:" gscolor='11'>
+            <el-input disabled v-model="formData.key3" style="width:100%;height:100%;"></el-input>
+        </td>
+    </tr>
+    <tr xy_type="2,true,5,true">
+        <td colspan="2" x1="1" x2="2" y1="5" y2="5" exceval="6" style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:34px;">原申请书编号:</td>
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:34px;"
+        title="原申请书编号:">
+            <el-input type="text" v-model="formData.key4" style="width:100%;height:100%;"></el-input>
+        </td>
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:34px;">要求付款额度</td>
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:34px;"
+        title="要求付款额度">
+            <el-input type="text" v-model="formData.key5" style="width:100%;height:100%;"></el-input>
+        </td>
+    </tr>
+    <tr xy_type="2,true,5,true">
+        <td colspan="2" exceval="7" style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:42px;">申请书收到时间:</td>
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:42px;"
+        title="申请书收到时间:">
+            <el-input type="text" v-model="formData.key6" style="width:100%;height:100%;"></el-input>
+        </td>
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:42px;">意见发出日期:</td>
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:42px;"
+            title="意见发出日期:">
+            <el-date-picker v-model="formData.key7" style="width:100%;height:100%;" placeholder="年月日"></el-date-picker>
+        </td>
+    </tr>
+    <tr xy_type="2,true,5,true">
+        <td rowspan="2" exceval="10" style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:146px; width: 6px; writing-mode: vertical-lr;">申请进度款摘录</td>
+        <td colspan="4" exceval="8" style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:left;word-wrap:inherit;height:146px; "
+        title="申请进度款摘录">
+            <el-input type="textarea" v-model="formData.key8" style="width:100%;height:100%;" :rows="0"></el-input>
+        </td>
+    </tr>
+    <tr xy_type="2,true,4,false">
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:38px;">摘录人</td>
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:38px;"
+        title="申请进度款摘录_摘录人">
+            <el-input type="text" v-model="formData.key9" style="width:100%;height:100%;"></el-input>
+        </td>
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:38px;">时间</td>
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:38px;"
+         title="申请进度款摘录_摘录人_时间" gscolor='11'>
+            <el-input disabled v-model="formData.key10" style="width:100%;height:100%;"></el-input>
+        </td>
+    </tr>
+    <tr xy_type="2,true,5,true">
+        <td rowspan="5" exceval="11" style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:300px;width: 6px;writing-mode: vertical-lr;">造价机构现场咨询意见</td>
+        <td colspan="4" rowspan="2" exceval="12" style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:18px;"
+            title="造价机构现场咨询意见">
+            <el-input type="textarea" v-model="formData.key11" style="width:100%;height:100%;" :rows="4"></el-input>
+        </td>
+    </tr>
+    <tr height="310" xy_type="2,true,0,false"></tr>
+    <tr xy_type="2,true,4,false">
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:44px;">本期审核进度款 (元)</td>
+        <td colspan="3" exceval="9" style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:44px;"
+            title="造价机构现场咨询意见_本期审核进度款 (元)">
+            <el-input type="text" v-model="formData.key12" style="width:100%;height:100%;"></el-input>
+        </td>
+    </tr>
+    <tr xy_type="2,true,4,false">
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:65px;">截止上期已累计审 批进度款(元)</td>
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:left;word-wrap:inherit;height:65px;"
+            title="造价机构现场咨询意见_截止上期已累计审 批进度款(元)" gscolor='11'>
+            <el-input disabled type="text" v-model="formData.key13" style="width:100%;height:100%;"></el-input>
+        </td>
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:65px;">截止本期已累计审核进 度款(元)</td>
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:left;word-wrap:inherit;height:65px;"
+            title="造价机构现场咨询意见_截止上期已累计审 批进度款(元)_截止本期已累计审核进 度款(元)" gscolor='11'>
+            <el-input disabled type="text" v-model="formData.key14" style="width:100%;height:100%;"></el-input>
+        </td>
+    </tr>
+    <tr xy_type="2,true,4,false">
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:51px;">现场造价人员</td>
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:51px;"
+            title="造价机构现场咨询意见_现场造价人员">
+            <el-input type="text" v-model="formData.key15" style="width:100%;height:100%;"></el-input>
+        </td>
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:51px;">负责人</td>
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:51px;"
+            title="造价机构现场咨询意见_现场造价人员_负责人">
+            <el-input type="text" v-model="formData.key16" style="width:100%;height:100%;"></el-input>
+        </td>
+    </tr>
+    <tr xy_type="2,true,5,false">
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:59px;"
+            title="项目名称:_原申请书编号:_申请书收到时间:_申请进度款摘录_造价机构现场咨询意见">
+            <el-input type="text" v-model="formData.key17" style="width:100%;height:100%;"></el-input>
+        </td>
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:59px;">建设单位签收</td>
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:59px;"
+            title="建设单位签收">
+            <el-input type="text" v-model="formData.key18" style="width:100%;height:100%;" placeholder=""></el-input>
+        </td>
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:59px;">日期</td>
+        <td style="color:rgb(0,0,0);font-family:宋体;font-size:10.0pt;background-color:rgb(255,255,255);border-top-color:000000;border-top-style:solid;border-top-width:1;border-bottom-color:000000;border-bottom-style:solid;border-bottom-width:1;border-left-color:000000;border-left-style:solid;border-left-width:1;border-right-color:000000;border-right-style:solid;border-right-width:1;vertical-align:center;text-align:center;word-wrap:inherit;height:59px;"
+            title="建设单位签收_日期" gscolor='11'>
+            <el-input disabled v-model="formData.key19" style="width:100%;height:100%;"></el-input>
+        </td>
+    </tr>
+    </tbody>
+</table>
+`

+ 22 - 1
yarn.lock

@@ -314,7 +314,7 @@
   resolved "http://39.108.216.210:9000/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz#b6c75a56a1947cc916ea058772d666a2c8932f31"
   integrity sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==
 
-"@element-plus/icons-vue@^2.3.1":
+"@element-plus/icons-vue@^2.0.6", "@element-plus/icons-vue@^2.3.1":
   version "2.3.1"
   resolved "http://39.108.216.210:9000/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz#1f635ad5fdd5c85ed936481525570e82b5a8307a"
   integrity sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==
@@ -3012,6 +3012,27 @@ yocto-queue@^0.1.0:
   resolved "http://39.108.216.210:9000/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
   integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
 
+z-element-plus@^1.1.4:
+  version "1.1.4"
+  resolved "http://39.108.216.210:9000/z-element-plus/-/z-element-plus-1.1.4.tgz#abc2684329ec7d509f7d2aac6f113f9f6ff27c4c"
+  integrity sha512-v6dNZNb9yFVDwkVG5m/x1Ev8rDvbY69drzDHAgOSeehYTGuYRKJLTUml1vK/GSLi/PXRQihquVZ4gpc9Jv8h3w==
+  dependencies:
+    "@ctrl/tinycolor" "^3.4.1"
+    "@element-plus/icons-vue" "^2.0.6"
+    "@floating-ui/dom" "^1.0.1"
+    "@popperjs/core" "npm:@sxzz/popperjs-es@^2.11.7"
+    "@types/lodash" "^4.14.182"
+    "@types/lodash-es" "^4.17.6"
+    "@vueuse/core" "^9.1.0"
+    async-validator "^4.2.5"
+    dayjs "^1.11.3"
+    escape-html "^1.0.3"
+    lodash "^4.17.21"
+    lodash-es "^4.17.21"
+    lodash-unified "^1.0.2"
+    memoize-one "^6.0.0"
+    normalize-wheel-es "^1.2.0"
+
 zip-stream@^6.0.1:
   version "6.0.1"
   resolved "http://39.108.216.210:9000/zip-stream/-/zip-stream-6.0.1.tgz#e141b930ed60ccaf5d7fa9c8260e0d1748a2bbfb"