Commit bf7244a861a8b4293017b6b6d668b5549faf0f02

Authored by Aaron
1 parent d09a3b67
Exists in master and in 1 other branch legacy

完善Scheme组件请求

examples/main.js
... ... @@ -13,7 +13,89 @@ import '@/styles/theme/index.css';
13 13 import '@/styles/nprogress.scss';
14 14 import "highlight.js/styles/color-brewer.css";
15 15  
16   -Vue.prototype.$axios = axios;
  16 +import { Notification } from 'element-ui';
  17 +
  18 +const request = axios.create({
  19 + baseURL: 'http://47.110.137.80:7101/',
  20 + timeout: 1000,
  21 + headers: {
  22 + 'Authorization': 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2NTE4ODM0MTEsInN1YiI6ImFkbWluIiwiY3JlYXRlZCI6MTU1MTg4MzQxMTk2NX0.rocgsQq_EEbBDV-BcHpJCUS92KGjBH-0Pf47IrW9v3aj6xJCoFIrnKX4vtpPfYscTk1roBhR5s3I1DIvT8B9wg'
  23 + }
  24 +});
  25 +
  26 +const codeMessage = {
  27 + 200: '服务器成功返回请求的数据',
  28 + 201: '新建或修改数据成功。',
  29 + 202: '一个请求已经进入后台排队(异步任务)',
  30 + 204: '删除数据成功。',
  31 + 400: '发出的请求有错误,服务器没有进行新建或修改数据,的操作。',
  32 + 401: '用户没有权限(令牌、用户名、密码错误)。',
  33 + 403: '用户得到授权,但是访问是被禁止的。',
  34 + 404: '发出的请求针对的是不存在的记录,服务器没有进行操作',
  35 + 406: '请求的格式不可得。',
  36 + 410: '请求的资源被永久删除,且不会再得到的。',
  37 + 422: '当创建一个对象时,发生一个验证错误。',
  38 + 500: '服务器发生错误,请检查服务器',
  39 + 502: '网关错误',
  40 + 503: '服务不可用,服务器暂时过载或维护',
  41 + 504: '网关超时'
  42 +};
  43 +
  44 +const checkStatus = (response) => {
  45 + if (response.status >= 200 && response.status < 300) {
  46 + return response;
  47 + }
  48 + const errortext = codeMessage[response.status] || response.statusText;
  49 + const messageContent = `
  50 + ${response.request.responseURL}
  51 + ${errortext}
  52 + `;
  53 + Notification.error({
  54 + title: `请求错误 ${response.status}:`,
  55 + message: messageContent,
  56 + duration: 3000,
  57 + });
  58 + const error = new Error(errortext);
  59 + error.name = response.status;
  60 + error.response = response;
  61 + return error;
  62 +}
  63 +
  64 +// respone 拦截器
  65 +request.interceptors.response.use(
  66 + response => {
  67 + const { data = {} } = response;
  68 + const { businessException, errorCode, message, success } = data;
  69 + if (success) {
  70 + return data;
  71 + } else if (businessException) {
  72 + if (errorCode) {
  73 + Notification.error({
  74 + title: '提示',
  75 + message,
  76 + duration: 3000,
  77 + });
  78 + }
  79 + return { success: false };
  80 + } else {
  81 + if (errorCode) {
  82 + Notification.error({
  83 + title: '提示',
  84 + message: codeMessage[errorCode],
  85 + duration: 3000,
  86 + });
  87 + }
  88 + return { success: false };
  89 + }
  90 + },
  91 + error => {
  92 + const e = checkStatus(error.response);
  93 + return { success: false };
  94 + });
  95 +
  96 +Vue.prototype.$axios = request;
  97 +
  98 +
