lrf402788946 há 4 anos atrás
pai
commit
a6233ba5dd

+ 1 - 0
package.json

@@ -8,6 +8,7 @@
     "lint": "vue-cli-service lint"
   },
   "dependencies": {
+    "animate.css": "^4.1.1",
     "axios": "^0.20.0",
     "babel-polyfill": "^6.26.0",
     "core-js": "^3.6.5",

+ 0 - 51
src/components/filter-page-table.md

@@ -1,51 +0,0 @@
-## filter-page-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|`[]`|否|额外查询|
-|operaWidth|Number|200|否|操作栏宽度|
-
->fields
->>
-|参数|类型|默认值|是否必填|说明|
-|:-:|:-:|:-:|:-:|:-:|
-|label|String|`-`|是|列名称|
-|model|String|`-`|是|字段名称|
-|format|Function/String|`-`|否|Function类型:数据需要过滤则将过滤方法写在这;String类型:走toFormat方法,参数位(model=>字段名,value=>值)|
-|custom|Boolean|false|否|自定义输出|
-|options|Object|`-`|否|添加额外属性,比如说样式之类的|
-|filter|String|`-`|否|如果填写,则这个字段会查询,这里只填写类型,input/select,select的选项在options插槽中使用|
-|selected|Array|`-`|false|多选选项的数据|
-|showTip|Boolean|false|否|是否使用tooltip显示过长内容|
-|filterReturn|Boolean|`-`|否|针对这个选项需要在选择后就做些逻辑处理时,改成true,然后再使用filterReturn方法处理,(例如二级联动的情况)|
-|notable|Boolean|false/undefined|否|不需要在表格中显示|
-|selected|Array|`-`|false|多选选项的数据|
-|type|String|`primary`|element的四大类型|
-
->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}|分页查询,及条件查询|
-|filterReturn|{data,model}|查询条件栏过滤条件中filterReturn字段为true的回调方法|

+ 0 - 321
src/components/filter-page-table.vue

@@ -1,321 +0,0 @@
-<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.model]"
-            size="mini"
-            clearable
-            filterable
-            :placeholder="`请选择${item.label}`"
-            @clear="toClear(item.model)"
-            @change="data => filterReturn(data, item)"
-          >
-            <slot name="options" v-bind="{ item }"></slot>
-          </el-select>
-        </template>
-        <template v-else-if="item.filter === 'date'">
-          <el-date-picker
-            v-model="searchInfo[item.model]"
-            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.model]" clearable size="mini" :placeholder="`请输入${item.label}`" @clear="toClear(item.model)"></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"
-      @row-click="rowClick"
-    >
-      <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.notable">
-          <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.model"
-              :formatter="toFormatter"
-              sortable
-              v-bind="item.options"
-              :show-overflow-tooltip="item.showTip"
-            >
-            </el-table-column>
-          </template>
-        </template>
-      </template>
-      <template v-if="opera.length > 0">
-        <el-table-column label="操作" align="center" :width="operaWidth">
-          <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-link
-                    :key="index"
-                    :type="item.type || 'primary'"
-                    :icon="item.icon || ''"
-                    size="mini"
-                    style="padding-right:10px"
-                    :underline="false"
-                    @click="handleOpera(row, item.method, item.confirm, item.methodZh, item.label, $index)"
-                  >
-                  </el-link>
-                </el-tooltip>
-                <el-link
-                  v-else
-                  :key="index"
-                  :type="item.type || 'primary'"
-                  :icon="item.icon || ''"
-                  size="mini"
-                  style="padding-right:10px"
-                  :underline="false"
-                  @click="handleOpera(row, item.method, item.confirm, item.methodZh, item.label, $index)"
-                >
-                  {{ item.label }}
-                </el-link>
-                <!-- <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="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>
-        <!-- sizes -->
-      </el-col>
-    </el-row>
-  </div>
-</template>
-
-<script>
-import _ from 'lodash';
-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: () => [] },
-    operaWidth: { type: Number, default: 200 },
-  },
-  components: {},
-  data: () => ({
-    pageSelected: [],
-    currentPage: 1,
-    limit: _.get(this, `$limit`, undefined) !== undefined ? this.$limit : process.env.VUE_APP_LIMIT * 1 || 10,
-    searchInfo: {},
-    useFilter: true,
-    filterList: [],
-  }),
-  created() {},
-  computed: {},
-  methods: {
-    toFormatter(row, column, cellValue, index) {
-      let this_fields = this.fields.filter(fil => fil.model === 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.currentPage) {
-      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.model] === undefined) this.$set(this.searchInfo, i.model, []);
-      });
-      res = [...res, ...this.filter];
-      this.$set(this, `filterList`, res);
-    },
-    filterSearch() {
-      this.currentPage = 1;
-      this.$emit('query', { skip: 0, limit: this.limit, ...this.searchInfo });
-    },
-    rowClick(row, column, event) {
-      this.$emit(`rowClick`, row);
-    },
-    toClear(model) {
-      delete this.searchInfo[model];
-    },
-    filterReturn(data, item) {
-      let { model, filterReturn } = item;
-      if (filterReturn) this.$emit('filterReturn', { data, model });
-    },
-  },
-  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>

+ 0 - 69
src/components/form.md

@@ -1,69 +0,0 @@
-# 组件说明文档
-### 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,number|
-|required|Boolean|`-`|否|是否必须输入|
-|model|String|`-`|是|字段名|
-|placeholder|String|`-`|否|占位,正常用,只是个透传|
-|options|object|`-`|否|标签的属性设置,例如:textarea 需要显示剩余字数,或者input限制长度,都往这里写,key-value形式(键值对,json的基本了解,不知道百度,具体属性看你具体用那个组件,那个组件有什么属性,瞎写不一定好使)|
-|custom|Boolean|`-`|否|是否使用自定义插槽|
-|remark|String|`-`|否|提示语,例如:请输入11位电话号码|
-|labelWidth|String|`120px`|否|表单label宽度,element的,默认120px|
-|format|Function|`-`|否|当type = text 时需要将该字段内容转换,可以使用format|
-|filterReturn|Boolean|`-`|否|针对这个选项需要在选择后就做些逻辑处理时,改成true,然后再使用filterReturn方法处理,(例如二级联动的情况)|
-
-
-### methods
-|方法名|参数|说明|
-|:-:|:-:|:-:|
-|filterReturn|{data,prop}|查询条件栏过滤条件中filterReturn字段为true的回调方法|
-
-
-
-
-
-
-### 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">`
-
->> **如果有多处需要自定义,请区分开去写**
-

+ 0 - 233
src/components/form.vue

