Browse Source

feat:[模板管理][组件抽离ing]

master
luojie 1 week ago
parent
commit
4bfea96ee7
13 changed files with 480 additions and 162 deletions
  1. +1
    -0
      src/assets/images/copy-icon.svg
  2. +1
    -0
      src/assets/images/question-icon.svg
  3. +1
    -0
      src/assets/images/record-icon.svg
  4. +16
    -5
      src/components/Template/BaseInfoFormPcakge.vue
  5. +271
    -36
      src/components/Template/CustomTable.vue
  6. +63
    -22
      src/components/Template/HandleFormItem.vue
  7. +1
    -1
      src/components/Template/LineLabel.vue
  8. +15
    -11
      src/components/Template/Table.vue
  9. +21
    -0
      src/components/Template/icons/Question.vue
  10. +3
    -1
      src/views/business/comps/template/TemplateTable.vue
  11. +54
    -75
      src/views/business/comps/template/comps/sp/Demo.vue
  12. +31
    -10
      src/views/business/comps/template/comps/sp/SWYPFXRYPZB.vue
  13. +2
    -1
      src/views/business/comps/template/mixins/templateMixin.js

+ 1
- 0
src/assets/images/copy-icon.svg View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1767343019086" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4571" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M796.444444 170.666667V85.333333H113.777778v739.555556h85.333333V227.555556a56.888889 56.888889 0 0 1 56.888889-56.888889h540.444444z m85.333334 0h56.888889a56.888889 56.888889 0 0 1 56.888889 56.888889v739.555555a56.888889 56.888889 0 0 1-56.888889 56.888889H256a56.888889 56.888889 0 0 1-56.888889-56.888889v-56.888889H85.333333a56.888889 56.888889 0 0 1-56.888889-56.888889V56.888889a56.888889 56.888889 0 0 1 56.888889-56.888889h739.555556a56.888889 56.888889 0 0 1 56.888889 56.888889v113.777778zM284.444444 256v682.666667h625.777778V256H284.444444z m526.222223 398.222222a14.222222 14.222222 0 0 1 14.222222 14.222222v56.888889a14.222222 14.222222 0 0 1-14.222222 14.222223h-426.666667a14.222222 14.222222 0 0 1-14.222222-14.222223v-56.888889a14.222222 14.222222 0 0 1 14.222222-14.222222h426.666667z m0-170.666666a14.222222 14.222222 0 0 1 14.222222 14.222222v56.888889a14.222222 14.222222 0 0 1-14.222222 14.222222h-426.666667a14.222222 14.222222 0 0 1-14.222222-14.222222v-56.888889a14.222222 14.222222 0 0 1 14.222222-14.222222h426.666667z" fill="#4ea2ff" p-id="4572"></path></svg>

+ 1
- 0
src/assets/images/question-icon.svg View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1767342719425" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1797" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M511.51393 63.894216c-114.5315 0-229.061976 43.508933-316.720432 131.167389-174.676321 174.676321-174.676321 458.764542 0 633.440863 87.658456 87.658456 202.188932 131.167389 316.720432 131.167389s229.062999-43.508933 316.720432-131.167389c174.676321-174.676321 174.676321-458.764542 0-633.440863C740.576929 107.403149 626.045429 63.894216 511.51393 63.894216zM511.51393 108.683305c52.466955 0 103.653755 10.237155 151.641699 29.432333 49.907667 20.475334 94.695732 49.907667 133.086088 88.937588 39.029922 38.390355 68.463278 83.179444 88.937588 133.086088 19.195178 47.987944 29.432333 99.174744 29.432333 151.641699s-10.237155 103.653755-29.432333 151.641699c-20.47431 49.907667-49.907667 94.695732-88.937588 133.086088-38.390355 39.029922-83.179444 68.463278-133.086088 88.937588-47.987944 19.195178-99.174744 29.432333-151.641699 29.432333-52.466955 0-103.653755-10.237155-151.641699-29.432333-49.907667-20.475334-94.695732-49.907667-133.086088-88.937588-39.029922-38.390355-68.463278-83.179444-88.937588-133.086088-19.195178-47.987944-29.432333-99.174744-29.432333-151.641699s10.237155-103.653755 29.432333-151.641699c20.475334-49.907667 49.907667-94.695732 88.937588-133.086088 38.390355-39.029922 83.179444-68.463278 133.086088-88.937588C407.860175 118.92046 459.046974 108.683305 511.51393 108.683305z" fill="#b2b2b2" p-id="1798"></path><path d="M511.51393 674.300456c-18.555611 0-34.55091 15.355733-34.55091 34.55091 0 18.555611 15.996322 33.911344 34.55091 33.911344 19.195178 0 34.55091-15.355733 34.55091-33.911344C546.065863 689.657212 530.709107 674.300456 511.51393 674.300456zM512.154519 280.799314c-42.2298 0-76.141144 10.877745-101.734032 33.911344-25.593911 22.394033-41.589211 55.026244-46.707788 97.895611l58.225099 7.0383c4.479011-31.991622 15.355733-55.665811 31.352055-70.381977 15.996322-15.355733 35.831067-22.394033 59.505255-22.394033 24.953322 0 46.068222 8.317433 63.343677 24.953322 16.635889 15.996322 24.953322 35.1915 24.953322 57.585533 0 11.517311-2.559289 23.034623-8.317433 33.271778-5.758144 10.237155-18.555611 23.674189-37.750789 40.949644-19.834744 17.275455-33.271778 30.072923-40.949644 39.029922-9.597589 12.156878-17.275455 24.313755-21.754466 36.470633-6.398734 15.996322-9.597589 35.1915-9.597589 56.945967l0.639566 17.275455 53.746088 0c0.639566-22.394033 1.919722-39.029922 4.479011-48.627511 3.198855-10.237155 7.0383-19.195178 12.796444-26.873044 5.758144-7.677866 17.275455-19.834744 35.831067-35.831067 26.873044-24.313755 45.428655-44.789089 55.026244-61.424978 8.958022-16.635889 14.0766-35.1915 14.0766-55.026244 0-34.55091-13.437034-63.984267-40.310078-88.298022C592.773651 292.956192 556.942585 280.799314 512.154519 280.799314z" fill="#b2b2b2" p-id="1799"></path></svg>

