Skip to content

Commit 71c799a

Browse files
authored
Merge pull request #14 from zhangchunlin/master
同步代码
2 parents 6aeac33 + 9a55c69 commit 71c799a

File tree

7 files changed

+212
-57
lines changed

7 files changed

+212
-57
lines changed

demo/apps/tables/settings.ini

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
[APIJSON_TABLES]
2+
moment = {
3+
"editable" : "auto",
4+
"table_fields" : [
5+
{"title":"#","key":"id","width":80},
6+
{"title":"User id","key":"user_id","width":100},
7+
{"title":"Date","key":"date","width":160},
8+
{"title":"Content","key":"content"},
9+
],
10+
"viewedit_fields" : [
11+
{"title":"#","key":"id","editable":False},
12+
{"title":"User id","key":"user_id"},
13+
{"title":"Date","key":"date","editable":False},
14+
{"title":"Content","key":"content","type":"textarea"},
15+
],
16+
}
17+
18+
comment = {
19+
"editable" : "auto",
20+
"table_fields" : [
21+
{"title":"#","key":"id","width":80},
22+
{"title":"User id","key":"user_id","width":100},
23+
{"title":"To id","key":"to_id","width":100},
24+
{"title":"Moment id","key":"moment_id","width":100},
25+
{"title":"Date","key":"date","width":160},
26+
{"title":"Content","key":"content"},
27+
],
28+
"viewedit_fields" : [
29+
{"title":"#","key":"id","editable":False},
30+
{"title":"User id","key":"user_id"},
31+
{"title":"To id","key":"to_id","editable":False},
32+
{"title":"Moment id","key":"moment_id","editable":False},
33+
{"title":"Date","key":"date","editable":False},
34+
{"title":"Content","key":"content","type":"textarea"},
35+
],
36+
}

demo/apps/tables/templates/Tables/list.html

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<div id="app">
1111
<tabs v-model:value="tab_current" type="card">
1212
<tab-pane v-for="item in tabs" :key="item" :label="item" :name="item">
13-
<apijson-table :table_name="item"></apijson-table>
13+
<apijson-table :table_name="item" :config="apijson_tables[item]"></apijson-table>
1414
</tab-pane>
1515
</tabs>
1616
</div>
@@ -21,7 +21,8 @@
2121
delimiters: ['{', '}'],
2222
data:{
2323
tab_current: null,
24-
tabs: {{=table_keys_json}}
24+
tabs: {{=table_keys_json}},
25+
apijson_tables: {{=apijson_tables_json}}
2526
}
2627
})
2728
</script>

demo/apps/tables/views.py

+9-7
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
#coding=utf-8
22
from uliweb import expose, functions
3-
from json import dumps
43

54
@expose('/tables')
65
class Tables(object):
76
@expose('')
87
def list(self):
98
table_keys = settings.APIJSON_MODELS.keys()
10-
if request.user and functions.has_role(request.user,"ADMIN"):
11-
role = "ADMIN"
12-
elif request.user:
13-
role = "LOGIN"
9+
if request.user:
10+
if functions.has_role(request.user,"ADMIN"):
11+
role = "ADMIN"
12+
else:
13+
role = "OWNER"
1414
else:
1515
role = "UNKNOWN"
16+
apijson_tables = functions.get_apijson_tables(role)
1617
return {
17-
"table_keys_json":dumps(table_keys),
18-
"role":role
18+
"table_keys_json":json_dumps(table_keys),
19+
"apijson_tables_json":json_dumps(apijson_tables),
20+
"role":role,
1921
}

uliweb_apijson/apijson/__init__.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#coding=utf-8
2+
3+
def get_apijson_tables(role="UNKNOWN"):
4+
from uliweb import settings
5+
apijson_tables = dict(settings.APIJSON_TABLES.iteritems())
6+
for n in apijson_tables:
7+
c = apijson_tables[n]
8+
editable = c["editable"]
9+
if editable=="auto":
10+
editable = False
11+
POST = settings.APIJSON_MODELS[n]["POST"]
12+
if POST:
13+
roles = POST["roles"]
14+
if roles:
15+
editable = role in roles
16+
c["editable"] = editable
17+
return apijson_tables

uliweb_apijson/apijson/settings.ini

+3
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@ user = {
1616
"PUT" : { "roles" : ["ADMIN","OWNER"] },
1717
"DELETE" : { "roles" : ["ADMIN","OWNER"] },
1818
}
19+
20+
[FUNCTIONS]
21+
get_apijson_tables = "uliweb_apijson.apijson.get_apijson_tables"

uliweb_apijson/apijson/templates/vue/inc_apijson_table.html

