Jelajahi Sumber

页面更新

sr 4 tahun lalu
induk
melakukan
8c4ef2eaad

+ 147 - 0
ruoyi-ui/src/components/FormItemComponent/index.vue

@@ -0,0 +1,147 @@
+<template>
+  <div class="FormComponent">
+      <div
+      class="FormItemComponent"
+      :style="setWidth"
+    >
+      <div
+        v-for="(item,index) in dataColRol"
+        :key="index"
+        class="FormItemComponent-item"
+        :style="setDiv(item)"
+      >
+        <component
+          :is="item.component"
+          :ref="'component_'+index"
+          :index="index"
+          :items="item.item"
+          :readonly="readonly"
+          @inputChange="inputChange"
+        />
+      </div>
+    </div>
+    <p v-if="buttonType">
+      <Button type="primary" @click="search">搜索</Button>
+      <Button type="fcdefault" @click="reset">重置</Button>
+    </p>
+  </div>
+</template>
+<script>
+import Vue from "vue";
+// import layoutAlgorithm from "../__utils__/layoutAlgorithm";
+export default {
+  name: "FormItemComponent",
+  props: {
+    formItemLists: {
+      type: Array,
+      default() {
+        return [];
+      }
+    },
+    buttonType: {
+      type: Boolean,
+      default() {
+        return true;
+      }
+    },
+    defaultColumn: {
+      type: Number,
+      default: 4
+    },
+    readonly: {
+      type: Boolean,
+      default: false
+    }
+  },
+  computed: {
+    // 通过layoutAlgorithm算法得到对应的位置坐标
+    dataColRol() {
+      // const list = layoutAlgorithm(this.defaultColumn, this.currentFormList);
+      // return Object.keys(list).reduce((temp, current) => {
+      //   // 计算显示行数
+      //   list[current].component = Vue.extend(list[current].component);
+      //   temp.push(list[current]);
+      //   return temp;
+      // }, []);
+    },
+    // 计算属性的 div 的坐标起始点
+    setDiv() {
+      return item =>
+        ` grid-column:${item.x}/${item.col + item.x};grid-row:${
+          item.y
+        }/${item.y + item.row};`;
+    },
+    // 计算属性的 div的排列格式
+    setWidth() {
+      // `this` 指向 vm 实例
+      const columns = Number(this.defaultColumn) || 4;
+      return `grid-template-columns: repeat(${columns},${100 / columns}%`;
+    }
+  },
+  watch: {
+    formItemLists() {
+      this.currentFormList = this.formItemLists.concat([]);
+    }
+  },
+  data() {
+    return {
+      // defaultColumn:4,  //默认一行4列
+      formData: {}, //保存form中输入数据
+      currentFormList: []
+    };
+  },
+  created() {
+    this.currentFormList = this.formItemLists.concat([]);
+  },
+  methods: {
+    inputChange(value, items, type) {
+      //有数据改变时
+      // if(Object.prototype.toString.call(value) === '[object Array]' && (!value[0] || !value[1])){
+      //   delete this.formData[items.filed]
+      // }else{
+      //   this.formData[items.filed] = value
+      // }
+      if (type && type === "select") {
+        this.formData[items.slotfiled] = value;
+      } else {
+        this.formData[items.filed] = value;
+      }
+      this.$emit("formChange", this.formData);
+    },
+    search() {
+      this.$emit("search", this.formData);
+    },
+    reset() {
+      this.formData = {};
+      this.currentFormList = this.currentFormList.concat([]);
+      this.$emit("search", this.formData);
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+.FormComponent {
+  padding: 2px 10px 10px 10px;
+  border: 1px solid rgba(228, 228, 228, 1);
+}
+
+.FormComponent > p {
+  padding-left: 108px;
+  margin-top: 10px;
+  display: flex;
+  width: 300px;
+
+  > button {
+    margin-right: 10px;
+  }
+}
+.FormItemComponent > div {
+  /*border:1px solid #fff;*/
+  box-sizing: border-box;
+}
+.FormItemComponent {
+  display: grid;
+  grid-template-columns: repeat(4, 25%);
+  grid-auto-rows: minmax(auto);
+}
+</style>

+ 664 - 0
ruoyi-ui/src/components/ItemComponent/index.vue

@@ -0,0 +1,664 @@
+<template>
+  <div class="ItemComponentRoot" v-if="!_items.hidden">
+    <span class="itemLabel">
+      <span v-if="_items.required" class="label-tip">*</span>
+      {{ _items.title }}:
+    </span>
+    <div class="itemComponent">
+      <Input
+        v-if="_items.type === 'input'"
+        v-model="_items.value"
+        :type="_items.props.type"
+        :clearable="_items.props.clearable"
+        :disabled="_items.props.disabled"
+        :readonly="_items.props.readonly"
+        :rows="_items.props.rows"
+        :autosize="_items.props.autosize"
+        :number="_items.props.number"
+        :autofocus="_items.props.autofocus"
+        :placeholder="_items.props.placeholder"
+        :size="_items.props.size"
+        :maxlength="_items.props.maxlength"
+        :icon="_items.props.icon"
+        :regx="_items.props.regx"
+        on-click="inputClick"
+        on-blur="inputBlur"
+        @on-change="inputChange"
+        @on-enert="inputEnter"
+        @on-focus="inputFocus"
+        @on-keyup="inputKeyUp"
+        @on-keydown="inputKeyDown"
+        @on-keypress="inputKeyPress"
+        @on-regx-check="inputRegxCheck"
+      />
+
+      <Checkbox
+        v-if="_items.type === 'checkbox'"
+        v-model="_items.value"
+        :disabled="_items.props.disabled"
+        :size="_items.props.size"
+        :circle="_items.props.circle"
+        @on-change="checkBoxChange"
+      />
+
+      <Select
+        v-if="_items.type === 'select'"
+        v-model="_items.value"
+        :clearable="_items.props.clearable"
+        :multiple="_items.props.multiple"
+        :multiple-type="_items.props.multipleType"
+        :disabled="_items.props.disabled"
+        :placeholder="_items.props.placeholder"
+        :not-found-text="_items.props['not-found-text']"
+        :label-in-value="_items.props['label-in-value']"
+        :placement="_items.props.placement"
+        :transfer="_items.props.transfer"
+        @on-change="selectChange"
+        @on-clear="selectClear"
+        @on-open-change="selectOpenChange"
+      >
+        <Option
+          v-for="item in _items.options"
+          :key="item.value"
+          :value="item.value"
+          :disabled="item.disabled"
+          :label="item.label"
+        >{{ item.label }}</Option>
+      </Select>
+
+      <i-switch v-if="_items.type === 'Switch'" v-model="_items.value" @on-change="SwitchChange" />
+
+      <DatePicker
+        v-if="_items.type === 'DatePicker'"
+        v-model="_items.value"
+        :type="_items.props.type"
+        :transfer="_items.props.transfer"
+        :format="_items.props.format"
+        :placement="_items.props.placement"
+        :placeholder="_items.props.placeholder"
+        :options="_items.props.options"
+        :open="_items.props.open"
+        :confirm="_items.props.confirm"
+        :size="_items.props.size"
+        :disabled="_items.props.disabled"
+        :clearable="_items.props.clearable"
+        :readonly="_items.props.readonly"
+        :editable="_items.props.editable"
+        @on-change="($event,event,instance) => datePickerChange(_items.value=$event,event,instance,_items.props.type)"
+        @on-clear="datePickerClear"
+      />
+
+      <DropMultiSelectFilter
+        v-if="_items.type === 'DropDownSelectFilter' && !_items.props.single"
+        :data="_items.props.data"
+        :single="_items.props.single"
+        :total-row-count="_items.props.totalRowCount"
+        :page-size="_items.props.pageSize"
+        :auto-data="_items.props.AutoData"
+        :disabled="_items.props.disabled"
+        :hidecolumns="_items.props.hidecolumns"
+        :data-empty-message="_items.props.dataEmptyMessage"
+        :default-selected="_items.props.defaultSelected"
+        :transfer="_items.props.transfer"
+        :columnsKey="_items.props.columnsKey"
+        :showColnameKey="_items.props.showColnameKey"
+        :placeholder="_items.props.placeholder"
+        @on-fkrp-selected="fkrpSelected"
+        @on-page-change="pageChange"
+        @on-input-value-change="inputValueChange"
+        @on-focus="fkrpSelectedInputFocus"
+        @on-blur="fkrpSelectedInputBlur"
+        @on-keyup="fkrpSelectedInputKeyup"
+        @on-keydown="fkrpSelectedInputKeydown"
+        @on-popper-show="fkrpSelectedPopperShow"
+        @on-popper-hide="fkrpSelectedPopperHide"
+        @on-clear="fkrpSelectedClear"
+      />
+
+      <DropDownSelectFilter
+        v-if="_items.type === 'DropDownSelectFilter' && _items.props.single"
+        :data="_items.props.data"
+        :single="_items.props.single"
+        :total-row-count="_items.props.totalRowCount"
+        :page-size="_items.props.pageSize"
+        :auto-data="_items.props.AutoData"
+        :disabled="_items.props.disabled"
+        :hidecolumns="_items.props.hidecolumns"
+        :data-empty-message="_items.props.dataEmptyMessage"
+        :default-selected="_items.props.defaultSelected"
+        :transfer="_items.props.transfer"
+        :columnsKey="_items.props.columnsKey"
+        :showColnameKey="_items.props.showColnameKey"
+        :placeholder="_items.props.placeholder"
+        @on-fkrp-selected="fkrpSelected"
+        @on-page-change="pageChange"
+        @on-input-value-change="inputValueChange"
+        @on-focus="fkrpSelectedInputFocus"
+        @on-blur="fkrpSelectedInputBlur"
+        @on-keyup="fkrpSelectedInputKeyup"
+        @on-keydown="fkrpSelectedInputKeydown"
+        @on-popper-show="fkrpSelectedPopperShow"
+        @on-popper-hide="fkrpSelectedPopperHide"
+        @on-clear="fkrpSelectedClear"
+      />
+      <div class="complex-input" v-if="_items.type === 'selectInput'">
+        <Input
+          v-model="_items.value"
+          :readonly="_items.props.readonly"
+          @on-change="inputChange"
+          @on-enert="inputEnter"
+          @on-focus="inputFocus"
+          @on-keyup="inputKeyUp"
+          @on-keydown="inputKeyDown"
+          @on-keypress="inputKeyPress"
+          @on-regx-check="inputRegxCheck"
+        >
+          <Select
+            v-if="_items.slot"
+            v-model="_items.slotValue"
+            slot="prepend"
+            style="width: 60px"
+            :transfer="true"
+            @on-change="selectChange"
+          >
+            <Option :value="0">指定</Option>
+            <Option :value="1">不限次数</Option>
+          </Select>
+        </Input>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+// import dataProp from "../config/props.config";
+export default {
+  name: "ItemComponent",
+  props: {
+    items: {
+      type: Object,
+      default() {
+        return {};
+      }
+    }
+  },
+  computed: {
+    _items() {
+      // 将设置的props和默认props进行assign
+      const item = JSON.parse(JSON.stringify(this.items));
+      // const item = this.items;
+      item.props = Object.assign(
+        {},
+        // dataProp[item.type].props,
+        this.items.props
+      );
+      item.event = Object.assign({}, this.items.event);
+      if (item.type === "DatePicker") {
+        if (
+          item.props.type === "datetimerange" ||
+          item.props.type === "daterange"
+        ) {
+          if (!item.value) {
+            item.value = [];
+          }
+        } else {
+          item.value = new Date();
+        }
+      }
+      return item;
+    }
+  },
+  methods: {
+    valueChange(type) {
+      // 值发生改变时触发  只要是item中的value改变就触发该方法,是为了让父组件数据同步
+      if(type&&type==='select'){
+        this.$emit("inputChange", this._items.slotValue, this._items,type);
+      }else{
+         this.$emit("inputChange", this._items.value, this._items);
+      }
+
+      // this.$emit("inputChange", this._items.value, this._items);
+    },
+    // Switch
+    SwitchChange() {
+      this.valueChange();
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "change") &&
+        typeof this._items.event.change === "function"
+      ) {
+        this._items.event.change(event);
+      }
+    },
+
+    // input event
+    inputChange(event, $this) {
+      this.valueChange();
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "change") &&
+        typeof this._items.event.change === "function"
+      ) {
+        this._items.event.change(event, $this);
+      }
+    },
+    inputEnter(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "enter") &&
+        typeof this._items.event.enter === "function"
+      ) {
+        this._items.event.enter(event, $this);
+      }
+    },
+    inputClick(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "click") &&
+        typeof this._items.event.click === "function"
+      ) {
+        this._items.event.click(event, $this);
+      }
+    },
+    inputFocus(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "focus") &&
+        typeof this._items.event.focus === "function"
+      ) {
+        this._items.event.focus(event, $this);
+      }
+    },
+    inputBlur(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "blur") &&
+        typeof this._items.event.blur === "function"
+      ) {
+        this._items.event.blur(event, $this);
+      }
+    },
+    inputKeyUp(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "keyup") &&
+        typeof this._items.event.keyup === "function"
+      ) {
+        this._items.event.keyup(event, $this);
+      }
+    },
+    inputKeyDown(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "keydown") &&
+        typeof this._items.event.keydown === "function"
+      ) {
+        this._items.event.keydown(event, $this);
+      }
+    },
+    inputKeyPress(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "keypress") &&
+        typeof this._items.event.keypress === "function"
+      ) {
+        this._items.event.keypress(event, $this);
+      }
+    },
+    inputRegxCheck(value, $this, errorValue) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "regxCheck") &&
+        typeof this._items.event.regxCheck === "function"
+      ) {
+        this._items.event.regxCheck(value, $this, errorValue);
+      }
+    },
+
+    // checkbox event
+    checkBoxChange(value, $this) {
+      this.valueChange();
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "change") &&
+        typeof this._items.event.change === "function"
+      ) {
+        this._items.event.change(value, $this);
+      }
+    },
+
+    // select input
+    selectChange(value, $this) {
+      if (this._items.type === "selectInput") {
+        this._items.slotValue = value;
+        this.valueChange("select");
+      } else {
+        this._items.value = value;
+        this.valueChange();
+      }
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "change") &&
+        typeof this._items.event.change === "function"
+      ) {
+        this._items.event.change(value, $this);
+      }
+    },
+    selectClear($this) {
+      this._items.value = null;
+      this.valueChange();
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "clear") &&
+        typeof this._items.event.clear === "function"
+      ) {
+        this._items.event.clear($this);
+      }
+    },
+    selectOpenChange(value, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "openChange") &&
+        typeof this._items.event.openChange === "function"
+      ) {
+        this._items.event.openChange(value, $this);
+      }
+    },
+    // datepick event
+    datePickerChange(value, type, $this) {
+      this.valueChange();
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "change") &&
+        typeof this._items.event.change === "function"
+      ) {
+        this._items.event.change(value, $this);
+      }
+    },
+    datePickerClear($this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "clear") &&
+        typeof this._items.event.clear === "function"
+      ) {
+        this._items.event.clear($this);
+      }
+    },
+
+    // TimePicker event
+    timePickerChange(value, timeType, $this) {
+      this.valueChange();
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "change") &&
+        typeof this._items.event.change === "function"
+      ) {
+        this._items.event.change(value, $this);
+      }
+    },
+    timePickerClear($this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "clear") &&
+        typeof this._items.event.clear === "function"
+      ) {
+        this._items.event.clear($this);
+      }
+    },
+
+    // fkrpSelected event
+    fkrpSelected(value, $this) {
+      this._items.value = value;
+      this.valueChange();
+      if (
+        Object.prototype.hasOwnProperty.call(
+          this._items.event,
+          "fkrpSelected"
+        ) &&
+        typeof this._items.event.fkrpSelected === "function"
+      ) {
+        this._items.event.fkrpSelected(value, $this);
+      }
+    },
+    inputValueChange(value, $this) {
+      this._items.value = value;
+      // this.valueChange();
+      if (
+        Object.prototype.hasOwnProperty.call(
+          this._items.event,
+          "inputValueChange"
+        ) &&
+        typeof this._items.event.inputValueChange === "function"
+      ) {
+        this._items.event.inputValueChange(value, $this);
+      }
+    },
+    fkrpSelectedClear($this) {
+      this._items.value = undefined;
+      this.valueChange();
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "clear") &&
+        typeof this._items.event.clear === "function"
+      ) {
+        this._items.event.clear($this);
+      }
+      if (
+        Object.prototype.hasOwnProperty.call(
+          this._items.event,
+          "inputValueChange"
+        ) &&
+        typeof this._items.event.inputValueChange === "function"
+      ) {
+        this._items.event.inputValueChange("", $this);
+      }
+    },
+    pageChange(value, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "pageChange") &&
+        typeof this._items.event.pageChange === "function"
+      ) {
+        this._items.event.pageChange(value, $this);
+      }
+    },
+    fkrpSelectedInputFocus(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "focus") &&
+        typeof this._items.event.focus === "function"
+      ) {
+        this._items.event.focus(event, $this);
+      }
+    },
+    fkrpSelectedInputBlur(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "blur") &&
+        typeof this._items.event.blur === "function"
+      ) {
+        this._items.event.blur(event, $this);
+      }
+    },
+    fkrpSelectedInputKeyup(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "keyup") &&
+        typeof this._items.event.keyup === "function"
+      ) {
+        this._items.event.keyup(event, $this);
+      }
+    },
+    fkrpSelectedInputKeydown(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "keydown") &&
+        typeof this._items.event.keydown === "function"
+      ) {
+        this._items.event.keydown(event, $this);
+      }
+    },
+    fkrpSelectedPopperShow($this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "on-show") &&
+        typeof this._items.event["on-show"] === "function"
+      ) {
+        this._items.event["on-show"]($this);
+      }
+    },
+    fkrpSelectedPopperHide($this) {
+      if (
+        Object.prototype.hasOwnProperty.call(
+          this._items.event,
+          "on-popper-hide"
+        ) &&
+        typeof this._items.event["on-popper-hide"] === "function"
+      ) {
+        this._items.event["on-popper-hide"]($this);
+      }
+    },
+
+    // AttachFilter event
+    attachFilterChange(value, $this) {
+      this._items.value = value;
+      this.valueChange();
+      if (
+        Object.prototype.hasOwnProperty.call(
+          this._items.event,
+          "popper-value"
+        ) &&
+        typeof this._items.event["popper-value"] === "function"
+      ) {
+        this._items.event["popper-value"]($this, value, "change", this.index);
+      }
+      if (
+        Object.prototype.hasOwnProperty.call(
+          this._items.event,
+          "inputValueChange"
+        ) &&
+        typeof this._items.event.inputValueChange === "function"
+      ) {
+        this._items.event.inputValueChange(value, $this);
+      }
+    },
+    attachFilterSelected(row, $this) {
+      this._items.value = row.label;
+      this._items.props.selected = row.value;
+      if (
+        Object.prototype.hasOwnProperty.call(
+          this._items.event,
+          "popper-value"
+        ) &&
+        typeof this._items.event["popper-value"] === "function"
+      ) {
+        this._items.event["popper-value"](
+          $this,
+          row.label,
+          row.value,
+          this.index
+        );
+      }
+    },
+    attachFilterInputFocus(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "focus") &&
+        typeof this._items.event.focus === "function"
+      ) {
+        this._items.event.focus(event, $this);
+      }
+    },
+    attachFilterInputBlur(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "blur") &&
+        typeof this._items.event.blur === "function"
+      ) {
+        this._items.event.blur(event, $this);
+      }
+    },
+    attachFilterInputKeyup(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "keyup") &&
+        typeof this._items.event.keyup === "function"
+      ) {
+        this._items.event.keyup(event, $this);
+      }
+    },
+    attachFilterInputKeydown(event, $this) {
+      if (
+        Object.prototype.hasOwnProperty.call(this._items.event, "keydown") &&
+        typeof this._items.event.keydown === "function"
+      ) {
+        this._items.event.keydown(event, $this);
+      }
+    },
+    attachFilterPopclick(event, row, targName, $this) {
+      if (targName !== "I" && event !== 1) {
+        // 打开弹窗
+
+        $this.showModal = true;
+        if (event !== 0) {
+          console.log(row.label);
+          this.filterDate = JSON.parse(row.label);
+        }
+      } else if (
+        targName === "I" &&
+        Object.prototype.hasOwnProperty.call(this._items.event, "on-delete") &&
+        typeof this._items.event["on-delete"] === "function"
+      ) {
+        this._items.event["on-delete"]($this, this._items, row.key, this.index);
+      }
+    },
+    attachFilterClear(event, $this) {
+      this._items.value = "";
+      if (
+        Object.prototype.hasOwnProperty.call(
+          this._items.event,
+          "popper-value"
+        ) &&
+        typeof this._items.event["popper-value"] === "function"
+      ) {
+        this._items.event["popper-value"]($this, "", [], this.index);
+      }
+    },
+    attachFilterPopperShow($this) {
+      if (
+        Object.prototype.hasOwnProperty.call(
+          this._items.event,
+          "popper-show"
+        ) &&
+        typeof this._items.event["popper-show"] === "function"
+      ) {
+        this._items.event["popper-show"]($this, this._items, this.index);
+      }
+    },
+    attachFilterOk($this) {
+      if (
+        Object.prototype.hasOwnProperty.call(
+          this._items.event,
+          "popper-value"
+        ) &&
+        typeof this._items.event["popper-value"] === "function"
+      ) {
+        if ($this._data.IN > 0) {
+          let value = `已经选中${$this._data.IN}条数据`;
+          this._items.value = value;
+          this.valueChange();
+          this._items.event["popper-value"](
+            $this,
+            value,
+            $this._data.IN,
+            this.index
+          );
+        }
+      }
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+.ItemComponentRoot {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  padding-top: 8px;
+
+  .itemLabel {
+    width: 100px;
+    margin-right: 8px;
+    text-align: right;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    display: inline-block;
+  }
+
+  .itemComponent {
+    flex: 1;
+    overflow: hidden;
+  }
+  .label-tip {
+    color: red;
+    font-size: 16px;
+    vertical-align: middle;
+    position: relative;
+    top: -1px;
+    right: 3px;
+  }
+}
+</style>

+ 128 - 0
ruoyi-ui/src/components/StandardTable/index.vue

@@ -0,0 +1,128 @@
+<template>
+  <div class="StandardTable">
+    <Page
+      v-if="showPage"
+     class="page"
+     :total="total"
+     show-total
+     show-sizer
+     show-elevator
+     transfer
+     :page-size="pageSize"
+     :current="currentPage"
+     :page-size-opts="pageSizeOpts"
+     v-on="standardTableEvent"
+    />
+
+    <div 
+      class="table"
+      v-if="showTable"
+    >
+      <Table
+        ref="table"
+        class="table"
+        :total="total"
+        :columns="columns"
+        :height = true
+        :data="data"
+        :border="border"
+        highlight-row
+        v-on="standardTableEvent"
+      >
+      </Table>
+
+
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  name:'StandardTable',
+  props:{
+    //事件回调
+    standardTableEvent:{
+      type:Object,
+      default() {
+        return {}
+      }
+    },
+    //分页属性
+    showPage:{  //控制分页是否展示
+      type:Boolean,
+      default:true
+    },
+    total:{
+      type:Number,
+      default:0
+    },
+    currentPage:{
+      type:Number,
+      default:1
+    },
+    pageSize:{
+      type:Number,
+      default:10
+    },
+    pageSizeOpts:{
+      type:Array,
+      default () {
+        return [10,20,30,40]
+      }
+    },
+
+    //表格属性
+    showTable:{  //控制表格是否展示
+      type:Boolean,
+      default:true
+    },
+    columns:{
+      type:Array,
+      default() {
+        return [];
+      }
+    },
+    data:{
+      type:Array,
+      default() {
+        return [];
+      }
+    },
+    border:{
+      type: Boolean,
+      default: false
+    }
+  },
+  watch:{
+    data () {
+      this.$refs.table.$el.getElementsByClassName('burgeon-table-body')[0].scrollTop = 0
+    }
+  },
+  methods:{
+  }
+}
+</script>
+<style lang="scss" scoped>
+.StandardTable{
+  display: flex;
+  overflow: hidden;
+  flex-direction: column;
+  .page{
+    margin-bottom: 8px;
+  }
+  
+  .table{
+    flex: 1;
+    overflow: hidden;
+    position: relative;
+    .noData{
+      position:absolute;
+      height: 200px;
+      top: 50%;
+      left: 50%;
+      margin-top: -90px;
+      margin-left: -80px;
+    }
+  }
+}
+</style>
+