+ 1
- 0
src/assets/images/record-icon.svg View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1767343239332" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="13552" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M924.416 62.656H163.744c-19.104 0-34.592 14.336-34.592 32v834.656c0 17.696 15.488 32 34.592 32h760.672c19.136 0 34.592-14.304 34.592-32V94.656c0-17.664-15.488-32-34.592-32z m-29.728 802.656c0 17.696-14.304 32-32 32H225.344c-17.664 0-32-14.304-32-32v-704c0-17.664 14.336-32 32-32h637.344c17.696 0 32 14.336 32 32v704z" p-id="13553" fill="#4ea2ff"></path><path d="M129.152 192.64c-35.328 0-64 28.672-64 64s28.672 64 64 64 64-28.672 64-64-28.672-64-64-64z m0 80c-8.832 0-16-7.168-16-16s7.168-16 16-16 16 7.168 16 16-7.168 16-16 16zM129.152 448c-35.328 0-64 28.672-64 64s28.672 64 64 64 64-28.672 64-64c0-35.36-28.672-64-64-64z m0 80c-8.832 0-16-7.168-16-16s7.168-16 16-16 16 7.168 16 16-7.168 16-16 16zM129.152 703.328c-35.328 0-64 28.64-64 64 0 35.328 28.672 64 64 64s64-28.672 64-64c0-35.392-28.672-64-64-64z m0 80c-8.832 0-16-7.2-16-16 0-8.864 7.168-16 16-16s16 7.136 16 16c0 8.8-7.168 16-16 16zM766.88 288.64c0 17.664-14.304 32-32 32H351.232c-17.664 0-32-14.336-32-32s14.336-32 32-32H734.88c17.696 0 32 14.336 32 32zM766.88 512c0 17.664-14.304 32-32 32H351.232c-17.664 0-32-14.336-32-32s14.336-32 32-32H734.88c17.696 0 32 14.304 32 32zM766.88 735.328c0 17.664-14.304 32-32 32H351.232c-17.664 0-32-14.336-32-32 0-17.696 14.336-32 32-32H734.88c17.696 0 32 14.304 32 32z" p-id="13554" fill="#4ea2ff"></path></svg>

+ 16
- 5
src/components/Template/BaseInfoFormPcakge.vue View File