+141-45
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
<script>
22
Vue.component('apijson-table', {
33
delimiters: ['{', '}'],
4-
props: ["table_name"],
4+
props: ["table_name","config"],
55
template: `<div>
66
<i-table stripe border :columns="tcolumns" :data="tlist" @on-sort-change="table_on_sort_change"></i-table>
77
<page :total="total" :page-size="query_count" :current.sync="current_page" :page-size-opts="[10, 20, 50, 100]" show-sizer @on-change="page_on_change" @on-page-size-change="page_on_page_size_change"></page>
8-
<modal v-model="modal_view" title="View">
8+
<modal v-model="modal_view" :title="viewedit_label">
99
<i-form @submit.native.prevent :label-width="80">
10-
<form-item v-for="item in view_items" :key="item.key" :label="item.key">
11-
<i-input v-if="typeof item.value !=='boolean'" v-model="item.value" :readonly=true></i-input>
12-
<checkbox v-if="typeof item.value ==='boolean'" v-model="item.value" disabled></checkbox>
10+
<form-item v-for="item in viewedit_items" :key="item.key" :label="item.title">
11+
<i-input v-if="item.type=='input'" v-model="item.value" :readonly="!editable(item)"></i-input>
12+
<checkbox v-if="item.type=='checkbox'" v-model="item.value" :disabled="!editable(item)"></checkbox>
13+
<i-input v-if="item.type=='textarea'" v-model="item.value" type="textarea" :autosize="{minRows: 2,maxRows: 5}"></i-input>
14+
</form-item>
15+
<form-item v-if="config_editable" label="action">
16+
<i-button type="info" icon="ios-download" @click="save">Save</i-button>
1317
</form-item>
1418
</i-form>
1519
</modal>
@@ -21,16 +25,32 @@
2125
var thisp = this
2226
return {
2327
modal_view: false,
24-
view_items: [],
28+
viewedit_items: [],
29+
30+
edit_params: {},
31+
2532
modal_delete: false,
26-
delete_params:{},
27-
tcolumns: [
28-
{title:'#',key:'id',width:80},
29-
{
33+
delete_params: {},
34+
35+
tcolumns: [],
36+
tcolumns_preset: {
37+
"id": {title:'#',key:'id',width:80},
38+
"action": {
3039
title: 'Action',
3140
width: 140,
32-
render: (h, params) => {
33-
return h('div', [
41+
render: function(h, params){
42+
var delete_button = h('Button', {
43+
props: {
44+
type: 'error',
45+
size: 'small'
46+
},
47+
on: {
48+
click: function(){
49+
thisp.remove(params)
50+
}
51+
}
52+
}, 'Delete')
53+
var buttons = [
3454
h('Button', {
3555
props: {
3656
type: 'primary',
@@ -44,31 +64,31 @@
4464
thisp.show(params)
4565
}
4666
}
47-
}, 'View'),
48-
h('Button', {
49-
props: {
50-
type: 'error',
51-
size: 'small'
52-
},
53-
on: {
54-
click: function(){
55-
thisp.remove(params)
56-
}
57-
}
58-
}, 'Delete')
59-
]);
67+
}, thisp.viewedit_label)
68+
]
69+
if (thisp.config_editable) {
70+
buttons.push(delete_button)
71+
}
72+
return h('div', buttons);
6073
}
6174
}
62-
],
75+
},
6376
tcolumns_init: false,
6477
tlist:[],
6578
query_count: 10,
6679
current_page: 1,
6780
total: 0,
6881
sort_key: "id",
69-
sort_order: "-"
82+
sort_order: "-",
83+
84+
config_editable: false,
85+
config_table_fields: null,
86+
config_viewedit_fields: null
7087
}
7188
},
89+
computed: {
90+
viewedit_label: function(){return this.config_editable?'Edit':'View'}
91+
},
7292
methods: {
7393
update_list: function(){
7494
var thisp = this
@@ -94,21 +114,30 @@
94114
if (data.code==200) {
95115
var arr = data["[]"]
96116
if (!thisp.tcolumns_init) {
97-
if (arr.length>0) {
98-
var item = arr[0]
99-
for (var k in item){
100-
if (k!="id") {
101-
var col = {title:k,key:k}
102-
if (typeof item[k] ==="boolean") {
103-
col["width"] = 80
104-
}
105-
else if (typeof item[k] ==="number") {
106-
col["width"] = 100
117+
if (thisp.config_table_fields!=null){
118+
thisp.tcolumns = thisp.config_table_fields
119+
thisp.tcolumns.push(thisp.tcolumns_preset["action"])
120+
thisp.tcolumns_init = true
121+
}
122+
else {
123+
thisp.tcolumns.push(thisp.tcolumns_preset["id"])
124+
if (arr.length>0) {
125+
var item = arr[0]
126+
for (var k in item){
127+
if (k!="id") {
128+
var col = {title:k,key:k}
129+
if (typeof item[k] ==="boolean") {
130+
col["width"] = 80
131+
}
132+
else if (typeof item[k] ==="number") {
133+
col["width"] = 100
134+
}
135+
thisp.tcolumns.push(col)
107136
}
108-
thisp.tcolumns.push(col)
109137
}
138+
thisp.tcolumns.push(thisp.tcolumns_preset["action"])
139+
thisp.tcolumns_init = true
110140
}
111-
thisp.tcolumns_init = true
112141
}
113142
}
114143
thisp.tlist = arr
@@ -119,20 +148,82 @@
119148
},
120149
show: function(params){
121150
var row = params.row
122-
this.view_items = []
123-
this.view_items.push({key:"id",value:row.id})
124-
for (var k in row){
125-
if (k!="id" && k[0]!="_") {
126-
value = row[k]
127-
this.view_items.push({key:k,value:value})
151+
this.viewedit_items = []
152+
if (this.config_viewedit_fields!=null) {
153+
for (var i in this.config_viewedit_fields) {
154+
var d = this.config_viewedit_fields[i]
155+
d.value = row[d.key]
156+
d.type = d.type || "input"
157+
this.viewedit_items.push(d)
158+
}
159+
}
160+
else {
161+
this.viewedit_items.push({title:"id",value:row.id,"type":"input"})
162+
var type2type = {
163+
"boolean":"checkbox"
128164
}
165+
for (var k in row){
166+
if (k!="id" && k[0]!="_") {
167+
var value = row[k]
168+
var type = type2type[typeof value] || "input"
169+
this.viewedit_items.push({title:k,value:value,type:type})
170+
}
171+
}
172+
}
173+
if (this.config_editable){
174+
this.edit_params = params
175+
}
176+
else {
177+
this.edit_params = null
129178
}
130179
this.modal_view = true
131180
},
181+
editable: function(item){
182+
var editable = true
183+
if (item.editable!=null) {editable=item.editable}
184+
return this.config_editable && editable && (item.key!="id")
185+
},
132186
remove: function(params){
133187
this.delete_params = params
134188
this.modal_delete = true
135189
},
190+
save: function(){
191+
var thisp = this
192+
var params = {
193+
"@tag": thisp.table_name
194+
}
195+
var record_params = {}
196+
var row = thisp.edit_params.row
197+
198+
for (var k in thisp.viewedit_items) {
199+
var d = thisp.viewedit_items[k]
200+
if (d.key=="id"|| d.value!=row[d.key]) {
201+
record_params[d.key] = d.value
202+
}
203+
}
204+
params[thisp.table_name] = record_params
205+
$.ajax({
206+
type: "POST",
207+
url: "{{=url_for('uliweb_apijson.apijson.views.ApiJson.put')}}",
208+
contentType: 'application/json',
209+
data: JSON.stringify(params),
210+
success: function (data) {
211+
if (data.code==200){
212+
thisp.$Notice.success({
213+
title: 'success update #'+row.id+' in table '+thisp.table_name,
214+
desc: data.msg
215+
})
216+
thisp.update_list()
217+
}
218+
else {
219+
thisp.$Notice.error({
220+
title: 'error when update #'+row.id+' in table '+thisp.table_name,
221+
desc: data.msg
222+
})
223+
}
224+
}
225+
})
226+
},
136227
real_remove: function(){
137228
var thisp = this
138229
var params = {
@@ -183,6 +274,11 @@
183274
}
184275
},
185276
mounted: function(){
277+
if (this.config!=null){
278+
this.config_editable = this.config.editable || false
279+
this.config_table_fields = this.config.table_fields || null
280+
this.config_viewedit_fields = this.config.viewedit_fields || null
281+
}
186282
this.update_list()
187283
}
188284
})

uliweb_apijson/apijson/views.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -499,14 +499,14 @@ def _put_one(self,key,tag):
499499
obj_dict = {"id":id_}
500500
if ret:
501501
obj_dict["code"] = 200
502-
obj_dict["message"] = "success"
502+
obj_dict["msg"] = "success"
503503
obj_dict["count"] = 1
504504
else:
505505
obj_dict["code"] = 400
506-
obj_dict["message"] = "fail"
506+
obj_dict["msg"] = "failed when updating, maybe no change"
507507
obj_dict["count"] = 0
508508
self.rdict["code"] = 400
509-
self.rdict["message"] = "fail"
509+
self.rdict["msg"] = "failed when updating, maybe no change"
510510
self.rdict[key] = obj_dict
511511

512512
def delete(self):

0 commit comments

Comments
 (0)