schangxiang@126.com
2025-09-10 3d43ffa3152110b7823f9fa6320c08a6ae02358a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
<template>
  <el-form-item v-if="element && element.key" :class="{active: selectWidget && selectWidget.key === element.key, 'is_req': element.options.required,'no-margin':element.options.noMargin}" :label="element.options.noLabel?null:element.label" :label-width="element.options['label-width']!=null?element.options['label-width']+'px':null" class="widget-view" @click.native.stop="handleSelectWidget(index)">
    <template v-if="element.type === 'input'">
      <el-input v-model="element.options.defaultValue" :style="{width: element.options.width}" :placeholder="element.options.placeholder" v-bind="element.options"></el-input>
    </template>
 
    <template v-if="element.type === 'textarea'">
      <el-input v-model="element.options.defaultValue" :style="{width: element.options.width}" :placeholder="element.options.placeholder" :rows="5" type="textarea"></el-input>
    </template>
 
    <template v-if="element.type === 'number'">
      <el-input-number v-model="element.options.defaultValue" :disabled="element.options.disabled" :controls-position="element.options.controlsPosition" :style="{width: element.options.width}"></el-input-number>
    </template>
 
    <template v-if="element.type === 'radio'">
      <el-radio-group v-model="element.options.defaultValue" :style="{width: element.options.width}">
        <el-radio v-for="(item, index) in element.options.options" :key="item.value + index" :style="{display: element.options.inline ? 'inline-block' : 'block'}" :label="item.value">
          {{ element.options.showLabel ? item.label : item.value }}
        </el-radio>
      </el-radio-group>
    </template>
 
    <template v-if="element.type === 'checkbox'">
      <el-checkbox-group v-model="element.options.defaultValue" :style="{width: element.options.width}">
        <el-checkbox v-for="(item, index) in element.options.options" :key="item.value + index" :style="{display: element.options.inline ? 'inline-block' : 'block'}" :label="item.value">
          {{ element.options.showLabel ? item.label : item.value }}
        </el-checkbox>
      </el-checkbox-group>
    </template>
 
    <template v-if="element.type === 'cascader'">
      <el-cascader :placeholder="element.options.placeholder" :options="element.options.options" :style="{width: element.options.width}" filterable change-on-select></el-cascader>
    </template>
 
    <template v-if="element.type === 'tree'">
      <el-popover placement="bottom" title="标题" width="200" trigger="click">
        <el-input slot="reference" v-model="element.options.defaultValue" :style="{width: element.options.width}" :placeholder="element.options.placeholder" suffix-icon="el-icon-yrt-xiangxiajiantou1"></el-input>
      </el-popover>
    </template>
 
    <!-- 输入选择框 -->
    <template v-if="element.type === 'input-select'">
      <input-select v-model="element.options.defaultValue" :style="{width: element.options.width}" :options="[]">
      </input-select>
    </template>
 
    <!-- 表格选择框 -->
    <template v-if="element.type === 'table-select'">
      <table-select v-model="element.options.defaultValue" :input-width="element.options.width" :options="element.options">
      </table-select>
    </template>
 
    <template v-if="element.type === 'time'">
      <el-time-picker v-model="element.options.defaultValue" :is-range="element.options.isRange" :placeholder="element.options.placeholder" :start-placeholder="element.options.startPlaceholder" :end-placeholder="element.options.endPlaceholder" :readonly="element.options.readonly" :disabled="element.options.disabled" :editable="element.options.editable" :clearable="element.options.clearable" :arrow-control="element.options.arrowControl" :style="{width: element.options.width}">
      </el-time-picker>
    </template>
 
    <template v-if="['date', 'datetime'].indexOf(element.type)>=0">
      <el-date-picker v-model="element.options.defaultValue" :type="element.options.type" :is-range="element.options.isRange" :placeholder="element.options.placeholder" :start-placeholder="element.options.startPlaceholder" :end-placeholder="element.options.endPlaceholder" :readonly="element.options.readonly" :disabled="element.options.disabled" :editable="element.options.editable" :clearable="element.options.clearable" :style="{width: element.options.width}">
      </el-date-picker>
    </template>
 
    <template v-if="element.type === 'rate'">
      <el-rate v-model="element.options.defaultValue" :max="element.options.max" :disabled="element.options.disabled" :allow-half="element.options.allowHalf"></el-rate>
    </template>
 
    <template v-if="element.type === 'color'">
      <el-color-picker v-model="element.options.defaultValue" :disabled="element.options.disabled" :show-alpha="element.options.showAlpha"></el-color-picker>
    </template>
 
    <template v-if="element.type === 'select'">
      <el-select v-model="element.options.defaultValue" :disabled="element.options.disabled" :multiple="element.options.multiple" :clearable="element.options.clearable" :placeholder="element.options.placeholder" :style="{width: element.options.width}">
        <el-option v-for="item in element.options.options" :key="item.value" :value="item.value" :label="element.options.showLabel?item.label:item.value"></el-option>
      </el-select>
    </template>
 
    <template v-if="element.type==='switch'">
      <el-switch v-model="element.options.defaultValue" v-bind="element.options" :disabled="element.options.disabled">
      </el-switch>
    </template>
 
    <template v-if="element.type==='slider'">
      <el-slider v-model="element.options.defaultValue" :min="element.options.min" :max="element.options.max" :disabled="element.options.disabled" :step="element.options.step" :show-input="element.options.showInput" :range="element.options.range" :style="{width: element.options.width}"></el-slider>
    </template>
 
    <template v-if="element.type==='upload-image'">
      <el-upload :action="element.options.serverAction" :list-type="element.options.listType">
        <i v-if="element.options.listType=='picture-card'" class="el-icon-plus"></i>
        <el-button v-else size="small" type="primary">点击上传</el-button>
      </el-upload>
    </template>
 
    <template v-if="element.type==='imgupload'">
      <fm-upload v-model="element.options.defaultValue" :disabled="element.options.disabled" :style="{'width': element.options.width}" :width="element.options.size.width" :height="element.options.size.height" token="xxx" domain="xxx">
      </fm-upload>
    </template>
 
    <template v-if="element.type==='blank'">
    </template>
 
    <!--富文本编辑器-->
    <template v-if="element.type==='tinymce-editor'">
      <tinymce :height="element.options.size.height" v-model="element.options.defaultValue" />
    </template>
 
    <el-button v-if="selectWidget && selectWidget.key === element.key" title="删除" class="widget-action-delete" circle plain type="danger" @click.stop="handleWidgetDelete(index)">
      <i class="el-icon-yrt-shanchu2"></i>
    </el-button>
    <el-button v-if="selectWidget && selectWidget.key === element.key" title="复制" class="widget-action-clone" circle plain type="primary" @click.stop="handleWidgetClone(index)">
      <i class="el-icon-yrt-fuzhi4"></i>
    </el-button>
 
  </el-form-item>
