lrf402788946 5 年之前
父节点
当前提交
6dfcd81a83

+ 45 - 0
src/components/data-table.md

@@ -0,0 +1,45 @@
+# 组件文档说明
+## data-table.vue
+#### prop
+|参数|类型|默认值|是否必填|说明|
+|:-:|:-:|:-:|:-:|:-:|
+|fields|Array|`-`|是|字段列表(下文会说明如何使用)|
+|data|Array|`-`|是|数据列表|
+|opera|Array|[ ]|否|操作列的列表(下文会说明如何使用)|
+|toFormat|Function|`-`|否|如果fields中的format不是function类型,则会走toFormat的方法,需要自己写过滤规则,多个的情况需要区分|
+|select|Boolean|false|否|需要选择就变成true|
+|total|NUmber|0|否|分页的总数据|
+|usePage|Boolean|true|否|是否使用分页|
+|options|Object|null|否|加些属性,不知道能加啥,反正我把合计加上好使了|
+|useSum|Boolean|false|否|使用合计|
+|filter|Array|`[]`|否|额外查询|
+
+>fields
+>>
+|参数|类型|默认值|是否必填|说明|
+|:-:|:-:|:-:|:-:|:-:|
+|label|String|`-`|是|列名称|
+|prop|String|`-`|是|字段名称|
+|format|Function/String|`-`|否|Function类型:数据需要过滤则将过滤方法写在这;String类型:走toFormat方法,参数位(model=>字段名,value=>值)|
+|custom|Boolean|false|否|自定义输出|
+|options|Object|`-`|否|添加额外属性,比如说样式之类的|
+|filter|String|`-`|否|如果填写,则这个字段会查询,这里只填写类型,input/select,select的选项在options插槽中使用|
+|selected|Array|`-`|false|多选选项的数据|
+
+>opera
+>>
+|参数|类型|默认值|是否必填|说明|
+|:-:|:-:|:-:|:-:|:-:|
+|label|String|`-`|是|操作按钮提示文字|
+|icon|String|`-`|否|图标|
+|method|String|`-`|是|此按钮连接的父级方法($emit)|
+|confirm|Boolean|`-`|否|是否需要确认提示|
+|methodZh|String/Function|label|否|确认提示的操作文字,1,Function参数为这条数据,自己随意组合;2,String为纯自定义字符串,需要自己写整个提示语;3,默认,使用label字段提示|
+|display|Function|`-`|否|控制按钮是否显示(目前为简单版,只是根据此条数据中的内容判断,以后要是有需求会修改成toFormat的形式)|
+
+>methods
+>>
+|方法名|参数|说明|
+|:-:|:-:|:-:|
+|handleSelect|Array[object]|返回选择的内容|
+|query|{skip,limit,...info}|分页查询,及条件查询|

+ 268 - 0
src/components/data-table.vue

