# ModelBasic 数据实体类的基类

# 属性

属性名称 属性类型 说明
$idField String 标识列,默认为'id'
$dataList Array 数据集
$apiGetAll String 加载所有数据的接口地址
$apiGetPage String 分页加载list接口地址
$apiGet String get单条数据 接口地址
$apiSet String 保存(添加、修改)数据 接口地址
$apiAdd String 添加数据 接口地址(0.0.82新增)
$apiEdit String 修改数据 接口地址(0.0.82新增)
$apiDel String 删除数据 接口地址
$defaults String 初始属性 该项必须在子类中重新定义
$limit Number 使用分页模式加载数据时的,每页数据量
id Number 标识,默认值为0
$total Number 总数据数,默认为0
$totalPage Number 总页数,默认值为0
$end Boolean 是否已到最后一页
$nowPage Number 当前页,默认为1
$searchForm Object 查询表单绑定的数据对象
$searchPara Object 实际发送到后台的数据
$setMode String 添加/修改数据时的Ajax提交方式,默认为postJson
$delMode String 删除数据时的Ajax提交方式,默认为postJson
$validate Object 数据校验对象

# 方法

方法签名 说明 参数说明 备注
$new() 将所有属性重置为默认值 - -
$check() 调用类中定义的$validate对象的CheckPro方法 - -
$getAllData(opt):Promise 读取所有数据集 - get
$getPageData(pageNum,opt):Promise 采用分页模式读取数据集 pageNum:Number,页码,必传 get,传递给后台的参数为:limit、offset
$getPage/$getPageDataPro:Promise 采用分页模式读取数据集,高度集成模式(使用内置的$nowPage、$queryPara、$searchPara来进行查询),0.64新增 -- --
$search 应用查询参数(拷贝$searchForm到$searchPara) -- --
$setLimit 重新设置limit --- --
$getData(id,key):Promise 通过id获取数据 key:发送到后台的id的键名 默认为get,可通过$getMode设置数据提交方式
$setData():Promise 保存数据 - postJson
$delData(id,key):Promise 删除数据 key:发送到后台的id的键名 默认为get,可通过$delMode设置数据提交方式
$findById():Object 通过ID在数据集中精确查找数据 - -
$find(fn):Array 返回符合条件的数据集 - -
$rollingData(limit,paras) 返回一个rollingData的实例 - 主要用于移动端滚动加载

# 事件

方法签名 说明 参数 参数说明
$afterGetList (分页list)加载完成后触发,用于对后端输出的数据作额外处理 data 数据集
$afterGet $getData完成后触发,用于对后端输出的数据作额外处理
$beforeSearch 当用户点击搜索(应用搜索条件)时触发,事件内可对$searchPara中的数据进行转换 searchPara, searchForm -

# 实例

  class UserInfo extends ModelBasic {

    constructor() {
      super();
      this.$defaults = {
        guestId: 0, // 客户ID
        id: 0, //
        lastLoginIp: '', // 上次登录IP
        lastLoginTime: '', // 上次登录时间
        loginTimes: 0, // 登录次数
        mobile: '', // 手机号码
        passWord: '', // 密码
        trueName: '', // 真实姓名
        userName: '', // 用户名
      };
      this.$init();

      //this.$apiGetAll = '';
      //this.$apiGetPage = '';
      this.$apiGet = '/User/UserInfo';
      this.$apiSet = '/User/UpdateInfo';
      //this.$apiDel = '';
    }
}

      const userInfo = new UserInfo();
      // 获取用户信息 以下两种写法均可
      userInfo.$getData(1);

      userInfo.id = 1;
      userInfo.$getData();
      // 修改用户信息
      userInfo.trueName = '新的姓名';
      userInfo.$setData();

      // 删除用户
      userInfo.$delData();

# 完整实例

# 数据模型

import {Ajax, ModelBasic} from 'sjfx';
import Config from './config';

class Activity extends ModelBasic {

  constructor() {
    super();
    this.$defaults = {
      name: '',              // 活动名称
      desc: '',          //活动说明
      type: '',              //活动类型 1秒杀 2砍价 3团购
      status: 0,             //0未上架 1已上架
      startTime: new Date(),
      endTime: new Date(),
    };

    this.$apiGetPage = Config.apiUrl('/Activity/List');
    this.$apiGet = Config.apiUrl('/Activity/Detail');
    this.$apiSet = Config.apiUrl('/Activity/Save');
    this.$apiDel = Config.apiUrl('/Activity/Delete');

    this.$queryPara = {
      name: '',
      type: -1,
      status: -1,
      date: ''
    };

    this.$init();
  }

}