17 99  
18 100 // 进度条配置
19 101 NProgress.configure({ showSpinner: false });
... ...
examples/router/routes.js
... ... @@ -54,24 +54,20 @@ const _components = [
54 54 component: () => import('@/views/docs/scheme.md'),
55 55 },
56 56 ]
  57 + },
  58 + {
  59 + group: '测试',
  60 + children: [
  61 + {
  62 + path: 'test',
  63 + name: 'test',
  64 + meta: { title: 'Scheme 测试' },
  65 + component: () => import('@/views/page/test'),
  66 + },
  67 + ]
57 68 }
58 69 ]
59 70  
60   -// const _components = [
61   -// {
62   -// path: 'select',
63   -// name: 'select',
64   -// meta: { title: 'Select 选择器', group },
65   -// component: () => import('@/views/docs/select.md'),
66   -// },
67   -// {
68   -// path: 'form',
69   -// name: 'form',
70   -// meta: { title: 'Form 表单' },
71   -// component: () => import('@/views/docs/form.md'),
72   -// },
73   -// ]
74   -
75 71 let _components_children = [];
76 72 _components.forEach(data => {
77 73 _components_children = [..._components_children, ...data.children]
... ...
examples/views/docs/scheme.md
... ... @@ -11,6 +11,9 @@ Scheme是一个数æ®é©±åŠ¨çš„è§£å†³æ–¹æ¡ˆï¼Œé€šè¿‡æ—¢å®šçš„ä¸šåŠ¡é…ç½®å‚æ•°ï¼
11 11 ```html
12 12 <template>
13 13 <eagle-scheme :list="schemeList">
  14 + <!-- <div slot="action-bar" slot-scope="{ handleNew }">
  15 + <el-button type="warn" @click="handleNew">新增</el-button>
  16 + </div> -->
14 17 <el-button slot="action-button" type="success" plain size="small">å¯ç”¨</el-button>
15 18 <el-button slot="action-button" type="danger" plain size="small">ç¦ç”¨</el-button>
16 19 <el-table-column type="selection" width="50" align="center"></el-table-column>
... ... @@ -66,9 +69,9 @@ export default {
66 69 { type: 'el-input', key: 'name', label: 'åç§°', rules: [{ required: true, message: '请输入åç§°' }] },
67 70 { type: 'el-input', key: 'code', label: 'ç¼–ç ', rules: [{ required: true, message: '请输入编ç ' }],
68 71 exclude: 'search', group: { label: '设置', key: 'setting', tip: { content: '哇哦', placement: 'left' } }, tip: 'ç¼–ç ä¸ºæ•°å­—' },
69   - { type: 'el-input', key: 'type', label: '类型', group: { label: '设置', key: 'setting' }, tip: '类型éšä¾¿å¡«' },
  72 + { type: 'el-input', key: 'type', label: '类型', group: { label: '设置', key: 'setting', icon: 'edit' }, formScheme: { tip: '类型éšä¾¿å¡«' } },
70 73 { type: 'el-input-number', key: 'sort', label: '排åº', include: ['form', 'table'], sortable: true },
71   - { type: 'el-input', key: 'status', label: '状æ€', formScheme: { label: '状æ€ç ' } },
  74 + { type: 'el-input', key: 'status', label: '状æ€', group: { label: 'ä¿¡æ¯', key: 'info', icon: 'info' }, formScheme: { label: '状æ€ç ' } },
72 75 ],
73 76 dataSource: [
74 77 { label: '选项A', value: 'A' },
... ...
examples/views/docs/table.md
... ... @@ -10,7 +10,7 @@
10 10  
11 11 ```html
12 12 <template>
13   - <eagle-table ref="table" :value="tableData" :list="tableList" :tableProps="tableProps"></eagle-table>
  13 + <eagle-table ref="table" :value="tableData" :list="tableList"></eagle-table>
14 14 </template>
15 15  
16 16 <script>
... ... @@ -23,9 +23,6 @@ export default {
23 23 { name: '项叔', address: '大楚小区', postcode: 555, number: '北城3号院' },
24 24 { name: '项季', address: '大楚小区', postcode: 555, number: '北城4号院' },
25 25 ],
26   - tableProps: {
27   - border: true
28   - },
29 26 tableList: [
30 27 { key: 'name', label: '名称',
31 28 formatter(row, column) {
... ... @@ -107,7 +104,7 @@ export default {
107 104 }
108 105 },
109 106 mounted() {
110   - console.log(this.$refs.table.tableInstance);
  107 + console.log(this.$refs.table.instance);
111 108 },
112 109 methods: {
113 110 handleSubmit(value) {
... ...
examples/views/page/test.vue 0 → 100644
... ... @@ -0,0 +1,83 @@
  1 +<template>
  2 + <eagle-scheme
  3 + :option="{ $http: $axios, url: '/dataDictionary', detailMethod: 'queryById', getMethod: 'queryById', editMethod: 'modify' }"
  4 + :list="schemeList"
  5 + :formProps="{ span: 24, 'label-width': '60px' }"
  6 + :detailProps="{ span: 24, 'label-width': '50px' }"
  7 + :dialogProps="dialogProps"
  8 + @dialog-change="handleDialogChange"
  9 + ></eagle-scheme>
  10 +</template>
  11 +
  12 +<script>
  13 +export default {
  14 + name: 'test',
  15 + data() {
  16 + return {
  17 + schemeList: [
  18 + { type: 'el-input', label: 'ID', key: 'id', include: 'form', visible: (model, { formMode } = {}) => { return formMode == 'edit' },
  19 + props: { disabled: true },
  20 + },
  21 + { type: 'el-input', label: '编码', key: 'code', exclude: 'search',
  22 + rules: [{ required: true, message: '编码不能为空', trigger: 'blur' }],
  23 + props: { placeholder: '编码' },
  24 + },
  25 + { type: 'el-input', label: '名称', key: 'name',
  26 + rules: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
  27 + props: { placeholder: '名称' },
  28 + },
  29 + { type: 'el-input', label: '备注', key: 'remark', include: 'table',
  30 + props: { placeholder: '备注' },
  31 + },
  32 + ],
  33 + dialogType: '',
  34 + }
  35 + },
  36 + computed: {
  37 + dialogProps() {
  38 + return { width: this.dialogType === 'dialog-form' ? '500px' : '400px' };
  39 + }
  40 + },
  41 + methods: {
  42 + async searchAPI(param) {
  43 + return this.$axios.get(`/dataDictionary/page?current=1&size=10`)
  44 + .then((response) => {
  45 + const { result = [], totalCount = 0 } = response || {};
  46 + return { result, totalCount };
  47 + }).catch(() => {
  48 + return {};
  49 + });
  50 + },
  51 + async getAPI(param) {
  52 + return this.$axios.get(`/dataDictionary/queryById?id=${param.id}`)
  53 + .then((response) => {
  54 + const { result = {} } = response || {};
  55 + return result;
  56 + }).catch(() => {
  57 + return {};
  58 + });
  59 + },
  60 + async newAPI(param) {
  61 + return this.$axios.post('/dataDictionary/add', param)
  62 + .then((response) => {
  63 + const { success = false } = response || {};
  64 + return success;
  65 + }).catch(() => {
  66 + return false;
  67 + });
  68 + },
  69 + async editAPI(param) {
  70 + return this.$axios.post('/dataDictionary/modify', param)
  71 + .then((response) => {
  72 + const { success = false } = response || {};
  73 + return success;
  74 + }).catch(() => {
  75 + return false;
  76 + });
  77 + },
  78 + handleDialogChange(type) {
  79 + this.dialogType = type;
  80 + }
  81 + }
  82 +}
  83 +</script>
0 84 \ No newline at end of file
... ...
packages/detail/index.vue
... ... @@ -145,6 +145,13 @@ export default {
145 145 list(value) {
146 146 this.initModel(value);
147 147 },
  148 + model: {
  149 + handler(val) {
  150 + this.$emit("input", val);
  151 + this.$emit("change", val);
  152 + },
  153 + deep: true
  154 + }
148 155 },
149 156 methods: {
150 157 // 设置表单值
... ...
packages/form/index.vue
... ... @@ -17,7 +17,7 @@
17 17 </style>
18 18  
19 19 <template>
20   - <el-form class="eagle-form" ref="form" :model="model" v-bind="formProps">
  20 + <el-form class="eagle-form" ref="form" :model="model" v-bind="{ size: 'small', 'label-width': '90px', ...formProps }">
21 21 <el-row :gutter="15">
22 22 <template v-for="(data, index) in listOption.dataList">
23 23 <template v-if="listOption.isGroup">
... ... @@ -72,12 +72,7 @@ export default {
72 72 // 表单参数
73 73 formProps: {
74 74 type: Object,
75   - default() {
76   - return {
77   - size: 'small',
78   - 'label-width': '70px'
79   - }
80   - }
  75 + default() { return {} }
81 76 },
82 77 // 纯净提交
83 78 submitPure: {
... ... @@ -87,13 +82,15 @@ export default {
87 82 // 底部样式
88 83 footerStyle: {
89 84 type: [String, Object],
90   - default: 'text-align: center'
  85 + default: 'text-align: center;margin-top: 20px;'
91 86 },
92 87 // 表单项占位
93 88 span: {
94 89 type: Number,
95 90 default: 24
96   - }
  91 + },
  92 + // 用于做动态判断的参数集
  93 + params: Object,
97 94 },
98 95 data() {
99 96 return {
... ... @@ -199,7 +196,7 @@ export default {
199 196 bindItemEvent(item) {
200 197 if (item.on) {
201 198 if (typeof item.on === 'function') {
202   - return item.on(this.model);
  199 + return item.on(this.model, this.params);
203 200 } else {
204 201 return item.on
205 202 }
... ... @@ -218,9 +215,9 @@ export default {
218 215 let visible = true;
219 216 const item = this.listKeySet[key] || {};
220 217 if (typeof item.visible === 'function') {
221   - visible = item.visible({ ...this.model }); // 返回model的复制结果,判断类属性禁止改变model,防止循环导致内存溢出
  218 + visible = item.visible({ ...this.model }, this.params); // 返回model的复制结果,判断类属性禁止改变model,防止循环导致内存溢出
222 219 } else {
223   - visible = item.visible === undefined ? true : item.visible; // 没有定义visible时返回true,否则返回visible定义的值。【注意:不可写成“ !item.visible ”】
  220 + visible = item.visible === undefined ? true : item.visible; // 没有定义visible时返回true,否则返回visible定义的值(包括false)。【注意:不可写成“ !item.visible ”】
224 221 }
225 222 return visible;
226 223 },
... ... @@ -228,7 +225,7 @@ export default {
228 225 bindItemVisible(visible = true) {
229 226 let result = visible;
230 227 if (typeof visible === 'function') {
231   - result = visible(this.model);
  228 + result = visible(this.model, this.params);
232 229 }
233 230 return result;
234 231 },
... ... @@ -236,7 +233,7 @@ export default {
236 233 bindItemShow(show = true) {
237 234 let result = show;
238 235 if (typeof show === 'function') {
239   - result = show(this.model);
  236 + result = show(this.model, this.params);
240 237 }
241 238 return result;
242 239 },
... ... @@ -246,7 +243,7 @@ export default {
246 243 let result = { ...props };
247 244 Object.keys(result).forEach(key => {
248 245 if (typeof result[key] === 'function') {
249   - result[key] = result[key](this.model);
  246 + result[key] = result[key](this.model, this.params);
250 247 }
251 248 });
252 249 return result;
... ...
packages/scheme/index.vue
... ... @@ -33,9 +33,11 @@
33 33 display: flex;
34 34 align-items: center;
35 35 }
36   -.eagle-scheme__table .eagle-scheme__table-btn:not(:first-child) {
37   - padding-left: 10px;
  36 +.eagle-scheme__table .eagle-scheme__table-btn:not(:last-child) {
  37 + padding-left: 0px;
  38 + padding-right: 10px;
38 39 margin-left: 0px;
  40 + margin-right: 0px;
39 41 }
40 42 .eagle-scheme__pagination {
41 43 text-align: right;
... ... @@ -59,17 +61,20 @@
59 61 </div>
60 62 <!-- 操作按钮栏 -->
61 63 <div v-if="!option.showActionBar" class="eagle-scheme__action" v-loading="tableLoading" element-loading-spinner="none" element-loading-background="rgba(255, 255, 255, 0.6)">
62   - <el-button class="eagle-scheme__action-btn" type="primary" size="small" @click="handleNew">新增</el-button>
63   - <el-button v-if="hasSelectionSlot" :disabled="tableSelection && tableSelection.length <= 0" class="eagle-scheme__action-btn" plain size="small" @click="handleDelete('more')">删除</el-button>
64   - <slot v-if="$scopedSlots['action-button'] || $slots['action-button']" name="action-button" class="eagle-scheme__action-btn" :model="formModel" :selection="tableSelection" :setDialog="setDialog"></slot>
65   - <div v-if="hasSelectionSlot && tableSelection && tableSelection.length > 0" class="eagle-scheme__action-btn eagle-scheme__text-selection">已选中<span class="eagle-scheme__text-selection-highlight">{{ tableSelection.length }}</span>项</div>
  64 + <slot v-if="$scopedSlots['action-bar'] || $slots['action-bar']" name="action-bar" :handleNew="handleNew" :handleDelete="handleDelete" :model="formModel" :selection="tableSelection" :setDialog="setDialog"></slot>
  65 + <template v-else>
  66 + <el-button class="eagle-scheme__action-btn" type="primary" size="small" @click="handleNew">新增</el-button>
  67 + <el-button v-if="hasSelectionSlot" :disabled="tableSelection && tableSelection.length <= 0" class="eagle-scheme__action-btn" plain size="small" @click="handleDelete('more')">删除</el-button>
  68 + <slot v-if="$scopedSlots['action-button'] || $slots['action-button']" name="action-button" class="eagle-scheme__action-btn" :model="formModel" :selection="tableSelection" :setDialog="setDialog"></slot>
  69 + <div v-if="hasSelectionSlot && tableSelection && tableSelection.length > 0" class="eagle-scheme__action-btn eagle-scheme__text-selection">已选中<span class="eagle-scheme__text-selection-highlight">{{ tableSelection.length }}</span>项</div>
  70 + </template>
66 71 </div>
67 72 <div class="eagle-scheme__table">
68 73 <!-- 表格 -->
69 74 <eagle-table ref="eagle-table" :list="_tableList" :value="tableData"
70 75 v-loading="tableLoading"
71 76 element-loading-background="rgba(255, 255, 255, 0.6)"
72   - :tableProps="{ size: 'small', border: true, 'row-key': 'id', ...tableProps }"
  77 + :tableProps="{ border: true, 'row-key': 'id', ...tableProps }"
73 78 :tableEvents="{
74 79 'selection-change': handleTableSelectionChange,
75 80 ...tableEvents,
... ... @@ -109,8 +114,8 @@
109 114 :page-size="pageSize" :total="totalCount" v-bind="{ 'page-sizes': [10, 20, 50], layout: 'total, sizes, prev, pager, next, jumper', ...paginationProps }"></el-pagination>
110 115 </div>
111 116 </div>
112   - <el-dialog :custom-class="dialogProps['custom-class'] || 'eagle-scheme__dialog'" :title="dialogProps.title || dialogTitle" :visible.sync="dialogVisible" v-bind="{ width: '65%', ...dialogProps }">
113   - <eagle-form v-if="dialogType === 'dialog-form' && !$scopedSlots['dialog-form'] && !$slots['dialog-form']" :list="_formList" v-model="formModel" :span="formProps.span || 12" :formProps="{ size: 'small', 'label-width': '90px', ...formProps }" @submit="handleSubmit" @cancel="handleCancel">
  117 + <el-dialog v-loading="dialogLoading" element-loading-background="rgba(255, 255, 255, 0.3)" :custom-class="dialogProps['custom-class'] || 'eagle-scheme__dialog'" :title="dialogProps.title || dialogTitle" :visible.sync="dialogVisible" v-bind="{ width: '65%', ...dialogProps }">
  118 + <eagle-form v-if="dialogType === 'dialog-form' && !$scopedSlots['dialog-form'] && !$slots['dialog-form']" :list="_formList" v-model="formModel" :params="{ formMode }" :span="formProps.span || 12" :formProps="formProps" @submit="handleSubmit" @cancel="handleCancel">
114 119 <!-- 表单分组具名插槽 -->
115 120 <template v-for="key in formGroupSlotsKeys">
116 121 <slot v-if="$scopedSlots[`form-${key}`] || $slots[`form-${key}`]" :name="`form-${key}`" :slot="key" :model="formModel"></slot>
... ... @@ -120,7 +125,7 @@
120 125 <slot v-if="$scopedSlots[`form-item-${item.key}`] || $slots[`form-item-${item.key}`]" :name="`form-item-${item.key}`" :slot="`item-${item.key}`" :model="formModel"></slot>
121 126 </template>
122 127 </eagle-form>
123   - <eagle-detail v-else-if="dialogType === 'dialog-view' && !$scopedSlots['dialog-view'] && !$slots['dialog-view']" v-model="formModel" :list="_formList">
  128 + <eagle-detail v-else-if="dialogType === 'dialog-view' && !$scopedSlots['dialog-view'] && !$slots['dialog-view']" v-model="formModel" :list="list || detailList || _formList" :span="detailProps.span || 8" :detailProps="detailProps">
124 129 <!-- 表单分组具名插槽 -->
125 130 <template v-for="key in formGroupSlotsKeys">
126 131 <slot v-if="$scopedSlots[`view-${key}`] || $slots[`view-${key}`]" :name="`view-${key}`" :slot="key" :model="formModel"></slot>
... ... @@ -138,6 +143,9 @@
138 143  
139 144 <script>
140 145 import { generateListSpace } from './parser';
  146 +import { stringify } from './utils';
  147 +
  148 +let _$http = null;
141 149  
142 150 export default {
143 151 name: 'Scheme',
... ... @@ -155,6 +163,8 @@ export default {
155 163 formList: Array,
156 164 // 表格配置
157 165 tableList: Array,
  166 + // 详情配置
  167 + detailList: Array,
158 168 // 表格参数
159 169 tableProps: {
160 170 type: Object,
... ... @@ -170,6 +180,11 @@ export default {
170 180 type: Object,
171 181 default() { return {} }
172 182 },
  183 + // 详情参数
  184 + detailProps: {
  185 + type: Object,
  186 + default() { return {} }
  187 + },
173 188 // 分页参数
174 189 paginationProps: {
175 190 type: Object,
... ... @@ -179,7 +194,7 @@ export default {
179 194 dialogProps: {
180 195 type: Object,
181 196 default() { return {} }
182   - }
  197 + },
183 198 },
184 199 data() {
185 200 return {
... ... @@ -191,6 +206,8 @@ export default {
191 206 _formList: [],
192 207 // 表单值
193 208 formModel: {},
  209 + // 表单模式 新增(new)/编辑(edit)/详情(view)
  210 + formMode: 'new',
194 211 // 表格配置
195 212 _tableList: [],
196 213 // 当前页
... ... @@ -205,25 +222,10 @@ export default {
205 222 dialogTitle: '',
206 223 // 弹出框类型
207 224 dialogType: '',
  225 + // 弹出框加载状态
  226 + dialogLoading: false,
208 227 // 表格数据
209   - tableData: [
210   - { name: '赵伯', code: 'U00001', type: 'admin', sort: 0, status: 'active' },
211   - { name: '钱仲', code: 'U00002', type: 'user', sort: 1, status: 'active' },
212   - { name: '孙叔', code: 'U00003', type: 'user', sort: 2, status: 'active' },
213   - { name: '李季', code: 'U00004', type: 'user', sort: 3, status: 'active' },
214   - { name: '赵伯', code: 'U00001', type: 'admin', sort: 0, status: '' },
215   - { name: '钱仲', code: 'U00002', type: 'user', sort: 1, status: 'active' },
216   - { name: '孙叔', code: 'U00003', type: 'user', sort: 2, status: '' },
217   - { name: '李季', code: 'U00004', type: 'user', sort: 3, status: 'active' },
218   - { name: '赵伯', code: 'U00001', type: 'admin', sort: 0, status: 'active' },
219   - { name: '钱仲', code: 'U00002', type: 'user', sort: 1, status: 'active' },
220   - { name: '孙叔', code: 'U00003', type: 'user', sort: 2, status: '' },
221   - { name: '李季', code: 'U00004', type: 'user', sort: 3, status: '' },
222   - { name: '赵伯', code: 'U00001', type: 'admin', sort: 0, status: 'active' },
223   - { name: '钱仲', code: 'U00002', type: 'user', sort: 1, status: '' },
224   - { name: '孙叔', code: 'U00003', type: 'user', sort: 2, status: '' },
225   - { name: '李季', code: 'U00004', type: 'user', sort: 3, status: '' },
226   - ],
  228 + tableData: [],
227 229 // 表格选中项
228 230 tableSelection: [],
229 231 // 表格加载状态
... ... @@ -244,13 +246,16 @@ export default {
244 246 this._tableList = this.tableList || [];
245 247 }
246 248 this.totalCount = this.tableData.length;
  249 + // 传入axios标准的http库
  250 + if (this.option.$http) {
  251 + _$http = this.option.$http;
  252 + }
247 253 },
248 254 mounted() {
249   - this.$axios.get('http://47.110.137.80:7102/article/categoryCode')
250   - .then((response) => {
251   - // handle success
252   - console.log(response);
253   - });
  255 + // 设置自动加载数据
  256 + if (!this.option.auto) {
  257 + this.handleSearch();
  258 + }
254 259 },
255 260 computed: {
256 261 // 解析表单组件分组具名插槽名称
... ... @@ -274,17 +279,45 @@ export default {
274 279 },
275 280 methods: {
276 281 // 查询数据
277   - handleSearch(param) {
278   - this.tableLoading = true;
279   - setTimeout(() => {
280   - this.tableLoading = false;
281   - console.log({
282   - param,
283   - searchModel: this.searchModel,
284   - currentPage: this.currentPage,
285   - pageSize: this.pageSize
  282 + async handleSearch(value) {
  283 + const param = {
  284 + ...this.searchModel,
  285 + ...value,
  286 + currentPage: this.currentPage,
  287 + pageSize: this.pageSize
  288 + };
  289 + this.doSearch(param);
  290 + },
  291 + // 查询数据逻辑
  292 + async doSearch(param) {
  293 + if (this.option.searchAPI) { // 配置了自定义查询API的情况
  294 + console.log('searchAPI');
  295 + this.tableLoading = true;
  296 + try {
  297 + const { result = [], totalCount = 0 } = await this.option.searchAPI(param);
  298 + this.tableData = result;
  299 + this.totalCount = totalCount;
  300 + } catch (error) {
  301 + console.error(error);
  302 + } finally {
  303 + this.tableLoading = false;
  304 + }
  305 + } else if (_$http && this.option.url) { // 给定了http的情况
  306 + console.log('_$http search');
  307 + this.tableLoading = true;
  308 + _$http.get(`${this.option.url.trim('/')}/${this.option.searchMethod || 'page'}?${stringify(param)}`)
  309 + .then((response) => {
  310 + const { result = [], totalCount = 0 } = response || {};
  311 + this.tableData = result;
  312 + this.totalCount = totalCount;
  313 + })
  314 + .finally(() => {
  315 + this.tableLoading = false;
286 316 });
287   - }, 2000);
  317 + } else {
  318 + this.tableLoading = true;
  319 + setTimeout(() => { this.tableLoading = false; }, 1500);
  320 + }
288 321 },
289 322 // 查看按钮
290 323 handleView({ row }) {
... ... @@ -292,11 +325,43 @@ export default {
292 325 this.dialogType = 'dialog-view';
293 326 this.tableCurrentRow = row;
294 327 this.formModel = {};
295   - // 设置表单值
296   - Object.keys(row).forEach(key => {
297   - this.formModel[key] = row[key];
298   - });
  328 + this.formMode = "view";
  329 + this.$emit('dialog-change', this.dialogType);
299 330 this.showDialog();
  331 + this.doDetail(row);
  332 + },
  333 + // 查询单项数据详情
  334 + async doDetail(param) {
  335 + const { primaryKey = 'id', detailPrimaryKey } = this.option || {};
  336 + if (this.option.detailAPI) { // 配置了自定义查询API的情况
  337 + console.log('detailAPI');
  338 + this.dialogLoading = true;
  339 + try {
  340 + const result = await this.option.detailAPI(param);
  341 + this.setFormModel(result);
  342 + } catch (error) {
  343 + console.error(error);
  344 + } finally {
  345 + this.dialogLoading = false;
  346 + }
  347 + } else if (_$http && this.option.url) { // 给定了http的情况
  348 + console.log('_$http detail');
  349 + this.dialogLoading = true;
  350 + const defaultDetailMethod = `info/${detailPrimaryKey || primaryKey}/${param[detailPrimaryKey] || param[primaryKey]}`;
  351 + const detailMethodFormat = this.option.detailMethod ? `${this.option.detailMethod.trim('/')}?${stringify({ [detailPrimaryKey || primaryKey]: param[detailPrimaryKey || primaryKey] })}` : undefined;
  352 + _$http.get(`${this.option.url.trim('/')}/${detailMethodFormat || defaultDetailMethod}`)
  353 + .then(response => {
  354 + const { result = {} } = response || {};
  355 + this.setFormModel(result);
  356 + })
  357 + .finally(() => {
  358 + this.dialogLoading = false;
  359 + });
  360 + } else {
  361 + this.dialogLoading = true;
  362 + this.setFormModel(param);
  363 + setTimeout(() => { this.dialogLoading = false; }, 1500);
  364 + }
300 365 },
301 366 // 新增按钮
302 367 handleNew({ row }) {
... ... @@ -304,19 +369,53 @@ export default {
304 369 this.dialogType = 'dialog-form';
305 370 this.tableCurrentRow = row;
306 371 this.formModel = {};
  372 + this.formMode = "new";
  373 + this.$emit('dialog-change', this.dialogType);
307 374 this.showDialog();
308 375 },
309 376 // 编辑按钮
310   - handleEdit({ row }) {
  377 + async handleEdit({ row }) {
311 378 this.dialogTitle = '编辑';
312 379 this.dialogType = 'dialog-form';
313 380 this.tableCurrentRow = row;
314 381 this.formModel = {};
315   - // 设置表单值
316   - Object.keys(row).forEach(key => {
317   - this.formModel[key] = row[key];
318   - });
  382 + this.formMode = "edit";
  383 + this.$emit('dialog-change', this.dialogType);
319 384 this.showDialog();
  385 + this.doGet(row);
  386 + },
  387 + // 查询单项数据
  388 + async doGet(param) {
  389 + const { primaryKey = 'id', getPrimaryKey } = this.option || {};
  390 + if (this.option.getAPI) { // 配置了自定义查询API的情况
  391 + console.log('getAPI');
  392 + this.dialogLoading = true;
  393 + try {
  394 + const result = await this.option.getAPI(param);
  395 + this.setFormModel(result);
  396 + } catch (error) {
  397 + console.error(error);
  398 + } finally {
  399 + this.dialogLoading = false;
  400 + }
  401 + } else if (_$http && this.option.url) { // 给定了http的情况
  402 + console.log('_$http get');
  403 + this.dialogLoading = true;
  404 + const defaultGetMethod = `get/${getPrimaryKey || primaryKey}/${param[getPrimaryKey] || param[primaryKey]}`;
  405 + const getMethodFormat = this.option.getMethod ? `${this.option.getMethod.trim('/')}?${stringify({ [getPrimaryKey || primaryKey]: param[getPrimaryKey || primaryKey] })}` : undefined;
  406 + _$http.get(`${this.option.url.trim('/')}/${getMethodFormat || defaultGetMethod}`)
  407 + .then(response => {
  408 + const { result = {} } = response || {};
  409 + this.setFormModel(result);
  410 + })
  411 + .finally(() => {
  412 + this.dialogLoading = false;
  413 + });
  414 + } else {
  415 + this.dialogLoading = true;
  416 + this.setFormModel(param);
  417 + setTimeout(() => { this.dialogLoading = false; }, 1500);
  418 + }
320 419 },
321 420 // 删除按钮
322 421 handleDelete(type, scope) {
... ... @@ -326,6 +425,14 @@ export default {
326 425 console.log(type, this.tableSelection);
327 426 }
328 427 },
  428 + // 设置表单值
  429 + setFormModel(value) {
  430 + if (value && value instanceof Object) {
  431 + Object.keys(value).forEach(key => {
  432 + this.formModel[key] = value[key];
  433 + });
  434 + }
  435 + },
329 436 // 改变每页总数大小
330 437 handleSizeChange(val) {
331 438 this.currentPage = 1;
... ... @@ -339,7 +446,85 @@ export default {
339 446 },
340 447 // 表单提交
341 448 handleSubmit(param) {
342   - console.log({ param });
  449 + if (this.formMode === 'new') {
  450 + this.doNewSubmit(param);
  451 + } else if (this.formMode === 'edit') {
  452 + this.doEditSubmit(param);
  453 + } else {
  454 + this.hideDialog();
  455 + this.handleSearch();
  456 + }
  457 + },
  458 + // 新增提交逻辑
  459 + async doNewSubmit(param) {
  460 + const { primaryKey = 'id', formPrimaryKey } = this.option || {};
  461 + if (this.option.newAPI) { // 配置了自定义查询API的情况
  462 + console.log('newAPI');
  463 + this.dialogLoading = true;
  464 + try {
  465 + const success = await this.option.newAPI(param);
  466 + if (success) {
  467 + this.hideDialog();
  468 + this.handleSearch();
  469 + if (this.$message) { this.$message({ message: '提交成功', type: 'success' }); }
  470 + }
  471 + } catch (error) {
  472 + console.error(error);
  473 + } finally {
  474 + this.dialogLoading = false;
  475 + }
  476 + } else if (_$http && this.option.url) { // 给定了http的情况
  477 + console.log('_$http new');
  478 + this.dialogLoading = true;
  479 + const postData = { ...param };
  480 + delete postData[formPrimaryKey || primaryKey];
  481 + _$http.post(`${this.option.url.trim('/')}/${this.option.newMethod || 'add'}`, postData)
  482 + .then(response => {
  483 + const { success = false } = response || {};
  484 + if (success) {
  485 + this.hideDialog();
  486 + this.handleSearch();
  487 + if (this.$message) { this.$message({ message: '提交成功', type: 'success' }); }
  488 + }
  489 + })
  490 + .finally(() => {
  491 + this.dialogLoading = false;
  492 + });
  493 + }
  494 + },
  495 + // 编辑提交逻辑
  496 + async doEditSubmit(param) {
  497 + if (this.option.editAPI) { // 配置了自定义查询API的情况
  498 + console.log('editAPI');
  499 + this.dialogLoading = true;
  500 + try {
  501 + const success = await this.option.editAPI(param);
  502 + if (success) {
  503 + this.hideDialog();
  504 + this.handleSearch();
  505 + if (this.$message) { this.$message({ message: '编辑成功', type: 'success' }); }
  506 + }
  507 + } catch (error) {
  508 + console.error(error);
  509 + } finally {
  510 + this.dialogLoading = false;
  511 + }
  512 + } else if (_$http && this.option.url) { // 给定了http的情况
  513 + console.log('_$http edit');
  514 + this.dialogLoading = true;
  515 + _$http.post(`${this.option.url.trim('/')}/${this.option.editMethod || 'update'}`, param)
  516 + .then(response => {
  517 + const { success = false } = response || {};
  518 + if (success) {
  519 + this.hideDialog();
  520 + this.handleSearch();
  521 + if (this.$message) { this.$message({ message: '编辑成功', type: 'success' }); }
  522 + }
  523 + })
  524 + .finally(() => {
  525 + this.dialogLoading = false;
  526 + });
  527 + }
343 528 },
344 529 // 表单取消
345 530 handleCancel() {
... ... @@ -368,6 +553,7 @@ export default {
368 553 setDialog({ title, type, model }) {
369 554 this.dialogTitle = title;
370 555 this.dialogType = type;
  556 + this.$emit('dialog-change', type);
371 557 if (model) {
372 558 Object.keys(model).forEach(key => {
373 559 this.formModel[key] = model[key];
... ...
packages/scheme/utils.js 0 → 100644
... ... @@ -0,0 +1,41 @@
  1 +export const stringify = (json) => {
  2 + const urlEncode = (param, key, encode) => {
  3 + if (param === null) return '';
  4 + let paramStr = '';
  5 + const t = typeof (param);
  6 + if (t === 'string' || t === 'number' || t === 'boolean') {
  7 + paramStr = `&${key}=${((encode === null || encode) ? encodeURIComponent(param) : param)}`;
  8 + } else {
  9 + for (const i in param) {
  10 + if (i) {
  11 + if (param[i] !== undefined && param[i] !== '' && !(param[i] && typeof param[i] === 'string' && /^\s+$/.test(param[i]))) {
  12 + const k = key == null ? i : `${key}${(param instanceof Array ? `[${i}]` : `.${i}`)}`;
  13 + paramStr += urlEncode(param[i], k, encode);
  14 + }
  15 + }
  16 + }
  17 + }
  18 + return paramStr;
  19 + };
  20 + return urlEncode(json).substring(1);
  21 +}
  22 +
  23 +export const parse = (url) => {
  24 + let obj = {};// 创建一个Object
  25 + let reg = /[?&][^?&]+=[^?&]+/g;// 正则匹配 ?&开始 =拼接 非?&结束 的参数
  26 + let arr = url.match(reg);// match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。
  27 + // arr数组形式 ['?id=12345','&a=b']
  28 + if (arr) {
  29 + arr.forEach((item) => {
  30 + /**
  31 + * tempArr数组 ['id','12345']和['a','b']
  32 + * 第一个是key,第二个是value
  33 + * */
  34 + let tempArr = item.substring(1).split('=');
  35 + let key = decodeURIComponent(tempArr[0]);
  36 + let val = decodeURIComponent(tempArr[1]);
  37 + obj[key] = val;
  38 + });
  39 + }
  40 + return obj;
  41 +}
0 42 \ No newline at end of file
... ...
packages/table/index.vue
... ... @@ -5,7 +5,7 @@
5 5 </style>
6 6  
7 7 <template>
8   - <el-table class="eagle-table" ref="table" :data="tableData" v-bind="tableProps" v-on="tableEvents">
  8 + <el-table class="eagle-table" ref="table" :data="tableData" v-bind="{ size: 'small', ...tableProps }" v-on="tableEvents">
9 9 <slot></slot>
10 10 <template v-if="list && list.length > 0">
11 11 <template v-for="(item, index) in list">
... ... @@ -32,11 +32,7 @@ export default {
32 32 // 表格参数
33 33 tableProps: {
34 34 type: Object,
35   - default() {
36   - return {
37   - size: 'small',
38   - }
39   - }
  35 + default() { return {} }
40 36 },
41 37 // 表格事件
42 38 tableEvents: Object,
... ...