Эх сурвалжийг харах

表单弹窗的测试开发

ZaiZai 2 жил өмнө
parent
commit
546dd6689a

+ 19 - 0
src/api/modules/api.js

@@ -0,0 +1,19 @@
+import {httpApi} from "../request/httpApi";
+
+export default {
+    async hcPostApi(form, msg = true) {
+        return httpApi({
+            url: '/api/' + form.url,
+            method: 'post',
+            params: form.params,
+            data: form.data
+        },msg);
+    },
+    async hcGetApi(form, msg = true) {
+        return httpApi({
+            url: '/api/' + form.url,
+            params: form.params,
+            method: 'get',
+        },msg);
+    },
+}

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

@@ -156,6 +156,8 @@ const handleBlur = () => {
     .hc-checkbox-group-input {
         position: absolute;
         z-index: -1;
+        right: 10px;
+        width: 10px;
     }
 }
 </style>

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

@@ -110,6 +110,8 @@ const handleBlur = () => {
     .hc-upload-input-src {
         position: absolute;
         z-index: -1;
+        right: 10px;
+        width: 10px;
     }
 }
 </style>

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

@@ -0,0 +1,351 @@
+<template>
+    <div class="hc-table-form-data-item" :id="`table-form-item-${keyId}`" :style="tableFormItemStyle">
+        <div :id="`table-form-${keyId}`" class="hc-excel-table-form"/>
+        <div v-if="isTableForm === false" class="hc-no-table-form">
+            <div class="table-form-no">
+                <img :src="notableform" alt=""/>
+                <div class="desc">暂无表单数据</div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import {ref, watch, onMounted, nextTick} from "vue"
+import {useAppStore} from "~src/store";
+import HTableForm from "~src/plugins/HTableForm"
+import notableform from '~src/assets/view/notableform.svg'
+import {getObjNullValue, isAsyncFunction, isString, getArrValue, deepClone} from "vue-utils-plus"
+
+const useAppState = useAppStore()
+
+//初始
+const props = defineProps({
+    tid: { // 树节点
+        type: [String, Number],
+        default: ''
+    },
+    kid: { // pkeyId
+        type: [String, Number],
+        default: ''
+    },
+    classify: { // 类型
+        type: [String, Number],
+        default: ''
+    },
+    api: { //请求方法函数列表
+        type: Object,
+        default: () => ({
+            dataInfo: null,
+            bussCols: null,
+            excelHtml: null
+        })
+    },
+})
+
+//初始变量
+const projectId = ref(useAppState.getProjectId)
+const contractId = ref(useAppState.getContractId)
+const keyId = ref(props.kid ? props.kid + '' : '')
+const treeId = ref(props.tid)
+const classify = ref(props.classify)
+const apis = ref(props.api)
+const tableFormItemStyle = ref('')
+
+//监听
+watch(() => [
+    props.tid,
+    props.kid,
+    useAppState.getProjectId,
+    useAppState.getContractId,
+    props.classify
+], ([tree_id, key_id, project_id, contract_id, cid]) => {
+    projectId.value = project_id
+    contractId.value = contract_id
+    treeId.value = tree_id
+    keyId.value = key_id ? key_id + '' : ''
+    classify.value = cid
+})
+
+//渲染完成
+onMounted(async () => {
+    let keys = []
+    const {dataInfo, bussCols, excelHtml} = apis.value
+    //获取已填写的数据
+    if (isAsyncFunction(dataInfo)) {
+        await getTableFormInfo(keyId.value, dataInfo)
+    }
+    //按键key列表
+    if (isAsyncFunction(bussCols)) {
+        keys = await getHtmlBussColsApi(keyId.value, bussCols)
+    }
+    //渲染表单
+    if (isAsyncFunction(excelHtml)) {
+        await getExcelHtml(keyId.value, excelHtml, keys)
+    }
+})
+
+//渲染状态变量
+const isTableForm = ref(false)
+const isTableRender = ref(false)
+const isRenderForm = ref(false)
+const tableFormInfo = ref({})
+
+//获取表单初始数据
+const getFormDataInit = () => {
+    return {
+        projectId: projectId.value,
+        contractId: contractId.value,
+        classify: classify.value,
+        pkeyId: keyId.value,
+        nodeId: treeId.value
+    }
+}
+
+//获取已填写的数据
+const getTableFormInfo = async (pkeyId, func) => {
+    if (pkeyId) {
+        const {error, code, data} = await func({
+            pkeyId: pkeyId
+        }, false)
+        const resData = getObjNullValue(data)
+        if (!error && code === 200 && resData) {
+            HTableForm.setPickerKey(resData)
+            tableFormInfo.value = {
+                ...resData,
+                ...getFormDataInit()
+            }
+        } else {
+            tableFormInfo.value = getFormDataInit()
+        }
+        console.log(tableFormInfo.value)
+    } else {
+        tableFormInfo.value = {}
+        window?.$message?.warning('pkeyId为空')
+    }
+}
+
+//获取按键切换输入框的key列表
+const getHtmlBussColsApi = async (pkeyId, func) => {
+    if (pkeyId) {
+        const {error, code, data} = await func({
+            pkeyId: pkeyId
+        }, false)
+        if (!error && code === 200) {
+            let keys = getArrValue(data);
+            for (let i = 0; i < keys.length; i++) {
+                if (keys[i].length <= 0) {
+                    keys.splice(i, 1)
+                }
+            }
+            return keys;
+        } else {
+            return [];
+        }
+    } else {
+        return [];
+    }
+}
+
+//获取模板标签数据
+const getExcelHtml = async (pkeyId, func, keys) => {
+    if (pkeyId) {
+        const {error, code, data} = await func({
+            pkeyId: pkeyId
+        }, false)
+        const resData = isString(data) ? data || '' : ''
+        if (!error && code === 200 && resData) {
+            isTableForm.value = true
+            //渲染表单
+            HTableForm.createForm({
+                template: resData,
+                tableForm: tableFormInfo.value,
+                keys: keys,
+                appId: `#table-form-${pkeyId}`,
+                onRight: (event, KeyName) => {
+                    onRightClick(pkeyId, event, KeyName)
+                },
+                //表单正则效验
+                onBlur: (event, key, reg, val, msg) => {
+                    setTableFormBlurReg(pkeyId, event, key, reg, val, msg)
+                }
+            })
+            isTableRender.value = true
+            isRenderForm.value = true
+            await nextTick(() => {
+                HTableForm.setByClassKeyup(keys)
+                const dom = document.getElementById(`table-form-item-${pkeyId}`)
+                tableFormItemStyle.value = `width: ${dom?.offsetWidth}px; height: ${dom?.offsetHeight}px;`
+            })
+        } else {
+            isTableForm.value = false
+            isTableRender.value = false
+            isRenderForm.value = false
+            tableFormItemStyle.value = ''
+            window?.$message?.warning('暂无表单')
+        }
+    } else {
+        isTableForm.value = false
+        isTableRender.value = false
+        isRenderForm.value = false
+        tableFormItemStyle.value = ''
+        window?.$message?.warning('pkeyId为空')
+    }
+}
+
+//正则效验
+const formRegExpJson = ref({})
+const setTableFormBlurReg = (pkeyId, event, key, reg, val, msg) => {
+    const dom = document.getElementById(key)?.parentElement ?? ''
+    if (dom) {
+        if (val && reg) {
+            let regx = new RegExp(reg);
+            let state = regx.test(val);
+            if (state) {
+                formRegExpJson.value = {}
+                dom.style = ''
+            } else {
+                formRegExpJson.value = {key, reg, val, msg, state}
+                dom.style = '--el-input-border-color: #fe0000; box-shadow: 0 0 0 2px #fe0000 inset;'
+                window?.$message?.warning(msg)
+            }
+        } else {
+            formRegExpJson.value = {}
+            dom.style = ''
+        }
+    } else {
+        formRegExpJson.value = {}
+        dom.style = ''
+    }
+}
+
+//事件
+const emit = defineEmits(['rightTap'])
+
+//鼠标右键事件
+const onRightClick = (pkeyId, event, KeyName) => {
+    //取光标位置
+    const specialDom = document.getElementById(KeyName + "")
+    const startPos = specialDom?.selectionStart || 0
+    const endPos = specialDom?.selectionEnd || 0
+    emit('rightTap', {event, KeyName, startPos, endPos, pkeyId})
+}
+
+//获取表单数据
+const getFormData = () => {
+    return tableFormInfo.value
+}
+
+//获取表单效验数据
+const getRegExpJson = () => {
+    return deepClone(formRegExpJson.value);
+}
+
+// 暴露出去
+defineExpose({
+    getFormData,
+    getRegExpJson
+})
+</script>
+
+<style lang="scss">
+.hc-table-form-data-item {
+    position: relative;
+    padding: 24px;
+    height: 100%;
+    overflow: hidden;
+    border: 8px solid #50545E;
+    .hc-excel-table-form {
+        position: relative;
+        display: flex;
+        justify-content: center;
+        td {
+            padding: 6px;
+            font-family: "EUDC", 宋体, v-sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !important;
+            .el-input {
+                background-color: #ffffff !important;
+                border-radius: 3px;
+                color: #606266;
+                .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 !important;
+                    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 {
+                height: 100%;
+                width: 100%;
+            }
+            //焦点
+            .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-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: 100%;
+            }
+        }
+        //非输入框颜色
+        td:not([titlexx]), td[titlexx*=''],
+        td:not([title]), td[title*=''] {
+            background-color: #f1f5f8 !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;
+            }
+        }
+    }
+}
+</style>