export {
  Activity
}

# Vue页面

<template>
  <div>
    <search-form v-on:on-search="search">
      <div class="main-query-list">
        <el-form-item label="活动名称:">
          <el-input v-model="activity.$queryPara.name"></el-input>
        </el-form-item>
      </div>
      <div class="main-query-list">
        <el-form-item label="活动类型:">
          <el-select v-model="activity.$queryPara.type">
            <el-option
              label="全部"
              :value="-1"
            ></el-option>
            <el-option
              v-for="item of typeList"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            ></el-option>
          </el-select>
        </el-form-item>
      </div>
      <div class="main-query-list">
        <el-form-item label="状态:">
          <el-select v-model="activity.$queryPara.status">
            <el-option
              label="全部"
              :value="-1"
            ></el-option>
            <el-option
              v-for="item of statusList"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            ></el-option>
          </el-select>
        </el-form-item>
      </div>
      <div class="main-query-list">
        <el-form-item label="活动日期:">
          <el-date-picker
            v-model="activity.$queryPara.date"
            type="date"
            placeholder="选择日期">
          </el-date-picker>
        </el-form-item>
      </div>
    </search-form>
    <div class="main-content">
      <div class="main-table-btn">
        <el-button type="primary" size="small" @click="add">添加活动</el-button>
      </div>
      <div class="main-table">
        <el-table :data="activity.$dataList" border>
          <el-table-column prop="name" label="活动名称" min-width="180"></el-table-column>
          <el-table-column prop="desc" label="活动说明" min-width="200"></el-table-column>
          <el-table-column label="活动类型" align="center" width="100">
            <template slot-scope="scope">
              {{typeList[scope.row.type-1].label}}
            </template>
          </el-table-column>
          <el-table-column prop="status" label="状态" align="center" width="100">
            <template slot-scope="scope">
              {{statusList[scope.row.status].label}}
            </template>
          </el-table-column>
          <el-table-column label="活动时间" align="center" width="320">

            <template slot-scope="scope">
              {{scope.row.startTime}}至{{scope.row.endTime}}
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center" width="230">
            <template slot-scope="scope">
              <el-button type="text" @click="edit(scope.row)">编辑</el-button>
              <el-button type="text" @click="del(scope.row)" v-if="scope.row.status===0">删除</el-button>
              <el-button type="text" @click="open(scope.row)" v-if="scope.row.status===0">上架</el-button>
              <el-button type="text" @click="close(scope.row)" v-if="scope.row.status===1">下架</el-button>
              <el-button type="text" @click="showCode(scope.row)">下载二维码</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>

      <div class="main-page text-right mt10">
        <el-pagination
          :page-sizes="[10,20, 50, 100]"
          layout="sizes, prev, pager, next"
          :total="activity.$total"
          :page-size="activity.$limit"
          :current-page="activity.$nowPage"
          v-on:current-change="handlerPageChange"
          v-on:size-change="handleSizeChange"
        >
        </el-pagination>
      </div>
    </div>

    <activity-form ref="myForm"></activity-form>
  </div>
</template>

<script>
  import SearchForm from "@/components/searchForm";
  import Config from './config';
  import {Activity} from './model';
  import ActivityForm from "@/app/activity/form";
  import {layer} from "sjfx";

  export default {
    components: {ActivityForm, SearchForm},
    data() {
      return {
        statusList: Config.statusList,
        takeTypeList: Config.takeTypeList,
        typeList: Config.typeList,
        activity: new Activity(),
      }
    },
    created() {

      this.loadList();
      this.$setTitle('活动管理');

    },
    methods: {

      //加载分页数据
      loadList() {
        this.activity.$getPageDataPro().then(data => {
          data.convertTime(false, 'yyyy.M.d h:mm');
        });
      },
      //执行搜索
      search() {
        this.activity.$search();
        this.loadList();
      },
      //换页
      handlerPageChange(newPage) {
        this.activity.$nowPage = newPage;
        this.loadList();
      },
      //更改每页数据条数
      handleSizeChange(limit) {
        this.activity.$setLimit(limit);
        this.loadList();
      },

      /**
       * 添加
       */
      add() {
        this.$refs.myForm.show();
      },
      /**
       * 修改
       */
      edit(item) {
        this.$refs.myForm.show(item.id);
      },
      /**
       * 删除
       */
      del(item) {
        layer.confirm('确实要删除该活动吗?', '操作确认').then(() => {
          this.activity.delete(item.id).then(() => {
            layer.toast('删除成功', 'success');
            this.loadList();
          });
        }).catch(()=>{})
      },
      /**
       * 下架
       */
      close() {

      },
      /**
       * 上架
       */
      open() {

      },
      /**
       * 显示二维码
       */
      showCode() {

      },
    }
  }
