|
@@ -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>
|