+ 341 - 0
ruoyi-ui/src/components/listModalComponent/index.vue

@@ -0,0 +1,341 @@
+// 列表模型块组件
+<template>
+  <div class="listModalComponent" :class="(active && readonly)?'active':null" @click="ckeckModal">
+    <div class="preview" @mouseout="mouseout" :style="`backgroundImage:url(${items.url?items.url:''})`">
+      <!-- <img :src="items.url?items.url:''" alt=""> -->
+
+      <div class="more" v-show="!readonly" >
+        <Poptip trigger="click" placement="bottom-end" :width="100" ref="poptip" @mouseout.native.stop="">
+            <span class="dot"></span>
+            <span class="dot"></span>
+            <span class="dot"></span>
+
+            <ul slot="content" class="options">
+              <li @click="releaseProcess" v-if="items.status === 0 || items.status === 2">发布流程</li>
+              <li @click="editingProcess" v-if="items.status === 0">编辑流程</li>
+              <li @click="copyProcess" v-if="items.status === 0 || items.status === 2 ">复制流程</li>
+              <li @click="deleteProcess" v-if="items.status === 0 || items.status === 2 ">删除流程</li>
+              <li @click="stopProcess" v-if="items.status === 1">停用流程</li>
+              <li @click="previewProcess">预览</li>
+            </ul>
+        </Poptip>
+      </div>
+    </div>
+    <div class="info">
+      <p class="infoTitle">{{items.name}}</p>
+      <p>
+        <span class="creatTime">创建时间:{{items.createTime}}</span>
+      </p>
+
+      <span class="status" :class="statusClass">{{statusName}}</span>
+    </div>
+
+
+  </div>
+</template>
+<script>
+// import {DispatchEvent} from '../__utils__/dispatchEvent'
+import {  mapMutations } from 'vuex';
+export default {
+  name:'listModalComponent',
+  props:{
+    items:{
+      type:Object,
+      default () {
+        return {
+          name:'模型名称',
+          url:'',  //缩略图base64数据
+          createTime:'2019-03-18',
+          status:1,  //已发布是1  未发布是2
+        }
+      }
+    },
+    readonly:{
+      type:Boolean,
+      default: false
+    }
+  },
+  data () {
+    return {
+      active:false
+    }
+  },
+  computed:{
+    statusName () {
+      let str = ''
+      switch (this.items.status) {
+        case -1:
+          str = '已删除';
+          break;
+        case 0:
+          str = '未发布';
+          break;
+        case 1:
+          str = '已发布';
+          break;
+        case 2:
+          str = '已停用';
+          break;
+        case 3:
+          str = '草稿';
+          break;
+
+      }
+      return str
+    },
+    statusClass () {
+      return [{
+        'published':this.items.status === 1,
+        'notRelease':this.items.status === 0,
+        'stop':this.items.status === 2
+      }]
+    }
+  },
+  watch:{
+    readonly () {
+      this.active = false
+    }
+  },
+  methods:{
+    ...mapMutations(['currentChange','changeKeepAliveArray']),
+    mouseout () {
+      this.$refs.poptip.handleClose()
+    },
+    releaseProcess () {  //发布流程
+      this.$refs.poptip.handleClose()
+      this.$network.post('/p/cs/module/publish', {id:this.items.id}).then((res) => {
+        if(typeof this.items.event.queryLists === 'function'){
+          this.items.event.queryLists()
+        }
+      })
+    },
+    editingProcess () { //编辑流程
+      this.$refs.poptip.handleClose()
+      this.changeKeepAliveArray(['TemplateManagementLists'])
+      this.$router.push({ path: `/TemplateManagementNew/${this.items.id}` })
+      this.currentChange({
+        path:'/TemplateManagementLists'
+      });
+    },
+    deleteProcess () {  //删除流程
+      this.$refs.poptip.handleClose()
+      this.$network.post('/p/cs/module/remove', {id:this.items.id}).then((res) => {
+        if(typeof this.items.event.queryLists === 'function'){
+          this.items.event.queryLists()
+        }
+      })
+    },
+    stopProcess () {  //停用流程
+      this.$refs.poptip.handleClose()
+      this.$network.post('/p/cs/module/unpublish', {id:this.items.id}).then((res) => {
+        if(typeof this.items.event.queryLists === 'function'){
+          this.items.event.queryLists()
+        }
+      })
+    },
+    copyProcess () {  //复制流程
+      this.$refs.poptip.handleClose()
+      this.$network.post('/p/cs/module/copy', {id:this.items.id}).then((res) => {
+        if(res.data.resultCode === 0){
+          this.changeKeepAliveArray(['TemplateManagementLists'])
+          this.$router.push({ path: `/TemplateManagementNew/${res.data.data.id}` })
+          this.currentChange({
+            path:'/TemplateManagementLists'
+          });
+        }
+      })
+    },
+    previewProcess () { //预览流程
+      this.$refs.poptip.handleClose()
+      this.changeKeepAliveArray(['TemplateManagementLists'])
+      this.$router.push({ path: `/TemplateManagementNew/${this.items.id}/1` })
+      this.currentChange({
+        path:'/TemplateManagementLists'
+      });
+    },
+
+    ckeckModal () {  //选择流程
+      if(this.readonly){
+        this.active = !this.active
+        // DispatchEvent('modalClick',{
+        //   detail:{
+        //     items:this.items,
+        //     value:this.active
+        //   }
+        // })
+      }
+
+    }
+  }
+}
+</script>
+<style lang="scss" >
+.listModalComponent{
+  height:220px;
+  background:rgba(255,255,255,1);
+  box-shadow:0px 1px 5px 0px rgba(0,0,0,0.1)!important;
+  border-radius:4px;
+  cursor: pointer;
+  display: flex;
+  flex-direction: column;
+  border-radius:4px;
+  position: relative;
+
+  &.active{
+    border: 1px solid #5982E7;
+  }
+
+  .info{
+    height: 62px;
+    padding: 10px 0 8px 12px;
+    position: relative;
+
+    .infoTitle{
+      height: 20px;
+      font-size: 15px;
+      font-family: PingFangSC-Medium;
+      font-weight: 500;
+      color: #515a6e;
+      line-height: 20px;
+      margin-bottom: 6px;
+    }
+
+    >p:last-child{
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      span{
+        font-size:12px;
+        font-family:PingFangSC-Regular;
+        font-weight:400;
+        color:rgba(81,90,110,1);
+        line-height:16px;
+      }
+    }
+
+    span.status{
+      position: absolute;
+      right: 0;
+      bottom: 8px;
+      width:75px;
+      height:24px;
+      background:#B4B4B4;
+      border-radius:12px 0px 0px 12px;
+      color: white;
+      text-align: center;
+      line-height: 24px;
+      font-size:12px;
+      font-family:PingFangSC-Regular,PingFang SC;
+      font-weight:400;
+
+      &.published{
+        background:rgba(9, 161, 85, 1)
+      }
+
+      &.notRelease{
+        background:#B4B4B4
+      }
+
+      &.stop{
+        background: #ED4014;
+      }
+    }
+
+  }
+
+  .preview{
+    flex: 1;
+    border-radius:4px 4px 0px 0px;
+    overflow: hidden;
+    text-align: center;
+    background-size: contain;
+    background-repeat: no-repeat;
+    background-position: center;
+    img{
+      // width: 100%;
+      height: 100%;
+    }
+
+    &:hover{
+      // transform: translateY(-4px);
+      img{
+
+      }
+      .more{
+        display: block;
+      }
+    }
+
+    .more{
+      width: 40px;
+      height: 24px;
+      position: absolute;
+      top: 12px;
+      right: 12px;
+      background: white;
+      box-shadow:0px 1px 5px 0px rgba(0,0,0,0.1);
+      border-radius:4px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      display: none;
+
+    .burgeon-poptip{
+      width: 100%;
+      height: 100%;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      .burgeon-poptip-body{
+        padding: 5px 0;
+      }
+      .burgeon-poptip-rel{
+        display: flex;
+        width: 100%;
+        height: 100%;
+        align-items: center;
+        justify-content: center;
+      }
+
+      .burgeon-poptip-popper{
+        min-width: auto;
+      }
+    }
+
+
+    .dot{
+      width: 4px;
+      height: 4px;
+      background: rgba(51, 51, 51, 1);
+      border-radius: 50%;
+      display: inline-block;
+      margin-right: 4px;
+
+      &:last-child{
+        margin-right: 0;
+      }
+    }
+
+    .options{
+        li{
+          height: 29px;
+          display: flex;
+          align-items: center;
+          padding-left: 16px;
+          font-size:12px;
+          font-family:PingFangSC-Regular;
+          font-weight:400;
+          color:rgba(81,90,110,1);
+
+          &:hover{
+            background: rgba(243, 243, 243, 1);
+          }
+        }
+      }
+    }
+  }
+  &:hover{
+     transform: translateY(-4px);
+  }
+}
+</style>

