+
{{col.title}}:
-
onCalendarChange(time, timeStr, col)" @openChange="open => onCalendarOpenChange(open, col)" class="time-picker" size="small" :get-popup-container="() => $refs.root"/>
+ onCalendarChange(time, timeStr, col)" @openChange="open => onCalendarOpenChange(open, col)" class="time-picker" size="small" :get-popup-container="() => $refs.root"/>
-
+
{{col.title}}:
-
onCalendarChange(date, dateStr, col)" @openChange="open => onCalendarOpenChange(open, col)" class="datetime-picker" size="small" show-time :getCalendarContainer="() => $refs.root"/>
+ onCalendarChange(date, dateStr, col)" @openChange="open => onCalendarOpenChange(open, col)" class="datetime-picker" size="small" show-time :getCalendarContainer="() => $refs.root"/>
-
+
{{col.title}}:
@@ -38,23 +39,24 @@
-
-
+
+
{{col.title}}
- : {{col | searchValue}}
-
-
-
-
-
+
: {{col.search.format && typeof col.search.format === 'function' ? col.search.format(col.search.value) : col.search.value}}
+
+
+
+
+
onCloseClick(e, col)" class="close" type="close-circle" theme="filled"/>
+
@@ -65,35 +67,31 @@
export default {
name: 'SearchArea',
- props: ['columns'],
+ props: ['columns', 'formatConditions'],
inject: ['table'],
created() {
this.columns.forEach(item => {
- this.$set(item, 'search', {...item.search, visible: false, value: item.dataType === 'boolean' ? false : undefined, format: this.getCalendarFormat(item)})
+ this.$set(item, 'search', {...item.search, visible: false, value: undefined, format: this.getFormat(item)})
})
- },
- filters: {
- searchValue(col) {
- if (col.dataType === 'time' && col.search.value) {
- return col.search.value.format('HH:mm:ss')
- }
- return col.search.value
- }
+ console.log(this.columns)
},
watch: {
searchCols(newVal, oldVal) {
if (newVal.length != oldVal.length) {
const newConditions = this.getConditions(newVal)
+ const newSearchOptions = this.getSearchOptions(newVal)
if (!fastEqual(newConditions, this.conditions)) {
this.conditions = newConditions
- this.$emit('change', this.conditions)
+ this.searchOptions = newSearchOptions
+ this.$emit('change', this.conditions, this.searchOptions)
}
}
}
},
data() {
return {
- conditions: []
+ conditions: {},
+ searchOptions: []
}
},
computed: {
@@ -105,72 +103,99 @@
}
},
methods: {
+ onCloseClick(e, col) {
+ e.preventDefault()
+ e.stopPropagation()
+ col.search.value = undefined
+ const {backup, value} = col.search
+ if (backup !== value) {
+ this.backupAndEmitChange(col)
+ }
+ },
onCancel(col) {
col.search.value = col.search.backup
col.search.visible = false
},
onConfirm(col) {
- col.search.backup = col.search.value
+ const {backup, value} = col.search
col.search.visible = false
- const conditions = this.getConditions(this.searchCols)
- if (!fastEqual(conditions, this.conditions)) {
- this.conditions = conditions
- this.$emit('change', this.conditions)
+ if (backup !== value) {
+ this.backupAndEmitChange(col)
}
},
- onSwitchChange() {
- this.conditions = this.getConditions(this.searchCols)
- this.$emit('change', this.conditions)
+ onSwitchChange(col) {
+ const {backup, value} = col.search
+ if (backup !== value) {
+ this.backupAndEmitChange(col)
+ }
},
- onSelectChange() {
- this.conditions = this.getConditions(this.searchCols)
- this.$emit('change', this.conditions)
+ onSelectChange(col) {
+ this.backupAndEmitChange(col)
},
onCalendarOpenChange(open, col) {
col.search.visible = open
- const {momentEqual, getConditions} = this
+ const {momentEqual, backupAndEmitChange} = this
const {value, backup, format} = col.search
if (!open && !momentEqual(value, backup, format)) {
- col.search.backup = moment(value)
- this.conditions = getConditions(this.searchCols)
- this.$emit('change', this.conditions)
+ backupAndEmitChange(col, moment(value))
}
},
onCalendarChange(date, dateStr, col) {
- const {momentEqual, getConditions} = this
+ const {momentEqual, backupAndEmitChange} = this
const {value, backup, format} = col.search
if (!col.search.visible && !momentEqual(value, backup, format)) {
- col.search.backup = moment(value)
- this.conditions = getConditions(this.searchCols)
- this.$emit('change', this.conditions)
+ backupAndEmitChange(col, moment(value))
}
},
onDateChange(col) {
- const {momentEqual, getConditions} = this
- const {value, backup} = col.search
- if (!momentEqual(value, backup, 'YYYY-MM-DD')) {
- col.search.backup = moment(value)
- this.conditions = getConditions(this.searchCols)
- this.$emit('change', this.conditions)
+ const {momentEqual, backupAndEmitChange} = this
+ const {value, backup, format} = col.search
+ if (!momentEqual(value, backup, format)) {
+ backupAndEmitChange(col, moment(value))
}
},
- getCalendarFormat(col) {
+ getFormat(col) {
+ if (col.search && col.search.format) {
+ return col.search.format
+ }
const dataType = col.dataType
switch(dataType) {
case 'time': return 'HH:mm:ss'
case 'date': return 'YYYY-MM-DD'
case 'datetime': return 'YYYY-MM-DD HH:mm:ss'
- default: return col.search && col.search.format
+ default: return undefined
}
},
+ backupAndEmitChange(col, backValue = col.search.value) {
+ const {getConditions, getSearchOptions} = this
+ col.search.backup = backValue
+ this.conditions = getConditions(this.searchCols)
+ this.searchOptions = getSearchOptions(this.searchCols)
+ this.$emit('change', this.conditions, this.searchOptions)
+ },
getConditions(columns) {
const conditions = {}
columns.filter(item => item.search.value !== undefined && item.search.value !== '' && item.search.value !== null)
.forEach(col => {
- conditions[col.dataIndex] = col.search.value
+ const {value, format} = col.search
+ if (this.formatConditions && format) {
+ if (typeof format === 'function') {
+ conditions[col.dataIndex] = format(col.search.value)
+ } else if (typeof format === 'string' && value.constructor.name === 'Moment') {
+ conditions[col.dataIndex] = value.format(format)
+ } else {
+ conditions[col.dataIndex] = value
+ }
+ } else {
+ conditions[col.dataIndex] = value
+ }
})
return conditions
},
+ getSearchOptions(columns) {
+ return columns.filter(item => item.search.value !== undefined && item.search.value !== '' && item.search.value !== null)
+ .map(({dataIndex, search}) => ({field: dataIndex, value: search.value, format: search.format}))
+ },
onVisibleChange(col, index) {
if (!col.search.visible) {
col.search.value = col.search.backup
@@ -214,6 +239,15 @@
user-select: none;
display: inline-flex;
align-items: center;
+ .close{
+ color: @text-color-second;
+ margin-left: 4px;
+ font-size: 12px;
+ vertical-align: middle;
+ :hover{
+ color: @text-color;
+ }
+ }
.switch{
margin-left: 4px;
}
@@ -233,6 +267,7 @@
display: inline-block;
overflow: hidden;
flex:1;
+ vertical-align: middle;
max-width: 144px;
text-overflow: ellipsis;
word-break: break-all;
@@ -243,7 +278,7 @@
}
}
.icon-down{
- margin-left: 4px;
+ vertical-align: middle;
font-size: 12px;
}
}
@@ -259,6 +294,7 @@
}
.operations{
display: flex;
+ margin: -6px 0;
justify-content: space-between;
.btn{
}
diff --git a/src/components/table/api/ApiTable.vue b/src/components/table/api/ApiTable.vue
new file mode 100644
index 0000000..1a73eca
--- /dev/null
+++ b/src/components/table/api/ApiTable.vue
@@ -0,0 +1,49 @@
+
+
+ {{title}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/mock/extend/index.js b/src/mock/extend/index.js
index b3741a6..769dc7f 100644
--- a/src/mock/extend/index.js
+++ b/src/mock/extend/index.js
@@ -50,6 +50,8 @@ const welcomeMessages = [
}
]
+const goods = ['运动鞋', '短裤', 'T恤', '七分裤', '风衣', '寸衫']
+
Random.extend({
admin () {
return this.pick(admins)
@@ -69,6 +71,9 @@ Random.extend({
position () {
return this.pick(positions)
},
+ goods () {
+ return this.pick(goods)
+ },
saying () {
return this.pick(sayings)
},
diff --git a/src/mock/goods/index.js b/src/mock/goods/index.js
new file mode 100644
index 0000000..4bdfa17
--- /dev/null
+++ b/src/mock/goods/index.js
@@ -0,0 +1,51 @@
+import Mock from 'mockjs'
+import '@/mock/extend'
+import {parseUrlParams} from '@/utils/request'
+
+const current = new Date().getTime()
+
+const goodsList = Mock.mock({
+ 'list|100': [{
+ 'id|+1': 0,
+ 'name': '@GOODS',
+ 'orderId': `${current}-@integer(1,100)`,
+ 'status|1-4': 1,
+ 'send': '@BOOLEAN',
+ 'sendTime': '@DATETIME',
+ 'orderDate': '@DATE',
+ 'auditTime': '@TIME'
+ }]
+})
+
+Mock.mock(RegExp(`${process.env.VUE_APP_API_BASE_URL}/goods` + '.*'),'get', ({url}) => {
+ const params = parseUrlParams(decodeURI(url))
+ let {page, pageSize} = params
+ page = eval(page) - 1 || 0
+ pageSize = eval(pageSize) || 10
+ delete params.page
+ delete params.pageSize
+ let result = goodsList.list.filter(item => {
+ for (let [key, value] of Object.entries(params)) {
+ if (item[key] != value) {
+ return false
+ }
+ }
+ return true
+ })
+ const total = result.length
+ if ((page) * pageSize > total) {
+ result = []
+ } else {
+ result = result.slice(page * pageSize, (page + 1) * pageSize)
+ }
+ return {
+ code: 0,
+ message: 'success',
+ data: {
+ page: page + 1,
+ pageSize,
+ total,
+ list: result
+ }
+ }
+})
\ No newline at end of file
diff --git a/src/mock/index.js b/src/mock/index.js
index dc180be..5a1ed69 100644
--- a/src/mock/index.js
+++ b/src/mock/index.js
@@ -4,8 +4,9 @@ import '@/mock/project'
import '@/mock/user/login'
import '@/mock/workplace'
import '@/mock/user/routes'
+import '@/mock/goods'
// 设置全局延时
Mock.setup({
- timeout: '300-600'
+ timeout: '200-400'
})
diff --git a/src/pages/components/table/Api.vue b/src/pages/components/table/Api.vue
new file mode 100644
index 0000000..505c649
--- /dev/null
+++ b/src/pages/components/table/Api.vue
@@ -0,0 +1,152 @@
+
+
+
+
说明
+
+ AdvanceTable 是基于 Ant Design Vue Table 组件封装,支持其所有 API。
+ 主要添加了列设置及搜索控件配置的功能,可用于一些需要动态配置表格展示、动态配置搜索条件的场景。
+ 使用方式 与 antd table 基本无异。添加了部分API,如下:
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/pages/components/Table.vue b/src/pages/components/table/Table.vue
similarity index 53%
rename from src/pages/components/Table.vue
rename to src/pages/components/table/Table.vue
index 87cc41d..7625a10 100644
--- a/src/pages/components/Table.vue
+++ b/src/pages/components/table/Table.vue
@@ -1,5 +1,5 @@
-
+
状态
@@ -20,31 +32,18 @@
{{text | statusStr}}
+
-
\ No newline at end of file
diff --git a/src/pages/components/table/index.js b/src/pages/components/table/index.js
new file mode 100644
index 0000000..d6c5b8e
--- /dev/null
+++ b/src/pages/components/table/index.js
@@ -0,0 +1,2 @@
+import Table from './Table'
+export default Table
\ No newline at end of file
diff --git a/src/router/config.js b/src/router/config.js
index cac44b5..34bf098 100644
--- a/src/router/config.js
+++ b/src/router/config.js
@@ -193,7 +193,7 @@ const options = {
},
{
path: 'components',
- name: '小组件',
+ name: '内置组件',
meta: {
icon: 'appstore-o'
},
@@ -212,7 +212,7 @@ const options = {
{
path: 'table',
name: '高级表格',
- component: () => import('@/pages/components/Table')
+ component: () => import('@/pages/components/table')
}
]
},
diff --git a/src/services/api.js b/src/services/api.js
index a5d1d40..26eee91 100644
--- a/src/services/api.js
+++ b/src/services/api.js
@@ -4,5 +4,6 @@
const BASE_URL = process.env.VUE_APP_API_BASE_URL
module.exports = {
LOGIN: `${BASE_URL}/login`,
- ROUTES: `${BASE_URL}/routes`
+ ROUTES: `${BASE_URL}/routes`,
+ GOODS: `${BASE_URL}/goods`,
}
diff --git a/src/services/dataSource.js b/src/services/dataSource.js
new file mode 100644
index 0000000..1846189
--- /dev/null
+++ b/src/services/dataSource.js
@@ -0,0 +1,8 @@
+import {GOODS} from './api'
+import {METHOD, request} from '@/utils/request'
+
+export async function goodsList(params) {
+ return request(GOODS, METHOD.GET, params)
+}
+
+export default {goodsList}
\ No newline at end of file
diff --git a/src/services/index.js b/src/services/index.js
index 3dfe985..221ac09 100644
--- a/src/services/index.js
+++ b/src/services/index.js
@@ -1,5 +1,7 @@
import userService from './user'
+import dataSource from './dataSource'
export {
- userService
+ userService,
+ dataSource
}
diff --git a/src/utils/request.js b/src/utils/request.js
index 5375dfd..df43642 100644
--- a/src/utils/request.js
+++ b/src/utils/request.js
@@ -134,6 +134,28 @@ function loadInterceptors(interceptors, options) {
})
}
+/**
+ * 解析 url 中的参数
+ * @param url
+ * @returns {Object}
+ */
+function parseUrlParams(url) {
+ const params = {}
+ if (!url || url === '' || typeof url !== 'string') {
+ return params
+ }
+ const paramsStr = url.split('?')[1]
+ if (!paramsStr) {
+ return params
+ }
+ const paramsArr = paramsStr.replace(/&|=/g, ' ').split(' ')
+ for (let i = 0; i < paramsArr.length / 2; i++) {
+ const value = paramsArr[i * 2 + 1]
+ params[paramsArr[i * 2]] = value === 'true' ? true : (value === 'false' ? false : value)
+ }
+ return params
+}
+
export {
METHOD,
AUTH_TYPE,
@@ -141,5 +163,6 @@ export {
setAuthorization,
removeAuthorization,
checkAuthorization,
- loadInterceptors
+ loadInterceptors,
+ parseUrlParams
}
diff --git a/yarn.lock b/yarn.lock
index 9be1a23..2d8e941 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5302,6 +5302,11 @@ hex-color-regex@^1.1.0:
resolved "https://registry.npm.taobao.org/hex-color-regex/download/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
integrity sha1-TAb8y0YC/iYCs8k9+C1+fb8aio4=
+highlight.js@^10.2.1:
+ version "10.2.1"
+ resolved "https://registry.npm.taobao.org/highlight.js/download/highlight.js-10.2.1.tgz#09784fe2e95612abbefd510948945d4fe6fa9668"
+ integrity sha1-CXhP4ulWEqu+/VEJSJRdT+b6lmg=
+
highlight.js@^9.6.0:
version "9.18.1"
resolved "https://registry.npm.taobao.org/highlight.js/download/highlight.js-9.18.1.tgz#ed21aa001fe6252bb10a3d76d47573c6539fe13c"