| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542 |
- <template>
- <div class="ele-body">
- <el-button type="primary" @click="addHtml('customText')" v-if="edit"
- >插入自定义文本</el-button
- >
- <el-button type="primary" @click="addHtml('customTable')" v-if="edit"
- >插入表格</el-button
- >
- <!-- <el-button type="primary" @click="save()">保存</el-button> -->
- <div
- style="
- display: flex;
- width: 100%;
- padding: 10px;
- border: solid 1px #f1f1f1;
- margin-top: 10px;
- "
- >
- <vue-draggable
- v-model="list"
- group="project1"
- :animation="300"
- handle=".sort-handle"
- style="flex: 1"
- >
- <div
- class="demo-drag-list-item ele-cell"
- v-for="item in list"
- :key="item.id"
- >
- <div class="listItem">
- <i
- class="sort-handle el-icon-_nav move"
- style="display: none"
- v-if="edit"
- ></i>
- <i
- class="sort-handle el-icon-delete delete"
- v-if="edit"
- style="display: none"
- @click="del(item.id)"
- ></i>
- <customText
- :ref="'customTextRef' + item.id"
- style="flex: 1"
- v-if="item.type == 'customText'"
- :id="item.id"
- :form="item.value"
- :valueObj="item.valueObj"
- @editShow="editShowFn"
- @calculation="calculation"
- :edit="edit"
- ></customText>
- <customTable
- :ref="'customTextRef' + item.id"
- style="flex: 1"
- v-if="item.type == 'customTable'"
- :id="item.id"
- :form="item.value"
- :valueObj="item.valueObj"
- @calculation="calculation"
- @editShow="editShowFn"
- :edit="edit"
- ></customTable>
- </div>
- </div>
- </vue-draggable>
- <el-card class="box-card" v-show="editShow" style="width: 320px">
- <div slot="header" class="clearfix">
- <span>配置</span>
- <el-button
- style="float: right; padding: 3px 0"
- type="text"
- @click="editShow = false"
- >关闭</el-button
- >
- </div>
- <el-form label-width="80px">
- <el-form-item label="字段标识:" prop="id">
- <el-input
- v-model="domObj.id"
- placeholder=""
- @change="editInputChange"
- ></el-input>
- </el-form-item>
- <el-form-item label="宽度:" prop="width" v-if="!domObj.isNoWidth">
- <el-input
- v-model="domObj.width"
- type="number"
- placeholder=""
- @change="editInputChange"
- ></el-input>
- </el-form-item>
- <el-form-item label="是否只读:" prop="readonly">
- <el-select
- v-model="domObj.readonly"
- placeholder="请选择"
- @change="editInputChange"
- >
- <el-option :key="1" label="否" :value="1"> </el-option>
- <el-option :key="2" label="是" :value="2"> </el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="计算公式:" prop="readonly">
- <el-input
- :value="domObj.equation?.map((item) => item.value).join('')"
- type="textarea"
- placeholder=""
- disabled
- ></el-input>
- <el-button type="primary" @click="setEquation">配置公式</el-button>
- <el-button type="primary" @click="delEquation">重置</el-button>
- </el-form-item>
- </el-form>
- </el-card>
- </div>
- <ele-modal
- title="配置公式"
- :visible.sync="visible"
- :close-on-click-modal="false"
- append-to-body
- width="800px"
- resizable
- maxable
- >
- <div class="formula-builder__selects">
- <!-- 选择参数:从已填的非计算参数内容里取 -->
- <el-select
- v-model="equationUnit.paramSelect"
- placeholder="选择参数"
- size="mini"
- style="width: 100px; margin-right: 8px; flex-shrink: 0"
- @change="paramSelectChange($event, 'id')"
- filterable
- >
- <el-option
- v-for="item in idList"
- :key="item"
- :label="item"
- :value="item"
- />
- </el-select>
- <!-- 选择运算符 -->
- <el-select
- v-model="equationUnit.opSelect"
- placeholder="选择符号"
- size="mini"
- style="width: 100px; flex-shrink: 0; margin-right: 8px"
- @change="paramSelectChange($event, 'symbol')"
- >
- <el-option
- v-for="op in opSelectOptions"
- :key="op"
- :label="op"
- :value="op"
- />
- </el-select>
- <!-- 选择值 -->
- <el-input
- v-model="equationUnit.currentValue"
- placeholder="输入值"
- size="mini"
- style="width: 150px; flex-shrink: 0"
- >
- <template slot="append">
- <span
- style="cursor: pointer"
- @click="paramSelectChange(equationUnit.currentValue, 'value')"
- >确认</span
- >
- </template>
- </el-input>
- <!-- 替换或者追加 -->
- <el-select
- v-if="equationUnit.activeIndex != undefined"
- v-model="equationUnit.replaceOrAppend"
- placeholder="选择"
- size="mini"
- style="width: 80px; margin-left: 8px; flex-shrink: 0"
- >
- <el-option key="append" label="追加" value="append" />
- <el-option key="replace" label="替换" value="replace" />
- </el-select>
- <el-input
- v-model.number="domObj.units.decimalPlace"
- placeholder="小数位"
- size="mini"
- style="width: 120px; margin-left: 8px; flex-shrink: 0"
- >
- </el-input>
- <el-select
- v-model="domObj.units.takeValueMethod"
- placeholder="取值方法"
- size="mini"
- style="width: 100px; margin-left: 8px; flex-shrink: 0"
- >
- <el-option key="1" label="四舍五入" value="1" />
- <el-option key="2" label="去尾" value="2" />
- </el-select>
- </div>
- <!-- 已组装公式标签展示 -->
- <div
- v-if="equationUnit.equation.length"
- style="
- display: inline-flex;
- flex-wrap: wrap;
- max-width: 100%;
- margin-top: 5px;
- "
- >
- <el-tag
- v-for="(p, index) in equationUnit.equation"
- :key="index"
- size="mini"
- closable
- :type="equationUnit.activeIndex === index ? 'primary' : 'info'"
- @click="formulaPartsTagClick(index)"
- @close="tagItemDelete(index)"
- >
- {{ p.value }}
- </el-tag>
- </div>
- <el-input
- style="margin-top: 5px"
- :value="equationUnit.equation?.map((item) => item.value).join('')"
- type="textarea"
- placeholder=""
- disabled
- ></el-input>
- <div slot="footer" class="footer">
- <el-button type="primary" @click="editInputChange('equation')"
- >确认</el-button
- >
- <el-button @click="visible = false">返回</el-button>
- </div>
- </ele-modal>
- </div>
- </template>
- <script>
- import customText from './templateDiv/customText.vue';
- import customTable from './templateDiv/customTable.vue';
- import VueDraggable from 'vuedraggable';
- import { generateRandomString } from '@/utils/util';
- export default {
- components: {
- customText,
- VueDraggable,
- customTable
- },
- props: {
- edit: {
- default: true,
- type: Boolean
- }
- },
- computed: {},
- data() {
- return {
- list: [],
- editShow: false,
- visible: false,
- templateDivRef: '',
- domObj: { units: {} },
- idList: [],
- opSelectOptions: ['+', '-', '*', '/', '%', '(', ')'],
- equationUnit: {
- equation: [],
- activeIndex: '',
- paramSelect: '',
- opSelect: '',
- currentValue: '',
- replaceOrAppend: 'append'
- }
- };
- },
- mounted() {},
- created() {},
- methods: {
- // 计算
- calculation() {
- this.getValue();
- let equation = [];
- this.list.forEach((item) => {
- equation.push({
- id: item.id,
- equation: item.equation
- });
- });
- equation.forEach((item) => {
- for (const key in item.equation) {
- let { data, units } = this.getObjValue(); //每次计算都获取最新的值
- let value = '';
- if (item.equation[key].length) {
- item.equation[key].forEach((equationItem) => {
- if (
- equationItem.type == 'symbol' ||
- equationItem.type == 'value'
- ) {
- value += equationItem.value;
- } else if (equationItem.type == 'id') {
- value += Number(data[equationItem.value]) || 0;
- }
- });
- if (units[key]?.decimalPlace) {
- if (units[key]?.takeValueMethod) {
- value =
- units[key]?.takeValueMethod == 1
- ? parseFloat(eval(value).toFixed(units[key].decimalPlace))
- : this.truncateToFixedManual(
- eval(value),
- units[key].decimalPlace
- );
- } else {
- value = parseFloat(
- eval(value).toFixed(units[key].decimalPlace)
- );
- }
- } else {
- value = parseFloat(eval(value).toFixed(2));
- }
- if (this.$refs['customTextRef' + item.id][0]) {
- this.$refs['customTextRef' + item.id][0].equationValue({
- domId: key,
- value
- });
- }
- }
- }
- });
- },
- truncateToFixedManual(num, decimalPlaces) {
- let factor = Math.pow(10, decimalPlaces);
- return Math.floor(num * factor) / factor;
- },
- getObjValue() {
- this.getValue();
- let data = {};
- let units = {};
- this.list.forEach((item) => {
- units = { ...item.units, ...units };
- if (item.type == 'customText') {
- data = { ...item.valueObj, ...data };
- } else {
- item.valueObj.columns.forEach((row) => {
- row.forEach((cell) => {
- data[cell.id] = cell.value;
- });
- });
- }
- });
- return { data: data || {}, units: units || {} };
- },
- setEquation() {
- this.getValue();
- this.idList = [];
- if (this.domObj.equation) {
- this.equationUnit.equation = JSON.parse(
- JSON.stringify(this.domObj.equation)
- );
- this.equationUnit.activeIndex = this.domObj.equation.length;
- } else {
- this.equationUnit.equation = [];
- }
- this.list.forEach((item) => {
- if (item.type == 'customText') {
- for (let key in item.valueObj) {
- this.idList.push(key);
- }
- } else {
- item.valueObj.columns.forEach((row) => {
- row.forEach((cell) => {
- this.idList.push(cell.id);
- });
- });
- }
- });
- this.visible = true;
- },
- delEquation() {
- this.equationUnit.equation = [];
- this.editInputChange('equation');
- },
- tagItemDelete(index) {
- this.equationUnit.equation.splice(index, 1);
- },
- formulaPartsTagClick(index, row) {
- if (!this.equationUnit.replaceOrAppend) {
- // 默认追加
- this.equationUnit_replaceOrAppend = 'append';
- }
- if (
- this.equationUnit.activeIndex &&
- this.equationUnit.activeIndex === index
- ) {
- this.$set(this.equationUnit, 'activeIndex', undefined);
- } else {
- this.$set(this.equationUnit, 'activeIndex', index);
- }
- },
- paramSelectChange(val, type) {
- if (!val) {
- return;
- }
- if (type == 'id') {
- this.setValue({ type: 'id', value: val });
- this.equationUnit.paramSelect = null;
- } else if (type == 'symbol') {
- this.setValue({ type: 'symbol', value: val });
- this.equationUnit.opSelect = null;
- } else if (type == 'value') {
- this.setValue({ type: 'value', value: val });
- }
- },
- setValue(val) {
- if (this.equationUnit.activeIndex != undefined) {
- if (
- !this.equationUnit.replaceOrAppend ||
- this.equationUnit.replaceOrAppend === 'replace'
- ) {
- this.equationUnit.equation.splice(
- this.equationUnit.activeIndex,
- 1,
- val
- );
- } else if (this.equationUnit.replaceOrAppend === 'append') {
- this.equationUnit.equation.splice(
- this.equationUnit.activeIndex + 1,
- 0,
- val
- );
- // 追加后activeIndex后移一位
- this.$set(
- this.equationUnit,
- 'activeIndex',
- this.equationUnit.activeIndex + 1
- );
- }
- } else {
- this.equationUnit.equation.push(val);
- }
- },
- init(list) {
- this.list = JSON.parse(list);
- if (this.list.length) {
- this.$nextTick(() => {
- this.list.forEach((item) => {
- this.$refs['customTextRef' + item.id][0].init({
- form: item.value,
- valueObj: item.valueObj,
- equation: item.equation,
- units: item.units
- });
- });
- });
- }
- },
- editShowFn({ templateDivRef, domObj }) {
- this.templateDivRef = templateDivRef;
- this.$set(this, 'domObj', domObj);
- this.editShow = true;
- },
- editInputChange(type) {
- if (type == 'equation') {
- this.visible = false;
- this.domObj.equation = JSON.parse(
- JSON.stringify(this.equationUnit.equation)
- );
- }
- this.$nextTick(() => {
- this.$refs[this.templateDivRef][0].editInputChange(this.domObj);
- });
- },
- del(id) {
- this.list = this.list.filter((item) => item.id != id);
- },
- addHtml(type) {
- this.list.push({
- id: generateRandomString(6),
- type: type,
- value: '',
- valueObj: {}
- });
- },
- getValue() {
- this.list.forEach((item, index) => {
- let { form, valueObj, equation, units } =
- this.$refs['customTextRef' + item.id][0].getValue();
- this.$set(this.list[index], 'value', form);
- this.$set(this.list[index], 'valueObj', valueObj);
- this.$set(this.list[index], 'equation', equation);
- this.$set(this.list[index], 'units', units);
- });
- return this.list;
- }
- }
- };
- </script>
- <style scoped lang="scss">
- .listItem {
- padding: 5px;
- padding-top: 15px;
- border: solid 1px #f1f1f1;
- display: flex;
- width: 100%;
- align-items: center;
- margin-top: 3px;
- position: relative;
- }
- .sort-handle {
- font-size: 16px;
- position: absolute;
- left: 0;
- top: 0;
- }
- .move {
- cursor: move;
- }
- .delete {
- cursor: pointer;
- left: 20px;
- color: #f56c6c;
- }
- .listItem:hover {
- .sort-handle {
- display: block !important;
- }
- }
- </style>
|