@@ -1,233 +0,0 @@
-<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.remark" placement="top-start" :disabled="!item.remark">
-                  <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 === 'number'">
-                    <el-input-number v-model="form[item.model]" placeholder=""></el-input-number>
-                  </template>
-                  <template v-else-if="item.type === 'time'">
-                    <el-time-picker v-model="form[item.model]" placeholder="请选择时间" format="HH:mm" value-format="HH:mm"></el-time-picker>
-                  </template>
-                  <template v-else-if="item.type === 'radio'">
-                    <el-radio-group v-model="form[item.model]" size="mini" v-bind="item.options">
-                      <template v-if="item.list">
-                        <el-radio v-for="(i, iIndex) in item.list" :key="`radio-${iIndex}`" :label="i.value">{{ i.label }}</el-radio>
-                      </template>
-                      <template v-else>
-                        <slot name="radios" v-bind="{ item, form, fieldChange }"></slot>
-                      </template>
-                    </el-radio-group>
-                  </template>
-                  <template v-else-if="item.type === 'checkbox'">
-                    <el-checkbox-group v-model="form[item.model]" v-bind="item.options">
-                      <template v-if="item.list">
-                        <el-checkbox v-for="(i, iIndex) in item.list" :key="`checkbox-${iIndex}`" :label="i.value">{{ i.label }}</el-checkbox>
-                      </template>
-                      <template v-else>
-                        <slot name="checkboxs" v-bind="{ item, form, fieldChange }"></slot>
-                      </template>
-                    </el-checkbox-group>
-                  </template>
-                  <template v-else-if="item.type === 'select'">
-                    <el-select v-model="form[item.model]" v-bind="item.options" filterable clearable @change="data => filterReturn(data, item)">
-                      <template v-if="item.list">
-                        <el-option v-for="(i, iIndex) in item.list" :key="`checkbox-${iIndex}`" :label="i.label" :value="i.value"></el-option>
-                      </template>
-                      <template v-else>
-                        <slot name="options" v-bind="{ item, form, fieldChange }"> </slot>
-                      </template>
-                    </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>
-                <template v-if="item.format">
-                  {{ item.format(form[item.model]) }}
-                </template>
-                <template v-else>
-                  {{ form[item.model] }}
-                </template>
-              </template>
-            </template>
-            <template v-else>
-              <slot name="custom" v-bind="{ item, form, fieldChange }"></slot>
-            </template>
-          </el-form-item>
-        </template>
-      </template>
-      <el-form-item label="" v-if="needSave" class="btn">
-        <el-row type="flex" align="middle" justify="start">
-          <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 '@frame/components/wang-editor';
-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);
-    },
-    filterReturn(data, item) {
-      let { model, filterReturn } = item;
-      if (filterReturn) this.$emit('filterReturn', { data, model });
-    },
-  },
-};
-</script>
-
-<style lang="less" scoped>
-.form {
-  padding: 1.5rem 1rem;
-  background: #fff;
-  border-radius: 20px;
-}
-// /deep/.btn .el-form-item__content {
-//   margin-left: 0 !important;
-// }
-</style>

+ 0 - 54
src/components/qrcode.vue

@@ -1,54 +0,0 @@
-<template>
-  <div id="qrcode">
-    <img :src="dataUrl" />
-  </div>
-</template>
-
-<script>
-import Vue from 'vue';
-import QRCode from 'qrcode';
-export default {
-  name: 'qrcode',
-  props: {
-    exchange: null,
-    qrcode: { type: String, required: true },
-    config: { type: Object, required: true },
-    uri: { type: String },
-  },
-  components: {},
-  data: () => ({
-    dataUrl: null,
-    token: null,
-  }),
-  async mounted() {
-    await this.initQrcode();
-  },
-  created() {},
-  computed: {},
-  methods: {
-    async initQrcode() {
-      // 创建二维码
-      if (!this.exchange) return;
-      //二维码地址应该是变量,不过这里需要处理
-      let uri = `${this.config.weixin.baseUrl}${this.uri}`;
-      // console.log(uri);
-      // if (uri.startsWith('/')) {
-      //   uri = `${location.protocol}//${location.host}${uri}`;
-      // }
-      this.dataUrl = await QRCode.toDataURL(uri);
-
-      this.$stomp({
-        [`/exchange/${this.exchange}/${this.qrcode}`]: this.onMessage,
-      });
-      console.log(`/exchange/${this.exchange}/${this.qrcode}`);
-      // console.log(uri);
-    },
-    onMessage(message) {
-      console.log('receive a message: ', message.body);
-      this.$emit('toReturn', message);
-    },
-  },
-};
-</script>
-
-<style lang="less" scoped></style>

+ 0 - 77
src/components/wang-editor.vue

@@ -1,77 +0,0 @@
-<template>
-  <div ref="editor" style="text-align:left"></div>
-</template>
-<script>
-import E from 'wangeditor';
-
-const menus = [
-  'code', // 插入代码
-  'head', // 标题
-  'bold', // 粗体
-  'fontSize', // 字号
-  'fontName', // 字体
-  'italic', // 斜体
-  'underline', // 下划线
-  'strikeThrough', // 删除线
-  'foreColor', // 文字颜色
-  'backColor', // 背景颜色
-  'link', // 插入链接
-  'list', // 列表
-  'justify', // 对齐方式
-  'quote', // 引用
-  // 'emoticon', // 表情
-  'table', // 表格
-  // 'video', // 插入视频
-  'undo', // 撤销
-  'redo', // 重复
-];
-
-export default {
-  name: 'wang-editor',
-  model: {
-    prop: 'value',
-    event: 'change', // 默认为input时间,此处改为change
-  },
-  props: {
-    value: { type: String, required: false, default: '' },
-  },
-  data() {
-    return {
-      editorContent: this.value,
-    };
-  },
-  mounted() {
-    var editor = new E(this.$refs.editor);
-    editor.customConfig.onchange = html => {
-      this.editorContent = html;
-      this.$emit('change', html);
-    };
-    // 自定义菜单配置
-    editor.customConfig.menus = menus;
-    editor.customConfig.zIndex = 0;
-    editor.customConfig.uploadImgServer = '/files/cms/images/upload';
-    editor.customConfig.uploadImgMaxLength = 1;
-    editor.customConfig.uploadImgHooks = {
-      // 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置
-      // (但是,服务器端返回的必须是一个 JSON 格式字符串!!!否则会报错)
-      customInsert: function(insertImg, result, editor) {
-        // 图片上传并返回结果,自定义插入图片的事件(而不是编辑器自动插入图片!!!)
-        // insertImg 是插入图片的函数,editor 是编辑器对象,result 是服务器端返回的结果
-
-        // 举例:假如上传图片成功后,服务器端返回的是 {url:'....'} 这种格式,即可这样插入图片:
-        var url = result.uri;
-        insertImg(url);
-
-        // result 必须是一个 JSON 格式字符串!!!否则报错
-      },
-    };
-    editor.create();
-    editor.txt.html(this.value);
-  },
-  methods: {
-    getContent: function() {
-      return this.editorContent;
-    },
-  },
-};
-</script>

+ 2 - 4
src/main.js

@@ -6,17 +6,15 @@ import ElementUI from 'element-ui';
 import '@/plugins/axios';
 import '@/plugins/check-res';
 import '@/plugins/meta';
-import '@/plugins/filters';
 import '@/plugins/loading';
-import '@/plugins/var';
-import '@/plugins/methods';
 import '@/plugins/setting';
 import 'element-ui/lib/theme-chalk/index.css'; // 默认主题
 // import './assets/css/theme-green/index.css'; // 浅绿色主题
 import './assets/css/icon.css';
 import '@l/directives';
 import 'babel-polyfill';