</script>

# MainPage集成

在data中实例化类
搜索表单的form数据绑定到该实例的$searchForm对象
表格数据绑定到该实例的$dataList属性
加载分页数据则是调用该实例的$getData()方法

# DEMO

<template>
  <div>
    <main-page :target="templates">
      <template slot="button"><el-button type="primary" @click="add">添加模板</el-button></template>
      <template slot="form">
        <div class="main-query-list">
          <el-form-item label="模板类型">
            <el-select v-model="templates.$searchForm.type" clearable placeholder="请选择">
              <el-option
                v-for="item in templateTypeList"
                :key="item.value"
                :label="item.label"
                :value="item.value">
              </el-option>
            </el-select>
          </el-form-item>
        </div>
        <div class="main-query-list">
          <el-form-item label="模板名称"><el-input v-model="templates.$searchForm.title"></el-input></el-form-item>
        </div>
      </template>
      <div class="main-table">
        <el-table border :data="templates.$dataList">
          <el-table-column prop="typeName" label="模板类型" width="180"></el-table-column>
          <el-table-column prop="title" label="模板名称" min-width="180"></el-table-column>
          <el-table-column prop="code" label="模板代码" align="center" width="150"></el-table-column>
          <el-table-column prop="content" label="内容" min-width="200"></el-table-column>
          <el-table-column label="操作" align="center" width="120">
            <template slot-scope="scope">
              <el-button type="text" @click="edit(scope.row)">编辑</el-button>
              <el-button type="text" @click="del(scope.row)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <!--添加模板-->
      <template-form ref="myForm" @update="getList"></template-form>
    </main-page>
  </div>
</template>

<script>
    import {MainPage} from "sjfx/pc";
    import TemplateForm from './form'
    import Config from '../config'
    import {Templates} from './model'
    export default {
      components: {MainPage,TemplateForm},
      data(){
          return{
            templates: new Templates(),
            templateTypeList:Config.templateTypeList,
          }
      },
      created(){
        this.getList();
      },
      methods:{

        /**
         * 加载分页数据
         */
        getList(){
          this.templates.$getPage();
        },

        /**
         * 添加模板
         */
        add(){
          this.$refs['myForm'].init();
        },

        /**
         * 编辑模板
         */
        edit(data){
          this.$refs['myForm'].init(data);
        },

        /**
         * 删除模板
         */
        /**
         * 删除
         */
        del(item) {
          this.$confirm('确实要删除该模板吗?', '操作确认').then(() => {
            this.templates.$delData(item.id).then(() => {
              this.$message({
                type:"success",
                message:"删除成功"
              })
              this.getList();
            });
          }).catch(() => {
          })
        },
      }
    }
</script>

# 数据校验

# Model部分代码

class Activity extends ModelBasic {
  constructor() {
  	/*此处省略代码若干*/
  	this.$rule = {
		  type: {
			label: '模板类型',
			rule: 'notEmpty',
			msg: '请选择模板类型'
		  },
		  title: {
			label: '模板名称',
			rule: 'notEmpty'
		  },
		  code: {
			label: '模板代码',
			rule: 'notEmpty'
		  },
		  content: {
			label: '模板内容',
			rule: 'notEmpty'
		  },
    }

	//$rule必须在$init之前定义
    this.$init();
  }

}

# 逻辑部分代码

save() {
	this.templates.$check().then(() => {
		this.templates.$setData().then(() => {
			layer.toast('保存成功!', 'success');
			this.visible = false;
			this.$emit('update');
		});
	});
}
Last Updated: 1/14/2020, 3:34:31 PM