+ 96 - 2
src/test/index.vue

@@ -1,7 +1,15 @@
 <template>
     <div class="hc-page-box">
-        <HcCard title="测试">
-            <el-button type="primary">测试</el-button>
+        <HcCard>
+            <template #header>
+                <el-button type="primary">测试</el-button>
+            </template>
+
+            <div class="hc-drag-node-box" @mousewheel.prevent="dragNodeMousewheel">
+                <div class="hc-drag-node-content" :id="'drag-node-' + uuid" @mousedown="dragNodeMouseDown" :style="{zoom: zoomRef + '%'}">
+                    <HcTableForm kid="1572864967831453696" :api="apis"/>
+                </div>
+            </div>
 
         </HcCard>
     </div>
@@ -9,4 +17,90 @@
 
 <script setup>
 import {nextTick, onMounted, ref} from "vue";
+import HcTableForm from "~com/table-form/index.vue"
+import wbsApi from "~api/data-fill/wbs"
+import {getRandom} from "vue-utils-plus"
+
+const uuid = getRandom()
+const apis = ref({
+    dataInfo: wbsApi.getBussDataInfo,
+    bussCols: wbsApi.getHtmlBussCols,
+    excelHtml: wbsApi.getExcelHtml
+})
+
+onMounted(() => {
+
+})
+
+//放大缩小
+const zoomRef = ref(100)
+const dragNodeMousewheel = (event) => {
+    /* 获取当前页面的缩放比 若未设置zoom缩放比,则为默认100%,即1,原图大小 */
+    let zoom = parseInt(zoomRef.value + '') || 100
+    /* event.wheelDelta 获取滚轮滚动值并将滚动值叠加给缩放比zoom wheelDelta统一为±120,其中正数表示为向上滚动,负数表示向下滚动 */
+    zoom += event.wheelDelta / 12
+    /* 最小范围 和 最大范围 的图片缩放尺度 */
+    if (zoom >= 40 && zoom < 300) {
+        zoomRef.value = zoom
+    }
+    return false
+}
+
+const isDown = ref(false)
+const dragNodeMouseDown = (event) => {
+    // 阻止默认事件和冒泡
+    //event.preventDefault()
+    event.stopPropagation()
+    //获取相关dom元素
+    let dom = document.getElementById('drag-node-' + uuid)
+    //获取x坐标和y坐标
+    let clientX = event.clientX, clientY = event.clientY;
+
+    //获取左部和顶部的偏移量
+    let offsetLeft = dom.offsetLeft, offsetTop = dom.offsetTop;
+    //开关打开
+    isDown.value = true;
+
+    //设置样式
+    dom.style.cursor = 'move';
+
+    document.onmousemove = (e) => {
+        if (isDown.value === false) {
+            return;
+        }
+        //获取x和y
+        let nx = e.clientX;
+        let ny = e.clientY;
+        //计算移动后的左偏移量和顶部的偏移量
+        let nl = nx - (clientX - offsetLeft);
+        let nt = ny - (clientY - offsetTop);
+
+        dom.style.left = nl + 'px';
+        dom.style.top = nt + 'px';
+    }
+    document.onmouseup = () => {
+        //开关关闭
+        isDown.value = false;
+        dom.style.cursor = 'default';
+        document.onmousemove = null;
+        document.onmouseup = null;
+    }
+}
+
 </script>