+ 435 - 0
ruoyi-ui/src/views/activiti/modeler/index.vue

@@ -0,0 +1,435 @@
+<template>
+  <div class="TemplateManagementLists">
+    <div class="listContent">
+      <p class="title">模版管理</p>
+      <p class="buttonLists">
+        <Button type="primary" @click="searchData.page = 1;queryLists()">查询</Button>
+        <Button type="fcdefault" :disabled="listsStatus === 1" @click="addTemplate">新建模板</Button>
+        <Button type="fcdefault" v-if="listsStatus === 0" @click="templateMigration">模版迁移</Button>
+        <Button type="fcdefault" v-if="listsStatus === 1" @click="removeMigration">取消迁移</Button>
+        <Button type="fcdefault" v-if="listsStatus === 1" @click="perform">执行</Button>
+        <Button type="fcdefault" v-if="listsStatus === 1" @click="performAll">执行全部</Button>
+      </p>
+      <Alert show-icon closable v-if="listsStatus === 1">依次单击模板可进行多选模板</Alert>
+      <FormItemComponent
+        class="form"
+        :formItemLists="formLists"
+        :buttonType="false"
+        @formChange="formChange"
+      ></FormItemComponent>
+
+      <StandardTable
+        class="table"
+        :currentPage="searchData.page"
+        :pageSize="searchData.pageSize"
+        :pageSizeOpts="[20,40,60,80]"
+        :total="total"
+        :showTable="false"
+        :standardTableEvent="standardTableEvent"
+      >
+      </StandardTable>
+
+      <div class="list">
+        <FormItemComponent
+          class="listsForm"
+          :formItemLists="listsConfig"
+          :buttonType="false"
+          :readonly="listsStatus === 1"
+        ></FormItemComponent>
+
+        <div  class="noData" v-if="listsConfig.length == 0" >
+          <span>
+            暂无模版
+          </span>
+        </div>
+      </div>
+    </div>
+
+    <!-- 模版迁移弹窗 -->
+    <Modal
+      v-model="migrationModel"
+      title="模版迁移"
+      mask
+      :width="440"
+      :mask-closable="false"
+      >
+      <div class="migrationModelContent">
+        <p>
+          <Input v-model="serverUrl"  placeholder="请输入目标服务器地址" style="width: 320px" />
+        </p>
+      </div>
+
+      <p slot="footer">
+        <Button :loading="performloading" @click="migrationModel = false">取消</Button>
+        <Button :loading="performloading" type="primary" @click="performConfirm">确定</Button>
+      </p>
+    </Modal>
+  </div>
+</template>
+<script>
+import FormItemComponent from '@/components/FormItemComponent';
+import ItemComponent from '@/components/ItemComponent';
+import StandardTable from '@/components/StandardTable';
+import listModalComponent from '@/components/listModalComponent'
+// import router from '../config/router.config'
+import {  mapMutations,mapState } from 'vuex';
+export default {
+  name:'TemplateManagementLists',
+  components:{FormItemComponent,StandardTable},
+  data () {
+    return {
+      // 状态  0为搜索状态,1为模版迁移状态
+      listsStatus:0,
+      //表单配置
+      formLists:[
+        {
+          row:1,
+          col:1,
+          component:ItemComponent,
+          item:{
+            type:'input',
+            title:'模型名称',
+            filed:'name',
+            event:{
+              'keydown': (event) => {
+                if(event.keyCode === 13){
+                  this.searchData.page = 1
+                  this.queryLists()
+                }
+              }
+            }
+          }
+        },
+        {
+          row:1,
+          col:1,
+          component:ItemComponent,
+          item:{
+            type:'select',
+            title:'模版状态',
+            filed:'status',
+            options: [
+              { value: 1, label: '已发布'},
+              { value: 0, label: '未发布'},
+              { value: 2, label: '已停用'}
+            ],
+            props:{
+              multiple: true,
+              multipleType: true
+            },
+            value:[0,1]
+          }
+        },
+        {
+          row:1,
+          col:1,
+          component:ItemComponent,
+          item:{
+            type:'DatePicker',
+            title:'创建时间',
+            filed:'createTime',
+            value:[]
+          }
+        }
+      ],
+      //查询条件
+      searchData:{
+        page:1,
+        pageSize:20,
+        createTime:[],
+        status: [0,1]
+      },
+
+      //分页数据
+      total:0,
+      standardTableEvent:{
+        'on-change':(page) => {
+          this.searchData.page = page
+          this.queryLists()
+        },
+        'on-page-size-change':(pageSize) => {
+          this.searchData.page = 1
+          this.searchData.pageSize = pageSize
+          this.queryLists()
+        }
+      },
+      listsConfig:[  //列表数据
+      ],
+
+      // 迁移数据
+      selectModal:[],  //选中的迁移模版
+      migrationModel:false, //控制模版迁移弹窗
+      serverUrl:null,  //目标服务地址
+      migrationType:null,  //0为执行  1为执行全部
+      performloading:false
+
+    }
+  },
+  computed:{
+    ...mapState({
+      currentMenu:(state) =>{
+        return  state.currentMenu
+      }
+    })
+  },
+  watch:{
+    listsStatus () {
+      if(this.listsStatus === 0){
+        this.selectModal = []
+      }
+    }
+  },
+  methods:{
+    ...mapMutations(['currentChange','changeKeepAliveArray']),
+    formChange (data) {  //表单数据修改时,修改searchData数据
+      if(data.status){
+        this.formLists[0].item.value = data.name
+        this.formLists[1].item.value = data.status
+        this.formLists[2].item.value = data.createTime
+        // this.formLists = this.formLists.concat([])
+      }
+      this.searchData = Object.assign({},this.searchData,data)
+      if(Object.prototype.toString.call(this.searchData.status) === '[object Array]' && this.searchData.status.length === 0){
+        delete this.searchData.searchStatus
+        delete this.searchData.status
+      }
+
+      // this.queryLists()
+    },
+    queryLists () {  //查询列表
+      if(this.searchData.status && this.searchData.status.indexOf('bSelect-all') >= 0){
+        this.searchData.searchStatus = []
+      }else{
+        this.searchData.searchStatus = this.searchData.status
+      }
+
+      if(this.searchData.createTime && this.searchData.createTime[0] && this.searchData.createTime[1]){
+        this.searchData.startTime = new Date(this.searchData.createTime[0]).format('yyyy-MM-dd hh:mm')
+        this.searchData.endTime = new Date(this.searchData.createTime[1]).format('yyyy-MM-dd hh:mm')
+      }else{
+        this.searchData.startTime = ''
+        this.searchData.endTime = ''
+      }
+
+      let obj = Object.assign({},this.searchData)
+      delete obj.createTime
+      delete obj.status
+      this.$network.post('/p/cs/module/search', obj).then((res) => {
+        if(res.data.resultCode !== 0){
+          return
+        }
+        let data = res.data.data
+        this.total = data.total
+
+        this.listsConfig = data.records.reduce((arr,item) => {
+          let items = {
+            event:{
+              queryLists:() => {
+                this.queryLists()
+              }
+            }
+          }
+          items = Object.assign(items,item)
+          arr.push({
+            row:1,
+            col:1,
+            component:listModalComponent,
+            item:items
+          })
+          return arr
+        },[])
+      });
+    },
+    addTemplate () {  //新建模版
+      this.changeKeepAliveArray(['TemplateManagementLists'])
+      // router.push({ path: '/TemplateManagementNew/-1' })
+      this.currentChange({
+        path:'/TemplateManagementLists'
+      });
+    },
+    templateMigration () { //模版迁移
+      this.listsStatus = 1
+    },
+    removeMigration () {  //取消迁移
+      this.listsStatus = 0
+    },
+    modalClick (event) {  //模版点击
+      let value = event.detail.value
+      let items = event.detail.items
+      if(value){
+        this.selectModal.push(items.id)
+      }else{
+        this.selectModal.splice(this.selectModal.findIndex(item => item === items.id), 1)
+      }
+    },
+    perform () {  //执行迁移
+      if(this.selectModal.length === 0){
+        this.$Modal.fcWarning({
+          title:'警告',
+          content:'请选择需要迁移的模版!',
+          mask:true
+        })
+        return
+      }
+      this.migrationType = 0
+      this.serverUrl = null
+      this.migrationModel = true
+
+    },
+    performAll () {  //迁移全部
+      this.migrationType = 1
+      this.serverUrl = null
+      this.migrationModel = true
+    },
+    performConfirm () {  //模版迁移确认
+      let obj = {}
+      if(!(this.serverUrl.startsWith('http://') || this.serverUrl.startsWith('https://'))){
+        this.$Modal.fcWarning({
+          title:'警告',
+          content:'目标服务器地址必须以http://或者https://开头',
+          mask:true
+        })
+        return
+      }
+      this.performloading = true
+      if(this.migrationType === 0){  //执行选中模版
+        obj = {
+          moduleIds:this.selectModal.join(',')
+        }
+      }else{  //执行所有模版
+        if(this.searchData.createTime && this.searchData.createTime[0] && this.searchData.createTime[1]){
+          this.searchData.startTime = new Date(this.searchData.createTime[0]).format('yyyy-MM-dd hh:mm')
+          this.searchData.endTime = new Date(this.searchData.createTime[1]).format('yyyy-MM-dd hh:mm')
+        }else{
+          this.searchData.startTime = ''
+          this.searchData.endTime = ''
+        }
+
+        obj = Object.assign({},this.searchData)
+      }
+
+      obj.url = this.serverUrl
+      this.$network.post('/p/cs/module/migrate', obj)
+        .then((res) => {
+          if(res.data.resultCode === 0){
+            this.$Modal.fcSuccess({
+              title:'成功',
+              content:res.data.resultMsg,
+              onOk: () => {
+                this.queryLists()
+                this.listsStatus = 0
+                this.migrationModel = false
+                this.performloading = false
+              }
+            })
+
+          }else{
+            this.performloading = false
+          }
+
+        })
+    }
+  },
+  created () {
+    //判断首页跳转状态,修改查询条件
+    let status = Number(this.$route.query.status)
+    if(status){
+      this.searchData.status = [status]
+      this.formLists[1].item.value = [status]
+      this.formLists = this.formLists.concat([])
+    }
+    this.queryLists()
+  },
+  mounted () {
+    // 监听modal的点击事件
+    window.addEventListener('modalClick',this.modalClick)
+  },
+  beforeDestroy () {
+    window.removeEventListener('modalClick', this.modalClick);
+  },
+  activated () {
+    this.queryLists()
+  }
+}
+</script>
+<style lang="scss" >
+.TemplateManagementLists{
+  display: flex;
+  flex-direction: column;
+  .listContent{
+    background: white;
+    flex: 1;
+    padding: 16px;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
+
+    .title{
+      font-size:18px;
+      font-family:PingFangSC-Medium;
+      font-weight:500;
+      color:rgba(81,90,110,1);
+      line-height:24px;
+      margin-bottom: 16px;
+    }
+
+    .buttonLists{
+      margin-bottom: 10px;
+      >button{
+        width: 90px;
+        margin-right: 10px;
+      }
+    }
+    .form{
+      margin-bottom: 16px;
+    }
+
+    .list{
+      flex: 1;
+      margin-right: -16px;
+      overflow: auto;
+      position: relative;
+      .listsForm{
+        border: none;
+        padding: 0;
+        margin-left: 5px;
+        margin-top: 5px;
+
+        .FormItemComponent-item{
+          margin-right: 16px;
+          margin-bottom: 20px;
+        }
+      }
+
+      .noData{
+        position: absolute;
+        top: 50%;
+        left: 50%;
+        width: 280px;
+        height: 292px;
+        margin-top: -146px;
+        margin-left: -140px;
+        // background-image: url('../assets/img/nodata.png');
+        background-size: cover;
+
+        >span{
+          position: absolute;
+          bottom: 40px;
+          left: 20px;
+          display: inline-block;
+          width: 240px;
+          height: 40px;
+          text-align: center;
+        }
+      }
+    }
+
+  }
+}
+
+.migrationModelContent{
+  height: 115px;
+  padding: 30px 44px 17px 44px;
+  box-sizing: border-box;
+}
+</style>