Skip to content

Commit

Permalink
Merge branch 'master' of github.com:szuprefix/vue-django
Browse files Browse the repository at this point in the history
  • Loading branch information
szuprefix committed Jan 4, 2021
2 parents 04eea7c + 036cbbc commit 8d0e144
Show file tree
Hide file tree
Showing 47 changed files with 1,750 additions and 181 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vue-django",
"version": "0.8.1",
"version": "0.9.0",
"description": "个人实验项目, 本框架的目标是借鉴并超越django admin的自动化思想, 实现UI前端的极简快速定制开发",
"main": "index.js",
"files": [
Expand Down
13 changes: 10 additions & 3 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div id="app" v-cloak>
<div id="app" v-cloak :class="{mobile_mode:isMobile}">
<router-view v-if="layout === 'main'">
</router-view>
<template v-else>
Expand All @@ -24,7 +24,7 @@
</el-col>
</el-row>
<!--<login-view></login-view>-->
<drawer></drawer>
<drawer :size="isMobile?'50%': '30%'"></drawer>
</template>
</div>
</template>
Expand Down Expand Up @@ -54,7 +54,14 @@
layout (){
return this.$route.meta.layout
},
...mapState(['user', 'system_name', 'party'])
...mapState(['user', 'system_name', 'party']),
isMobile () {
let ua = navigator.userAgent
if (ua.match(/Android/i) || ua.match(/webOS/i) || ua.match(/iPhone/i) || ua.match(/iPad/i) || ua.match(/iPod/i) || ua.match(/BlackBerry/i) || ua.match(/Windows Phone/i)) {
return true
}
return false
}
},
methods: {
logout(){
Expand Down
4 changes: 4 additions & 0 deletions src/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
visibility: hidden;
}

.mobile_mode .hover-show {
visibility: visible;
}

.el-table__row:hover .hover-show, .el-tree-node__content:hover .hover-show {
visibility: visible;
cursor: pointer;
Expand Down
38 changes: 38 additions & 0 deletions src/components/async/Progress.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<template>
<div>
<el-timeline :reverse="$attrs.reverse">
<el-timeline-item
v-for="(m, i) in messages"
:key="i"
:timestamp="m.timestamp">
{{m.status}} {{m.text}}
</el-timeline-item>
</el-timeline>
</div>
</template>
<script>
import progress from './progress'
import {parseTime} from '../../utils/filters'
export default{
props: {
task: Object
},
data () {
return {
messages: []
}
},
components: {},
created () {
progress(this.task, {progress: this.onProgress}).then((rs) => {
this.$emit('done', rs)
})
},
methods: {
onProgress(m) {
this.messages.push({...m, timestamp: parseTime(new Date(), '{h}:{i}:{s}')})
}
},
computed: {}
}
</script>
46 changes: 46 additions & 0 deletions src/components/async/progress.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* Created by denishuang on 2018/3/12.
*/
export default function (task, context) {
let sm = {
'PENDING': '排队中',
'STARTED': '开始执行',
'RETRY': '重试',
'SUCCESS': '任务成功',
'FAILURE': '任务失败',
...context.status
}
let progress = context.progress || function () {}
let promise = new Promise((resolve, reject) => {
let s = task.status
let ps = s.split(' ')
// progress({status:sm[ps[0]], text: ps[1]})
let protocal = location.protocol === "https:" ? "wss" : "ws"
let url = `${protocal}://${location.host}/api/common/async_result/${task.id}/`
let ws = new WebSocket(url)
ws.onload = function () {
console.log('websocket conneted.')
}
ws.onmessage = (e) => {
let rs = JSON.parse(e.data)
if (rs.task_id !== task.id) {
console.log(`got other task id , ignore: ${rs.task_id}`)
return
}
ps = rs.status.split(' ')
progress({status:sm[ps[0]] || ps[0], text: rs.status.slice(ps[0].length)})
console.log(rs)
if (['SUCCESS', 'FAILURE'].includes(rs.status)) {
ws.close()
ws = null
if (rs.status === 'SUCCESS') {
resolve(rs)
} else if (rs.status === 'FAILURE') {
reject({code: 500, msg: rs.result, asyncResult: rs})
}
}
}

})
return promise
}
19 changes: 19 additions & 0 deletions src/components/form/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,24 @@

import arrayNormalize from '../../utils/array_normalize'

export const defaultProps = {
value: Object,
actions: Array,
items: {type: Array, default: () => []},
url: String,
method: {
type: String, default: 'post'
},
options: {
type: Object,
default: () => {
return {}
}
},
submitName: {
type: String, default: '提交'
}
}
export function joinErrors (errors) {
let es = {}
for (let n in errors) {
Expand Down Expand Up @@ -81,6 +99,7 @@ export default {
defaultRuleType,
defaultSpan,
defaultWidget,
defaultProps,
normalizeItem,
normalizeItems,
getItemRules,
Expand Down
18 changes: 1 addition & 17 deletions src/components/form/Form.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,8 @@
ServerResponse
],
props: {
value: Object,
actions: Array,
items: {type: Array, default: () => []},
url: String,
method: {
type: String, default: 'post'
},
options: {
type: Object,
default: () => {
return {}
}
},
...Form.defaultProps,
submit: Function,
submitName: {
type: String, default: '提交'
},
successInfo: String
},
components: {Item, Actions},
Expand Down
2 changes: 1 addition & 1 deletion src/components/form/Widget.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
@change="fieldValueChanged">
</el-switch>
<el-input-number v-model="value[field.name]" v-else-if="field.widget === 'number'" :disabled="field.disabled"
:controls="field.type === 'integer'" @change="fieldValueChanged">
controls-position="right" :controls="field.type === 'integer'" @change="fieldValueChanged">
</el-input-number>
<el-date-picker v-model="value[field.name]" :type="field.widget" value-format="yyyy-MM-ddTHH:mm:ss"
:placeholder="field.placeholder || field.label" :readonly="field.read_only"
Expand Down
103 changes: 103 additions & 0 deletions src/components/form/widgets/NumberRange.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<template>
<el-dropdown @command="handleCommand" trigger="click" class="number-range">
<el-button class="el-dropdown-link" :class="{empty: isEmpty}">
{{field.label}} {{selectValue}}<i class="el-icon-arrow-down el-icon--right"></i>
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="o in options" :command="o" v-key="o.text">{{o.text}}</el-dropdown-item>
<el-dropdown-item :command="undefined">无</el-dropdown-item>
<el-dropdown-item>
<div @click.stop="noCommand">
<el-input-number v-model="range[0]" controls-position="right" clearable
@change="onInputChange"></el-input-number>
-
<el-input-number v-model="range[1]" controls-position="right" clearable
@change="onInputChange"></el-input-number>
</div>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
<script>
import {get} from 'lodash'
// let DEFAULT_OPTIONS = [
// {text: '0-99', range: [0, 99]},
// {text: '100-199', range: [100, 199]},
// {text: '200-299', range: [200, 299]},
// {text: '300-', range: [300, 99999]}
//
// ]
export default{
props: {
value: String,
field: Object,
separator: {type: String, default: ''}
},
data () {
return {
selectValue: '',
range: [undefined, undefined]
}
},
components: {},
methods: {
handleCommand (c) {
if (!c) {
this.range = [undefined, undefined]
this.selectValue = null
} else {
this.range = c.range
this.selectValue = c.text || this.genRangeText(c.range)
}
},
noCommand() {
},
genRangeText(range) {
if (!range[0] && !range[1]) {
return null
}
else if (!range[0] && range[1]) {
return `${range[1]}及以下`
} else if (!range[1] && range[0]) {
return `${range[0]}及以上`
} else {
return `${range[0]}-${range[1]}`
}
},
onInputChange () {
this.selectValue = this.genRangeText(this.range)
}
},
computed: {
isEmpty () {
return !this.range[0] && !this.range[1]
},
options () {
return get(this.field, 'options') || [] // || DEFAULT_OPTIONS
}
},
watch: {
selectValue(v){
if (this.isEmpty) {
this.$emit('input', undefined)
} else {
let min = this.range[0] || 0
let max = this.range[1] || 999999
this.$emit('input', `${min},${max}`)
}
}
}
}
</script>
<style>
.number-range .empty {
color: lightgray;
}
.el-input.range_begin, .el-input.range_end {
width: 6rem;
text-align: right;
}
</style>
27 changes: 20 additions & 7 deletions src/components/form/widgets/Percent.vue
Original file line number Diff line number Diff line change
@@ -1,35 +1,48 @@
<template>
<span class="el-input-group" style="width:6rem;">
<el-input-number v-model="number" :controls="false" style="width:6rem;"
@change="onChange"></el-input-number><span class="el-input-group__append">%</span>
@change="onChange"></el-input-number><span class="el-input-group__append percent-input">%</span>
</span>
</template>
<script>
import {options_without_time} from '../../../utils/date_picker_options'
import dateUtil from 'element-ui/src/utils/date'
export default{
props: {
value: String,
field: Object
},
data () {
return {
number: this.value * 100
number: 0
}
},
components: {},
created () {
this.number = this.value * 100
this.calNumber(this.value)
},
methods: {
calNumber (v) {
this.number = (v * 100).toFixed(this.fixed)
},
onChange(v) {
this.$emit('input', v / 100)
let rv = (v / 100).toFixed(this.fixed+2)
this.calNumber(rv)
this.$emit('input', rv)
}
},
computed: {
fixed () {
return this.field.fixed || 2
}
},
watch: {
value (v) {
this.number = this.value * 100
this.calNumber(v)
}
}
}
</script>
<style>
.el-input-group__append.percent-input{
padding: 0 10px;
}
</style>

0 comments on commit 8d0e144

Please sign in to comment.