@ -1,5 +1,6 @@
<template>
<div>
<LineLabel v-if="label" :label = "label"/>
<div v-for="(item, index) in formConfig" :key="index">
<template v-if="item.type === 'cardItem'">
<div class="grid-container">
@ -58,6 +59,10 @@
<HandleFormItem :item="sItem" v-model="formFields[key]"
@copy="onCopy(sItem, key)" />
</div>
<div v-else-if="sItem.type === 'textarea'">
<HandleFormItem type="textarea" :item="sItem" v-model="formFields[key]"
@copy="onCopy(sItem, key)" />
</div>
</div>
</div>
@ -99,12 +104,18 @@
</template>
<script>
import HandleFormItem from "./HandleFormItem.vue"
import HandleFormItem from "./HandleFormItem.vue";
import LineLabel from "./LineLabel.vue";
export default {
components: {
HandleFormItem
HandleFormItem,
LineLabel
},
props: {
label:{//
type: String,
default: "",
},
formConfig: {
type: Array,
value: () => [],
@ -300,7 +311,7 @@ export default {
display: grid;
grid-template-columns: repeat(2, 1fr);
/* 默认2列 */
gap: 0 24px;
gap: 0 20px;
}
.gap2{
gap:0 64px;
@ -315,8 +326,8 @@ export default {
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
margin-top: 24px;
padding: 24px;
margin-top: 20px;
padding: 20px;
border-radius: 5px 5px;
}

+ 271
- 36
src/components/Template/CustomTable.vue View File

@ -2,43 +2,79 @@
<div class="custom-table-wrapper">
<div class="custom-table-header">
<div class="custom-table-row">
<div
v-for="(col, index) in columns"
:key="index"
class="custom-table-cell header-cell"
:style="{ width: col.width ? col.width + 'px' : 'auto' }"
>
<div v-for="(col, index) in columns" :key="index" class="custom-table-cell header-cell"
:style="{ width: col.width ? col.width + 'px' : 'auto' }">
<div class="header-cell-content">
<div>{{ col.label }}</div>
<template v-if="col.showSelect&& col.options">
<select v-model="col.selected" @change="onHeaderSelectChange(index, $event)">
<option value="" disabled>{{ col.placeholder || '请选择' }}</option>
<option
v-for="opt in col.options"
:key="opt.value"
:value="opt.value"
>
{{ opt.label }}
</option>
</select>
</template>
<template v-if="col.headerSelectKey && col.headerOptions">
<HandleFormItem type="select" class="header-select" :item="getHeaderItem(col)"
v-model="headerSelectFields[col.headerSelectKey]" @change="onHeaderSelectChange(index, $event)" />
</template>
</div>
</div>
<!-- 默认操作栏 -->
<div class="custom-table-cell header-cell" :style="{ width: '80px' }">
<div class="header-cell-content">
<div>操作</div>
</div>
</div>
</div>
</div>
<div class="custom-table-body">
<div
v-for="(row, rowIndex) in dataSource"
:key="rowIndex"
class="custometable-row"
>
<div
v-for="(col, colIndex) in columns"
:key="colIndex"
class="custom-table-cell body-cell"
:style="{ width: col.width ? col.width + 'px' : 'auto' }"
>
{{ row[col.prop] }}
<div v-for="(row, rowIndex) in localDataSource" :key="rowIndex" class="custometable-row">
<div v-for="(col, colIndex) in columns" :key="colIndex" class="custom-table-cell body-cell"
:style="{ width: col.width ? col.width + 'px' : 'auto' }">
<div class="inner-table-cell">
<div>
<template v-if="col.bodyType === 'input'">
<HandleFormItem type="input" class="body-input" :item="getBodyItem(col)" v-model="row[col.prop]" @change="onBodyValueChange(rowIndex, colIndex, $event)" />
</template>
<template v-else-if="col.bodyType === 'inputNumber'">
<HandleFormItem type="inputNumber" class="body-input-number" :item="getBodyItem(col)"
v-model="row[col.prop]" @change="onBodyValueChange(rowIndex, colIndex, $event)" />
</template>
<template v-else-if="col.bodyType === 'select'">
<HandleFormItem type="select" class="body-select" :item="getBodyItem(col)" v-model="row[col.prop]" @change="onBodyValueChange(rowIndex, colIndex, $event)" />
</template>
<template v-else>
{{ row[col.prop] }}
</template>
</div>
<div class="m-l-5">
<template v-if="col.bodySubType === 'inputNumber'">
<HandleFormItem type="inputNumber" :item="getBodySubItem(col)"
v-model="row[col.bodySubKey]" @change="onBodySubValueChange(rowIndex, colIndex, $event)" />
</template>
<!-- 预填才显示精度输入框 -->
<template v-else-if="col.bodySubType === 'precisionNumber'&& $store.state.template.templateStatus === 'preFill'">
<HandleFormItem type="inputNumber" class="sub-input-number" :item="getPrecisionNumberItem(col)"
v-model="row[col.bodySubKey]" @change="onBodySubValueChange(rowIndex, colIndex, $event)" />
</template>
<template v-else>
{{ row[col.bodySubKey] }}
</template>
</div>
</div>
</div>
<!-- 默认操作栏 -->
<div class="custom-table-cell body-cell" :style="{ width: '80px' }">
<div class="inner-table-cell">
<el-popconfirm
confirm-button-text='确认'
cancel-button-text='取消'
icon="el-icon-info"
icon-color="red"
title="确认删除当前数据?"
@confirm = "deleteRow(rowIndex)"
>
<el-button slot="reference" type="text" size="small" class="delete-button" >
删除
</el-button>
</el-popconfirm>
</div>
</div>
</div>
</div>
@ -46,8 +82,12 @@
</template>
<script>
import HandleFormItem from "./HandleFormItem.vue"
export default {
name: 'CustomTable',
components: {
HandleFormItem
},
props: {
columns: {
type: Array,
@ -63,9 +103,168 @@ export default {
required: true
}
},
data() {
return {
localDataSource: [],
headerSelectFields: {}
}
},
watch: {
dataSource: {
immediate: true,
handler(newData) {
this.localDataSource = JSON.parse(JSON.stringify(newData));
//
}
},
columns: {
immediate: true,
handler(newColumns) {
this.initHeaderSelectValues();
}
}
},
methods: {
onHeaderSelectChange(colIndex, event) {
this.$emit('header-select-change', colIndex, event.target.value);
//
initHeaderSelectValues() {
const headerSelectObj = {};
this.columns.map(col => {
if(col.headerSelectKey){
headerSelectObj[col.headerSelectKey] = col.defaultValue || col.headerOptions[0].value || ""
}
});
console.log(headerSelectObj,"headerSelectObj")
this.headerSelectFields = headerSelectObj;
},
//
getFormData() {
// columns
//
const validateResult = this.validateFormData();
return new Promise((resolve,reject)=>{
if(validateResult.valid){
resolve({
dataSource: [...this.localDataSource],
headerSelectFields: this.headerSelectFields,
})
}else{
this.$message.error(validateResult.errors[0].error);
reject(validateResult.errors[0].error)
}
})
},
//
validateFormData() {
const templateStatus = this.$store.state.template.templateStatus;
const errors = [];
//
this.localDataSource.forEach((row, rowIndex) => {
//
this.columns.forEach((col, colIndex) => {
// fillType
if (col.bodyFillType === templateStatus || col.bodySubType === templateStatus) {
//
const mainValue = row[col.prop];
if (this.isValueEmpty(mainValue)) {
errors.push({
rowIndex,
colIndex,
field: col.prop,
label: col.label,
error: `请填写${col.label}`
});
}
//
if (col.bodySubKey) {
const subValue = row[col.bodySubKey];
if (this.isValueEmpty(subValue)) {
errors.push({
rowIndex,
colIndex,
field: col.bodySubKey,
label: `${col.label}单位`,
error: `请填写${col.label}单位`
});
}
}
}
});
});
return {
valid: errors.length === 0,
errors: errors
};
},
//
isValueEmpty(value) {
if (value === null || value === undefined || value === '') {
return true;
}
if (typeof value === 'string' && value.trim() === '') {
return true;
}
if (Array.isArray(value) && value.length === 0) {
return true;
}
return false;
},
//
onHeaderSelectChange(colIndex, value) {
this.headerSelectValues[colIndex] = value;
this.$emit('header-select-change', colIndex, value);
},
//
onBodyValueChange(rowIndex, colIndex, value) {
const col = this.columns[colIndex];
this.localDataSource[rowIndex][col.prop] = value;
this.$emit('body-value-change', rowIndex, colIndex, value);
},
//
onBodySubValueChange(rowIndex, colIndex, value) {
const col = this.columns[colIndex];
this.localDataSource[rowIndex][col.bodySubKey] = value;
this.$emit('body-sub-value-change', rowIndex, colIndex, value);
},
getHeaderItem(col) {
return {
fillType: col.fillType,
options: col.headerOptions,
label: ""
}
},
getBodyItem(col) {
return {
fillType: col.bodyFillType,
options: col.bodyOptions,
maxLength: col.bodyMaxLength,
label: ""
}
},
getBodySubItem(col) {
return {
fillType: col.bodySubFillType,
options: col.bodySubOptions,
label: "",
}
},
getPrecisionNumberItem(col) {
return {
fillType: col.bodySubFillType,
options: col.bodySubOptions,
label: "",
placeholder:"请输入保留小数位数"
}
},
//
deleteRow(rowIndex) {
this.localDataSource.splice(rowIndex, 1);
this.$emit('row-delete', rowIndex);
}
}
};
@ -78,6 +277,22 @@ export default {
overflow: hidden;
font-size: 14px;
color: #606266;
margin-top: 20px;
}
.inner-table-cell{
display: flex;
align-items: center;
justify-content: center;
}
.m-l-5{
margin-left: 5px;
}
.sub-input-number{
width: 145px;
.el-input-number--mini{
width: 145px;
}
}
/* 表头 */
@ -89,7 +304,14 @@ export default {
}
.custom-table-body {
max-height: 300px; /* 可根据需要调整或由父组件控制 */
max-height: 300px;
/* 可根据需要调整或由父组件控制 */
}
.header-cell-content {
display: flex;
align-items: center;
justify-content: center;
}
/* 共同行样式 */
@ -103,6 +325,9 @@ export default {
display: table;
width: 100%;
table-layout: fixed;
&:not(:last-child) {
border-bottom: 1px solid #ebeef5;
}
}
/* 单元格 */
@ -140,7 +365,8 @@ export default {
background-color: #fff;
font-size: 13px;
color: #606266;
appearance: none; /* 隐藏默认箭头(可选) */
appearance: none;
/* 隐藏默认箭头(可选) */
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6,9 12,15 18,9'%3e%3c/polyline%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: right 8px center;
@ -152,7 +378,8 @@ export default {
.custom-table-wrapper {
display: flex;
flex-direction: column;
max-width: 100%; /* 父容器决定宽度 */
max-width: 100%;
/* 父容器决定宽度 */
overflow-x: auto;
}
@ -160,4 +387,12 @@ export default {
.custom-table-body {
min-width: 100%;
}
.header-select {
width: 100px;
margin-left: 5px;
}
.delete-button{
color: red;
}
</style>

+ 63
- 22
src/components/Template/HandleFormItem.vue View File

@ -4,14 +4,31 @@
<el-input v-if="type === 'input'" :maxlength="item.maxlength || 30" :disabled="getDisabled()"
:class="item.fillType | getFillType"
:placeholder="item.placeholder ? item.placeholder : ('请输入' + item.label)"
v-model="inputValue" />
v-model="inputValue" @input="onInputChange" @change="onInputChange" />
<el-input v-else-if="type === 'textarea'" :maxlength="item.maxlength || 30" :disabled="getDisabled()"
:class="item.fillType | getFillType"
type = "textarea"
show-word-limit
resize = "none"
:rows="item.rows || 3"
:placeholder="item.placeholder ? item.placeholder : ('请输入' + item.label)"
v-model="inputValue" @input="onInputChange" @change="onInputChange" />
<el-input-number v-else-if="type === 'inputNumber'"
:maxlength="item.maxlength || 30"
:disabled="getDisabled()"
:controls = "item.controls || false"
:min = "item.min || 0"
:precision="item.precision"
:class="item.fillType | getFillType"
:placeholder="item.placeholder ? item.placeholder : ('请输入' + item.label)"
v-model="inputValue" @change="onInputChange" />
<el-select v-else-if="type === 'select'" class="flex1"
:multiple = "item.multiple"
:class="item.fillType | getFillType"
v-model="inputValue"
:disabled="getDisabled()"
:placeholder="item.placeholder ? item.placeholder : ('请选择' + item.label)"
@change = "onSelectChange"
@change = "onInputChange"
>
<el-option v-for="op in item.options" :key="op.value" :label="op.label"
:value="op.value">
@ -23,21 +40,26 @@
v-model="inputValue"
:disabled="getDisabled()"
format="yyyy/MM/DD HH:mm:ss" value-format="yyyy/MM/DD HH:mm:ss"
:placeholder="item.placeholder ? item.placeholder : ('请选择' + item.label)">
:placeholder="item.placeholder ? item.placeholder : ('请选择' + item.label)"
@change="onInputChange">
</el-date-picker>
</div>
<!-- qc才能操作 -->
<div class="handle-row" v-if="isShowHandle()">
<i class="el-icon-question"></i>
<el-checkbox></el-checkbox>
<span @click="onCopy">复制</span>
<span>稽查轨迹</span>
<el-checkbox class = "ml-5"></el-checkbox>
<Question class="handle-icon" :class = "getQuestionColor()"/>
<img @click="onCopy" src="@/assets/images/copy-icon.svg" class="handle-icon" alt=""/>
<img src="@/assets/images/record-icon.svg" class="handle-icon" alt=""/>
</div>
</div>
</template>
<script>
import Question from "./icons/Question.vue"
export default {
components: {
Question
},
props: {
type: {//form input/select
type:String,
@ -67,15 +89,7 @@ export default {
},
watch: {
value(newVal) {
console.log(newVal,"value")
this.inputValue = newVal
},
inputValue(newVal) {
if(this.type === "input"){
this.$emit('input', newVal)
}else{
this.$emit('change', newVal)
}
}
},
filters: {
@ -90,6 +104,17 @@ export default {
},
methods: {
//question
getQuestionColor(){
//gray green 绿 orange
return "green"
},
//
onInputChange(val) {
const value = val !== undefined ? val : this.inputValue;
this.$emit('input', value);
this.$emit('change', value);
},
//
isShowHandle(){
const {fillType} = this.item;
@ -120,9 +145,6 @@ export default {
onBlur(val){
this.$emit("blur",val)
},
onSelectChange(val){
this.$emit("change",val)
},
},
}
</script>
@ -139,13 +161,32 @@ export default {
.handle-row {
margin-left: 10px;
display: flex;
align-items: center;
cursor: pointer;
}
.w-100{
width: 100%;
}
.handle-icon{
width: 18px;
height: 18px;
margin-left: 5px;
}
.ml-5{
margin-left: 5px;
}
.orange{
color: #f9c588;
}
.green{
color: green;
}
.gray{
color: #b2b2b2;
}
.orange-border {
input {
input, textarea {
border-color: #f9c588;
&:focus {
@ -163,7 +204,7 @@ export default {
}
.green-border {
input {
input, textarea {
border-color: green;
&:focus {
@ -181,7 +222,7 @@ export default {
}
.blue-border {
input {
input, textarea {
border-color: #4ea2ff;
&:focus {

+ 1
- 1
src/components/Template/LineLabel.vue View File

@ -23,7 +23,7 @@
display: flex;
justify-content: flex-start;
text-align: left;
margin-top: 20px;
.line {
width: 2px;
float: left;

+ 15
- 11
src/components/Template/Table.vue View File

@ -1,14 +1,16 @@
<template>
<el-table
:data="dataSource"
>
<el-table-column
v-for="(item) in columns"
:prop="item.prop"
:key = "item.prop"
:label="item.label">
</el-table-column>
</el-table>
<div class="mt-20">
<el-table
:data="dataSource"
>
<el-table-column
v-for="(item) in columns"
:prop="item.prop"
:key = "item.prop"
:label="item.label">
</el-table-column>
</el-table>
</div>
</template>
<script>
@ -29,5 +31,7 @@
</script>
<style lang="scss" scoped>
.mt-20 {
margin-top: 20px;
}
</style>

+ 21
- 0
src/components/Template/icons/Question.vue View File

@ -0,0 +1,21 @@
<template>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg
t="1767342719425" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
fill="currentColor" p-id="1797" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
<path
d="M511.51393 63.894216c-114.5315 0-229.061976 43.508933-316.720432 131.167389-174.676321 174.676321-174.676321 458.764542 0 633.440863 87.658456 87.658456 202.188932 131.167389 316.720432 131.167389s229.062999-43.508933 316.720432-131.167389c174.676321-174.676321 174.676321-458.764542 0-633.440863C740.576929 107.403149 626.045429 63.894216 511.51393 63.894216zM511.51393 108.683305c52.466955 0 103.653755 10.237155 151.641699 29.432333 49.907667 20.475334 94.695732 49.907667 133.086088 88.937588 39.029922 38.390355 68.463278 83.179444 88.937588 133.086088 19.195178 47.987944 29.432333 99.174744 29.432333 151.641699s-10.237155 103.653755-29.432333 151.641699c-20.47431 49.907667-49.907667 94.695732-88.937588 133.086088-38.390355 39.029922-83.179444 68.463278-133.086088 88.937588-47.987944 19.195178-99.174744 29.432333-151.641699 29.432333-52.466955 0-103.653755-10.237155-151.641699-29.432333-49.907667-20.475334-94.695732-49.907667-133.086088-88.937588-39.029922-38.390355-68.463278-83.179444-88.937588-133.086088-19.195178-47.987944-29.432333-99.174744-29.432333-151.641699s10.237155-103.653755 29.432333-151.641699c20.475334-49.907667 49.907667-94.695732 88.937588-133.086088 38.390355-39.029922 83.179444-68.463278 133.086088-88.937588C407.860175 118.92046 459.046974 108.683305 511.51393 108.683305z"
fill="currentColor" p-id="1798"></path>
<path
d="M511.51393 674.300456c-18.555611 0-34.55091 15.355733-34.55091 34.55091 0 18.555611 15.996322 33.911344 34.55091 33.911344 19.195178 0 34.55091-15.355733 34.55091-33.911344C546.065863 689.657212 530.709107 674.300456 511.51393 674.300456zM512.154519 280.799314c-42.2298 0-76.141144 10.877745-101.734032 33.911344-25.593911 22.394033-41.589211 55.026244-46.707788 97.895611l58.225099 7.0383c4.479011-31.991622 15.355733-55.665811 31.352055-70.381977 15.996322-15.355733 35.831067-22.394033 59.505255-22.394033 24.953322 0 46.068222 8.317433 63.343677 24.953322 16.635889 15.996322 24.953322 35.1915 24.953322 57.585533 0 11.517311-2.559289 23.034623-8.317433 33.271778-5.758144 10.237155-18.555611 23.674189-37.750789 40.949644-19.834744 17.275455-33.271778 30.072923-40.949644 39.029922-9.597589 12.156878-17.275455 24.313755-21.754466 36.470633-6.398734 15.996322-9.597589 35.1915-9.597589 56.945967l0.639566 17.275455 53.746088 0c0.639566-22.394033 1.919722-39.029922 4.479011-48.627511 3.198855-10.237155 7.0383-19.195178 12.796444-26.873044 5.758144-7.677866 17.275455-19.834744 35.831067-35.831067 26.873044-24.313755 45.428655-44.789089 55.026244-61.424978 8.958022-16.635889 14.0766-35.1915 14.0766-55.026244 0-34.55091-13.437034-63.984267-40.310078-88.298022C592.773651 292.956192 556.942585 280.799314 512.154519 280.799314z"
fill="currentColor" p-id="1799"></path>
</svg>
</template>
<script>
export default {
}
</script>
<style lang="scss" scoped></style>

+ 3
- 1
src/views/business/comps/template/TemplateTable.vue View File

@ -11,10 +11,11 @@
//
import SP001 from './comps/sp/SP001';
import SWYPFXRYPZB from "./comps/sp/SWYPFXRYPZB.vue";
import Demo from "./comps/sp/Demo.vue";
export default {
name: "TemplateTable",
components: {
SP001,SWYPFXRYPZB
SP001,SWYPFXRYPZB ,Demo
},
props: {
sn: {
@ -32,6 +33,7 @@ export default {
if (!this.componentMap) {
this.componentMap = {
'SP001': 'SWYPFXRYPZB',
// 'SP001': 'Demo',
}
}
return this.componentMap

+ 54
- 75
src/views/business/comps/template/comps/sp/Demo.vue View File

@ -6,18 +6,16 @@
src="@/assets/images/detail-title.png" /></div>
<div class="detail-content">
<div class="content">
<LineLabel label = "试验基本信息"/>
<BaseInfoFormPcakge ref = "baseInfo" :formConfig = "formConfig" :formData = "formData"/>
<LineLabel class="mt-20" label = "试验试剂信息"/>
<TableList class="mt-20" :columns = "sysjColumns" :dataSource = "dataSource"/>
<LineLabel class="mt-20" label = "仪器使用信息"/>
<TableList class="mt-20" :columns = "yqsColumns" :dataSource = "dataSource"/>
<LineLabel class="mt-20" label = "存储条件"/>
<BaseInfoFormPcakge ref = "storageCondition" :formConfig = "storageFormConfig" :formData = "formData"/>
<LineLabel class="mt-20" label = "操作步骤"/>
<BaseInfoFormPcakge label = "试验基本信息" ref = "baseInfo" :formConfig = "formConfig" :formData = "formData"/>
<LineLabel label = "试验试剂信息"/>
<TableList :columns = "sysjColumns" :dataSource = "dataSource"/>
<LineLabel label = "仪器使用信息"/>
<TableList :columns = "yqsColumns" :dataSource = "dataSource"/>
<BaseInfoFormPcakge label = "存储条件" ref = "storageCondition" :formConfig = "storageFormConfig" :formData = "formData"/>
<LineLabel label = "操作步骤"/>
<div class="template-form-item">
<BaseInfoFormPcakge ref = "stepFormPackage" :formConfig = "stepFormConfig" :formData = "formData"/>
<!-- <CustomTable class="mt-20" :columns = "stepColumns" :dataSource = "stepDataSource"/> -->
<CustomTable ref = "stepTable" :columns = "stepColumns" :dataSource = "stepDataSource"/>
</div>
<Step ref = "stepRef"></Step>
</div>
@ -34,6 +32,11 @@ import TableList from "@/components/Template/Table";
import Step from "@/components/Template/Step";
import templateMixin from "../../mixins/templateMixin";
import CustomTable from '@/components/Template/CustomTable.vue'
const volumeUnitOptions = [
{ label: 'mg', value: 'mg' },
{ label: 'ng', value: 'ng' },
]
export default {
name: "SWYPFXRYPZB",
components: { BaseInfoFormPcakge,LineLabel,TableList,Step,CustomTable },
@ -55,75 +58,50 @@ export default {
data() {
return {
dataSource:[{name:"名称1"}],
stepDataSource:[{
code1:"目标溶液编号1",
code1:"目标溶液编号1",
code1:"目标溶液编号1",
code1:"目标溶液编号1",
code1:"目标溶液编号1",
code1:"目标溶液编号1",
code1:"目标溶液编号1",
code1:"目标溶液编号1",
code1:"目标溶液编号1",
code2:"起始溶液编号1",
code3:"预设起始溶液体积1",
code4:"实际起始溶液体积1",
code5:"预设稀释液体积1",
code6:"实际稀释液体积1",
code7:"预设目标溶液浓度1",
code8:"实际目标溶液浓度1",
}],
stepColumns:[
{label:"目标溶液编号",prop:"code1",width: 120},
{label:"起始溶液编号",prop:"code2",width: 120},
{label:"起始溶液编号",prop:"code2",width: 120},
{label:"起始溶液编号",prop:"code2",width: 120},
{label:"起始溶液编号",prop:"code2",width: 120},
{label:"起始溶液编号",prop:"code2",width: 120},
{label:"起始溶液编号",prop:"code2",width: 120},
{label:"起始溶液编号",prop:"code2",width: 120},
{label:"起始溶液编号",prop:"code2",width: 120},
{
label:"预设起始溶液体积",prop:"code3",showSelect: true,
options: [
{ label: 'mg', value: 'mg' },
{ label: 'ng', value: 'ng' },
]
},
stepDataSource:[
{
label:"实际起始溶液体积",prop:"code4",showSelect: true,width: 180,
options: [
{ label: 'mg', value: 'mg' },
{ label: 'ng', value: 'ng' },
]
code1:"目标溶液编号1",
code2:"起始溶液编号1",
},
{
label:"预设稀释液体积",prop:"code5",showSelect: true,width: 180,
options: [
{ label: 'mg', value: 'mg' },
{ label: 'ng', value: 'ng' },
]
code1:"目标溶液编号2",
code2:"起始溶液编号2",
},
],
stepColumns:[
{label:"目标溶液编号",prop:"code1",width: 120},
{
label:"实际稀释液体积",prop:"code6",showSelect: true,width: 180,
options: [
{ label: 'mg', value: 'mg' },
{ label: 'ng', value: 'ng' },
]
label:"起始溶液编号",prop:"code2",
width: 280,
bodyType:"input",
bodyFillType:"actFill",
bodyMaxLength:10,
},
{
label:"预设目标溶液浓度",prop:"code7",showSelect: true,width: 180,
options: [
{ label: 'mg', value: 'mg' },
{ label: 'ng', value: 'ng' },
]
label:"预设起始溶液体积",prop:"code3",
width: 280,
headerSelectKey:"volumeUnit1",
fillType:"preFill",
headerOptions:volumeUnitOptions,
defaultValue:"mg",
bodyType:"inputNumber",
bodySubType:"precisionNumber",
bodySubKey:"volumePrecision1",
bodyFillType:"preFill",
bodySubFillType:"preFill",
},
{
label:"实际目标溶液浓度",prop:"code8",showSelect: true,width: 180,
options: [
{ label: 'mg', value: 'mg' },
{ label: 'ng', value: 'ng' },
]
label:"预设起始溶液体积",prop:"code4",
width: 280,
headerSelectKey:"volumeUnit2",
fillType:"preFill",
headerOptions:volumeUnitOptions,
defaultValue:"mg",
bodyType:"inputNumber",
bodySubType:"precisionNumber",
bodySubKey:"volumePrecision2",
bodyFillType:"preFill",
bodySubFillType:"preFill",
},
],
sysjColumns:[
@ -267,25 +245,26 @@ export default {
mounted() {
setTimeout(()=>{
this.formData = {
// code:"code1",name:"name1",act:["1","-1"],taget1:"mg",targetCode1:"123456",taget1c:""
code:"code1",name:"name1",act:["1","-1"],taget1:"mg",targetCode1:"123456",taget1c:"可点击"
}
},3000)
},300)
setTimeout(()=>{
this.storageFormConfig[0].config.storageCondition1.options = [
{label:"白光",value:"1"},
{label:"黄光",value:"3"},
{label:"其他",value:"-1"},
]
},4000)
},400)
},
methods: {
async onSave(){
// const result1 = await this.$refs.baseInfo.getFormData();
// const result2 = await this.$refs.storageCondition.getFormData();
// const result3 = await this.$refs.stepRef.getFormData();
const result = await this.$refs.stepFormPackage.getFormData();
console.log(result,"reee")
// const result = await this.$refs.stepFormPackage.getFormData();
const result1 = await this.$refs.stepTable.getFormData();
console.log(result1,"reee")
}
}
};

+ 31
- 10
src/views/business/comps/template/comps/sp/SWYPFXRYPZB.vue View File

@ -6,21 +6,22 @@
src="@/assets/images/detail-title.png" /></div>
<div class="detail-content">
<div class="content">
<LineLabel label = "试验基本信息"/>
<BaseInfoFormPcakge ref = "baseInfo" :formConfig = "formConfig" :formData = "formData"/>
<LineLabel class="mt-20" label = "试验试剂信息"/>
<TableList class="mt-20" :columns = "sysjColumns" :dataSource = "dataSource"/>
<LineLabel class="mt-20" label = "仪器使用信息"/>
<TableList class="mt-20" :columns = "yqsColumns" :dataSource = "dataSource"/>
<LineLabel class="mt-20" label = "存储条件"/>
<BaseInfoFormPcakge ref = "storageCondition" :formConfig = "storageFormConfig" :formData = "formData"/>
<LineLabel class="mt-20" label = "操作步骤"/>
<BaseInfoFormPcakge label = "试验基本信息" ref = "baseInfo" :formConfig = "formConfig" :formData = "formData"/>
<LineLabel label = "试验试剂信息"/>
<TableList :columns = "sysjColumns" :dataSource = "dataSource"/>
<LineLabel label = "仪器使用信息"/>
<TableList :columns = "yqsColumns" :dataSource = "dataSource"/>
<BaseInfoFormPcakge label = "存储条件" ref = "storageConditionRef" :formConfig = "storageFormConfig" :formData = "formData"/>
<LineLabel label = "操作步骤"/>
<div class="template-form-item">
<BaseInfoFormPcakge ref = "stepFormPackage" :formConfig = "stepFormConfig" :formData = "formData"/>
</div>
<Step ref = "stepRef"></Step>
<BaseInfoFormPcakge label = "备注" ref = "remarkRef" :formConfig = "remarkConig" :formData = "formData"/>
</div>
</div>
<!-- <button @click = "onSave">保存</button> -->
</div>
</div>
</template>
@ -96,6 +97,22 @@ export default {
}
}
],
remarkConig:[
{
type:"cellItem",
config:{
remark:{
label:"",
type:"textarea",
fillType:"actFill",
span:1,
placeholder:"请输入备注",
maxlength:500,
rows:5
}
}
}
],
formConfig: [
{
type:"cardItem",
@ -243,7 +260,7 @@ export default {
methods: {
async getFormData(){
const baseData = await this.$refs.baseInfo.getFormData();
const conditionData = await this.$refs.storageCondition.getFormData();
const conditionData = await this.$refs.storageConditionRef.getFormData();
const stepData = await this.$refs.stepRef.getFormData();
const stepFormData = await this.$refs.stepFormPackage.getFormData();
return {
@ -253,6 +270,10 @@ export default {
...stepFormData,
}
},
async onSave(){
const formData = await this.getFormData();
console.log(formData,"formData")
}
}
};
</script>

+ 2
- 1
src/views/business/comps/template/mixins/templateMixin.js View File

@ -4,7 +4,8 @@ export default {
},
mounted() {
this.setTemplateStatus(this.fillType)
this.setTemplateStatus("preFill")
// this.setTemplateStatus(this.fillType)
},
methods: {

Loading…
Cancel
Save