+
+<style lang="scss">
+.hc-drag-node-box {
+    position: relative;
+    width: 100%;
+    height: 100%;
+    overflow: auto;
+    .hc-drag-node-content {
+        display: table;
+        text-align: center;
+        position: absolute;
+        left: 50%;
+        transform: translate(-50%, 0);
+    }
+}
+</style>

+ 1 - 6
src/views/data-fill/components/ListItem.vue

@@ -58,7 +58,7 @@
                             </div>
                         </div>
                     </template>
-                    <div :style="`height: calc(100vh - ${drawType ? '555px' : '386px'} - ${menuBarShow ? 50 : 0}px);`"
+                    <div :style="`height: calc(100vh - ${drawType ? '555px' : '386px'});`"
                          class="data-fill-list-item-content">
                         <div class="data-fill-table-form-box">
                             <div :id="`table-form-${item?.pkeyId}`" class="hc-excel-table-form-view"/>
@@ -498,9 +498,7 @@ const componentDetail = ref({
         value: [
             {label: '是', value: 1},
             {label: '否', value: 0},
-
         ]
-
     }
 })
 
@@ -1114,10 +1112,7 @@ const handleMenuSelect = ({key}) => {
         formulaModal.value = true
         console.log(tableFormItemNode.value, 'tableFormItemNode.value');
         getPanel()
-
-
     }
-
 }
 //获取公式面板数据
 const getPanel = async () => {