@@ -0,0 +1,268 @@
+<template>
+  <div id="data-table">
+    <el-form :model="searchInfo" :inline="true" style="padding:0.9rem 1.875rem ;" size="mini" v-if="useFilter">
+      <el-form-item v-for="(item, index) in filterList" :key="index">
+        <template v-if="item.filter === 'select'">
+          <el-select v-model="searchInfo[item.prop]" size="mini" clearable filterable :placeholder="`请选择${item.label}`">
+            <slot name="options" v-bind="{ item }"></slot>
+          </el-select>
+        </template>
+        <template v-else-if="item.filter === 'date'">
+          <el-date-picker
+            v-model="searchInfo[item.prop]"
+            value-format="yyyy-MM-dd"
+            format="yyyy-MM-dd"
+            type="daterange"
+            range-separator="-"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+            clearable
+          >
+          </el-date-picker>
+        </template>
+        <template v-else>
+          <el-input v-model="searchInfo[item.prop]" clearable size="mini" :placeholder="`请输入${item.label}`"></el-input>
+        </template>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" size="mini" @click="filterSearch">查询</el-button>
+      </el-form-item>
+    </el-form>
+    <el-table
+      ref="table"
+      row-key="id"
+      :data="data"
+      border
+      stripe
+      size="mini"
+      :max-height="height !== null ? height : ''"
+      @select="handleSelectionChange"
+      @select-all="handleSelectAll"
+      v-bind="options"
+      :show-summary="useSum"
+    >
+      <el-table-column type="selection" width="55" v-if="select" prop="id" :reserve-selection="true"> </el-table-column>
+      <template v-for="(item, index) in fields">
+        <template v-if="item.custom">
+          <el-table-column :key="index" align="center" :label="item.label" v-bind="item.options">
+            <template v-slot="{ row }">
+              <slot name="custom" v-bind="{ item, row }"></slot>
+            </template>
+          </el-table-column>
+        </template>
+        <template v-else>
+          <el-table-column :key="index" align="center" :label="item.label" :prop="item.prop" :formatter="toFormatter" sortable v-bind="item.options">
+          </el-table-column>
+        </template>
+      </template>
+      <template v-if="opera.length > 0">
+        <el-table-column label="操作" align="center">
+          <template v-slot="{ row, $index }">
+            <template v-for="(item, index) in opera">
+              <template v-if="display(item, row)">
+                <el-tooltip v-if="item.icon" :key="index" effect="dark" :content="item.label" placement="bottom">
+                  <el-button
+                    :key="index"
+                    type="text"
+                    :icon="item.icon || ''"
+                    size="mini"
+                    @click="handleOpera(row, item.method, item.confirm, item.methodZh, item.label, $index)"
+                  ></el-button>
+                </el-tooltip>
+                <el-button v-else :key="index" type="text" size="mini" @click="handleOpera(row, item.method, item.confirm, item.methodZh, item.label, $index)">
+                  {{ item.label }}
+                </el-button>
+              </template>
+            </template>
+          </template>
+        </el-table-column>
+      </template>
+    </el-table>
+    <el-row type="flex" align="middle" justify="end" style="padding-top:1rem" v-if="usePage">
+      <el-col :span="24" style="text-align:right;">
+        <el-pagination
+          background
+          layout="sizes, total, prev, pager, next"
+          :page-sizes="[10, 15, 20, 50, 100]"
+          :total="total"
+          :page-size="limit"
+          :current-page.sync="currentPage"
+          @current-change="changePage"
+          @size-change="sizeChange"
+        >
+        </el-pagination>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import dataForm from '@/components/form.vue';
+export default {
+  name: 'data-table',
+  props: {
+    fields: { type: Array, required: true },
+    data: { type: Array, required: true },
+    opera: { type: Array, default: () => [] },
+    toFormat: null,
+    height: null,
+    select: { type: Boolean, default: false },
+    selected: { type: Array, default: () => [] },
+    usePage: { type: Boolean, default: true },
+    total: { type: Number, default: 0 },
+    options: null,
+    useSum: { type: Boolean, default: false },
+    filter: { type: Array, default: () => [] },
+  },
+  components: {},
+  data: () => ({
+    pageSelected: [],
+    currentPage: 1,
+    limit: _.get(this, `$limit`, undefined) !== undefined ? this.$limit : process.env.VUE_APP_LIMIT * 1,
+    searchInfo: {},
+    useFilter: true,
+    filterList: [],
+  }),
+  created() {},
+  computed: {},
+  methods: {
+    toFormatter(row, column, cellValue, index) {
+      let this_fields = this.fields.filter(fil => fil.prop === column.property);
+      if (this_fields.length > 0) {
+        let format = _.get(this_fields[0], `format`, false);
+        if (format) {
+          let res;
+          if (_.isFunction(format)) {
+            res = format(cellValue);
+          } else {
+            res = this.toFormat({
+              model: this_fields[0].prop,
+              value: cellValue,
+            });
+          }
+          return res;
+        } else return cellValue;
+      }
+    },
+    handleOpera(data, method, confirm = false, methodZh, label, index) {
+      let self = true;
+      if (_.isFunction(methodZh)) {
+        methodZh = methodZh(data);
+      } else if (!_.isString(methodZh)) {
+        methodZh = label;
+        self = false;
+      }
+      if (confirm) {
+        this.$confirm(self ? methodZh : `您确认${methodZh}该数据?`, '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning',
+        })
+          .then(() => {
+            this.$emit(method, { data, index });
+          })
+          .catch(() => {});
+      } else {
+        this.$emit(method, { data, index });
+      }
+    },
+    handleSelectionChange(selection, row) {
+      // console.log(selection);
+      // console.log(row);
+      //根据row是否再pageSelected中,判断是添加还是删除
+      let res = [];
+      if (this.pageSelected.find(i => i.id === row.id)) {
+        res = this.pageSelected.filter(f => f.id !== row.id);
+      } else {
+        this.pageSelected.push(row);
+        res = this.pageSelected;
+      }
+      this.$set(this, `pageSelected`, res);
+      this.$emit(`handleSelect`, _.uniqBy(res, 'id'));
+    },
+    handleSelectAll(selection) {
+      //处于没全选状态,选择之后一定是全选,只有处于全选状态时,才会反选(全取消)
+      // console.log(selection);
+      let res = [];
+      if (selection.length > 0) {
+        //全选
+        res = _.uniqBy(this.pageSelected.concat(selection), 'id');
+      } else {
+        //全取消
+        res = _.differenceBy(this.pageSelected, this.data, 'id');
+      }
+      this.$set(this, `pageSelected`, res);
+      this.$emit(`handleSelect`, res);
+    },
+    initSelection() {
+      this.$nextTick(() => {
+        this.$refs.table.clearSelection();
+        this.selected.forEach(info => {
+          let d = this.data.filter(p => p.id === info.id);
+          if (d.length > 0) this.$refs.table.toggleRowSelection(d[0]);
+        });
+      });
+    },
+    selectReset() {
+      this.$refs.table.clearSelection();
+    },
+    display(item, row) {
+      let display = _.get(item, `display`, true);
+      if (display === true) return true;
+      else {
+        let res = display(row);
+        return res;
+      }
+    },
+    //
+    changePage(page) {
+      this.$emit('query', { skip: (page - 1) * this.limit, limit: this.limit, ...this.searchInfo });
+    },
+    sizeChange(limit) {
+      this.limit = limit;
+      this.currentPage = 1;
+      this.$emit('query', { skip: 0, limit: this.limit, ...this.searchInfo });
+    },
+    getFilterList() {
+      let res = this.fields.filter(f => _.get(f, 'filter', false));
+      this.$set(this, `useFilter`, res.length > 0);
+      res.map(i => {
+        if (i.filter === 'date' && this.searchInfo[i.porp] === undefined) this.$set(this.searchInfo, i.prop, []);
+      });
+      res = [...res, ...this.filter];
+      this.$set(this, `filterList`, res);
+    },
+    filterSearch() {
+      this.currentPage = 1;
+      this.$emit('query', { skip: 0, limit: this.limit, ...this.searchInfo });
+    },
+  },
+  watch: {
+    selected: {
+      handler(val) {
+        if (val.length > 0) {
+          this.pageSelected = val;
+          this.initSelection();
+        }
+      },
+      immediate: true,
+    },
+    data: {
+      handler(val, oval) {
+        if (this.select) {
+          this.initSelection();
+        }
+      },
+    },
+    fields: {
+      handler(val, oval) {
+        if (val) this.getFilterList();
+      },
+      immediate: true,
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 81 - 0
src/components/form.md

@@ -0,0 +1,81 @@
+# 组件说明文档
+### form.vue
+### props
+
+|参数|类型|默认值|是否必填|说明|
+|:-:|:-:|:-:|:-:|:-:|
+|fields|Array|`-`|是|字段相关都在这里,用来自动输出,详情见下面|
+|submitText|String|`保存`|否|默认保存按钮的文字|
+|rules|Object|`-`|否|校验规则,不会找el-form的例子,不过使用的async-validator这个依赖为基础,会写这个也可以~~(那就厉害了,反正我是不行)~~|
+|isNew|Boolean|`-`|是|修改还是添加的提示|
+|data|Object|`-`|否|修改传来的数据|
+|needSave|Boolean|false|否|是否禁用保存按钮|
+|useEnter|Boolean|true|否|使用回车提交|
+|reset|Boolean|true|否|提交后是否重置表单|
+
+
+### fields
+>Array类型 必填
+>>
+|参数|类型|默认值|是否必填|说明|
+|:-:|:-:|:-:|:-:|:-:|
+|label|String|`-`|是|显示的字段中文|
+|type|String|input|否|这个字段要用什么类型来输出 input的基本类型可选值:date,datetime,radio,checkbox,select,text(只显示值),editor(富文本编辑器),password|
+|required|Boolean|`-`|否|是否必须输入|
+|model|String|`-`|是|字段名|
+|placeholder|String|`-`|否|占位,正常用,只是个透传|
+|options|object|`-`|否|标签的属性设置,例如:textarea 需要显示剩余字数,或者input限制长度,都往这里写,key-value形式(键值对,json的基本了解,不知道百度,具体属性看你具体用那个组件,那个组件有什么属性,瞎写不一定好使)|
+|custom|Boolean|`-`|否|是否使用自定义插槽|
+|tip|String|`-`|否|提示语,例如:请输入11位电话号码|
+|labelWidth|String|`120px`|否|表单label宽度,element的,默认120px|
+
+
+
+
+
+
+
+### slot
+>
+|插槽名|说明|
+|:-:|:-:|
+|options|fields中type为select的,选项都写在这个插槽中,多个select则需要区分options所属问题|
+|radios|fields中type为radio的,选项都写在这个插槽中,多个radio则需要区分radios所属问题|
+|checkbox|fields中type为checkbox的,选项都写在这个插槽中,多个checkbox则需要区分checkboxs所属问题|
+|custom|自定义插槽,完全自己去写|
+|submit|提交按钮部分,当needSave为false时才可以使用|
+>>关于自定义的用法:
+>>在fields中,custom:true的情况即需要自定义,写法如下
+
+>>`<template #custom="{ item, form, fieldChange }"> ... </template>`
+>>
+|参数名|说明|
+|:-:|:-:|
+|item|fields循环出来的每一项|
+|form|组件内部的表单|
+|fieldChange|组件内部的修改方法,此方法不一定必须使用,看情况来;参数:{model:xxx,value:XXX}(model:字段名,value:值)|
+>>在使用时,此插槽内的v-model可以写成form[item.model],也可以写成form.字段名
+
+>>例如`<el-input v-model="form[item.model]">`或者`<el-input v-model="form.xxx">`
+
+>> **如果有多处需要自定义,请区分开去写**
+
+
+***
+### upload
+|参数|类型|默认值|是否必填|说明|
+|:-:|:-:|:-:|:-:|:-:|
+|url|String|`-`|是|上传地址|
+|limit|Number|`-`|是|限制上传数量|
+|data|any|`-`|否|上传数据|
+|type|String|`-`|否|上传返回的字段|
+|isBtn|Boolean|false|否|是否只显示按钮|
+|showList|Boolean|true|否|是否显示上传列表|
+|accept|String|`-`|否|可以上传的文件类型,不写就没限制|
+|tip|String|`-`|否|提示信息|
+|listType|String|picture-card|否|上传文件列表显示类型|
+
+>### method
+>|方法名|返回参数|说明|
+|:-:|:-:|:-:|
+|upload|{type,data}|上传成功返回

+ 203 - 0
src/components/form.vue

@@ -0,0 +1,203 @@
+<template>
+  <div id="add">
+    <el-form
+      ref="form"
+      :model="form"
+      :rules="rules"
+      :label-width="labelWidth"
+      class="form"
+      size="small"
+      @submit.native.prevent
+      :style="styles"
+      :inline="inline"
+    >
+      <template v-for="(item, index) in fields">
+        <template v-if="!loading">
+          <el-form-item v-if="display(item)" :key="'form-field-' + index" :label="getField('label', item)" :prop="item.model" :required="item.required">
+            <template v-if="!item.custom">
+              <template v-if="item.type !== 'text'">
+                <el-tooltip class="item" effect="dark" :content="item.tip" placement="top-start" :disabled="!item.tip">
+                  <template v-if="item.type === `date` || item.type === `datetime`">
+                    <el-date-picker
+                      v-model="form[item.model]"
+                      :type="item.type"
+                      placeholder="选择择"
+                      format="yyyy-MM-dd"
+                      value-format="yyyy-MM-dd"
+                      v-bind="item.options"
+                    >
+                    </el-date-picker>
+                  </template>
+                  <template v-else-if="item.type === `year` || item.type === `week` || item.type === `day`">
+                    <el-date-picker
+                      v-model="form[item.model]"
+                      :type="item.type"
+                      placeholder="选择择"
+                      :format="`${item.type === 'year' ? 'yyyy' : item.type === 'week' ? 'MM' : 'dd'}`"
+                      :value-format="`${item.type === 'year' ? 'yyyy' : item.type === 'week' ? 'MM' : 'dd'}`"
+                      v-bind="item.options"
+                    >
+                    </el-date-picker>
+                  </template>
+                  <template v-else-if="item.type === 'radio'">
+                    <el-radio-group v-model="form[item.model]" size="mini" v-bind="item.options">
+                      <slot name="radios" v-bind="{ item, form, fieldChange }"></slot>
+                    </el-radio-group>
+                  </template>
+                  <template v-else-if="item.type === 'checkbox'">
+                    <el-checkbox-group v-model="form[item.model]" v-bind="item.options">
+                      <slot name="checkboxs" v-bind="{ item, form, fieldChange }"></slot>
+                    </el-checkbox-group>
+                  </template>
+                  <template v-else-if="item.type === 'select'">
+                    <el-select v-model="form[item.model]" v-bind="item.options" filterable clearable>
+                      <slot name="options" v-bind="{ item, form, fieldChange }"></slot>
+                    </el-select>
+                  </template>
+                  <template v-else-if="item.type === 'textarea'">
+                    <el-input clearable v-model="form[item.model]" type="textarea" :autosize="{ minRows: 3, maxRows: 5 }"></el-input>
+                  </template>
+                  <template v-else-if="item.type === 'editor'">
+                    <wang-editor v-model="form[item.model]"></wang-editor>
+                  </template>
+                  <template v-else>
+                    <el-input
+                      clearable
+                      v-model="form[item.model]"
+                      :type="getField('type', item)"
+                      :placeholder="getField('placeholder', item)"
+                      :show-password="getField('type', item) === 'password'"
+                      v-bind="item.options"
+                    ></el-input>
+                  </template>
+                </el-tooltip>
+              </template>
+              <template v-else>
+                {{ form[item.model] }}
+              </template>
+            </template>
+            <template v-else>
+              <slot name="custom" v-bind="{ item, form, fieldChange }"></slot>
+            </template>
+          </el-form-item>
+        </template>
+      </template>
+      <el-form-item v-if="needSave" class="btn">
+        <el-row type="flex" align="middle" justify="space-around">
+          <el-col :span="6">
+            <el-button type="primary" @click="save">{{ submitText }}</el-button>
+          </el-col>
+        </el-row>
+      </el-form-item>
+      <el-form-item v-else>
+        <slot name="submit"></slot>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import _ from 'lodash';
+import wangEditor from './wang-editor.vue';
+export default {
+  name: 'add',
+  props: {
+    fields: { type: Array, default: () => [] },
+    rules: { type: Object, default: () => {} },
+    isNew: { type: Boolean, default: true },
+    data: null,
+    styles: { type: Object, default: () => {} },
+    needSave: { type: Boolean, default: true },
+    labelWidth: { type: String, default: '120px' },
+    useEnter: { type: Boolean, default: true },
+    submitText: { type: String, default: '保存' },
+    inline: { type: Boolean, default: false },
+    reset: { type: Boolean, default: true },
+  },
+  components: {
+    wangEditor,
+  },
+  data: () => ({
+    form: {},
+    show: false,
+    dateShow: false,
+    loading: true,
+  }),
+  created() {
+    if (this.useEnter) {
+      document.onkeydown = () => {
+        let key = window.event.keyCode;
+        if (key == 13) {
+          this.save();
+        }
+      };
+    }
+  },
+  computed: {},
+  mounted() {},
+  watch: {
+    fields: {
+      handler(val) {
+        this.checkType();
+      },
+      immediate: true,
+    },
+    data: {
+      handler(val) {
+        this.loading = true;
+        if (val) this.$set(this, `form`, this.data);
+        this.loading = false;
+      },
+      immediate: true,
+      deep: true,
+    },
+  },
+  methods: {
+    getField(item, data) {
+      let res = _.get(data, item, null);
+      if (item === 'type') res = res === null ? `text` : res;
+      if (item === 'placeholder') res = res === null ? `请输入${data.label}` : res;
+      if (item === 'required') res = res === null ? false : res;
+      if (item === `error`) res = res === null ? `${data.label}错误` : res;
+      return res;
+    },
+    save() {
+      this.$refs['form'].validate(valid => {
+        if (valid) {
+          this.$emit(`save`, { isNew: this.isNew, data: JSON.parse(JSON.stringify(this.form)) });
+          if (this.reset) this.$refs.form.resetFields();
+        } else {
+          console.warn('form validate error!!!');
+        }
+      });
+    },
+    fieldChange({ model, value }) {
+      this.$set(this.form, model, value);
+    },
+    checkType() {
+      let arr = this.fields.filter(fil => fil.type === 'checkbox');
+      if (arr.length > 0 && this.isNew) {
+        for (const item of arr) {
+          this.$set(this.form, `${item.model}`, []);
+        }
+      }
+    },
+    display(field) {
+      let dis = _.get(field, `display`);
+      if (!_.isFunction(dis)) return true;
+      else return dis(field, this.form);
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.form {
+  padding: 2rem 1rem;
+  background: #fff;
+  border-radius: 20px;
+}
+/deep/.btn .el-form-item__content {
+  margin-left: 0 !important;
+}
+</style>

+ 111 - 27
src/layout/user/mainForm.vue

@@ -3,40 +3,76 @@
     <el-row>
       <el-col :span="24" class="linksForm">
         <el-form ref="form" :model="form" label-width="100px">
+          <el-form-item label="用户状态" v-if="form.role !== '1'">
+            <el-radio-group v-model="form.status" @change="setIsQy">
+              <el-radio label="0" disabled>已注册</el-radio>
+              <el-radio label="1">审核成功</el-radio>
+              <el-radio label="2">拒绝审核</el-radio>
+            </el-radio-group>
+          </el-form-item>
           <el-form-item label="身份证">
-            <el-input v-model="form.sfzh" placeholder="请输入身份证"></el-input>
+            <el-input v-model="form.cardnumber" placeholder="请输入身份证" :minlength="18" :maxlength="18"></el-input>
           </el-form-item>
           <el-form-item label="姓名">
-            <el-input v-model="form.name" placeholder="请输入身份证"></el-input>
+            <el-input v-model="form.name" placeholder="请输入姓名"></el-input>
           </el-form-item>
-          <el-form-item label="登录名称">
-            <el-input v-model="form.loginName" placeholder="请输入登录名称"></el-input>
+          <el-form-item label="手机号">
+            <el-input v-model="form.phone" placeholder="请输入手机号" :minlength="11" :maxlength="11"></el-input>
           </el-form-item>
-          <el-form-item label="联系电话">
-            <el-input v-model="form.phone" placeholder="请输入联系电话"></el-input>
+          <el-form-item label="密码" v-if="isNew">
+            <el-input v-model="form.password" placeholder="请输入密码" show-password></el-input>
           </el-form-item>
-          <el-form-item label="E-mail">
-            <el-input v-model="form.email" placeholder="请输入email"></el-input>
+          <el-form-item label="邮箱">
+            <el-input v-model="form.email" placeholder="请输入邮箱"></el-input>
           </el-form-item>
           <el-form-item label="地址">
-            <el-input v-model="form.address" placeholder="请输入地址"></el-input>
+            <el-input v-model="form.addr" placeholder="请输入地址"></el-input>
           </el-form-item>
-          <el-form-item label="角色">
-            <el-radio-group v-model="form.jiaose">
-              <el-radio label="普通成员"></el-radio>
-              <el-radio label="平台管理员"></el-radio>
-              <el-radio label="企业管理员"></el-radio>
+          <el-form-item label="用户类别">
+            <el-radio-group v-model="form.role" @change="setIsQy">
+              <el-radio v-model="form.role" label="1">管理员</el-radio>
+              <el-radio label="2">个人</el-radio>
+              <el-radio label="3">企业管理员</el-radio>
             </el-radio-group>
           </el-form-item>
-          <el-form-item label="可管理对象">
-            <el-input v-model="form.name" placeholder="请输入可管理对象"></el-input>
+          <el-form-item label="身份证正面">
+            <upload :limit="1" :data="form.cardfile_a" type="cardfile_a" :url="'/files/cardfilea/upload'" @upload="uploadSuccess"></upload>
+          </el-form-item>
+          <el-form-item label="身份证背面">
+            <upload :limit="1" :data="form.cardfile_b" type="cardfile_b" :url="'/files/cardfileb/upload'" @upload="uploadSuccess"></upload>
+          </el-form-item>
+          <el-form-item label="组织机构图片" v-if="form.role == '3'">
+            <upload :limit="1" :data="form.img_qy" type="img_qy" :url="'/files/imgqy/upload'" @upload="uploadSuccess"></upload>
           </el-form-item>
-          <el-form-item label="用户简介">
-            <el-input type="textarea" v-model="form.content" placeholder="请输入用户简介"></el-input>
+          <el-form-item label="简介" placeholder="请输入简介">
+            <el-input type="textarea" v-model="form.resume"></el-input>
+          </el-form-item>
+          <el-form-item label="专业领域" placeholder="请输入专业领域" v-if="form.role !== '1'">
+            <el-input v-model="form.major"></el-input>
+          </el-form-item>
+          <template v-if="form.role == '3'">
+            <el-form-item label="机构类型" placeholder="请输入机构类型">
+              <el-input v-model="form.institution_type"></el-input>
+            </el-form-item>
+            <el-form-item label="机构名称" placeholder="请输入机构名称">
+              <el-input v-model="form.institution_name"></el-input>
+            </el-form-item>
+            <el-form-item label="机构代码" placeholder="请输入机构代码">
+              <el-input v-model="form.institution_code"></el-input>
+            </el-form-item>
+            <el-form-item label="机构性质" placeholder="请输入机构性质">
+              <el-input v-model="form.institution_nature"></el-input>
+            </el-form-item>
+          </template>
+          <el-form-item label="办公电话" placeholder="请输入办公电话">
+            <el-input v-model="form.office_phone"></el-input>
+          </el-form-item>
+          <el-form-item label="所属行业" placeholder="请输入所属行业" v-if="form.role !== '1'">
+            <el-input v-model="form.profession"></el-input>
           </el-form-item>
           <el-form-item>
             <el-button @click="handleCancel">返回</el-button>
-            <el-button type="primary" @click="handleEdit()">提交</el-button>
+            <el-button type="primary" @click="handleSave()">提交</el-button>
           </el-form-item>
         </el-form>
       </el-col>
@@ -45,22 +81,70 @@
 </template>
 
 <script>
+import upload from '@/components/upload.vue';
+import { mapActions, mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: user } = createNamespacedHelpers('user');
 export default {
   name: 'mainForm',
-  props: {
-    form: null,
-  },
-  components: {},
-  data: () => ({}),
+  props: {},
+  components: { upload },
+  data: () => ({
+    form: {},
+  }),
   created() {},
-  computed: {},
   methods: {
-    handleEdit() {
-      this.$emit('submitDate', { data: this.form, id: this.form.id });
+    ...user(['fetch', 'create', 'update']),
+    async search() {
+      const res = await this.fetch(this.id);
+      console.log(res);
+      if (this.$checkRes(res)) this.$set(this, `form`, res.data);
+    },
+    async handleSave() {
+      let res;
+      let msg;
+      let data = JSON.parse(JSON.stringify(this.form));
+      if (this.isNew) {
+        data.status = '1';
+        res = await this.create(data);
+        msg = '用户创建成功';
+      } else {
+        res = await this.update(data);
+        msg = '用户修改成功';
+      }
+      if (this.$checkRes(res, msg, res.errmsg)) {
+        console.log(`success`);
+      }
     },
     handleCancel() {
       this.$router.push({ path: '/user/index' });
     },
+    setIsQy(data) {
+      let val = '0';
+      data == '2' ? (val = '0') : (val = '1');
+      this.$set(this.form, `is_qy`, val);
+    },
+    uploadSuccess({ type, data }) {
+      this.$set(this.form, `${type}`, data.uri);
+    },
+  },
+  computed: {
+    id() {
+      return this.$route.query.id;
+    },
+    isNew() {
+      return this.$route.query.id ? false : true;
+    },
+  },
+  watch: {
+    isNew: {
+      handler(val) {
+        if (!val) {
+          console.log('in function:');
+          this.search();
+        }
+      },
+      immediate: true,
+    },
   },
 };
 </script>

+ 6 - 0
src/main.js

@@ -2,6 +2,7 @@ import Vue from 'vue';
 import App from './App.vue';
 import router from './router';
 import store from './store';
+import Router from 'vue-router';
 import '@/plugins/element.js';
 import '@/plugins/axios';
 import '@/plugins/check-res';
@@ -17,3 +18,8 @@ new Vue({
   store,
   render: h => h(App),
 }).$mount('#app');
+
+const originalPush = Router.prototype.push;
+Router.prototype.push = function push(location) {
+  return originalPush.call(this, location).catch(err => err);
+};

+ 6 - 2
src/store/index.js

@@ -19,6 +19,9 @@ import talentResume from './talentResume';
 import dictionary from './dictionary';
 import protype from './protype';
 
+import user from './user';
+import * as ustate from './user/state';
+import * as umutations from './user/mutations';
 Vue.use(Vuex);
 
 export default new Vuex.Store({
@@ -40,8 +43,9 @@ export default new Vuex.Store({
     talentResume,
     dictionary,
     protype,
+    user,
   },
-  state: {},
-  mutations: {},
+  state: { ...ustate },
+  mutations: { ...umutations },
   actions: {},
 });

+ 39 - 0
src/store/user.js

@@ -0,0 +1,39 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  interface: `/api/market/user`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit = 10, ...info } = {}) {
+    const res = await this.$axios.$get(api.interface, { skip, limit, ...info });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.interface}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.interface}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...info } = {}) {
+    const res = await this.$axios.$post(`${api.interface}/${id}`, { ...info });
+    return res;
+  },
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.interface}/${payload}`);
+    return res;
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 29 - 0
src/store/user/mutations.js

@@ -0,0 +1,29 @@
+const jwt = require('jsonwebtoken');
+
+export const setUser = (state, payload) => {
+  let res = true;
+  //登陆时
+  if (payload) {
+    state.token = payload;
+    let user = jwt.decode(payload);
+    console.log(user);
+  } else {
+    //已经登陆,切换路由时取出用户信息放在总store中
+    let token = localStorage.getItem('token');
+    if (token) {
+      state.user = jwt.decode(token);
+    } else {
+      res = false;
+      state.user = undefined;
+      console.warn('用户未登录');
+    }
+  }
+  return res;
+};
+
+export const deleteUser = (state, payload) => {
+  state.user = {};
+  state.menuList = [];
+  localStorage.removeItem('user');
+  localStorage.removeItem('menuList');
+};

+ 2 - 0
src/store/user/state.js

@@ -0,0 +1,2 @@
+export const user = {};
+export const token = undefined;

+ 2 - 2
src/util/axios-wrapper.js

@@ -87,7 +87,7 @@ export default class AxiosWrapper {
       }
       // unwrap data
       if (this.unwrap) {
-        res = _.omit(res, ['errmsg', 'details']);
+        res = _.omit(res, ['details']);
         const keys = Object.keys(res);
         if (keys.length === 1 && keys.includes('data')) {
           res = res.data;
@@ -107,7 +107,7 @@ export default class AxiosWrapper {
       );
       return { errcode: ErrorCode.SERVICE_FAULT, errmsg, details: err.message };
     } finally {
-    /* eslint-disable */
+      /* eslint-disable */
       currentRequests -= 1;
       if (currentRequests <= 0) {
         currentRequests = 0;

+ 1 - 2
src/views/user/detail.vue

@@ -6,7 +6,7 @@
           <topInfo :topTitle="topTitle"></topInfo>
         </el-col>
         <el-col :span="24" class="main">
-          <mainForm :form="form" @submitDate="updateDate"></mainForm>
+          <mainForm></mainForm>
         </el-col>
       </el-col>
     </el-row>
@@ -25,7 +25,6 @@ export default {
   },
   data: () => ({
     topTitle: '用户添加',
-    form: {},
   }),
   created() {},
   computed: {},

+ 61 - 15
src/views/user/index.vue

@@ -5,46 +5,92 @@
         <el-col :span="24" class="top">
           <topInfo :topTitle="topTitle"></topInfo>
         </el-col>
-        <el-col :span="24" class="search">
-          <searchInfo></searchInfo>
+        <el-col :span="24" class="search" style="text-align:right">
+          <el-button size="mini" type="primary" @click="$router.push({ path: './detail' })" icon="el-icon-plus">添加用户</el-button>
         </el-col>
         <el-col :span="24" class="main">
-          <mainData :tableData="tableData" :total="total" @delete="deleteData"></mainData>
+          <!-- <mainData :tableData="tableData" :total="total" @delete="deleteData"></mainData> -->
+          <data-table
+            :fields="fields"
+            @delete="toDelete"
+            :data="list"
+            :opera="opera"
+            @edit="toEdit"
+            :total="total"
+            @query="search"
+            @status="toStatus"
+          ></data-table>
         </el-col>
       </el-col>
     </el-row>
+    <el-dialog title="用户审核" :visible.sync="dialog" center :destroy-on-close="true">
+      <data-form :data="info" :fields="fields" :rules="{}" @save="handleSave" :isNew="true"> </data-form>
+    </el-dialog>
   </div>
 </template>
 
 <script>
 import topInfo from '@/layout/public/top.vue';
 import searchInfo from '@/layout/user/searchInfo.vue';
-import mainData from '@/layout/user/mainData.vue';
+import dataForm from '@/components/form.vue';
+import dataTable from '@/components/data-table.vue';
+import { mapActions, mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: user } = createNamespacedHelpers('user');
 export default {
   name: 'index',
   props: {},
   components: {
     topInfo, //头部标题
-    searchInfo, //搜索
-    mainData, //用户列表
+    // searchInfo, //搜索
+    dataTable,
   },
   data: () => ({
     topTitle: '用户管理',
-    tableData: [
+    dialog: false,
+    opera: [
       {
-        name: '名稱',
-        sfzh: '220182199603257019',
-        loginName: 'jalsfjalsfj',
-        phone: '0431-12345678',
-        email: '123456789@163.com',
-        date: '2020-01-01',
+        label: '编辑',
+        icon: 'el-icon-edit',
+        method: 'edit',
       },
+      {
+        label: '删除',
+        icon: 'el-icon-delete',
+        method: 'delete',
+        confirm: true,
+      },
+    ],
+    fields: [
+      { label: '姓名', prop: 'name', filter: 'input' },
+      { label: '身份证号', prop: 'cardnumber', filter: 'input' },
+      { label: '电话', prop: 'phone', filter: 'input' },
+      { label: '状态', prop: 'status', format: i => (i == '0' ? '待审核' : i == '1' ? '审核成功' : '审核拒绝') },
     ],
+    list: [],
+    form: {},
     total: 0,
   }),
-  created() {},
+  created() {
+    this.search();
+  },
   computed: {},
-  methods: {},
+  methods: {
+    ...user(['query', 'delete', 'update']),
+    async search({ skip = 0, limit = 10, ...info } = {}) {
+      const res = await this.query({ skip, limit, ...info });
+      if (this.$checkRes(res)) {
+        this.$set(this, `list`, res.data);
+        this.$set(this, `total`, res.total);
+      }
+    },
+    toEdit({ data }) {
+      this.$router.push({ path: './detail', query: { id: data.id } });
+    },
+    async toDelete({ data }) {
+      const res = await this.delete(data.id);
+      if (this.$checkRes(res, '删除成功', res.errmsg || '删除失败')) this.search();
+    },
+  },
 };
 </script>