-
+import animated from 'animate.css';
+Vue.use(animated);
 Vue.config.productionTip = false;
 Vue.use(ElementUI, {
   size: 'small',

+ 1 - 1
src/plugins/axios.js

@@ -1,5 +1,5 @@
 import Vue from 'vue';
-import AxiosWrapper from '@/util/axios-wrapper';
+import AxiosWrapper from '@f/util/axios-wrapper';
 
 const Plugin = {
   install(vue, options) {

+ 0 - 6
src/plugins/filters.js

@@ -1,6 +0,0 @@
-import Vue from 'vue';
-import filters from '@/util/filters';
-
-for (const method in filters) {
-  Vue.filter(method, filters[method]);
-}

+ 0 - 33
src/plugins/methods.js

@@ -1,33 +0,0 @@
-import Vue from 'vue';
-import _ from 'lodash';
-const Plugin = {
-  install(Vue, options) {
-    // 3. 注入组件
-    Vue.mixin({
-      created() {
-        if (this.$store && !this.$store.$toUndefined) {
-          this.$store.$toUndefined = this.$toUndefined;
-        }
-      },
-    });
-    // 4. 添加实例方法
-    Vue.prototype.$toUndefined = object => {
-      let keys = Object.keys(object);
-      keys.map(item => {
-        object[item] = object[item] === '' ? (object[item] = undefined) : object[item];
-      });
-      return object;
-    };
-    Vue.prototype.$turnTo = item => {
-      if (item.info_type == 1) {
-        window.open(item.url);
-      } else {
-        let router = window.vm.$router;
-        let route = window.vm.$route.path;
-        router.push({ path: `/info/detail?id=${item.id}` });
-      }
-    };
-  },
-};
-
-Vue.use(Plugin);

+ 0 - 25
src/plugins/var.js

@@ -1,25 +0,0 @@
-import Vue from 'vue';
-import _ from 'lodash';
-
-const getSiteId = () => {
-  let host = `${window.location.hostname}`; //`999991.smart.jilinjobswx.cn ${window.location.hostname}`
-  let schId;
-  host = host.replace('http://', '');
-  let arr = host.split('.');
-  if (arr.length > 0) {
-    schId = arr[0];
-    if (schId === 'smart') schId = 'master';
-    else `${schId}`.includes('localhost') || `${schId}`.includes('127.0.0.1') ? (schId = '99991') : '';
-    sessionStorage.setItem('schId', `${schId}`.includes('localhost') || `${schId}`.includes('127.0.0.1') ? '99991' : schId);
-  }
-  return schId;
-};
-const Plugin = {
-  install(vue, options) {
-    // 4. 添加实例方法
-    vue.prototype.$limit = 10;
-    vue.prototype.$site = getSiteId();
-  },
-};
-
-Vue.use(Plugin);

+ 7 - 0
src/router/index.js

@@ -2,6 +2,7 @@ import Vue from 'vue';
 import Router from 'vue-router';
 import test from './test';
 import auth from './auth';
+import order from './order';
 import Home from '@l/Home.vue';
 
 Vue.use(Router);
@@ -26,6 +27,7 @@ export default new Router({
         },
         ...test,
         ...auth,
+        ...order,
       ],
     },
     {
@@ -33,6 +35,11 @@ export default new Router({
       component: () => import('../views/Login.vue'),
       meta: { title: '登录' },
     },
+    {
+      path: '/404',
+      component: () => import('../views/404.vue'),
+      meta: { title: '未找到页面' },
+    },
     {
       path: '*',
       redirect: '/404',

+ 12 - 0
src/router/order.js

@@ -0,0 +1,12 @@
+export default [
+  {
+    path: '/order/index',
+    component: () => import('../views/order/index.vue'),
+    meta: { title: '订单管理' },
+  },
+  {
+    path: '/order/card',
+    component: () => import('../views/order/index-card.vue'),
+    meta: { title: '订单-卡片模式' },
+  },
+];

+ 0 - 135
src/util/axios-wrapper.js

@@ -1,135 +0,0 @@
-/* eslint-disable require-atomic-updates */
-/* eslint-disable no-console */
-/* eslint-disable no-param-reassign */
-
-import _ from 'lodash';
-import Axios from 'axios';
-import { Util, Error } from 'naf-core';
-import { Loading } from 'element-ui';
-import UserUtil from './user-util';
-
-const { trimData, isNullOrUndefined } = Util;
-const { ErrorCode } = Error;
-
-let currentRequests = 0;
-
-export default class AxiosWrapper {
-  constructor({ baseUrl = '', unwrap = true } = {}) {
-    this.baseUrl = baseUrl;
-    this.unwrap = unwrap;
-  }
-
-  // 替换uri中的参数变量
-  static merge(uri, query = {}) {
-    if (!uri.includes(':')) {
-      return uri;
-    }
-    const keys = [];
-    const regexp = /\/:([a-z0-9_]+)/gi;
-    let res;
-    // eslint-disable-next-line no-cond-assign
-    while ((res = regexp.exec(uri)) != null) {
-      keys.push(res[1]);
-    }
-    keys.forEach(key => {
-      if (!isNullOrUndefined(query[key])) {
-        uri = uri.replace(`:${key}`, query[key]);
-      }
-    });
-    return uri;
-  }
-
-  $get(uri, query, options) {
-    return this.$request(uri, null, query, options);
-  }
-
-  $delete(uri, query, options = {}) {
-    return this.$request(uri, null, query, { ...options, method: 'delete' });
-  }
-
-  $post(uri, data = {}, query, options) {
-    return this.$request(uri, data, query, options);
-  }
-
-  async $request(uri, data, query, options) {
-    // 过滤key:''的情况
-    query = _.pickBy(query, val => val !== '' && val !== 'undefined' && val !== 'null');
-    if (!uri) console.error('uri不能为空');
-    if (_.isObject(query) && _.isObject(options)) {
-      const params = query.params ? query.params : query;
-      options = { ...options, params };
-    } else if (_.isObject(query) && !query.params) {
-      options = { params: query };
-    } else if (_.isObject(query) && query.params) {
-      options = query;
-    }
-    if (!options) options = {};
-    if (options.params) options.params = trimData(options.params);
-    const url = AxiosWrapper.merge(uri, options.params);
-
-    currentRequests += 1;
-    // const loadingInstance = Loading.service({ spinner: 'el-icon-loading', background: 'rgba(0, 0, 0, 0.5)' });
-
-    try {
-      const axios = Axios.create({
-        baseURL: this.baseUrl,
-      });
-      const user = localStorage.getItem('user');
-      if (user) {
-        axios.defaults.headers.common.Authorization = encodeURI(user);
-      }
-      let res = await axios.request({
-        method: isNullOrUndefined(data) ? 'get' : 'post',
-        url,
-        data,
-        responseType: 'json',
-        ...options,
-      });
-      res = res.data || {};
-      const { errcode, errmsg, details } = res;
-      if (errcode) {
-        console.warn(`[${uri}] fail: ${errcode}-${errmsg} ${details}`);
-        return undefined;
-      }
-      // unwrap data
-      if (this.unwrap) {
-        res = _.omit(res, ['errcode', 'errmsg', 'details']);
-        const keys = Object.keys(res);
-        if (keys.length === 1 && keys.includes('data')) {
-          res = res.data;
-        }
-      }
-      return res;
-    } catch (err) {
-      let errmsg = '接口请求失败,请稍后重试';
-      if (err.response) {
-        const { status, data = {} } = err.response;
-        console.log(err.response);
-        if (status === 401) errmsg = '用户认证失败,请重新登录';
-        if (status === 403) errmsg = '当前用户不允许执行该操作';
-        if (status === 400 && data.errcode) {
-          const { errcode, errmsg, details } = data;
-          console.warn(`[${uri}] fail: ${errcode}-${errmsg} ${details}`);
-          return data;
-        }
-        if (data && data.error) {
-          const { status, error, message } = data;
-          console.warn(`[${uri}] fail: ${status}: ${error}-${message}`);
-          return {
-            errcode: status || ErrorCode.SERVICE_FAULT,
-            errmsg: error,
-            details: message,
-          };
-        }
-      }
-      console.error(`[AxiosWrapper] 接口请求失败: ${err.config && err.config.url} - ${err.message}`);
-      return { errcode: ErrorCode.SERVICE_FAULT, errmsg, details: err.message };
-    } finally {
-      currentRequests -= 1;
-      if (currentRequests <= 0) {
-        currentRequests = 0;
-        // loadingInstance.close();
-      }
-    }
-  }
-}

+ 0 - 10
src/util/filters.js

@@ -1,10 +0,0 @@
-import _ from 'lodash';
-
-const filters = {
-  getName(object) {
-    const { data, searchItem } = object;
-    return _.get(data, searchItem) === undefined ? '' : _.get(data, searchItem);
-  },
-};
-
-export default filters;

+ 0 - 282
src/util/iconmenu.js

@@ -1,282 +0,0 @@
-export const iconmenu = [
-  { iconkey: 'el-icon-platform-eleme' },
-  { iconkey: 'el-icon-eleme' },
-  { iconkey: 'el-icon-delete-solid' },
-  { iconkey: 'el-icon-delete' },
-  { iconkey: 'el-icon-s-tools' },
-  { iconkey: 'el-icon-setting' },
-  { iconkey: 'el-icon-user-solid' },
-  { iconkey: 'el-icon-user' },
-  { iconkey: 'el-icon-phone' },
-  { iconkey: 'el-icon-phone-outline' },
-  { iconkey: 'el-icon-more' },
-  { iconkey: 'el-icon-more-outline' },
-  { iconkey: 'el-icon-star-on' },
-  { iconkey: 'el-icon-star-off' },
-  { iconkey: 'el-icon-s-goods' },
-  { iconkey: 'el-icon-goods' },
-  { iconkey: 'el-icon-warning' },
-  { iconkey: 'el-icon-warning-outline' },
-  { iconkey: 'el-icon-question' },
-  { iconkey: 'el-icon-info' },
-  { iconkey: 'el-icon-remove' },
-  { iconkey: 'el-icon-circle-plus' },
-  { iconkey: 'el-icon-success' },
-  { iconkey: 'el-icon-error' },
-  { iconkey: 'el-icon-zoom-in' },
-  { iconkey: 'el-icon-zoom-out' },
-  { iconkey: 'el-icon-remove-outline' },
-  { iconkey: 'el-icon-circle-plus-outline' },
-  { iconkey: 'el-icon-circle-check' },
-  { iconkey: 'el-icon-circle-close' },
-  { iconkey: 'el-icon-s-help' },
-  { iconkey: 'el-icon-help' },
-  { iconkey: 'el-icon-minus' },
-  { iconkey: 'el-icon-plus' },
-  { iconkey: 'el-icon-check' },
-  { iconkey: 'el-icon-close' },
-  { iconkey: 'el-icon-picture' },
-  { iconkey: 'el-icon-picture-outline' },
-  { iconkey: 'el-icon-picture-outline-round' },
-  { iconkey: 'el-icon-upload' },
-  { iconkey: 'el-icon-upload2' },
-  { iconkey: 'el-icon-download' },
-  { iconkey: 'el-icon-camera-solid' },
-  { iconkey: 'el-icon-camera' },
-  { iconkey: 'el-icon-video-camera-solid' },
-  { iconkey: 'el-icon-video-camera' },
-  { iconkey: 'el-icon-message-solid' },
-  { iconkey: 'el-icon-bell' },
-  { iconkey: 'el-icon-s-cooperation' },
-  { iconkey: 'el-icon-s-order' },
-  { iconkey: 'el-icon-s-platform' },
-  { iconkey: 'el-icon-s-fold' },
-  { iconkey: 'el-icon-s-unfold' },
-  { iconkey: 'el-icon-s-operation' },
-  { iconkey: 'el-icon-s-promotion' },
-  { iconkey: 'el-icon-s-home' },
-  { iconkey: 'el-icon-s-release' },
-  { iconkey: 'el-icon-s-ticket' },
-  { iconkey: 'el-icon-s-management' },
-  { iconkey: 'el-icon-s-open' },
-  { iconkey: 'el-icon-s-shop' },
-  { iconkey: 'el-icon-s-marketing' },
-  { iconkey: 'el-icon-s-flag' },
-  { iconkey: 'el-icon-s-comment' },
-  { iconkey: 'el-icon-s-finance' },
-  { iconkey: 'el-icon-s-claim' },
-  { iconkey: 'el-icon-s-custom' },
-  { iconkey: 'el-icon-s-opportunity' },
-  { iconkey: 'el-icon-s-data' },
-  { iconkey: 'el-icon-s-check' },
-  { iconkey: 'el-icon-s-grid' },
-  { iconkey: 'el-icon-menu' },
-  { iconkey: 'el-icon-share' },
-  { iconkey: 'el-icon-d-caret' },
-  { iconkey: 'el-icon-caret-left' },
-  { iconkey: 'el-icon-caret-right' },
-  { iconkey: 'el-icon-caret-bottom' },
-  { iconkey: 'el-icon-caret-top' },
-  { iconkey: 'el-icon-bottom-left' },
-  { iconkey: 'el-icon-bottom-right' },
-  { iconkey: 'el-icon-back' },
-  { iconkey: 'el-icon-right' },
-  { iconkey: 'el-icon-bottom' },
-  { iconkey: 'el-icon-top' },
-  { iconkey: 'el-icon-top-left' },
-  { iconkey: 'el-icon-top-right' },
-  { iconkey: 'el-icon-arrow-left' },
-  { iconkey: 'el-icon-arrow-right' },
-  { iconkey: 'el-icon-arrow-down' },
-  { iconkey: 'el-icon-arrow-up' },
-  { iconkey: 'el-icon-d-arrow-left' },
-  { iconkey: 'el-icon-d-arrow-right' },
-  { iconkey: 'el-icon-video-pause' },
-  { iconkey: 'el-icon-video-play' },
-  { iconkey: 'el-icon-refresh' },
-  { iconkey: 'el-icon-refresh-right' },
-  { iconkey: 'el-icon-refresh-left' },
-  { iconkey: 'el-icon-finished' },
-  { iconkey: 'el-icon-sort' },
-  { iconkey: 'el-icon-sort-up' },
-  { iconkey: 'el-icon-sort-down' },
-  { iconkey: 'el-icon-rank' },
-  { iconkey: 'el-icon-loading' },
-  { iconkey: 'el-icon-view' },
-  { iconkey: 'el-icon-c-scale-to-original' },
-  { iconkey: 'el-icon-date' },
-  { iconkey: 'el-icon-edit' },
-  { iconkey: 'el-icon-edit-outline' },
-  { iconkey: 'el-icon-folder' },
-  { iconkey: 'el-icon-folder-opened' },
-  { iconkey: 'el-icon-folder-add' },
-  { iconkey: 'el-icon-folder-remove' },
-  { iconkey: 'el-icon-folder-delete' },
-  { iconkey: 'el-icon-folder-checked' },
-  { iconkey: 'el-icon-tickets' },
-  { iconkey: 'el-icon-document-remove' },
-  { iconkey: 'el-icon-document-delete' },
-  { iconkey: 'el-icon-document-copy' },
-  { iconkey: 'el-icon-document-checked' },
-  { iconkey: 'el-icon-document' },
-  { iconkey: 'el-icon-document-add' },
-  { iconkey: 'el-icon-printer' },
-  { iconkey: 'el-icon-paperclip' },
-  { iconkey: 'el-icon-takeaway-box' },
-  { iconkey: 'el-icon-search' },
-  { iconkey: 'el-icon-monitor' },
-  { iconkey: 'el-icon-attract' },
-  { iconkey: 'el-icon-mobile' },
-  { iconkey: 'el-icon-scissors' },
-  { iconkey: 'el-icon-umbrella' },
-  { iconkey: 'el-icon-headset' },
-  { iconkey: 'el-icon-brush' },
-  { iconkey: 'el-icon-mouse' },
-  { iconkey: 'el-icon-coordinate' },
-  { iconkey: 'el-icon-magic-stick' },
-  { iconkey: 'el-icon-reading' },
-  { iconkey: 'el-icon-data-line' },
-  { iconkey: 'el-icon-data-board' },
-  { iconkey: 'el-icon-pie-chart' },
-  { iconkey: 'el-icon-data-analysis' },
-  { iconkey: 'el-icon-collection-tag' },
-  { iconkey: 'el-icon-film' },
-  { iconkey: 'el-icon-suitcase' },
-  { iconkey: 'el-icon-suitcase-1' },
-  { iconkey: 'el-icon-receiving' },
-  { iconkey: 'el-icon-collection' },
-  { iconkey: 'el-icon-files' },
-  { iconkey: 'el-icon-notebook-1' },
-  { iconkey: 'el-icon-notebook-2' },
-  { iconkey: 'el-icon-toilet-paper' },
-  { iconkey: 'el-icon-office-building' },
-  { iconkey: 'el-icon-school' },
-  { iconkey: 'el-icon-table-lamp' },
-  { iconkey: 'el-icon-house' },
-  { iconkey: 'el-icon-no-smoking' },
-  { iconkey: 'el-icon-smoking' },
-  { iconkey: 'el-icon-shopping-cart-full' },
-  { iconkey: 'el-icon-shopping-cart-1' },
-  { iconkey: 'el-icon-shopping-cart-2' },
-  { iconkey: 'el-icon-shopping-bag-1' },
-  { iconkey: 'el-icon-shopping-bag-2' },
-  { iconkey: 'el-icon-sold-out' },
-  { iconkey: 'el-icon-sell' },
-  { iconkey: 'el-icon-present' },
-  { iconkey: 'el-icon-box' },
-  { iconkey: 'el-icon-bank-card' },
-  { iconkey: 'el-icon-money' },
-  { iconkey: 'el-icon-coin' },
-  { iconkey: 'el-icon-wallet' },
-  { iconkey: 'el-icon-discount' },
-  { iconkey: 'el-icon-price-tag' },
-  { iconkey: 'el-icon-news' },
-  { iconkey: 'el-icon-guide' },
-  { iconkey: 'el-icon-male' },
-  { iconkey: 'el-icon-female' },
-  { iconkey: 'el-icon-thumb' },
-  { iconkey: 'el-icon-cpu' },
-  { iconkey: 'el-icon-link' },
-  { iconkey: 'el-icon-connection' },
-  { iconkey: 'el-icon-open' },
-  { iconkey: 'el-icon-turn-off' },
-  { iconkey: 'el-icon-set-up' },
-  { iconkey: 'el-icon-chat-round' },
-  { iconkey: 'el-icon-chat-line-round' },
-  { iconkey: 'el-icon-chat-square' },
-  { iconkey: 'el-icon-chat-dot-round' },
-  { iconkey: 'el-icon-chat-dot-square' },
-  { iconkey: 'el-icon-chat-line-square' },
-  { iconkey: 'el-icon-message' },
-  { iconkey: 'el-icon-postcard' },
-  { iconkey: 'el-icon-position' },
-  { iconkey: 'el-icon-turn-off-microphone' },
-  { iconkey: 'el-icon-microphone' },
-  { iconkey: 'el-icon-close-notification' },
-  { iconkey: 'el-icon-bangzhu' },
-  { iconkey: 'el-icon-time' },
-  { iconkey: 'el-icon-odometer' },
-  { iconkey: 'el-icon-crop' },
-  { iconkey: 'el-icon-aim' },
-  { iconkey: 'el-icon-switch-button' },
-  { iconkey: 'el-icon-full-screen' },
-  { iconkey: 'el-icon-copy-document' },
-  { iconkey: 'el-icon-mic' },
-  { iconkey: 'el-icon-stopwatch' },
-  { iconkey: 'el-icon-medal-1' },
-  { iconkey: 'el-icon-medal' },
-  { iconkey: 'el-icon-trophy' },
-  { iconkey: 'el-icon-trophy-1' },
-  { iconkey: 'el-icon-first-aid-kit' },
-  { iconkey: 'el-icon-discover' },
-  { iconkey: 'el-icon-place' },
-  { iconkey: 'el-icon-location' },
-  { iconkey: 'el-icon-location-outline' },
-  { iconkey: 'el-icon-location-information' },
-  { iconkey: 'el-icon-add-location' },
-  { iconkey: 'el-icon-delete-location' },
-  { iconkey: 'el-icon-map-location' },
-  { iconkey: 'el-icon-alarm-clock' },
-  { iconkey: 'el-icon-timer' },
-  { iconkey: 'el-icon-watch-1' },
-  { iconkey: 'el-icon-watch' },
-  { iconkey: 'el-icon-lock' },
-  { iconkey: 'el-icon-unlock' },
-  { iconkey: 'el-icon-key' },
-  { iconkey: 'el-icon-service' },
-  { iconkey: 'el-icon-mobile-phone' },
-  { iconkey: 'el-icon-bicycle' },
-  { iconkey: 'el-icon-truck' },
-  { iconkey: 'el-icon-ship' },
-  { iconkey: 'el-icon-basketball' },
-  { iconkey: 'el-icon-football' },
-  { iconkey: 'el-icon-soccer' },
-  { iconkey: 'el-icon-baseball' },
-  { iconkey: 'el-icon-wind-power' },
-  { iconkey: 'el-icon-light-rain' },
-  { iconkey: 'el-icon-lightning' },
-  { iconkey: 'el-icon-heavy-rain' },
-  { iconkey: 'el-icon-sunrise' },
-  { iconkey: 'el-icon-sunrise-1' },
-  { iconkey: 'el-icon-sunset' },
-  { iconkey: 'el-icon-sunny' },
-  { iconkey: 'el-icon-cloudy' },
-  { iconkey: 'el-icon-partly-cloudy' },
-  { iconkey: 'el-icon-cloudy-and-sunny' },
-  { iconkey: 'el-icon-moon' },
-  { iconkey: 'el-icon-moon-night' },
-  { iconkey: 'el-icon-dish' },
-  { iconkey: 'el-icon-dish-1' },
-  { iconkey: 'el-icon-food' },
-  { iconkey: 'el-icon-chicken' },
-  { iconkey: 'el-icon-fork-spoon' },
-  { iconkey: 'el-icon-knife-fork' },
-  { iconkey: 'el-icon-burger' },
-  { iconkey: 'el-icon-tableware' },
-  { iconkey: 'el-icon-sugar' },
-  { iconkey: 'el-icon-dessert' },
-  { iconkey: 'el-icon-ice-cream' },
-  { iconkey: 'el-icon-hot-water' },
-  { iconkey: 'el-icon-water-cup' },
-  { iconkey: 'el-icon-coffee-cup' },
-  { iconkey: 'el-icon-cold-drink' },
-  { iconkey: 'el-icon-goblet' },
-  { iconkey: 'el-icon-goblet-full' },
-  { iconkey: 'el-icon-goblet-square' },
-  { iconkey: 'el-icon-goblet-square-full' },
-  { iconkey: 'el-icon-refrigerator' },
-  { iconkey: 'el-icon-grape' },
-  { iconkey: 'el-icon-watermelon' },
-  { iconkey: 'el-icon-cherry' },
-  { iconkey: 'el-icon-apple' },
-  { iconkey: 'el-icon-pear' },
-  { iconkey: 'el-icon-orange' },
-  { iconkey: 'el-icon-coffee' },
-  { iconkey: 'el-icon-ice-tea' },
-  { iconkey: 'el-icon-ice-drink' },
-  { iconkey: 'el-icon-milk-tea' },
-  { iconkey: 'el-icon-potato-strips' },
-  { iconkey: 'el-icon-lollipop' },
-  { iconkey: 'el-icon-ice-cream-square' },
-  { iconkey: 'el-icon-ice-cream-round' },
-];

+ 0 - 50
src/util/methods-util.js

@@ -1,50 +0,0 @@
-import { Util } from 'naf-core';
-
-const { isNullOrUndefined } = Util;
-
-export default {
-  //判断信息是否过期
-  isDateOff(dataDate) {
-    const now = new Date(new Date().getTime() - 24 * 60 * 60 * 1000);
-    dataDate = new Date(dataDate);
-    return now.getTime() <= dataDate.getTime();
-  },
-  //判断企业是否可以执行此动作/显示
-  checkCorp(data) {
-    const { role, unit, selfUnit, status, displayType, userid } = data;
-    if (!isNullOrUndefined(selfUnit) && !isNullOrUndefined(status)) {
-      return role === 'corp' && selfUnit === unit && status === '0';
-    } else if (!isNullOrUndefined(displayType)) {
-      if (role === 'corp') {
-        return role === displayType;
-      } else {
-        return role === displayType && !isNullOrUndefined(userid);
-      }
-    }
-  },
-  //获取url的参数params
-  getParams() {
-    let str = location.href;
-    let num = str.indexOf('?');
-    const param = {};
-    str = str.substr(num + 1);
-    let num2 = str.indexOf('#');
-    let str2 = '';
-    if (num2 > 0) {
-      str2 = str.substr(0, num2);
-    } else {
-      num2 = str.indexOf('/');
-      str2 = str.substr(0, num2);
-    }
-    const arr = str2.split('&');
-    for (let i = 0; i < arr.length; i++) {
-      num = arr[i].indexOf('=');
-      if (num > 0) {
-        const name = arr[i].substring(0, num);
-        const value = arr[i].substr(num + 1);
-        param[name] = decodeURI(value);
-      }
-    }
-    return param;
-  },
-};

+ 0 - 1
src/util/type.js

@@ -1 +0,0 @@
-export const type = [{ name: 'Km常规保养口' }, { name: '一般维修口' }, { name: '事故车口' }, { name: '洗车口' }, { name: '其他口' }];

+ 0 - 69
src/util/user-util.js

@@ -1,69 +0,0 @@
-/* eslint-disable no-console */
-export default {
-  get user() {
-    const val = sessionStorage.getItem('user');
-    try {
-      if (val) return JSON.parse(val);
-    } catch (err) {
-      console.error(err);
-    }
-    return null;
-  },
-  set user(userinfo) {
-    sessionStorage.setItem('user', JSON.stringify(userinfo));
-  },
-  get token() {
-    return sessionStorage.getItem('token');
-  },
-  set token(token) {
-    sessionStorage.setItem('token', token);
-  },
-  get openid() {
-    return sessionStorage.getItem('openid');
-  },
-  set openid(openid) {
-    sessionStorage.setItem('openid', openid);
-  },
-  get isGuest() {
-    return !this.user || this.user.role === 'guest';
-  },
-  save({ userinfo, token }) {
-    sessionStorage.setItem('user', JSON.stringify(userinfo));
-    sessionStorage.setItem('token', token);
-  },
-
-  get corpInfo() {
-    const val = sessionStorage.getItem('corpInfo');
-    if (val) return JSON.parse(val);
-    return null;
-  },
-  set corpInfo(corpInfo) {
-    sessionStorage.setItem('corpInfo', JSON.stringify(corpInfo));
-  },
-  saveCorpInfo(corpInfo) {
-    sessionStorage.setItem('corpInfo', JSON.stringify(corpInfo));
-  },
-
-  get unit() {
-    const val = sessionStorage.getItem('unit');
-    if (val) return JSON.parse(val);
-    return null;
-  },
-  set unit(unitList) {
-    sessionStorage.setItem('unit', JSON.stringify(unitList));
-  },
-  saveUnit(unitList) {
-    sessionStorage.setItem('unit', JSON.stringify(unitList));
-  },
-  get userInfo() {
-    const val = sessionStorage.getItem('userInfo');
-    if (val) return JSON.parse(val);
-    return null;
-  },
-  set userInfo(userInfo) {
-    sessionStorage.setItem('userInfo', JSON.stringify(userInfo));
-  },
-  saveUserInfo(userInfo) {
-    sessionStorage.setItem('userInfo', JSON.stringify(userInfo));
-  },
-};

Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 16989
src/util/user.js


+ 7 - 10
src/views/auth/menu.vue

@@ -3,9 +3,12 @@
     <el-row>
       <el-col :span="24" class="main">
         <el-col :span="24" class="container info">
-          <el-col :span="24" class="top right btn_bar">
-            <el-button type="primary" size="mini" @click="toDialog()">添加主目录</el-button>
-          </el-col>
+          <el-row type="flex" justify="space-between" align="middle" class="btn_bar">
+            <el-col :span="24" class="top right">
+              <el-button type="primary" size="mini" @click="toDialog()">添加主目录</el-button>
+            </el-col>
+          </el-row>
+
           <el-col :span="24" class="list">
             <el-table :data="list" row-key="title" border stripe :tree-props="defaultProps" :default-expand-all="true">
               <el-table-column header-align="center" label="目录名称" prop="title"></el-table-column>
@@ -41,7 +44,7 @@
 </template>
 
 <script>
-import dataForm from '@/components/form.vue';
+import dataForm from '@f/components/form.vue';
 import { mapState, createNamespacedHelpers } from 'vuex';
 const { mapActions: util } = createNamespacedHelpers('util');
 const { mapActions: menu } = createNamespacedHelpers('menu');
@@ -78,12 +81,6 @@ export default {
     async getModel() {
       let res = await this.authModel('menu');
       if (res) {
-        res = res.map(i => {
-          let { options } = i;
-          i = { ..._.omit(i, ['options']), ...options };
-          return i;
-        });
-
         this.$set(this, `fields`, res);
       }
     },

+ 127 - 0
src/views/order/index-card.vue

@@ -0,0 +1,127 @@
+<template>
+  <div id="card-mode">
+    <el-row :gutter="20" style="overflow-y:auto; height: 74vh;">
+      <transition-group
+        mode="out-in"
+        enter-active-class="animate__animated animate__zoomIn animate__delay "
+        leave-active-class="animate__animated animate__zoomOutDown"
+      >
+        <template v-if="view == 'list'">
+          <el-col :span="span" v-for="(i, index) in list" :key="`col${index}`" style="padding-top:10px">
+            <el-card body-style="height:250px; overflow-y:auto">
+              <template #header>
+                <el-row type="flex" justify="space-between" align="middle">
+                  <el-col :span="10"> 订单号:{{ i.order_no }} </el-col>
+                  <el-col :span="2">
+                    <el-link type="primary" :underline="false" @click="toEdit(i)">编辑</el-link>
+                  </el-col>
+                  <el-col :span="2">
+                    <el-link type="danger" :underline="false">删除</el-link>
+                  </el-col>
+                </el-row>
+              </template>
+              <el-row class="row">
+                <el-col :span="24">客户:长春市福瑞科技有限公司</el-col>
+                <el-col :span="24">发货时间:2020-11-11</el-col>
+                <el-col :span="24">要求到达时间: 2020-11-15</el-col>
+                <el-col :span="24">
+                  货物:
+                  <el-col :span="24">玻璃 1t 5件 30m³</el-col>
+                  <el-col :span="24">铁桶 0.5t 1件 5m³</el-col>
+                </el-col>
+              </el-row>
+            </el-card>
+          </el-col>
+        </template>
+        <template v-else>
+          <order-form v-model="form" key="detail" @toReturn="view = 'list'"></order-form>
+          <el-row key="detailRow" type="flex" justify="space-around">
+            <el-col :span="4">
+              <el-button type="primary" @click="toSave">保存订单</el-button>
+            </el-col>
+          </el-row>
+        </template>
+      </transition-group>
+      <el-col :span="24" v-if="disabled">没有订单啦!</el-col>
+    </el-row>
+    <page @query="search" :total="total" :limit="limit" :step="8"></page>
+  </div>
+</template>
+
+<script>
+import page from '@f/components/pagination.vue';
+import orderForm from './index-parts/form.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'card-mode',
+  props: {},
+  components: { orderForm, page },
+  data: function() {
+    return {
+      form: {},
+      list: [],
+      total: 50,
+      sform: {},
+      view: 'list',
+      limit: 8,
+      step: 8,
+      span: 6,
+      disabled: false,
+    };
+  },
+  created() {
+    this.search();
+  },
+  methods: {
+    async search({ skip = 0, limit = this.limit } = {}) {
+      if (this.limit !== limit) this.$set(this, `limit`, limit);
+      this.disabled = true;
+      const l = skip;
+      let arr = [];
+      for (let i = 1; i <= limit; i++) {
+        const obj = { order_no: `no${l + i}`, goods: [{ name: `g${l + i}`, number: l + i }] };
+        arr.push(obj);
+      }
+      this.$set(this, `list`, arr);
+      if (this.list.length < 40) this.disabled = false;
+    },
+    // 保存
+    async toSave() {
+      let duplicate = _.cloneDeep(this.form);
+      const { id } = this.form;
+      let res;
+      if (id) {
+        res = await this.update(duplicate);
+      } else {
+        res = await this.create(duplicate);
+      }
+      if (this.$checkRes(res, '保存成功', '保存失败')) {
+        this.search();
+      }
+    },
+    // 编辑
+    async toEdit({ data }) {
+      console.log('in function:toEdit');
+      this.view = 'detail';
+    },
+    // 删除
+    async toDelete({ data }) {
+      console.log('in function:delete');
+    },
+    toAdd() {
+      this.view = 'detail';
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 157 - 0
src/views/order/index-parts/form.vue

@@ -0,0 +1,157 @@
+<template>
+  <div id="form">
+    <el-row>
+      <el-col :span="24">
+        <el-button type="info" @click="toReturn">返回</el-button>
+      </el-col>
+      <el-col :span="24">
+        订单详情
+      </el-col>
+    </el-row>
+    <el-row type="flex" style="padding:10px" :gutter="20">
+      <el-col :span="9">
+        <el-form :model="form" label-width="100px">
+          <el-form-item label="订单号">
+            <el-input v-model="form.order_no" placeholder="请填写订单号(若需要延后填写,可以不填)"></el-input>
+          </el-form-item>
+          <el-form-item label="订单生成人">
+            {{ form.user || '此处应该是默认且不需要填写,若您看到该信息,说明程序或账户出现问题' }}
+          </el-form-item>
+          <el-form-item label="客户" prop="client" required>
+            <el-select v-model="form.client" placeholder="请选择客户">
+              <el-option v-for="(i, index) in clientList" :key="index" :label="i.name" :value="i._id"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="要求发货日期">
+            <el-date-picker v-model="form.rq_send_time" type="date" placeholder="选择择要求发货日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd">
+            </el-date-picker>
+          </el-form-item>
+          <el-form-item label="发货日期">
+            {{ form.send_time }}
+          </el-form-item>
+          <el-form-item label="要求到达日期">
+            <el-date-picker v-model="form.rq_arrive_time" type="date" placeholder="选择择要求发货日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd">
+            </el-date-picker>
+          </el-form-item>
+          <el-form-item label="实际到达日期">
+            {{ form.arrive_time }}
+          </el-form-item>
+          <el-form-item label="预收金额">
+            <el-tooltip effect="dark" content="若没有预收金额,无需填写" placement="top">
+              <el-input-number controls-position="right" v-model="form.pre_money" :min="0"></el-input-number>
+            </el-tooltip>
+          </el-form-item>
+          <el-form-item label="备注">
+            <el-input type="textarea" :autosize="{ minRows: 5, maxRows: 10 }" placeholder="请填写备注"></el-input>
+          </el-form-item>
+        </el-form>
+      </el-col>
+      <el-col :span="15">
+        <el-row>
+          <el-col :span="24">
+            <el-alert type="warning" title="某种货物需要按不同方式计费时,请将货物按计算方式分成多个货物录入" :closable="false"></el-alert>
+          </el-col>
+          <el-col :span="24" style="text-align:right">
+            <el-button type="primary" @click="addGoods">添加货物</el-button>
+          </el-col>
+          <el-col :span="24">
+            <el-table :data="form.goods" stripe border>
+              <el-table-column align="center" label="货物名称">
+                <template v-slot="{ row }">
+                  <el-input v-model="row.name" placeholder="请填写货物名称"></el-input>
+                </template>
+              </el-table-column>
+              <el-table-column align="center" label="数量">
+                <template v-slot="{ row }">
+                  <el-input-number controls-position="right" v-model="row.number" :min="0"></el-input-number>
+                </template>
+              </el-table-column>
+              <el-table-column align="center" label="重量(t)">
+                <template v-slot="{ row }">
+                  <el-input-number controls-position="right" v-model="row.weight" :min="0"></el-input-number>
+                </template>
+              </el-table-column>
+              <el-table-column align="center" label="体积(m³)">
+                <template v-slot="{ row }">
+                  <el-input-number controls-position="right" v-model="row.volume" :min="0"></el-input-number>
+                </template>
+              </el-table-column>
+              <el-table-column align="center" label="计费方式">
+                <template v-slot="{ row }">
+                  <el-select v-model="row.type" placeholder="请选择计费方式">
+                    <el-option v-for="(i, index) in costType" :key="index" :label="i.name" :value="i._id"></el-option>
+                  </el-select>
+                </template>
+              </el-table-column>
+              <el-table-column align="center" label="操作" width="70px">
+                <template v-slot="{ row }">
+                  <el-link type="danger" :underline="false" @click="toDeletGoods(row)">删除</el-link>
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-col>
+        </el-row>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+const _ = require('lodash');
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'order-form',
+  props: ['form'],
+  model: {
+    prop: 'form',
+    event: 'change',
+  },
+  components: {},
+  data: function() {
+    return {
+      fields: [{ label: '订单号', model: 'order_no' }],
+      clientList: [],
+      costType: [],
+    };
+  },
+  created() {},
+  methods: {
+    // 添加货物
+    addGoods() {
+      let goodsList = _.cloneDeep(this.form.goods);
+      if (goodsList) this.form.goods.push({});
+      else {
+        this.$set(this.form, `goods`, [{}]);
+      }
+    },
+    // 删除货物
+    toDeletGoods(data) {
+      let duplicate = _.cloneDeep(this.form);
+      const i = duplicate.goods.findIndex(f => _.isEqual(f, data));
+      if (i <= -1) return;
+      duplicate.goods.splice(i, 1);
+      this.$set(this, 'form', duplicate);
+    },
+    toReturn() {
+      this.$emit('toReturn');
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.el-row {
+  .el-col {
+    padding-top: 15px;
+  }
+}
+</style>

+ 139 - 0
src/views/order/index.vue

@@ -0,0 +1,139 @@
+<template>
+  <div id="index">
+    <!-- 列表 -->
+    <template v-if="view == 'list'">
+      <el-row type="flex" v-if="view == 'list'">
+        <el-col :span="20">
+          <el-input v-model="sform.order_no" placeholder="请填写要查询的订单号" style="width:170px;padding-right: 5px;"></el-input>
+          <el-select v-model="sform.client" placeholder="请选择要查询客户的订单" style="width:200px;padding-right: 5px;"></el-select>
+          <el-select v-model="sform.contact" placeholder="请选择要查询的合同" style="width:200px;padding-right: 5px;"></el-select>
+          <el-select v-model="sform.project" placeholder="请选择要查询的项目" style="width:200px;padding-right: 5px;"></el-select>
+          <el-select v-model="sform.way" placeholder="请选择要查询的运输方式" style="width:200px;padding-right: 5px;"></el-select>
+          <el-date-picker
+            v-model="sform.date"
+            type="daterange"
+            format="yyyy-MM-dd"
+            value-format="yyyy-MM-dd"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+            style="width:270px;padding-right: 5px;"
+          ></el-date-picker>
+        </el-col>
+        <el-col :span="2">
+          <el-button type="primary" @click="search">查询</el-button>
+        </el-col>
+        <el-col :span="2" style="text-align:right;padding-bottom:10px">
+          <el-button type="primary" @click="toAdd">新建订单</el-button>
+        </el-col>
+      </el-row>
+      <data-table height="600px" :fields="fields" :data="list" :opera="opera" :total="total" @query="search" @delete="toDelete" @edit="toEdit"> </data-table>
+    </template>
+    <!-- 编辑 -->
+    <template v-else>
+      <order-form v-model="form" key="detail" @toReturn="view = 'list'"></order-form>
+      <el-row key="detailRow" type="flex" justify="space-around">
+        <el-col :span="4">
+          <el-button type="primary" @click="toSave">保存订单</el-button>
+        </el-col>
+      </el-row>
+    </template>
+  </div>
+</template>
+
+<script>
+import dataTable from '@f/components/filter-page-table.vue';
+import orderForm from './index-parts/form.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+const { mapActions: menu } = createNamespacedHelpers('menu');
+export default {
+  name: 'index',
+  props: {},
+  components: { dataTable, orderForm },
+  data: function() {
+    return {
+      opera: [
+        {
+          label: '编辑',
+          method: 'edit',
+        },
+        {
+          label: '删除',
+          confirm: true,
+          type: 'danger',
+          method: 'delete',
+        },
+      ],
+      fields: [
+        { label: '订单号', model: 'order_no' },
+        { label: '客户', model: 'client' },
+        { label: '要求发货日期', model: 'rq_send_time' },
+        { label: '状态', model: 'status' },
+      ],
+      form: {},
+      list: [],
+      total: 0,
+      sform: {},
+      view: 'list',
+    };
+  },
+  created() {
+    this.search();
+  },
+  methods: {
+    async search({ skip = 0, limit = 10 } = {}) {
+      this.disabled = true;
+      const l = skip;
+      let arr = [];
+      for (let i = 1; i <= limit; i++) {
+        const obj = { order_no: `no${l + i}`, goods: [{ name: `g${l + i}`, number: l + i }] };
+        arr.push(obj);
+      }
+      this.$set(this, `list`, arr);
+      if (this.list.length < 40) this.disabled = false;
+    },
+    // 保存
+    async toSave() {
+      let duplicate = _.cloneDeep(this.form);
+      const { id } = this.form;
+      let res;
+      if (id) {
+        res = await this.update(duplicate);
+      } else {
+        res = await this.create(duplicate);
+      }
+      if (this.$checkRes(res, '保存成功', '保存失败')) {
+        this.search();
+      }
+    },
+    // 编辑
+    async toEdit({ data }) {
+      console.log('in function:toEdit');
+      this.view = 'detail';
+    },
+    // 删除
+    async toDelete({ data }) {
+      console.log('in function:delete');
+    },
+    toAdd() {
+      this.view = 'detail';
+    },
+  },
+  computed: {
+    ...mapState(['user', 'project']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.row {
+  .el-col {
+    padding-top: 10px;
+  }
+}
+</style>