</template>
 
<script>
import FmUpload from "./Upload";
import Tinymce from "@/components/Tinymce";
import InputSelect from "@/components/base/InputSelect";
import TableSelect from "@/components/base/TableSelect";
 
export default {
  components: {
    FmUpload,
    Tinymce,
    InputSelect,
    TableSelect
  },
  props: {
    element: {
      type: Object,
      default: () => {
        return {};
      }
    },
    select: {
      type: Object,
      default: () => {
        return {};
      }
    },
    index: {
      type: Number,
      default: null
    },
    fields: {
      type: Array,
      default: () => {
        return [];
      }
    },
    configType: {
      type: String,
      default: null
    }
  },
  data() {
    return {
      selectWidget: this.select
    };
  },
  watch: {
    select(val) {
      this.selectWidget = val;
    },
    selectWidget: {
      handler(val) {
        this.$emit("update:select", val);
      },
      deep: true
    }
  },
  methods: {
    handleSelectWidget(index) {
      this.selectWidget = this.fields[index];
      this.$emit("update:configType", "WidgetConfig");
    },
    handleWidgetDelete(index) {
      if (this.fields.length - 1 === index) {
        if (index === 0) {
          this.selectWidget = {};
        } else {
          this.selectWidget = this.fields[index - 1];
        }
      } else {
        this.selectWidget = this.fields[index + 1];
      }
 
      this.$nextTick(() => {
        this.fields.splice(index, 1);
      });
    },
    handleWidgetClone(index) {
      let cloneData = {
        ...this.fields[index],
        options: { ...this.fields[index].options },
        key: Date.parse(new Date()) + "_" + Math.ceil(Math.random() * 99999)
      };
 
      if (this.fields[index].type === "radio" || this.fields[index].type === "checkbox") {
        cloneData = {
          ...cloneData,
          options: {
            ...cloneData.options,
            options: cloneData.options.options.map(item => ({ ...item }))
          }
        };
      }
 
      this.fields.splice(index, 0, cloneData);
 
      this.$nextTick(() => {
        this.selectWidget = this.fields[index + 1];
      });
    }
  }
};
</script>
 
<style rel="stylesheet/scss" lang="scss" scoped>
.widget-view {
  div.el-input:not(.no-bg) {
    /deep/ input.el-input__inner[readonly] {
      background-color: #f5f7fa;
      cursor: not-allowed;
    }
  }
}
</style>