后台管理系统的美化以及模板的编写
先上图吧模板的演化,先从h5 - jquery版本(基于h5+layui改造)vue单页面版本(基于ant design vue)上面放了功能的截图.色调关于ui的架构以及配色,个人觉得比较讨厌透明度来标示颜色,一般都用色值或者字体大小来进行区分。主用的色调,一般都是按系统的风格选相近的搭配色来进行处理(当然我不是专业的ui,大多数时候凭感觉)布局个人做起来大多数比较按着开合比较大的大气布局系统模
·
先上图吧
模板的演化,先从h5 - jquery版本(基于h5+layui改造)
vue 单页面版本(基于ant design vue)
上面放了功能的截图.
色调
关于ui的架构以及配色,个人觉得比较讨厌透明度来标示颜色,一般都用色值或者字体大小来进行区分。
主用的色调,一般都是按系统的风格选相近的搭配色来进行处理(当然我不是专业的ui,大多数时候凭感觉)
布局
个人做起来大多数比较按着开合比较大的大气布局
系统模板的编写,可以大大提升工作的效率。
比如编写一个增删改查的模板(elementui)
<!-- wbstc 写于 2019年3月08日 20:06:17 -->
<template>
<div class="dialog_height" :class="{'dialog_none':!pageJson.colModel}">
<div class="loc-manage-content">
<div id="hyzw_search" v-if="page_query_formModel && page_query_formModel.length>0" ref="hyzw_query"
class="loc-search-form">
<div class="loc-query-form" v-for="(item,index) in page_query_formModel">
<p class="loc-query-name" v-if="item.required">{{item.label}}<span class="field_required">*</span></p>
<p class="loc-query-name" v-if="!item.required">{{item.label}}</p>
<input class="loc-input " v-if="item.type=='text' || !item.type"
:class=" {' required':item.check,'loc-input':!item.check}" ref="hyzw_template" v-model="item['value']"
:placeholder=" '请输入' +item.label" @blur="componentQueryBlur('query_colModel',index)">
<el-select v-if="item.type=='select'" v-model="item.value"
popper-class="loc-main-selectbox loc-white-selectbox" ref="hyzw_template"
class="loc-main-select loc-white-select" placeholder="-请选择-" @change="queryChange(item)">
<el-option v-if="!item.no_display_select" label="-请选择-" value="">
</el-option>
<el-option v-for="option in item.options" :label="option.label" :value="option.value">
</el-option>
</el-select>
<el-select v-if="item.type=='select2'" filterable multiple v-model="item.value"
popper-class="loc-main-selectbox loc-white-selectbox" ref="hyzw_template"
class="loc-main-select loc-white-select" placeholder="-请选择-" @change="queryChange(item)">
<el-option v-if="!item.no_display_select" label="-请选择-" value="">
</el-option>
<el-option v-for="option in item.options" :label="option.label" :value="option.value">
</el-option>
</el-select>
<el-cascader v-if="item.type=='cascader' && item.options && item.options.length>0 " style="width: 300px;"
:options="item.options" v-model="item['value']" :show-all-levels="true" :clearable="true" :change-on-select="true" ref="hyzw_template">
</el-cascader>
<el-date-picker ref="hyzw_template" v-if="item.type=='startDate' " class="patrol-content loc-date-picker"
v-model="item.value" type="date" placeholder="开始日期" :picker-options="startDateTimePicker">
</el-date-picker>
<el-date-picker ref="hyzw_template" v-if="item.type=='endDate' " class="patrol-content loc-date-picker"
v-model="item.value" type="date" placeholder="结束日期" :picker-options="endDateTimePicker">
</el-date-picker>
<el-date-picker ref="hyzw_template" v-if="item.type=='startDateTime' " class="patrol-content loc-date-picker"
v-model="item.value" type="datetime" placeholder="开始時間" :picker-options="startDateTimePicker">
</el-date-picker>
<el-date-picker ref="hyzw_template" v-if="item.type=='endDateTime' " class="patrol-content loc-date-picker"
v-model="item.value" type="datetime" placeholder="结束時間" :picker-options="endDateTimePicker">
</el-date-picker>
<el-date-picker ref="hyzw_template" v-if="item.type=='datetime' " class="patrol-content loc-date-picker"
v-model="item.value" type="datetime" placeholder="选择時間" :picker-options="pickerOptions">
</el-date-picker>
</div>
<div class="loc-query-btn">
<el-button class="loc-btn submit-btn" @click="query()" type="primary"><i class="fa fa-search"></i>搜索
</el-button>
<!-- <el-button class="loc-btn reset-btn" @click="reset()" type="primary"><i class="fa fa fa-refresh"></i>重置
</el-button> -->
</div>
</div>
<div id="hyzw_btns" class="loc-opera-group">
<el-button v-if="pageJson.btns" @click="calc_fun(item)" v-for="(item,index) in pageJson.btns" :type="item.type"
class="loc-btn " :class="{' icon-btn':item.type!='danger'}">
<span><i class="fa " :class=" item.icon"></i>{{item.name}}</span>
</el-button>
</div>
<div id="hyzw_table" tag="table" v-if="page_colModel.length>0">
<el-table :data="grid_data" v-loading="grid_loading" @selection-change="changeSelects" @row-click="click_row"
@sort-change="sort_change" ref="hyzw_elTable" size="mini" class="transparent-table transparent-white-table"
style="width: 100%">
<el-table-column class-name="my-checkbox" type="selection" width="62" v-if="multipleCheck"
:selectable='selectable'></el-table-column>
<el-table-column v-for="(item,index) in page_colModel" v-if="page_colModel.length>0 && !item.modify"
:prop="item.name" :label="item.label" :sortable="item.sortable.type" :min-width="item.width + '%'">
<template slot="header" slot-scope="scope">
<span>{{item.label}}</span>
<el-popover v-if="item.header" placement="bottom-end" class="my-popover" popper-class="my-popover-content"
ref="hyzw_popover">
<div>
<div v-for="(header_item,index) in item.header.children" class="my-popover-item com-hover">
<div v-if="header_item.type=='select'">
{{header_item.label}}
<el-select v-model="header_item.value" popper-class="loc-main-selectbox loc-white-selectbox"
class="loc-main-select loc-white-select" placeholder="-请选择-">
<el-option label="-请选择-" value="">
</el-option>
<el-option v-for="option in header_item.options" :label="option.label" :value="option.value">
</el-option>
</el-select>
</div>
<div v-if="header_item.type=='checkbox'">
{{header_item.label}}
<el-checkbox class="my-content-checkbox" v-for="option in header_item.options" name="option.name"
v-model="option.value">
</el-checkbox>
</div>
<div class="popover-edit-content" v-if="header_item.type=='radio'">
{{header_item.label}}
<el-radio class="my-radio" v-model="item.header.radio" :label="header_item.value"></el-radio>
</div>
</div>
<div style="margin:0 5px 0 5px;">
<el-button @click="filter_load(index)" type="text">筛选</el-button>
</div>
</div>
<i slot="reference" class="com-hover el-icon-arrow-down" :class="{'active': item.header.isValue}"
@click="filter_load()" @click.stop></i>
</el-popover>
</template>
<template slot-scope="scope">
<div style="padding-right: 24px;">
<el-progress v-if="item.type=='progress'" class="home-progress" :text-inside="true" :stroke-width="18"
:percentage="item.inFlowPerc" :status="item.inFlowPerc < 70 ? 'success':'exception'"></el-progress>
</div>
<span v-if="item.type=='icon'">
<i class="fa " :class=" scope.row[item.name]"></i>
</span>
<span v-if="item.type=='html'" v-html="scope.row[item.name]">
</span>
<span v-if="item.type=='time'">
{{scope.row[item.name] | dateTime(scope.row,item.name)}}
</span>
<span v-if="item.type!='icon' && item.type!='html' && item.type!='progress' && item.type!='time' ">
{{scope.row[item.name] | dateRender(scope.row,item.name) }}
</span>
</template>
</el-table-column>
<el-table-column v-if="page_colModel.length>0 && page_colModel[page_colModel.length-1].modify"
:label="page_colModel[page_colModel.length-1].label" :width="page_colModel[page_colModel.length-1].width">
<template slot-scope="scope">
<el-button v-if="page_colModel[page_colModel.length-1].funs
&& page_colModel[page_colModel.length-1].funs.length==1
&& (scope.row[ page_colModel[page_colModel.length-1].funs[0].name ] == null ||
scope.row[page_colModel[page_colModel.length-1].funs[0].name])
" @click.native.prevent="rowFun(page_colModel[page_colModel.length-1].funs[0],scope)" type="text" size="small">
{{page_colModel[page_colModel.length-1].funs[0].label}}
</el-button>
<el-popover placement="bottom" trigger="click" class="my-popover" v-if="page_colModel[page_colModel.length-1].funs
&& page_colModel[page_colModel.length-1].funs.length>1" popper-class="my-popover-content my-popover-left">
<div>
<div class="my-popover-item com-hover"
v-for="item_fun in page_colModel[page_colModel.length-1].funs " @click="rowFun(item_fun,scope)"
v-if="menuShow(scope.row,item_fun)">
<el-popover v-if="item_fun.children && item_fun.children.length>0" placement="left" trigger="hover"
class="my-popover" popper-class="my-popover-content">
<div slot="reference">
{{item_fun.label}}
<span style="float: right;line-height: 16px;" class="el-icon-arrow-right"></span>
</div>
<div>
<div class="my-popover-item com-hover" v-for=" item_children in item_fun.children"
v-if="menuChildShow(scope.row,item_fun,item_children)" @click="rowFun(item_children,scope)">
{{item_children.label}}</div>
</div>
</el-popover>
<span v-if="!item_fun.children">{{item_fun.label}}</span>
</div>
</div>
<i slot="reference" class="fa fa-cog com-hover"></i>
</el-popover>
</template>
</el-table-column>
</el-table>
</div>
<div id="hyzw_page" v-if="page_colModel.length>0" class="loc-pagination">
<div class="my-pagination-group">
<el-pagination @size-change="handleSizeChange" @current-change="handlePageChange" :current-page="page_current"
:page-sizes="[10, 20, 50, 100]" :page-size="page_size" layout="total, sizes, prev, pager, next"
:total="total">
</el-pagination>
<button class="my-pagination-btn my-pagination-first com-hover" :disabled='page_current == 1'
:style="{ 'cursor': page_current == 1 ? 'not-allowed' : 'pointer' }"
@click="handlePageChange(1)">首页</button>
<button class="my-pagination-btn my-pagination-last com-hover" :disabled='page_current == page_count'
:style="{ 'cursor': page_current == page_count ? 'not-allowed' : 'pointer' }"
@click="handlePageChange(page_count)">尾页</button>
</div>
</div>
</div>
<div tag="dialog">
<el-dialog :title="title" :visible.sync="dialogVisible" :width="dialogWidth" :show-close="true"
:close-on-click-modal="false" class="blue-dialog my-edit-dialog">
<div class="system-min-dialog">
<div class="template_row" v-for="(master,index) in am_formModel">
<div class="my-edit-group" v-for="(item,child_index) in master"
:class="{'my-edit-group my-fill-line system-checkbox-form':item.type=='fold_tree'}"
v-show="item.type!='hidden' && !item.hidden">
<span class="my-group-title" v-if="!item.required">{{item.label}}</span>
<span class="my-group-title" v-if="item.required">{{item.label}}<span
class="field_required">*</span></span>
<div class="my-group-content " v-if="pageJson.cols" :class=" 'cols-' + pageJson.cols + '-' + item.cols ">
<div class="dialog_icon" v-if="item.type=='icon'">
<i class="fa " :class=" item['value']"></i>
</div>
<el-date-picker v-if="item.type=='date' " class="patrol-content loc-date-picker"
v-model="item['value']" type="date" placeholder="选择日期" :readonly="item.readonly"
:picker-options="pickerOptions">
</el-date-picker>
<el-date-picker v-if="item.type=='datetime' " class="patrol-content loc-date-picker"
v-model="item['value']" type="datetime" placeholder="选择时间" :readonly="item.readonly"
:picker-options="pickerOptions">
</el-date-picker>
<input v-if="item.type=='text' " class="loc-input " :class="{'required':item.check}"
ref="hyzw_template_dialog" v-model="item['value']" :placeholder="item.placeholder"
@blur="componentBlur(index,child_index)" :readonly="item.readonly" autocomplete="off" />
<input v-if="item.type=='password' " type="password" class="loc-input " :class="{'required':item.check}"
ref="hyzw_template_dialog" v-model="item['value']" :placeholder=" '请输入' +item.label"
@blur="componentBlur(index,child_index)" :readonly="item.readonly" autocomplete="off" />
<span v-if="item.type=='html'" class="dialogIcon" v-html="item.value">
</span>
<input v-if="item.type=='mobile'" type="number" class="loc-input " :class="{'required':item.check}"
ref="hyzw_template_dialog" v-model="item['value']" :placeholder=" '请输入' +item.label"
@blur="componentBlur(index,child_index)" :readonly="item.readonly" />
<input v-if="item.type=='number'" type="number" class="loc-input " :class="{'required':item.check}"
ref="hyzw_template_dialog" v-model="item['value']" :placeholder=" '请输入' +item.label"
@blur="componentBlur(index,child_index)" :readonly="item.readonly" />
<el-checkbox style="margin:5px 0 0 0" @change="dialogChange(item)" v-model="item.value"
v-if="item.type=='checkbox'" ref="hyzw_template_dialog" class="my-content-checkbox"></el-checkbox>
<input v-if="item.type=='email'" class="loc-input " :class="{'required':item.check}"
ref="hyzw_template_dialog" v-model="item['value']" :placeholder=" '请输入' +item.label"
@blur="componentBlur(index,child_index)" :readonly="item.readonly" />
<input v-if="item.type=='ip'" class="loc-input " :class="{'required':item.check}"
ref="hyzw_template_dialog" v-model="item['value']" :placeholder=" '请输入' +item.label"
@blur="componentBlur(index,child_index)" :readonly="item.readonly" />
<el-upload class="upload-demo" v-if="item.type=='upload'" ref="hyzw_template_dialog"
:action="item.action" :auto-upload="true" :on-exceed="handleExceed">
<el-button size="small" class="dialog-btn submit-btn" type="primary">点击上传</el-button>
</el-upload>
<textarea v-if="item.type=='textarea'" class="el-textarea__inner "
:class=" {' required':item.check,'textarea':!item.check}" ref="hyzw_template_dialog" required
v-model="item['value']" :placeholder=" '请输入' +item.label" @blur="componentBlur(index,child_index)"
:readonly="item.readonly"></textarea>
<el-select v-if="item.type=='select'" v-bind:filterable="item.filterable" v-model="item['value']"
@change="dialogChange(item)" popper-class="loc-main-selectbox loc-white-selectbox"
ref="hyzw_template_dialog" class="loc-main-select loc-white-select" placeholder="-请选择-">
<el-option v-if="!item.no_display_select" label="-请选择-" value="">
</el-option>
<el-option v-for="option in item.options" :label="option.label" :value="option.value">
</el-option>
</el-select>
<el-select v-if="item.type=='select2'" multiple filterable v-model="item.value"
popper-class="loc-main-selectbox loc-white-selectbox" ref="hyzw_template"
class="loc-main-select loc-white-select" placeholder="-请选择-">
<el-option v-if="!item.no_display_select" label="-请选择-" value="">
</el-option>
<el-option v-for="option in item.options" :label="option.label" :value="option.value">
</el-option>
</el-select>
<el-cascader v-if="item.type=='cascader'" :options="item.options" v-model="item['value']"
:show-all-levels="true" :clearable="true" :change-on-select="true"
ref="hyzw_template_dialog">
</el-cascader>
<el-radio-group v-if="item.type=='radio'" v-model="item['value']" @change="dialogChange(item)"
ref="hyzw_template_dialog" class="loc-radio">
<el-radio v-for="option in item.options" :label="option.value">{{option.label}}</el-radio>
</el-radio-group>
<component :is="component"></component>
<div v-if="item.type=='fold_tree'" v-for="fold in item.options" class="system-checkbox-content">
<div class="system-checkbox-text">
<span class="system-checkbox-title">{{fold.title}}</span>
<div class="system-checkbox" v-for="flod_item in fold.children">
<el-checkbox v-model="flod_item.value" @change="dialogCheck(flod_item)"
class="my-content-checkbox">{{flod_item.label}}</el-checkbox>
</div>
</div>
</div>
</div>
</div>
</div>
<input type="hidden" v-for="(item,index) in hidden_formModel" v-model="item['value']" />
</div>
<span slot="footer" class="dialog-footer">
<el-button class="dialog-btn submit-btn" v-if="dialog_submit" type="primary" @click="submitDialog()"
:loading="loading">确认</el-button>
<el-button class="dialog-btn cancel-btn" v-if="dialog_cancel" @click="dialogVisible = false"
:disabled="loading">取消</el-button>
</span>
</el-dialog>
</div>
</div>
</template>
<script>
import configJson from './config.json';
export default {
name: 'hyzw_singleGridTabTemplate',
data() {
return {
pickerOptions: { //选择日期不会超过当前时间日期
disabledDate(time) {
return time.getTime() > Date.now();
},
},
startDateTimePicker: this.beginDate(), //选择日期时间不会超过当前日期
endDateTimePicker: this.endDate(), //选择结束日期在开始日期和当前时间之间
page_size: configJson.page_size, //每页显示条数
page_current_field: configJson.page_current_field, //当前页数,缺省字段
page_size_field: configJson.page_size_field, //当前页面条数,缺省字段
page_result_field: configJson.page_result_field, //结果集,缺省字段
page_rows_field: configJson.page_rows_field, //总条数,缺省字段
total_field: configJson.total_field, //总条数,缺省字段
delete_value_field: configJson.delete_value_field, //删除字段名
delete_params_id: configJson.delete_params_id, //传入参数字段名
page_count: 0, //总页数
page_current: 1, //当前页数
total: 0, //总条数
title: "",
mode: "",
dialogAction: {},
isDev: false,
multipleCheck: true,
dialogVisible: false,
handleClose: false,
loading: false,
dialogWidth: "",
query_colModel: "query_colModel",
am_colModel: "am_colModel",
am_formModel: [],
hidden_formModel: [],
page_query_formModel: [],
page_colModel: [],
grid_loading: false,
grid_data: [],
getSelectIds: [],
temp_formData: {}, //页面临时结果集不参与清洗数据
replace_formData: [], //替换数据
replace_query_formData: [], //替换数据
default_page_query_formModel: [],
modify_colModel: [],
dialog_submit: true,
dialog_cancel: true,
sorter: [],
query_select2_options: [],
dialog_select2_options: [],
component: null, //默认组件集合
}
},
props: {
pageJson: {
type: Object,
default: function () {
return {};
}
}
},
computed: {
loader() {
if (!this.pageJson.components) {
return null;
}
return () =>
import(`./${this.components}`);
}
},
created: function () {
window.vue = this;
if (this.pageJson && this.pageJson.cols) {
this.dataQueryCleaing(); //同步查询数据清洗
this.dataGridCleaing(); //同步表格数据清洗
}
},
mounted: function () {
window.vue = this;
if (this.pageJson && this.pageJson.cols) {
this.initSynchronization();
this.initAsynchronous();
}
// this.loader().then(()=>{
// this.component = () => this.loader();
// });
},
methods: {
beginDate() {
return {
disabledDate(time) {
return time.getTime() > new Date().getTime()//开始时间不选时,结束时间最大值小于等于当天
}
}
},
endDate() {
var $this = this
return {
disabledDate(time) {
var beginTime = null;
for (var i = 0; i < $this.page_query_formModel.length; i++) {
if ($this.page_query_formModel[i].name == 'startTime') {
beginTime = $this.page_query_formModel[i].value;
break;
}
}
if (beginTime) {
return new Date(beginTime).getTime() > time.getTime() || time.getTime() > new Date().getTime()
} else {
return time.getTime() > new Date().getTime()//开始时间不选时,结束时间最大值小于等于当天
}
}
}
},
initSynchronization: function () {
this.queryFocus(false);
this.load();
this.multipleCheck = this.pageJson.multipleCheck;
this.isDev = this.pageJson.isDev;
if (this.hyzw.isBlank(this.pageJson.multipleCheck)) {
this.multipleCheck = true;
}
if (this.hyzw.isBlank(this.pageJson.isDev)) {
this.isDev = true;
}
if (this.hyzw.notBlank(this.pageJson.page_result_field)) {
this.page_result_field = this.pageJson.page_result_field;
}
if (this.hyzw.notBlank(this.pageJson.delete_value_field)) {
this.delete_value_field = this.pageJson.delete_value_field;
}
if (this.hyzw.notBlank(this.pageJson.delete_params_id)) {
this.delete_params_id = this.pageJson.delete_params_id;
}
if (this.$parent.init) {
this.$parent.init(this);
}
var serachHeight = 0;
var btnsHeight = 0;
var pageHeight = 0;
if (this.hyzw.notBlank(document.getElementById("hyzw_search"))) {
serachHeight = document.getElementById("hyzw_search").clientHeight;
}
if (this.hyzw.notBlank(document.getElementById("hyzw_btns"))) {
btnsHeight = document.getElementById("hyzw_btns").clientHeight == 0 ? 0 + 16 : document.getElementById("hyzw_btns").clientHeight + 32;
}
if (this.hyzw.notBlank(document.getElementById("hyzw_page"))) {
pageHeight = document.getElementById("hyzw_page").clientHeight;
}
var tableHeight = this.hyzw.getContentHeight() - serachHeight - btnsHeight - pageHeight - 40 - 40 - 40;
if (document.getElementById("hyzw_table") && document.getElementById("hyzw_table").childNodes[0]) {
var eltable = document.getElementById("hyzw_table").childNodes[0].childNodes[2];
eltable.style.height = tableHeight + "px";
eltable.style.overflowY = "auto";
}
},
initAsynchronous: function () {
var $this = this;
setTimeout(function () {
$this.initAsynDatas($this.page_query_formModel);
$this.initAsynDatas($this.pageJson.am_colModel);
}, 100);
setTimeout(function () {
if ($this.pageJson.query_colModel) {
var json = JSON.stringify($this.pageJson.query_colModel);
let am_colModel = JSON.parse(json);
$this.default_page_query_formModel = am_colModel;
}
}, 1000);
},
loadAsynSelectValue: function (in_models, action, params, method, fn) {
var $this = this;
return new Promise((resolve, reject) => {
$this.http.req(action, params, function (res, rs) {
var rs_model = $this.getModelByUrl(in_models, rs.req_url);
if (rs_model.source.result_field) {
res = res[rs_model.source.result_field];
}
if (res) {
var datas = [];
if (rs_model.source.label) {
for (var i = 0; i < res.length; i++) {
var data = res[i];
datas.push({
label: data[rs_model.source.label],
value: data[rs_model.source.value],
children: data.children
});
}
} else {
for (let i in res) {
datas.push({
label: res[i],
value: i
});
}
}
rs_model.options = datas;
in_models = in_models.slice();
$this.page_query_formModel = $this.page_query_formModel.slice();
$this.am_formModel = $this.am_formModel.slice();
if (fn) {
fn(in_models);
}
resolve(in_models);
}
}, method);
});
},
initAsynDatas: function (in_models, fn) {
var $this = this;
if (in_models) {
var isCallBack = false;
for (var i = 0; i < in_models.length; i++) {
var model = in_models[i];
if (model.source && !model.cascade) {
var source = model.source;
isCallBack = true;
this.loadAsynSelectValue(in_models,
source.action, source.params, source.method, fn);
}
if (model.cascade) {
var source = model.source;
var params_id = model.cascade.params_id;
var params_value_id = model.cascade.parent_field;
var value = this.getSelectByField(params_value_id);
if (value) {
if (!model.source.yaction) {
model.source.yaction = source.action;
}
var action = model.source.yaction + "?" + params_id + "=" + value;
model.source.action = action;
this.loadAsynSelectValue(in_models,
action, source.params, source.method, fn);
}
}
}
if (!isCallBack && fn) {
fn();
}
}
},
getModelByUrl: function (in_modes, url) {
if (in_modes[0] instanceof Array) {
for (var i = 0; i < in_modes.length; i++) {
var jmodel = in_modes[i];
for (var j = 0; j < jmodel.length; j++) {
var model = jmodel[j];
if (model.source) {
var action = model.source.action;
if (action == url) {
return model;
}
}
}
}
} else {
for (var i = 0; i < in_modes.length; i++) {
var model = in_modes[i];
if (model.source) {
var action = model.source.action;
if (action == url) {
return model;
}
}
}
}
return null;
},
initParams: function () {
this.loading = false;
},
queryChange: function (item) {
if (this.$parent.queryChange) {
var rs = this.$parent.queryChange(this, item);
if (!rs) {
return;
}
}
if (item.parent) {
var parent_field = item.name;
//寻找子集合集,是否加载子集
var childModel = this.queryChangeByCascade(
parent_field, this.page_query_formModel);
if (item.value == "") {
childModel.options = [];
childModel.value = "";
return;
}
if (childModel) {
var params = {};
params[childModel.cascade.params_id] = item.value;
var $this = this;
this.loadAsynSelectValue(this.page_query_formModel,
childModel.source.action, params,
childModel.source.method,
function (res) {
childModel.value = "";
});
}
}
},
querySelect2Method: function (query) {
if (this.$parent.querySelect2Method) {
this.$parent.querySelect2Method(this, query);
}
},
dialogChange: function (item) {
if (this.$parent.dialogChange) {
var rs = this.$parent.dialogChange(this, item);
if (!rs) {
return;
}
}
if (item.parent) {
var parent_field = item.name;
//寻找子集合集,是否加载子集
var childModel = this.dialogChangeByCascade(
parent_field, this.am_formModel);
if (item.value == "") {
childModel.options = [];
childModel.value = "";
return;
}
if (childModel) {
var params = {};
params[childModel.cascade.params_id] = item.value;
var $this = this;
this.loadAsynSelectValue(this.am_formModel,
childModel.source.action, params,
childModel.source.method,
function (res) {
childModel.value = "";
});
}
}
},
dialogCheck: function (item) {
if (this.$parent.dialogCheck) {
this.$parent.dialogCheck(this, item);
}
},
dialogSelect2Method: function (query) {
if (this.$parent.dialogSelect2Method) {
this.$parent.dialogSelect2Method(this, query);
}
},
parentClick: function (name, index) {
var $this = this;
var row = this.grid_data[index];
this.setRowSelect(row, function () {
if ($this.$parent.parentClick) {
$this.$parent.parentClick($this, name, index);
}
});
},
queryChangeByCascade: function (in_parent_field, in_models) { //根据当前的节点,去查询他的子集节点集合.
for (var i = 0; i < in_models.length; i++) {
var model = in_models[i];
if (model.cascade) { //如果支持父级级联
var parent_field = model.cascade.parent_field;
if (in_parent_field == parent_field) {
return model;
}
}
}
return null;
},
getModel: function (in_models, field, field2) {
var source_param = field2;
if (!source_param) {
source_param = "name";
}
for (var i = 0; i < in_models.length; i++) {
var model = in_models[i];
var name = model[source_param];
if (field == name) {
return model;
}
}
return null;
},
getParentByCascade: function (in_parent_field, in_models) { //根据当前的节点,去查询他的父集节点集合.
for (var i = 0; i < in_models.length; i++) {
var model = in_models[i];
if (model.source) { //如果支持父级级联
var name = model.name;
if (in_parent_field == name) {
return model;
}
}
}
return null;
},
dialogChangeByCascade: function (in_parent_field, in_models) { //根据当前的节点,去查询他的子集节点集合.
for (var i = 0; i < in_models.length; i++) {
var model = in_models[i];
for (var j = 0; j < model.length; j++) {
var jmodel = model[j];
if (jmodel.cascade) { //如果支持父级级联
var parent_field = jmodel.cascade.parent_field;
if (in_parent_field == parent_field) {
return jmodel;
}
}
}
}
return null;
},
calc_fun: function (item) {
if (item.fun.indexOf("open_") >= 0) {
eval("this." + item.fun + "()");
} else {
eval("this.$parent." + item.fun + "(this)");
}
this.saveLog(item.name);
},
changeSelects: function (val) {
this.getSelectIds = val;
},
menuShow: function (row, item) {
if (row[item.name] == null || row[item.name]) {
return true;
}
return false;
},
menuChildShow: function (row, item, children) {
if (!row[item.name]) {
row[item.name] = {};
}
if (row[item.name][children.name] == null || row[item.name][children.name]) {
return true;
}
return false;
},
sort_change: function ({
column,
prop,
order
}) {
this.sorter = [];
if (prop) {
var style = order;
if (style == "ascending") {
style = "asc";
} else if (style == "descending") {
style = "desc";
}
this.sorter = [{
name: prop,
value: style
}];
}
this.load();
},
filter_load: function (index) {
if (this.$refs.hyzw_popover) {
for (var i = 0; i < this.$refs.hyzw_popover.length; i++) {
var popver = this.$refs.hyzw_popover[i];
popver.doClose();
}
}
if (!index) {
return;
}
if (this.page_colModel) {
var real_cnt = 0;
for (var i = 0; i < this.page_colModel.length; i++) {
var page = this.page_colModel[i];
if (page.header) {
real_cnt++;
}
if (index == real_cnt - 1) {
break;
}
}
this.$refs.hyzw_popover[real_cnt - 1].doClose();
if (this.$parent.filter_load) {
this.$parent.filter_load(this, index);
}
}
},
selectable: function (row, index) {
let selectable = true;
//需补充数据
if (this.modify_colModel) {
for (var i = 0; i < this.modify_colModel.length; i++) {
var colmodel = this.modify_colModel[i];
if (!colmodel.children) {
row[colmodel.name] = true;
}
if (colmodel.children) {
if (!row[colmodel.name]) {
row[colmodel.name] = {};
}
if (!row[colmodel.name].children) {
// row[colmodel.name].children = {};
for (var i = 0; i < colmodel.children.length; i++) {
var children = colmodel.children[i];
row[colmodel.name][children.name] = true;
}
}
}
}
}
if (this.$parent.render) {
selectable = this.$parent.render(row, index);
}
if (selectable == undefined) {
selectable = true;
}
row.selectable = selectable;
return selectable;
},
open_add: function (fn) {
this.initParams();
this.initDialogWidth();
this.mode = "open_add";
this.dataAmCleaing(this.pageJson.am_colModel, this.pageJson.cols);
this.title = "新增" + this.pageJson.title;
this.dialogVisible = true;
this.dialog_submit = true;
this.amFocus();
if (fn) {
fn();
}
},
open_modify: function (fn) {
if (!this.isSelect()) {
this.warning('请至少选择一条!');
return;
}
if (this.getSelectCount() > 1) {
this.warning('只能选择一条!');
return;
}
this.initParams();
this.initDialogWidth();
this.mode = "open_modify";
this.dataAmCleaing(this.pageJson.am_colModel, this.pageJson.cols);
this.title = "修改" + this.pageJson.title;
this.dialogVisible = true;
this.dialog_submit = true;
this.loading = true;
var getAction = this.pageJson.getAction;
//开始填充结果集
var params = this.getSelectData();
var $this = this;
this.initAsynDatas(this.pageJson.am_colModel, function (res) {
if (res) {
$this.dataAmCleaing(res, $this.pageJson.cols);
}
if (params) {
if ($this.hyzw.notBlank(getAction)) {
$this.http.req(getAction.action, params, function (res) {
$this.loading = false;
if (res == null) {
$this.dialogVisible = false;
alert("请检查该数据是否被删除!");
return;
}
$this.loadFieldValue(res);
$this.loading = false;
$this.amFocus();
}, getAction.method, function (res) {
if (res == null) {
alert("请检查该数据是否被删除!!");
$this.dialogVisible = false;
}
});
} else {
$this.loading = false;
$this.loadFieldValue(params);
}
}
if (fn) {
fn();
}
$this.amFocus();
});
},
open_delete: function () {
if (!this.isSelect()) {
this.warning('请至少选择一条!');
return;
}
var $this = this;
$this.mode = "open_modify";
var delAction = this.pageJson.delAction;
var idField = this.delete_params_id;
var idValue = this.delete_value_field;
var values = this.getSelectByField(idValue);
if (idField.indexOf("[]") > 0) {
values = this.getSelectByFields(idValue);
}
var params = {};
params[idField] = values;
this.log(params);
this.confirm("您确定删除吗?", function () {
$this.grid_loading = true;
$this.http.req(delAction.action, params, function (res) {
$this.dialogVisible = false;
$this.success("操作成功!");
$this.load();
}, delAction.method, function (res) {
alert(res);
$this.grid_loading = false;
});
});
},
createFormDialog: function (title, addAction, in_modes, cols, params, fn) { //params#action
this.initParams();
this.pageJson.cols = cols;
this.initDialogWidth();
this.title = title;
this.dialogVisible = true;
this.dialog_submit = true;
if (addAction != null) {
this.dialogAction = addAction;
}
this.am_formModel = [];
this.mode = "open_dialog";
var $this = this;
$this.dataAmCleaing(in_modes, cols);
this.initAsynDatas(in_modes, function (res) {
if (res) {
$this.dataAmCleaing(res, cols);
}
if (params) {
$this.loadFieldValue(params);
}
if (fn) {
fn();
}
$this.amFocus();
});
},
detail: function (title, in_modes, cols, params) {
this.initParams();
this.dataAmCleaing(in_modes, cols);
this.title = title;
this.dialogVisible = true;
this.dialog_submit = false;
this.mode = "open_dialog";
if (params) {
this.loadFieldValue(params);
}
},
loadFieldValue: function (res) {
this.temp_formData = res;
for (var i = 0; i < this.am_formModel.length; i++) {
var modes = this.am_formModel[i];
if (modes) {
for (var j = 0; j < modes.length; j++) {
var mode = modes[j];
if (!mode.value) {
mode.value = "";
}
if (mode.name.indexOf(".") == -1) {
if (res[mode.name]) {
mode.value = res[mode.name];
}
} else {
if (eval("res." + mode.name)) {
mode.value = eval("res." + mode.name);
}
}
}
}
}
for (var i = 0; i < this.hidden_formModel.length; i++) {
var modes = this.hidden_formModel[i];
if (modes) {
for (var j = 0; j < modes.length; j++) {
var mode = modes[j];
if (!mode.value) {
mode.value = "";
}
if (mode.name.indexOf(".") == -1) {
mode.value = res[mode.name];
} else {
mode.value = eval("res." + mode.name);
}
}
}
}
},
isSelect: function () {
if (this.getSelectIds.length > 0) {
return true;
}
return false;
},
getSelectCount: function () {
return this.getSelectIds.length;
},
getSelect: function () {
return this.getSelectIds;
},
getSelectData: function () {
return this.getSelectIds[this.getSelectIds.length - 1];
},
getSelectByField: function (field) {
var value = "";
if (this.getSelectIds.length > 0) {
for (var i = 0; i < this.getSelectIds.length; i++) {
var item = this.getSelectIds[i];
value += item[field] + ",";
}
}
if (this.hyzw.notBlank(value)) {
value = value.substring(0, value.length - 1);
}
return value;
},
getSelectByFields: function (field) {
var values = new Array();
if (this.getSelectIds.length > 0) {
for (var i = 0; i < this.getSelectIds.length; i++) {
var item = this.getSelectIds[i];
values.push(item[field]);
}
}
return values;
},
log: function (msg) {
if (this.isDev) {
}
},
click_row: function (row, event, column) {
if (this.pageJson.rowSelect && row.selectable) {
this.$refs.hyzw_elTable.toggleRowSelection(row);
}
if (event && event.srcElement) {
var html = event.srcElement.outerHTML;
if (html.indexOf("el-popover") >= 0) { //此时判定为el点击
this.setRowSelect(row);
}
}
},
setRowSelect: function (row, fn) {
var $this = this;
this.$refs.hyzw_elTable.clearSelection();
setTimeout(function () {
$this.$refs.hyzw_elTable.toggleRowSelection(row, true); //点击选中
if (fn) {
fn();
}
}, 20);
},
rowFun: function (item, scope) {
var $this = this;
$this.setRowSelect(scope.row, function () {
if (!item.fun) {
return;
}
if (item.fun.indexOf("open_") >= 0) {
eval("$this." + item.fun + "()");
} else {
eval("$this.$parent." + item.fun + "($this)");
}
});
},
error: function (msg) {
this.$message.error(msg);
},
success: function (msg) {
this.$message.success(msg);
},
warning: function (msg) {
this.$message.warning(msg);
},
confirmDialog: function (msg, action, params, multiple_selection) {
if (!this.isSelect()) {
var msg = "请至少选择一条!";
if (!multiple_selection) {
msg = "必须选择一条!";
}
this.warning(msg);
return;
}
if (!multiple_selection && this.getSelectCount() > 1) {
this.warning("只能选择一条!");
return;
}
var $this = this;
this.confirm(msg, function () {
$this.http.req(action.action, params, function (res) {
$this.success("操作成功!");
$this.load();
}, action.method, function (res) {
$this.warning(res);
});
});
},
confirm: function (msg, fn) {
this.$confirm(msg, '提示', {
cancelButtonText: '取消',
confirmButtonText: '确定',
type: 'warning'
}).then(() => {
if (fn) {
fn();
}
}).catch(() => { });
},
handleSizeChange: function (val) {
this.page_size = val;
this.load();
},
handlePageChange: function (val) {
this.page_current = val;
this.load();
},
load: function () {
if (!this.pageJson.action) {
return;
}
if (this.$parent.checkLoad) {
var isCheckLoad = this.$parent.checkLoad(this);
if (!isCheckLoad) {
return;
}
}
let isCheck = this.checkQuery(true);
if (!isCheck) {
return;
}
var action = this.pageJson.action;
this.grid_loading = true;
var $this = this;
var params = {}; //收集参数
if (this.page_query_formModel) {
for (let i = 0; i < this.page_query_formModel.length; i++) {
let model = this.page_query_formModel[i];
if (this.hyzw.notBlank(model.value)) {
params[model.name] = model.value;
}
};
}
if (this.sorter && this.sorter.length > 0) {
for (var k = 0; k < this.sorter.length; k++) {
var model = this.sorter[k];
if (this.hyzw.notBlank(model.value)) {
if (this.page_colModel) {
for (var j = 0; j < this.page_colModel.length; j++) {
var page = this.page_colModel[j];
if (page && page.name == model.name) {
params["sorter"] = page.sortable.name;
params["order"] = model.value;
break;
}
}
}
}
};
}
if (this.replace_query_formData) {
for (let i = 0; i < this.replace_query_formData.length; i++) {
let model = this.replace_query_formData[i];
params[model.name] = model.value;
}
}
params[this.page_current_field] = this.page_current;
params[this.page_size_field] = this.page_size;
this.log(params);
setTimeout(function () {
$this.http.req(action.action, params, function (res) {
$this.log(res);
$this.grid_loading = false;
$this.grid_data = res[$this.page_result_field];
$this.total = res[$this.page_rows_field];
$this.page_count = res[$this.total_field];
}, action.method, function (e) {
$this.grid_loading = false;
});
}, 100);
},
submitDialog: function () {
var Action = this.pageJson.addAction;
if (this.mode == "open_add") {
Action = this.pageJson.addAction;
} else if (this.mode == "open_modify") {
Action = this.pageJson.modifyAction;
} else if (this.mode == "open_dialog") {
Action = this.dialogAction;
}
this.log(Action);
const isCheck = this.checkSubmit(true);
let isActionCheck = true;
if (Action && Action.before && isCheck) {
isActionCheck = Action.before(this);
}
if (isCheck && isActionCheck) {
this.loading = true;
let req_json = this.getReqJson();
var $this = this;
this.http.req(Action.action, req_json, function (res) {
$this.loading = false;
$this.dialogVisible = false;
$this.success("操作成功!");
$this.load();
if (Action && Action.after) {
Action.after(this);
}
}, Action.method, function (e) {
alert(e);
$this.loading = false;
});
}
},
getReqJson: function () {
let req_json = this.temp_formData;
for (let i = 0; i < this.am_formModel.length; i++) {
let models = this.am_formModel[i];
for (let j = 0; j < models.length; j++) {
let model = models[j];
var label = model.label;
req_json[model.name] = model.value;
}
};
for (let i = 0; i < this.hidden_formModel.length; i++) {
let model = this.hidden_formModel[i];
req_json[model.name] = model.value;
};
if (this.replace_formData) {
for (let i = 0; i < this.replace_formData.length; i++) {
let model = this.replace_formData[i];
req_json[model.name] = model.value;
}
}
return req_json;
},
saveLog:function(actionname){
if (this.hyzw.get("click_menu")) {
var menu = JSON.parse(this.hyzw.get("click_menu"));
this.hyzw.saveLog(menu.parent_name, menu.name, actionname);
}
},
query: function () {
let isCheck = this.checkQuery(true);
if (isCheck) {
this.load();
this.saveLog("查询");
}
},
reset: function () {
this.page_query_formModel = this.default_page_query_formModel;
this.saveLog("重置");
},
componentQueryBlur: function (modelType, index) {
let model = this.pageJson[modelType][index];
if (this.hyzw.notBlank(model.value)) {
model.check = false;
} else { //打开校验,增加样式
if (this.hyzw.notBlank(model.blur) && model.required && model.blur) {
model.check = true;
}
}
},
componentBlur: function (index, child_index) {
const am_mode = this.am_formModel;
let model = am_mode[index][child_index];
if (this.hyzw.notBlank(model.value)) {
model.check = false;
} else { //打开校验,增加样式
if (this.hyzw.notBlank(model.blur) && model.required && model.blur) {
model.check = true;
}
}
this.am_formModel = am_mode.slice();
},
queryFocus: function (isCheck) { //设置默认选中,且是否变红
var isFoucs = true;
var models = this.page_query_formModel;
if (models) {
for (var i = 0; i < models.length; i++) {
var model = models[i];
model.check = false;
if (this.hyzw.isBlank(model.value)) {
model.focus = true;
if (this.$refs.hyzw_template && this.$refs.hyzw_template[i]
&& this.$refs.hyzw_template[i].focus) {
this.$refs.hyzw_template[i].focus();
}
isFoucs = true;
if (isCheck) {
model.check = true;
}
return false;
}
}
}
return isFoucs;
},
amFocus: function () { //设置默认选中,且是否变红
var $this = this;
setTimeout(function () {
var models = $this.am_formModel;
if (models) {
let k = 0;
for (let i = 0; i < models.length; i++) {
let item = models[i];
for (let j = 0; j < item.length; j++) {
k++;
let model = item[j];
if ($this.hyzw.notBlank(model.focus) && model.focus) {
model.focus = true;
if ($this.$refs && $this.$refs.hyzw_template_dialog &&
$this.$refs.hyzw_template_dialog[k - 1]) {
$this.$refs.hyzw_template_dialog[k - 1].focus();
}
if (model.check) {
model.check = true;
}
break;
}
}
}
}
}, 100);
},
checkQuery: function (isCheck) { //设置默认选中,且是否变红
var isFoucs = true;
var models = this.page_query_formModel;
if (models) {
for (var i = 0; i < models.length; i++) {
var model = models[i];
model.check = false;
if (this.hyzw.isBlank(model.value) && model.required) {
model.focus = true;
if (this.$refs.hyzw_template && this.$refs.hyzw_template[i] && this.$refs.hyzw_template[i].focus) {
this.$refs.hyzw_template[i].focus();
}
isFoucs = true;
if (isCheck) {
model.check = true;
}
return false;
}
}
}
return isFoucs;
},
checkSubmit: function (isCheck) { //表单提交是否变红
let isFoucs = true;
let models = this.am_formModel;
let k = 0;
for (let i = 0; i < models.length; i++) {
let item = models[i];
for (let j = 0; j < item.length; j++) {
k++;
let model = item[j];
model.check = false;
if ((this.hyzw.isBlank(model.value) || (model.type=="select" && model.value == -1)) && model.required) {
model.focus = true;
isFoucs = true;
if (isCheck) {
model.check = true;
}
this.$refs.hyzw_template_dialog[k - 1].focus();
if (model.type == "select") {
this.$message.error(model.label + '必填!');
}
return false;
}
if (this.hyzw.notBlank(model.value)) {
var isRep = true;
var notice = "";
if (model.type == "mobile" && !this.hyzw.isMobile(model.value)) {
isRep = false;
notice = "必须为手机格式";
}
if (model.type == "email" && model.value.indexOf("@") == -1) {
isRep = false;
notice = "必须为邮箱格式";
}
if (model.value.length > model.max_length) {
isRep = false;
notice = "长度不能大于" + model.max_length;
}
if (model.value.length < model.min_length) {
isRep = false;
notice = "长度不能小于" + model.min_length;
}
if (model.type == "ip" && !this.hyzw.isIP(model.value)) {
isRep = false;
notice = "必须为IP格式";
}
if (!isRep) {
this.$refs.hyzw_template_dialog[k - 1].focus();
this.$message.error(model.label + notice);
return false;
}
}
}
}
this.am_formModel = this.am_formModel.slice();
return isFoucs;
},
initDialogWidth: function () {
let cols = this.pageJson.cols;
if (cols == 1) {
this.dialogWidth = "500px";
} else if (cols == 2) {
this.dialogWidth = "630px";
} else if (cols == 3) {
this.dialogWidth = "900px";
}
},
dataAmCleaing: function (in_modes, cols) { //新增修改表单数据清洗
if (!in_modes) {
return;
}
const temp_am_formModel = [];
this.hidden_formModel = [];
var json = JSON.stringify(in_modes);
let am_colModel = JSON.parse(json);
var items = [];
for (let i = 0; i < am_colModel.length; i++) {
let formItem = am_colModel[i];
if (!formItem.type) {
formItem.type = "text";
}
if (!formItem.check) {
formItem.check = false;
}
if (!formItem.placeholder) {
formItem.placeholder = "请输入 " + formItem.label;
}
if (formItem.type == "select") {
if (!formItem.options) {
formItem.options = [];
}
if (!formItem.value) {
formItem.value = "";
}
}
if (formItem.type == "cascader") {
if (!formItem.value) {
formItem.value = [];
}
}
if (formItem.type == "select2") {
if (!formItem.value) {
formItem.value = [];
}
}
if (!formItem.cols) {
formItem.cols = 1;
}
if (formItem.modify != undefined && formItem.modify != null && !formItem.modify &&
this.mode == "open_modify") {
// formItem.modify = true;
// formItem.type = "hidden";
continue;
}
if (formItem.type == "hidden") {
this.hidden_formModel.push(formItem);
continue;
}
items.push(formItem);
if (formItem.break_line) {
temp_am_formModel.push(items);
items = [];
}
}
if (items.length > 0) {
temp_am_formModel.push(items);
}
this.am_formModel = temp_am_formModel;
},
dataQueryCleaing: function () { //查询表单数据清洗
if (this.pageJson.query_colModel) {
var json = JSON.stringify(this.pageJson.query_colModel);
let in_modes = JSON.parse(json);
for (let i = 0; i < in_modes.length; i++) {
let formItem = in_modes[i];
if (!formItem.type) {
formItem.type = "text";
}
if (formItem.type == "select") {
if (!formItem.options) {
formItem.options = [];
}
if (!formItem.value) {
formItem.value = "";
}
}
if (formItem.type == "cascader") {
if (!formItem.value) {
formItem.value = [];
}
}
if (formItem.type == "select2") {
if (!formItem.value) {
formItem.value = [];
}
}
}
this.page_query_formModel = in_modes;
}
},
dataGridCleaing: function () { //查询表单数据清洗
if (this.pageJson.colModel) {
var json = JSON.stringify(this.pageJson.colModel);
let in_modes = JSON.parse(json);
for (let i = 0; i < in_modes.length; i++) {
let formItem = in_modes[i];
if (!formItem.sortable) {
formItem.sortable = {};
formItem.sortable.type = false;
}
if (formItem.modify && formItem.funs) {
for (var j = 0; j < formItem.funs.length; j++) {
var fun = formItem.funs[j];
if (fun.children) {
this.modify_colModel.push(fun);
}
}
}
}
this.page_colModel = in_modes;
}
}
}
}
</script>
<style type="text/css" scoped>
.el-dialog__footer {
padding: 16px 30px 30px 35px !important;
}
.my-edit-group .my-group-title {
text-align: center !important;
padding-right: 7px !important;
margin: 0 -12px 0 15px !important;
min-width: 98px;
}
.cols-1-1 {
width: 360px !important;
}
.cols-2-3 {
width: 455px !important;
}
.cols-3-3 {
width: 455px !important;
}
.cols-3-5 {
width: 735px !important;
}
.template_row {
width: 100%;
height: auto;
}
input:read-only {
background: #cccccc4f;
cursor: not-allowed
}
body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
overflow: hidden;
}
.loc-index-content .loc-right-content .loc-manage-content {
/* padding-top:1px !important; */
}
.el-table__body-wrapper {
/* overflow-y: auto !important; */
/* height: calc(100vh - 290px) !important; */
}
.required {
border: 1px solid rgb(255, 0, 0) !important;
box-shadow: rgb(255, 0, 0) 0px 0px 3px !important;
}
.dialogIcon {
height: 28px;
line-height: 28px;
}
.dialog_height {
height: 100%;
}
.dialog_none {
height: 0px;
}
.dialog_icon {
margin: 8px 0 0 0px;
}
.attributeTable {
padding: 5px 20px;
}
.attributeTable .attribute_but {
margin-bottom: 5px;
}
.attribute_box {
padding: 10px 20px;
}
.attribute_box .queryBox {
padding: 0 0 10px;
}
</style>
依次向模板传入json。一个功能分分钟做完
关于系统的自定义查询,此处需要后台配合支持(后台也是我写的。哈哈。跳过.).
更多推荐
已为社区贡献1条内容
所有评论(0)